/* ==========================================================================
   Écrans d'étape du tunnel : lieux de livraison, assurances, validation,
   remboursement sur facture.

   Chargé avec media="(max-width: 768px)" — aucun @media ici.

   Ces écrans partagent un même défaut : une mise en page desktop en float et
   en largeurs fixes, pensée pour une colonne de 740px. Le dé-flottement passe
   par .m-stack (base.css) quand il suffit ; les cas particuliers sont
   ci-dessous.
   ========================================================================== */

/* --------------------------------------------------------------------------
   Lieux de livraison (avec et sans horaire)

   Deux colonnes flottantes : l'arbre des sites à gauche (30%), le détail du
   site choisi à droite (69%). Sur mobile elles s'empilent — et c'est déjà
   l'ordre du DOM : .lieux_gauche puis .lieux_droite sont frères dans le bon
   ordre. Il n'y a donc rien à déplacer, seulement des float et des largeurs à
   neutraliser.

   C'est l'option 1 des maquettes. L'option 2 (détail imbriqué dans l'élément
   déplié) est structurellement incompatible avec jstree, dont redraw_node
   supprime le <li> et le reconstruit depuis un template à chaque ouverture ou
   fermeture de nœud : le détail en cours de saisie y serait annihilé, avec ses
   handlers et l'état de sélection. Son défaut d'utilisabilité — le détail
   apparaît hors écran — est corrigé par le défilement automatique que pose
   mobile/tunnel-steps.js, sans toucher à jstree.
   -------------------------------------------------------------------------- */
.livraison .lieux_gauche,
.livraison .lieux_droite,
.livraison .lieux,
.livraison .arbre_gauche,
.livraison .detail_lieu,
.livraison .img_coordonnees_lieu,
.livraison .coordonnees_lieu,
.livraison .jours_lieu,
.livraison .bloc_jours_lieu,
.livraison .heures_lieu,
.livraison .bloc_heures_lieu,
.livraison .msg_sans_horaire {
    float: none;
    width: auto;
    max-width: 100%;
    margin-left: 0;
    box-sizing: border-box;
}

/* .lieux impose width:175px ET overflow-x:scroll : l'arbre devient une
   fenêtre de 175px à faire défiler horizontalement, inutilisable au doigt. */
.livraison .lieux {
    overflow-x: visible;
}

.livraison .arbre_gauche {
    min-height: 0;
}

/* Listes et lignes bornées à leur conteneur. Sans largeur définie, elles se
   dimensionnent à leur contenu — et le panneau de détail imbriqué, exprimé en
   pourcentage, n'avait alors rien contre quoi se calculer : mesuré, une liste
   de 375px dans un cadre de 345, débordant de 35px hors de l'écran. */
.livraison .arbre_gauche ul {
    width: 100%;
    box-sizing: border-box;
}

.livraison .jstree-default-responsive .jstree-node {
    max-width: 100%;
    box-sizing: border-box;
}

.livraison .lieux_gauche {
    margin-bottom: var(--m-space-4);
}

/* Détail du lieu retenu : panneau bleu imbriqué dans la ligne du lieu, comme
   la maquette. Le déplacement est fait par mobile/tunnel-steps.js ; ici on ne
   décrit que son habillage et sa place dans la rangée flex de la ligne. */
.livraison .lieux_droite {
    order: 3;
    flex: 0 0 100%;
    margin-top: var(--m-space-2);
    padding: var(--m-space-4);
    border-top: 0;
    border-radius: var(--m-radius-sm);
    background: var(--m-accent-blue);
    color: var(--m-bg);
    box-sizing: border-box;
    /* Le bloc hérite d'un `white-space: nowrap` — 27 éléments concernés. Sur la
       colonne desktop de 690px la ligne tient ; dans un panneau de 319px, le
       nom du lieu réclame 333px et débordait, coupé net, en tirant une barre
       de défilement horizontale sous l'arbre. */
    white-space: normal;
}

.livraison .lieux_droite:empty {
    display: none;
}

