/* =========================================================
 * SM Timeline - styles front
 * Tout est scope sous .smt-timeline : aucune collision avec
 * Astra / Spectra. Police héritée du thème.
 * UN SEUL carrousel Swiper :
 * - .smt-track : frise des vignettes (drag, snap, molette,
 *   clavier, flèches — modules natifs Swiper). Naviguer ne
 *   sélectionne rien.
 * - .smt-panels : zone des panneaux, PLUS un carrousel.
 *   Emplacement unique : message d'attente (.smt-idle) tant
 *   qu'aucune machine n'est sélectionnée, puis le panneau
 *   .smt-panel.is-active de la machine choisie (fondu +
 *   translation en CSS). Une machine = un descriptif.
 * Les classes .swiper / .swiper-wrapper / .swiper-slide sont celles
 * de swiper-bundle.css (chargé en dépendance de ce fichier).
 * ========================================================= */
.smt-timeline {
    --smt-accent: #f2916d;
    --smt-polaroid-ar: 4/3;
    --smt-ink: #1e293b;
    --smt-muted: #64748b;
    --smt-line: #e5e7eb;
    --smt-card-w: 220px;
    --smt-pipe-w: 80px;
    --smt-pipe-h: 200px;
    /* Gouttière latérale de la frise : espace entre le tuyau et la première /
     *	   dernière vignette (24px desktop, 16px mobile). Consommée comme padding
     *	   horizontal symétrique de .smt-track — PAS via slidesOffset (qui, combiné
     *	   à centeredSlides, décalait le centrage). */
    --smt-gutter: 24px;
    /* Image de fond commune à tous les panneaux descriptifs.
     *	   Affichée sur la moitié basse de chaque panneau, fondue en
     *	   transparence sur la moitié supérieure (masque en dégradé).
     *	   >>> Remplacez l'URL ci-dessous par celle de votre image. <<<
     *	   Mettez "none" pour désactiver complètement l'effet.
     *	   Surchargeable par l'attribut panel_card_bg_image du shortcode
     *	   (prioritaire sur cette valeur par défaut).
     *	   Désactivée en plein écran mobile (voir media queries en bas). */
    --smt-panel-card-bg: url('https://monsite.fr/wp-content/uploads/2026/08/monimage.avif');
    position: relative;
    width: 100%;
    max-width: 100%;
    font-family: inherit;
    color: var(--smt-ink);
    /* Fond du carrousel : personnalisable via --smt-carousel-bg */
    background: var(--smt-carousel-bg, repeating-linear-gradient(-45deg, #f6f6f6, #f6f6f6 6px, #f0f0f0 0, #f0f0f0 12px));
    border-radius: 12px;
    padding: 24px 0 0;
    /* (4.4.2) Le padding ne doit pas s'ajouter à height:100% : en plein écran
     *   la racine est position:fixed;inset:0, et ces 24px (8px en densité
     *   compacte) rejetaient donc le bas du bloc sous l'écran — morceau perdu,
     *   le JS verrouillant body{overflow:hidden}. Mesuré : +24px en densité
     *   bureau et +8px en compact, sur tous les appareils en mode secours (donc
     *   sur tout iPhone, qui n'a pas l'API :fullscreen element). La règle
     *   `.smt-timeline *` plus bas ne couvrait que les enfants, jamais la racine. */
    box-sizing: border-box;
    overflow: hidden;
}
.smt-timeline *,
.smt-timeline *::before,
.smt-timeline *::after { box-sizing: border-box; }
.smt-timeline img { max-width: 100%; height: auto; }
/* Reset des boutons du composant (neutralise les styles du thème) */
.smt-timeline button {
    appearance: none;
    -webkit-appearance: none;
    font: inherit;
    line-height: 1;
    cursor: pointer;
    border: none;
    background: none;
    padding: 0;
    margin: 0;
}
/* ---------- Titre / sous-titre (empilés, centrés) ---------- */
.smt-header {
    text-align: center;
    /* Décalage configurable via l'attribut header_offset du shortcode */
    margin: var(--smt-header-offset, 0) 0 28px;
    padding: 0 20px;
}
.smt-title {
    display: block;
    width: fit-content;
    margin: 0 auto 8px;
    font-family: var(--smt-title-font, inherit);
    font-size: var(--smt-title-size, clamp(24px, 4vw, 36px));
    font-weight: var(--smt-title-weight, 700);
    color: var(--smt-title-color, var(--smt-ink));
    background: var(--smt-title-bg, transparent);
    padding: var(--smt-title-padding, 0);
    border-radius: var(--smt-title-radius, 0);
    text-shadow: var(--smt-title-shadow, none);
}
.smt-subtitle {
    display: block;
    width: fit-content;
    margin: 0 auto;
    opacity: .75;
    font-family: var(--smt-subtitle-font, inherit);
    font-size: var(--smt-subtitle-size, clamp(14px, 2vw, 17px));
    font-weight: var(--smt-subtitle-weight, 400);
    color: var(--smt-subtitle-color, inherit);
    background: var(--smt-subtitle-bg, transparent);
    padding: var(--smt-subtitle-padding, 0);
    border-radius: var(--smt-subtitle-radius, 0);
    text-shadow: var(--smt-subtitle-shadow, none);
}
/* ---------- Zone d'introduction (bloc réutilisable ou texte libre) ----------
 *   Visible sur la page uniquement : masquée dès que la frise est révélée
 *   (smt-fs-open) et dans les deux modes plein écran (natif / fallback). */
.smt-intro {
    margin: 0 0 20px;
    padding: 0 20px;
    text-align: center;
    line-height: 1.65;
    /* Neutralise les variables internes du plugin : le contenu de la
     *	   composition ne doit pas hériter des dimensions de la frise */
    --smt-card-w: initial;
    --smt-pipe-w: initial;
    --smt-pipe-h: initial;
}
.smt-intro p { margin: 0 0 12px; }
.smt-timeline.smt-fs-only.smt-fs-open > .smt-intro,
.smt-timeline:fullscreen > .smt-intro,
.smt-timeline.smt-fs-fallback > .smt-intro {
    display: none;
}
/* ---------- Bouton plein écran ---------- */
.smt-fs-btn {
    position: absolute;
    top: 12px;
    right: 12px;
    z-index: 20;
    width: 44px;
    height: 44px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 50%;
    background: #fff;
    color: #334155;
    border: 1px solid rgba(0, 0, 0, .12);
    box-shadow: 0 2px 6px rgba(0, 0, 0, .15);
    transition: background .15s ease, color .15s ease, opacity .3s ease;
}
.smt-fs-btn svg { width: 20px; height: 20px; display: block; }
.smt-fs-btn .smt-ico-exit { display: none; }
.smt-fs-btn[aria-pressed="true"] .smt-ico-enter { display: none; }
.smt-fs-btn[aria-pressed="true"] .smt-ico-exit { display: block; }
.smt-fs-btn:hover,
.smt-fs-btn:focus-visible {
    background: var(--smt-accent, #f2916d);
    color: #fff;
}
.smt-timeline.smt-fs-active .smt-fs-btn { opacity: 0; pointer-events: none; }
.smt-timeline.smt-fs-active .smt-fs-btn.is-visible { opacity: 1; pointer-events: auto; }
/* ---------- Conteneur frise + tuyaux ---------- */
.smt-track-wrap {
    position: relative;
    display: flex;
    align-items: center;
    padding: 0;
}
/* Tuyaux décoratifs aux extrémités */
.smt-pipe {
    position: relative;
    flex: 0 0 var(--smt-pipe-w);
    height: var(--smt-pipe-h);
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 2; /* (3.2.1) au-dessus des flèches (z-index 2) : masque la moitié de la pastille */
    pointer-events: none; /* la zone de la flèche cachée sous le tuyau reste cliquable */
}
/* max-width empêche l'image de déborder de son conteneur
 *   (sécurité pour les images dont le ratio hauteur/largeur est élevé) */
.smt-pipe img {
    height: 100%;
    width: auto;
    max-width: 100%;
    display: block;
    object-fit: contain;
}
.smt-pipe--right img { transform: scaleX(-1); } /* miroir : supprimez si 2 images distinctes */
/* Racine Swiper de la frise : c'est ELLE qui masque le débordement
 *   (Swiper pose overflow:hidden via la classe .swiper), sinon les dates
 *   positionnées au-dessus des vignettes (top: -62px) seraient rognées.
 *   Le padding horizontal (= --smt-gutter) laisse un espace entre le tuyau
 *   et la vignette d'extrémité, qui reste ENTIÈREMENT visible et cliquable.
 *   touch-action: pan-y -> le drag horizontal est pris en charge par
 *   Swiper, le scroll vertical de la page reste possible au tactile.
 *   (Le curseur grab/grabbing est posé par Swiper : grabCursor true.) */
.smt-track {
    flex: 1 1 0;
    min-width: 0;
    overflow: hidden;
    touch-action: pan-y;
    padding: 76px var(--smt-gutter) 28px;
    position: relative;
    z-index: 1;
}
/* Indicateur de focus réservé à la navigation clavier (classe posée par le JS) :
 *   au clic souris, aucune bordure n'apparaît. */
.smt-track:focus { outline: none; }
.smt-track.smt-kb-focus:focus { outline: 2px solid var(--smt-accent); outline-offset: -2px; }
/* Affichage de secours avant l'initialisation de Swiper
 *   (vignettes en ligne, sans JS ou si le vendor est manquant).
 *   On force le wrapper en ligne (au cas où swiper-bundle.css n'est pas chargé).
 *   Dans CE mode de secours seulement, l'espacement des vignettes est une marge
 *   CSS (24px ; 16px sur mobile). En mode Swiper, l'écart est POSE par Swiper
 *   via spaceBetween (margin-right inline) : aucune marge CSS, sinon le centrage
 *   se désaligne (offset résiduel -> comportement erratique). */
.smt-track:not(.swiper-initialized) .swiper-wrapper { display: block; white-space: nowrap; }
.smt-track:not(.swiper-initialized) .smt-cell { display: inline-block; vertical-align: top; }
.smt-track:not(.swiper-initialized) .smt-cell { margin-right: 24px; }
/* ---------- Vignettes de la frise ---------- */
.smt-cell {
    position: relative;
    flex: 0 0 auto;
    width: var(--smt-card-w);
    height: auto;
    /* Pas de marge ici : l'écart entre vignettes est posé par Swiper (spaceBetween),
     *   qui le prend en compte pour mesurer, centrer et snap -> centrage exact.
     *   Une marge CSS résiduelle décalerait le centrage (voir commentaire plus haut). */
    margin-right: 0;
    background: #fff;
    border-radius: 8px;
    padding: 16px;
    box-shadow: 0 0 0 4px transparent, 0 8px 20px rgba(0, 0, 0, .18);
    transition: box-shadow .2s ease, transform .2s ease;
    user-select: none;
    cursor: pointer;
}
/* Petit effet au survol : la vignette se soulève légèrement.
 *   is-active = machine SÉLECTIONNÉE (son panneau est affiché) : anneau
 *   accent + icône ↗ maintenue visible. La vignette centrée pendant la
 *   navigation, elle, ne reçoit AUCUNE classe : naviguer ne sélectionne rien. */
.smt-cell:hover {
    transform: translateY(-4px);
    box-shadow: 0 0 0 4px transparent, 0 12px 24px rgba(0, 0, 0, .22);
}
.smt-cell.is-active {
    box-shadow: 0 0 0 4px var(--smt-accent), 0 8px 20px rgba(0, 0, 0, .2);
}
@media (hover: none) {
    /* Écran tactile : pas de survol -> léger retour visuel au toucher only */
    .smt-cell:hover { transform: none; box-shadow: 0 8px 20px rgba(0, 0, 0, .18); }
    .smt-cell.is-active:hover { box-shadow: 0 0 0 4px var(--smt-accent), 0 8px 20px rgba(0, 0, 0, .2); }
}
.smt-cell time {
    position: absolute;
    top: -62px;
    left: 0;
    right: 0;
    text-align: center;
    font-family: var(--smt-date-font, inherit);
    font-size: 30px;
    font-weight: 800;
    line-height: 1;
    color: var(--smt-ink);
    pointer-events: none;
}
.smt-cell time span {
    display: block;
    font-size: 13px;
    font-weight: 600;
    text-transform: lowercase;
}
.smt-cell-img {
    position: relative;
    width: 100%;
    aspect-ratio: 4 / 3;
    overflow: hidden;
    border-radius: 8px;
    background: #f1f5f9;
    border: 1px solid #e2e8f0;
}
.smt-cell-img img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
    pointer-events: none;
    transition: transform .3s ease;
}
/* Petit effet sur l'image complète au survol de la vignette (léger zoom) */
.smt-cell:hover .smt-cell-img img { transform: scale(1.05); }
/* ---------- Icône d'action ↗ (haut droit de l'image de la vignette) ----------
 *   Affichée au survol de la vignette (desktop), en permanence sur écran
 *   tactile, et sur la vignette sélectionnée. Le clic dessus — comme le
 *   clic sur la vignette entière — affiche le panneau descriptif. */
.smt-cell-more {
    position: absolute;
    top: 10px;
    right: 10px;
    z-index: 2;
    width: 38px;
    height: 38px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 50%;
    background: #fff;
    color: var(--smt-ink);
    box-shadow: 0 3px 10px rgba(0, 0, 0, .35);
    opacity: 0;
    visibility: hidden;
    transform: scale(.55);
    transition: opacity .22s ease, transform .22s ease, visibility .22s ease,
                background .15s ease, color .15s ease;
}
.smt-cell-more svg { display: block; }
.smt-cell:hover .smt-cell-more,
.smt-cell-more:focus-visible,
.smt-cell.is-active .smt-cell-more {
    opacity: 1;
    visibility: visible;
    transform: none;
}
.smt-cell-more:hover,
.smt-cell-more:focus-visible {
    background: var(--smt-accent, #f2916d);
    color: #fff;
    outline: none;
}
/* Écran tactile : le survol n'existe pas -> l'icône est toujours visible
 *   (elle matérialise l'action possible au toucher). */
@media (hover: none) {
    .smt-cell-more {
        opacity: 1;
        visibility: visible;
        transform: none;
    }
}
/* Cadrage individuel des vignettes (meta smt_cell_pos de la machine).
 *   Utile pour les images verticales : la partie visible est le haut (ou le bas)
 *   au lieu du centre. Sans classe, object-position reste center (défaut). */
.smt-cell-img--top img    { object-position: center top; }
.smt-cell-img--bottom img { object-position: center bottom; }
/* Liseré parasite : certains thèmes (Astra, Spectra…) / le navigateur posent
 *   un contour de focus (outline bleu) ou une surbrillance de sélection sur les
 *   vignettes .smt-cell et leurs <img> (diffusé ensuite sur le côté gauche via
 *   le box-shadow/overflow de .smt-cell). On neutralise tout contour hérité
 *   pour ne garder que l'anneau accent géré par .smt-cell.is-active et
 *   l'indicateur clavier dédié (.smt-track.smt-kb-focus). */
.smt-cell,
.smt-cell *,
.smt-cell img {
    outline: none;
    -webkit-tap-highlight-color: transparent;
}
.smt-cell.is-active,
.smt-cell.is-active img { outline: none; }
/* Conserve l'accessibilité : anneau accent UNIQUEMENT en navigation clavier */
.smt-track.smt-kb-focus .smt-cell:focus-visible,
.smt-track.smt-kb-focus .smt-cell time:focus-visible,
.smt-track.smt-kb-focus .smt-cell-img:focus-visible { outline: 2px solid var(--smt-accent); outline-offset: -2px; }
/* Icône ↗ : halo accent au focus clavier (le contour est neutralisé par
 *   la règle anti-liseré ci-dessus ; le changement de fond ne suffit pas
 *   seul comme indicateur de focus). */
.smt-track.smt-kb-focus .smt-cell-more:focus-visible {
    outline: 2px solid var(--smt-accent);
    outline-offset: 2px;
}
/* ---------- (3.2.1) Flèches : demi-pastille orange accolée au tuyau ----------
 *   Demi-stade (forme en « D ») : seuls les coins extérieurs sont arrondis,
 *   le bord plat est aligné exactement sur le bord intérieur du tuyau.
 *   Spécificité 0-2-0 (.smt-timeline .smt-arrow) : nécessaire pour battre
 *   le reset ".smt-timeline button { background: none }" (0-1-1). */
.smt-timeline .smt-arrow {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    z-index: 2; /* au-dessus de la frise (z-index 1) */
    width: 60px;
    height: 60px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--smt-accent, #f2916d);
    color: #fff;
    border: none;
    box-shadow: 0 4px 10px rgba(0, 0, 0, .25);
    transition: transform .15s ease, opacity .2s ease, filter .15s ease;
}
/* Neutralise les styles du thème au survol / focus / clic :
 *   la pastille reste orange et le chevron blanc dans tous les états */
.smt-timeline .smt-arrow:hover,
.smt-timeline .smt-arrow:focus,
.smt-timeline .smt-arrow:focus-visible,
.smt-timeline .smt-arrow:active {
    background: var(--smt-accent, #f2916d);
    color: #fff;
    outline: none;
}
/* Bord plat contre le tuyau, côté visible arrondi.
 *   transform-origin sur le bord plat : au survol, le zoom ne fait
 *   pas « décoller » la forme du tuyau. */
.smt-timeline .smt-arrow--prev {
    left: var(--smt-pipe-w);
    border-radius: 0 999px 999px 0;
    transform-origin: left center;
}
.smt-timeline .smt-arrow--next {
    right: var(--smt-pipe-w);
    border-radius: 999px 0 0 999px;
    transform-origin: right center;
}
.smt-timeline .smt-arrow svg {
    width: 20px;
    height: 20px;
    display: block;
    flex: 0 0 auto;
}
.smt-timeline .smt-arrow:not(:disabled):hover,
.smt-timeline .smt-arrow:not(:disabled):focus-visible {
    transform: translateY(-50%) scale(1.06);
    filter: brightness(1.08);
}
.smt-timeline .smt-arrow:disabled,
.smt-timeline .smt-arrow:disabled:hover {
    opacity: .35;
    transform: translateY(-50%);
    cursor: default;
}
/* ---------- Zone des panneaux descriptifs (emplacement unique) ----------
 *   .smt-panels n'est PLUS un carrousel : elle affiche soit le message
 *   d'attente (.smt-idle) tant qu'aucune machine n'est sélectionnée, soit
 *   le panneau .smt-panel.is-active de la machine choisie. Une machine =
 *   un descriptif. Le fond de zone (--smt-panel-bg) reste visible en
 *   permanence, notamment à l'attente (image de fond + message). */
.smt-panels {
    /* Fond des panneaux : personnalisable via --smt-panel-bg */
    background: var(--smt-panel-bg, linear-gradient(90deg, var(--smt-accent), #f2bf6c));
    padding: 24px 0;
    overflow: hidden;
}
/* --- Carte d'attente (.smt-idle) : affichée tant qu'aucune machine n'est
 *   sélectionnée ; masquée dès qu'un descriptif est ouvert (classe
 *   smt-has-selection posée par le JS sur .smt-timeline). Même gabarit
 *   qu'un panneau descriptif (90 % de la zone, même bord/radius/ombre).
 *   Composition (par couches) :
 *   - ::before : image de fond (attributs panel_idle_image*) traitée
 *     EXACTEMENT comme celle des cartes machines — posée sur le carton
 *     blanc, sans aucun voile, même fondu de transparence vers le haut ;
 *   - .smt-idle-media : image décorative positionnable (panel_idle_media*),
 *     posée au centre par défaut, au-dessus du fond, au-dessous du texte ;
 *   - .smt-idle-head (icône + message) en haut à gauche, texte sombre sur
 *     le blanc du carton — comme les titres des panneaux machines ;
 *   - .smt-idle-logo (mode URL de panel_title_logo) à droite de la tête. */
.smt-idle {
    position: relative;
    z-index: 0;
    display: flex;
    flex-direction: row;
    align-items: flex-start;
    justify-content: space-between;
    gap: 16px;
    width: 90%;
    margin: 0 auto;
    padding: 20px 32px 24px;
    min-height: var(--smt-idle-panel-h, 320px);
    max-height: 480px;
    background: #fff;
    border: 1px solid var(--smt-line);
    border-radius: 10px;
    box-shadow: 0 12px 28px rgba(0, 0, 0, .18);
    overflow: hidden;
    text-align: left;
}
.smt-timeline.smt-has-selection .smt-idle { display: none; }
/* Tête de carte : icône + message empilés, à gauche */
.smt-idle-head {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 12px;
    flex: 0 1 auto;
    min-width: 0;
}
/* Image de fond : cadrage/position/taille/répétition pilotés par
 *   les attributs panel_idle_image_position / _size / _repeat du shortcode
 *   (variables posées inline, défauts : center / cover / no-repeat). */
.smt-idle::before {
    content: "";
    position: absolute;
    inset: 0;
    z-index: -1;
    background: var(--smt-idle-img, none) var(--smt-idle-img-pos, center) / var(--smt-idle-img-size, cover) var(--smt-idle-img-repeat, no-repeat);
    border-radius: inherit;
    pointer-events: none;
    /* Même fondu que les cartes machines : invisible en haut (zone texte),
 *       pleinement opaque en bas */
    -webkit-mask-image: linear-gradient(to bottom, transparent 20%, black 70%);
    mask-image: linear-gradient(to bottom, transparent 20%, black 70%);
}
/* Image décorative (panel_idle_media*) : ancre = centre de l'image
 *   (translate -50/-50), position/largeur pilotées par variables inline
 *   (défauts : centre / 200px). Au-dessus du fond (z -1), au-dessous du
 *   texte (z 1). Ne capte aucun clic. */
.smt-timeline .smt-idle-media {
    position: absolute;
    left: var(--smt-idle-media-x, 50%);
    top: var(--smt-idle-media-y, 50%);
    width: var(--smt-idle-media-w, 200px);
    transform: translate(-50%, -50%);
    z-index: 0;
    pointer-events: none;
    user-select: none;
    -webkit-user-drag: none;
    display: block;
    height: auto;
}
/* Logo du titre de la carte d'attente (mode URL uniquement) : mêmes
 *   règles de dimensionnement que le logo des titres de panneaux. */
.smt-timeline .smt-idle-logo {
    flex: 0 0 auto;
    height: var(--smt-panel-title-logo-h, 44px);
    max-height: var(--smt-panel-title-logo-h, 44px);
    width: auto;
    max-width: 40%;
    object-fit: contain;
    display: block;
    margin-left: auto;
    position: relative;
    z-index: 1;
}
/* Icône de la tête : pastille accent (rappel des icônes de survol) */
.smt-idle-ico {
    position: relative;
    z-index: 1;
    width: 44px;
    height: 44px;
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 50%;
    background: var(--smt-accent, #f2916d);
    color: #fff;
}
.smt-idle-ico svg { width: 22px; height: 22px; display: block; }
/* Message : texte sombre sur le blanc du carton (comme .smt-panel-title).
 *   Halo clair très léger : reste lisible si le message est long et
 *   déborde sur la zone de fondu de l'image. */
.smt-idle-msg {
    position: relative;
    z-index: 1;
    margin: 0;
    max-width: 640px;
    overflow-wrap: break-word;
    color: var(--smt-ink);
    font-size: 15px;
    line-height: 1.6;
    font-weight: 600;
    text-shadow: 0 1px 2px rgba(255, 255, 255, .85);
}
/* Panneau descriptif d'une machine : un seul affiché à la fois.
 *   Par défaut tous masqués (aucune sélection au départ) ; le JS pose
 *   is-active sur celui de la machine sélectionnée, avec fondu +
 *   translation (keyframes smt-fade).
 *   Largeur : 90 % de la zone (comme les anciens slides du carrousel),
 *   centré — rendu identique à l'ancien mode sans la contrainte carrousel.
 *   Hauteur : contenu, plafonnée à 480px en mode automatique (borne de
 *   secours) ; en hauteur fixe / plein écran, voir les règles dédiées
 *   plus bas (100% de la zone). */
.smt-panel {
    display: none;
    width: 90%;
    margin: 0 auto;
    height: auto;
    background: #fff;
    border: 1px solid var(--smt-line);
    border-radius: 10px;
    box-shadow: 0 12px 28px rgba(0, 0, 0, .18);
    padding: 20px 32px 24px;
    max-height: 480px;
    overflow: auto;
    /* Contexte d'empilement pour le pseudo-élément de fond. */
    position: relative;
    z-index: 0;
}
.smt-panel.is-active {
    display: block;
    animation: smt-fade .3s ease;
}
/* Bouton de fermeture du descriptif (retour au message d'attente) */
.smt-panel-close {
    position: absolute;
    top: 14px;
    right: 14px;
    z-index: 3;
    width: 36px;
    height: 36px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 50%;
    background: #f1f5f9;
    color: #334155;
    border: 1px solid rgba(0, 0, 0, .08);
    box-shadow: 0 2px 6px rgba(0, 0, 0, .12);
    transition: background .15s ease, color .15s ease, transform .15s ease;
}
.smt-panel-close:hover,
.smt-panel-close:focus-visible {
    background: var(--smt-accent, #f2916d);
    color: #fff;
    transform: scale(1.08);
    outline: none;
}
.smt-panel-close svg { display: block; }
/* Image de fond commune à tous les panneaux.
 *   Le pseudo-élément porte l'image (variable --smt-panel-card-bg définie
 *   en tête de fichier, surchargeable via l'attribut panel_card_bg_image
 *   du shortcode) et c'est LUI qu'on masque : appliquer le masque
 *   directement sur .smt-panel rendrait aussi le texte transparent.
 *   - z-index: -1 : au-dessus du fond blanc de la carte, sous le contenu
 *   - le dégradé rend l'image transparente en haut, opaque à 55%
 *   - border-radius: inherit épouse les coins arrondis de la carte
 *   - l'image suit le scroll interne du panneau (overflow: auto) */
.smt-panel::before {
    content: "";
    position: absolute;
    inset: 0;
    z-index: -1;
    background: var(--smt-panel-card-bg, none) var(--smt-panel-card-bg-pos, center) / cover no-repeat;
    border-radius: inherit;
    pointer-events: none;
    -webkit-mask-image: linear-gradient(to bottom, transparent 20%, black 70%);
    mask-image: linear-gradient(to bottom, transparent 20%, black 70%);
}
/* Fondu + translation à l'affichage d'un panneau sélectionné */
@keyframes smt-fade { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) {
    .smt-panel.is-active { animation: none; }
    .smt-cell, .smt-cell-img img, .smt-cell-more { transition: none; }
    .smt-cell:hover { transform: none; }
    .smt-cell:hover .smt-cell-img img { transform: none; }
}
.smt-timeline .smt-panel-title {
    position: static;
    margin: 0 0 14px;
    /* padding droit : place pour le bouton de fermeture en haut à droite */
    padding: 16px 48px 10px 0;
    /* Titre en flex : texte à gauche, logo (optionnel) aligné à droite.
     *   Sans logo, le rendu est identique à un simple bloc de texte. */
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    /* Blanc translucide au lieu de blanc opaque, pour harmoniser avec
     *   l'image de fond du panneau tout en gardant la lisibilité du titre
     *   pendant le scroll */
    background: transparent;
    border-bottom: 1px solid rgba(0, 0, 0, .08);
    font-family: var(--smt-title-font, inherit);
    font-size: clamp(22px, 3vw, 30px);
    font-weight: 700;
    line-height: 1.2;
    color: var(--smt-panel-title-color, var(--smt-ink));
    z-index: 2;
}
/* Texte du titre : peut rétrécir et passer à la ligne */
.smt-panel-title-text { flex: 0 1 auto; min-width: 0; }
/* Logo aligné à droite du titre (attribut panel_title_logo du shortcode).
 *   Hauteur pilotable par --smt-panel-title-logo-h (44px par défaut,
 *   32px sur mobile) ; plafonné à 40 % de la largeur pour ne jamais
 *   écraser le titre ; margin-left auto = alignement droit garanti
 *   même quand le titre occupe plusieurs lignes. */
.smt-timeline .smt-panel-title-logo {
    flex: 0 1 auto;
    height: var(--smt-panel-title-logo-h, 44px);
    max-height: var(--smt-panel-title-logo-h, 44px);
    width: auto;
    max-width: 40%;
    object-fit: contain;
    display: block;
    margin-left: auto;
}
.smt-panel-content p { margin: 0 0 12px; line-height: 1.65; }
/* ---------- Polaroids ---------- */
.smt-polaroids {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
    gap: 18px;
    margin-top: 18px;
}
.smt-polaroid {
    position: relative; /* repère pour le badge lecture vidéo */
    margin: 0;
    background: #fff;
    border: 1px solid var(--smt-line);
    border-radius: 6px;
    box-shadow: 0 8px 16px rgba(0, 0, 0, .15);
    /* Haut : 12.5% de la largeur = espace blanc latéral d'une image carrée
     *	   dans un cadre 4/3 (object-fit: contain) -> bordure haute identique
     *	   aux bordures gauche/droite. (Un padding-top en % est calculé par
     *	   rapport à la LARGEUR du conteneur.)
     *	   Valeur liée au ratio : (1 - 1/ar) / 2 -> si --smt-polaroid-ar change,
     *	   ajuster (1/1 -> 0, 16/9 -> ~21.9%). Bas : 4px (minimum uniforme). */
    padding: 12.5% 8px 4px;
    text-align: center;
    transform: rotate(-1.6deg);
    transition: transform .18s ease, box-shadow .18s ease;
    cursor: zoom-in;
}
.smt-polaroid:nth-child(2n) { transform: rotate(1.2deg); }
.smt-polaroid:nth-child(3n) { transform: rotate(-2.2deg); }
.smt-polaroid:hover,
.smt-polaroid:focus-visible {
    transform: rotate(0) scale(1.02);
    box-shadow: 0 14px 22px rgba(0, 0, 0, .22);
    outline: none;
}
.smt-polaroid img,
.smt-polaroid video {
    width: 100%;
    aspect-ratio: var(--smt-polaroid-ar);
    object-fit: contain;
    border-radius: 4px;
    display: block;
    margin-bottom: 8px;
}
/* Miniature vidéo générée par le navigateur : fond sombre derrière
 *   la frame (letterboxing) et clic transmis au <figure> parent */
.smt-polaroid video {
    background: #0f172a;
    pointer-events: none;
}
.smt-polaroid figcaption {
    font-size: 12px;
    line-height: 1.2;
    min-height: 2.4em; /* = 2 lignes : bande basse normalisée */
    max-height: 2.4em;
    overflow: hidden;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
}
.smt-polaroid--spec img { background: #f8fafc; border: 1px dashed #e2e8f0; }
/* Libellé « Fiche technique » en gras */
.smt-polaroid--spec figcaption {
    font-weight: 700;
}
/* Badge lecture sur les polaroids vidéo */
.smt-polaroid--video { cursor: pointer; }
.smt-play-badge {
    position: absolute;
    top: 12.5%; /* aligne sur le bord haut de l'image (padding-top du polaroid) */
    left: 8px;
    right: 8px;
    /* hauteur de l'image = largeur / ratio ; on centre le badge dessus */
    aspect-ratio: var(--smt-polaroid-ar);
    display: flex;
    align-items: center;
    justify-content: center;
    pointer-events: none;
}
.smt-play-badge svg {
    width: 44px;
    height: 44px;
    padding: 10px;
    border-radius: 50%;
    background: rgba(15, 23, 42, .65);
    color: #fff;
    box-shadow: 0 2px 8px rgba(0, 0, 0, .35);
    transition: transform .18s ease, background .18s ease;
}
.smt-polaroid--video:hover .smt-play-badge svg,
.smt-polaroid--video:focus-visible .smt-play-badge svg {
    transform: scale(1.12);
    background: var(--smt-accent, #f2916d);
}
.smt-polaroid.is-popped > img,
.smt-polaroid.is-popped > figcaption,
.smt-polaroid.is-popped > .smt-play-badge { visibility: hidden; }
/* ---------- Popups (fiche) + lightbox (galerie) ---------- */
.smt-pop-root { position: fixed; inset: 0; z-index: 100000; pointer-events: none; }
.smt-pop-root.is-open { pointer-events: auto; cursor: zoom-out; background: rgba(15, 23, 42, .35); }
.smt-pop {
    position: absolute;
    background: #fff;
    border: 1px solid var(--smt-line);
    border-radius: 8px;
    box-shadow: 0 22px 44px rgba(0, 0, 0, .28);
    padding: 12px 12px 16px;
    text-align: center;
    overflow: auto;
    cursor: default;
    animation: smt-pop-in 140ms ease-out;
}
@keyframes smt-pop-in {
    from { transform: translateY(6px) scale(.96); opacity: 0; }
    to   { transform: none; opacity: 1; }
}
@media (prefers-reduced-motion: reduce) { .smt-pop { animation: none; } }
/* Lightbox galerie : hauteur fixe, largeur ADAPTATIVE.
 *   La popup se resserre latéralement sur chaque media (bordures
 *   latérales constantes = padding 48px) ; le JS la re-centre dans
 *   le viewport à chaque navigation.
 *   PAS de min()/clamp() avec fit-content : rejeté par certains
 *   navigateurs -> max-width simple en vw. */
.smt-pop--media {
    width: fit-content;
    max-width: 92vw;
    max-height: 92vh;
    padding-left: 48px;
    padding-right: 48px;
}
/* Zone d'affichage : hauteur FIXE (la hauteur de la popup et la
 *   légende ne bougent jamais), largeur calquée sur le media affiché.
 *   Le cadre polaroid est porté par le padding du stage
 *   (haut 24px, bas 48px = bande de la légende). */
.smt-lb-stage {
    position: relative; /* repère pour la légende en absolu */
    height: min(62vh, 560px);
    width: fit-content;
    min-width: 300px; /* évite un stage vide trop étroit le temps du chargement */
    max-width: 100%;
    margin: 0 auto;
    padding: 24px 0 48px;
    /* Le swipe horizontal est géré par le JS ; le scroll vertical
     *	   de la page reste possible au tactile */
    touch-action: pan-y;
}
/* L'image et la vidéo pilotent la largeur du stage : hauteur pleine,
 *   largeur proportionnelle (ratio préservé, jamais de déformation).
 *   max-width = sécurité petits écrans (92vw - padding popup 96px
 *   - marge de sécurité). */
.smt-lb-stage img,
.smt-lb-stage video {
    display: block;
    height: 100%;
    width: auto;
    max-width: calc(92vw - 120px);
    object-fit: contain;
    margin: 0 auto;
    border-radius: 4px;
}
.smt-lb-stage video { background: #000; }
/* Légende : positionnée en absolu dans la bande basse du stage (48px).
 *   UNE SEULE règle pour les deux types de médias : images et vidéos
 *   ont leur légende exactement à la même place. */
.smt-lb-stage figcaption {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    height: 48px; /* = padding-bottom du stage */
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 12px;
}
/* Flèches de navigation de la lightbox */
.smt-lb-nav {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    width: 44px;
    height: 44px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 50%;
    background: #f1f5f9;
    color: #334155;
    border: 1px solid rgba(0, 0, 0, .08);
    box-shadow: 0 2px 6px rgba(0, 0, 0, .12);
    transition: background .15s ease, color .15s ease, transform .15s ease;
    z-index: 2;
}
.smt-lb-prev { left: 2px; }
.smt-lb-next { right: 2px; }
.smt-lb-nav:hover,
.smt-lb-nav:focus-visible {
    background: var(--smt-accent, #f2916d);
    color: #fff;
    outline: none;
}
.smt-lb-nav:hover { transform: translateY(-50%) scale(1.08); }
.smt-lb-nav svg { display: block; }
/* Compteur « n / total » */
.smt-lb-counter {
    position: absolute;
    top: 10px;
    right: 14px;
    font-size: 12px;
    font-weight: 600;
    color: var(--smt-muted);
    background: #f1f5f9;
    border-radius: 999px;
    padding: 3px 10px;
    line-height: 1.4;
}
/* Compatibilité ascendante : ancienne classe de la popup image simple */
.smt-pop--image { width: min(560px, 92vw); max-height: 92vh; }
.smt-pop--image img { width: 100%; height: auto; max-height: calc(92vh - 72px); object-fit: contain; border-radius: 4px; }
.smt-pop--image figcaption { font-size: 12px; margin-top: 8px; }
/* Popup fiche technique — UNE SEULE règle pour ce sélecteur.
 *   width: fit-content + max-width simple en px. PAS de clamp()/min() avec
 *   fit-content : rejeté par certains navigateurs, ce qui faisait retomber
 *   la popup en width:auto (shrink-to-fit = max-content du tableau = 2355px).
 *   max-width plafonne la largeur utilisée APRÈS le calcul de fit-content. */
.smt-pop--spec {
    width: fit-content;
    max-width: 680px; /* 640px image + ~40px padding */
    max-height: 92vh;
    text-align: left;
}
/* Sécurité petits écrans : la popup ne dépasse jamais le viewport */
@media (max-width: 740px) {
    .smt-pop--spec { max-width: 92vw; }
}
/* ---------- Fiche technique ---------- */
/* min-width: 0 autorise le flex container à rétrécir en dessous
 *   de la largeur de son contenu (sinon il étire la popup fit-content) */
.smt-specsheet-banner {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    align-items: center;
    gap: 12px;
    padding-bottom: 10px;
    border-bottom: 1px solid var(--smt-line);
    min-width: 0;
}
.smt-specsheet-logo { flex: 0 0 160px; max-width: 160px; display: flex; justify-content: center; }
.smt-specsheet-logo img { max-height: 90px; width: auto; object-fit: contain; }
/* flex: 1 1 0 + min-width: 0 autorisent le rétrécissement ;
 *   overflow-wrap coupe les noms longs */
.smt-specsheet-name {
    flex: 1 1 0;
    min-width: 0;
    text-align: center;
    font-size: 20px;
    font-weight: 800;
    line-height: 1.25;
    overflow-wrap: break-word;
}
.smt-specsheet-name span { display: block; font-size: 13px; font-weight: 600; color: var(--smt-muted); }
/* L'image garde ses proportions naturelles, plafonnée à 640px.
 *   Pas de min()/calc() imbriqué : rejeté par certains navigateurs. */
.smt-specsheet-media { margin: 12px 0; text-align: center; }
.smt-specsheet-media img {
    width: auto;
    max-width: 640px; /* plafond absolu — c'est lui qui dimensionne la popup */
    max-height: 50vh;
    object-fit: contain;
    display: inline-block;
    border-radius: 6px;
    background: #f8fafc;
    border: 1px solid #e2e8f0;
}
/* Sécurité petits écrans : l'image ne dépasse jamais la popup */
@media (max-width: 700px) {
    .smt-specsheet-media img { max-width: 100%; }
}
/* overflow-wrap/word-break sur les cellules — coupe les longues
 *   valeurs techniques et URLs qui étiraient le tableau (et donc la popup) */
.smt-specsheet-table { width: 100%; border-collapse: collapse; table-layout: fixed; }
.smt-specsheet-table th,
.smt-specsheet-table td {
    text-align: left;
    padding: 10px 8px;
    vertical-align: top;
    overflow-wrap: break-word;
    word-break: break-word;
}
.smt-specsheet-table th { width: 38%; color: #334155; background: #f8fafc; border-right: 1px solid var(--smt-line); }
.smt-specsheet-table tr + tr th,
.smt-specsheet-table tr + tr td { border-top: 1px solid var(--smt-line); }
/* ---------- Plein écran (fallback CSS) ----------
 *   Layout en flex et non grid : display:grid sur l'élément fullscreen
 *   déclenche un bug de composition Chromium (crop à droite) sur
 *   certaines configs GPU.
 *   Les panneaux : la racine Swiper occupe toute la hauteur de la zone
 *   et chaque panneau remplit cette hauteur (100%), avec le padding
 *   vertical de .smt-panels comme respiration pour les ombres. */
.smt-timeline.smt-fs-fallback {
    position: fixed;
    inset: 0;
    z-index: 99999;
    width: 100%;
    max-width: 100%;
    height: 100%;
    border-radius: 0;
    display: flex;
    flex-direction: column;
    overflow: hidden;
}
.smt-timeline.smt-fs-fallback .smt-panels {
    flex: 1 1 auto;
    min-height: 0;
}
.smt-timeline.smt-fs-fallback .smt-panel {
    max-height: none;
    height: 100%;
}
/* Message d'attente : occupe toute la hauteur de la zone en plein écran */
.smt-timeline.smt-fs-fallback .smt-idle {
    min-height: 0;
    height: 100%;
    max-height: none;
}
/* ---------- Plein écran (fullscreen natif) ----------
 *   Même logique : dimensions relatives au viewport réel, contexte isolé. */
.smt-timeline:fullscreen {
    width: 100%;
    height: 100%;
    max-width: none;
    max-height: none;
    margin: 0;
    border-radius: 0;
    display: flex;
    flex-direction: column;
    /* Neutralise d'éventuels transform/filter hérités des ancêtres
     *	   qui décaleraient le positionnement en fullscreen */
    transform: none !important;
    /* Isole le contexte de rendu de l'élément en fullscreen */
    contain: layout style;
}
.smt-timeline:fullscreen .smt-panels {
    flex: 1 1 auto;
    min-height: 0;
}
.smt-timeline:fullscreen .smt-panel {
    max-height: none;
    height: 100%;
}
.smt-timeline:fullscreen .smt-idle {
    min-height: 0;
    height: 100%;
    max-height: none;
}
/* ---------- Hauteur fixe + ratio (attributs height / ratio du shortcode) ----------
 *   Actif uniquement quand l'attribut height est renseigné (classe .smt-has-height
 *   posée par le PHP). Le flex-grow répartit l'espace restant après le titre
 *   éventuel : 60/40 par défaut. Placé APRÈS les règles plein écran pour que
 *   le ratio s'y applique aussi (spécificité égale -> ordre source). */
.smt-timeline.smt-has-height {
    height: var(--smt-height, 80vh);
    display: flex;
    flex-direction: column;
}
.smt-timeline.smt-has-height .smt-header { flex: 0 0 auto; }
.smt-timeline.smt-has-height .smt-track-wrap {
    flex: var(--smt-ratio-top, 60) 1 0;
    min-height: 0;
}
.smt-timeline.smt-has-height .smt-panels {
    flex: var(--smt-ratio-bottom, 40) 1 0;
    min-height: 0;
}
.smt-timeline.smt-has-height .smt-panel {
    max-height: none;
    height: 100%;
}
.smt-timeline.smt-has-height .smt-idle {
    min-height: 0;
    height: 100%;
    max-height: none;
}
/* En plein écran, la hauteur reste 100% du viewport (le ratio, lui, s'applique) */
.smt-timeline.smt-has-height:fullscreen,
.smt-timeline.smt-has-height.smt-fs-fallback { height: 100%; }
/* ---------- (4.4.2) Le rang ne se laisse plus écraser, le tuyau ne déborde plus ----------
 *   min-height:0 (règle .smt-has-height .smt-track-wrap ci-dessus) désactive la taille
 *   minimale automatique du flexbox : la part de `ratio` pouvait donc descendre le rang
 *   SOUS sa hauteur de contenu. Or le rang n'a pas d'overflow et ses enfants gardent
 *   leur hauteur propre (.smt-track = 277px en densité bureau, .smt-pipe = pipe_height)
 *   → piste et tuyaux peignaient par-dessus les panneaux. Constaté sur iPad Air
 *   paysage : rang mesuré 232px pour un tuyau de 248px, débordement de ~8px de chaque
 *   côté. Le verrou `flex: 0 0 auto` de la media query ne protégeait que <=768px, et le
 *   sortir de cette media query écrase l'intention du shortcode (rang de l'iPad portrait
 *   effondré de 628 à 277px) : d'où min-height:auto, qui se borne à instaurer un plancher.
 *   En clair, en plein écran le ratio devient une répartition MINIMALE : il s'applique
 *   dès qu'il y a la place, et ne comprime plus jamais le contenu. */
.smt-timeline.smt-has-height:fullscreen .smt-track-wrap,
.smt-timeline.smt-has-height.smt-fs-fallback .smt-track-wrap {
    min-height: auto;
}
/*   Et le tuyau prend la hauteur du rang au lieu de la lui imposer : le bloc ne peut
 *   plus déborder, quelle que soit la valeur de pipe_height. L'artwork n'est pas
 *   déformé — l'image est déjà en object-fit:contain (règle .smt-pipe img) et se
 *   letterbox ; pipe_width (80px) étant la dimension contrainte, le rendu reste
 *   identique dès que le tuyau est plus haut que large, le cas des visuels fournis.
 *   Corollaire assumé : en plein écran, pipe_height ne gouverne plus la hauteur et ne
 *   peut donc plus rogner les panneaux. En densité compacte les tuyaux sont masqués
 *   (media query), ces deux règles n'y changent rien. */
.smt-timeline:fullscreen .smt-pipe,
.smt-timeline.smt-fs-fallback .smt-pipe {
    align-self: stretch;
    height: auto;
}
/* =========================================================
 * Mode « plein écran uniquement » (fullscreen_only)
 * La frise est masquée derrière un lanceur ; le JS ajoute
 * .smt-fs-open au clic pour la révéler avant le fullscreen.
 * ========================================================= */
/* Le lanceur disparaît dès que la frise est révélée (plein écran natif
 *   ou fallback CSS) et réapparaît à la sortie (smt-fs-open retirée par le JS) */
.smt-timeline.smt-fs-only.smt-fs-open > .smt-launcher {
    display: none;
}
/* Fond neutre tant que la frise n'est pas lancée (le fond carrousel
 *   n'a de sens que lorsque la frise est visible) */
.smt-timeline.smt-fs-only:not(.smt-fs-open) {
    background: none;
    border-radius: 0;
    padding: 0;
    overflow: visible;
    /* La hauteur fixe (smt-has-height) n'a aucun sens quand seuls
     *	   lanceur/intro/header sont visibles : le conteneur garde 80vh
     *	   avec overflow:visible et le lanceur déborde. */
    height: auto;
    display: block;
}
/* Tout est masqué sauf le lanceur, le header (titre/sous-titre)
 *   et la zone d'introduction (.smt-intro) */
.smt-timeline.smt-fs-only:not(.smt-fs-open) > :not(.smt-launcher):not(.smt-header):not(.smt-intro) {
    display: none;
}
/* ---------- Lanceur ---------- */
.smt-launcher {
    text-align: center;
    padding: 8px 0 24px;
}
/* Alignement horizontal du lanceur (attribut launch_align).
 *   text-align gère le bouton texte (inline-block) ;
 *   les marges gèrent le bouton image (block).
 *   Spécificité 0-2-0 : nécessaire pour battre le reset
 *   ".smt-timeline button { margin: 0 }" (0-1-1). */
.smt-launcher--left  { text-align: left; }
.smt-launcher--right { text-align: right; }
.smt-launcher--center .smt-launch-btn--img { margin-left: auto; margin-right: auto; }
.smt-launcher--left   .smt-launch-btn--img { margin-left: 0;    margin-right: auto; }
.smt-launcher--right  .smt-launch-btn--img { margin-left: auto; margin-right: 0; }
/* Bouton texte (sans image d'appel) */
.smt-launch-btn {
    display: inline-block;
    padding: 16px 36px;
    font-size: 18px;
    font-weight: 700;
    line-height: 1.3;
    color: #fff;
    background: var(--smt-accent, #f2916d);
    border-radius: 10px;
    box-shadow: 0 8px 20px rgba(0, 0, 0, .22);
    transition: transform .2s ease, box-shadow .2s ease, filter .2s ease;
}
.smt-launch-btn:hover,
.smt-launch-btn:focus-visible {
    transform: translateY(-2px);
    box-shadow: 0 12px 26px rgba(0, 0, 0, .28);
    filter: brightness(1.06);
    outline: none;
}
.smt-launch-btn:focus-visible {
    box-shadow: 0 0 0 4px rgba(0, 0, 0, .25), 0 12px 26px rgba(0, 0, 0, .28);
}
/* Bouton illustré : la capture d'écran sert de bouton.
 *   Largeur max personnalisable via --smt-launch-w (attribut launch_width),
 *   960px par défaut. PAS de margin ici : les marges sont posées par les
 *   règles .smt-launcher--* ci-dessus (sinon le reset bouton gagne). */
.smt-launch-btn--img {
    position: relative;
    display: block;
    padding: 0;
    max-width: var(--smt-launch-w, 960px);
    width: 100%;
    border-radius: 12px;
    overflow: hidden;
    background: none;
    box-shadow: 0 10px 28px rgba(0, 0, 0, .3);
    transition: transform .2s ease, box-shadow .2s ease;
}
.smt-launch-btn--img img {
    display: block;
    width: 100%;
    height: auto;
}
/* Icône « plein écran » : apparaît au survol / focus clavier,
 *   en même temps que le zoom (même déclencheur :hover / :focus-visible) */
.smt-launch-fs-icon {
    position: absolute;
    top: 12px;
    right: 12px;
    width: 40px;
    height: 40px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 50%;
    background: rgba(255, 255, 255, .92);
    color: #334155;
    box-shadow: 0 2px 6px rgba(0, 0, 0, .25);
    opacity: 0;
    transform: scale(.8);
    transition: opacity .2s ease, transform .2s ease;
    pointer-events: none;
}
.smt-launch-fs-icon svg { width: 20px; height: 20px; display: block; }
.smt-launch-btn--img:hover .smt-launch-fs-icon,
.smt-launch-btn--img:focus-visible .smt-launch-fs-icon {
    opacity: 1;
    transform: none;
}
/* Bandeau d'appel à l'action superposé en bas de l'image */
.smt-launch-overlay {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    padding: 14px 20px;
    font-weight: 700;
    font-size: 17px;
    color: #fff;
    background: linear-gradient(transparent, rgba(0, 0, 0, .78));
    text-align: center;
    pointer-events: none;
}
.smt-launch-btn--img:hover,
.smt-launch-btn--img:focus-visible {
    transform: scale(1.02);
    box-shadow: 0 16px 36px rgba(0, 0, 0, .35);
    outline: none;
}
/* Halo accent au focus clavier (accessibilité) */
.smt-launch-btn--img:focus-visible {
    box-shadow: 0 0 0 4px var(--smt-accent, #f2916d), 0 16px 36px rgba(0, 0, 0, .35);
}
/* ---------- Responsive ---------- */
/* (4.4.2) La densité compacte n'était ancrée que sur la LARGEUR, donc un téléphone
 *   paysage (812-932px) basculait en densité « bureau » : vignettes 220px, frise
 *   277px, tuyaux et pastilles 60px de retour, et les panneaux retombés à 48px
 *   (74% de l'écran mangé par la frise sur iPhone 8 paysage). L'ancrer aussi sur la
 *   HAUTEUR rend le bloc compact dès que le budget vertical est tenu, quel que soit
 *   l'angle, sans correctif par appareil. 560px = seuil lu sur la matrice : le plus
 *   haut des téléphones paysage mesurés est 430px (iPhone 15 Pro Max), le plus bas
 *   des iPad paysage est 744px (iPad mini) — marge confortable des deux côtés, et
 *   aucun bureau ne descend là. */
@media (max-width: 768px), (max-height: 560px) {
    .smt-timeline { --smt-card-w: 168px; --smt-pipe-w: 50px; --smt-pipe-h: 140px; --smt-gutter: 16px; padding-top: 16px; }
    .smt-cell time { font-size: 22px; top: -52px; }
    .smt-track { padding: 60px var(--smt-gutter) 20px; }
    /* Espacement de secours (sans Swiper) réduit sur mobile. En mode Swiper,
     *   la marge est ignorée (l'écart vient de spaceBetween inline) : on ne le
     *   laisse donc pas s'appliquer au chemin Swiper. */
    .smt-track:not(.swiper-initialized) .smt-cell { margin-right: 16px; }
    /* (3.2.1) Demi-pastilles réduites sur mobile */
    .smt-timeline .smt-arrow { width: 50px; height: 50px; }
    .smt-timeline .smt-arrow svg { width: 16px; height: 16px; }
    .smt-panel { padding: 14px 16px 18px; max-height: 60vh; }
    .smt-idle { padding: 14px 16px 18px; }
    /* Média décoratif plafonné sur mobile */
    .smt-timeline .smt-idle-media { max-width: 45%; }
    .smt-panels { padding: 20px 10px; }
    .smt-specsheet-logo { flex-basis: 90px; }
    /* Logo du titre de panneau : plus petit sur mobile */
    .smt-timeline .smt-panel-title-logo,
    .smt-timeline .smt-idle-logo { height: var(--smt-panel-title-logo-h, 32px); max-height: var(--smt-panel-title-logo-h, 32px); }
    /* Lightbox : marges latérales réduites sur mobile, cadre polaroid
     *	   du stage réduit en conséquence, légende alignée dessus */
    .smt-pop--media { padding-left: 40px; padding-right: 40px; }
    .smt-lb-nav { width: 38px; height: 38px; }
    .smt-lb-prev { left: 1px; }
    .smt-lb-next { right: 1px; }
    .smt-lb-stage { height: min(56vh, 420px); min-width: 220px; padding: 12px 0 28px; }
    .smt-lb-stage img,
    .smt-lb-stage video { max-width: calc(92vw - 104px); }
    .smt-lb-stage figcaption { height: 28px; }
    /* Hauteur fixe désactivée sur mobile, UNIQUEMENT hors plein écran :
     *   les :not() empêchent ces règles de s'appliquer en fullscreen natif
     *   ou fallback (sinon la zone des panneaux retombe en hauteur auto et
     *   s'effondre sur son padding). */
    .smt-timeline.smt-has-height:not(:fullscreen):not(.smt-fs-fallback) { height: auto; display: block; }
    .smt-timeline.smt-has-height:not(:fullscreen):not(.smt-fs-fallback) .smt-panel { max-height: 60vh; height: auto; }
    .smt-timeline.smt-has-height:not(:fullscreen):not(.smt-fs-fallback) .smt-idle { height: auto; min-height: 160px; max-height: none; }
    .smt-timeline.smt-has-height:not(:fullscreen):not(.smt-fs-fallback) .smt-idle { min-height: 240px; }
    /* ---------- Plein écran : verrouillage du layout sur petits écrans ----------
     *	   La frise garde sa hauteur naturelle, les panneaux prennent le reste. */
    .smt-timeline:fullscreen .smt-track-wrap,
    .smt-timeline.smt-fs-fallback .smt-track-wrap {
        flex: 0 0 auto;
    }
    .smt-timeline:fullscreen .smt-panels,
    .smt-timeline.smt-fs-fallback .smt-panels {
        flex: 1 1 0;
        min-height: 0;
    }
    /* ========== Optimisation plein écran mobile ==========
     *	   Le budget vertical d'un mobile est trop juste pour tout afficher :
     *	   on libère de la place pour les panneaux descriptifs.
     *	   1. En-tête compact (titre + sous-titre en version réduite, ~50px).
     *	   2. Frise compactée : vignettes 120px, dates et paddings réduits
     *	      (~140px au lieu de ~206px).
     *	   3. Image de fond des panneaux désactivée : lisibilité garantie
     *	      et le navigateur ne la télécharge même pas (économie de data).
     *	   AUCUN de ces changements ne touche le mode page mobile :
     *	   tout est ciblé sur :fullscreen / .smt-fs-fallback. */
    /* 1. En-tête compact en plein écran : le titre et le sous-titre
     *	   restent visibles (contexte) mais en version réduite — marges
     *	   resserrées, tailles plafonnées, le tout tient en ~50px. */
    .smt-timeline:fullscreen .smt-header,
    .smt-timeline.smt-fs-fallback .smt-header {
        margin: 0 0 8px;
        padding: 10px 48px 0; /* 10px en haut : redescend le titre du bord supérieur ;
        48px latéraux : passage du bouton plein écran */
    }
    .smt-timeline:fullscreen .smt-title,
    .smt-timeline.smt-fs-fallback .smt-title {
        font-size: 18px;
        margin-bottom: 2px;
        max-width: 100%;
    }
    .smt-timeline:fullscreen .smt-subtitle,
    .smt-timeline.smt-fs-fallback .smt-subtitle {
        font-size: 12px;
        max-width: 100%;
    }
    /* 2. Frise compacte */
    .smt-timeline:fullscreen,
    .smt-timeline.smt-fs-fallback {
        --smt-card-w: 120px; /* vignettes 120x90 au lieu de 168x126 */
        padding-top: 8px;
    }
    .smt-timeline:fullscreen .smt-track,
    .smt-timeline.smt-fs-fallback .smt-track {
        padding: 44px var(--smt-gutter) 12px;
    }
    .smt-timeline:fullscreen .smt-cell,
    .smt-timeline.smt-fs-fallback .smt-cell {
        /* Vignettes compactes : ce padding s'applique dans les DEUX modes
         *   (Swiper et secours). box-sizing: border-box (réglé en tête de
         *   fichier) l'inclut dans les 120px de --smt-card-w : il ne fausse
         *   donc aucune mesure. */
        padding: 10px;
    }
    /* Marge de secours : EXCLUSIVEMENT au mode secours (:not(.swiper-initialized)).
     *   En mode Swiper l'écart vient de spaceBetween (margin-right inline, 24px) :
     *   au rendu la marge CSS est bien écrasée par l'inline — mais PAS à la mesure :
     *   Swiper retire son margin-right inline avant de remesurer, les 12px CSS
     *   entrent alors dans la mesure (132px mémorisés au lieu de 120px), la grille
     *   de snap se décale d'un multiple de 12px à chaque vignette et la dernière
     *   position n'est jamais atteinte -> en bout de frise, le carrousel poursuit
     *   son défilement jusqu'à ce que la dernière vignette sorte du champ.
     *   La marge est donc sortie du bloc ci-dessus et limitée au seul mode de
     *   secours, exactement comme les règles de même ordre plus haut
     *   (24px desktop, 16px mobile). */
    .smt-timeline:fullscreen .smt-track:not(.swiper-initialized) .smt-cell,
    .smt-timeline.smt-fs-fallback .smt-track:not(.swiper-initialized) .smt-cell {
        margin-right: 12px;
    }
    .smt-timeline:fullscreen .smt-cell time,
    .smt-timeline.smt-fs-fallback .smt-cell time {
        font-size: 18px;
        top: -40px;
    }
    .smt-timeline:fullscreen .smt-cell time span,
    .smt-timeline.smt-fs-fallback .smt-cell time span {
        font-size: 11px;
    }
    /* (3.2.1) Demi-pastilles compactes en plein écran mobile.
     *	   Le positionnement (bord plat au bord de l'écran) est hérité
     *	   des règles de la media query ci-dessus. */
    .smt-timeline:fullscreen .smt-arrow,
    .smt-timeline.smt-fs-fallback .smt-arrow {
        width: 44px;
        height: 44px;
    }
    .smt-timeline:fullscreen .smt-arrow svg,
    .smt-timeline.smt-fs-fallback .smt-arrow svg {
        width: 14px;
        height: 14px;
    }
    /* 3. Image de fond des panneaux désactivée.
     *     On neutralise la variable plutôt que le pseudo-élément : le fond
     *     blanc et le fondu haut sont préservés, seule l'image disparaît,
     *     et le navigateur ne télécharge pas le fichier.
     *     Parité : la carte d'attente (mode panel) subit le même traitement. */
    .smt-timeline:fullscreen .smt-panel,
    .smt-timeline.smt-fs-fallback .smt-panel {
        --smt-panel-card-bg: none;
    }
    .smt-timeline:fullscreen .smt-idle,
    .smt-timeline.smt-fs-fallback .smt-idle {
        --smt-idle-img: none;
    }
    /* Tuyaux masqués sur mobile — l'espace horizontal est trop
     *	   précieux, et les images décoratives risquent de masquer les vignettes.
     *	   (3.2.1) La demi-pastille est collée au bord de l'écran,
     *	   bord plat contre le bord, côté arrondi vers l'intérieur. */
    .smt-pipe { display: none; }
    .smt-timeline .smt-arrow--prev { left: 0; }
    .smt-timeline .smt-arrow--next { right: 0; }
}