/* Tant qu'aucun lieu n'est choisi, le bloc ne porte qu'une invite —
   « choisissez votre lieu de livraison ». Elle n'a pas à prendre l'habillage
   d'un panneau de détail : sous l'arbre, en pleine largeur et en bleu, elle
   ressemblait à une réponse alors qu'elle est une consigne.

   L'état est posé par mobile/tunnel-steps.js : le balisage est le même dans
   les deux cas, seul le texte change, donc rien ici ne permettrait de les
   distinguer. */
.livraison .lieux_droite.m-lieu-invite {
    padding: var(--m-space-2) 0 0;
    background: transparent;
    color: var(--m-ink-2);
}

.livraison .lieux_droite.m-lieu-invite .nom_lieu {
    color: var(--m-ink-2);
    font-family: inherit;
    font-size: var(--m-fs-sm);
    font-weight: normal;
    line-height: 1.4;
    text-transform: none;
}

/* Détail du lieu retenu. Structure servie — le titre est SEUL dans
   .detail_lieu, le reste en est frère :

     .lieux_droite
       .detail_lieu > .nom_lieu
       .img_coordonnees_lieu > img.picto_lieu
       .coordonnees_lieu > .carte_lieu + #popinCarte
       .msg_sans_horaire

   L'ordre du DOM place donc « Voir la carte » AVANT les horaires ; la
   maquette fait l'inverse, et c'est le bon sens de lecture — on veut d'abord
   savoir quand venir. Réordonné en CSS, sans rien déplacer. */
.livraison .lieux_droite {
    display: flex;
    flex-direction: column;
}

.livraison .lieux_droite .nom_lieu {
    font-family: var(--m-font-bold);
    font-weight: bold;
    line-height: 1.35;
    color: var(--m-bg);
}

/* Les horaires ressortent en encadré clair sur le panneau, comme la maquette */
.livraison .lieux_droite > .msg_sans_horaire {
    margin-top: var(--m-space-3);
    padding: var(--m-space-3);
    border-radius: var(--m-radius-sm);
    background: var(--m-bg-alt-2);
    color: var(--m-ink);
    line-height: 1.4;
}

.livraison .lieux_droite > .detail_lieu {
    order: 0;
}

.livraison .lieux_droite > .msg_sans_horaire {
    order: 1;
}

.livraison .lieux_droite > .coordonnees_lieu {
    order: 2;
    margin-top: var(--m-space-3);
}

/* La pastille qui surmonte le bloc d'adresse est un marqueur décoratif : les
   coordonnées elles-mêmes vivent dans une popin. Isolée et centrée sous le
   titre, elle ne dit rien et fait doublon avec celle de la ligne d'arbre. */
.livraison .lieux_droite > .img_coordonnees_lieu {
    display: none;
}

/* « Voir la carte » est un <div> avec un onclick : rien n'indique qu'on peut
   le toucher. La maquette en fait un lien centré. */
.livraison .lieux_droite .carte_lieu {
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: var(--m-tap);
    color: var(--m-bg);
    font-weight: bold;
    text-decoration: underline;
    cursor: pointer;
}

/* Nœuds de l'arbre : cibles tactiles. jstree rend des <a> de 24px de haut. */
.livraison .jstree-anchor {
    display: inline-flex;
    align-items: center;
    min-height: var(--m-tap);
    padding: 0 var(--m-space-2);
}

/* jstree embarque son PROPRE thème responsive (classe jstree-default-responsive
   posée sur le conteneur) : sous 768px il repasse toutes ses icônes en 40x40
   avec un background-size de 120x200, dimensions de SA planche de sprites.

   Or le CSE y substitue son image (coordonnees_lieu_arbre.png), calibrée pour
   12x20 par cart.css. L'image ne couvrant plus la boîte, la couleur de fond
   que le gabarit pose sur l'icône apparaissait à nu : un carré bleu de 40px à
   la place de chaque pastille de lieu, sur les neuf sites.

   Mesuré en 1280 : 12x20 et background-size auto. On rend donc au mobile les
   dimensions du desktop — c'est l'icône du client, pas celle de jstree. */
.livraison .jstree-anchor > .jstree-themeicon {
    width: 12px;
    height: 20px;
    margin-right: var(--m-space-2);
    background-size: auto;
}

/* Flèche de dépliage : le thème responsive la rend en 40x40 depuis sa planche
   40px.png, ce qui laissait une colonne vide de la largeur d'un doigt devant
   chaque libellé. Le sélecteur reprend la classe du thème — à spécificité
   égale, sa feuille est chargée après la nôtre et l'emportait.

   Le chevron est dessiné plutôt que découpé dans le sprite : deux bordures
   valent mieux qu'un décalage en pixels à retrouver, et c'est la forme que
   montre la maquette. */
.livraison .jstree-default-responsive .jstree-ocl {
    position: relative;
    /* Le contrôle de dépliage d'un site est un passage obligé du choix d'un
       lieu : 28px de large pour 44 de haut en faisaient une cible étroite. */
    width: var(--m-tap);
    height: var(--m-tap);
    background-image: none;
}

.livraison .jstree-default-responsive .jstree-node > .jstree-ocl::before {
    content: '';
    position: absolute;
    top: 50%;
    left: 50%;
    width: 7px;
    height: 7px;
    margin: -5px 0 0 -4px;
    border-right: 2px solid var(--m-muted-3);
    border-bottom: 2px solid var(--m-muted-3);
    transform: rotate(45deg);
    transition: transform .2s;
}

.livraison .jstree-default-responsive .jstree-open > .jstree-ocl::before {
    margin-top: -1px;
    transform: rotate(-135deg);
}

/* Une feuille n'a rien à déplier : ni chevron, ni gouttière pour l'accueillir.
   Le lieu de retrait lui-même cumulait sinon 80px de vide avant son libellé —
   40px d'indentation du thème responsive, 28px de chevron vide et 12px de
   boîte d'icône sans image — au point de paraître centré dans sa ligne. */
.livraison .jstree-default-responsive .jstree-leaf > .jstree-ocl {
    width: 0;
}

/* Le lieu retenu est mis en couleur par le gabarit, qui peint l'ANCRE. Cette
   ancre doit donc couvrir toute la ligne, sinon la surbrillance s'arrête là où
   commence l'indentation — mesuré : une barre partant de x=51 quand les autres
   lignes partent de 35, avec un liseré clair à sa gauche.

   L'indentation passe donc de la LIGNE au TEXTE : le fond court sur toute la
   largeur, et le libellé se cale sous celui de ses parents. Le rembourrage
   reprend la gouttière d'une ligne de site — son propre retrait, le chevron,
   la pastille et l'écart qui la suit — pour rester juste si l'un d'eux change. */
/* `.jstree-node` porte l'indentation générale : il faut donc une classe de
   plus ici, sinon les deux règles se valent et la dernière écrite l'emporte. */
.livraison .jstree-default-responsive .jstree-node.jstree-leaf {
    margin-left: 0;
}

/* Le chevron étant renvoyé à droite, la gouttière d'une ligne de site se
   réduit à son propre retrait, la pastille et l'écart qui la suit. La feuille
   la reprend, plus un décrochement, pour se poser sous ses parents. */
.livraison .jstree-default-responsive .jstree-leaf > .jstree-anchor {
    padding-left: calc(var(--m-space-2) + 12px + var(--m-space-2) + var(--m-space-3));
}

.livraison .jstree-default-responsive .jstree-leaf > .jstree-ocl::before {
    content: none;
}

/* Indentation : 40px sur un écran de 390 poussent le libellé vers le milieu.
   Un décrochement suffit à marquer la hiérarchie.

   La ligne devient une rangée flex pour que l'ancre puisse s'étendre jusqu'au
   bord droit — voir la note sur la sélection ci-dessous. Les enfants d'un
   nœud déplié passent à la ligne entière. */
.livraison .jstree-default-responsive .jstree-node {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    margin-left: var(--m-space-4);
}

.livraison .jstree-default-responsive .jstree-node > .jstree-anchor {
    flex: 1 1 auto;
}

/* Les enfants passent à la ligne entière ET en dernier : sans cet ordre
   explicite, le chevron renvoyé à droite (order 1) se retrouvait APRÈS eux,
   donc seul sur une ligne sous le lieu déplié. */
.livraison .jstree-default-responsive .jstree-node > .jstree-children {
    order: 2;
    flex: 0 0 100%;
}

/* Sélection d'un lieu.

   jstree superpose une couche `.jstree-wholerow` par ligne pour la
   surbrillance. Le gabarit, lui, peint la couleur du CSE sur l'ANCRE
   (`.jstree-wholerow-ul .jstree-clicked`), pas sur cette couche. En desktop
   l'ancre est inline : le fond épouse le libellé, ce qui passe. Passée en
   bloc de 44px pour la cible tactile, elle devenait un pavé coloré qui ne
   couvrait pas la ligne et débordait de la couche de 40px — deux filets gris
   apparaissaient de part et d'autre.

   L'ancre s'étire donc jusqu'au bord droit, et la couche reprend la hauteur
   réelle de la ligne. La couleur reste celle que le CSE configure. */
.livraison .jstree-default-responsive .jstree-wholerow {
    height: var(--m-tap);
}

/* Lignes : le thème jstree les remplit d'un gris uniforme ; la maquette les
   montre blanches, séparées d'un simple filet. */
.livraison .jstree-default-responsive .jstree-wholerow:not(.jstree-wholerow-clicked):not(.jstree-wholerow-hovered) {
    background: transparent;
}

.livraison .jstree-default-responsive > ul > .jstree-node + .jstree-node {
    border-top: 1px solid var(--m-line-2);
}

/* Chevron à droite du libellé, comme la maquette. La ligne étant déjà une
   rangée flex, il suffit de le renvoyer après l'ancre. */
.livraison .jstree-default-responsive .jstree-node > .jstree-ocl {
    order: 1;
}

/* Le gabarit ne définit d'image que pour les SITES (coordonnees_lieu*.png) :
   sur les autres types de nœud, la boîte d'icône restait vide mais occupait sa
   place. On ne la montre donc que là où il y a quelque chose à montrer. */
.livraison .jstree-anchor > .jstree-themeicon {
    display: none;
}

.livraison .model_node_site > .jstree-anchor > .jstree-themeicon {
    display: block;
}

/* cart.css:328 porte un !important côté desktop sur cette marge négative :
   c'est l'un des rares cas où l'ordre de cascade ne suffit pas. */
.livraison .model_node_locaux > a {
    margin-left: 0 !important;
}

/* Dates et créneaux : pastilles alignées, tapables.

   Le legacy fige ces deux blocs à min-height: 200px, une réserve dimensionnée
   pour la colonne du bureau. Sur mobile ils se suivent verticalement : à eux
   deux ils occupaient 400px des 642px de l'écran, et se lisaient comme deux
   grandes zones vides quand la sélection n'a pas encore été faite. Ils se
   dimensionnent désormais à leurs pastilles — aucune n'est retirée, elles
   cessent seulement de flotter dans une réserve de bureau. */
.livraison .bloc_jours_lieu,
.livraison .bloc_heures_lieu {
    display: flex;
    flex-wrap: wrap;
    gap: var(--m-space-2);
    height: auto;
    min-height: 0;
}

.livraison .bloc_jours_lieu .date,
.livraison .bloc_heures_lieu .horaire {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: var(--m-tap);
    padding: 0 var(--m-space-3);
    border: 1px solid var(--m-line-4);
    border-radius: var(--m-radius-sm);
    box-sizing: border-box;
}

.livraison .heures_lieu {
    margin-top: var(--m-space-4);
}

/* La popin carte est un dialog jQuery UI : sa largeur est déjà traitée par la
   primitive. Il ne reste que l'image, qui porte des dimensions intrinsèques. */
#popinCarte img {
    max-width: 100%;
    height: auto;
}

/* --------------------------------------------------------------------------
   Répartition du montant par participant

   Libellé à 40% et champ à 20%, tous deux en inline-block : sur 375px cela
   donne un libellé de 150px qui se coupe en trois lignes et un champ de 68px.
   On empile, pleine largeur.
   -------------------------------------------------------------------------- */
/* Le gabarit de la répartition par participant pose `display: inline-block`
   en attribut sur chaque `.champ_edit` — un par participant. La mise en bloc
   déclarée dans tunnel.css ne le bat pas, faute d'!important : les blocs
   « Montant pour X » se rangeaient donc côte à côte, chacun avec son libellé
   à 40% et son champ à 20%, sur 375px.

   L'!important est posé ICI et non sur la règle générale de `.champ_edit` :
   celle-là sert tout le tunnel, et plusieurs de ses variantes passent
   délibérément en flex — un !important sur le display les casserait toutes.
   Le sélecteur ne vise donc que les champs de la répartition, reconnaissables
   au libellé qu'ils portent. */
#commande_etape_contenu .champ_edit:has(> .repartition_participant_nom) {
    display: block !important;
}

.repartition_participant_nom {
    /* !important : le libellé porte sa mise en forme de bureau en attribut
       style, le gabarit étant partagé avec le back-office. */
    display: block !important;
    width: auto !important;
    text-align: left !important;
    margin-bottom: var(--m-space-1);
    font-weight: bold;
}

/* --------------------------------------------------------------------------
   Zones à hauteur contrainte (assurances, conditions d'inscription)

   400px est dimensionné pour une colonne desktop : le contenu y est tronqué
   dès qu'il s'empile. Ces dimensions vivaient dans l'attribut style des
   templates et étaient donc neutralisées en JS à l'exécution ; passées en
   classes (cart.css), une règle CSS suffit — un contournement de moins.
   -------------------------------------------------------------------------- */
/* !important : les 400px vivent dans l'attribut style du gabarit, où ils
   restent — c'est le rendu de bureau, que le ticket ne touche pas. Aucune
   règle de feuille ne bat un attribut style. */
.tunnel_zone_fixe {
    height: auto !important;
}

/* MAIS une zone explicitement DÉFILANTE doit le rester : les conditions
   générales font 7 544px. Libérées comme les assurances, elles produisaient
   une page de 8 271px — près de dix écrans à traverser avant d'atteindre la
   case d'acceptation, elle-même à 7 657px du haut.

   Le desktop les présente dans un encadré de 400px avec son propre
   ascenseur ; on garde ce principe, à une hauteur adaptée au petit écran.
   L'encadré est marqué visuellement pour qu'on comprenne qu'il défile. */
.tunnel_zone_defilante {
    height: auto !important;
    /* 50vh laissait 300px de hublot pour 7 544px de conditions générales :
       une quinzaine d'écrans à faire défiler DANS un cadre, en luttant contre
       le défilement de la page. On donne au texte la plus grande fenêtre
       possible sans perdre de vue qu'il y a une suite. */
    max-height: 68vh;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    overscroll-behavior: contain;
    /* !important : le gabarit porte `padding: 0 10px` en attribut style, qu'il
       garde — c'est le rendu de bureau. Sans lui, le texte reste collé aux
       filets de l'encadré. */
    padding: var(--m-space-3) !important;
    border: 1px solid var(--m-line-4);
    border-radius: var(--m-radius-sm);
    background: var(--m-bg);
}

/* Quand le texte tient tout entier, le cadre et son ascenseur n'ont pas lieu
   d'être : ils faisaient une fenêtre de lecture autour de deux lignes.
   L'état est posé par mobile/tunnel-steps.js — seule la mesure du contenu
   permet de trancher, et elle n'existe pas en CSS. */
.tunnel_zone_defilante.m-zone-tient {
    max-height: none;
    overflow-y: visible;
    padding: 0 !important;
    border: 0;
    background: transparent;
}

/* Les conditions de l'étape de paiement sont figées par leur id — 150px de
   haut et un ascenseur permanent, qu'aucune classe ne peut atteindre. Le
   gabarit les déclare comme zone défilante ; il ne reste qu'à rendre la main
   à la primitive sur les deux propriétés que l'id verrouille. */
#texte_cgv.tunnel_zone_defilante {
    height: auto;
    overflow-y: auto;
}

#texte_cgv.tunnel_zone_defilante.m-zone-tient {
    overflow-y: visible;
}

/* --------------------------------------------------------------------------
   Modes de paiement

   Chaque moyen est un inline-block de 101px centré, dont 81x52 seulement sont
   tapables — pour l'arbitrage le plus engageant de l'écran. Chacun devient une
   ligne pleine largeur, encadrée, tapable sur toute sa surface.
   -------------------------------------------------------------------------- */
#paiement_moyens {
    text-align: left;
}

#paiement_moyens .type_paiement {
    display: block;
    width: auto;
    margin-bottom: var(--m-space-2);
}

#paiement_moyens .typeMoyenPaiement {
    display: flex;
    align-items: center;
    gap: var(--m-space-3);
    min-height: var(--m-tap);
    padding: var(--m-space-2) var(--m-space-3);
    box-sizing: border-box;
    border: 1px solid var(--m-line-4);
    border-radius: var(--m-radius-sm);
    text-align: left;
    cursor: pointer;
}

#paiement_moyens .txt_mode_paiement {
    display: flex;
    align-items: center;
    gap: 10px;
    flex: 1 1 auto;
    text-align: left;
}

#paiement_moyens .icone__mode_paiement {
    flex: 0 0 auto;
}

/* --------------------------------------------------------------------------
   Assurances

   Trois colonnes flottantes par assurance — libellé et case à cocher (40%),
   tarif et conditions générales (35%), prix (10%, calé à droite) — dans un
   conteneur à hauteur fixe de 60px. Empilées, elles débordent immédiatement de
   cette hauteur : c'est elle qu'il faut libérer en premier.

   La hauteur de 400px du conteneur d'assurances est traitée par
   Mobile.unlockHeights (elle est dans l'attribut style).
   -------------------------------------------------------------------------- */
.div_content_insurance_details {
    height: auto;
    display: flex;
    flex-direction: column;
    gap: var(--m-space-2);
    padding: var(--m-space-3);
    border-bottom: 1px solid var(--m-line-2);
}

.div_insurance_details,
.div_insurance_details.col1,
.div_insurance_details.col2,
.div_insurance_details.col3 {
    float: none;
    width: auto;
    max-width: 100%;
    padding: 0;
    box-sizing: border-box;
}

/* Le prix est l'information décisive : il passe en tête de carte plutôt qu'en
   bas, là où il tombait après l'empilement. */
.div_insurance_details.col3 {
    order: -1;
    font-weight: bold;
    font-size: var(--m-fs-lg);
}

.insurance_name {
    padding: var(--m-space-3);
    font-weight: bold;
    line-height: 1.35;
}

/* La case à cocher « Je souhaite m'assurer » est la seule action de la carte :
   toute la ligne devient tapable. */
.div_insurance_details.col1 label,
.selection_insurance + label {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    min-height: var(--m-tap);
}

.selection_insurance {
    width: 20px;
    height: 20px;
    flex: 0 0 auto;
}

/* Contraste des cartes d'assurance.

   Le legacy écrit en orange de marque tout ce que la carte porte d'utile :
   le tarif, la mention « Sélectionnée par votre CSE » et le libellé de la
   case. Mesuré sur le fond gris des cartes, cet orange donne 1.95 pour 1 —
   le seuil est à 4.5, et il s'agit du prix qu'on s'apprête à payer et de
   l'action qui l'engage. Ces trois-là passent en encre ; la couleur de
   marque reste sur les aplats pleins, où elle est portée par du blanc.

   Le gris de la mention de tarif est dans le même cas, à 2.56 pour 1. Sa
   hiérarchie tient à sa taille, pas à sa pâleur. */
.insurance_paid_price,
.insurance_highlight,
.insurance_grey_text,
.div_insurance_details.col1 label,
.selection_insurance + label {
    color: var(--m-ink-2);
}

/* Bandeau « Choix n°N » : repère de regroupement quand plusieurs choix sont
   assurés dans la même étape. */
.little_cart_align_line_offre {
    padding: var(--m-space-2) var(--m-space-3);
    font-weight: bold;
}

/* --------------------------------------------------------------------------
   Validation / conditions d'inscription
   -------------------------------------------------------------------------- */

/* cart.css:543 fige une hauteur de 50px : le libellé de la case déborde dès
   qu'il passe sur deux lignes, ce qui est systématique à 390px. */
.etape_message_confirmation {
    height: auto;
    min-height: var(--m-tap);
    display: flex;
    align-items: center;
    gap: 10px;
    padding: var(--m-space-3);
    box-sizing: border-box;
    line-height: 1.35;
}

.etape_message_confirmation input[type=radio],
.etape_message_confirmation input[type=checkbox] {
    flex: 0 0 auto;
    width: 20px;
    height: 20px;
    margin: 0;
}

.etape_message_confirmation label {
    margin: 0;
}

/* Sa voisine immédiate — « Je souhaite que mes coordonnées bancaires soient
   conservées » — s'empilait au lieu de s'aligner : case à y=328, libellé
   pleine largeur à y=355. Deux cases à se suivre, dessinées de deux façons.

   Le socle pilote l'affichage de ce bloc par un `display` en attribut inline,
   qu'une déclaration de feuille ne peut battre sans !important — lequel
   casserait le masquage. La case flotte donc, et le libellé prend la place
   restante par son propre contexte de formatage. */
#commande_etape_contenu .etape_message_iban > input[type=checkbox] {
    float: left;
    margin: var(--m-space-3) var(--m-space-2) 0 0;
}

#commande_etape_contenu .etape_message_iban > label[for] {
    display: block;
    overflow: hidden;
    min-height: var(--m-tap);
    padding: var(--m-space-2) 0;
    line-height: 1.35;
}

/* Blocs d'adhésion : flottants en desktop (d'où le clear:both du template) */
.participants_adhesion,
.adhesion_user,
.adhesion_justificatif,
.upload_adhesion {
    float: none;
    width: auto;
    max-width: 100%;
    box-sizing: border-box;
}

.adhesion_user {
    margin-bottom: var(--m-space-3);
    padding-bottom: var(--m-space-3);
    border-bottom: 1px solid var(--m-line-2);
}

/* Envoi de justificatif : le glisser-déposer de filedrop.js est inopérant au
   tactile, le champ natif doit donc rester une cible confortable et ne pas
   déborder — les input[type=file] ont une largeur intrinsèque. */
.upload_adhesion input[type=file],
input[type=file].files {
    display: block;
    width: 100%;
    max-width: 100%;
    min-height: var(--m-tap);
    box-sizing: border-box;
}

/* --------------------------------------------------------------------------
   Mode de remboursement — saisie de l'IBAN

   L'IBAN est découpé en 7 segments de 4 caractères, plus le BIC. La règle
   générique « champ pleine largeur » les étirait à 286px chacun : sept
   rangées pour saisir un IBAN, sur un écran de 375. On les dimensionne à
   leur contenu (via maxlength, donc sans dépendre de leur ordre) et on les
   laisse s'enchaîner sur la largeur disponible.
   -------------------------------------------------------------------------- */
#commande_etape_contenu .iban_bic {
    display: block;
    width: auto;
    margin-bottom: var(--m-space-1);
    text-align: left;
    font-weight: bold;
}

#commande_etape_contenu .saisie_iban_bic {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    width: 100%;
    margin-bottom: var(--m-space-3);
}

#commande_etape_contenu input.input_rib_iban {
    flex: 0 0 auto;
    width: auto;
    /* Les segments etaient exclus de la regle generique des champs, qui
       portait aussi le rembourrage : ils restaient hauts de 19px. */
    min-height: var(--m-tap);
    padding: 9px 4px;
    box-sizing: border-box;
    text-align: center;
    /* chiffres a chasse fixe : les segments gardent la meme largeur quel que
       soit le contenu saisi */
    font-variant-numeric: tabular-nums;
}

#commande_etape_contenu input.input_rib_iban[maxlength="4"] {
    width: 4.6em;
}

/* Le BIC fait 11 caracteres : il prend la ligne entiere */
#commande_etape_contenu input.input_rib_iban[maxlength="11"] {
    flex: 1 1 100%;
    width: auto;
}

/* Rappel du compte sélectionné, sous la liste déroulante des IBAN
   enregistrés (posé par mobile/tunnel-steps.js). Le libellé complet ne tient
   pas dans le champ fermé — 431px nécessaires pour 349 — et c'est la fin de
   l'IBAN qui distingue deux comptes. */
.m-rappel-choix {
    margin: 6px 0 0;
    padding: 0 2px;
    color: var(--m-ink-2);
    font-size: var(--m-fs-sm);
    line-height: 1.4;
    word-break: break-word;
}

.m-rappel-choix:empty {
    display: none;
}

/* --------------------------------------------------------------------------
   Étape « options / prestations »

   Chaque option est une rangée `.option_declination` laissée en bloc : la
   case et son libellé y sont deux éléments en ligne, donc solidaires tant
   que le libellé tient sur la ligne restante — et lui seulement. Mesuré sur
   le transport de Magic Circus, « Départ de Rouen (préacheminement vers
   Paris) » fait 309px pour 315 disponibles : ce libellé-là passait sous sa
   case pendant que les deux autres restaient à côté de la leur. Trois
   options du même groupe, deux alignements.
   -------------------------------------------------------------------------- */
#commande_etape_contenu .option_declination {
    display: flex;
    align-items: center;
    gap: var(--m-space-2);
}

/* Le libellé redevient du texte qui coule : la règle générale des cases en
   fait une boîte flex, ce qui séparait l'intitulé de son prix en deux
   colonnes — « (PU : 225.00 € » se retrouvait cassé sur trois lignes dans la
   gouttière de droite. Le centrage vertical est déjà porté par la rangée. */
#commande_etape_contenu .option_declination > label[for] {
    display: block;
    flex: 1 1 auto;
    min-width: 0;
    min-height: 0;
    line-height: 1.35;
    padding: var(--m-space-2) 0;
}

/* Le prix unitaire de l'option est rendu en ambre clair — mesuré à 2.4 pour 1
   sur le fond gris du bloc, très en dessous du seuil. C'est le montant que
   l'option ajoute à la commande : il se lit en encre franche, et reste
   distinct de l'intitulé par sa graisse. */
#commande_etape_contenu .option_price {
    color: var(--m-ink-2);
    font-weight: bold;
}

/* --------------------------------------------------------------------------
   Contenus rédigés en back-office

   Les conditions d'inscription, les descriptions d'offre et les textes
   d'assurance sont saisis dans un éditeur qui pose des largeurs de bureau en
   ATTRIBUT STYLE — mesuré sur « Billetterie Spectacles » : 660px et 620px
   imbriqués dans une zone de 332px. Le texte se lisait à travers un ascenseur
   horizontal, une ligne sur deux coupée à droite.

   `max-width` plutôt que `width: auto` : elle l'emporte sur la largeur posée
   sans avoir à la remplacer, donc sans écraser ce que l'éditeur aurait de
   légitime à dire sur un élément plus étroit que la zone. Le box-sizing va
   avec : ces blocs portent aussi leur rembourrage en attribut.

   Les tables sont exclues — elles ont leur propre traitement en cartes, et
   celles qui doivent défiler le font dans leur conteneur.
   -------------------------------------------------------------------------- */
#commande_etape_contenu .tunnel_zone_defilante *:not(table):not(table *),
#commande_etape_contenu #text_description *:not(table):not(table *) {
    max-width: 100% !important;
    box-sizing: border-box;
}
