:root {
    --prd-info-label-space: 15px;
    --prd-info-item-space: 25px;
}

/******** Product Img **********/

.prd-img-box {
    border: 1px solid #eaeaea;
    margin-bottom: var(--prd-info-item-space);
}

.prd-img-thumb-box {
    margin-bottom: var(--prd-info-item-space);
}

    .prd-img-thumb-box .prd-img-thumb-item {
        cursor: pointer;
    }

        .prd-img-thumb-box .prd-img-thumb-item .thumb-box {
            position: relative;
            border-radius: var(--border-radius-product-image);
            border: 1px solid var(--color-product-border);
        }

            .prd-img-thumb-box .prd-img-thumb-item .thumb-box img {
                position: relative;
                height: 100%;
                width: 100%;
                text-align: center;
            }

            .prd-img-thumb-box .prd-img-thumb-item .thumb-box .img-select {
                position: absolute;
                left: 0;
                bottom: 0;
                width: 0;
                height: 3px;
                background-color: var(--color-default);
                transition: width 0.3s ease-in-out;
            }

                .prd-img-thumb-box .prd-img-thumb-item .thumb-box .img-select.active {
                    width: 100%;
                }


    /******** Product Info **********/
    .prd-info-box {
        padding-left: 9.5rem;
    }

    .prd-info-box h1 {
        font-size: 2.3rem;
        padding-right: 3rem;
        color: var(--color-heading);
        font-weight: 700;
        text-transform: capitalize;
        margin-bottom: var(--prd-info-item-space);
    }

    /******** Price **********/
    .prd-info-box .price-box {
        font-size: 1.6rem;
        font-weight: 500;
        margin-bottom: var(--prd-info-label-space);
        color: var(--color-price);
    }

        .prd-info-box .price-box span {
            font-size: 2.3rem;
            font-weight: 700;
            color: var(--color-price);
        }

    /******** Desc **********/
    .prd-info-box .short-desc-box {
        line-height: 1.7;
        font-size: 1.3rem;
        margin-bottom: var(--prd-info-item-space);
    }

    /******** Color **********/
    .prd-info-box .label-color-box {
        text-transform: uppercase;
        font-weight: 700;
        font-size: 1.3rem;
        color: var(--color-heading);
        margin-bottom: var(--prd-info-label-space);
    }

    .prd-info-box .color-box {
        margin-bottom: var(--prd-info-item-space);
    }

        .prd-info-box .color-box .color-item-box {
            display: inline-block;
            width: 40px;
            height: 40px;
            border-radius: 50%;
            text-align: center;
            padding: 3px;
            margin-right: 2px;
        }

            .prd-info-box .color-box .color-item-box .color-item {
                border: 1px solid #eaeaea;
                display: inline-block;
                width: 100%;
                height: 100%;
                border-radius: 50%;
            }

            .prd-info-box .color-box .color-item-box.active,
            
            .prd-info-box .color-box .color-item-box:hover {
                border: 2px solid var(--color-default);
            }

    /******** Price Table **********/
    .prd-info-box .label-price-table {
        margin-bottom: var(--prd-info-label-space);
        text-transform: uppercase;
        font-weight: 700;
        font-size: 1.3rem;
        color: var(--color-heading);
    }

        .prd-info-box .label-price-table span {
            font-weight: 400;
            font-size: 1.3rem;
            font-style: italic;
            text-transform: none;
        }

    .prd-info-box .prd-price-table {
        border: 0;
        border-collapse: collapse;
        border-spacing: 0;
        width: 100%;
        font-size: 1.3rem;
        margin-bottom: var(--prd-info-item-space);
    }

        .prd-info-box .prd-price-table th {
            margin: 0;
            font-weight: 500;
        }

        .prd-info-box .prd-price-table td {
            font-weight: 400;
        }

/******** Product Options Card **********/

.prd-option-card-item,
.prd-option-card-item-text {
    border-radius: 10px;
    background-color: #fff;
    padding: 10px;
    border: 1px solid #e2e2e2;
    box-shadow: 3px 3px 6px 0px rgba(0, 0, 0, 0.08);
    margin-bottom: 15px;
}

    .prd-option-card-item:hover,
    .prd-option-card-item-text:hover {
        border-color: var(--color-primary);
    }

    .prd-option-card-item:hover img {
        -webkit-animation: policy 1.2s linear;
        animation: policy 1.2s linear;
    }

    .prd-option-card-item .thumb-box {
        overflow:hidden;
        border-radius: var(--border-radius-product-image);
    }

    .prd-option-card-item .text-box {
        padding: 10px 0 10px 0;
    }

        .prd-option-card-item .text-box .title-box {
            font-size: 1.3rem;
            font-weight: 700;
            height: 40px;
            color: var(--color-product-name);
        }

        .prd-option-card-item .text-box .price-box,
        .prd-option-card-item-text .price-box {
            font-size: 1.2rem;
            font-weight: 400;
            padding: 10px 0 0 0;
        }

            .prd-option-card-item .text-box .price-box span,
            .prd-option-card-item-text .price-box span {
                font-size: 1.4rem;
                font-weight: 700;
                color: var(--color-price);
            }


    .prd-option-card-item-text .title-box {
        font-size: 1.3rem;
        font-weight: 700;
        color: var(--color-product-name);
    }
    .prd-option-card-item-text .desc-box {
        padding: 10px 0 0 0;
    }

    @media(max-width: 991px) {
        .prd-info-box {
        padding-top: 20px;
        padding-left: 0;
    }
}

/* ============================================================================
   FICHE PRODUIT — popup et enrichissement de page
   ----------------------------------------------------------------------------
   ⚠️ DEPLACE DEPUIS items/calculator/calculator.css LE 2026-10-03.

   Ces blocs etaient ranges avec le calculateur parce qu'ils en reprennent les
   variables (--c2-*). Mauvais critere : ce qu'une feuille partage avec une
   autre ne dit pas a qui elle appartient. La fiche produit est le SQUELETTE DE
   LA PAGE — elle s'ouvre depuis le bouton « Fiche produit », existe sans
   calculateur, et survivrait a sa disparition. Elle appartient donc a la
   feuille de la page.

   ⚠️ ET L'ORDRE DU BUNDLE LE RENDAIT NECESSAIRE. product.css est chargee AVANT
   calculator.css (bundleconfig.json) : des regles d'alignement laissees dans
   calculator.css auraient battu les regles de base restees ici, a specificite
   egale, sans que rien ne le signale. La famille entiere vit dans un seul
   fichier, et l'arbitrage redevient lisible de haut en bas.

   Prefixe `str-` et non `calc2-` : ce n'est PAS le calculateur. Reutiliser son
   prefixe aurait fait croire a un lien qui n'existe pas, et surtout expose ces
   regles au scope #calc2-widget / #calc-stricker dont elles sont dehors.
   ========================================================================== */

/*  LA ZONE DE MARQUAGE EN IMAGE, onglets d'emplacement — 2026-10-06
    (`_zoneFig` de product_stricker_page.js). Premiere case de la rangee de
    cartes d'option, meme largeur qu'elles.

    Couleurs ECRITES EN DUR : ces onglets sont hors de la portee des
    variables --c2-* (une var hors portee invalide la declaration). Les
    valeurs sont celles des cartes voisines (filet #e2e2e2, rayon 10). */
.str-zone {
    position: relative;
    margin: 0 0 24px;
    border: 1px solid #e2e2e2;
    border-radius: 10px;
    overflow: hidden;
    background: #fff;
}

.str-zone img { display: block; width: 100%; height: auto; }

.str-zone-box {
    position: absolute;
    border: 2px dashed #0fb930;
    box-shadow: 0 0 0 1px rgba(255, 255, 255, .8);
    background: rgba(15, 185, 48, .10);
    pointer-events: none;
}

.str-zone-box.is-ellipse { border-radius: 50%; }

/*  Cliquable : elle s'agrandit dans GLightbox (`_zoneBind`). */
.str-zone[data-str-zone] { cursor: zoom-in; }
.str-zone[data-str-zone]:focus-visible { outline: 2px solid #0fb930; outline-offset: 2px; }

/*  En grand dans la lightbox : la meme figure, sans marge ni curseur. */
.str-zone-lb { padding: 16px; background: #fff; }
.str-zone-lb .str-zone.is-lg { margin: 0; cursor: default; }
.str-zone-lb p { margin: 12px 0 0; text-align: center; font-weight: 600; }

/*  ---------- L'onglet Tarifs (2026-10-06) ----------
    Meme lecture que la grille de la popup « Détail » du calculateur :
    quantite a gauche, une colonne par option, la surface en sous-titre.
    Couleurs en dur, pour la meme raison que `.str-zone` (hors portee --c2-*). */
.str-tarif-scroll { overflow-x: auto; margin: 0 0 32px; }

.str-tarif-tbl {
    width: 100%;
    border-collapse: collapse;
    font-variant-numeric: tabular-nums;
}

.str-tarif-tbl th,
.str-tarif-tbl td {
    padding: 8px 12px;
    border-bottom: 1px solid #ececec;
    text-align: right;
    white-space: nowrap;
}

.str-tarif-tbl th:first-child,
.str-tarif-tbl td:first-child { text-align: left; color: #6c6e76; }

.str-tarif-tbl thead th {
    border-bottom-color: #e2e2e2;
    font-weight: 600;
    vertical-align: bottom;
}

.str-tarif-tbl th small {
    display: block;
    font-weight: 400;
    color: #8a8c93;
}

.str-tarif-tbl tbody tr:hover { background: #f7f7f8; }

/*  GRILLE HORIZONTALE (2026-10-06) : l'en-tete de LIGNE porte l'option
    (« 2 couleurs ») et sa surface. Plus fonce que la quantite d'en-tete —
    c'est le nom de ce qu'on achete. `[scope]` pour l'emporter sur
    `th:first-child` (gris) par la specificite, pas par l'ordre. */
.str-tarif-tbl tbody th[scope="row"] {
    min-width: 150px;
    font-weight: 600;
    color: #1d1e22;
}

.str-tarif-tbl tbody th[scope="row"] small { margin-top: 2px; }

.str-info {
    display: grid;
    grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
    gap: 24px;
    align-items: start;
}

/* minmax(0, Nfr) : une piste `fr` a un plancher a auto, donc a la largeur
   min-content de son contenu. Le tableau des prix compte treize colonnes — sans
   plancher a zero, il ecraserait la visionneuse jusqu'a la faire disparaitre.
   Defaut deja rencontre le 2026-10-03 sur la popup couleurs. */

.str-info-media {
    border: 1px solid var(--c2-border);
    border-radius: var(--c2-radius-lg);
    padding: 12px;
    background: #fff;
}

.str-info-img { display: block; width: 100%; height: auto; }

.str-info-from { margin: 0 0 18px; font-size: 1.6rem; }
.str-info-from strong { font-size: 2.2rem; }

.str-info-h {
    margin: 18px 0 10px;
    font-size: 1.2rem;
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--c2-muted);
}

.str-info-h em { font-weight: 400; text-transform: none; letter-spacing: 0; }

.str-info-dots { display: flex; flex-wrap: wrap; gap: 7px; }

.str-info-dot {
    width: 26px;
    height: 26px;
    border-radius: 50%;
    border: 1px solid var(--c2-border-strong);
}

.str-info-kv { width: 100%; border-collapse: collapse; }

.str-info-kv td {
    padding: 7px 0;
    border-bottom: 1px solid var(--c2-border);
    vertical-align: top;
}

.str-info-kv td:first-child { width: 40%; padding-right: 16px; color: var(--c2-muted); }

.str-info-tbl { width: 100%; border-collapse: collapse; }

.str-info-tbl th,
.str-info-tbl td {
    padding: 7px 6px;
    border-bottom: 1px solid var(--c2-border);
    text-align: left;
    white-space: nowrap;
    font-size: 1.2rem;
}

.str-info-marks { margin: 0; padding: 0; list-style: none; }

.str-info-marks li {
    padding: 7px 0;
    border-bottom: 1px solid var(--c2-border);
}

/* ---------- Nuancier de la page ----------
   Le calculateur porte deja les coloris, mais il est plus haut et celui qui lit
   la fiche ne remonte pas. Trente-trois teintes se montrent, elles ne se
   decrivent pas. */
.str-swatches {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(104px, 1fr));
    gap: 12px;
    margin: 0 0 24px;
}

.str-swatch { margin: 0; text-align: center; }

.str-swatch img {
    width: 100%;
    height: 104px;
    object-fit: contain;
    border: 1px solid var(--c2-border);
    border-radius: var(--c2-radius);
    background: #fff;
}

.str-swatch figcaption {
    margin-top: 6px;
    font-size: 1.2rem;
    line-height: 1.3;
    color: var(--c2-text);
}

/* ---------- La vignette CLIQUABLE (GLightbox) ----------

   Un coloris qui porte un visuel devient un <a> ; celui qui n'en a pas reste
   une <figure>. Les deux gardent .str-swatch, donc tout ce qui precede
   s'applique aux deux — ici on ne traite que ce qu'un lien apporte en trop :
   la couleur de lien et le soulignement, qui feraient de trente-trois noms de
   teintes trente-trois liens bleus.

   APRES les regles generales, et c'est delibere : a specificite egale, c'est
   la derniere qui gagne. Ecrites avant, ces trois lignes auraient ete
   silencieusement annulees — defaut deja rencontre deux fois sur cette
   feuille le 2026-10-03.

   TEINTE, PAS APLAT : la vignette est repetee trente-trois fois sur fond
   clair. Un filet qui fonce au survol suffit a dire « cliquable » ; un fond
   colore aurait capte l'oeil sur toute la grille. */
a.str-swatch {
    display: block;
    color: inherit;
    text-decoration: none;
    cursor: zoom-in;
}

a.str-swatch:hover img,
a.str-swatch:focus-visible img {
    border-color: var(--c2-border-strong);
}

a.str-swatch:focus-visible {
    outline: 2px solid var(--c2-accent);
    outline-offset: 2px;
}

@media (max-width: 991px) {
    .str-info { grid-template-columns: 1fr; gap: 16px; }
}

/* ---------- Visionneuse de la popup : bande de vignettes ----------
   Les coloris pilotent la grande image, comme sur la fiche OBG. Sans cette
   bande, trente-trois pastilles promettaient un choix que rien ne rendait. */
.str-info-thumbs {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(54px, 1fr));
    gap: 6px;
    margin-top: 12px;
}

/*  ⛔ FILET, RAYON ET ETAT ACTIF RETIRES D'ICI — 2026-10-05.

    Ils etaient redeclares plus bas sous `.str-info .str-info-thumb` et
    `.str-info .str-info-dot` — specificite superieure, donc c'est le bloc
    unifie qui rendait. Ces declarations ne servaient qu'a faire croire, en
    lisant la feuille, que la verite etait ici.

    ⚠️ ET L'UNE D'ELLES ETAIT NUISIBLE : `.str-info-dot.is-on { border: 2px }`
    a la MEME specificite (0,2,0) que la regle unifiee. Seul l'ordre du fichier
    departageait — deplacer un bloc aurait silencieusement rendu la bordure a
    la place de l'anneau. Un arbitrage qui ne tient qu'a l'ordre est un
    arbitrage qu'on perdra un jour sans s'en apercevoir.

    Ne restent ici que les regles SANS equivalent dans le bloc unifie. */
.str-info-thumb img { width: 100%; height: 100%; object-fit: contain; }

/* La pastille est une COMMANDE, pas une puce : elle doit garder un focus
   visible au clavier, que ni le filet ni l'anneau ne remplacent. */
.str-info-dot:focus-visible,
.str-info-thumb:focus-visible {
    outline: 2px solid var(--c2-accent);
    outline-offset: 2px;
}

/* ---------- Le DEFILEMENT APPARTIENT AU TABLEAU, pas a l'ecran ----------
   Treize paliers ne tiennent pas dans la colonne droite d'une modale. Sans ce
   conteneur, c'est toute la fiche qui part en defilement horizontal : on fait
   glisser l'ecran entier pour lire une ligne de prix, et les caracteristiques
   sortent du champ. */
.str-info-scroll {
    overflow-x: auto;
    max-width: 100%;
    -webkit-overflow-scrolling: touch;
}

/* min-width: 0 sur la colonne de droite — sans lui, une piste de grille refuse
   de descendre sous la largeur min-content de son contenu, et le conteneur
   defilant ci-dessus n'aurait jamais l'occasion de defiler : c'est la grille
   qui s'elargirait. */
.str-info-side { min-width: 0; }


/* ---------- Fiche produit de la popup ----------
   Meme construction en colonnes que la fiche de /2 — les classes de
   product.css font le travail — mais COMPACTEE : une modale n'a pas la hauteur
   d'une page. Sans plafond, le packshot mangeait l'ecran et la colonne de
   droite partait sous la ligne de flottaison. */

.calc2-info .prd-img-box { margin: 0; }

/* Plafond en vh : la galerie doit tenir avec l'en-tete de la modale ET les
   vignettes, sur un portable comme sur un grand ecran. */
.calc2-info .carousel-item img {
    max-height: 46vh;
    width: auto;
    max-width: 100%;
    margin: 0 auto;
    object-fit: contain;
}

/* Vignettes en grille simple, PAS en rail Owl : Owl exige une init JS qui ne
   tournerait pas sur du DOM injecte, le rail resterait en display:none.
   data-bs-slide-to est traite par Bootstrap en delegation, donc sans init. */
/*  ⛔ LA GRILLE, LE FILET ET L'ETAT ACTIF NE SONT PLUS ICI — 2026-10-05.

    Ce bloc declarait .calc2-info-thumb{s} en entier, et le bloc d'unification
    plus bas (« UN SEUL HABILLAGE POUR LES DEUX VISIONNEUSES ») le redeclarait
    sous `.calc2-info .calc2-info-thumb` — specificite superieure, donc c'est
    lui qui gagnait. Tout ce qui est retire ici ne servait a rien : on lisait
    `56px` et `6px` dans la feuille alors que l'ecran rendait `aspect-ratio: 1`
    et le rayon du theme.

    `.is-on` etait meme declare TROIS fois (deux ici, une dans le bloc unifie).
    Trois porteurs pour un seul etat : celui qu'on corrige n'est jamais le bon.

    Ne reste ici que ce qui est PROPRE a OBG et absent du bloc unifie. */
.calc2-info-thumb img {
    width: 100%;
    height: 100%;
    object-fit: contain;
}

/* Colonne de droite resserree : dans une modale, le pas vertical de la fiche
   pleine page creuse des trous entre les blocs. */
.calc2-info .prd-info-box { padding: 0; }

.calc2-info .price-box { margin: 0 0 14px; }

/*  La marge de ces deux titres n'est plus ici : ils sont devenus des BANDEAUX
    dans le bloc d'unification (2026-10-05), qui pose sa propre marge et gagne
    l'arbitrage en venant plus tard. La laisser aurait fait un quatrieme
    porteur mort a cote des trois qu'on vient de retirer. */
.calc2-info .color-box { margin: 0; }

.calc2-info .prd-price-table th,
.calc2-info .prd-price-table td {
    padding: 6px 8px;
    font-size: 1.2rem;
    white-space: nowrap;
}

.calc2-info .calc2-tbl-kv { margin: 0; }

@media (max-width: 991px) {
    .calc2-info .carousel-item img { max-height: 34vh; }
}

.calc2-info-err { margin: 0; color: #c0392b; }
/* ---------- Popup fiche produit : visionneuse synchronisee ----------
   Pastilles de couleur et vignettes pilotent le meme carrousel, par index.
   Une couleur sans visuel n'a pas de diapositive : elle reste affichee mais
   n'est pas cliquable, et le curseur le dit. */
.calc2-info .color-item-box { cursor: pointer; }
.calc2-info .color-item-box.is-static { cursor: default; }

/* La vignette active suit le carrousel : Bootstrap ne marque que ses propres
   indicateurs, pas nos boutons — d'ou la synchro au changement de diapositive
   (voir product_v2_page.js).

   ⚠️ LE STYLE de `.is-on` n'est PAS ici : il est dans le bloc d'unification
   plus bas, commun aux deux visionneuses. Cette note ne documente plus que le
   MECANISME, qui lui est propre a OBG. */

/* ===========================================================================
   LA FICHE PRODUIT — UN SEUL HABILLAGE POUR LES DEUX VISIONNEUSES
   ---------------------------------------------------------------------------
   Deux vocabulaires rendent le MEME ecran : « calc2-info » cote OBG, rendu par
   le serveur (Calculator_Info.cshtml), et « str-info » cote Stricker, construit
   par product_stricker_page.js. Ils avaient diverge sans raison — pastilles de
   26 px d'un cote et 40 px de l'autre, vignettes en grille ici et en flex la.

   ⚠️ ON ALIGNE PAR LE CSS, ON NE RENOMME PAS. Le markup natif est partage par
   la fiche produit ET la modale ; y toucher pour une question d'apparence
   reviendrait a risquer la page de production pour un filet vert. Les deux
   familles sont donc pilotees ensemble, chacune gardant ses noms.

   ⚠️ ET A LA FIN DU FICHIER, deliberement : a specificite egale c'est la
   derniere regle qui gagne. Deux blocs ont deja ete silencieusement annules sur
   cette feuille le 2026-10-03 pour avoir ete ecrits trop haut.

   LES REGLES DE PORTEE SONT SCOPEES A LA MODALE (.calc2-info en tete de
   selecteur) : la fiche produit pleine page garde son gabarit propre. Sans ce
   prefixe, changer la pastille de la modale changeait celle de toutes les
   fiches du site.
   =========================================================================== */

/* ---------- 1. Les vignettes : filet vert quand selectionnees ----------
   Taille commune, et la MEME compensation de padding des deux cotes : un filet
   qui passe de 1 a 2 px sans compenser fait sauter la vignette d'un pixel au
   clic — un tressautement qu'on ne nomme pas mais qu'on voit. */
.calc2-info .calc2-info-thumbs,
.str-info .str-info-thumbs {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(56px, 1fr));
    gap: 6px;
    margin: 12px 0 0;
}

.calc2-info .calc2-info-thumb,
.str-info .str-info-thumb {
    width: auto;
    height: auto;
    aspect-ratio: 1;
    padding: 2px;
    border: 1px solid var(--c2-border);
    border-radius: var(--c2-radius);
    background: #fff;
    cursor: pointer;
    overflow: hidden;
    transition: border-color .15s ease;
}

/*  LE SURVOL, qui manquait aux deux visionneuses — ajoute le 2026-10-05.

    Une vignette est une COMMANDE : sans retour au survol, rien ne dit qu'elle
    repond, et l'acheteur ne sait pas que la bande est cliquable. Le curseur
    seul ne suffit pas, il faut l'avoir deja pose dessus pour le voir.

    ⚠️ IL NE DOIT PAS IMITER LA SELECTION — meme regle que les pastilles, ou
    le natif confondait les deux. Le survol FONCE le filet, il ne le verdit
    pas : « je passe dessus » et « c'est mon choix » restent distincts. */
.calc2-info .calc2-info-thumb:hover,
.str-info .str-info-thumb:hover {
    border-color: var(--c2-border-strong);
}

.calc2-info .calc2-info-thumb.is-on,
.str-info .str-info-thumb.is-on {
    border: 2px solid var(--c2-accent);
    padding: 1px;
}

/*  La vignette deja choisie garde son filet vert au survol, comme la pastille :
    passer la souris sur son propre choix ne doit pas le faire clignoter. */
.calc2-info .calc2-info-thumb.is-on:hover,
.str-info .str-info-thumb.is-on:hover {
    border-color: var(--c2-accent);
}

/*  LE CORIS SANS VISUEL — marque, jamais masque (2026-10-05).

    « Vert pastel » sur la 30102 : un ajout recent que Stricker n'a pas encore
    photographie. Il n'a ni vignette, ni vue de maquette, et sa pastille etait
    muette au clic.

    Il reste AFFICHE et SELECTIONNABLE — le commander est possible, seul
    l'apercu manque. La diagonale dit « pas d'image », pas « indisponible » :
    deux messages tres differents pour l'acheteur, et c'est le second qui
    ferait perdre une vente. */
.str-info .str-info-dot.is-noimg {
    background-image: linear-gradient(
        135deg, transparent 44%, rgb(0 0 0 / .28) 44%,
        rgb(0 0 0 / .28) 56%, transparent 56%);
}

/*  La place du visuel manquant. Elle occupe le cadre plutot que de le laisser
    vide : un cadre blanc se lit comme un chargement qui n'aboutit pas. */
.str-info-noimg {
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 180px;
    margin: 0;
    padding: 24px;
    border: 1px dashed var(--c2-border-strong);
    border-radius: var(--c2-radius);
    color: var(--c2-muted);
    text-align: center;
}

/* ---------- 2. Les pastilles : rond vert quand selectionnees ----------
   Le natif marque l'etat avec « .active », le module Stricker avec « .is-on ».
   Les deux sont declares ici plutot que d'en imposer un : renommer cote serveur
   toucherait un partiel partage, et renommer cote JS casserait la synchro avec
   les vignettes qui porte deja le meme attribut.

   ⚠️ Le natif enveloppe sa couleur dans .color-item ; Stricker peint le fond du
   bouton. Le filet est donc pose sur le CONTENEUR des deux cotes, seul element
   qu'ils ont en commun. */
/*  ⚠️ GRAMMAIRE ALIGNEE SUR .calc2-sw — 2026-10-05.

    Trois endroits montrent les memes coloris : le nuancier du calculateur, la
    fiche produit en popup, et le bloc natif OBG. Ils avaient DEUX grammaires :
    le calculateur cerclait par OMBRE PORTEE, les deux autres par BORDURE.

    L'ombre gagne, et pas par gout :
      - elle ne change pas la taille de la boite, donc aucun rembourrage a
        compenser a la selection — la rangee ne bouge pas d'un pixel ;
      - l'anneau se pose AUTOUR de la couleur au lieu de la rogner. Sur une
        pastille de 34 px, 2 px de bordure mangeaient 12 % du disque, et
        d'autant plus que la teinte etait claire ;
      - le liseré blanc intercalaire detache l'anneau vert des teintes vertes,
        qui sans lui se confondaient avec leur propre selection.

    Valeurs reprises telles quelles de .calc2-sw (calculator.css). Elles ne
    sont pas dans un jeton : si l'une bouge, chercher l'autre. */
.calc2-info .color-box .color-item-box,
.str-info .str-info-dot {
    width: 36px;
    height: 36px;
    padding: 0;
    margin: 0;
    border: 0;
    border-radius: 50%;
    box-shadow: 0 0 0 1px var(--c2-border-strong);
    cursor: pointer;
    transition: box-shadow .15s ease;
}

.str-info .str-info-dots,
.calc2-info .color-box {
    display: flex;
    flex-wrap: wrap;
    gap: 7px;
}

/*  (0,4,0) au minimum : la regle d'origine est
    « .prd-info-box .color-box .color-item-box.active », et un selecteur plus
    court aurait perdu l'arbitrage sans rien dire. */
.calc2-info .prd-info-box .color-box .color-item-box.active,
.str-info .str-info-dot.is-on {
    /*  Blanc PUIS vert : le liseré intercalaire est ce qui rend l'anneau
        lisible sur une pastille verte. Sans lui, « Vert » selectionne et
        « Vert » non selectionne se ressemblent. */
    box-shadow: 0 0 0 2px #fff, 0 0 0 4px var(--c2-accent);
}

/*  Le survol ne doit PAS imiter la selection. Le natif les confondait — meme
    filet vert pour « je passe dessus » et « c'est mon choix » —, donc rien a
    l'ecran ne disait laquelle des deux on regardait. */
.calc2-info .prd-info-box .color-box .color-item-box:hover,
.str-info .str-info-dot:hover {
    box-shadow: 0 0 0 2px var(--c2-border-strong);
}

/*  La pastille DEJA choisie garde son anneau au survol : le survol ne doit
    jamais defaire l'etat, sinon passer la souris sur son propre choix le fait
    clignoter comme s'il se perdait. */
.calc2-info .prd-info-box .color-box .color-item-box.active:hover,
.str-info .str-info-dot.is-on:hover {
    box-shadow: 0 0 0 2px #fff, 0 0 0 4px var(--c2-accent);
}

/* ---------- 3. Le rail de titres ----------
   « Tout est colle en un seul bloc » : caracteristiques, tableau des prix et
   marquages s'enchainaient sans respiration, et l'oeil ne trouvait plus ou
   commence quoi.

   MEME IDEE QUE LE RAIL DU CALCULATEUR, EN BEAUCOUP PLUS DISCRET. Le fanion du
   calculateur (page-title-item-box2) porte un aplat et une pointe : il sert a
   decouper un parcours de decision. Ici on ne decoupe qu'une lecture, donc un
   simple filet vertical suffit a dire « nouvelle section ».

   UN FILET A GAUCHE, PAS UNE LIGNE AU-DESSUS : une ligne au-dessus aurait
   demande une exception pour le premier titre, donc une regle de POSITION — et
   une regle de position se trompe de cible des que l'ordre des blocs change.
   Le filet lateral n'a pas ce defaut : il est juste sur tous les titres. */
.calc2-info .label-color-box,
.calc2-info .label-price-table,
.str-info .str-info-h {
    /*  BANDEAU, PAS SEULEMENT UN FILET — refonte du 2026-10-05.

        Ces titres portaient un filet navy sur du texte nu, en 1,2 rem
        majuscules grises : soit 12 px reels, la plus petite graisse de toute
        la fiche pour ce qui en structure la lecture. Rien ne les rattachait
        visuellement au contenu qu'ils annonçaient, et ils ne ressemblaient a
        aucun autre en-tete du parcours.

        Ils reprennent donc la grammaire des en-tetes de carte du calculateur
        (.calc2-mark-card-h) : teinte bleutee, filet bas, 14 px / 600, casse
        normale. Un en-tete de section se lit pareil partout — c'est la meme
        promesse « ce qui suit appartient a ce titre ».

        ⚠️ PAR LES JETONS, pas par des valeurs recopiees. Ils ont d'abord ete
        ecrits en dur ici (#f3f5fb / #dfe4f2) faute de voir que --c2-surface-head
        et --c2-line-head existaient deja — et que la popup ne les voyait pas,
        les jetons n'etant declares que sur les deux widgets. Le perimetre a
        ete etendu a .str-info dans calculator.css : une seule source.

        Le filet navy lateral RESTE : c'est lui qui distingue ces titres d'un
        simple en-tete de carte, et il parle la meme langue que .calc2-pop-intro
        et le bloc livraison. La teinte seule les aurait rendus muets. */
    margin: 22px 0 0;
    padding: 10px 14px;
    background: var(--c2-surface-head);
    border-left: 3px solid rgb(0 9 84 / .35);
    border-bottom: 1px solid var(--c2-line-head);
    font-size: 1.4rem;
    font-weight: 600;
    letter-spacing: 0;
    text-transform: none;
    color: var(--c2-heading);
}

/*  LE CONTENU RESPIRE SOUS SON TITRE.

    Le bandeau colle desormais a ce qu'il annonce — c'est voulu — mais sans
    rembourrage le premier element venait se coller au filet bas, et le dernier
    au titre suivant. Les caracteristiques, le nuancier et les tableaux etaient
    tous a zero.

    Le retrait horizontal reprend celui du bandeau (14 px) : le texte du titre
    et la premiere ligne du contenu tombent sur la meme verticale. Sans ca, le
    rembourrage se verrait comme un decalage.

    `+ *` et non une liste de classes : il y a quatre types de contenu ici
    (pastilles, tableau de caracteristiques, grille de prix, liste de
    marquages) et il s'en ajoutera. Une liste nommee aurait oublie le
    cinquieme, en silence. */
.calc2-info .label-color-box + *,
.calc2-info .label-price-table + *,
.str-info .str-info-h + * {
    /*  17 a GAUCHE et non 14 : le bandeau porte 3 px de filet EN PLUS de son
        rembourrage, donc son texte commence a +17. Mesure du 2026-10-05 —
        titre, pastilles et cellules tombent tous sur la meme verticale. */
    padding: 16px 14px 16px 17px;
    margin-top: 0;
}

/*  ⚠️ UNE TABLE EN `border-collapse: collapse` IGNORE SON PROPRE PADDING.

    C'est la specification, pas un bug de navigateur : dans le modele de
    bordures fusionnees, le rembourrage de l'element <table> n'a aucun effet.
    La regle ci-dessus etait donc bien APPLIQUEE sur les deux tableaux de cette
    fiche — getComputedStyle le confirmait — et ne faisait RIEN.

    Piege de diagnostic : on verifie que la propriete est calculee, on la voit
    juste, et on cherche l'erreur ailleurs. Il faut mesurer le RENDU.

    On passe donc par les cellules, en bordure de tableau uniquement. */
.str-info .str-info-h + table { padding: 0; }

.str-info .str-info-h + table td:first-child,
.str-info .str-info-h + table th:first-child { padding-left: 17px; }

.str-info .str-info-h + table td:last-child,
.str-info .str-info-h + table th:last-child { padding-right: 14px; }

.str-info .str-info-h + table tr:first-child > * { padding-top: 16px; }
.str-info .str-info-h + table tr:last-child  > * { padding-bottom: 16px; }

/*  La parenthese de precision garde sa voix basse : « (premiers prix hors
    taxes) » n'est pas un titre, c'est une note. */
.calc2-info .label-price-table span,
.str-info .str-info-h em {
    font-weight: 400;
    font-style: italic;
    text-transform: none;
    letter-spacing: 0;
}

/* ---------- 4. La grande image change en FONDU ----------
   Le remplacement etait sec : la photo sautait d'une couleur a l'autre, et sur
   une image lente le cadre restait vide un instant. Le fondu couvre les deux —
   il adoucit le changement ET masque l'attente.

   Le module ne retire « is-swapping » qu'une fois la nouvelle image decodee
   (voir product_stricker_page.js) : on ne revele jamais une image a moitie
   chargee. */
.str-info-img {
    transition: opacity .18s ease;
}

.str-info-img.is-swapping { opacity: 0; }

/* ============================================================================
   Calculateur v2 — feuille AUTONOME (route /p uniquement)
   ----------------------------------------------------------------------------
   Tout ce qui est propre au calculateur vit ici : loader, sections, pastilles,
   paliers, lignes, cartes, replis, recapitulatif, modale, responsive.
   Aucune dependance a page_items.css ni a calculator.css : les deux
   calculateurs ne coexistent jamais sur une page, l'isolation est totale.
   Prefixe impose : .calc2-*  — conteneur : #calc2-widget
   ========================================================================== */

/* ---------------------------------------------------------------------------
   TYPOGRAPHIE — on n'en declare pas.
   Tailles, familles et graisses sont HERITEES du site. Declarer les siennes
   faisait paraitre la page ecrasee : le calculateur sortait a 13 px la ou le
   reste du site est a 14 px (--font-size-base: 1.4rem).
   Les deux seules exceptions ci-dessous sont COPIEES du site, pas inventees :
     - titre de section : 2rem / 700, comme .page-title-item-box1 .title-txt
     - total du recapitulatif : 2rem, pour qu'il reste le point de fixation
   --------------------------------------------------------------------------- */

/*  ⛔ LES DEUX FICHES PRODUIT SONT DANS CETTE LISTE — CORRECTIF 2026-10-05.

    `.str-info` (Stricker, construite en JS) et `.calc2-info` (OBG, rendue par
    Calculator_Info.cshtml) vivent dans une MODALE, DEHORS du calculateur. Leurs
    regles (product.css) utilisent pourtant --c2-border, --c2-accent,
    --c2-radius... qui n'etaient declares que sur les deux widgets ci-dessous.

    Cote OBG le defaut etait MASQUE par des valeurs de repli
    — `var(--c2-border, #eaeaea)` — ecrites dans la moitie des regles
    seulement. D'ou un bloc a moitie juste, donc plus difficile a diagnostiquer
    que la panne franche cote Stricker. Les replis ont ete retires : une fois
    la portee juste, ils ne font que cacher la prochaine erreur du meme type.

    `[data-stricker-info]` — le volet « plus d'info » de la fiche Stricker,
    ajoute le meme jour et pour le meme defaut. Son nuancier « Coloris
    disponibles » declare pourtant bien
    `border: 1px solid var(--c2-border)` et un survol en
    `--c2-border-strong` : les deux etaient morts, donc des vignettes sans
    filet et sans reponse au survol. TROISIEME bloc touche par la meme cause —
    c'est le signe qu'il fallait traiter la PORTEE, pas les symptomes.

    ⚠️ LA LISTE EST UN CONTRAT. Tout composant qui utilise ces jetons et qui
    vit hors des deux widgets doit s'y ajouter. Le defaut ne se voit pas a la
    lecture de sa propre feuille : la regle y est juste, elle meurt ailleurs.

    Une variable absente ne retombe pas sur une valeur neutre : la declaration
    entiere devient INVALIDE AU CALCUL. `border: 1px solid var(--c2-border)`
    ne donne pas un filet gris, il ne donne AUCUN filet. Mesure du 2026-10-05
    dans la popup : vignettes a `0px none`, rayons a 0, pastilles sans contour.

    C'est le pire mode de panne du CSS — rien dans la feuille n'est faux, rien
    ne remonte en console, et on corrige regle par regle un defaut qui n'a
    qu'une cause. Le reflexe : quand PLUSIEURS proprietes disparaissent d'un
    coup sur un seul bloc, soupconner la PORTEE des variables avant les regles.

    On etend donc le perimetre plutot que d'ecrire les valeurs en dur dans
    product.css — ce qui aurait fige une copie du theme vouee a diverger. */
#calc2-widget,
#calc-stricker,
.calc2-info,
.str-info,
[data-stricker-info],
.calc2-q-prix,
[data-calc-delivery] {
    --c2-text: #3f4045;
    --c2-heading: #222222;
    --c2-muted: #8a8c93;
    --c2-border: #eaeaea;
    --c2-border-strong: #d4d4d4;
    --c2-surface: #ffffff;
    /* Les visuels produit sont des carres blancs detoures : tout fond gris
       derriere eux se voit comme un cadre parasite. Le calculateur est donc
       blanc partout, et seul le rail porte une teinte, tres legere. */
    --c2-surface-alt: #ffffff;

    /* SURFACE D'EN-TETE — bandeaux du panneau de prix et en-tetes de carte de
       marquage. Gris tres leger, DESATURE VERS LE NAVY des rails : les trois
       elements doivent se lire comme un seul ecran, et un gris parfaitement
       neutre a cote de filets bleutes se voit comme une couleur de plus.

       Distincte de --c2-surface-alt, qui reste BLANCHE pour la raison
       ci-dessus. Le gris n'est admis que la ou aucune image detouree ne se
       pose : ni les bandeaux du panneau ni les en-tetes de carte n'en portent.

       Une seule declaration pour les deux usages — la valeur a d'abord ete
       ecrite en dur sur .calc2-mark-card-h, et elle aurait diverge du panneau
       au premier ajustement. */
    --c2-surface-head: #f3f5fb;
    --c2-line-head: #dfe4f2;

    /*  LE SECOND NIVEAU D'EN-TETE — ajoute le 2026-10-05.

        Le panneau de prix a desormais des SOUS-CARTES (une par produit du
        devis), donc deux niveaux d'en-tete empiles : celui du panneau, et
        celui de chaque produit. Les deux tiraient sur --c2-surface-head, ce
        qui les rendait indistinguables — on lisait deux bandeaux de meme poids
        sans savoir lequel contenait l'autre.

        Meme teinte, valeur plus claire : la hierarchie se dit par la VALEUR,
        pas par une couleur differente. Introduire un second ton bleute aurait
        ajoute une couleur a la page pour exprimer une imbrication.

        En jeton et non en dur : le jour ou la teinte de tete bouge, ces deux
        valeurs doivent bouger ensemble ou l'ecart se verra. */
    --c2-surface-sub: #f9fafd;
    --c2-line-sub: #eceff8;

    --c2-accent: #0fb930;
    --c2-accent-dark: #0b8f25;
    /* Fond de selection — reserve aux blocs SANS image (paliers, lignes).
       Sur une carte qui contient un visuel a fond blanc, ce fond est
       decoupe par le carre blanc de l'image : la, c'est filet + texte. */
    --c2-accent-soft: #daf3e1;
    --c2-radius: 8px;
    --c2-radius-lg: 12px;
    --c2-gap: 12px;

    position: relative;
    color: var(--c2-text);
}

/* ---------- Etats ---------- */

#calc2-widget .calc2-state { width: 100%; }
#calc-stricker .calc2-state { width: 100%; }

/* L'ETAT D'ATTENTE reserve sa hauteur plutot que d'en prendre a l'arrivee du
   contenu. Sans plancher, le bloc faisait la taille de l'anneau : la page
   gagnait 2 600 px d'un coup a la reponse de l'API, et tout ce qui suit — le
   formulaire de devis, les garanties — sautait sous le curseur.

   Meme raisonnement que le min-height des corps de modale : le contenu remplit
   une place deja reservee au lieu de la creer.

   ⚠️ CLASSE PROPRE, ET SURTOUT PAS .calc2-state.

   Ces regles y ont d'abord ete posees. Or .calc2-state a DEJA un role dans le
   calculateur natif : sa vue en rend trois — loading, error et ready — et
   « ready » enveloppe TOUT le calculateur construit. Les passer en flex centre
   avec un min-height a donc centre et retreci le calculateur entier en
   production. Regression du 2026-10-03, vue sur sac-pub.

   La lecon : avant d'ajouter des regles a une classe existante, verifier qui
   d'autre la porte. Une classe au nom generique en a presque toujours un
   autre. */
#calc2-widget .calc2-loading,
#calc-stricker .calc2-loading {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 14px;
    min-height: 320px;
    color: var(--c2-muted);
}

#calc2-widget .calc2-loading p,
#calc-stricker .calc2-loading p { margin: 0; }
#calc2-widget .d-none { display: none !important; }
#calc-stricker .d-none { display: none !important; }

/* PAS de loader maison ici.
   Le site en a UN seul, .loader-spiner (page_items.css, charge globalement),
   deja utilise par le calculateur v1 et le moteur de maquette. Une copie
   « alignee sur » l'original avait ete ecrite puis retiree : elle divergeait
   des le premier reglage, et multiplier les loaders est le plus sur moyen de
   se retrouver avec autant de versions que d'ecrans.
   Seule l'ADAPTATION a un corps de modale reste ici (voir plus bas). */

#calc2-widget .calc2-error,
#calc-stricker .calc2-error {
    text-align: center;
    padding: 48px 16px;
}

#calc2-widget .calc2-btn-retry,
#calc-stricker .calc2-btn-retry {
    border: 0;
    background: none;
    color: var(--c2-accent-dark);
    text-decoration: underline;
    cursor: pointer;
    padding: 0;
    font: inherit;
}

/* ---------- Grille : colonne unique + recapitulatif ---------- */

#calc2-widget .calc2-grid,
#calc-stricker .calc2-grid {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 320px;
    gap: 28px;
    align-items: start;
}

#calc2-widget .calc2-col { min-width: 0; }
#calc-stricker .calc2-col { min-width: 0; }

/* ---------- Sections ---------- */

#calc2-widget .calc2-sec { margin: 0 0 30px; }
#calc-stricker .calc2-sec { margin: 0 0 30px; }

/* ---------- En-tete de section = le rail ----------
   Le rail porte le TITRE, pas le contenu : c'est un separateur de section
   avec son intitule dedans, pas un cadre autour des options. Les jeux
   d'options restent sur blanc, ils respirent.
   Filets haut et bas qui s'estompent aux extremites + halo central.
   Pour tester la variante verte : --c2-rail-glow: 15 185 48 et alpha 0.05.
   Reserve : le vert porte deja la selection, un halo vert partout dilue
   ce signal. */

#calc2-widget .calc2-rail,
#calc-stricker .calc2-rail,
#calc2-widget .calc2-sec-head,
#calc-stricker .calc2-sec-head,
.calc-sel .calc2-sec-head {
    /*  TEINTE NAVY, PAS APLAT NAVY — valeurs communes aux DEUX calculateurs
        depuis le 2026-10-03.

        Le navy franc du site (#000954) a ete essaye puis abandonne sur le
        panneau de prix ; l'historique est plus bas dans ce fichier. Le probleme
        n'etait pas la teinte mais la VALEUR : un aplat sombre dans une page
        claire devient le point le plus contraste de l'ecran, et l'oeil y
        revient meme quand on lit ailleurs. L'effet croit avec le nombre
        d'occurrences — une fiche a quatre emplacements de marquage porte six
        rails ou plus, contre un seul panneau de prix.

        D'ou des filets de 1 px a valeur claire, simplement desatures vers le
        navy, et un halo navy tres dilue : l'identite sans la dominance.

        UNE SEULE DECLARATION pour les deux racines. Elle a d'abord existe en
        surcharge #calc-stricker par-dessus un gris neutre ; les deux
        calculateurs partageant la meme valeur, un bloc suffit — et deux blocs a
        specificite egale, c'est l'ordre du fichier qui tranche, donc une
        occasion de se tromper en silence. */
    /*  DEUX LEVIERS DISTINCTS, et un seul est dangereux.

        La VALEUR (clair/sombre) est celle qui fait dominer : c'est elle qui a
        fait abandonner le navy plein. La SATURATION, elle, ne coute rien — on
        peut rendre le bleu franc sans qu'il capte l'oeil, tant qu'il reste
        clair.

        Premier reglage (196 202 224) : trop desature, il lisait argent bleute
        plutot que bleu. Ici on garde la meme luminosite et on remonte la
        chroma. Pour regler a l'oeil : ecarter B de R/G rend le bleu plus
        franc, baisser les trois ensemble assombrit — et c'est ce dernier geste
        qu'il faut eviter.                                                    */
    --c2-rail-line: 182 192 232;
    --c2-rail-glow: 0 9 84;
    --c2-rail-glow-alpha: 0.07;
    --c2-rail-fade: 12%;

    background-image:
        linear-gradient(to right,
            rgb(var(--c2-rail-line) / 0) 0%,
            rgb(var(--c2-rail-line) / 1) var(--c2-rail-fade),
            rgb(var(--c2-rail-line) / 1) calc(100% - var(--c2-rail-fade)),
            rgb(var(--c2-rail-line) / 0) 100%),
        linear-gradient(to right,
            rgb(var(--c2-rail-line) / 0) 0%,
            rgb(var(--c2-rail-line) / 1) var(--c2-rail-fade),
            rgb(var(--c2-rail-line) / 1) calc(100% - var(--c2-rail-fade)),
            rgb(var(--c2-rail-line) / 0) 100%),
        radial-gradient(60% 80% at 50% 50%,
            rgb(var(--c2-rail-glow) / var(--c2-rail-glow-alpha)) 0%,
            rgb(var(--c2-rail-glow) / calc(var(--c2-rail-glow-alpha) * .62)) 56%,
            rgb(var(--c2-rail-glow) / 0) 100%);
    background-repeat: no-repeat;
    background-size: 100% 1px, 100% 1px, 100% 100%;
    background-position: top, bottom, center;
}

#calc2-widget .calc2-sec-head,
#calc-stricker .calc2-sec-head,
.calc-sel .calc2-sec-head {
    display: flex;
    align-items: center;
    gap: 10px;
    margin: 0 0 18px;
    padding-block: 14px;
}

#calc2-widget .calc2-sec-title,
#calc-stricker .calc2-sec-title,
.calc-sel .calc2-sec-title {
    /* copie de .page-title-item-box1 .title-txt */
    font-size: 2rem;
    font-weight: 700;
    color: var(--c2-heading);
    white-space: nowrap;
}

/* Le groupement est porte par le rail, pas par un trait : on ne garde qu'un
   espaceur pour repousser la valeur courante a droite. */
#calc2-widget .calc2-sec-rule { flex: 1; }
#calc-stricker .calc2-sec-rule,
.calc-sel .calc2-sec-rule { flex: 1; }

/* ---------- Rail : bloc en creux qui groupe un jeu d'options ----------
   Un trait fin ne groupe rien. Le rail donne une surface propre a chaque
   section : l'oeil voit un bloc, pas une rangee de boutons en vrac.
   Le halo tres discret vient du haut, comme une lumiere rasante. */

/* Le rail vit sur .calc2-sec-head (voir plus haut) : il decoupe les sections.
   Les jeux d'options restent sur blanc et gardent leur propre bordure quand
   ils en ont une — aucun cadre dans un cadre. */

#calc2-widget .calc2-sec-aside,
#calc-stricker .calc2-sec-aside,
.calc-sel .calc2-sec-aside {
    color: var(--c2-muted);
    white-space: nowrap;
}

/*  ════════════════════════════════════════════════════════════════════════
    `.btn-navy` — LE BOUTON D'ACTION SECONDAIRE DES PAGES PRODUIT — 2026-10-06.

    Navy plein au repos, vert au survol. Porte par « Détail » (rail de
    section, OBG et Stricker), « Modifier » (recapitulatif), le crayon des
    sous-cartes du panneau de prix et « Adapter mon logo » (maquette).

    Ils avaient chacun leur copie de la meme recette — 24, 26, 28 et 34 px,
    trois tailles de texte — ecrite au fil des correctifs. Le style vit
    desormais ICI, une fois ; les classes propres a chaque bouton ne portent
    plus que leur PLACE (flex, marge, alignement), jamais leur habillage.

    Pourquoi navy : dans le calculateur le VERT veut dire « choix fait », et
    l'ORANGE est le CTA secondaire du site. Le navy des rails est la seule
    teinte qui n'emprunte le sens de rien d'autre. Le vert ne vient qu'au
    survol : un seul a la fois, il ne dilue pas le signal de selection.

    NON SCOPE (ni #calc2-widget ni #calc-stricker) : le recapitulatif vit dans
    la section devis, la maquette dans son propre bloc. Couleurs ECRITES EN
    DUR pour la meme raison — une var --c2-* hors de sa portee rend la
    declaration invalide, voir [[feedback_css_var_portee_invalide]].

    Pour l'instant, pages produit seulement (bundles product_v2 et copy).
    `.btn-navy-sq` : variante carree, icone seule.                         */
.btn-navy {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    height: 26px;
    padding: 0 10px;
    border: 1px solid #000954;
    border-radius: 6px;
    background: #000954;
    color: #fff;
    font: inherit;

    /*  ⚠️ JAMAIS SOUS 1rem : la racine du site est a 10 px.
        Apres `font: inherit`, qui la remettrait a zero. */
    font-size: 1.2rem;
    font-weight: 600;
    line-height: 1;
    white-space: nowrap;
    cursor: pointer;
    transition: background-color .15s, border-color .15s, color .15s;
}

.btn-navy:hover,
.btn-navy:focus-visible {
    border-color: #0fb930;
    background: #0fb930;
    color: #fff;
}

.btn-navy:focus-visible {
    outline: 2px solid #0fb930;
    outline-offset: 2px;
}

/*  L'icone prend la couleur du bouton, quoi que dise une regle de son
    conteneur — voir l'icone navy sur navy du 2026-10-06 dans mockup.css. */
.btn-navy i { color: inherit; }

.btn-navy-sq {
    width: 26px;
    padding: 0;
}

/* Bouton « detail » — NOIR au repos, vert au survol.
   Historique : gris plat (invisible), vert plein (trop fort), vert dilue,
   puis gris clair sur fond clair — invisible a nouveau, le rail de l'en-tete
   etant lui-meme gris.

   Le noir tranche sur ce rail sans reprendre le vert, qui dans ce calculateur
   veut dire « choix fait » (filets de selection, libelles selectionnes,
   quantite personnalisee, bouton Appliquer). Six pastilles vertes au repos
   diluaient ce signal ; une seule sous le curseur ne le dilue pas.

   Effet de bord : uniformement noires, elles restent lisibles sans devenir des
   balises criardes, ce qui permet de garder la loupe collee a son titre plutot
   que de la deplacer en tete de ligne pour aligner la colonne. */
/*  ⚠️ HABILLAGE PORTE PAR `.btn-navy` (juste au-dessus) depuis le 2026-10-06.
    Ici, seulement sa place dans le rail.

    Historique de la couleur : le quasi-noir #091017 d'origine se confondait
    avec le titre de section voisin (noir, gras, 2rem) — deux masses sombres
    dont une seule cliquable. D'ou le navy.

    LARGEUR LIBRE avec libelle, et plus un carre a loupe : une loupe seule
    n'annonce pas ce qu'elle ouvre. Le libelle tient parce que le filet du
    rail est en flex: 1 et cede sa place. */
#calc2-widget .calc2-help,
#calc-stricker .calc2-help,
.calc-sel .calc2-help {
    flex: 0 0 auto;
}

#calc2-widget .calc2-help-t,
#calc-stricker .calc2-help-t,
.calc-sel .calc2-help-t {
    letter-spacing: 0.01em;
}

/* SUR MOBILE le libelle s'efface et le bouton redevient carre.

   L'en-tete de section est une rangee flex : titre, bouton, filet, valeur
   courante. Les trois premiers sont en nowrap, seul le filet cede. Sous
   ~575 px il n'y a plus rien a ceder, et « Marquage · Poche frontale » suivi
   de « Plus d'infos » pousse la valeur courante hors du rail.

   On garde l'icone : le title et le lecteur d'ecran portent toujours le
   libelle, et sur mobile le pouce explore plus volontiers qu'il ne lit. */
@media (max-width: 575px) {
    #calc2-widget .calc2-help-t,
    #calc-stricker .calc2-help-t,
    .calc-sel .calc2-help-t { display: none; }

    #calc2-widget .calc2-help,
    #calc-stricker .calc2-help,
    .calc-sel .calc2-help {
        width: 26px;
        flex: 0 0 26px;
        padding: 0;
    }
}

/* Le plus est un signe maigre : deux traits, aucune masse. A 1.3rem il
   disparaissait a cote du libelle en gras. On le remonte et on l'epaissit —
   c'est le seul glyphe du calculateur qui doive tenir seul sous 575 px, ou le
   libelle s'efface. */
#calc2-widget .calc2-help i,
#calc-stricker .calc2-help i,
.calc-sel .calc2-help i {
    font-size: 1.1rem;
    font-weight: 900;
}

/* ---------- Bouton de palier PORTANT UN VISUEL ----------
   Reserve au tiroir Modele : une coupe cintree ne se devine pas d'un libelle,
   elle se voit. C'est le seul endroit du calculateur ou l'image porte
   l'information plutot que de la decorer — les paliers de quantite et les
   options de marquage restent des boutons de texte.

   Classe A PART, et pas un enrichissement de .calc2-tier : celle-ci sert aussi
   aux quantites et aux marquages, qui n'ont pas d'image et n'ont aucune raison
   de changer de gabarit. Meme regle que pour .calc2-state, apprise le meme
   jour — on n'ajoute pas a une classe deja portee ailleurs. */
#calc2-widget .calc2-tier-media,
#calc-stricker .calc2-tier-media {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 6px;
    padding: 12px 10px;
}

#calc2-widget .calc2-tier-img,
#calc-stricker .calc2-tier-img {
    display: flex;
    align-items: center;
    justify-content: center;
    height: 64px;
    width: 100%;
}

#calc2-widget .calc2-tier-img img,
#calc-stricker .calc2-tier-img img {
    max-height: 100%;
    max-width: 100%;
    object-fit: contain;
}

/*  ════════════════════════════════════════════════════════════════════════
    OPTION ECARTEE PAR LA PALETTE DU LOGO — 2026-10-05.

    Elle n'est pas « indisponible » : elle ne correspond pas au nombre de
    couleurs du logo deposé. Deux consequences sur la forme.

    ⚠️ BARREE, ET PAS SEULEMENT GRISEE. Le gris seul se lit comme « en
    panne » ou « bientot » ; la barre dit qu'il y a eu un ARBITRAGE. C'est
    d'ailleurs la forme que le user a employee spontanement en annotant ses
    captures — on reprend son vocabulaire plutot que d'en inventer un.

    ⚠️ ELLE RESTE LISIBLE. Le prix et le libelle doivent se lire malgre la
    barre : l'acheteur compare encore, et une option ecartee aujourd'hui
    redevient disponible des qu'il transforme son logo. On baisse donc
    l'opacite sans descendre sous le seuil de lecture, et on ne cache rien.

    Le `title` pose par le JS dit POURQUOI et COMMENT en sortir — sans lui,
    une barre serait un refus muet.                                         */
#calc-stricker .calc2-tier.is-ko {
    position: relative;
    opacity: .55;
    border-color: var(--c2-border);
    background: var(--c2-surface);
    cursor: not-allowed;
}

#calc-stricker .calc2-tier.is-ko::after {
    content: "";
    position: absolute;
    left: 8%;
    right: 8%;
    top: 50%;
    height: 1px;
    background: #c0392b;
    transform: rotate(-11deg);
    pointer-events: none;
}

/*  ⛔ PAS D'EFFET DE SURVOL sur une option ecartee : un bouton qui reagit
    au passage de la souris promet qu'il va se passer quelque chose. */
#calc-stricker .calc2-tier.is-ko:hover {
    border-color: var(--c2-border);
    background: var(--c2-surface);
}

/*  MEME LANGAGE pour les CARTES du calculateur natif OBG (2026-10-14, moteur
    de maquette commun, phase B) : une technique que la palette du logo exclut
    est barree, lisible, inerte — son `title` dit pourquoi et comment en
    sortir (« Blanc du logo »). */
.calc2-card.is-ko {
    position: relative;
    opacity: .55;
    cursor: not-allowed;
}

.calc2-card.is-ko::after {
    content: "";
    position: absolute;
    left: 8%;
    right: 8%;
    top: 50%;
    height: 1px;
    background: #c0392b;
    transform: rotate(-11deg);
    pointer-events: none;
}

.calc2-card.is-ko:hover {
    border-color: var(--c2-border);
    box-shadow: none;
}

/*  EN ATTENTE DU LOGO (2026-10-21) : vue sans logo ni texte, seul « Aucun »
    vit. Grisee comme le bloc inerte Stricker (.calc2-mark-cards.is-inert),
    JAMAIS barree : rien n'est refuse, il manque juste le fichier. */
.calc2-card.is-wait {
    opacity: .72;
    cursor: default;
}

.calc2-card.is-wait:hover {
    border-color: var(--c2-border);
    box-shadow: none;
}

/* ---------- Hero produit ----------
   Aucune regle ici : le hero reutilise .page-hero-hub de page_items.css,
   la meme construction que les hubs Univers. Le panneau « bulle » facon DLE
   a ete essaye puis abandonne — sur fond clair il ne rendait pas. */

/* ---------- Produits similaires, bas de page ----------
   AUCUNE regle ici, volontairement. Le bas de page utilise Product_Large,
   la carte produit standard du site, exactement comme la route /2.

   Une version compacte propre au calculateur (.calc2-sim-item) a existe puis
   a ete retiree : elle rendait mal et, surtout, elle faisait diverger pour la
   seule page /p un item que /2, le Blog et les Univers partagent. La frontiere
   est la : le comparateur AU-DESSUS du calculateur a ses propres vignettes
   parce qu'il pilote le calculateur, le bas de page parle le vocabulaire du
   site. Si ces cartes doivent changer, c'est dans prd_card_large.css et pour
   tout le monde. */

/* ---------- Rangee Couleurs : visuel carre + pastilles ----------
   Le visuel n'a plus de bandeau a lui. Il vit ici, en carre, a gauche des
   pastilles : il change a la selection et s'ouvre en grand au clic. On gagne
   toute la hauteur de l'ancien bloc pour la meme information. */

#calc2-widget .calc2-colorrow,
#calc-stricker .calc2-colorrow {
    display: flex;
    align-items: center;
    gap: 20px;
}

#calc2-widget .calc2-visual,
#calc-stricker .calc2-visual {
    position: relative;
    flex: 0 0 124px;
    width: 124px;
    height: 124px;
    padding: 8px;
    border: 1px solid var(--c2-border);
    border-radius: var(--c2-radius-lg);
    background: var(--c2-surface);
    cursor: zoom-in;
}

#calc2-widget .calc2-visual:hover { border-color: var(--c2-border-strong); }
#calc-stricker .calc2-visual:hover { border-color: var(--c2-border-strong); }

#calc2-widget .calc2-visual img,
#calc-stricker .calc2-visual img {
    width: 100%;
    height: 100%;
    object-fit: contain;
}

/* Pastille loupe, coin bas-droit — signale que l'image s'agrandit. */
#calc2-widget .calc2-visual-zoom,
#calc-stricker .calc2-visual-zoom {
    position: absolute;
    right: 6px;
    bottom: 6px;
    width: 20px;
    height: 20px;
    border-radius: 50%;
    background: var(--c2-surface);
    border: 1px solid var(--c2-border);
}

#calc2-widget .calc2-visual-zoom::before,
#calc-stricker .calc2-visual-zoom::before,
#calc2-widget .calc2-visual-zoom::after,
#calc-stricker .calc2-visual-zoom::after {
    content: "";
    position: absolute;
    background: var(--c2-muted);
}

#calc2-widget .calc2-visual-zoom::before,
#calc-stricker .calc2-visual-zoom::before {
    left: 5px; top: 9px; width: 9px; height: 1px;
}

#calc2-widget .calc2-visual-zoom::after,
#calc-stricker .calc2-visual-zoom::after {
    left: 9px; top: 5px; width: 1px; height: 9px;
}

#calc2-widget .calc2-visual:hover .calc2-visual-zoom { border-color: var(--c2-accent); }
#calc-stricker .calc2-visual:hover .calc2-visual-zoom { border-color: var(--c2-accent); }
#calc2-widget .calc2-visual:hover .calc2-visual-zoom::before,
#calc-stricker .calc2-visual:hover .calc2-visual-zoom::before,
#calc2-widget .calc2-visual:hover .calc2-visual-zoom::after { background: var(--c2-accent-dark); }
#calc-stricker .calc2-visual:hover .calc2-visual-zoom::after { background: var(--c2-accent-dark); }

#calc2-widget .calc2-swatches,
#calc-stricker .calc2-swatches {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    min-width: 0;
}

@media (max-width: 575px) {
    #calc2-widget .calc2-colorrow { gap: 14px; }
    #calc-stricker .calc2-colorrow { gap: 14px; }
    #calc2-widget .calc2-visual { flex: 0 0 96px; width: 96px; height: 96px; }
    #calc-stricker .calc2-visual { flex: 0 0 96px; width: 96px; height: 96px; }
}

/* overflow reste VISIBLE ici : l'infobulle est un ::after de ce bouton, un
   overflow: hidden la couperait net. Le rognage rond du visuel est deja
   assure par le border-radius de .calc2-sw-flat / .calc2-sw-svg. */
#calc2-widget .calc2-sw,
#calc-stricker .calc2-sw {
    position: relative;
    width: 36px;
    height: 36px;
    padding: 0;
    border: 0;
    border-radius: 50%;
    background: none;
    cursor: pointer;
    box-shadow: 0 0 0 1px var(--c2-border-strong);
}

#calc2-widget .calc2-sw:hover { box-shadow: 0 0 0 1px var(--c2-muted); }
#calc-stricker .calc2-sw:hover { box-shadow: 0 0 0 1px var(--c2-muted); }

#calc2-widget .calc2-sw.is-on,
#calc-stricker .calc2-sw.is-on {
    box-shadow: 0 0 0 2px var(--c2-surface), 0 0 0 4px var(--c2-accent);
}

#calc2-widget .calc2-sw-flat,
#calc-stricker .calc2-sw-flat,
#calc2-widget .calc2-sw-svg,
#calc-stricker .calc2-sw-svg {
    display: block;
    width: 100%;
    height: 100%;
    border-radius: 50%;
    overflow: hidden;
}

/* ---------- Infobulle des pastilles ----------
   Elle n'est plus rendue ici. Le nom de la couleur passe par data-tip et la
   bulle commune du calculateur (tip2.css) : une seule bulle pour les pastilles
   produit, les encres du logo et les couleurs de texte.

   Ce bloc faisait le travail en ::after depuis data-color. Il tenait tant
   qu'il s'agissait d'un mot, mais un pseudo-element ne contient que du texte
   — donc pas le tableau de correspondances demande sur les couleurs — et se
   fait rogner par le premier ancetre en overflow: hidden. Il avait deja fallu
   une regle :first-child pour rattraper le debordement en bout de rangee. */

/* ---------- Quantite : paliers portant le prix ---------- */

/* Piste FIXE, pas 1fr. Avec auto-fit + 1fr les pistes s'etirent pour remplir
   la ligne : deux valeurs donnaient deux cartes a 50 % de large, sans rapport
   avec la longueur de leur libelle. auto-fill garde les pistes vides en fin de
   ligne, justify-content: start colle le tout a gauche.
   Concerne aussi les paliers de quantite, qui partagent cette classe — un
   produit a deux paliers avait le meme probleme. */
#calc2-widget .calc2-tiers,
#calc-stricker .calc2-tiers {
    display: grid;
    grid-template-columns: repeat(auto-fill, 132px);
    justify-content: start;
    gap: 8px;
}

/* PISTE ELARGIE pour les boutons portant un visuel (tiroir Modele).

   On elargit la GRILLE, pas le bouton : .calc2-tiers pose des pistes FIXES, et
   un bouton plus large que sa piste deborde sur son voisin au lieu de pousser
   la colonne. La largeur se decide ici.

   ⚠️ APRES le bloc ci-dessus, et pas avant : les deux pesent (1,1,0), donc
   c'est l'ordre du fichier qui tranche. Ecrit plus haut, ce bloc etait
   silencieusement repris par les 132 px — erreur faite puis corrigee le
   2026-10-03, pour la deuxieme fois dans la journee. */
#calc2-widget .calc2-tiers-media,
#calc-stricker .calc2-tiers-media {
    grid-template-columns: repeat(auto-fill, 162px);
}

#calc2-widget .calc2-tier,
#calc-stricker .calc2-tier {
    border: 1px solid var(--c2-border);
    border-radius: var(--c2-radius);
    background: var(--c2-surface);
    padding: 9px 4px;
    cursor: pointer;
    text-align: center;
    line-height: 1.3;
}

#calc2-widget .calc2-tier:hover { border-color: var(--c2-border-strong); }
#calc-stricker .calc2-tier:hover { border-color: var(--c2-border-strong); }

/* ETAT SELECTIONNE — une seule grammaire pour tout le calculateur :
   filet vert 2px + texte vert GRAS, jamais de fond plein.
   Deux raisons. D'abord l'uniformite : un fond plein est impossible sur les
   cartes qui contiennent un visuel a fond blanc (le carre blanc y ferait un
   trou), donc il aurait fallu deux langages de selection dans le meme widget.
   Ensuite le CTA : « Demander un devis » est le seul bloc vert plein de la
   page. Multiplier les aplats verts lui ferait concurrence. */
#calc2-widget .calc2-tier.is-on,
#calc-stricker .calc2-tier.is-on {
    border: 2px solid var(--c2-accent);
    padding: 8px 3px;
    background: var(--c2-surface);
}

#calc2-widget .calc2-tier-n,
#calc-stricker .calc2-tier-n {
    display: block;
    color: var(--c2-heading);
}

#calc2-widget .calc2-tier-p,
#calc-stricker .calc2-tier-p {
    display: block;
    color: var(--c2-muted);
}

#calc2-widget .calc2-tier.is-on .calc2-tier-n,
#calc-stricker .calc2-tier.is-on .calc2-tier-n,
#calc2-widget .calc2-tier.is-on .calc2-tier-p,
#calc-stricker .calc2-tier.is-on .calc2-tier-p {
    color: var(--c2-accent-dark);
    font-weight: 700;
}

/* Ligne « quantite precise » — alternative aux paliers, donc elle doit se
   lire comme une option offerte et non comme une mention de bas de bloc.
   Gris + colle aux cartes, elle disparaissait. Respiration verticale (py-3
   Bootstrap) + texte vert : elle se detache des paliers sans ajouter de
   cadre, et le vert la rattache au reste du vocabulaire de selection. */
#calc2-widget .calc2-qtyfree,
#calc-stricker .calc2-qtyfree {
    display: flex;
    align-items: center;
    gap: 8px;
    margin: 20px 0 0;
    padding: 1rem 0;
    color: var(--c2-accent-dark);
}

/* Le champ etait blanc sur blanc, donc invisible. Filet et fond vert tres
   dilues : il se voit sans crier, et il se rattache visuellement aux paliers
   dont il est l'alternative. */
#calc2-widget .calc2-qtyfree input,
#calc-stricker .calc2-qtyfree input {
    width: 104px;
    height: 38px;
    border: 1px solid rgba(15, 185, 48, .35);
    border-radius: var(--c2-radius);
    background: rgba(15, 185, 48, .05);
    padding: 0 10px;
    font: inherit;
    font-weight: 700;
    color: var(--c2-accent-dark);
}

#calc2-widget .calc2-qtyfree input:focus,
#calc-stricker .calc2-qtyfree input:focus {
    outline: none;
    border-color: var(--c2-accent);
    background: var(--c2-surface);
    box-shadow: 0 0 0 3px rgba(15, 185, 48, .14);
}

/* ERREUR — en dessous du minimum de commande. Rouge et gras : la saisie n'est
   pas servable en l'etat, et il faut que ca se voie. */
#calc2-widget .calc2-qty-hint,
#calc-stricker .calc2-qty-hint {
    color: #c0392b;
    font-weight: 700;
}

/* CONSEIL — le palier suivant est moins cher a la piece.

   CLASSE DISTINCTE, et c'est le correctif du 2026-10-03 : ce message
   reutilisait .calc2-qty-hint, donc le rouge d'erreur. Pose a cote du champ de
   quantite, « À 50 pièces : 3,93 € la pièce » se lisait comme un refus de
   saisie — l'acheteur croyait que le champ avait rejete sa valeur alors qu'on
   lui annoncait une ECONOMIE.

   Deux roles opposes ne peuvent pas partager un style : l'un dit « corrigez »,
   l'autre dit « vous pouvez mieux faire ». Vert accent, poids intermediaire :
   lisible, sans alarme. */
#calc2-widget .calc2-qty-nudge,
#calc-stricker .calc2-qty-nudge {
    color: var(--c2-accent-dark);
    font-weight: 600;
}

/* ---------- Lignes radio : variante, options, livraison ---------- */

#calc2-widget .calc2-rows,
#calc-stricker .calc2-rows {
    border: 1px solid var(--c2-border);
    border-radius: var(--c2-radius);
    overflow: hidden;
}

#calc2-widget .calc2-row,
#calc-stricker .calc2-row {
    display: flex;
    align-items: center;
    gap: 10px;
    width: 100%;
    border: 0;
    border-bottom: 1px solid var(--c2-border);
    background: var(--c2-surface);
    padding: 11px 14px;
    cursor: pointer;
    text-align: left;
    font: inherit;
}

#calc2-widget .calc2-row:last-child { border-bottom: 0; }
#calc-stricker .calc2-row:last-child { border-bottom: 0; }
#calc2-widget .calc2-row:hover { background: var(--c2-surface-alt); }
#calc-stricker .calc2-row:hover { background: var(--c2-surface-alt); }
#calc2-widget .calc2-row.is-on { background: var(--c2-surface); }
#calc-stricker .calc2-row.is-on { background: var(--c2-surface); }

#calc2-widget .calc2-radio,
#calc-stricker .calc2-radio {
    width: 16px;
    height: 16px;
    flex: 0 0 16px;
    border: 1px solid var(--c2-border-strong);
    border-radius: 50%;
    background: var(--c2-surface);
}

#calc2-widget .calc2-row.is-on .calc2-radio,
#calc-stricker .calc2-row.is-on .calc2-radio {
    border: 5px solid var(--c2-accent);
}

#calc2-widget .calc2-row-lbl,
#calc-stricker .calc2-row-lbl {
    flex: 1;
    color: var(--c2-heading);
}

#calc2-widget .calc2-row-p,
#calc-stricker .calc2-row-p {
    color: var(--c2-muted);
}

#calc2-widget .calc2-row.is-on .calc2-row-lbl,
#calc-stricker .calc2-row.is-on .calc2-row-lbl,
#calc2-widget .calc2-row.is-on .calc2-row-p,
#calc-stricker .calc2-row.is-on .calc2-row-p {
    color: var(--c2-accent-dark);
    font-weight: 700;
}

/* ---------- Cartes : marquage ---------- */

/* Piste FIXE, pas auto-fit : avec auto-fit les cartes s'etirent pour remplir
   la ligne, donc un attribut a 6 valeurs et un autre a 5 ne donnaient pas la
   meme largeur — Recto et Verso ne s'alignaient pas. En piste fixe, une carte
   fait toujours la meme taille et les rangees se superposent proprement.
   auto-fill (et non auto-fit) garde les pistes vides en fin de ligne. */
/* Piste de 172px, soit la largeur ou « Transfert quadri 2 faces identiques »
   tient sur deux lignes. A 110px, chaque mot prenait sa ligne : les libelles
   se lisaient en colonnes verticales et les cartes montaient a quatre lignes
   de texte, d'ou des rectangles etroits et hauts. La largeur est dictee par
   le libelle le plus long, pas par la vignette. */
#calc2-widget .calc2-cards,
#calc-stricker .calc2-cards {
    display: grid;
    grid-template-columns: repeat(auto-fill, 176px);
    justify-content: start;
    gap: 10px;
}

/* Hauteur FIXE egale a la largeur : la carte est un carre, quel que soit le
   nombre de lignes du libelle. Sans hauteur fixe, une valeur a une ligne et
   une valeur a deux lignes donnaient deux hauteurs differentes dans la meme
   rangee. Le texte long est tronque plutot que d'etirer la carte. */
#calc2-widget .calc2-card,
#calc-stricker .calc2-card {
    display: flex;
    flex-direction: column;
    height: 176px;
    border: 1px solid var(--c2-border);
    border-radius: var(--c2-radius);
    background: var(--c2-surface);
    padding: 0;
    overflow: hidden;
    cursor: pointer;
    /* Centre comme les paliers de quantite et les vignettes du comparateur :
       tout ce qui est cliquable dans le calculateur centre son libelle. */
    text-align: center;
    font: inherit;
}

#calc2-widget .calc2-card:hover { border-color: var(--c2-border-strong); }
#calc-stricker .calc2-card:hover { border-color: var(--c2-border-strong); }

/* Filet 2px vert + texte vert gras. Pas de compensation de padding a faire :
   la carte n'en a plus, et box-sizing: border-box absorbe le pixel. */
#calc2-widget .calc2-card.is-on,
#calc-stricker .calc2-card.is-on {
    border: 2px solid var(--c2-accent);
    background: var(--c2-surface);
}

#calc2-widget .calc2-card-body,
#calc-stricker .calc2-card-body {
    display: block;
    flex: 1 1 auto;
    min-height: 0;
    padding: 0 10px 10px;
    overflow: hidden;
}

/* 500 et non 700 : a 700 le libelle gagnait assez de largeur pour passer de
   deux a trois lignes, et la ligne de prix sortait de la carte a hauteur fixe.
   Le vert porte deja la selection, le gras n'a qu'a l'appuyer. */
#calc2-widget .calc2-card.is-on .calc2-card-n,
#calc-stricker .calc2-card.is-on .calc2-card-n,
#calc2-widget .calc2-card.is-on .calc2-card-p,
#calc-stricker .calc2-card.is-on .calc2-card-p {
    color: var(--c2-accent-dark);
    font-weight: 500;
}

/* Bandeau image a fond perdu : ni padding avant, ni marge apres. Les visuels
   sont detoures sur blanc, donc du padding autour ne produisait que du vide
   supplementaire autour d'un vide deja present dans l'image.
   Hauteur fixe et non aspect-ratio : un carre calcule sur la largeur de la
   carte mangeait toute la hauteur et repoussait le texte hors du carre.
   L'image reste carree d'elle-meme via object-fit: contain.

   Le visuel remplit le bandeau : le JS sert image_url(../../theme/css/items/calculator/400x400) et non
   image_thumb_url(../../theme/css/items/calculator/50x50). Avec la vignette, max-width/max-height plafonnaient
   sans jamais agrandir, donc l'image restait a 50px au centre d'un bandeau
   deux fois plus haut. */
#calc2-widget .calc2-card-img,
#calc-stricker .calc2-card-img {
    display: flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    height: 96px;
    width: 100%;
    margin: 0;
    background: var(--c2-surface);
    overflow: hidden;
}

/* 100% et non max-*: la source fait 400px, elle DOIT etre redimensionnee a la
   hauteur du bandeau. contain garde le carre et evite toute deformation. */
#calc2-widget .calc2-card-img img,
#calc-stricker .calc2-card-img img {
    width: 100%;
    height: 100%;
    object-fit: contain;
}

/* Deux lignes maximum : au-dela on tronque, sinon le libelle repousserait le
   prix hors de la carte a hauteur fixe. */
#calc2-widget .calc2-card-n,
#calc-stricker .calc2-card-n {
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
    color: var(--c2-heading);
}

#calc2-widget .calc2-card-p,
#calc-stricker .calc2-card-p {
    display: block;
    color: var(--c2-muted);
}

/*  CARTES REDUITES DANS LA MAQUETTE (calculateur natif, 2026-10-14) — user :
    « detail = taille actuelle / maquette = reduit ». La fente partage sa
    largeur avec le bilan de couleurs : a 176 px, sept techniques prenaient
    deux rangees hautes au-dessus de la scene. La popup Detail garde la
    grande taille (elle est faite pour comparer). */
#calc2-widget .mk2-sel-opts .calc2-cards {
    grid-template-columns: repeat(auto-fill, 128px);
    gap: 8px;
}

#calc2-widget .mk2-sel-opts .calc2-card { height: 128px; }

#calc2-widget .mk2-sel-opts .calc2-card-img { height: 62px; }

#calc2-widget .mk2-sel-opts .calc2-card-body { padding: 0 8px 8px; }

/* ---------- Livraison : selecteur de pays ---------- */

#calc2-widget .calc2-country,
#calc-stricker .calc2-country {
    width: 100%;
    height: 40px;
    border: 1px solid var(--c2-border-strong);
    border-radius: var(--c2-radius);
    padding: 0 10px;
    margin: 0 0 12px;
    font: inherit;
    color: var(--c2-heading);
    background: var(--c2-surface);
}

/* ---------- Recapitulatif ---------- */

/* ---------- Panneau de prix : carte a trois bandes ----------
   Bandes haute et basse en vert tres dilue, corps blanc. Pas de rail ici,
   volontairement : le calculateur utilise deja un halo gris pour ses
   separateurs de section, et du gris pose sur du gris ne separe rien.

   Historique des essais : navy #000954 (en-tete du site) puis #091017 (pied
   de page). Les deux ont ete abandonnes. Le probleme n'etait pas la teinte
   mais la VALEUR : un aplat sombre au milieu d'une page en blanc et teintes
   claires est le point le plus contraste de l'ecran, donc l'oeil y revient
   sans arret, meme quand on lit ailleurs. Le panneau doit etre trouvable,
   pas dominant.

   Le vert retenu (#f2faf4) est plus clair que le fond du bouton loupe : les
   bandes ne sont pas des actions, elles delimitent. Le rapport tient —
   loupe plus soutenue que le panneau, filet vert plein pour la selection. */

#calc2-widget .calc2-summary,
#calc-stricker .calc2-summary {
    /* Bandeaux GRIS, pas verts.

       Le vert signale la selection dans tout le calculateur — palier de
       quantite actif, pastille choisie, onglet de vue courant. Un bandeau vert
       qui ne se selectionne pas fait donc une promesse fausse, et il isolait
       visuellement le panneau au milieu d'une page batie sur des rails et des
       aplats gris.

       Memes valeurs que les en-tetes de carte de la maquette et de marquage :
       les trois doivent se lire comme un seul ecran. D'ou le passage, le
       2026-10-03, d'un gris neutre (#fafafa / #ededed) aux variables communes
       desaturees vers le navy des rails — un gris parfaitement neutre a cote
       de filets bleutes se voit comme une couleur de plus. */
    --c2-panel-band: var(--c2-surface-head);
    --c2-panel-line: var(--c2-line-head);

    position: sticky;
    top: 20px;
    border: 1px solid var(--c2-border);
    border-radius: var(--c2-radius-lg);
    background: var(--c2-surface);
    overflow: hidden;
}

/* --- En-tete : le total --- */
#calc2-widget .calc2-sum-head,
#calc-stricker .calc2-sum-head {
    background: var(--c2-panel-band);
    border-bottom: 1px solid var(--c2-panel-line);
    padding: 16px 18px;
}

#calc2-widget .calc2-sum-lbl,
#calc-stricker .calc2-sum-lbl {
    display: block;
    color: var(--c2-muted);
    text-transform: uppercase;
    letter-spacing: 0.04em;
}

#calc2-widget .calc2-sum-val,
#calc-stricker .calc2-sum-val {
    /* meme echelle que les titres de section — point de fixation du panneau */
    font-size: 2rem;
    display: block;
    line-height: 1.2;
    font-weight: 700;
    /* Le total suit son bandeau : sur fond gris, le vert n'etait plus un
       contraste mais le dernier reste d'un code couleur qu'on vient de
       retirer. Il reste le plus gros caractere du panneau — c'est la TAILLE
       qui en fait le point de fixation, pas la teinte. */
    color: var(--c2-heading);
}

/* --- Corps : le detail --- */
#calc2-widget .calc2-sum-body { padding: 14px 18px 16px; }
#calc-stricker .calc2-sum-body { padding: 14px 18px 16px; }

#calc2-widget .calc2-sum-rows { margin: 0 0 12px; }
#calc-stricker .calc2-sum-rows { margin: 0 0 12px; }

#calc2-widget .calc2-sl,
#calc-stricker .calc2-sl {
    display: flex;
    justify-content: space-between;
    gap: 12px;
    padding: 4px 0;
    color: var(--c2-text);
}

/* LE MONTANT NE SE COUPE JAMAIS, le libelle si.

   Les deux spans sont des elements flexibles, donc tous deux retractables : un
   libelle long — « Manche · Sérigraphie Textile · 1 couleur », qui arrive des
   qu'on marque plusieurs emplacements — comprimait la valeur jusqu'a la plier,
   et « + » se retrouvait seul sur sa ligne, le montant sur la suivante.

   `flex: 0 0 auto` interdit a la valeur de retrecir, `min-width: 0` autorise le
   libelle a passer sous sa largeur de contenu — sans lui, un element flexible
   refuse de descendre sous son min-content et ne se replie pas. */
#calc2-widget .calc2-sl > span:first-child,
#calc-stricker .calc2-sl > span:first-child { min-width: 0; }

#calc2-widget .calc2-sl > span:last-child,
#calc-stricker .calc2-sl > span:last-child {
    flex: 0 0 auto;
    white-space: nowrap;
    text-align: right;
}

#calc2-widget .calc2-sl-sub,
#calc-stricker .calc2-sl-sub {
    color: var(--c2-muted);
    padding-left: 10px;
}

#calc2-widget .calc2-sl-strong,
#calc-stricker .calc2-sl-strong {
    border-top: 1px solid var(--c2-border);
    margin-top: 6px;
    padding-top: 8px;
    color: var(--c2-heading);
}

#calc2-widget .calc2-sl-ok { color: var(--c2-accent-dark); }
#calc-stricker .calc2-sl-ok { color: var(--c2-accent-dark); }

#calc2-widget .calc2-sum-ttc,
#calc-stricker .calc2-sum-ttc {
    display: flex;
    justify-content: space-between;
    gap: 12px;
    border-top: 1px solid var(--c2-border);
    padding: 12px 0 0;
    color: var(--c2-heading);
    font-weight: 700;
}

/* --- Pied : le code promo --- */
#calc2-widget .calc2-sum-foot,
#calc-stricker .calc2-sum-foot {
    background: var(--c2-panel-band);
    border-top: 1px solid var(--c2-panel-line);
    padding: 14px 18px;
}

/* Champ combine facon barre de recherche : l'input et le bouton ne forment
   qu'un seul bloc borde de vert, donc le champ se voit. */
#calc2-widget .calc2-promo,
#calc-stricker .calc2-promo,
.calc2-q-prix .calc2-promo {
    display: flex;
    border: 2px solid var(--c2-accent);
    border-radius: var(--c2-radius);
    overflow: hidden;
    background: var(--c2-surface);
}

#calc2-widget .calc2-promo input,
#calc-stricker .calc2-promo input,
.calc2-q-prix .calc2-promo input {
    flex: 1;
    min-width: 0;
    height: 40px;
    border: 0;
    padding: 0 12px;
    font: inherit;
    color: var(--c2-heading);
    background: transparent;
}

#calc2-widget .calc2-promo input:focus { outline: none; }
#calc-stricker .calc2-promo input:focus,
.calc2-q-prix .calc2-promo input:focus { outline: none; }

#calc2-widget .calc2-promo button,
#calc-stricker .calc2-promo button,
.calc2-q-prix .calc2-promo button {
    flex: 0 0 auto;
    height: 40px;
    padding: 0 20px;
    border: 0;
    background: var(--c2-accent);
    color: #fff;
    font: inherit;
    font-weight: 700;
    cursor: pointer;
}

#calc2-widget .calc2-promo button:hover { background: var(--c2-accent-dark); }
#calc-stricker .calc2-promo button:hover,
.calc2-q-prix .calc2-promo button:hover { background: var(--c2-accent-dark); }

#calc2-widget .calc2-promo-err,
#calc-stricker .calc2-promo-err,
.calc2-q-prix .calc2-promo-err {
    margin: 8px 0 0;
    color: #c0392b;
}

/* ---------- Portee des selecteurs ----------
   .calc2-modal*, .calc2-loader et .calc2-tbl NE SONT PAS scopees sous
   #calc2-widget, contrairement au reste du fichier.

   Raison : la popup « Plus d'informations » du hero est une modale NATIVE
   Bootstrap, donc hors du widget, et le partial qu'elle charge utilise ce meme
   loader et ces memes tableaux. Le prefixe calc2- porte seul l'isolation, ce
   qui suffit — aucune autre feuille du site n'emploie ce prefixe.

   .calc2-modal* n'a plus de consommateur hors du widget depuis le passage a
   Bootstrap ; la regle est laissee non scopee par coherence avec les deux
   autres, et parce que la rescoper ne gagnerait rien.
   ------------------------------------------------------------------------- */

/* ---------- Modale d'information ---------- */

.calc2-modal {
    display: none;
    position: fixed;
    inset: 0;
    z-index: 1060;
    background: rgba(0, 0, 0, 0.45);
    padding: 20px;
    overflow: auto;
}

.calc2-modal.is-open { display: flex; justify-content: center; }

/* Centrage vertical par « margin: auto 0 », PAS par align-items: center.
   Les deux centrent une boite courte, mais sur une boite plus haute que
   l'ecran align-items la centre quand meme et le haut sort du conteneur
   defilant : on ne peut plus atteindre l'en-tete ni la croix de fermeture.
   Les marges auto, elles, se rabattent a zero des que la place manque et la
   boite redevient simplement defilante. */
.calc2-modal-box {
    background: var(--c2-surface);
    border-radius: var(--c2-radius-lg);
    max-width: 820px;
    width: 100%;
    margin: auto 0;
}

/*  En-tete NAVY comme toutes les popups du site (page_items.css, .modal-header) :
    user, 2026-10-15. Arrondis du haut portes ici, la boite ne coupe pas. */
.calc2-modal-head {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 16px 20px;
    border-radius: var(--c2-radius-lg) var(--c2-radius-lg) 0 0;
    background: #000954;
}

.calc2-modal-title {
    flex: 1;
    color: #ffffff;
    font-weight: 700;
}

.calc2-modal-x {
    border: 0;
    background: none;
    line-height: 1;
    color: #ffffff;
    opacity: .85;
    cursor: pointer;
    padding: 0 4px;
}

.calc2-modal-x:hover { opacity: 1; }

.calc2-modal-body { padding: 20px; overflow-x: auto; }

/* ---------- Popup Couleurs : deux colonnes ----------
   7/5 comme demande. Le visuel porte la decision, le texte l'accompagne. */
/* minmax(0, Nfr) ET NON Nfr : une piste `fr` a un plancher implicite a
   `auto`, donc a la largeur min-content de son contenu. Un tableau ou un mot
   long dans la colonne de droite repoussait la colonne de gauche jusqu'a la
   faire disparaitre — l'image du coloris s'evaporait sans qu'aucune regle ne
   la cache. Avec un plancher a 0, le rapport 7/5 est tenu quoi qu'on y mette. */
#calc2-widget .calc2-pop,
#calc-stricker .calc2-pop {
    display: grid;
    grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
    gap: 20px;
    align-items: start;
    margin: 0 0 20px;
}

/* Visionneuse SEULE, quand le fournisseur ne donne aucune caracteristique a
   mettre en regard. Un panneau vide a cote de l'image lui volerait 5/12 de la
   largeur pour ne rien montrer.

   Doit etre porte par une racine, comme .calc2-pop juste au-dessus : a (0,1,0)
   contre (1,1,0), la regle ne passerait jamais. Et place APRES, les deux
   pesant alors (1,1,0) — a specificite egale, c'est l'ordre qui tranche. */
#calc2-widget .calc2-pop-solo,
#calc-stricker .calc2-pop-solo { grid-template-columns: 1fr; }

/* Filet leger et arrondi : les packshots sont detoures sur blanc, sans cadre
   ils flottent dans la modale, elle aussi blanche. */
#calc2-widget .calc2-pop-media,
#calc-stricker .calc2-pop-media {
    border: 1px solid var(--c2-border);
    border-radius: var(--c2-radius-lg);
    padding: 12px;
    background: var(--c2-surface);
}

/* Le tableau se resserre ici : en colonne etroite, le pas vertical du tableau
   pleine largeur creusait des trous entre les lignes. */
/* Pas horizontal a zero SAUF entre les deux colonnes : sans gouttiere, un
   libelle qui remplit sa cellule vient toucher sa valeur — « Conditionnement »
   et « 100 pieces par carton » se lisaient comme un seul mot. */
#calc2-widget .calc2-pop-side .calc2-tbl-kv td { padding: 7px 0; }
#calc-stricker .calc2-pop-side .calc2-tbl-kv td { padding: 7px 0; }
#calc2-widget .calc2-pop-side .calc2-tbl-kv td:first-child,
#calc-stricker .calc2-pop-side .calc2-tbl-kv td:first-child { padding-right: 16px; }

/* Donnee isolee : libelle et valeur sur la meme ligne, separes par deux points
   et une espace — pas deux colonnes de tableau. */
/* ---------- Phrase d'introduction d'une popup ----------
   Un encart d'information, pas une alerte : rien n'est en panne et rien n'est
   a corriger. D'ou le bleu des rails plutot que le rouge d'erreur ou le vert
   de selection, qui veulent tous deux dire autre chose dans ce calculateur.

   Le filet lateral plutot qu'un cadre complet : l'encart ouvre la lecture, il
   ne l'enferme pas. */
#calc2-widget .calc2-pop-intro,
#calc-stricker .calc2-pop-intro {
    margin: 0 0 18px;
    padding: 11px 14px;
    border-left: 3px solid rgb(0 9 84 / .35);
    border-radius: 0 var(--c2-radius) var(--c2-radius) 0;
    background: var(--c2-surface-head);
    color: var(--c2-text);
    line-height: 1.5;
}

#calc2-widget .calc2-pop-line,
#calc-stricker .calc2-pop-line {
    margin: 14px 0 0;
    color: var(--c2-heading);
}

#calc2-widget .calc2-pop-line span { color: var(--c2-muted); }
#calc-stricker .calc2-pop-line span { color: var(--c2-muted); }

/* Fiche de la valeur SELECTIONNEE — le paragraphe qui explique la technique.
   Detachee du reste par un filet vert a gauche : elle ne decrit pas l'attribut
   mais le choix en cours, et elle change a chaque vignette cliquee. */
#calc2-widget .calc2-pop-sel,
#calc-stricker .calc2-pop-sel {
    margin: 16px 0 0;
    padding: 12px 14px;
    border-left: 3px solid var(--c2-accent);
    background: var(--c2-panel-band, #f2faf4);
    border-radius: 0 var(--c2-radius) var(--c2-radius) 0;
}

#calc2-widget .calc2-pop-sel-n,
#calc-stricker .calc2-pop-sel-n {
    display: block;
    margin: 0 0 6px;
    color: var(--c2-accent-dark);
    font-weight: 700;
}

#calc2-widget .calc2-pop-sel p,
#calc-stricker .calc2-pop-sel p {
    margin: 0;
    color: var(--c2-text);
    font-size: 1.3rem;
}

/* max-height en vh : l'image doit tenir avec l'en-tete ET la rangee de
   vignettes, sinon la croix de fermeture sort du cadre sur ecran bas. */
#calc2-widget .calc2-zoom-img,
#calc-stricker .calc2-zoom-img {
    display: block;
    width: auto;
    max-width: 100%;
    max-height: 42vh;
    margin: 0 auto;
    object-fit: contain;
}

@media (max-width: 767px) {
    #calc2-widget .calc2-pop { grid-template-columns: 1fr; gap: 16px; }
    #calc-stricker .calc2-pop { grid-template-columns: 1fr; gap: 16px; }
    #calc2-widget .calc2-zoom-img { max-height: 34vh; }
    #calc-stricker .calc2-zoom-img { max-height: 34vh; }
}

/* ---------- Vignettes selectionnables de la popup Couleurs ----------
   Plus grandes que les pastilles de la rangee, et nommees : c'est tout
   l'interet du second niveau. Meme grammaire de selection que les cartes de
   marquage — filet vert 2px et libelle vert, jamais d'aplat, parce que les
   visuels sont detoures sur blanc et qu'un fond colore les couperait. */
#calc2-widget .calc2-picks,
#calc-stricker .calc2-picks {
    display: grid;
    grid-template-columns: repeat(auto-fill, 104px);
    justify-content: center;
    gap: 10px;
    margin: 0 0 20px;
}

#calc2-widget .calc2-pick,
#calc-stricker .calc2-pick {
    display: flex;
    flex-direction: column;
    height: 132px;
    padding: 0;
    border: 1px solid var(--c2-border);
    border-radius: var(--c2-radius);
    background: var(--c2-surface);
    overflow: hidden;
    cursor: pointer;
    text-align: center;
    font: inherit;
}

/* ---------- Vignettes SANS image ----------
   La vignette standard fait 132 px de haut sur une piste de 104 px : un visuel
   surmontant un nom court. Les marquages Stricker n'ont pas de visuel — leur
   AreaImage est renseigne sur 53 922 lignes mais aucun chemin du CDN ne
   repond — et leurs libelles sont longs (« Sérigraphie Textile · 2 couleurs »).
   Dans le gabarit standard : cartes aux trois quarts vides et libelles
   tronques a deux lignes.

   Pistes plus larges, hauteur libre, contenu centre. Le jour ou ces images
   deviennent joignables, retirer la classe suffit. */
#calc2-widget .calc2-picks-text,
#calc-stricker .calc2-picks-text {
    grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
    justify-content: stretch;
}

#calc2-widget .calc2-picks-text .calc2-pick,
#calc-stricker .calc2-picks-text .calc2-pick {
    height: auto;
    min-height: 62px;
    padding: 11px 12px;
    justify-content: center;
    gap: 4px;
}

#calc2-widget .calc2-picks-text .calc2-pick-n,
#calc-stricker .calc2-picks-text .calc2-pick-n {
    flex: 0 0 auto;
    padding: 0;
    -webkit-line-clamp: 3;
}

/* La variante large accepte un VISUEL, elle n'est pas « sans image ».
   Les modeles en ont un ; leurs libelles restent longs, donc ils ont besoin de
   la piste large plutot que du gabarit a 104 px. Hauteur fixe pour que les
   cartes s'alignent quand un modele n'a pas de photo. */
#calc2-widget .calc2-picks-text .calc2-pick-img,
#calc-stricker .calc2-picks-text .calc2-pick-img {
    flex: 0 0 auto;
    height: 84px;
    margin: 0 0 8px;
    display: flex;
    align-items: center;
    justify-content: center;
}

#calc2-widget .calc2-picks-text .calc2-pick-img img,
#calc-stricker .calc2-picks-text .calc2-pick-img img {
    max-height: 100%;
    max-width: 100%;
    object-fit: contain;
}

#calc2-widget .calc2-pick-p,
#calc-stricker .calc2-pick-p {
    color: var(--c2-muted);
    font-size: 1.2rem;
    line-height: 1.3;
}

#calc2-widget .calc2-pick.is-on .calc2-pick-p,
#calc-stricker .calc2-pick.is-on .calc2-pick-p {
    color: var(--c2-accent-dark);
    font-weight: 600;
}

/* Le prix se detache de la gamme de tailles posee juste au-dessus : c'est le
   chiffre qu'on compare d'une vignette a l'autre, pas une caracteristique de
   plus. Couleur du texte courant plutot que le gris attenue des libelles. */
#calc2-widget .calc2-pick-price,
#calc-stricker .calc2-pick-price {
    margin-top: 2px;
    color: var(--c2-heading);
    font-weight: 600;
}

#calc2-widget .calc2-pick:hover { border-color: var(--c2-border-strong); }
#calc-stricker .calc2-pick:hover { border-color: var(--c2-border-strong); }

#calc2-widget .calc2-pick.is-on { border: 2px solid var(--c2-accent); }
#calc-stricker .calc2-pick.is-on { border: 2px solid var(--c2-accent); }

#calc2-widget .calc2-pick-img,
#calc-stricker .calc2-pick-img {
    display: flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    height: 84px;
    width: 100%;
    background: var(--c2-surface);
    overflow: hidden;
}

#calc2-widget .calc2-pick-img img,
#calc-stricker .calc2-pick-img img {
    width: 100%;
    height: 100%;
    object-fit: contain;
}

#calc2-widget .calc2-pick-n,
#calc-stricker .calc2-pick-n {
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
    flex: 1 1 auto;
    min-height: 0;
    padding: 0 6px 6px;
    color: var(--c2-heading);
    font-size: 1.2rem;
    line-height: 1.3;
}

#calc2-widget .calc2-pick.is-on .calc2-pick-n,
#calc-stricker .calc2-pick.is-on .calc2-pick-n {
    color: var(--c2-accent-dark);
    font-weight: 500;
}

#calc2-widget .calc2-help-desc,
#calc-stricker .calc2-help-desc,
.calc-sel .calc2-help-desc {
    margin: 0 0 16px;
    color: var(--c2-text);
}

.calc2-tbl {
    width: 100%;
    border-collapse: collapse;
}

/* Texte reduit et gouttieres resserrees : la grille de paliers peut monter a
   dix colonnes (1 -> 5000), et a la taille du corps de texte le tableau
   debordait de la modale, imposant un scroll horizontal pour lire les gros
   volumes — exactement ce qu'on vient consulter. Un tableau dense est ici la
   bonne forme : on le balaie du regard, on ne le lit pas en continu. */
.calc2-tbl th,
.calc2-tbl td {
    padding: 8px 10px;
    border-bottom: 1px solid var(--c2-border);
    text-align: left;
    white-space: nowrap;
    font-size: 1.2rem;
}

/* Le tableau cle/valeur garde la taille du corps : deux colonnes, aucun
   probleme de largeur, et il se lit ligne a ligne.

   ET IL REVIENT A LA LIGNE. Le nowrap herite de .calc2-tbl ci-dessus est fait
   pour la matrice de prix — des nombres courts qu'on ne veut jamais voir se
   couper. Applique a du texte, il a produit le defaut du 2026-10-03 : la ligne
   « Entretien » du t-shirt (« Lavage en machine, Température max. 30°, Ne pas
   nettoyer a sec… ») tenait sur une seule ligne de 1 200 px.

   Le degat ne s'arretait pas a la barre de defilement. La largeur min-content
   de ce tableau gonflait la colonne de droite de .calc2-pop, et comme les
   pistes `fr` ont un plancher a auto, elle ECRASAIT la colonne de gauche :
   l'image du coloris disparaissait purement et simplement. */
.calc2-tbl-kv th,
.calc2-tbl-kv td {
    font-size: inherit;
    white-space: normal;
}

.calc2-tbl th {
    color: var(--c2-heading);
}

/* LA MATRICE DE PALIERS se resserre encore.

   Treize paliers chez Stricker, et chaque colonne porte « 10000+ » ou
   « 14,47 € » : a 10 px de gouttiere laterale, le tableau depasse les 930 px
   et deborde la modale, qui ouvre alors un defilement horizontal — juste sur
   ce qu'on vient y lire.

   6 px de chaque cote rendent une centaine de pixels sur la largeur totale.
   Avec la colonne de libelles retiree quand elle ne sert pas, l'ensemble
   tient. Le tableau reste dense, et c'est la bonne forme : on le balaie du
   regard pour comparer, on ne le lit pas en continu. */
.calc2-tbl-matrix th,
.calc2-tbl-matrix td { padding-inline: 6px; }

/* LES COLONNES DE PALIERS ONT TOUTES LA MEME LARGEUR.

   Sans plancher, chacune se dimensionne sur son contenu : « 1+ / 14,47 € »
   etait nettement plus etroite que « 10000+ », et la grille se lisait comme un
   accordeon. Une grille de prix se balaie du regard — un pas regulier aide a
   suivre la ligne, un pas irregulier la fait perdre. */
.calc2-tbl-matrix th,
.calc2-tbl-matrix td { min-width: 58px; }

/* LA COLONNE DE LIBELLES SE REPLIE, les colonnes de prix jamais.

   Le nowrap de .calc2-tbl est fait pour des nombres courts — « 10000+ »,
   « 64,33 € » — qu'on ne veut pas voir casser. Applique a un libelle comme
   « Sérigraphie Textile · 3 couleurs », il ouvre une colonne de 200 px sur un
   tableau qui compte deja treize colonnes de chiffres.

   DESIGNEE PAR SA CLASSE, pas par sa position. En td:first-child, la regle
   frappait la premiere colonne de PRIX des que la colonne de libelles etait
   retiree — ce qui arrive sur une matrice a une seule ligne — et cette
   colonne-la s'affichait deux fois plus large que ses voisines. */
.calc2-tbl-matrix .calc2-tbl-lbl {
    white-space: normal;
    min-width: 110px;
    max-width: 150px;
}

.calc2-tbl tr:nth-child(even) td { background: var(--c2-surface-alt); }

/* Le palier courant. APRES la regle paire, et pas avant : les deux selecteurs
   pesent (0,2,2), donc c'est l'ordre du fichier qui tranche — place plus haut,
   un palier pair n'aurait pas ete surligne.

   Le tableau de prix sert a situer son volume dans la degressivite ; sans
   repere, on le relit en comptant les lignes. */
.calc2-tbl tr.is-on td {
    background: var(--c2-accent-soft);
    font-weight: 600;
}

/* La meme chose en COLONNE, pour la matrice ou les paliers sont en tete.

   `tbody tr td.is-on` et non `td.is-on` : seul, il pese (0,2,1) et se fait
   battre par la regle paire a (0,2,2). Avec les deux elements intermediaires
   il monte a (0,2,3) et gagne quelle que soit sa position dans le fichier. */
.calc2-tbl th.is-on,
.calc2-tbl tbody tr td.is-on {
    background: var(--c2-accent-soft);
    font-weight: 600;
}

/* ---------- Marquage : une carte par technique ----------

   Les techniques d'un emplacement etaient rendues en rails pleine largeur —
   douze rails pour quatre emplacements, chacun suivi de deux ou trois boutons.
   L'ecran se parcourait a la molette sans qu'on puisse jamais comparer deux
   prix, alors que c'est exactement l'arbitrage : serigraphie ou transfert, a
   combien.

   auto-fill ET NON auto-fit : auto-fit replie les pistes vides et etire les
   cartes restantes sur toute la largeur. Un emplacement qui n'offre qu'une
   technique se retrouvait avec une carte de 1 200 px pour deux boutons. */
.calc2-mark-cards {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(255px, 1fr));
    gap: 12px;
    align-items: start;
}

/* ---------- Le detail « Marquage », panneau de REFERENCE (2026-10-04) ----------

   Il repond a « que puis-je faire sur ce produit », pas a « que vais-je
   commander ». Rien n'y engage le devis : seule la rangee d'emplacements est
   cliquable, et elle ne change que ce que le panneau montre. */
/* ===========================================================================
   LA VIGNETTE MODELE EST UN CONTENEUR, PLUS UN BOUTON — 2026-10-05
   ---------------------------------------------------------------------------
   Elle porte deux actions : choisir le modele (le voir) et le mettre au devis.
   Un <button> ne peut pas en contenir un autre — le navigateur defait
   l'imbrication en silence — donc l'enveloppe est un <div>, la selection un
   bouton qui couvre image et libelles, l'action de devis un bouton SOEUR.

   Le rembourrage descend sur le bouton de selection : garde sur l'enveloppe,
   il aurait laisse une bande morte entre le filet et la zone cliquable — on
   clique au bord de la carte et il ne se passe rien.
   ======================================================================== */
/*  Le message au-dessus des vignettes. Meme marge que la consigne de marquage
    (.calc2-mark-hint) : les deux jouent le meme role a deux endroits, et deux
    espacements differents pour une meme fonction se voient. */
#calc-stricker .calc2-models-hint { margin: 0 0 16px; }

/* ---------- La livraison, entre la maquette et le formulaire (2026-10-05) ----

   Elle ferme la configuration et ouvre la demande. Elle porte un FANION et non
   un en-tete de section : elle n'appartient a aucun produit, elle vaut pour le
   devis entier — comme « Votre devis en ligne » et « Recevez votre devis » qui
   l'encadrent. */
#calc-stricker .calc2-deliv-row,
#calc2-widget .calc2-deliv-row {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 10px;
    margin: 0 0 14px;
}

#calc-stricker .calc2-deliv-lbl,
#calc2-widget .calc2-deliv-lbl { color: var(--c2-muted); }

/*  Largeur bornee : un <select> etire sur toute la page donne une cible
    immense pour une liste courte, et eloigne le libelle de sa valeur. */
#calc-stricker .calc2-country,
#calc2-widget .calc2-country {
    flex: 0 1 320px;
    max-width: 100%;
    padding: 9px 12px;
    border: 1px solid var(--c2-border-strong);
    border-radius: var(--c2-radius);
    background: #fff;
    color: var(--c2-text);
    font: inherit;
}

/* ===========================================================================
   LE RECAPITULATIF DETAILLE — le dernier ecran avant de s'engager
   ---------------------------------------------------------------------------
   Il repete le total du panneau lateral, et c'est assume : les deux ne
   repondent pas a la meme question. Le panneau ACCOMPAGNE la configuration, on
   le consulte du coin de l'oeil ; celui-ci ARRETE — il montre de quoi le
   total est fait, juste avant qu'on donne ses coordonnees.

   ⚠️ NAVY, PAS VERT. Le concurrent pose un degrade vert soutenu ; sur cette
   page le vert est deja la couleur du CHOIX (filets de selection, CTA), et un
   aplat vert de cette taille entrerait en concurrence avec tout ce qui compte
   au-dessus. Le navy est la teinte d'identite du site — celle des rails, des
   filets de section, des en-tetes — et il n'a pas de fonction a voler.

   Teinte CLAIRE et non aplat sombre : c'est la lecon du panneau de prix, deja
   ecrite plus haut dans ce fichier — un aplat sombre dans une page claire
   devient le point le plus contraste de l'ecran, et l'oeil y revient meme
   quand on lit ailleurs.
   ======================================================================== */
/*  LE GRIS STANDARD DU TEMPLATE, et pas une teinte propre au calculateur.

    Ce panneau a d'abord porte un navy tres clair (#f7f9fd) invente pour lui.
    Il tenait, mais il n'existait nulle part ailleurs sur le site : une
    quinzieme nuance de clair dans une page qui en avait deja assez.

    Il reprend donc l'habillage des cartes `.policy-card-item` — fond
    `--bg-item-secondary`, filet #e2e2e2, rayon 10 px. C'est la forme que le
    template donne deja a « un bloc d'information pose dans une page
    blanche », et ce panneau n'est rien d'autre. Meme grammaire, meme page.

    ⚠️ `--bg-item-secondary` est declaree sur `:root` dans global.css, pas
    dans le jeu de tokens du calculateur : elle est donc en portee ici sans
    rien ajouter. Voir [[feedback_css_var_portee_invalide]] — une variable
    hors portee ne tombe pas en repli, elle invalide la declaration entiere.  */
#calc-stricker .calc2-rc,
.calc2-q-prix .calc2-rc {
    margin: 48px 0 0;
    border: 1px solid #e2e2e2;
    border-radius: 10px;
    background: var(--bg-item-secondary);

    /*  LE PADDING EST SUR LA CARTE, une seule fois.

        Il etait reparti sur les trois blocs interieurs, qui portaient chacun
        le leur et un filet pleine largeur : la carte n'etait pas une carte,
        c'etait une pile de bandes. D'ou le pied blanc qu'il a fallu retirer —
        une fois qu'on empile des bandes, les teinter separement devient
        tentant.

        Carte > filet > padding > contenu. Les separateurs interieurs
        s'arretent desormais au padding au lieu de toucher le bord, ce qui est
        la difference visible entre un encadre et un tableau.                */
    padding: 24px;

    /*  ⛔ PAS DE `max-width` — pleine largeur ASSUMEE, arbitre le 2026-10-05.

        Un plafond de 860 px a ete essaye : il reglait d'un coup la distance
        entre un libelle et son montant. Ecarte quand meme — la barre de
        livraison au-dessus et le formulaire en dessous sont pleine largeur,
        et une carte etroite au milieu se lisait comme un bloc mal place
        plutot que comme un choix.

        ⚠️ CE QUI REND CE CHOIX TENABLE, C'EST LE GUIDE POINTILLE (voir sa
        regle plus bas). Sur 1 400 px, « Prix unitaire de base » et
        « 4,47 € /pc » n'appartiennent visiblement plus a la meme ligne : le
        pointille est ce qui les rattache. Le retirer rouvrirait le probleme
        que le plafond devait resoudre — ce n'est pas une decoration, c'est la
        contrepartie de la pleine largeur.

        A ne pas confondre avec un probleme de taille de texte : le corps est
        a 1,4 rem, soit 14 px, la taille normale du site (`html` a 62,5 %,
        racine = 10 px). Rien n'est reduit ici, c'est la DISTANCE qui se
        traite.                                                              */
}

/*  Plus de padding propre : il vit sur la carte. */
#calc-stricker .calc2-rc-body,
.calc2-q-prix .calc2-rc-body { padding: 0; }

/*  ════════════════════════════════════════════════════════════════════════
    LE GRIS DES VALEURS, REDRESSE SUR CETTE CARTE — « textes reduit ».

    Mesure et non impression : `--c2-muted` (#8a8c93) sur le fond de carte
    #f3f3f3 donne un contraste de 3,0:1. Le minimum lisible pour du texte
    courant est 4,5:1 (WCAG AA). Ce gris a ete choisi pour du texte sur BLANC,
    ou il passe — la carte lui a retire la moitie de son ecart.

    #6a6d75 remonte a 4,7:1 sur ce meme fond. Il reste un gris de voix basse,
    il cesse d'etre un gris qu'on devine.

    ⚠️ CORRIGE ICI SEULEMENT, par une variable redefinie sur la carte. Changer
    `--c2-muted` a la racine aurait assombri tout le calculateur — y compris
    les dizaines d'endroits ou il vit sur blanc et ou il est juste. Un reglage
    de contraste se fait la ou le FOND a change, pas a la source.           */
#calc-stricker .calc2-rc,
.calc2-q-prix .calc2-rc { --c2-muted: #6a6d75; }

/*  DANS LA SECTION DEVIS, ENTRE LES CHAMPS ET LE BOUTON — 2026-10-06.

    Les 48 px de marge haute etaient calibres pour l'ancienne place, ou le
    recapitulatif ouvrait un bloc a lui seul apres la livraison. Ici il est
    pris entre deux elements d'un meme formulaire : il garde de l'air au-
    dessus pour se detacher des champs, et en gagne en dessous pour ne pas
    coller au bouton d'envoi.

    Trois classes, donc plus specifique que la regle generale (deux) : elle
    l'emporte ou qu'elle soit placee, pas par l'ordre du fichier.        */
.calc2-quote .calc2-q-prix .calc2-rc { margin: 24px 0 20px; }

/*  Le message « devis, pas commande » en tete de section : de l'air sous
    lui, il precede les champs et doit se lire avant eux. */
.calc2-quote .calc2-q-what { margin: 0 0 20px; }

/*  ════════════════════════════════════════════════════════════════════════
    LE RAIL — la grammaire commune de TOUT ce qui ouvre un bloc.

    Trois sortes de lignes vivent dans ce panneau : les en-tetes de produit,
    les lignes globales (port, remise), et les lignes de decomposition. Les
    deux premieres ont la meme nature — elles OUVRENT quelque chose — et
    portent donc la meme forme : un bandeau teinte, pleine largeur.

    Pose d'abord sur la seule livraison, etendu aux en-tetes de produit le
    2026-10-05 : « la logique veut qu'on mette un rail bleu marine sur chaque
    nom de produit aussi ». C'est juste — une forme qui distingue ne distingue
    que si elle s'applique a tout ce qui appartient a la meme categorie.
    Reservee a la livraison, elle faisait du port un cas special alors qu'il
    est un ouvreur de bloc comme les autres.

    ⛔ RIEN NE DEBORDE DU PADDING. Regle posee le 2026-10-05 : « ça devrait
    pas exister, un élément qui fait full width à l'intérieur de la carte ».

    Les bandeaux ont d'abord ete construits en debord (`margin-inline: -24px`
    + `padding-inline: 24px`) pour toucher les bords de la carte. Deux defauts,
    et le second suffit : la valeur de droite finissait collee au bord — c'est
    ce qui se voyait sur « incluse » — et le couplage au padding de la carte
    obligeait a tenir deux nombres d'accord dans deux regles differentes.

    Le bandeau occupe donc simplement LA ZONE DE CONTENU, comme tout le reste.
    Carte > filet > padding > contenu, sans exception. Il se distingue par sa
    TEINTE, ce qui suffisait depuis le debut — c'est le debord qui etait de
    trop, pas la couleur.

    ⚠️ VALEUR LITTERALE ET NON `var(--c2-rail-glow)`. Cette variable est
    declaree SUR `.calc2-rail` / `.calc2-sec-head`, qui ne sont pas des
    ancetres de ce bloc : elle n'est pas en portee ici. Une variable hors
    portee n'est pas un repli, elle invalide la declaration entiere — les
    bandeaux n'auraient aucun fond. Voir [[feedback_css_var_portee_invalide]].

    0 9 84 est le navy du site, a 6 % : une TEINTE, pas un aplat. Assez pour
    se distinguer du #f3f3f3 de la carte, trop peu pour devenir le point le
    plus contraste de l'ecran — la regle posee pour le rail le 2026-10-03.

    ⚠️ LA REGLE D'APPARTENANCE, posee par le user le 2026-10-05 : le rail va
    LA OU IL Y A UN BOUTON « MODIFIER ». Les deux vont ensemble parce qu'ils
    disent la meme chose — « ceci ouvre une section, et on peut y retourner ».

    C'est pour ca que `.calc2-rc-ok`, la ligne de remise, N'EN A PAS : elle
    n'a pas de bouton, parce qu'elle n'est pas une section. C'est une
    CONSEQUENCE du code promo saisi plus bas, pas un endroit ou l'on retourne.
    Lui donner un rail aurait promis un retour qui n'existe pas.

    En pratique : si un jour une ligne gagne un rail, elle doit gagner un
    bouton — et l'inverse. Une seule des deux est un bug d'affichage.       */
#calc-stricker .calc2-rc-p,
.calc2-q-prix .calc2-rc-p,
#calc-stricker .calc2-rc-glob,
.calc2-q-prix .calc2-rc-glob {
    /*  `padding-inline: 0` — utile pour l'en-tete de produit, qui n'est pas
        une `.calc2-rc-l`.

        ⚠️ IL NE SUFFIT PAS POUR LA LIGNE LIVRAISON, contrairement a ce que
        disait ce commentaire jusqu'au 2026-10-06. Elle est aussi une
        `.calc2-rc-l`, dont le raccourci `padding: 5px 0 5px 14px` est ecrit
        PLUS BAS dans le fichier : a specificite egale, il gagnait, et la
        ligne restait indentee de 14 px. La remise a zero qui fait foi pour
        elle est la regle a deux classes `.calc2-rc-l.calc2-rc-glob`, posee
        apres les lignes globales.                                          */
    padding-inline: 0;

    /*  ════════════════════════════════════════════════════════════════════
        UN HALO, PAS UN RECTANGLE — 2026-10-05.

        L'aplat teinte marchait, mais il ajoutait deux bords nets dans une
        carte qui n'est deja qu'angles droits : filet de carte, filets de
        separation, colonnes alignees, guides pointilles. Un rectangle de plus
        « casse le côté carré rectangle linéaire » dans le mauvais sens — il
        le renforce.

        Le halo dit la meme chose sans bord : la teinte est dense au centre et
        s'eteint vers les extremites, donc la ligne se detache sans qu'on
        puisse dire ou elle commence. C'est aussi la raison pour laquelle le
        debord n'est plus necessaire — un halo n'a pas de bord a aligner sur
        celui de la carte.

        ⚠️ C'EST LE MOTIF DE `.calc2-rail`, plus haut dans ce fichier, aux
        memes valeurs : navy 0 9 84, filets qui s'estompent sur 12 %, halo
        radial central. On reprend la forme que ce calculateur donne deja a
        « ce qui encadre » au lieu d'en inventer une seconde.

        ⚠️ VALEURS LITTERALES ET NON `var(--c2-rail-*)`. Ces variables sont
        declarees SUR `.calc2-rail` / `.calc2-sec-head`, qui ne sont pas des
        ancetres de ce bloc : hors de portee, elles n'invalideraient pas la
        couleur mais la declaration ENTIERE, et les rails n'auraient aucun
        fond. Voir [[feedback_css_var_portee_invalide]].                    */
    background-image:
        linear-gradient(to right,
            rgb(182 192 232 / 0) 0%,
            rgb(182 192 232 / 1) 12%,
            rgb(182 192 232 / 1) 88%,
            rgb(182 192 232 / 0) 100%),
        linear-gradient(to right,
            rgb(182 192 232 / 0) 0%,
            rgb(182 192 232 / 1) 12%,
            rgb(182 192 232 / 1) 88%,
            rgb(182 192 232 / 0) 100%),
        radial-gradient(60% 80% at 50% 50%,
            rgb(0 9 84 / .07) 0%,
            rgb(0 9 84 / .043) 56%,
            rgb(0 9 84 / 0) 100%);
    background-repeat: no-repeat;
    background-size: 100% 1px, 100% 1px, 100% 100%;
    background-position: top, bottom, center;
}

/*  L'en-tete d'un produit : son nom a gauche, sa quantite a droite. */
#calc-stricker .calc2-rc-p,
.calc2-q-prix .calc2-rc-p {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 12px;

    /*  Marge HAUTE seulement, et petite en bas : le bandeau doit toucher sa
        premiere ligne de decomposition — c'est ce qui dit qu'elles lui
        appartiennent. Un ecart symetrique aurait fait flotter le rail entre
        deux blocs sans dire auquel il se rattache.

        ⚠️ `margin-block` ET NON LE RACCOURCI `margin`. Un raccourci redefinit
        les QUATRE cotes : ecrit ici, il ecraserait silencieusement ce que la
        regle partagee du rail pose en longhand juste au-dessus. Le piege a
        deja coute un desalignement de 24 px entre les deux bandeaux, du temps
        ou ils debordaient. Il vaut pour toute propriete portee en longhand
        par une regle partagee.                                             */
    margin-block: 18px 2px;
    padding-block: 9px;

    font-weight: 600;
    color: var(--c2-heading);
}

/*  Le premier rail touche le padding haut de la carte : une marge l'aurait
    fait commencer 18 px plus bas que le bord, pour rien. */
#calc-stricker .calc2-rc-p:first-child,
.calc2-q-prix .calc2-rc-p:first-child { margin-top: 0; }

#calc-stricker .calc2-rc-n em,
.calc2-q-prix .calc2-rc-n em {
    font-style: normal;
    font-weight: 400;
    color: var(--c2-muted);
}

#calc-stricker .calc2-rc-q,
.calc2-q-prix .calc2-rc-q { color: var(--c2-muted); font-weight: 400; white-space: nowrap; }

/*  ════════════════════════════════════════════════════════════════════════
    LE GUIDE POINTILLE — relier le libelle a sa valeur.

    Ce panneau est pleine largeur : entre « Prix unitaire de base » a gauche
    et « 4,47 € /pc » a droite, il y a plus de mille pixels de vide. L'oeil
    perd la ligne en route et doit la retrouver a la hauteur — sur sept
    lignes, chaque valeur demande un effort.

    C'est le probleme que resolvent depuis toujours les cartes de restaurant
    et les sommaires : un filet pointille qui PORTE le regard. Rien de
    decoratif — c'est le seul element de ce panneau dont la fonction est
    d'etre suivi.

    ⚠️ RIEN DE TEL N'EXISTE AILLEURS DANS LE PROJET. Verifie avant de
    l'ecrire. Aucune autre page n'aligne des libelles et des montants sur
    cette largeur : le besoin est propre a ce panneau, la regle y reste donc
    bornee. Si un second endroit en a besoin un jour, c'est a ce moment-la
    qu'elle sortira d'ici.

    COMMENT : le libelle devient lui-meme une boite flex et pousse un
    `::after` vide qui prend tout l'espace restant. Pas de balise en plus
    dans le JS, et le pointille s'arrete exactement ou commence la valeur,
    quelle que soit la largeur.

    ⚠️ LE `gap` EST OBLIGATOIRE sur `.calc2-rc-n`. Ce libelle contient du
    texte ET un `<em>` — « THC ATHENS (Bleu) ». En passant le span en flex,
    l'espace entre les deux disparait : les noeuds texte deviennent des
    elements anonymes et l'espace blanc entre eux est absorbe. Le `gap` le
    rend explicite.                                                        */
/*  ════════════════════════════════════════════════════════════════════════
    LE RETOUR EN ARRIERE DEPUIS LE RECAPITULATIF.

    Ce panneau est le dernier ecran avant le formulaire : c'est la qu'on
    s'apercoit qu'on a oublie une couleur ou choisi le mauvais port. Sans ces
    boutons, il fallait remonter a l'aveugle et retrouver la bonne section.

    EN TETE DE LIGNE, dans le libelle lui-meme — donc AVANT le guide
    pointille, qui est pousse d'autant. Place a droite, pres de la valeur, il
    se serait lu comme une action sur le MONTANT.

    AVEC SON MOT, contrairement au crayon des sous-cartes du panneau lateral.
    Deux raisons, et la seconde est la vraie : la place existe ici, mais
    surtout ce bouton est le SEUL chemin de retour a ce stade, alors que
    celui du panneau double la section « Modeles ». Ce qui n'a pas d'autre
    chemin ne se devine pas.

    ⚠️ NAVY PLEIN AU REPOS, VERT AU SURVOL — c'est-a-dire EXACTEMENT le bouton
    « Détail » du rail (`.calc2-help`). Il a d'abord ete pose en filet blanc,
    discret, au motif qu'il y en a un par produit plus un pour la livraison et
    que quatre paves navy concurrenceraient le total.

    Mauvais arbitrage, corrige le 2026-10-05 : « bouton inline blanc n'est pas
    visible au depart ». Un bouton qu'on ne voit qu'en survolant n'existe pas
    pour qui ne survole pas — et celui-ci est le SEUL chemin de retour a ce
    stade de la page. La discretion est un luxe d'action secondaire ; ce
    bouton n'en est pas une ici.

    Le calculateur a deja tranche ce debat une fois, pour « Détail » : gris
    plat (invisible), vert plein (trop fort), gris clair sur rail gris
    (invisible a nouveau), puis navy. On reprend la conclusion au lieu de
    refaire le chemin.                                                      */
#calc-stricker .calc2-rc-pen,
.calc2-q-prix .calc2-rc-pen {
    flex: 0 0 auto;

    /*  Le libelle qui le contient aligne ses elements sur la LIGNE DE BASE,
        ce qui est juste pour du texte et faux pour un bouton : cale sur sa
        base, il remonterait d'un ou deux pixels selon la police. */
    align-self: center;

    /*  Habillage : `.btn-navy`, depuis le 2026-10-06. */
}

#calc-stricker .calc2-rc-n,
.calc2-q-prix .calc2-rc-n,
#calc-stricker .calc2-rc-l > span:first-child,
.calc2-q-prix .calc2-rc-l > span:first-child {
    display: flex;
    align-items: baseline;
    flex: 1 1 auto;
    min-width: 0;
    gap: 6px;
}

#calc-stricker .calc2-rc-n::after,
.calc2-q-prix .calc2-rc-n::after,
#calc-stricker .calc2-rc-l > span:first-child::after,
.calc2-q-prix .calc2-rc-l > span:first-child::after {
    content: "";

    /*  `align-self: center` et non `baseline` : une boite VIDE n'a pas de
        ligne de base, elle s'alignerait alors par son bord inferieur et le
        pointille descendrait sous le texte. */
    align-self: center;

    flex: 1 1 auto;

    /*  Jamais moins de 24 px, meme quand le libelle est long : un pointille
        de trois points se lit comme un defaut d'affichage, pas comme un
        guide. */
    min-width: 24px;

    border-bottom: 1px dotted #c3c6cc;
}

/*  ⛔ PAS DE GUIDE SUR LE TOTAL. Sa valeur fait 2 rem et pese assez pour
    etre trouvee seule ; un pointille l'aurait rangee parmi les lignes de
    detail, alors que tout le bloc existe pour la detacher. */
#calc-stricker .calc2-rc-tot > span:first-child::after,
.calc2-q-prix .calc2-rc-tot > span:first-child::after { content: none; }

/*  Une ligne de decomposition. Legerement indentee : elle appartient au
    produit qui la precede, et sans ce retrait trois produits a la suite
    forment une seule colonne indistincte. */
#calc-stricker .calc2-rc-l,
.calc2-q-prix .calc2-rc-l {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 12px;
    padding: 5px 0 5px 14px;
    color: var(--c2-text);
    font-variant-numeric: tabular-nums;
}

/*  LES LIGNES GLOBALES — port et remise. Elles ne dependent d'aucun produit :
    elles perdent le retrait, gagnent un filet, et sont mises EN GRAS.

    Le gras n'est pas une emphase decorative : c'est ce qui les distingue des
    lignes de decomposition juste au-dessus, qui appartiennent chacune a UN
    produit. Ici le port vaut pour la commande entiere — il se lit comme le
    total, pas comme un poste de plus dans la liste du dernier produit.

    ⚠️ PADDING SYMETRIQUE, et c'est le correctif du 2026-10-05. La regle
    posait `padding-left: 0` par-dessus le raccourci de .calc2-rc-l, qui
    laissait 5 px en haut et en bas : le texte collait au filet du haut, et
    les 16 px de marge du bloc Total s'ajoutaient en dessous. La ligne
    paraissait posee en haut d'une bande trop grande au lieu d'y etre centree.

    Le bloc Total perd donc sa marge superieure (voir sa regle) : la
    separation vit ICI, une seule fois, au lieu d'etre comptee deux fois.    */
#calc-stricker .calc2-rc-glob,
.calc2-q-prix .calc2-rc-glob,
#calc-stricker .calc2-rc-ok,
.calc2-q-prix .calc2-rc-ok {
    /*  ════════════════════════════════════════════════════════════════════
        LES LIGNES GLOBALES — port et remise.

        Ces lignes portaient le meme guide pointille que les lignes produit.
        Or le pointille a une fonction precise : relier un libelle au montant
        de SA ligne, dans une liste ou l'oeil se perd. Sur le port, qui est
        au-dessus de la liste et vaut pour la commande entiere, il ne reliait
        rien — il rangeait juste le port parmi les lignes dont il se
        distingue, et son trait se confondait avec le filet de separation.

        ⚠️ LE RAIL (fond teinte + pleine largeur) N'EST PAS ICI : il vit dans
        la regle partagee plus haut, qui ne prend QUE `.calc2-rc-glob` et les
        en-tetes de produit. `.calc2-rc-ok` reste donc une ligne bornee,
        simplement mise en gras — elle n'ouvre aucune section, elle constate
        une remise.                                                         */
    padding-block: 12px;
    font-weight: 600;
    color: var(--c2-heading);
}

/*  ⛔ ALIGNEMENT A GAUCHE — correctif du 2026-10-06, par la SPECIFICITE.

    La ligne livraison etait indentee de 14 px : son bouton « Modifier »
    demarrait plus a droite que celui du produit au-dessus, et que le libelle
    « Total » en dessous.

    Cause : ces lignes sont AUSSI des `.calc2-rc-l`, et la regle de
    `.calc2-rc-l` — `padding: 5px 0 5px 14px`, un raccourci — vit plus bas
    dans le fichier que la regle partagee du rail qui posait
    `padding-inline: 0`. A specificite egale l'ordre decide, et le dernier
    raccourci rendait les 14 px de retrait.

    On ne corrige PAS en deplacant une regle : le prochain ajout dans ce
    fichier referait le meme desordre sans rien signaler. On monte la
    specificite a DEUX classes, qui l'emporte sur `.calc2-rc-l` seule ou
    qu'elle soit placee. C'est la troisieme fois que ce piege tombe sur ce
    panneau ; la parade est la meme a chaque fois.                          */
#calc-stricker .calc2-rc-l.calc2-rc-glob,
.calc2-q-prix .calc2-rc-l.calc2-rc-glob,
#calc-stricker .calc2-rc-l.calc2-rc-ok,
.calc2-q-prix .calc2-rc-l.calc2-rc-ok {
    padding-inline: 0;
}

/*  ⛔ PAS DE GUIDE POINTILLE SUR LE RAIL. C'est tout l'objet du changement
    ci-dessus : le pointille appartient aux lignes de la liste, le bandeau
    n'en fait plus partie. Les deux traits se confondaient. */
#calc-stricker .calc2-rc-glob > span:first-child::after,
.calc2-q-prix .calc2-rc-glob > span:first-child::after,
#calc-stricker .calc2-rc-ok   > span:first-child::after,
.calc2-q-prix .calc2-rc-ok   > span:first-child::after { content: none; }

/*  PLUS DE FILET : le bandeau se separe par sa teinte. Ajouter un trait
    par-dessus aurait remis le « strait » que le rail devait justement
    remplacer. La marge ne vaut que pour la PREMIERE ligne globale — elle
    decolle le bandeau de la decomposition du dernier produit. Entre port et
    remise, rien : les deux appartiennent au meme bandeau et doivent se
    toucher. */
#calc-stricker .calc2-rc-glob,
.calc2-q-prix .calc2-rc-glob { margin-top: 18px; }

#calc-stricker .calc2-rc-ok,
.calc2-q-prix .calc2-rc-ok { color: var(--c2-accent-dark); }

/*  EMPLACEMENT SANS MARQUAGE dans le recapitulatif — 2026-10-06.

    Il doit ATTIRER L'OEIL sans ALARMER. Ne pas marquer la manche est le cas
    le plus frequent : rien de rouge, rien qui ressemble a une erreur.

    C'est la FORME qui le distingue : un mot en italique la ou toutes les
    lignes voisines portent un montant, precede d'une icone grise. Dans une
    colonne de chiffres, un mot se voit sans qu'on le cherche.

    Pas en voix basse (`--c2-muted`) : grise, la ligne se fondrait dans le
    decor et raterait precisement ce pour quoi elle existe. */
#calc-stricker .calc2-rc-none > span:last-child,
.calc2-q-prix .calc2-rc-none > span:last-child {
    font-style: italic;
    color: var(--c2-text);
    white-space: nowrap;
}

/*  LA LIGNE « MARQUAGES » REPLIABLE — 2026-10-06.

    Un <button>, parce qu'il agit (il deplie) et qu'il doit etre atteignable
    au clavier. Mais il se LIT comme une ligne du recapitulatif : meme
    retrait, meme guide pointille, montant a droite. Seuls la puce de compte
    et le chevron disent qu'il s'ouvre.

    Uniquement sous `.calc2-q-prix` : le recapitulatif ne vit plus que dans la
    section devis depuis ce jour. Les regles `#calc-stricker .calc2-rc*` qui
    precedent ne s'appliquent plus a rien — a retirer lors d'un nettoyage.  */
.calc2-q-prix .calc2-rc-mkh {
    width: 100%;
    border: 0;
    border-radius: 6px;
    background: none;
    font: inherit;
    text-align: left;
    cursor: pointer;
    transition: background-color .15s;
}

.calc2-q-prix .calc2-rc-mkh:hover,
.calc2-q-prix .calc2-rc-mkh:focus-visible {
    outline: none;
    background: rgba(0, 9, 84, .04);
}

/*  Le compte « 1/4 » en puce : c'est LUI qui doit accrocher l'oeil quand le
    detail est replie — il dit qu'il reste des emplacements sans marquage. */
.calc2-q-prix .calc2-rc-mkc {
    padding: 1px 7px;
    border-radius: 999px;
    background: #e6e8ee;
    color: #3f4045;
    font-size: 1.2rem;
    font-style: normal;
    font-weight: 600;
    white-space: nowrap;
}

/*  LE CHEVRON EN PASTILLE NAVY — 2026-10-06.

    Il etait en gris, nu, en bout de ligne : « on ne la voit pas ». Or c'est
    le seul signe que la ligne se deplie. Il reprend donc la grammaire des
    actions secondaires du calculateur (« Modifier », « Détail ») : navy plein
    au repos, vert au survol. Rond et petit pour rester un SIGNE accole au
    montant, pas un bouton concurrent du « Modifier » de l'en-tete.

    La pastille entiere tourne a l'ouverture : un rond est symetrique, seul
    le chevron change visiblement de sens. */
.calc2-q-prix .calc2-rc-mkh i {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 22px;
    height: 22px;
    margin-left: 8px;
    border-radius: 50%;
    background: #000954;
    color: #fff;

    /*  ⚠️ jamais sous 1rem : la racine du site est a 10 px. */
    font-size: 1.1rem;
    vertical-align: middle;
    transition: transform .15s, background-color .15s;
}

.calc2-q-prix .calc2-rc-mkh:hover i,
.calc2-q-prix .calc2-rc-mkh:focus-visible i { background: var(--c2-accent); }

.calc2-q-prix .calc2-rc-mkh.is-open i { transform: rotate(180deg); }

/*  Le detail deplie : un cran de retrait de plus, il appartient a la ligne
    « Marquages » au-dessus de lui. Trois classes, pour l'emporter sur le
    retrait general de `.calc2-rc-l` par la specificite, pas par l'ordre.  */
.calc2-q-prix .calc2-rc-mk .calc2-rc-l { padding-left: 28px; }

.calc2-q-prix .calc2-rc-mk[hidden] { display: none; }

#calc-stricker .calc2-rc-none > span:last-child i,
.calc2-q-prix .calc2-rc-none > span:last-child i {
    color: #b5b7bd;
    font-style: normal;
}

/*  LA VENTILATION PAR TAILLE — une ligne de DESCRIPTION dans une colonne de
    montants.

    Sa valeur est du texte (« M ×50, L ×60 ») la ou toutes ses voisines sont
    des euros : alignee comme elles, en chiffres tabulaires et en pleine
    couleur, elle se lisait comme un prix mal forme. On la met donc en voix
    basse — c'est un rappel de ce qu'on commande, pas un poste de cout.

    ⚠️ `white-space: normal` et non `nowrap` : une repartition sur six tailles
    deborde, et c'est le seul contenu de ce bloc qui puisse etre long.
    `text-align: right` garde l'alignement de la colonne quand elle passe a la
    ligne.                                                                   */
#calc-stricker .calc2-rc-spec > span:last-child,
.calc2-q-prix .calc2-rc-spec > span:last-child {
    color: var(--c2-muted);
    font-variant-numeric: normal;
    white-space: normal;
    text-align: right;
}

#calc-stricker .calc2-rc-tot,
.calc2-q-prix .calc2-rc-tot {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 16px;

    /*  NI MARGE NI FILET EN HAUT — c'est le bandeau qui precede qui separe.

        La marge a d'abord disparu parce qu'elle s'ajoutait au padding bas de
        la ligne globale et creusait un vide sous le port. Le filet l'a suivie
        quand cette ligne est devenue un rail teinte : un trait pose juste
        sous le bord d'un bandeau fait deux separations pour une seule
        frontiere, et c'est exactement le « strait » qu'on cherchait a
        enlever. Le padding suffit a donner l'air.                          */
    padding: 16px 0 0;
}

#calc-stricker .calc2-rc-tot-l,
.calc2-q-prix .calc2-rc-tot-l { color: var(--c2-muted); }

/*  La precision « 5 000 pièces (3,19 €/pc) » en voix basse : elle qualifie le
    total, elle ne le concurrence pas. */
#calc-stricker .calc2-rc-tot-l em,
.calc2-q-prix .calc2-rc-tot-l em { font-style: normal; }

#calc-stricker .calc2-rc-tot-v,
.calc2-q-prix .calc2-rc-tot-v {
    font-size: 2rem;
    font-weight: 700;
    line-height: 1.1;
    color: var(--c2-heading);
    font-variant-numeric: tabular-nums;
}

/*  PAS DE FOND PROPRE — le pied est GRIS comme le reste de la carte.

    Il portait un blanc, du temps ou la carte etait teintee navy : le blanc
    detachait le code promo du recapitulatif pour en faire une barre d'action.
    Mais une carte faite de deux couleurs se lit comme DEUX blocs colles, et
    le code promo n'est pas un ailleurs : il agit sur le total juste au-dessus.

    Un filet suffit a le separer. C'est la forme des cartes du template —
    `.policy-card-item` : un fond, un filet, un rayon, et rien d'autre.      */
#calc-stricker .calc2-rc-foot,
.calc2-q-prix .calc2-rc-foot {
    margin-top: 16px;
    padding: 16px 0 0;
    border-top: 1px solid #e2e2e2;
}

/*  LES OPTIONS DE LIVRAISON EN PASTILLES, pas en rangees.

    Elles sont DEUX au plus : une liste verticale leur donnait la forme d'un
    inventaire, avec un gros vide a droite. Cote a cote, elles se comparent
    d'un regard — ce qu'on vient faire ici.

    Meme grammaire de selection que le reste du calculateur : filet vert 2 px
    et libelle vert, jamais d'aplat. C'est un CHOIX qui part dans le devis, et
    le vert le dit partout ailleurs. */
#calc-stricker [data-deliv-opts],
#calc2-widget [data-deliv-opts] {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
}

#calc-stricker .calc2-deliv-pill,
#calc2-widget .calc2-deliv-pill {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 2px;
    padding: 10px 16px;
    border: 1px solid var(--c2-border);
    border-radius: var(--c2-radius);
    background: var(--c2-surface);
    color: var(--c2-text);
    cursor: pointer;
    font: inherit;
    text-align: left;
}

#calc-stricker .calc2-deliv-pill:hover,
#calc2-widget .calc2-deliv-pill:hover { border-color: var(--c2-border-strong); }

#calc-stricker .calc2-deliv-pill.is-on,
#calc2-widget .calc2-deliv-pill.is-on {
    border: 2px solid var(--c2-accent);
    padding: 9px 15px;
    color: var(--c2-accent-dark);
    font-weight: 600;
}

/*  Le prix sous le libelle et non a cote : il est ce qu'on compare, il doit
    tomber a la meme hauteur d'une pastille a l'autre quelle que soit la
    longueur du nom. */
#calc-stricker .calc2-deliv-p,
#calc2-widget .calc2-deliv-p {
    color: var(--c2-muted);
    font-weight: 400;
    font-variant-numeric: tabular-nums;
}

#calc-stricker .calc2-deliv-pill.is-on .calc2-deliv-p,
#calc2-widget .calc2-deliv-pill.is-on .calc2-deliv-p { color: var(--c2-accent-dark); }

#calc-stricker .calc2-country:focus-visible,
#calc2-widget .calc2-country:focus-visible {
    outline: 2px solid var(--c2-accent);
    outline-offset: 2px;
}

/*  LA VIGNETTE DE POPUP suit la meme refonte que celle de la rangee : un
    conteneur, un bouton de selection, un pied d'action. Les regles communes
    (.calc2-tier-act, .calc2-tier-add, .calc2-tier-del, .calc2-tier-flag) sont
    reutilisees telles quelles — c'est le MEME balisage, produit par la meme
    fonction `_tileAction`. On ne pose ici que ce qui tient a la popup. */
/*  ⚠️ SPECIFICITE ALIGNEE SUR `.calc2-picks-text .calc2-pick` (1,2,0).

    Cette regle-la pose `padding: 11px 12px` et `cursor: pointer` sur la carte.
    Depuis que la carte est un CONTENEUR et non un bouton, les deux sont
    nuisibles : le rembourrage laisse une bande morte au bord — on clique dans
    la carte et rien ne se passe — et le curseur promet un clic qui n'existe
    plus a cet endroit.

    Un selecteur plus court aurait perdu l'arbitrage sans rien dire. */
#calc-stricker .calc2-picks-text .calc2-pick {
    display: flex;
    flex-direction: column;
    min-height: 230px;
    padding: 0;
    border: 1px solid var(--c2-border);
    border-radius: var(--c2-radius);
    background: var(--c2-surface);
    overflow: hidden;
    cursor: default;
}

#calc-stricker .calc2-picks-text .calc2-pick.is-on { border: 2px solid var(--c2-accent); }

#calc-stricker .calc2-pick-b {
    position: relative;
    display: flex;
    flex: 1 1 auto;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 4px;
    width: 100%;
    padding: 12px 10px;
    border: 0;
    background: none;
    color: inherit;
    font: inherit;
    line-height: 1.3;
    text-align: center;
    cursor: pointer;
}

/*  HAUTEUR MINIMALE COMMUNE. Sans elle les cartes s'alignaient en escalier :
    un libelle sur deux lignes, une gamme de tailles plus courte, et le pied
    de chaque carte tombait a une hauteur differente. Or le pied porte une
    ACTION — une rangee de boutons en dents de scie se vise mal.

    `min-height` et non `height` : un libelle exceptionnellement long doit
    pouvoir pousser, pas deborder. */
#calc-stricker .calc2-tier-media {
    display: flex;
    flex-direction: column;
    min-height: 230px;
    padding: 0;
    cursor: default;
}

/*  Le corps prend toute la place disponible, ce qui POUSSE le pied en bas :
    c'est ce qui aligne les boutons entre cartes de contenus inegaux. */
#calc-stricker .calc2-tier-pick {
    position: relative;
    display: flex;
    flex: 1 1 auto;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 6px;
    width: 100%;
    padding: 12px 10px;
    border: 0;
    background: none;
    color: inherit;
    font: inherit;
    line-height: 1.3;
    text-align: center;
    cursor: pointer;
}

/*  LA COCHE SEULE, EN HAUT A DROITE — 2026-10-05, apres deux essais.

    1. Voile vert sur l'image : teintait un tiers de la carte, se lisait comme
       un badge collé sur la photo.
    2. Voile sur tout le corps : devenait bien l'etat DE LA CARTE, mais
       delavait les libelles et entrait en concurrence avec le filet vert de
       selection — deux aplats verts sur le meme objet.
    3. ✅ La coche seule. Elle dit la meme chose en un signe, a l'endroit ou
       l'on code conventionnellement un etat, et laisse la carte lisible.

    Le voile etait de l'insistance : le pied porte DEJA « ✓ Au devis » en
    toutes lettres. Repeter le meme message en aplat, en coche et en texte,
    c'est trois fois pour une information binaire.

    Le filet vert reste donc seul a signifier « je regarde », et la coche seule
    a signifier « au devis ». Un signe, un sens. */
#calc-stricker .calc2-tier-flag {
    position: absolute;
    top: 6px;
    right: 8px;
    color: var(--c2-accent-dark);
    font-size: 1.4rem;
    line-height: 1;
    pointer-events: none;
}

/*  Le pied d'action, separe par un filet : deux cibles dans une meme carte
    doivent SE VOIR comme deux cibles. Lecon de la bibliotheque de logos, ou
    deux actions superposees produisaient des suppressions accidentelles. */
#calc-stricker .calc2-tier-act {
    display: flex;
    flex: 0 0 auto;
    align-items: center;
    justify-content: center;
    gap: 8px;
    padding: 8px;
    border-top: 1px solid var(--c2-border);
}

/*  Le bouton d'ajout reprend .mk2-btn ; on ne pose ici que ce qui tient a sa
    place dans une carte etroite. */
#calc-stricker .calc2-tier-add {
    padding: 7px 10px;
    white-space: nowrap;
}

#calc-stricker .calc2-tier-badge {
    color: var(--c2-accent-dark);
    font-weight: 600;
}

/*  Le badge de la ligne native parle en voix basse : elle est au devis par
    nature, pas par un geste de l'acheteur. L'annoncer aussi fort que les
    autres ferait croire a une action qu'il aurait faite. */
#calc-stricker .calc2-tier-badge.is-fixed {
    color: var(--c2-muted);
    font-weight: 400;
}

/*  LA CORBEILLE EST ROUGE DES LE REPOS, icone sombre.

    Partout ailleurs dans le calculateur une action destructive se teinte au
    survol seulement. Ici elle doit se voir sans etre survolee : la carte porte
    deja un bouton d'ajout vert et un badge vert, et une croix grise s'y serait
    lue comme un element de decor. Un retrait qu'on ne distingue pas est un
    retrait qu'on clique par erreur.

    ⚠️ GRAMMAIRE REPRISE DE `.mk2-clear`, PAS INVENTEE. Le bouton de remise a
    zero de la maquette dit deja « action destructive » sur cette page : filet
    et icone rouges sur fond blanc, rouge plein au survol. En creer une
    deuxieme pour la meme fonction aurait demande a l'acheteur d'apprendre
    deux formes pour un seul sens.

    Deux essais ecartes avant d'y venir :
      - rouge tres clair (#fdecea) « pour ne pas crier » : ca ne donnait pas un
        bouton discret, ca donnait du SAUMON — une couleur sale qui
        n'appartient a aucune palette de la page. Diluer une teinte d'alerte ne
        la rend pas sobre, elle la rend fausse ;
      - rouge plein avec icone sombre : contraste suffisant sur le papier,
        sale a l'ecran.

    Au repos il se voit sans peser ; il ne « s'arme » qu'au survol. C'est le bon
    poids pour une action secondaire repetee sur quatre cartes. */
#calc-stricker .calc2-tier-del {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    border-color: #c0392b;
    background: #fff;
    color: #c0392b;
    transition: background-color .15s, color .15s;
}

#calc-stricker .calc2-tier-del:hover {
    background: #c0392b;
    color: #fff;
}

/* ---------- Le panneau de prix en N sections (2026-10-05) ----------

   Une section par ligne de devis. Celle qu'on REGARDE est ouverte, les autres
   repliees sur leur nom et leur total : on ne lit en detail que ce qu'on est
   en train de regler, et replier le reste empeche le pied de page de sortir de
   l'ecran des la troisieme ligne. */
/*  LA SOUS-CARTE : en-tete, corps, pied — une par ligne de devis.

    Elle existe MEME A UN SEUL PRODUIT : la forme du panneau ne doit pas
    dependre du nombre. Un rendu qui change de structure en passant de un a
    deux produits oblige a tenir deux versions, et c'est celle du cas rare
    qu'on oublie de corriger.

    ⛔ PLUS D'ACCORDEON. Les regles `:not(.is-open) { display: none }` ont ete
    retirees : tout s'affiche a la suite. Replier demandait un etat d'ouverture
    en plus de l'etat de selection, et cachait justement ce que ce panneau
    existe pour montrer — ce qu'on a compose sur les AUTRES produits. */
#calc-stricker .calc2-sc + .calc2-sc,
#calc2-widget .calc2-sc + .calc2-sc { margin-top: 10px; }

#calc-stricker .calc2-sc,
#calc2-widget .calc2-sc {
    border: 1px solid var(--c2-border);
    border-radius: var(--c2-radius);
    overflow: hidden;
}

/*  La carte du produit REGARDE se signale par son filet, pas par un fond :
    le panneau est deja une surface claire posee sur une surface claire, et un
    aplat de plus y ferait un troisieme niveau sans hierarchie. */
#calc-stricker .calc2-sc.is-current,
#calc2-widget .calc2-sc.is-current { border-color: var(--c2-accent); }

/*  Teinte du SECOND niveau : l'en-tete du panneau garde --c2-surface-head,
    celui de la sous-carte prend la valeur plus claire. Sans ca les deux
    bandeaux avaient le meme poids et rien ne disait lequel contenait l'autre. */
#calc-stricker .calc2-sc-h,
#calc2-widget .calc2-sc-h {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 8px 10px;
    background: var(--c2-surface-sub);
    border-bottom: 1px solid var(--c2-line-sub);
}

#calc-stricker .calc2-sc-n,
#calc2-widget .calc2-sc-n {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-weight: 600;
}

/*  Le retrait, a droite de l'en-tete. Meme grammaire que la corbeille des
    vignettes et que `.mk2-clear` : filet et icone rouges sur blanc, rouge
    plein au survol. Un seul sens, une seule forme, trois endroits. */
#calc-stricker .calc2-sp-x,
#calc2-widget .calc2-sp-x {
    display: inline-flex;
    flex: 0 0 auto;
    align-items: center;
    justify-content: center;
    width: 26px;
    height: 26px;
    padding: 0;
    border: 1px solid #c0392b;
    border-radius: 6px;
    background: #fff;
    color: #c0392b;
    font-size: 1.1rem;
    cursor: pointer;
    transition: background-color .15s, color .15s;
}

#calc-stricker .calc2-sp-x:hover,
#calc2-widget .calc2-sp-x:hover {
    background: #c0392b;
    color: #fff;
}

#calc-stricker .calc2-sc-b,
#calc2-widget .calc2-sc-b { padding: 4px 10px; }

/*  L'EDITION — une icone en tete d'en-tete, rien de plus.

    Historique court et utile : d'abord un bouton libelle « Modifier » sous
    les donnees de la carte, puis le meme en plus petit, puis ceci. Le bouton
    libelle occupait une RANGEE ENTIERE par carte dans un panneau large de
    300 px — a trois produits, trois pavés navy pour une action secondaire.
    Ici l'edition ne coute aucune hauteur : elle se loge dans un en-tete qui
    existait deja.

    MEME GRAMMAIRE ET MEME HAUTEUR QUE LA CORBEILLE (.calc2-sp-x, juste en
    dessous) : 26 px, filet et contenu colores sur blanc, couleur pleine au
    survol. Les deux boutons de la carte ont donc le meme poids et vivent aux
    deux bouts de l'en-tete, le nom du produit entre eux. Un mis-clic sur l'un
    ne peut pas atteindre l'autre : c'etait la contrainte posee des le depart.

    SANS LIBELLE, parce que ce bouton est un RACCOURCI et non un chemin : la
    section « Modeles » du calculateur bascule deja d'un produit a l'autre.
    Une action secondaire qui double un chemin existant ne prend pas de
    largeur. Le detail de l'arbitrage — et la mesure qui montre que le mot
    tenait — est dans le JS qui pose ce bouton.

    NAVY, et pas vert : dans ce calculateur le VERT signifie « choix fait »
    (palier actif, pastille retenue, onglet selectionne). L'orange est le CTA
    secondaire du site, le rouge est le retrait. Le navy est la seule teinte
    qui n'emprunte le sens de rien d'autre — meme raison que le bouton
    « Détail » du rail, plus haut dans ce fichier.                          */
#calc-stricker .calc2-sc-edit,
#calc2-widget .calc2-sc-edit {
    flex: 0 0 auto;

    /*  Habillage : `.btn-navy .btn-navy-sq` (carre de 26 px), depuis le
        2026-10-06. Historique conserve ci-dessous.

        ⚠️ NAVY PLEIN AU REPOS, VERT AU SURVOL — le bouton « Détail » du rail
        (.calc2-help), au gabarit de la corbeille.

        Pose d'abord en filet navy sur blanc, par symetrie avec la corbeille
        qui lui fait face. Corrige le 2026-10-05 : « bouton inline blanc
        n'est pas visible au depart ». Un bouton qu'on ne voit qu'en
        survolant n'existe pas pour qui ne survole pas.

        La symetrie avec la corbeille porte donc sur la TAILLE et la
        POSITION, plus sur le remplissage — et c'est juste : une corbeille se
        doit d'etre discrete au repos, une porte de retour non.             */
}

/*  Le pied porte le prix de CETTE ligne. Filet haut plutot qu'un fond : il
    conclut le corps, il ne repete pas l'en-tete. */
#calc-stricker .calc2-sc-f,
#calc2-widget .calc2-sc-f {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 8px;
    padding: 8px 10px;
    border-top: 1px solid var(--c2-border);
    font-weight: 600;
    font-variant-numeric: tabular-nums;
}

/*  L'etat de maquette se lit a l'icone, pas au mot : dans une colonne de
    valeurs chiffrees, « oui »/« non » demande une lecture, un signe non.

    ⚠️ LA CROIX EST GRISE, PAS ROUGE. Ne pas avoir de maquette n'est pas une
    erreur — c'est l'etat normal tant qu'aucun logo n'est depose. Une croix
    rouge transformerait un etat neutre en reproche. */
#calc-stricker .calc2-ok,
#calc2-widget .calc2-ok { color: var(--c2-accent-dark); }
#calc-stricker .calc2-ko,
#calc2-widget .calc2-ko { color: var(--c2-muted); }


/*  La remise est GLOBALE : filet plein pour la detacher des sections, et pas
    d'indentation — ce n'est pas une sous-ligne de produit. */
#calc-stricker .calc2-sl-glob,
#calc2-widget .calc2-sl-glob {
    margin-top: 6px;
    padding-top: 10px;
    border-top: 1px solid var(--c2-border);
}

#calc-stricker .calc2-pop-nav {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    margin: 0 0 16px;
}

/* ⚠️ PAS LE VERT DE LA SELECTION. Dans tout le calculateur le vert signifie
   « retenu, dans ton devis » ; ici l'emplacement actif n'est retenu de rien,
   il est seulement affiche. Meme distinction que les onglets de la maquette. */
#calc-stricker .calc2-pop-navb {
    padding: 6px 12px;
    border: 1px solid var(--c2-border);
    border-radius: 999px;
    background: #fff;
    color: var(--c2-muted);
    cursor: pointer;
    font: inherit;
}

#calc-stricker .calc2-pop-navb.is-on {
    background: var(--c2-heading);
    border-color: var(--c2-heading);
    color: #fff;
}

#calc-stricker .calc2-pop-loc {
    margin: 0 0 18px;
    color: var(--c2-muted);
}

#calc-stricker .calc2-pop-tech { margin: 0 0 22px; }

/*  ⚠️ 1.5rem et plus 1rem — correctif du 2026-10-06 : la racine est a
    10 px, le titre de technique sortait a 10 px, plus petit que les prix
    de sa propre grille. Voir [[feedback_rem_racine_10px]]. */
#calc-stricker .calc2-pop-tech h4 {
    margin: 0 0 8px;
    font-size: 1.5rem;
    font-weight: 600;
}

/*  LA ZONE EN IMAGE A GAUCHE DE LA GRILLE — 2026-10-06 (`_zoneFig`).
    Seulement si la figure existe (`has-zone`) : sans image, la grille
    reprend toute la largeur, sans colonne vide. */
#calc-stricker .calc2-pop-tech.has-zone {
    display: grid;
    grid-template-columns: 160px minmax(0, 1fr);
    column-gap: 20px;
    align-items: start;
}

#calc-stricker .calc2-pop-tech.has-zone > h4 { grid-column: 1 / -1; }

#calc-stricker .calc2-zone {
    position: relative;
    margin: 0;
    border: 1px solid var(--c2-border);
    border-radius: var(--c2-radius);
    overflow: hidden;
    background: #fff;
}

#calc-stricker .calc2-zone img {
    display: block;
    width: 100%;
    height: auto;
}

/*  Le cadre de pose : pointille vert sur halo blanc, lisible sur un textile
    clair comme fonce. Il DESIGNE, il ne remplit pas — le produit doit rester
    visible au travers. */
#calc-stricker .calc2-zone-box {
    position: absolute;
    border: 2px dashed #0fb930;
    box-shadow: 0 0 0 1px rgba(255, 255, 255, .8);
    background: rgba(15, 185, 48, .10);
    pointer-events: none;
}

#calc-stricker .calc2-zone-box.is-ellipse { border-radius: 50%; }

@media (max-width: 575px) {
    #calc-stricker .calc2-pop-tech.has-zone { grid-template-columns: 1fr; }
    #calc-stricker .calc2-zone { max-width: 160px; margin-bottom: 10px; }
}

/*  ---------- LA GRILLE TARIFAIRE, UNE SEULE FORME ----------

    `.calc2-pop-grid` a disparu : la popup de marquage et celle de la quantite
    passent desormais par le meme constructeur (_grilleTarifs) et portent la
    meme classe. Deux tableaux de prix qui ne se ressemblent pas font croire a
    deux baremes.

    PALIERS EN LIGNES, decision du 2026-10-05. En colonnes, treize paliers
    imposaient un defilement HORIZONTAL dans une modale qui defile deja
    verticalement — deux axes, on perd sa ligne des qu'on bouge. */
.calc2-tbl-grid {
    font-variant-numeric: tabular-nums;
}

.calc2-tbl-grid th,
.calc2-tbl-grid td {
    padding: 6px 10px;
    text-align: right;
}

/*  La colonne des quantites est un REPERE, pas une valeur : a gauche, et en
    voix basse pour que les prix restent ce qu'on lit. */
.calc2-tbl-grid thead th:first-child,
.calc2-tbl-grid tbody th {
    text-align: left;
    font-weight: 400;
    color: var(--c2-muted);
}

.calc2-tbl-grid thead th { font-weight: 600; }

/*  LA LIGNE DU PALIER COURANT. Teinte tres legere plutot qu'un aplat : elle
    doit se reperer en balayant sans devenir le point de fixation du tableau —
    ce qu'on vient y chercher, c'est la ligne d'A COTE. */
.calc2-tbl-grid tbody tr.is-on {
    background: var(--c2-surface-head);
}

.calc2-tbl-grid tbody tr.is-on th,
.calc2-tbl-grid tbody tr.is-on td {
    font-weight: 600;
    color: var(--c2-heading);
}

/* La surface sous le nom de l'option : c'est ce qui distingue deux tables
   tarifaires d'une meme technique, et sans elle on ne comprend pas pourquoi
   « 2 couleurs » peut couter moins cher qu'on l'attend. */
#calc-stricker .calc2-pop-sub {
    display: block;
    color: var(--c2-muted);
    font-weight: 400;
    /* 1,1 rem = 11 px. Racine du site a 10 px : .75rem rendait 7,5 px,
       illisible. Une sous-mention se tient sous le corps (1,4 rem), jamais
       a la moitie. */
    font-size: 1.1rem;
}

#calc-stricker .calc2-pop-vide { color: var(--c2-muted); }

/* ---------- La barre basse de prix (2026-10-04) ----------

   Elle prend le relais du panneau collant des que celui-ci sort du champ. Le
   panneau s'arretait en haut de la maquette, qui mesure trois ecrans : des
   qu'on travaillait dedans, le prix avait disparu.

   ⚠️ ELLE NE DOUBLE PAS LE PANNEAU, elle le remplace — un IntersectionObserver
   la montre exactement quand l'autre n'est plus visible. Deux totaux a l'ecran
   sont deux occasions de diverger. */
#calc-stricker .calc2-bar {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 1030;
    background: #fff;
    border-top: 1px solid var(--c2-border);
    box-shadow: 0 -4px 16px rgba(0, 0, 0, .08);
}

/*  ⚠️ PAS de `justify-content: space-between` — correctif du 2026-10-05.

    Il envoyait le total et la quantite dans deux coins opposes, separes par
    toute la largeur de l'ecran. Deux fragments aussi eloignes ne se lisent pas
    comme une meme information.

    Ils sont donc colles, alignes sur leur LIGNE DE BASE pour que « Total HT »,
    « 17,64 € » et « pour 3 pièces » reposent sur la meme ligne malgre trois
    tailles differentes — c'est ce qui les fait lire comme une phrase. */
#calc-stricker .calc2-bar-in {
    display: flex;
    align-items: baseline;
    gap: 10px;
    max-width: 1320px;
    margin: 0 auto;
    padding: 10px 16px;
}

#calc-stricker .calc2-bar-lbl {
    color: var(--c2-muted);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    /* 7,5 px avant — voir la note sur la racine a 10 px. */
    font-size: 1.1rem;
}

/*  Le nom du produit ferme la phrase, DANS le groupe.

    Il avait d'abord ete pousse a droite par `margin-left: auto`, au motif
    qu'il qualifie l'ensemble au lieu d'en etre un terme. Teste a l'ecran :
    ca reproduisait exactement le defaut qu'on venait de corriger — une
    information dans chaque coin. L'argument etait juste, le placement non.

    Tronque plutot que de pousser la barre sur deux lignes : la hauteur est ce
    qu'on protege ici. */
#calc-stricker .calc2-bar-prd {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    color: var(--c2-muted);
}

@media (max-width: 575px) {
    /* Sur mobile la phrase seule tient ; le nom du produit saute plutot que
       de manger la place du prix. */
    #calc-stricker .calc2-bar-prd { display: none; }
}

/* Le total reste le plus gros caractere de la barre, comme il l'est dans le
   panneau : c'est la meme information, elle garde le meme poids. */
#calc-stricker .calc2-bar-val {
    font-size: 1.5rem;
    font-weight: 700;
    line-height: 1.1;
    color: var(--c2-heading);
}

#calc-stricker .calc2-bar-qty {
    color: var(--c2-muted);
    white-space: nowrap;
}

/* La maquette hors grille occupe toute la largeur du bloc. Elle est le seul
   element de la page qu'on REGARDE, et elle etait bridee a ~70 % par une
   colonne qui n'existait que pour le panneau de prix — lequel a desormais sa
   barre. */
#calc-stricker [data-mockup-full] { width: 100%; }

/* ⚠️ L'ETAT INFORMATIF, avant qu'un logo soit depose — 2026-10-04.

   Le bloc est alors une DESCRIPTION : il annonce les techniques et leurs prix
   au palier courant, sans que rien soit cliquable. C'est volontairement le
   MEME rendu qu'a l'etat actif, pas un second balisage : deux rendus a tenir
   synchronises, c'est toujours celui qu'on oublie qui part en production.

   On attenue, on ne masque pas. Les prix restent parfaitement lisibles —
   c'est tout l'interet de cet etat : chiffrer sans rien fournir. */
.calc2-mark-cards.is-inert .calc2-tier {
    cursor: default;
    opacity: .72;
}

/* Sauf « Produit nu », qui n'est pas une option grisee mais l'etat COURANT de
   l'emplacement. L'attenuer ferait lire le bloc comme une panne. */
.calc2-mark-cards.is-inert .calc2-tier.is-on {
    opacity: 1;
}

.calc2-mark-cards.is-inert .calc2-tier:hover {
    border-color: var(--c2-border);
}

/*  Dire POURQUOI, sinon le grisage se lit comme un defaut. Et le dire comme une
    invitation : l'upload est un raccourci vers moins d'options et un prix plus
    juste, jamais une porte a franchir pour obtenir un prix.

    ⚠️ PAS DE font-size EN DESSOUS DE 1rem DANS CE PROJET. La racine du site est
    a 10 px — le `.875rem` d'origine rendait donc 8,75 px, plus petit que tout
    ce qui l'entoure. Le corps de texte du site est a 1,4 rem ; une note se
    tient au meme calibre ou juste en dessous, jamais a la moitie.

    L'habillage vient de Bootstrap (.alert-info), comme les messages du moteur
    de maquette : un seul vocabulaire pour « lis ceci » sur toute la page. On ne
    pose ici que la marge, qui depend de l'endroit. */
.calc2-mark-hint {
    margin: 0 0 16px;
}

/* Le rembourrage vit dans le CORPS, pas sur la carte : l'en-tete doit aller
   bord a bord. overflow: hidden pour que sa bande grise soit rognee par les
   coins arrondis — sans lui, elle deborde en deux angles carres. */
.calc2-mark-card {
    border: 1px solid var(--c2-border);
    border-radius: var(--c2-radius-lg);
    background: var(--c2-surface);
    overflow: hidden;
}

/* Bandeau gris leger : il separe le nom de la technique de ses options et
   donne aux cartes un point d'accroche commun quand il y en a quatre de front.

   ⚠️ SURTOUT PAS var(--c2-surface-alt) : elle vaut #ffffff dans ce
   calculateur, et volontairement — les visuels produit sont des carres blancs
   detoures, donc tout fond gris derriere eux se lit comme un cadre parasite.
   Un premier jet l'a utilisee : le bandeau etait blanc, invisible hormis son
   filet.

   Ici le gris est sans danger, parce qu'AUCUNE IMAGE ne s'y pose : ces cartes
   ne portent que du texte, faute de visuels de zone joignables chez Stricker.
   D'ou une variable dediee plutot qu'un detournement de celle du fond. */
.calc2-mark-card-h {
    margin: 0;
    padding: 10px 14px;
    background: var(--c2-surface-head);
    border-bottom: 1px solid var(--c2-line-head);
    color: var(--c2-heading);
    font-weight: 600;
    line-height: 1.25;
}

/* Deux colonnes : les libelles vont de « 1 couleur » a « Quadrichromie », et
   une seule colonne doublait la hauteur des cartes pour rien. */
.calc2-mark-opts {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 8px;
    padding: 14px;
}

/* Les boutons heritent de .calc2-tier, dont la largeur est normalement fixee
   par la piste de .calc2-tiers. Ici c'est cette grille qui la donne : sans
   width 100%, ils gardaient leur largeur de contenu et laissaient des trous.

   PORTE PAR LES DEUX RACINES, contrairement aux regles de carte au-dessus :
   .calc2-tier est elle-meme scopee (1,1,0). Une regle nue pesant (0,2,0)
   passe aujourd'hui parce que .calc2-tier ne declare pas de largeur — mais
   elle se ferait battre en silence le jour ou elle en declarerait une. */
#calc2-widget .calc2-mark-opts .calc2-tier,
#calc-stricker .calc2-mark-opts .calc2-tier {
    width: 100%;
    margin: 0;
}

/* ---------- Repartition par declinaison (calculateur fournisseur) ----------

   DES CASES EN LIGNE, PLUS UN TABLEAU. Six tailles en rangs donnaient une
   colonne haute et maigre qu'on parcourt du regard sans rien comparer, pour une
   information qui tient sur un trait. La doctrine « paliers en colonnes » vaut
   pour les tableaux de PRIX, qui se lisent ; ceci est un groupe de saisie.

   DES BULLES, EXACTEMENT SUR LA TRAME DES PALIERS — aligne le 2026-10-04.

   La premiere version posait un libelle nu au-dessus d'un champ de 86 px, dans
   une rangee flex. Resultat : trois gabarits differents empiles — boutons de
   palier a 132 px, boutons de taille a 132 px, cases de saisie a 86 px — et
   rien qui s'aligne verticalement d'une section a l'autre. L'ecran se lisait
   comme trois listes sans rapport.

   La case devient donc une BULLE : meme piste de grille, meme bordure, meme
   rayon, meme etat selectionne que les boutons du dessus. L'acheteur voit une
   seule famille d'objets, dont certains se cliquent et d'autres se remplissent.

   ⚠️ PORTEE #calc-stricker : cette grille n'existe que dans le calculateur
   fournisseur. Scoper lui donne la meme specificite qu'a .calc2-tiers juste
   au-dessus, donc un arbitrage lisible plutot qu'une course a l'ordre. */
#calc-stricker .calc2-rep {
    display: grid;
    grid-template-columns: repeat(auto-fill, 132px);
    justify-content: start;
    gap: 8px;
}

/*  Le <label> EST la bulle : cliquer n'importe ou dedans donne le focus au
    champ, sans une ligne de JS. C'est aussi pourquoi le curseur est `text` et
    non `pointer` — on ne selectionne pas, on saisit. */
/*  UNE CARTE EN TROIS ZONES : libelle en tete, nombre au centre, stock en pied.

    Le libelle est a GAUCHE et le nombre CENTRE, volontairement. La taille est
    une etiquette — on la lit en balayant la rangee, et des etiquettes centrees
    de longueurs differentes (« S » contre « XXXL ») ne s'alignent sur rien. Le
    nombre, lui, est la valeur : centre sous son trait, il se compare d'une
    carte a l'autre. */
#calc-stricker .calc2-rep-cell {
    display: flex;
    flex-direction: column;
    gap: 2px;
    margin: 0;
    padding: 8px 10px 7px;
    border: 1px solid var(--c2-border);
    border-radius: var(--c2-radius);
    background: var(--c2-surface);
    cursor: text;
    transition: border-color .15s ease;
}

#calc-stricker .calc2-rep-cell:hover { border-color: var(--c2-border-strong); }

/*  REMPLIE = SELECTIONNEE, et c'est la meme grammaire que partout : filet vert
    2 px, jamais d'aplat. Le padding compense le pixel de bordure en plus, sinon
    la bulle grandit d'un pixel a la premiere frappe et pousse ses voisines. */
#calc-stricker .calc2-rep-cell.is-on {
    border: 2px solid var(--c2-accent);
    padding: 7px 9px 6px;
}

/*  Le focus se voit sur la BULLE, pas sur le champ : un contour autour d'un
    champ deja sans bordure, a l'interieur d'une bulle bordee, faisait deux
    cadres concentriques. */
#calc-stricker .calc2-rep-cell:focus-within { border-color: var(--c2-accent); }

#calc-stricker .calc2-rep-lbl {
    color: var(--c2-heading);
    font-size: 1.25rem;
    font-weight: 700;
    line-height: 1.3;
    text-align: left;
}

/*  Le champ se fond dans la bulle : c'est elle qui porte le cadre. Largeur
    pleine et texte centre pour que le nombre tombe sous son libelle. */
/*  LE NOMBRE EST LA VALEUR DE LA CARTE — il doit peser plus que son libelle.

    A 1,6 rem en 600, il faisait la meme taille que « XS » juste au-dessus et se
    lisait comme une legende de plus. Or c'est la seule chose qu'on vient y
    ecrire et relire. Monte a 2 rem en 700, dans la couleur des titres : la
    carte a maintenant une hierarchie — etiquette, VALEUR, appoint. */
#calc-stricker .calc2-rep-qty {
    width: 100%;
    padding: 0;
    border: 0;
    background: transparent;
    color: var(--c2-heading);
    font-size: 2rem;
    font-weight: 700;
    text-align: center;
    line-height: 1.35;
}

/*  Le zero d'attente reste GRIS ET LEGER : c'est un emplacement vide, pas une
    quantite commandee. Le distinguer d'une vraie saisie evite de croire qu'on a
    deja reparti quelque chose. */
#calc-stricker .calc2-rep-qty::placeholder {
    color: var(--c2-border-strong);
    font-weight: 400;
}

#calc-stricker .calc2-rep-qty:focus { outline: none; }

/*  Les fleches natives de <input type=number> mangent la moitie de la bulle et
    n'apparaissent qu'au survol — un controle qui bouge sous le curseur. On tape
    un nombre, on ne l'incremente pas de 1 a 250. */
#calc-stricker .calc2-rep-qty::-webkit-outer-spin-button,
#calc-stricker .calc2-rep-qty::-webkit-inner-spin-button {
    -webkit-appearance: none;
    margin: 0;
}

#calc-stricker .calc2-rep-qty { -moz-appearance: textfield; }

/*  SOULIGNEMENT SOUS LE CHAMP. Sans lui, un nombre centre dans une bulle ne se
    distingue pas d'un nombre affiche : rien ne dit qu'on peut le changer. Le
    trait est la plus petite marque qui dise « ceci se saisit ». */
#calc-stricker .calc2-rep-qty {
    border-bottom: 1px solid var(--c2-border);
    padding-bottom: 2px;
}

#calc-stricker .calc2-rep-cell:focus-within .calc2-rep-qty {
    border-bottom-color: var(--c2-accent);
}

/*  LE STOCK SOUS LA BULLE — 9,5 px, gris, une seule ligne.

    Volontairement discret : c'est une information d'appoint, pas la decision.
    Elle n'apparait QUE si on la connait — une ligne vide a cet endroit se
    lirait comme « zero » alors qu'elle veut dire « on ne sait pas ». */
/*  LE PIED DE CARTE — toujours la, meme vide.

    min-height plutot qu'un contenu de remplissage : la place est reservee par
    la REGLE, pas par un caractere invisible qu'un lecteur d'ecran annoncerait.
    Sans elle, une taille sans stock donne une carte plus courte que sa voisine
    et la rangee se deforme — alors que l'absence d'information est le cas le
    plus frequent tant que la synchro n'est pas planifiee.

    La valeur suit la ligne du texte (0.95rem x 1.2) : la carte garde donc la
    meme hauteur qu'une carte renseignee, au pixel pres. */
#calc-stricker .calc2-rep-stock {
    display: block;
    min-height: 1.14rem;
    margin-top: 4px;
    /* 9,5 px avant — voir la note sur la racine a 10 px. */
    font-size: 1.2rem;
    line-height: 1.2;
    color: var(--c2-muted);
    text-align: center;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* ---------- Au-dela du stock : AMBRE, et surtout pas bloque ----------

   La quantite demandee depasse ce qui est disponible tout de suite. Ce n'est
   pas une erreur — c'est un CHANGEMENT DE REGIME : sous le stock on livre
   immediatement, au-dessus on produit sur reassort.

   D'ou l'ambre et non le rouge. Le rouge de cette feuille est reserve a ce qui
   EMPECHE (#c0392b, champ invalide, envoi bloque) ; ici rien n'empeche, et
   teindre en rouge une commande parfaitement vendable ferait reculer sur la
   plus grosse. Mesure a l'appui : plafonner aurait ferme les paliers >= 1 000
   sur 71,6 % des SKU. */
#calc-stricker .calc2-rep-cell.is-over {
    border-color: #f59e0b;
}

#calc-stricker .calc2-rep-cell.is-over.is-on {
    border: 2px solid #f59e0b;
    padding: 8px 3px;
}

#calc-stricker .calc2-rep-stock.is-over {
    color: #b45309;
    font-weight: 700;
}

/*  Le plafond de la selection, a cote de la saisie libre. Meme ton que les
    pieds de carte : une information d'appoint, pas la decision. */
#calc-stricker .calc2-qty-stock {
    margin-left: 10px;
    font-size: 1.1rem;
    color: var(--c2-muted);
}

#calc-stricker .calc2-qty-stock.is-over {
    color: #b45309;
    font-weight: 700;
}

#calc-stricker #calc-str-qty.is-over {
    border-color: #f59e0b;
}

/*  UNE TAILLE EN REASSORT RESTE UN CHOIX. On la teinte, on ne l'eteint pas :
    elle est vendable, simplement avec un autre delai. Le filet vert de la
    selection reste prioritaire — ce que l'acheteur a choisi doit se voir avant
    ce qu'il doit savoir. */
/* ---------- L'alerte de depassement ----------

   Encart ambre a filet lateral, meme geste que .calc2-pop-intro : il OUVRE la
   lecture, il ne l'enferme pas dans un cadre. Ce n'est pas une erreur a
   corriger, c'est une information a lire une fois.

   Fond tres dilue : l'encart apparait sous une grille deja chargee, et un
   aplat ambre franc y serait le point le plus contraste de l'ecran — pour un
   message qui ne demande aucune action.

   ⚠️ `.calc2-stock-alert` N'EXISTE PLUS (2026-10-06) : l'encart est devenu
   le bandeau `.calc2-msg.is-warn` de la pile ci-dessous, et son gabarit a
   ete etendu aux deux autres messages. */

/*  ════════════════════════════════════════════════════════════════════════
    LA PILE DE MESSAGES — 2026-10-06.

    Un seul gabarit pour les trois messages de la saisie : minimum non
    atteint, depassement de stock, palier suivant. C'est celui de l'ancien
    encart de stock (filet lateral, fond tres dilue), la TEINTE portant le
    role. Avant, deux d'entre eux etaient du texte nu colle a l'encart, et
    l'on avait des explications dans une section et pas dans l'autre.

    L'ESPACE vit sur la pile, pas sur les messages : 16 px au-dessus (ce qui
    precede — total, saisie libre — respire), 8 px entre deux bandeaux. Vide,
    elle ne prend aucune place.                                            */
#calc-stricker .calc2-msgs {
    display: flex;
    flex-direction: column;
    gap: 8px;
}

#calc-stricker .calc2-msgs:not(:empty) { margin-top: 16px; }

#calc-stricker .calc2-msg {
    padding: 11px 14px;
    border-left: 3px solid;
    border-radius: 0 var(--c2-radius) var(--c2-radius) 0;
    color: var(--c2-text);
    font-size: 1.2rem;
    line-height: 1.5;
}

#calc-stricker .calc2-msg.is-err  { border-left-color: #c0392b; background: rgb(192 57 43 / .06); }
#calc-stricker .calc2-msg.is-err strong  { color: #c0392b; }

#calc-stricker .calc2-msg.is-warn { border-left-color: #f59e0b; background: rgb(245 158 11 / .07); }
#calc-stricker .calc2-msg.is-warn strong { color: #b45309; }

#calc-stricker .calc2-msg.is-tip  { border-left-color: #0fb930; background: rgb(15 185 48 / .06); }
#calc-stricker .calc2-msg.is-tip strong  { color: var(--c2-accent-dark); }

#calc-stricker .calc2-size.is-over { border-color: #f59e0b; }
#calc-stricker .calc2-size.is-over .calc2-tier-p { color: #b45309; font-weight: 700; }
#calc-stricker .calc2-size.is-over.is-on { border-color: var(--c2-accent); }

.calc2-rep-sum {
    margin: 12px 0 0;
    color: var(--c2-heading);
}

/* ---------- Le mode inactif ----------

   GRISE, JAMAIS `disabled`. Un vrai disabled des deux cotes enferme l'acheteur :
   plus aucun geste ne permet de revenir dans l'autre mode. C'est la saisie
   elle-meme qui reprend la main, donc tout doit rester cliquable.

   Pas de pointer-events: none pour la meme raison. */
.calc2-sec.is-muted { opacity: .45; }

.calc2-sec.is-muted:focus-within,
.calc2-sec.is-muted:hover { opacity: 1; }

/* La ligne du coloris courant dans la matrice de disponibilite. Par CLASSE,
   jamais par position : la ligne surlignee se deplace avec la selection. */
.calc2-tbl-matrix tbody tr.is-on td {
    color: var(--c2-heading);
    font-weight: 600;
}

.calc2-tbl-kv { margin: 0 0 18px; }
.calc2-tbl-kv td:first-child { color: var(--c2-muted); width: 40%; }

/* ---------- Responsive ---------- */

@media (max-width: 991px) {
    #calc2-widget .calc2-grid { grid-template-columns: minmax(0, 1fr); gap: 20px; }
    #calc-stricker .calc2-grid { grid-template-columns: minmax(0, 1fr); gap: 20px; }
    #calc2-widget .calc2-summary { position: static; }
    #calc-stricker .calc2-summary { position: static; }
}

@media (max-width: 575px) {
    #calc2-widget .calc2-tiers { grid-template-columns: repeat(auto-fill, 108px); }
    #calc-stricker .calc2-tiers { grid-template-columns: repeat(auto-fill, 108px); }

    /*  La repartition suit la MEME piste que les paliers — sinon les deux
        rangees cessent de s'aligner exactement la ou la place manque le plus. */
    #calc-stricker .calc2-rep { grid-template-columns: repeat(auto-fill, 108px); }

    /* La rangee a visuels se resserre aussi, sinon elle gardait ses 162 px et
       debordait la colonne une fois les autres passees a 108. */
    #calc2-widget .calc2-tiers-media { grid-template-columns: repeat(auto-fill, 136px); }
    #calc-stricker .calc2-tiers-media { grid-template-columns: repeat(auto-fill, 136px); }
    #calc2-widget .calc2-cards { grid-template-columns: repeat(auto-fill, 150px); }
    #calc-stricker .calc2-cards { grid-template-columns: repeat(auto-fill, 150px); }
    #calc2-widget .calc2-card { height: 150px; }
    #calc-stricker .calc2-card { height: 150px; }
    #calc2-widget .calc2-card-img { height: 78px; }
    #calc-stricker .calc2-card-img { height: 78px; }
    /* Garde les marges auto : le centrage vaut aussi en mobile, et il se
       neutralise tout seul des que la fiche depasse la hauteur de l'ecran. */
    .calc2-modal-box { margin: auto 0; }
}

/* ---------- Bouton et fiche « Plus d'informations » (hero, route /p) ----------
   Hors #calc2-widget : le bouton vit dans le hero, et la popup est montee sur
   <body>. Le prefixe calc2- reste la garantie d'isolation. */

/* Le bouton « Plus d'informations » n'a AUCUNE regle ici : il utilise
   .default-btn .default-btn-green de page_items.css, charge globalement.
   Un bouton maison avait ete ecrit puis retire — la page produit n'a pas a
   inventer son propre vocabulaire de boutons quand le template en a un.
   Seul l'espacement de l'icone est repris ci-dessous. */
.default-btn .fa-circle-info { margin-right: 8px; }


/* ---------- Boutons du hero : vert + orange ----------
   Le template fait survoler le vert vers le NOIR et l'orange vers le VERT.
   Cote a cote, ca donne deux boutons de la meme couleur des qu'on survole
   l'un des deux : le vert devient noir quand l'orange l'est deja, ou l'orange
   devient vert quand le vert est encore vert. On force donc les DEUX vers le
   noir au survol — un seul bouton bouge a la fois, et la paire reste lisible.
   Surcharge LOCALE : les boutons orange du reste du site ne bougent pas. */
.calc2-hero-actions .default-btn.default-btn-orange:hover { background-color: #000; }

/* ---------- Etapes de page : configurer / visualiser / demander ----------
   Le calculateur, la maquette et (a venir) le formulaire sont trois ETAPES,
   pas trois sections d'un meme reglage. Sans separation ils s'enchainaient en
   flux continu et on ne voyait plus ou finissait l'un et ou commencait l'autre.

   Le separateur est .page-title-item-box2, le RUBAN du template — deja utilise
   par le calculateur v1 pour ses en-tetes d'etape. Aucune forme inventee ici.

   Une carte bordee avait ete essayee puis retiree : cadre dans cadre autour du
   panneau prix, et surtout son overflow: hidden cassait le position: sticky de
   ce panneau (un ancetre en overflow devient le conteneur de defilement de ses
   descendants). Le ruban separe sans encadrer, donc sans ce piege.

   Le rail a filets reste reserve aux sections INTERNES du calculateur : deux
   niveaux, deux formes, sinon ils se lisent sur le meme plan. */

/*  LE RUBAN NE PORTE AUCUN ESPACE AU-DESSUS DE LUI.

    Il en portait 4rem, herites du ruban de titre de page (3rem), dimensionnes
    pour un titre isole en haut d'ecran. Deux lignes plus bas, un
    « :first-child » les annulait a l'interieur du calculateur — et comme
    chaque ruban est le premier enfant de sa section, l'annulation les
    attrapait TOUS. Ces 4rem n'ont donc jamais servi a l'interieur : ils ne
    s'appliquaient qu'au seul ruban situe hors du widget, celui du devis, ou
    ils n'etaient pas voulus. Du code mort partout, un defaut a un endroit.

    L'espace entre deux etapes appartient au PARCOURS, pas au titre : il est
    porte une seule fois, par .calc2-quote (voir quote.css). Un titre qui
    porte sa propre marge haute la fait s'additionner a celle du conteneur des
    qu'on le deplace — c'est exactement ce qui creait le trou de 135 px avant
    « Recevez votre devis ».

    Seul reste l'air EN DESSOUS, qui lui appartient bien au ruban : il separe
    le titre de son propre contenu. */
.calc2-block-head {
    margin-bottom: 2.4rem;
}

.calc2-block { margin: 0; }

/* ---------- Le loader du site, ADAPTE a un corps de modale ----------
   .loader-spiner fait 120 px, dimensionne pour la pleine largeur d'une page.
   Dans une modale il deborde, ce qui sort une barre de defilement
   (modal-dialog-scrollable), et comme la boite est centree verticalement elle
   se recentre a chaque changement de hauteur — le loader « sautait » puis
   passait sous le pli.

   On ne redefinit PAS un loader : on redimensionne celui du site, et seulement
   dans ce contexte. Le min-height approche la hauteur du contenu charge pour
   que la modale s'ouvre deja a sa taille a peu pres definitive ; sans lui,
   reduire l'anneau ne ferait que deplacer le probleme — la boite passerait de
   60 px a 600 px d'un coup. */
/* SELECTEUR DESCENDANT, pas enfant direct.

   Ecrit d'abord « .modal-body > .loader-spiner », la regle ne s'appliquait
   qu'a la popup Fiche produit, dont le corps recoit directement le loader.
   Celle du devis a un conteneur intermediaire (.body-secondary) : le loader y
   est un petit-fils, gardait ses 120 px, et la boite passait de 140 px a la
   hauteur du formulaire d'un coup. La page changeait de hauteur, sa barre de
   defilement apparaissait puis disparaissait, et Bootstrap recompensait le
   padding du body a chaque fois — d'ou la fenetre qui « danse ».

   La lecon : une regle de presentation ne doit pas dependre de la PROFONDEUR
   d'imbrication. Celle-ci change au premier conteneur ajoute, sans erreur. */
.modal-body .loader-spiner {
    width: 56px;
    height: 56px;
    margin: 0 auto;
}

.modal-body .loader-spiner:before {
    width: 56px;
    height: 56px;
    border-width: 5px;
}

/* Le corps reserve sa hauteur AVANT que le contenu arrive.

   La marge de 162 px qui centrait le loader ne reglait le probleme qu'a
   moitie : elle donnait une hauteur de depart, mais la boite sautait quand
   meme a l'arrivee du formulaire. Une hauteur minimale sur le CONTENEUR, avec
   le loader centre dedans, tient la boite immobile — le contenu remplit une
   place deja reservee au lieu de la creer. */
/* ⚠️ DESCENDANT A PROFONDEUR LIBRE, et c'est la troisieme ecriture.

   Les deux precedentes etaient « :has(> .loader-spiner) » puis, apres avoir
   constate qu'elle ratait la popup devis, « :has(> .loader-spiner),
   :has(> * > .loader-spiner) ». Le commentaire ci-dessus tirait pourtant deja
   la bonne lecon — « une regle de presentation ne doit pas dependre de la
   PROFONDEUR d'imbrication » — et la correction la respectait a moitie : elle
   exigeait desormais exactement un OU deux niveaux.

   Un conteneur de plus, et le defaut revient a l'identique. « :has(.x) »
   couvre toutes les profondeurs, aujourd'hui et apres le prochain wrapper. */
.modal-body:has(.loader-spiner) {
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 380px;
}

/* Repli pour les navigateurs sans :has() — la hauteur est alors portee par la
   marge, comme avant. Moins bon, mais jamais pire qu'aujourd'hui. */
@supports not selector(:has(*)) {
    .modal-body .loader-spiner { margin: 162px auto; }
}





/*  Repli visuel d'une carte : deux icones, deux messages.
    « Aucun » = un choix, image absente = un manque. Voir _cardVisual(). */
#calc2-widget .calc2-card-ph,
#calc-stricker .calc2-card-ph {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    height: 100%;
    color: #c8ccd2;
}

#calc2-widget .calc2-card-ph i { font-size: 3.2rem; line-height: 1; }
#calc-stricker .calc2-card-ph i { font-size: 3.2rem; line-height: 1; }

/*  « Aucun » : la barre est tournee pour barrer dans le sens de la lecture,
    et un cran plus pale que l'icone d'image. Le choix de ne rien mettre est
    legitime — il ne doit pas attirer l'oeil plus que les vraies options. */
#calc2-widget .calc2-card-ph.is-none,
#calc-stricker .calc2-card-ph.is-none {
    color: #d8dce1;
    transform: rotate(-12deg);
}

/*  Image absente : un peu plus marque, parce que c'est la seule trace
    visible qu'il reste un visuel a charger en admin. */
#calc2-widget .calc2-card-ph.is-noimg { color: #c2c7ce; }
#calc-stricker .calc2-card-ph.is-noimg { color: #c2c7ce; }

/* ===========================================================================
   LA MAQUETTE — apercu du logo pose sur le produit
   ---------------------------------------------------------------------------
   POSITIONNEMENT EN POURCENTAGES, pas en pixels. Le HotSpot est exprime sur un
   canevas 500 et le packshot est servi en 1000 : convertir en pourcentage
   absorbe le facteur ET rend la pose independante de la taille d'affichage.
   Le meme CSS tient sur un telephone et sur un grand ecran, sans JavaScript de
   redimensionnement.

   C'est aussi pourquoi il n'y a pas de <canvas> ici. Konva sera necessaire pour
   DEPLACER, redimensionner et exporter ; poser ne demande qu'un bloc en absolu.
   =========================================================================== */

#calc-stricker .calc2-mk-tabs { margin-bottom: 14px; }

/*  La scene : l'image donne sa taille, l'overlay s'y cale. `position:relative`
    + une image en display:block — sans le block, la ligne de base du texte
    ajoute trois pixels sous l'image et le cadre se decale d'autant. */
#calc-stricker .calc2-mk-stage {
    position: relative;
    display: inline-block;
    max-width: 420px;
    width: 100%;
    border: 1px solid var(--c2-border);
    border-radius: var(--c2-radius-lg);
    background: #fff;
    overflow: hidden;
}

#calc-stricker .calc2-mk-bg {
    display: block;
    width: 100%;
    height: auto;
}

/*  LA ZONE IMPRIMABLE. Filet vert en pointilles : c'est un REPERE, pas un
    cadre de selection — d'ou le pointille, qui ne se confond pas avec le filet
    plein d'un element choisi. */
#calc-stricker .calc2-mk-zone {
    position: absolute;
    border: 2px dashed var(--c2-accent);
    box-sizing: border-box;
    pointer-events: none;
}

/*  1,7 % des zones sont des ELLIPSES — badges, boutons, mugs. Les rendre
    rectangulaires serait faux sans que rien ne le signale. */
#calc-stricker .calc2-mk-zone.is-ellipse { border-radius: 50%; }

/*  Le logo tient DANS la zone sans la deformer. `contain` plutot que `cover` :
    un logo recadre est un logo mutile, et c'est exactement ce qu'un apercu ne
    doit pas faire croire. */
#calc-stricker .calc2-mk-logo {
    width: 100%;
    height: 100%;
    object-fit: contain;
    display: block;
}

#calc-stricker .calc2-mk-bar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 12px;
    margin-top: 14px;
}

/*  Le <label> EST le bouton : l'input natif est masque, et cliquer le libelle
    ouvre le selecteur sans une ligne de JavaScript. */
#calc-stricker .calc2-mk-file {
    margin: 0;
    padding: 9px 16px;
    border: 1px solid var(--c2-border-strong);
    border-radius: var(--c2-radius);
    background: var(--c2-surface);
    cursor: pointer;
    font-weight: 600;
    transition: border-color .15s ease;
}

#calc-stricker .calc2-mk-file:hover { border-color: var(--c2-accent); }

#calc-stricker .calc2-mk-clear {
    border: 0;
    background: none;
    padding: 0;
    color: var(--c2-muted);
    text-decoration: underline;
    cursor: pointer;
}

#calc-stricker .calc2-mk-note { color: var(--c2-muted); font-size: 1.2rem; }

/* ---------- Disponibilite : coche verte / croix rouge ----------
   Matrice coloris x taille de la popup « Taille » DU CALCULATEUR — elle reste
   donc ici, contrairement a l'habillage de la fiche produit, parti dans
   pages/product/product.css : la fiche produit est du squelette de page, pas
   un item de calculateur.

   Deux points de tailles differentes se distinguaient mal, et rien ne disait
   lequel etait le bon : il fallait une legende pour lire le tableau.

   LE ROUGE EST ICI UNE INFORMATION, PAS UNE ALERTE — d'ou un ton attenue
   plutot que le rouge d'erreur du site. « Cette teinte n'existe pas en XXL »
   n'est pas une panne, c'est une contrainte de catalogue.

   Et c'est aussi pourquoi le vert reste discret : sur 225 grilles, 192 sont
   pleines. Un vert soutenu aurait fait un mur de coches ou les 33 trous — la
   seule chose qu'on vient y chercher — se seraient perdus. */
.calc2-tbl-matrix .calc2-yes,
.calc2-tbl-matrix .calc2-no {
    text-align: center;
    font-size: 1.2rem;
}

.calc2-tbl-matrix .calc2-yes { color: var(--c2-accent); }
.calc2-tbl-matrix .calc2-no  { color: #c0392b; }

/*  ÉPUISÉ N'EST PAS ABSENT — ambre, pas rouge.

    La croix rouge dit « cette combinaison n'existe pas » : elle ne reviendra
    jamais. « Épuisé » dit « elle existe, il n'en reste plus » : elle revient au
    prochain reassort. Les teindre pareil ferait renoncer a un coloris pour une
    rupture passagere. */
.calc2-tbl-matrix .calc2-out {
    color: #b45309;
    font-size: 1.05rem;
    text-align: center;
}

/* ---------- La matrice de DISPONIBILITE, pas celle des prix ----------

   .calc2-tbl aligne tout a GAUCHE, ce qui convient a une grille de prix : on y
   compare des nombres de longueurs proches, cale sur leur bord gauche.

   Ici non. Les en-tetes de taille etaient a gauche et les coches au centre :
   la colonne et son titre ne tombaient pas en face, et sur six colonnes l'oeil
   perdait la correspondance. Une classe A PART plutot qu'une retouche de
   .calc2-tbl-matrix, qui sert aussi au tableau des paliers. */
.calc2-tbl-dispo th,
.calc2-tbl-dispo td { text-align: center; }

/* La colonne des coloris garde son alignement a gauche : c'est du texte de
   longueur variable, pas une valeur a comparer. */
.calc2-tbl-dispo .calc2-tbl-lbl { text-align: left; }

/* ============================================================================
   « VOTRE PANIER » — facon panier e-commerce (calc_global.js, 2026-10-15)
   ----------------------------------------------------------------------------
   Dessine par theme.CalcGlobal dans l'aside .calc2-summary (vide) du
   sous-calculateur visible : memes regles pour OBG et Stricker.

   RANGEES SUR RAIL, fond blanc, un filet entre deux — PAS de cartes (user :
   les sous-cartes s'etiraient, « a 3 c'est la folie, a 10 la misere »).
   Repliee, une rangee tient en 3 lignes ; « Détail » deroule le reste.
   Au-dela de ~4 produits la liste DEFILE dans sa zone : le panneau reste
   collant sans depasser l'ecran. Totaux en pied, comme un panier.
   ========================================================================== */

.calc2-summary .cg-cart { display: flex; flex-direction: column; }

/* En-tete : icone panier, titre, nombre de produits. */
.calc2-summary .cg-cart-h {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 14px 16px;
    border-bottom: 1px solid var(--c2-panel-line);
    background: var(--c2-panel-band);
    color: var(--c2-heading);
}

.calc2-summary .cg-cart-h > i { color: #000954; font-size: 1.8rem; }

.calc2-summary .cg-cart-t { font-weight: 700; font-size: 1.6rem; }

.calc2-summary .cg-cart-n { margin-left: auto; color: var(--c2-muted); font-size: 1.3rem; }

/* La liste : defile au-dela de ~4 rangees repliees. */
.calc2-summary .cg-rows {
    position: relative; /* offsetTop des rangees relatif a la liste (defilement vers l'ajout) */
    max-height: 360px;
    margin: 0;
    padding: 0;
    overflow-y: auto;
    list-style: none;
}

/* UNE RANGEE : rail a gauche (transparent ; vert sur le produit ouvert),
   filet NET en bas — le filet clair (#eaeaea) ne demarquait rien sur fond
   blanc (user, 2026-10-15 : « pas de demarcation, tout est trop tasse ») :
   filet bleute des en-tetes, et de l'air dans la rangee. */
.calc2-summary .cg-row {
    padding: 14px 16px 14px 13px;
    border-left: 3px solid transparent;
    border-bottom: 1px solid var(--c2-line-head);
    background: var(--c2-surface);
}

.calc2-summary .cg-row:last-child { border-bottom: 0; }

.calc2-summary .cg-row.is-current { border-left-color: var(--c2-accent); }

.calc2-summary .cg-row-h {
    display: flex;
    align-items: center;
    gap: 8px;
}

.calc2-summary .cg-row-edit { flex: 0 0 auto; }

.calc2-summary .cg-row-n {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    color: var(--c2-heading);
    font-weight: 600;
    white-space: nowrap;
    text-overflow: ellipsis;
}

.calc2-summary .cg-row-del {
    flex: 0 0 26px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 26px;
    height: 26px;
    border: 1px solid #e6b8b8;
    border-radius: 6px;
    background: #ffffff;
    color: #c0392b;
    font-size: 1.2rem;
    cursor: pointer;
}

.calc2-summary .cg-row-del:hover { background: #fdf0ef; }

/* Lignes 2 et 3 : etiquette a gauche, valeur a droite. */
.calc2-summary .cg-row-l {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    margin-top: 8px;
    color: var(--c2-text);
    font-size: 1.3rem;
}

.calc2-summary .cg-row-tot { color: var(--c2-heading); font-size: 1.4rem; }

.calc2-summary .cg-row-sub { margin-top: 6px; color: var(--c2-muted); font-size: 1.2rem; }

.calc2-summary .cg-row-sub i { margin-right: 4px; }

/* Le deroulant : un CHEVRON discret, gris, pas un libelle — « Détail » en
   navy gras saturait la colonne. */
.calc2-summary .cg-row-more {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 24px;
    height: 24px;
    border: 0;
    border-radius: 50%;
    background: none;
    color: var(--c2-muted);
    cursor: pointer;
}

.calc2-summary .cg-row-more:hover { background: var(--c2-surface-sub); color: #000954; }

.calc2-summary .cg-row-more i { transition: transform .15s; }

.calc2-summary .cg-row.is-open .cg-row-more i { transform: rotate(180deg); }

/* Le detail deroule : LEGER — pas de bloc colore, texte gris, un filet a
   gauche pour le rattacher a sa rangee. */
.calc2-summary .cg-row-det {
    margin-top: 8px;
    padding: 2px 0 2px 10px;
    border-left: 2px solid var(--c2-line-head);
}

.calc2-summary .cg-row-det .cg-kv { color: var(--c2-muted); padding: 2px 0; }

/* Paire etiquette / valeur — detail ET totaux. */
.calc2-summary .cg-kv {
    display: flex;
    justify-content: space-between;
    gap: 10px;
    padding: 3px 0;
    color: var(--c2-text);
    font-size: 1.2rem;
}

.calc2-summary .cg-kv > span:last-child { text-align: right; white-space: nowrap; }

.calc2-summary .cg-kv-none > span:last-child { color: var(--c2-muted); }

/* LES TOTAUX, facon panier. */
.calc2-summary .cg-tot { padding: 12px 16px 4px; }

.calc2-summary .cg-tot .cg-kv { font-size: 1.3rem; }

.calc2-summary .cg-kv-ok > span:last-child { color: var(--c2-accent-dark); }

.calc2-summary .cg-kv-ht {
    margin-top: 6px;
    padding-top: 8px;
    border-top: 1px solid var(--c2-border);
    color: var(--c2-heading);
    font-weight: 700;
}

.calc2-summary .cg-tot .cg-kv-ht { font-size: 1.5rem; }

.calc2-summary .cg-tot .cg-kv-ttc { color: var(--c2-heading); font-weight: 700; font-size: 1.6rem; }

.calc2-summary .cg-promo-box {
    padding: 12px 16px 14px;
    border-top: 1px solid var(--c2-panel-line);
    background: var(--c2-panel-band);
}

.calc2-summary .cg-promo-box .calc2-promo-err { margin: 6px 0 0; }

/* LE BLOC CODE PROMO COMMUN (2026-10-18) — panier ET recapitulatif, un seul
   etat (calc_global.js _promoBoxHtml). Trois etats : saisie, verification
   (spinner sur le bouton), code applique (etiquette + « Retirer »). */
.cg-promo-on {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    min-height: 40px;           /* meme hauteur que le champ : rien ne saute */
}

.cg-promo-tag { color: var(--c2-accent-dark); font-weight: 600; }
.cg-promo-tag strong { letter-spacing: .5px; }

.cg-promo-del {
    flex: 0 0 auto;
    padding: 4px 10px;
    border: 1px solid #d4d4d4;
    border-radius: 6px;
    background: #fff;
    color: #555;
    font: inherit;
    font-size: 1.3rem;
    cursor: pointer;
}

.cg-promo-del:hover { border-color: #c0392b; color: #c0392b; }

/* Le bouton ne change pas de largeur en passant au spinner. */
#calc2-widget .calc2-promo button,
#calc-stricker .calc2-promo button,
.calc2-q-prix .calc2-promo button { min-width: 112px; }

.calc2-promo button:disabled { cursor: progress; opacity: .85; }
.calc2-promo input:disabled { color: #9a9a9a; }

/* Dans le recapitulatif : sous les totaux, PLEINE LARGEUR (user 18/10) —
   seulement sans code ; applique, « Retirer » vit sur la ligne de remise. */
.calc2-rc-promo { margin: 16px 0 0; }

.cg-promo-del-sm {
    margin-left: 10px;
    padding: 1px 8px;
    font-size: 1.2rem;
    vertical-align: middle;
}

/* ANIMATIONS D'AJOUT / RETRAIT (user, 2026-10-15) :
   - TOUT LE PANIER clignote, en long (deux halos verts sur 1,8 s), a l'ajout
     comme au retrait — pose sur l'aside, qui survit aux redessins ;
   - a l'AJOUT seulement, la rangee neuve nait sur fond vert qui s'estompe.
     Au retrait, rien d'autre : le clignotement du panier suffit. */
@keyframes cg-blink {
    0%, 50%, 100% { box-shadow: 0 0 0 0 rgb(15 185 48 / 0); }
    20%, 70%      { box-shadow: 0 0 0 4px rgb(15 185 48 / .45); }
}

@keyframes cg-flash-add {
    0%   { background-color: rgb(15 185 48 / .22); }
    100% { background-color: var(--c2-surface); }
}

.calc2-summary.cg-blink { animation: cg-blink 1.8s ease-in-out; }

.calc2-summary .cg-row.cg-flash { animation: cg-flash-add 1.4s ease-out; }

@media (prefers-reduced-motion: reduce) {
    .calc2-summary.cg-blink,
    .calc2-summary .cg-row.cg-flash { animation: none; }
}

/* ============================================================================
   LA LIVRAISON COMMUNE — panier MIXTE (OBG + Stricker), calc_global.js
   ----------------------------------------------------------------------------
   Panier d'UN moteur : chaque calculateur garde son bloc Livraison, rien ne
   change. Panier MIXTE : ces blocs se masquent (body.cg-mixte) et le global
   rend UN bloc dans [data-calc-delivery] — memes pastilles, meme selecteur. */
body.cg-mixte #calc2-ancre-livraison,
body.cg-mixte #calc2-widget .calc2-deliv,
body.cg-mixte #calc-stricker [data-delivery] { display: none !important; }

[data-calc-delivery] .calc2-deliv-row {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 10px;
    margin: 0 0 14px;
}

[data-calc-delivery] .calc2-deliv-lbl { color: var(--c2-muted); }

[data-calc-delivery] .calc2-country {
    flex: 0 1 320px;
    max-width: 100%;
    height: 40px;
    padding: 0 12px;
    border: 1px solid var(--c2-border-strong);
    border-radius: var(--c2-radius);
    background: #fff;
    color: var(--c2-text);
    font: inherit;
}

[data-calc-delivery] .calc2-country:focus-visible { outline: 2px solid var(--c2-accent); outline-offset: 2px; }

[data-calc-delivery] .cg-deliv-opts { display: flex; flex-wrap: wrap; gap: 10px; }

[data-calc-delivery] .calc2-deliv-pill {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 2px;
    padding: 10px 16px;
    border: 1px solid var(--c2-border);
    border-radius: var(--c2-radius);
    background: var(--c2-surface);
    color: var(--c2-text);
    cursor: pointer;
    font: inherit;
    text-align: left;
}

[data-calc-delivery] .calc2-deliv-pill:hover { border-color: var(--c2-border-strong); }

[data-calc-delivery] .calc2-deliv-pill.is-on {
    padding: 9px 15px;
    border: 2px solid var(--c2-accent);
    color: var(--c2-accent-dark);
    font-weight: 600;
}

[data-calc-delivery] .calc2-deliv-p { color: var(--c2-muted); font-weight: 400; font-variant-numeric: tabular-nums; }

[data-calc-delivery] .calc2-deliv-pill.is-on .calc2-deliv-p { color: var(--c2-accent-dark); }

[data-calc-delivery] .cg-deliv-note { margin: 12px 0 0; }

/* ============================================================================
   Maquette v2 — feuille propre au module (route /p uniquement)
   ----------------------------------------------------------------------------
   Miroir de items/calculator/mockup.css : le moteur en production n'est pas
   touche. Prefixe impose : .mk2-*

   Les regles ne sont PAS scopees sous #calc2-widget bien que la section y vive
   aujourd'hui : le module doit pouvoir etre monte ailleurs (popup, page de
   maquette dediee) sans deplacer sa feuille. Le prefixe porte l'isolation.
   ========================================================================== */

/* ---------- Onglets de vue (recto / verso / ...) ----------
   Affiches seulement s'il y a plusieurs vues : une pastille unique et inerte
   est un controle qui ment. */
/* La barre : vues a gauche, couleur du produit a droite. Meme grammaire que
   les en-tetes de section du calculateur, ou la valeur courante est poussee a
   droite du titre. */
.mk2-bar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
    margin: 0 0 12px;
}

/* Une LIGNE d'onglets, posee sur un filet continu. Le filet est ce qui fait
   lire la rangee comme une barre de navigation plutot que comme une grille de
   boutons : l'onglet actif l'interrompt, les autres restent dessus. */
/* Une LIGNE d'onglets posee sur un rail continu. Le rail fait lire la rangee
   comme une barre de navigation plutot que comme une grille de boutons :
   l'onglet actif l'interrompt, les autres restent dessus.

   Le rail est porte par .mk2-bar et non par .mk2-tabs : il doit traverser
   TOUTE la largeur, y compris derriere le nom du coloris pousse a droite. Pose
   sur .mk2-tabs il se serait arrete au dernier onglet, laissant la rangee
   coupee en deux. */
/*  ⛔ ONGLETS → PILULES, LE RAIL VERT EST RETIRE — 2026-10-06.

    Toute la construction en onglets reposait sur une JONCTION : l'onglet
    actif interrompt le rail et se raccorde au panneau dessous. Or dessous il
    n'y a plus UN panneau mais une rangee de cartes separees (une par
    technique, plus le bilan) : le rail ne raccordait plus rien. Il restait une
    seconde ligne horizontale pleine largeur, a 50 px du filet du titre
    « Maquette », au-dessus de cartes qui ont deja leurs bordures et leurs
    filets d'en-tete — la surcharge de traits signalee par le user.

    Les pilules n'ont pas besoin de raccord : chacune est une forme close.
    L'aplat vert de la vue regardee reste — c'est lui qu'on cherchait des
    yeux ; les autres prennent le gris du template au lieu du vide.        */
.mk2-tabs {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
}

.mk2-bar {
    align-items: center;
    gap: 8px;
    margin-bottom: 0;
}

/* La fente du calculateur, juste sous le rail. Elle est PLEINE LARGEUR depuis
   que les onglets sont sortis de la grille : les cartes de technique
   s'etalent sur toute la section au lieu d'etre serrees dans 70 %. */
[data-mk2-slot]:not(:empty) {
    padding: 16px 0 4px;
}

/* ---------- L'attente au changement de vue (2026-10-04) ----------

   Le fond est un PNG de 100 a 300 Ko servi par la racine d'assets : il y a un
   vrai delai entre le clic sur un onglet et le premier trait.

   ⚠️ ON VOILE, ON NE VIDE PAS. Le canvas garde l'image precedente sous le
   voile, attenuee. Le masquer ferait clignoter un trou blanc a chaque
   navigation, ce qui est plus agressif que l'attente elle-meme — et sur une
   image deja en cache, ou la promesse se resout immediatement, le trou serait
   la seule chose qu'on verrait. */
/* `position: relative` sur .mk2-stage n'est PAS redeclare ici : il est deja
   pose plus bas pour le bouton d'effacement. Le repeter donnerait deux
   porteurs d'une meme propriete, dont on ne corrigerait qu'un le jour ou elle
   change. */
.mk2-stage.is-loading > canvas {
    opacity: .35;
    filter: saturate(.4);
    transition: opacity .12s linear;
}

.mk2-stage.is-loading::after {
    content: "";
    position: absolute;
    top: 50%;
    left: 50%;
    width: 34px;
    height: 34px;
    margin: -17px 0 0 -17px;
    border: 3px solid rgba(0, 0, 0, .12);
    border-top-color: #0fb930;
    border-radius: 50%;
    animation: mk2-spin .7s linear infinite;
    /* Au-dessus du canvas mais SOUS les poignees de selection du logo, qui
       montent plus haut : pendant le chargement il n'y a rien a saisir, et
       apres, le voile a disparu. */
    z-index: 2;
}

/* Les controles poses sur le visuel — le bouton de remise a zero — n'ont pas
   a rester cliquables pendant qu'on charge : ils agiraient sur une scene qui
   va etre remplacee. */
.mk2-stage.is-loading { pointer-events: none; }

@keyframes mk2-spin { to { transform: rotate(360deg); } }

/* Le coloris se realigne sur la ligne de base des onglets plutot que sur leur
   bas, sinon il flotte au ras du rail. */
.mk2-bar-color {
    padding: 0 4px;
}

/* Pousse la couleur a droite, y compris quand il n'y a PAS d'onglet : c'est
   la marge automatique qui le fait, pas un flex sur un conteneur d'onglets
   qui pourrait ne pas exister. */
.mk2-bar-color {
    margin-left: auto;
    color: #8a8c93;
}

/* ⚠️ UN ONGLET NAVIGUE, IL NE CHOISIT PAS — refonte du 2026-10-04.

   Ces onglets portaient la grammaire de selection du calculateur : filet vert
   2px, libelle vert. C'etait une erreur de langue. Le vert veut dire « ceci est
   ton choix, il part dans ton devis » ; or changer d'onglet ne commande rien,
   ca change seulement ce qu'on REGARDE. Un acheteur qui voyait « Poitrine » en
   vert pouvait croire avoir retenu la poitrine.

   CONSTRUCTION CLASSIQUE : une boite bordee sur trois cotes, ouverte en bas.
   L'onglet actif INTERROMPT le rail et se raccorde au bloc qui suit — c'est
   cette jonction qui dit « ce que tu vois dessous appartient a cet onglet ».
   Un simple soulignement ne le disait pas : il marquait la position sans
   rattacher le contenu.

   Le -1px de .mk2-tabs et le fond blanc de l'onglet actif font ce raccord :
   l'onglet recouvre le rail sur sa propre largeur. */
/*  ⚠️ LA TAILLE EST DECLAREE, pas heritee — 2026-10-05.

    `font: inherit` laissait l'onglet prendre ce que lui donnait son ancetre, ce
    qui le rendait plus petit que tout ce qui l'entoure. Ces onglets sont la
    navigation principale du bloc : ils doivent etre au moins a la taille du
    corps de texte du site (1,4 rem = 14 px, la racine etant a 10 px).

    ET PLUS LARGES. 16 px de cote sur un libelle court donnait des cibles
    etroites, collees les unes aux autres : on lisait une liste de mots, pas
    une rangee d'onglets. */
/*  PILULE depuis le 2026-10-06 (voir `.mk2-tabs`) : bordee sur ses quatre
    cotes, arrondie, fond gris du template (#f3f3f3) au repos. */
.mk2-tab {
    position: relative;
    padding: 9px 20px;
    border: 1px solid #f3f3f3;
    border-radius: 999px;
    background: #f3f3f3;
    color: #6c6e76;
    cursor: pointer;
    font-family: inherit;
    font-size: 1.4rem;
    line-height: 1.2;
}

.mk2-tab:hover {
    color: #3f4045;
    background: #e9e9ea;
    border-color: #e9e9ea;
}

/*  L'ONGLET ACTIF EN APLAT VERT — 2026-10-05, apres deux revisions.

    1. Fond blanc, filet sur trois cotes. Construction juste, mais sur une page
       deja tres claire un blanc sur blanc ne se distinguait pas : on relisait
       la rangee pour savoir ou l'on etait.
    2. Aplat sombre. Lisible, mais sans rapport avec la langue de la page.
    3. Aplat vert + rail vert pleine largeur. Retenu.

    ⚠️ J'AVAIS OBJECTE QUE LE VERT EST LA COULEUR DU CHOIX, donc qu'un onglet
    vert ferait croire a un marquage retenu. Mis a l'ecran, l'objection ne
    tient pas, et pour une raison qu'il faut garder :

      - LE RAIL COURT SUR TOUTE LA LARGEUR. Il appartient au conteneur, pas a
        un controle : il encadre la section au lieu de designer un element.
      - LES VRAIS MARQUEURS DE CHOIX SONT DES CARTES a filet vert. Une forme
        differente, a un autre endroit. Le vert n'est donc pas ambigu ici — il
        est porte par deux objets qu'on ne confond pas.

    La regle de fond n'est pas « le vert est reserve », elle est « deux choses
    differentes ne doivent pas avoir la MEME FORME ». Ce qui reste vrai. */
.mk2-tab.is-on {
    background: #0fb930;
    border-color: #0fb930;
    color: #fff;
    font-weight: 600;
}

.mk2-tab.is-on:hover {
    background: #0fb930;
    border-color: #0fb930;
    color: #fff;
}

/*  ⛔ DEFAUT CORRIGE LE 2026-10-05 : le libelle de l'onglet actif passait en
    gris fonce sur l'aplat vert, donc illisible.

    `.mk2-tab.is-on` et `.mk2-tab.has-mark` ont la MEME specificite (0,2,0), et
    `.has-mark` vient plus bas dans le fichier : elle gagnait. Un onglet a la
    fois actif ET porteur d'un marquage recuperait donc son `color: #3f4045`.

    Le cas n'est pas marginal, c'est le plus frequent : on regarde justement
    l'emplacement qu'on vient de regler.

    ⚠️ LA PROTECTION EST LA SPECIFICITE, PAS LA POSITION. Le selecteur a trois
    classes (0,3,0) l'emporte ou qu'il soit dans le fichier. Compter sur
    l'ordre aurait reporte le probleme au prochain deplacement de bloc — et il
    se serait represente en silence. */
.mk2-tab.is-on,
.mk2-tab.is-on.has-mark { color: #fff; }

/*  Le prix en PASTILLE BLANCHE sur l'onglet actif. Du texte vert sur un aplat
    vert faisait disparaitre le montant ; l'inversion le detache sans ajouter
    de teinte. */
.mk2-tab.is-on .mk2-tab-b {
    padding: 2px 7px;
    border-radius: 999px;
    background: #fff;
    color: #0b8f25;
}

/* ---------- Le resume des choix, DANS les onglets (2026-10-04) ----------

   Les options de marquage vivent desormais sous les onglets : une seule vue
   est visible a la fois. Sans marqueur, verifier ce qui est retenu au dos
   demanderait d'aller au dos — et personne ne parcourt quatre onglets pour
   relire ses propres choix.

   ⚠️ ICI LE VERT EST JUSTE, contrairement a l'onglet actif. Il ne dit pas
   « tu regardes ceci », il dit « ceci est retenu et part dans ton devis » —
   exactement le sens qu'il a dans tout le calculateur. Les deux etats sont
   donc lisibles ENSEMBLE et sans ambiguite : l'aplat vert designe la vue
   affichee, la pastille les vues qui portent un marquage.

   ⚠️ SECOND PORTEUR DE `.mk2-tab`, et c'est voulu : celui du haut regle
   l'apparence (taille, filets, rembourrage), celui-ci la MISE EN LIGNE du
   libelle et de sa pastille. Les deux ne se recouvrent sur aucune propriete —
   verifie le 2026-10-05. Les fusionner melangerait deux sujets dans un bloc
   deja long. */
.mk2-tab {
    display: inline-flex;
    align-items: baseline;
    gap: 7px;
}

/*  LE PRIX EN BADGE BLANC, texte vert.

    Il etait en texte vert sur l'aplat vert de l'onglet actif : deux verts
    superposes, le montant disparaissait au moment ou il compte le plus. Le
    pastillage inverse le rapport — fond blanc, chiffre vert — ce qui le
    detache sans ajouter de couleur a la page.

    Sur les onglets INACTIFS il reste du texte simple : un badge blanc sur fond
    blanc ne dessinerait rien, et quatre pastilles dans une rangee de
    navigation feraient concurrence au contenu. */
.mk2-tab-b {
    color: #0b8f25;
    font-weight: 600;
    /* 8,1 px avant : la pastille de prix etait la plus petite chose de la
       rangee alors qu'elle en porte l'information. */
    font-size: 1.2rem;
    white-space: nowrap;
}

/* Un onglet qui porte un marquage reste lisible meme inactif : c'est une
   information sur la COMMANDE, pas sur la navigation, donc elle ne doit pas
   s'eteindre avec l'onglet. */
.mk2-tab.has-mark { color: #3f4045; }

/* ---------- Scene ----------
   Plafond en vh : le packshot de maquette est un carre pleine resolution, sans
   limite il pousserait tout le bas du calculateur hors de l'ecran. */
/* Le visuel prend la largeur, les controles tiennent a droite. On a cette
   place parce que la maquette est un bloc pleine largeur — chez BigBot elle
   vit dans une carte d'etape et le produit y est ecrase. */
.mk2-grid { align-items: flex-start; }

.mk2-stage {
    display: flex;
    align-items: center;
    justify-content: center;
    background: #fff;
    border: 1px solid #eaeaea;
    border-radius: 12px;
    padding: 12px;
    min-height: 160px;
}

/* Le canvas est rendu a la resolution du packshot et remis a l'echelle ici :
   le detail est conserve sur ecran dense, et le plafond en vh evite que le
   produit pousse le bas de page hors du champ. */
.mk2-stage canvas {
    display: block;
    width: auto;
    max-width: 100%;
    max-height: 58vh;
    touch-action: none;   /* le glisser du logo ne doit pas faire defiler la page */
    cursor: grab;
}

.mk2-stage canvas:active { cursor: grabbing; }

.mk2-side { display: flex; flex-direction: column; gap: 18px; }

.mk2-side-block { display: flex; flex-direction: column; gap: 8px; }

/* ---------- Titres d'etape : le rail, en plus discret ----------
   Meme construction que les en-tetes de section du calculateur
   (.calc2-sec-head) : deux filets d'un pixel qui s'estompent aux extremites,
   plus un halo central tres dilue. On reprend le motif plutot qu'un trait
   simple pour que la colonne parle la meme langue que le reste de la page.

   Trois differences, toutes dictees par la hierarchie : ces titres sont des
   ETAPES a l'interieur d'une carte, pas des sections de premier niveau. Donc
   texte a la taille du corps et non 2rem, respiration divisee par deux, et
   estompe porte a 18 % — dans une colonne etroite, un fondu court fait
   paraitre les filets pleins, et ils entrent alors en concurrence avec la
   bordure de la carte, a quelques pixels de la.

   C'est aussi ce qui reglait le probleme de depart : les titres etaient
   tasses contre le bloc precedent parce que rien ne les separait. Le rail
   fait le groupement, sans qu'on ait a empiler des marges. */
.mk2-side-title {
    /*  Navy, aligné sur --c2-rail-* le 2026-10-03 : ce rail cohabite avec ceux
        du calculateur sur le même écran, et deux démarcateurs de teintes
        différentes se lisent comme deux systèmes. L'alpha reste légèrement plus
        bas qu'ailleurs — la colonne latérale est étroite, le halo y porte plus. */
    --mk2-rail-line: 182 192 232;
    --mk2-rail-glow: 0 9 84;
    --mk2-rail-alpha: 0.055;
    --mk2-rail-fade: 18%;

    /* Respiration au-dessus du rail, la valeur d'un pt-3 Bootstrap.
       Portee par le TITRE et non par le bloc : le critere est « ce conteneur
       a un titre-rail », pas « ce conteneur suit un autre ». Le bloc du
       fichier, qui n'a pas de titre, ne prend donc rien — et l'espace suivrait
       le rail si on le deplacait ailleurs. */
    margin: 1rem 0 2px;
    padding-block: 9px;
    color: #222222;
    font-weight: 700;
    line-height: 1.2;

    background-image:
        linear-gradient(to right,
            rgb(var(--mk2-rail-line) / 0) 0%,
            rgb(var(--mk2-rail-line) / 1) var(--mk2-rail-fade),
            rgb(var(--mk2-rail-line) / 1) calc(100% - var(--mk2-rail-fade)),
            rgb(var(--mk2-rail-line) / 0) 100%),
        linear-gradient(to right,
            rgb(var(--mk2-rail-line) / 0) 0%,
            rgb(var(--mk2-rail-line) / 1) var(--mk2-rail-fade),
            rgb(var(--mk2-rail-line) / 1) calc(100% - var(--mk2-rail-fade)),
            rgb(var(--mk2-rail-line) / 0) 100%),
        radial-gradient(60% 80% at 50% 50%,
            rgb(var(--mk2-rail-glow) / var(--mk2-rail-alpha)) 0%,
            rgb(var(--mk2-rail-glow) / calc(var(--mk2-rail-alpha) * .62)) 56%,
            rgb(var(--mk2-rail-glow) / 0) 100%);
    background-repeat: no-repeat;
    background-size: 100% 1px, 100% 1px, 100% 100%;
    background-position: top, bottom, center;
}

/* Icone d'etape (2026-10-14) — « Blanc du logo », « Couleurs du marquage »,
   « Placement ». UNE SEULE COULEUR pour les icones de titre du panneau, celle
   du TEXTE du titre (#222) : essaye en navy puis abandonne le meme jour — a
   cote du vert de « Votre logo », trois teintes pour un meme role. Un poil
   plus grande que celle de l'entete (1.15em) : l'icone porte le reperage.
   Moteur commun : vaut pour OBG ET Stricker. */
.mk2-side-title > i {
    margin-right: 7px;
    color: #222222;
    font-size: 1.15em;
}

/* Version compacte de la zone de depot pour la colonne etroite. */
.mk2-dz-sm { padding: 16px 12px; gap: 4px; }
.mk2-dz-sm .mk2-dz-ico { font-size: 2rem; }
.mk2-dz-sm .mk2-dz-txt { font-size: 1.2rem; }

.mk2-place-btns { display: flex; flex-wrap: wrap; gap: 6px; }

/* Pas de regle d'apparence ici : ces boutons portent deja .mk2-btn-ico, comme
   ceux des lignes de texte. Une seconde definition sur « .mk2-place-btns
   button » refaisait le meme travail avec des valeurs legerement differentes
   (bordure #eaeaea au lieu de #d4d4d4) et, etant plus specifique, elle
   ecrasait le blanc de la corbeille au survol — d'ou un bouton rouge a l'icone
   verte. Les deux categories doivent se ressembler : elles partagent donc UNE
   definition, pas deux qui se surveillent. */
.mk2-place-btns button { line-height: 1; }

.mk2-place-hint { margin: 0; color: #8a8c93; font-size: 1.2rem; }

/* Pas de logo = rien a placer. Des controles actifs sur une zone vide
   promettent une action qui ne fait rien. */
/* ---------- Reglages sans objet ----------
   MASQUES, pas grises. Un reglage grise dit « ceci existe et vous ne pouvez
   pas y toucher » — il faut alors deviner ce qui le debloquerait. Ici la
   reponse est toujours la meme et elle est triviale : deposer un logo. Le
   demi-etat n'apporte donc rien, il occupe une place et pose une question.

   Meme regle pour les trois etapes qui n'agissent que sur un fichier :
   detourage, encres, placement. La carte s'ouvre sur la seule zone de depot
   et se remplit a mesure que chaque reglage a un objet. */
.mk2-place.is-off,
.mk2-cutbox.is-off,
.mk2-inks.is-off { display: none; }

/* .mk2-legend n'est plus emise : le nom de la vue est porte par l'onglet
   actif et la couleur par .mk2-bar-color. La regle reste quelques temps au
   cas ou un ancien rendu en cache la referencerait encore. */
.mk2-legend {
    margin: 10px 0 0;
    color: #8a8c93;
}

/* Les messages du module (attente, pas de maquette, vue manquante, panne)
   utilisent .alert-info de Bootstrap — aucune classe maison. Volontairement
   informatifs et jamais en rouge : un produit sans maquette n'est pas une
   panne, c'est un produit dont le graphiste n'a pas encore prepare les
   visuels. */

@media (max-width: 767px) {
    .mk2-bg { max-height: 38vh; }
}

/* ---------- Depot du logo ----------
   Zone maison, pas la lib Dropzone du site : elle est singleton et se serait
   detruite mutuellement avec celle du formulaire de devis (voir mockup2.js).
   Le back-end reste le meme, seule l'interface est propre au module. */

/* Bloc de depot, FRERE de l'alerte et non imbrique dedans : l'alerte dit un
   etat, le depot est une action. Une regle .mk2-upload en flex trainait ici,
   heritee de la version a bouton : elle mettait l'invitation a gauche et la
   zone a droite, reduite a sa largeur de contenu. */
/* Le retrait vertical est porte par pt-3 dans le markup, pas ici. */
.mk2-upload { margin: 0; }

.mk2-dz {
    position: relative;
    width: 100%;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 6px;
    padding: 26px 20px;
    border: 2px dashed rgba(15, 185, 48, .45);
    border-radius: 12px;
    background: #fff;
    cursor: pointer;
    text-align: center;
    transition: border-color .15s, background-color .15s;
}

.mk2-dz:hover,
.mk2-dz.is-over {
    border-color: #0fb930;
    background: #f2faf4;
}

/* L'input couvre toute la zone : le clic n'importe ou l'ouvre, sans label ni
   gestionnaire supplementaire. */
.mk2-dz-input {
    position: absolute;
    inset: 0;
    opacity: 0;
    cursor: pointer;
}

/* L'invitation vit DANS la zone : elle dit pourquoi deposer, la ligne suivante
   dit comment. Dehors, c'etait une legende orpheline a cote d'un cadre. */
.mk2-dz-lead {
    color: #222222;
    font-weight: 500;
    max-width: 62ch;
}

.mk2-dz-ico { font-size: 2.6rem; color: #0fb930; }
.mk2-dz-txt { color: #3f4045; }
.mk2-dz-hint { color: #8a8c93; font-size: 1.2rem; }

/* Pendant l'envoi : la zone ne repond plus et le dit. */
.mk2-dz.is-busy { opacity: .55; pointer-events: none; }

.mk2-dz-err { margin: 8px 0 0; color: #c0392b; }

/* Fichier depose — icone, nom, retrait. Remplace la zone plutot que de
   s'ajouter dessous : un seul fichier est accepte, garder la zone ouverte
   inviterait a en deposer un second. */
.mk2-dz-file {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 12px 14px;
    border: 1px solid #eaeaea;
    border-radius: 12px;
    background: #fff;
}

.mk2-dz-fico { font-size: 2.2rem; color: #0b8f25; }

.mk2-dz-name {
    flex: 1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    color: #222222;
}

.mk2-dz-del {
    flex: 0 0 auto;
    width: 30px;
    height: 30px;
    border: 1px solid #eaeaea;
    border-radius: 6px;
    background: #fff;
    color: #8a8c93;
    cursor: pointer;
    line-height: 1;
}

.mk2-dz-del:hover { background: #c0392b; border-color: #c0392b; color: #fff; }

/* ---------- Colonne droite : detourage, bibliotheque, placement ---------- */

.mk2-select {
    width: 100%;
    height: 38px;
    padding: 0 10px;
    border: 1px solid #d4d4d4;
    border-radius: 8px;
    background: #fff;
    font: inherit;
    color: #3f4045;
}

.mk2-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    padding: 9px 16px;
    border: 1px solid #d4d4d4;
    border-radius: 8px;
    background: #fff;
    color: #3f4045;
    cursor: pointer;
    font: inherit;
}

.mk2-btn:hover { border-color: #0fb930; color: #0b8f25; }

.mk2-btn-ico {
    width: 38px;
    height: 38px;
    border: 1px solid #d4d4d4;
    border-radius: 8px;
    background: #fff;
    color: #3f4045;
    cursor: pointer;
}

.mk2-btn-ico:hover { border-color: #0fb930; color: #0b8f25; }

/* ---------- Bibliotheque de logos ----------
   Grille et non rangee horizontale : la colonne est etroite mais haute, donc
   on gagne en lisibilite verticalement. Chez BigBot la rangee horizontale
   ecrase les vignettes pour tenir en largeur, et on n'identifie plus rien.
   Fond DAMIER : un logo detoure sur une vignette blanche est invisible. */
.mk2-lib { display: flex; flex-direction: column; gap: 8px; }

/* Intitule de liste, pas titre d'etape : pas de rail, sinon « Mes logos
   recents » aurait le meme poids que « Placement ». */
.mk2-lib-title { color: #8a8c93; font-size: 1.2rem; }

/*  VIGNETTES PLUS GRANDES — 2026-10-05.

    56 px laissaient peu de place au logo lui-meme : avec `object-fit: contain`,
    un logo large y tombait a une bande de 20 px de haut, qu'on ne reconnait
    pas. Or c'est tout l'interet de cette bibliotheque — retrouver SON fichier
    d'un coup d'oeil, sans lire le nom.

    Et cet agrandissement sert aussi la cible : le bouton de retrait occupe une
    part bien plus faible de la vignette (voir .mk2-lib-del). */
.mk2-lib-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(76px, 1fr));
    gap: 8px;
}

.mk2-lib-item {
    position: relative;
    aspect-ratio: 1 / 1;
    border: 1px solid #eaeaea;
    border-radius: 8px;
    overflow: hidden;
    cursor: pointer;
    /* Gris clair uni, PAS un damier. Le damier avait ete pose pour signaler la
       transparence, mais la bibliotheque stocke le fichier D'ORIGINE : un logo
       a fond blanc y dessinait un carre blanc opaque par-dessus le damier,
       donc un contour net et parasite. Et c'etait trompeur — sur la maquette
       ce meme logo apparait detoure, le detourage etant applique au rendu.
       Un gris clair suffit a faire ressortir un logo transparent. */
    background-color: #f5f5f5;
}

.mk2-lib-item:hover { border-color: #0fb930; }

/* PAS de padding : avec object-fit: contain, une image carree dans une
   vignette carree remplirait la boite moins le padding, laissant un liseré de
   fond sur les quatre cotes — qui se lisait comme un contour parasite.
   A zero, un logo carre remplit exactement. Un logo non carre garde ses bandes
   de fond sur deux cotes, ce qui est le comportement attendu. */
.mk2-lib-item img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: contain;
}

/*  ⚠️ LE RETRAIT ET LA SELECTION SE DISPUTAIENT LA MEME CIBLE — 2026-10-05.

    Toute la vignette est cliquable pour « utiliser ce logo ». Le bouton de
    retrait etait pose a 2 px du coin, en 20 px, sur une vignette de 56 : il en
    couvrait pres d'un huitieme, et il apparaissait AU SURVOL — c'est-a-dire
    exactement quand le curseur traverse la vignette pour la choisir. Un geste
    de selection pouvait donc supprimer, et ces deux actions ne se valent pas :
    l'une se defait d'un clic, l'autre ne se defait pas.

    Trois changements, qui se cumulent :
      - la vignette passe a 76 px, donc le bouton pese deux fois moins ;
      - il se decolle du bord (4 px) et porte un anneau blanc, qui le detache
        du logo au lieu de s'y confondre ;
      - il ne reagit qu'a son propre survol pour virer au rouge, et le reste du
        temps il est sombre et discret.

    ON NE L'A PAS DEPLACE HORS DE LA VIGNETTE : une corbeille posee a cote
    aurait demande une rangee de plus sous chaque logo, et sur une colonne
    etroite c'est la bibliotheque entiere qui doublait de hauteur. */
.mk2-lib-del {
    position: absolute;
    top: 4px;
    right: 4px;
    width: 22px;
    height: 22px;
    /*  FLEX, et c'est le correctif du mauvais centrage : avec `line-height: 1`
        seul, la croix Font Awesome se calait sur sa ligne de base et pendait
        bas a droite dans son disque. Le centrage optique d'une icone ne se
        fait pas au line-height. */
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    border: 0;
    border-radius: 50%;
    background: rgba(0, 0, 0, .62);
    box-shadow: 0 0 0 2px #fff;
    color: #fff;
    font-size: 1.1rem;
    line-height: 1;
    cursor: pointer;
    opacity: 0;
    transition: opacity .12s, background .12s;
}

.mk2-lib-item:hover .mk2-lib-del,
.mk2-lib-del:focus-visible { opacity: 1; }

.mk2-lib-del:hover { background: #c0392b; }

/* ---------- Bandeau bas : les calques texte ----------
   Une LIGNE par calque, toutes visibles. Pas besoin de selectionner pour
   corriger celui qu'on veut — c'est ce qui distingue ce modele d'un panneau
   de reglages pour le calque actif.
   Ici et pas en colonne droite : une ligne porte un champ plus ses options,
   elle est large par nature. */
.mk2-foot { margin: 18px 0 0; }

/* 4 px entre les rails : assez pour que les filets ne se touchent pas, pas
   assez pour que les lignes cessent de se lire comme une liste. */
.mk2-rows { display: flex; flex-direction: column; gap: 4px; margin: 16px 0 0; }

/* Chaque ligne porte le RAIL, en gris au repos et en vert quand elle est
   active. Pas de bordure fermee : un cadre autour d'une ligne qui contient
   deja des champs bordes faisait cadre dans cadre.

   Le rail est la construction des en-tetes de section du calculateur — filets
   haut et bas qui s'estompent aux extremites, plus un halo central tres
   dilue. Seule la TEINTE change a la selection, jamais la geometrie : la
   ligne ne bouge donc pas d'un pixel. */
.mk2-row {
    /*  Navy au repos, aligné sur --c2-rail-* le 2026-10-03. Le VERT de l'état
        actif (.mk2-row.is-on) est inchangé : c'est lui qui dit la sélection, et
        il ne doit sa lisibilité qu'au contraste avec le repos. */
    --mk2-rail: 182 192 232;
    --mk2-glow: 0 9 84;
    --mk2-glow-a: 0.055;

    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px;
    padding: 16px 14px;
    border: 0;
    border-radius: 0;
    background-color: transparent;
    background-image:
        linear-gradient(to right,
            rgb(var(--mk2-rail) / 0) 0%,
            rgb(var(--mk2-rail) / 1) 12%,
            rgb(var(--mk2-rail) / 1) 88%,
            rgb(var(--mk2-rail) / 0) 100%),
        linear-gradient(to right,
            rgb(var(--mk2-rail) / 0) 0%,
            rgb(var(--mk2-rail) / 1) 12%,
            rgb(var(--mk2-rail) / 1) 88%,
            rgb(var(--mk2-rail) / 0) 100%),
        radial-gradient(60% 80% at 50% 50%,
            rgb(var(--mk2-glow) / var(--mk2-glow-a)) 0%,
            rgb(var(--mk2-glow) / calc(var(--mk2-glow-a) * .62)) 56%,
            rgb(var(--mk2-glow) / 0) 100%);
    background-repeat: no-repeat;
    background-size: 100% 1px, 100% 1px, 100% 100%;
    background-position: top, bottom, center;
    cursor: pointer;
    transition: none;
}

/* Le rail passe au vert. Trois variables, rien d'autre — geometrie inchangee. */
.mk2-row.is-on {
    --mk2-rail: 15 185 48;
    --mk2-glow: 15 185 48;
    --mk2-glow-a: 0.06;
}

.mk2-row-txt {
    flex: 1 1 200px;
    min-width: 0;
    height: 38px;
    padding: 0 10px;
    border: 1px solid #d4d4d4;
    border-radius: 8px;
    font: inherit;
}

.mk2-row-font { flex: 0 0 auto; width: auto; min-width: 140px; }

.mk2-row-col {
    flex: 0 0 auto;
    width: 38px;
    height: 38px;
    padding: 2px;
    border: 1px solid #d4d4d4;
    border-radius: 8px;
    background: #fff;
    cursor: pointer;
}

.mk2-btn-ico.is-on { border-color: #0fb930; background: #0fb930; color: #fff; }

.mk2-row-del:hover { border-color: #c0392b; background: #c0392b; color: #fff; }

/* La vignette active porte le filet vert : c'est elle qui indique quel logo est
   sur la maquette, puisque la zone de depot reste toujours disponible et ne
   porte donc plus l'etat. */
.mk2-lib-item.is-on {
    border: 2px solid #0fb930;
}

/* ---------- Bouton general : effacer la vue ----------
   Pose sur l'image, en haut a droite. Il n'agit ni sur un calque ni sur un
   module : il remet la vue a zero. Le mettre dans la colonne de reglages
   l'aurait fait passer pour un reglage de plus. */
.mk2-stage { position: relative; }

/*  ════════════════════════════════════════════════════════════════════════
    L'INVITATION SUR LA MAQUETTE VIDE — 2026-10-06 (`data-mk2-empty`).

    Le bandeau cyan au-dessus des options ne se lisait pas ; ici on parle la
    ou l'oeil arrive.

    VOILE LEGER + CARTE, et plus un voile blanc a 90 % — corrige le jour
    meme : a 90 % la VRAIE photo du produit se lisait comme une silhouette
    generique de t-shirt (« sur un sac, le t-shirt va etre laid »). C'est
    pourtant bien le produit de la page, dans son coloris. On le laisse donc
    reconnaissable (voile 35 %), et c'est la CARTE au centre qui porte la
    lisibilite du texte.

    `[hidden]` redeclare : le `display: flex` ci-dessous l'emporterait sur
    l'attribut, et le voile resterait pose sur une maquette deja composee. */
.mk2-empty {
    position: absolute;
    inset: 0;
    z-index: 3;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 24px;
    border: 2px dashed transparent;
    border-radius: 12px;
    background: rgba(255, 255, 255, .35);
    text-align: center;
    transition: border-color .15s, background-color .15s;
}

.mk2-empty[hidden] { display: none; }

/*  Un fichier survole la scene : le cadre vert du depot, comme la zone du
    panneau. */
.mk2-empty.is-over {
    border-color: #0fb930;
    background: rgba(240, 251, 242, .55);
}

/*  CARTE « GLASSY » — 2026-10-06. Le blanc a 96 % ne laissait rien voir
    au travers. Verre depoli : fond blanc a 55 %, flou + saturation de ce qui
    est dessous (le produit passe en tache de couleur, le texte reste net),
    liseré clair qui accroche la lumiere. Repli sans `backdrop-filter`
    (vieux navigateurs) : le fond seul, plus opaque, pour rester lisible. */
.mk2-empty-in {
    max-width: 460px;
    padding: 22px 26px;
    border: 1px solid rgba(255, 255, 255, .7);
    border-radius: 14px;
    background: rgba(255, 255, 255, .85);
    box-shadow: 0 10px 32px rgba(0, 9, 84, .16),
                inset 0 1px 0 rgba(255, 255, 255, .8);
}

@supports ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
    .mk2-empty-in {
        background: rgba(255, 255, 255, .55);
        -webkit-backdrop-filter: blur(12px) saturate(160%);
        backdrop-filter: blur(12px) saturate(160%);
    }
}

/*  « Mes logos » dans l'invitation : vignettes carrees cliquables, le
    filet vert au survol dit « ceci va se poser ». */
.mk2-empty-lib .mk2-empty-h { margin-top: 14px; }

.mk2-empty-libg {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 8px;
    margin-top: 8px;
}

.mk2-empty-libi {
    width: 56px;
    height: 56px;
    padding: 4px;
    border: 1px solid #e2e2e2;
    border-radius: 8px;
    background: #fff;
    cursor: pointer;
    transition: border-color .15s, box-shadow .15s;
}

.mk2-empty-libi img { width: 100%; height: 100%; object-fit: contain; }

.mk2-empty-libi:hover,
.mk2-empty-libi:focus-visible {
    outline: none;
    border-color: #0fb930;
    box-shadow: 0 0 0 2px rgba(15, 185, 48, .25);
}

.mk2-empty-ico {
    font-size: 3.2rem;
    color: #0fb930;
}

.mk2-empty-t {
    margin: 12px 0 4px;
    font-size: 1.8rem;
    font-weight: 700;
    color: #1d1e22;
}

.mk2-empty-s {
    margin: 0 0 16px;
    font-size: 1.4rem;
    color: #55575e;
}

.mk2-empty-acts {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 10px;
}

/*  Les deux boutons de l'invitation, plus grands que les actions d'en-tete :
    ici ils SONT l'ecran. */
.mk2-empty-acts .btn-navy {
    height: 38px;
    padding: 0 16px;
    font-size: 1.4rem;
}

.mk2-empty-h {
    margin: 12px 0 0;
    font-size: 1.2rem;
    color: #8a8c93;
}

.mk2-clear {
    position: absolute;
    top: 10px;
    right: 10px;
    width: 34px;
    height: 34px;
    border: 1px solid #c0392b;
    border-radius: 8px;
    background: #fff;
    color: #c0392b;
    cursor: pointer;
    line-height: 1;
    transition: background-color .15s, color .15s, opacity .15s;
}

.mk2-clear:hover { background: #c0392b; color: #fff; }

/*  ════════════════════════════════════════════════════════════════════════
    RIEN A EFFACER : INERTE, MAIS PRESENT — troisieme etat, 2026-10-06.

    Historique, parce qu'il compte :
      1. rouge a 30 % d'opacite  → une « pastille fantome » en haut du visuel ;
      2. masque (`display: none`) → il disparaissait sous le clic qui venait
         de vider la vue, et le user l'a releve comme un BUG : on ne sait plus
         ou il est, ni s'il existe encore.

    Les deux echouaient pour la meme raison : ils parlaient de la COULEUR
    d'action. Un rouge pale reste un rouge, donc une promesse ; une absence
    ne dit rien du tout.

    Ici : forme et taille INCHANGEES — le bouton reste a sa place, on le
    retrouve —, mais en GRIS NEUTRE et pleinement opaque. C'est la grammaire
    d'un controle desactive, pas celle d'un fantome. Voir la doctrine
    « freedom over conditional hides » au vault : un controle se grise, il
    ne disparait pas.

    Le JS pose aussi `disabled` : le bouton refuse le clic lui-meme. */
.mk2-clear.is-off,
.mk2-clear.is-off:hover {
    border-color: #d4d4d4;
    background: #fff;
    color: #b5b7bd;
    cursor: default;
}

/* Poignee de selection en tete de ligne : designer un calque n'est pas la meme
   intention que cliquer dans son champ pour ecrire. */
.mk2-row-grip {
    flex: 0 0 auto;
    width: 22px;
    text-align: center;
    color: #c4c4c4;
    cursor: pointer;
}

.mk2-row.is-on .mk2-row-grip { color: #0fb930; }

/* ---------- Panneau couleur : RVB et Pantone cote a cote ---------- */
.mk2-cp {
    flex: 1 1 100%;
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.4fr);
    gap: 18px;
    /* AUCUNE bordure : le panneau fait partie du rail, il ne s'y ajoute pas.
       Un filet en haut redecoupait la ligne en deux et cassait la continuite
       que le rail venait justement d'etablir. La separation est portee par
       l'espacement seul. */
    margin: 14px 0 0;
    padding: 0 4px;
}

.mk2-cp-side { display: flex; flex-direction: column; gap: 8px; min-width: 0; }

.mk2-cp-title { font-weight: 700; color: #222222; }

.mk2-cp-pick { display: flex; align-items: center; gap: 8px; }

/* Carree et fixe : c'est un echantillon de couleur, pas un champ. L'etirer sur
   toute la largeur lui donnait l'importance d'une zone de saisie. */
.mk2-cp-native {
    flex: 0 0 auto;
    width: 44px;
    height: 44px;
    padding: 2px;
    border: 1px solid #d4d4d4;
    border-radius: 8px;
    background: #fff;
    cursor: pointer;
}

.mk2-cp-pick .mk2-cp-hex { flex: 1 1 auto; min-width: 0; height: 44px; }

.mk2-cp-hex,
.mk2-cp-search {
    width: 100%;
    height: 38px;
    padding: 0 10px;
    border: 1px solid #d4d4d4;
    border-radius: 8px;
    font: inherit;
}

.mk2-cp-tbl { width: 100%; font-size: 1.2rem; }
.mk2-cp-tbl td { padding: 4px 0; }
.mk2-cp-tbl td:first-child { color: #8a8c93; width: 34%; }

/* Grille defilante : 1342 teintes, on en rend 400 au plus et la recherche
   filtre le reste. Tout afficher figerait le navigateur. */
.mk2-pt-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, 22px);
    gap: 3px;
    max-height: 220px;
    overflow-y: auto;
    padding: 4px;
    border: 1px solid #eaeaea;
    border-radius: 8px;
}

.mk2-pt {
    width: 22px;
    height: 22px;
    border: 1px solid rgba(0, 0, 0, .08);
    border-radius: 4px;
    cursor: pointer;
    padding: 0;
}

.mk2-pt:hover { outline: 2px solid #0fb930; outline-offset: 1px; }
.mk2-pt.is-on { outline: 2px solid #091017; outline-offset: 1px; }

.mk2-row-col {
    flex: 0 0 auto;
    width: 38px;
    height: 38px;
    border: 1px solid #d4d4d4;
    border-radius: 8px;
    cursor: pointer;
    padding: 0;
}

/* Separateur entre groupes de boutons, convention des editeurs de texte :
   contenu | typographie | placement | suppression. Huit icones a la suite se
   lisent comme une rangee indifferenciee ; groupees, on trouve du premier
   coup d'oeil. */
.mk2-sep {
    flex: 0 0 auto;
    width: 1px;
    height: 24px;
    margin: 0 3px;
    background: #e0e0e0;
}

/* ---------- Focus des champs ----------
   Le contour noir par defaut du navigateur est brutal sur un rail clair, et il
   ne dit rien du vocabulaire de la page. On reprend le focus du champ de
   quantite du calculateur : filet vert fin + halo tres dilue. Meme signal
   partout, et il ne crie pas. */
.mk2-row-txt:focus,
.mk2-select:focus,
.mk2-cp-hex:focus,
.mk2-cp-search:focus {
    outline: none;
    border-color: #0fb930;
    box-shadow: 0 0 0 3px rgba(15, 185, 48, .14);
}

/* Focus clavier des boutons : visible mais dans la meme langue. */
.mk2-btn-ico:focus-visible,
.mk2-btn:focus-visible,
.mk2-row-col:focus-visible,
.mk2-pt:focus-visible {
    outline: 2px solid #0fb930;
    outline-offset: 2px;
}

/* ====================== Encres du logo ======================
   Meme grammaire que la pastille d'un calque texte : meme taille, meme rayon,
   meme anneau vert a l'ouverture. Une encre et une couleur de texte se
   choisissent de la meme facon, elles doivent donc se ressembler.

   La difference est le NUMERO : avec deux ou quatre pastilles cote a cote,
   rien ne dit laquelle est la premiere couleur. Le chiffre le dit, et il
   correspond a l'ordre d'importance detecte sur le logo. */

.mk2-ink-row {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
}

.mk2-ink {
    position: relative;
    flex: 0 0 auto;
    width: 38px;
    height: 38px;
    padding: 0;
    border: 1px solid #d4d4d4;
    border-radius: 8px;
    cursor: pointer;
}

.mk2-ink.is-on { border-color: #0fb930; box-shadow: 0 0 0 2px rgb(15 185 48 / .25); }

/* Cercle blanc cercle de noir : le chiffre doit rester lisible sur une encre
   claire comme sur une encre sombre, et on ne peut pas savoir laquelle a
   l'avance. */
.mk2-ink-n {
    position: absolute;
    right: -3px;
    bottom: -3px;
    min-width: 15px;
    height: 15px;
    padding: 0 3px;
    border: 1px solid #2b2b2b;
    border-radius: 9px;
    background: #fff;
    color: #2b2b2b;
    font-size: 10px;
    line-height: 13px;
    font-weight: 600;
}

/* Teinte imposee : ni curseur main, ni anneau au survol. La pastille INFORME,
   elle n'invite pas. */
.mk2-ink.is-fixed { cursor: default; opacity: .9; }

.mk2-ink-note {
    margin: 6px 0 0;
    color: #6b6b6b;
    font-size: 12px;
    line-height: 1.35;
}

/* Corbeille : rouge des le repos, pas seulement au survol. C'est la seule
   action irreversible de la ligne — elle doit se distinguer AVANT le clic,
   pas pendant. */
.mk2-row-del { color: #c62828; }
.mk2-row-del:hover { border-color: #c62828; background: #c62828; color: #fff; }

/* ====================== Cartes de la maquette ======================
   Deux cartes, deux sujets : le logo a droite, le texte en bas. L'entete nomme
   le sujet une fois, et les titres internes redeviennent des etapes plutot que
   six blocs autonomes empiles.

   Filet gris et non aplat vert : le bandeau « Votre maquette personnalisee »
   est deja un aplat vert plein juste au-dessus. Deux verts qui se suivent se
   font concurrence, et la carte n'a pas a crier plus fort que la section qui
   la contient. */
.mk2-card {
    display: block;
    border: 1px solid #e4e4e4;
    border-radius: 10px;
    background: #fff;
    overflow: hidden;          /* les coins arrondis rognent l'entete */
}

.mk2-card-head {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 10px 14px;
    border-bottom: 1px solid #ededed;
    background: #fafafa;
    color: #2b2b2b;
    font-weight: 600;
    line-height: 1.2;
}

/* Icone de titre de carte (« Votre logo », « Votre texte », « Couleurs de
   votre maquette ») : la couleur du texte, comme les icones d'etape
   (.mk2-side-title > i) — 2026-10-14, une teinte pour un role. Enfant DIRECT
   seulement : l'icone d'un bouton pose dans l'entete (« Blanc du logo »,
   .btn-navy) garde la couleur de son bouton. */
.mk2-card-head > i { color: #222222; }

/* 1rem franc, la valeur d'un p-3 Bootstrap. A 14px le contenu frolait la
   bordure et l'entete : la carte paraissait tassee meme une fois les etapes
   espacees entre elles, parce que c'est le POURTOUR qui manquait, pas
   l'interligne. */
.mk2-card-body { padding: 1rem; }

/* .mk2-foot ne portait qu'une marge haute ; elle reste, la carte fait le
   reste. Le bouton « Ajouter du texte » et la liste des lignes vivent
   desormais dans .mk2-card-body, donc leur marge interieure vient de la. */
.mk2-foot.mk2-card .mk2-rows { margin-top: 12px; }



/* ---------- Precision libre ----------
   Une carte comme les autres, parce que c'est un module de la maquette au
   meme titre que le logo et le texte — pas un champ orphelin pose en bas. */
.mk2-memo { margin-top: 16px; }

/* La mention « facultatif » est poussee a droite de l'entete : elle repond a
   la question qu'on se pose en lisant le titre, au moment ou on se la pose. */
.mk2-opt {
    margin-left: auto;
    color: #8a8c93;
    font-weight: 400;
    font-size: 1.2rem;
}

.mk2-memo-txt {
    width: 100%;
    padding: 10px 12px;
    border: 1px solid #d4d4d4;
    border-radius: 8px;
    color: #3f4045;
    line-height: 1.4;
    resize: vertical;
}

.mk2-memo-txt::placeholder { color: #a8aab0; }

/*  ════════════════════════════════════════════════════════════════════════
    LE BILAN DE COULEURS — entre les cartes de marquage et le visuel.

    ⛔ PLUS DE CADRE « VITRE » — remplace le 2026-10-06 par la carte standard
    (`.mk2-card`, la meme que « Votre logo » et « Votre texte »). Le fond
    translucide et le flou en faisaient une zone d'une autre famille que ses
    voisines ; c'est un bloc de la maquette comme les autres. Seuls le
    conteneur exterieur et le contenu propre au bilan (liste, total,
    pastilles) gardent des regles ici — l'habillage vient de `.mk2-card`.

    Depuis le 2026-10-06 il vit A DROITE des cartes de marquage, dans le
    meme conteneur flex (`.mk2-sel`) : c'est ce conteneur qui porte l'espace
    avant le visuel, plus le bilan lui-meme.                                */
.mk2-sel {
    display: flex;
    align-items: flex-start;
    gap: 16px;

    /*  16 px en haut : l'ecart que la fente des options portait seule sous
        les onglets — voir la regle juste en dessous, qui le lui retire. */
    margin: 16px 0 18px;
}

/*  ⛔ LA FENTE PERD SON RETRAIT HAUT DANS LA RANGEE — correctif du
    2026-10-06.

    `[data-mk2-slot]:not(:empty)` lui donne `padding: 16px 0 4px`, pense pour
    l'epoque ou elle etait seule sous les onglets. Depuis que le bilan est son
    voisin dans `.mk2-sel`, ce padding ne s'appliquait qu'a ELLE : les cartes
    d'options demarraient 16 px plus bas que la carte du bilan, deux hauts de
    carte decales sur une meme rangee.

    L'ecart vit desormais sur le conteneur commun, une seule fois, pour les
    deux. Trois selecteurs (classe, attribut, pseudo-classe) contre deux :
    l'emporte par la specificite, pas par l'ordre du fichier.            */
.mk2-sel > [data-mk2-slot]:not(:empty) { padding-top: 0; }

/*  La fente prend TOUT l'espace restant : seule quand le bilan est masque
    (pas de logo), aux deux tiers quand il est la. `min-width: 0` sans quoi la
    grille d'options refuserait de passer sous sa largeur de contenu. */
.mk2-sel-opts {
    flex: 1 1 auto;
    min-width: 0;
}

.mk2-bilan {
    flex: 0 0 calc(33.333% - 11px);
    min-width: 0;
}

.mk2-bilan.is-off { display: none; }

/*  SOUS 992 px, les deux s'empilent : un tiers d'ecran de telephone ne
    tient ni la liste ni le bouton. Le bilan repasse sous les options, a la
    place qu'il avait avant. */
@media (max-width: 991.98px) {
    .mk2-sel { flex-direction: column; align-items: stretch; }
    .mk2-bilan { flex-basis: auto; }
}

/*  LE BILAN PORTE L'HABILLAGE DES CARTES DE TECHNIQUE (`.calc2-mark-card`,
    calculator.css) depuis le 2026-10-06 : seuls l'icone et le corps lui sont
    propres.

    L'en-tete des cartes de technique n'a pas d'icone, donc pas de flex : on
    l'ajoute ICI, pour le bilan seul, sans toucher a celui des techniques.
    L'icone en navy — elle dit « information », les cartes voisines ne
    reglent rien d'autre que ce qu'elles nomment.                         */
.mk2-bilan-card .calc2-mark-card-h {
    display: flex;
    align-items: center;
    gap: 8px;
}

/*  `> i` : l'icone du TITRE seule. Un `i` descendant attrapait aussi celle
    du bouton « Adapter mon logo » une fois monte dans l'en-tete — navy sur
    fond navy, invisible. */
.mk2-bilan-card .calc2-mark-card-h > i { color: #000954; }

/*  Meme rembourrage que le corps des cartes de technique (`.calc2-mark-opts`,
    14 px) : les contenus des cartes voisines demarrent a la meme distance de
    leur bord. */
.mk2-bilan-b { padding: 14px; }

/*  LE BOUTON QUI MENE A « ADAPTER MON LOGO ».

    Navy plein, vert au survol : la grammaire des actions secondaires du
    calculateur (« Détail », « Modifier »). Pas de vert au repos — il voudrait
    dire « deja applique ». Il ne modifie rien, il emmene.

    DANS L'EN-TETE depuis le 2026-10-06, pousse a droite (`margin-left:
    auto`) et a la taille compacte des actions d'en-tete (26 px, comme le
    « Modifier » du recapitulatif) : a 34 px il faisait gonfler l'en-tete
    au-dela de celui des cartes voisines. */
/*  Habillage : `.btn-navy` (calculator.css), depuis le 2026-10-06. Ici, sa
    seule place : poussee a droite, marges negatives pour ne pas grandir
    l'en-tete au-dela de celui des cartes voisines. */
.mk2-bilan-cta {
    margin: -4px 0 -4px auto;
}

/*  LA MISE EN EVIDENCE DU MENU a l'arrivee : un anneau vert qui pulse deux
    fois puis s'eteint. Breve parce qu'elle DESIGNE — une fois l'oeil arrive,
    elle n'a plus rien a dire et ne doit pas rester comme une alerte. */
.mk2-cutbox.is-hint {
    border-radius: 10px;
    animation: mk2-hint 1.6s ease-out;
}

@keyframes mk2-hint {
    0%, 50%  { box-shadow: 0 0 0 0 rgba(15, 185, 48, .45); }
    25%, 75% { box-shadow: 0 0 0 8px rgba(15, 185, 48, 0); }
    100%     { box-shadow: 0 0 0 0 rgba(15, 185, 48, 0); }
}

/*  Qui demande moins de mouvement n'a pas l'animation — l'ouverture du
    menu suffit a designer l'endroit. */
@media (prefers-reduced-motion: reduce) {
    .mk2-cutbox.is-hint { animation: none; }
}

.mk2-bilan-list {
    list-style: none;
    margin: 0;
    padding: 0;
}

.mk2-bilan-list li {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 12px;
    padding: 3px 0;
    color: #6a6d75;
}

.mk2-bilan-v { white-space: nowrap; }

/*  Le total se detache par un filet, pas par un fond : le cadre porte deja
    une couleur, un second aplat dedans ferait une boite dans une boite. */
.mk2-bilan-tot {
    display: flex;
    align-items: center;
    gap: 10px;
    margin: 8px 0 0;
    padding: 9px 0 0;
    border-top: 1px solid rgba(16, 24, 56, .10);
    font-weight: 600;
    color: #222;
}

.mk2-bilan-tot-v { margin-left: auto; white-space: nowrap; }

.mk2-bilan-dots { display: flex; gap: 4px; }

/*  Filet sombre translucide plutot que blanc : une encre blanche sur un
    cadre clair serait invisible, et c'est justement un cas frequent. */
.mk2-bilan-dot {
    width: 16px;
    height: 16px;
    border-radius: 4px;
    border: 1px solid rgba(16, 24, 56, .25);
}

.mk2-bilan-note,
.mk2-bilan-hint {
    margin: 8px 0 0;
    color: #6a6d75;
}

/*  ════════════════════════════════════════════════════════════════════════
    « ADAPTER MON LOGO » — menu a familles, 2026-10-06.

    Remplace le <select> natif « Fond du logo ». Le bouton ferme reprend
    EXACTEMENT la geometrie de `.mk2-select` (38 px, filet #d4d4d4, rayon
    8 px) : c'est le meme controle, au meme endroit, qui fait plus de choses.
    L'acheteur ne doit pas croire a un nouvel outil.

    Les options sont des CASES (a cocher) et non des puces radio, alors
    qu'une famille n'en admet qu'une : re-cliquer une case cochee la
    decoche, ce qu'une puce radio ne sait pas faire. « Rien de coche » est
    un etat legitime — le logo original — et il doit rester atteignable. */
.mk2-xf { position: relative; }

.mk2-xf-btn {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    width: 100%;
    height: 38px;
    padding: 0 12px;
    border: 1px solid #d4d4d4;
    border-radius: 8px;
    background: #fff;
    font: inherit;
    color: #3f4045;
    text-align: left;
    cursor: pointer;
}

.mk2-xf-btn:focus-visible,
.mk2-xf-btn[aria-expanded="true"] {
    outline: none;
    border-color: #0fb930;
    box-shadow: 0 0 0 3px rgba(15, 185, 48, .14);
}

.mk2-xf-val {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/*  Le menu se pose PAR-DESSUS les reglages du dessous, sans les pousser :
    deplie, il ne doit pas faire sauter la colonne. */
.mk2-xf-menu {
    position: absolute;
    z-index: 20;
    top: calc(100% + 4px);
    left: 0;
    right: 0;
    padding: 6px;
    border: 1px solid #d4d4d4;
    border-radius: 8px;
    background: #fff;
    box-shadow: 0 6px 18px rgba(16, 24, 56, .12);
}

.mk2-xf-menu[hidden] { display: none; }

/*  Titre de famille : petit, gris, non cliquable — il groupe, il n'agit pas. */
.mk2-xf-fam {
    padding: 8px 8px 4px;
    font-size: 1.2rem;
    font-weight: 600;
    color: #8a8c93;
    text-transform: uppercase;
    letter-spacing: .03em;
}

.mk2-xf-opt {
    display: flex;
    align-items: center;
    gap: 10px;
    width: 100%;
    padding: 8px;
    border: 0;
    border-radius: 6px;
    background: none;
    font: inherit;
    color: #3f4045;
    text-align: left;
    cursor: pointer;
}

.mk2-xf-opt:hover { background: #f6f6f7; }

/*  La case : vide au repos, VERTE et cochee quand l'option est appliquee.
    Le vert est ici a sa place — il dit « ceci est applique a ton logo »,
    exactement ce qu'il signifie dans le reste du calculateur. */
.mk2-xf-box {
    position: relative;
    flex: 0 0 auto;
    width: 18px;
    height: 18px;
    border: 1.5px solid #b5b7bd;
    border-radius: 4px;
    background: #fff;
}

.mk2-xf-opt.is-on .mk2-xf-box {
    border-color: #0fb930;
    background: #0fb930;
}

.mk2-xf-opt.is-on .mk2-xf-box::after {
    content: "";
    position: absolute;
    left: 5px;
    top: 1px;
    width: 5px;
    height: 10px;
    border: solid #fff;
    border-width: 0 2px 2px 0;
    transform: rotate(45deg);
}

/* ====================== PAS DE MAQUETTE (2026-10-18) ======================
   Les emplacements dont la vue n'est pas utilisable pour le coloris
   ([data-mk-marks], hors du corps de la maquette) : un titre d'emplacement,
   puis le meme bloc que la fente. Vide = aucun espace. */
.nm-marks:empty { display: none; }
.nm-marks { padding-top: 16px; }
.nm-mark + .nm-mark { padding-top: 16px; }
.nm-mark-name {
    font-weight: 700;
    color: #000954;
    padding-bottom: 8px;
}
/* ============================================================================
   Infobulle unique du calculateur v2
   ----------------------------------------------------------------------------
   Pas de selecteur de contexte (#calc2-widget ...) : la bulle vit sur <body>,
   volontairement hors de toute colonne en overflow: hidden. C'est ce qui lui
   permet de deborder du cadre de la maquette, ce que la version en ::after ne
   pouvait pas faire.
   ========================================================================== */

.tip2 {
    position: fixed;
    z-index: 2000;              /* au-dessus des modales Bootstrap (1055) */
    max-width: 280px;
    padding: 8px 10px;
    border-radius: 8px;
    background: #091017;
    color: #fff;
    font-size: 12px;
    line-height: 1.4;
    text-align: left;
    white-space: normal;
    pointer-events: none;       /* ne vole jamais le survol a sa cible */
    opacity: 0;
    visibility: hidden;
    transition: opacity .12s ease;
    box-shadow: 0 6px 18px rgb(0 0 0 / .22);
}

.tip2.is-on { opacity: 1; visibility: visible; }

/* Fleche : un carre pivote, aligne sur le declencheur via --tip2-ax, que le
   module met a jour. Quand la bulle a ete recalee contre un bord de l'ecran,
   son centre n'est plus celui de la cible — une fleche fixee a 50 % pointerait
   alors a cote. */
.tip2::after {
    content: "";
    position: absolute;
    top: 100%;
    left: var(--tip2-ax, 50%);
    width: 8px;
    height: 8px;
    margin-top: -4px;
    transform: translateX(-50%) rotate(45deg);
    background: #091017;
}

.tip2.is-below::after { top: 0; margin-top: -4px; }

/* ---------- Carte couleur ----------
   Meme tableau que le panneau de la maquette, en plus compact. L'acheteur
   retrouve les memes cinq lignes dans le meme ordre : ce qu'il lit au survol
   est ce qu'il verra en ouvrant le panneau. */
.tip2-color { max-width: 220px; }

.tip2-chip {
    display: block;
    height: 22px;
    margin-bottom: 6px;
    border: 1px solid rgb(255 255 255 / .35);
    border-radius: 4px;
}

.tip2-tbl {
    width: 100%;
    border-collapse: collapse;
    font-size: 11px;
}

.tip2-tbl td {
    padding: 1px 0;
    vertical-align: top;
}

/* Colonne des intitules en retrait : c'est la VALEUR qu'on vient lire, elle
   doit sortir la premiere. */
.tip2-tbl td:first-child {
    width: 42px;
    color: #9fb0c0;
    text-transform: uppercase;
    font-size: 10px;
    letter-spacing: .02em;
}

.tip2-tbl td:last-child {
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

/* ============================================================================
   Formulaire de devis allege (calculateur v2)
   ----------------------------------------------------------------------------
   Meme vocabulaire que le calculateur et la maquette : carte a filet gris,
   champs a rayon 8, vert reserve au focus et a la selection, orange pour
   l'action finale. Rien de nouveau n'est invente ici — c'est une section de
   plus de la meme page, pas un composant importe.
   ========================================================================== */

/*  40 px : l'ecart qui SEPARE le formulaire du calculateur, a l'interieur du
    meme conteneur de parcours (.calc2-flow, voir Product/DisplayV2). C'est la
    valeur des sections a l'interieur du calculateur — le formulaire en est la
    derniere, pas un nouveau chapitre de la page. */
.calc2-quote { margin-top: 40px; }

/*  Sur un produit SANS calculateur, le formulaire est seul : la marge n'a
    plus rien a separer et s'ajouterait au padding du conteneur. Une marge de
    separation ne doit jamais faire office de marge de tete. */
.calc2-flow > .calc2-quote:first-child { margin-top: 0; }

.calc2-quote-box {
    border: 1px solid #e4e4e4;
    border-radius: 10px;
    background: #fff;
    padding: 20px;
}

/* Deux colonnes a partir du moment ou la ligne est assez large. Sur mobile,
   une seule : des champs a moitie larges y deviennent illisibles et le clavier
   masque de toute facon le reste du formulaire. */
.calc2-q-grid {
    display: grid;
    grid-template-columns: 1fr;
    gap: 14px;
}

@media (min-width: 576px) {
    .calc2-q-grid { grid-template-columns: 1fr 1fr; }
    .calc2-q-full { grid-column: 1 / -1; }
}

.calc2-q-field { display: flex; flex-direction: column; gap: 6px; }

.calc2-q-field label {
    margin: 0;
    color: #222222;
    font-weight: 600;
    line-height: 1.2;
}

/* L'asterisque est ROUGE et la mention facultative GRISE : les deux signaux
   sont lisibles sans lire, et ils ne disent pas la meme chose. */
.calc2-q-req { color: #c62828; }
.calc2-q-opt { color: #8a8c93; font-weight: 400; }

.calc2-q-input {
    width: 100%;
    padding: 10px 12px;
    border: 1px solid #d4d4d4;
    border-radius: 8px;
    background: #fff;
    color: #3f4045;
    line-height: 1.3;
}

/* Meme focus que partout ailleurs : filet vert fin et halo tres dilue. Le
   contour noir du navigateur est brutal sur un fond clair et ne dit rien du
   vocabulaire de la page. */
.calc2-q-input:focus {
    outline: none;
    border-color: #0fb930;
    box-shadow: 0 0 0 3px rgb(15 185 48 / .12);
}

.calc2-q-input::placeholder { color: #a8aab0; }

/* ---------- Livraison repliee ---------- */
.calc2-q-ship { margin-top: 16px; }

/* Pas de style de case ici : le formulaire utilise .checkbox .checkbox-success
   du gabarit (page_items.css). Une definition locale aurait donne deux cases
   differentes sur le meme site, et c'est precisement ce qu'on evite ailleurs
   en partageant une seule definition. On ne reprend que le poids du libelle,
   pour qu'il pese comme les autres etiquettes du formulaire. */
/* Le demarcateur : rail global + la case du gabarit. On ne reprend ici que
   ce qui leur est propre — l'alignement vertical de la case sur le libelle,
   que .checkbox ne gere pas quand son conteneur a du padding-block. */
.calc2-q-ship-head {
    display: flex;
    align-items: center;
    margin: 4px 0 0;
}

.calc2-q-ship-head label { margin: 0; color: #222222; font-weight: 600; }

/* Le bloc ouvert est RETRAIT derriere un filet : il dit « ceci depend de la
   case au-dessus » sans qu'on ait a l'ecrire.

   TEINTE NAVY depuis le 2026-10-03, comme les rails. Le gris neutre #e4e4e4
   etait le dernier filet du formulaire a ne rien dire du site, juste sous un
   rail desature vers le navy : deux filets de teintes differentes a quelques
   pixels l'un de l'autre se lisent comme deux systemes.

   Meme valeur que .calc2-pop-intro — c'est le meme geste, un filet lateral qui
   rattache un bloc a ce qui le precede sans l'enfermer dans un cadre. */
.calc2-q-ship-box {
    margin-top: 14px;
    padding-left: 14px;
    border-left: 2px solid rgb(0 9 84 / .35);
}

/* ---------- Envoi ---------- */

/* Pleine largeur : c'est la seule action de la section, rien ne lui dispute
   la ligne, et un bouton large est plus sur au doigt. */
.calc2-q-send {
    display: block;
    width: 100%;
    margin-top: 20px;
    padding: 14px 20px;
    font-weight: 700;
}

.calc2-q-foot {
    margin: 10px 0 0;
    color: #8a8c93;
    font-size: 1.2rem;
    text-align: center;
}

/* ====================== Complétion d'adresse ======================
   Le défaut du modèle observé chez le concurrent : une ligne de texte brute
   par résultat, toutes du même poids, et une liste qui déborde du champ sans
   s'y raccrocher. On lit cinq fois la même chose avant de repérer laquelle
   est la bonne.

   Ici chaque ligne porte DEUX niveaux : la voie en noir, le code postal et la
   ville en gris. Comme les voies se ressemblent souvent (« Avenue Thiers » à
   Bordeaux, Nice, Saint-Maur), c'est le second niveau qui fait le choix — il
   doit donc être lisible séparément, pas noyé dans la même phrase. */

.addr-wrap { position: relative; }

.addr-list {
    position: absolute;
    z-index: 30;
    top: calc(100% + 4px);
    left: 0;
    right: 0;                    /* exactement la largeur du champ : la liste
                                    prolonge le champ, elle ne flotte pas à côté */
    max-height: 264px;
    overflow-y: auto;
    border: 1px solid #d4d4d4;
    border-radius: 8px;
    background: #fff;
    box-shadow: 0 8px 22px rgb(0 0 0 / .10);
}

.addr-item {
    display: flex;
    align-items: baseline;       /* aligne les deux niveaux sur la ligne de
                                    base, pas sur leurs boîtes : sans ça le
                                    gris flotte d'un pixel sous le noir */
    gap: 8px;
    width: 100%;
    padding: 9px 12px;
    border: 0;
    border-bottom: 1px solid #f0f0f0;
    background: none;
    text-align: left;
    cursor: pointer;
    line-height: 1.35;
}

.addr-item:last-child { border-bottom: 0; }

/* Même vert que partout, et le MÊME état pour le survol et la navigation au
   clavier : deux mises en évidence différentes feraient croire à deux choses
   différentes. */
.addr-item:hover,
.addr-item.is-on { background: rgb(15 185 48 / .10); }

.addr-line {
    flex: 1 1 auto;
    min-width: 0;
    color: #222222;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* La partie tapée, mise en gras par le module. Poids seul, pas de couleur :
   sur cinq lignes, cinq fragments colorés feraient du bruit. */
.addr-line b { font-weight: 700; }

.addr-detail {
    flex: 0 0 auto;
    color: #8a8c93;
    font-size: 1.2rem;
    white-space: nowrap;
}

/* ---------- Erreurs de validation ----------
   Message SOUS le champ concerné, jamais en liste en tête de formulaire : une
   liste oblige à faire l'aller-retour entre le reproche et le champ, et
   devient illisible passé deux lignes.

   Rouge sur la bordure ET texte : la bordure seule se rate sur un formulaire
   dense, le texte seul ne dit pas quel champ quand deux se suivent. */
.calc2-q-input.is-invalid { border-color: #c62828; }

.calc2-q-input.is-invalid:focus {
    border-color: #c62828;
    box-shadow: 0 0 0 3px rgb(198 40 40 / .12);
}

.calc2-q-err {
    margin: 4px 0 0;
    color: #c62828;
    font-size: 1.2rem;
    line-height: 1.35;
}

/* L'erreur d'envoi vit sous le bouton, pas sous un champ : elle ne reproche
   rien à une saisie, elle dit que le trajet a échoué. */
.calc2-q-err-fatal { margin-top: 10px; text-align: center; }

/* Bouton verrouille pendant l'envoi.
   Le module le desactive pour qu'un double clic ne parte pas deux fois, mais
   le theme n'a aucun style :disabled — le bouton restait identique, et il
   virait meme au noir au survol comme s'il etait actif. On le rend
   visiblement inerte.

   Porte ICI et non sur .default-btn : la regle vaut pour ce bouton-la, pas
   pour les centaines d'autres du site qu'on ne desactive jamais. */
.calc2-q-send:disabled {
    opacity: .6;
    cursor: default;
}

.calc2-q-send:disabled:hover {
    background-color: var(--color-default);   /* pas de noir : rien ne repond */
}

/* ---------- Confirmation ----------
   Occupe la place du formulaire qu'elle remplace : rien ne bouge sous les yeux
   de l'acheteur au moment ou il attend une preuve que sa demande est partie. */
.calc2-q-done { text-align: center; padding: 20px 10px; }

/*  La GRANDE coche verte seulement — enfant DIRECT. En `.calc2-q-done i`, la
    regle grossissait aussi l'icone du bouton « Voir mon devis » (2026-10-12). */
.calc2-q-done > i {
    font-size: 3.4rem;
    color: #0fb930;
    margin-bottom: 12px;
}

/*  « Voir mon devis » — un <a> qui porte .default-btn : en ligne par defaut,
    il ne centrait ni son texte ni son icone. On le pose en flex, et l'icone
    prend la taille et la couleur du texte du bouton. */
.calc2-q-done .calc2-q-done-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: .8rem;
    padding: 0 2.4rem;
    margin-top: 1.6rem;
    text-decoration: none;
}

    .calc2-q-done .calc2-q-done-btn i {
        font-size: inherit;
        color: inherit;
        margin: 0;
    }

.calc2-q-done h3 {
    margin: 0 0 8px;
    color: #222222;
    font-weight: 700;
}

.calc2-q-done p { margin: 0 0 6px; color: #3f4045; }

/* La mention « indésirables » est une precaution, pas l'information
   principale : elle ne doit pas peser autant que la confirmation. */
.calc2-q-done-hint { color: #8a8c93; font-size: 1.2rem; }

/* Repli de confirmation quand Bootstrap est absent : meme place que le
   message d'erreur d'envoi, mais en vert. Annoncer un succes dans le style
   d'une erreur ferait croire a un echec. */
.calc2-q-ok {
    margin-top: 10px;
    color: #0b8f25;
    font-weight: 600;
    text-align: center;
}

/* ====================== Demande d'information (produit sans calculateur) ======
   Meme presentation que le devis : ces deux ecrans occupent la meme place sur
   la page produit et concluent le meme parcours. Seuls les elements qui leur
   sont propres sont definis ici. */

/* Le chapo explique POURQUOI il n'y a pas de prix. Sans lui, un acheteur
   habitue au calculateur croit a une panne. */
.calc2-req-lead {
    margin: 0 0 20px;
    color: #3f4045;
    line-height: 1.5;
}

/* Zone de texte : meme champ que les autres, en plus haut. Redimensionnable
   verticalement seulement — en largeur elle sortirait de la grille. */
.calc2-q-area {
    min-height: 120px;
    line-height: 1.45;
    resize: vertical;
}

.calc2-q-files { margin-top: 18px; }

.calc2-q-files > label {
    display: block;
    margin: 0 0 8px;
    color: #222222;
    font-weight: 600;
}

/* Le conteneur reserve sa hauteur pendant le chargement AJAX, pour la meme
   raison que le corps des modales : sans elle, la page grandit d'un coup a
   l'arrivee du formulaire et tout ce qui suit saute. */
.calc2-req-host:empty {
    display: block;
    min-height: 420px;
}

/* ---------- Formulaires EN PAGE : pas de carte ----------
   La boite bordee servait a detacher le formulaire dans une popup. En page,
   la section a deja son bandeau de titre et occupe toute la largeur : le
   cadre ajoute une boite dans une boite, et le fond blanc sur blanc ne
   delimite rien.

   La popup, elle, GARDE sa carte : c'est ce qui l'assoit dans la modale. */
.calc2-quote > .calc2-quote-box {
    padding: 0;
    border: 0;
    background: none;
}

/* Le chapo n'a plus la marge interieure de la carte pour le decoller du
   bandeau. */
.calc2-req-lead { margin-top: 4px; }

/*  Les surcharges de intl-tel-input ont ete DEPLACEES dans page_items.css
    (global) le 2026-09-26 : le formulaire de contact porte lui aussi un champ
    telephone, et il ne charge pas ce bundle-ci. Une surcharge de bibliotheque
    n'appartient a aucune page en particulier. */

/* ---------- Champ numerique court ----------
   Une quantite tient en quatre chiffres. Sur toute la largeur, le champ
   promet une saisie longue et casse le rythme de la grille — l'oeil cherche
   ce qu'il faut ecrire d'autre.

   Le conteneur garde sa pleine largeur (l'etiquette se lit a sa place
   normale), c'est le CHAMP qui est court. */
.calc2-q-num {
    max-width: 180px;
    /* Aligne a GAUCHE : a droite, la valeur venait toucher les fleches. */
    font-variant-numeric: tabular-nums;
}

/* Les FLECHES NATIVES sont conservees : elles disent d'un coup d'oeil que le
   champ attend un nombre, et elles permettent d'ajuster sans retaper. Avec
   step=1 et min=1, elles produisent des entiers — pas de demi-piece.

   Une version precedente les masquait au motif qu'elles ajoutent du bruit.
   C'etait faire passer l'esthetique avant l'affordance sur le seul champ de
   la page ou le type de donnee n'est pas evident. */
.calc2-q-num::-webkit-outer-spin-button,
.calc2-q-num::-webkit-inner-spin-button {
    opacity: 1;              /* Chrome les cache tant que le champ n'a pas le focus */
    height: 28px;
}

/* ---------- Champ refuse par la validation serveur ----------
   MVC pose « input-validation-error » sur les champs en faute au re-rendu du
   partial. Le bandeau d'erreur parle de « champs en rouge » : encore faut-il
   qu'ils le soient. */
.calc2-q-input.input-validation-error {
    border-color: #c62828;
}

.calc2-q-input.input-validation-error:focus {
    border-color: #c62828;
    box-shadow: 0 0 0 3px rgb(198 40 40 / .12);
}

/* Message sous le champ. Meme classe que le devis : une erreur se lit au
   meme endroit sur les deux formulaires. */
.field-validation-error { display: block; }

/* ---------- Recapitulatif de la confirmation ----------
   Deux colonnes serrees, centrees sous le message. Volontairement DISCRET :
   l'information principale est que la demande est partie, le recapitulatif
   n'est la que pour reperer une faute de frappe dans l'e-mail.

   En <dl> et non en tableau : ce sont des paires libelle/valeur, pas des
   donnees a comparer ligne a ligne. */
.calc2-q-recap {
    display: grid;
    grid-template-columns: auto auto;
    justify-content: center;
    gap: 4px 16px;
    margin: 18px auto 14px;
    padding: 14px 18px;
    border: 1px solid #ededed;
    border-radius: 8px;
    background: #fafafa;
    text-align: left;
    max-width: 380px;
}

.calc2-q-recap dt {
    color: #8a8c93;
    font-weight: 400;
    font-size: 1.2rem;
}

.calc2-q-recap dd {
    margin: 0;
    color: #222222;
    font-weight: 600;
    font-size: 1.2rem;
    word-break: break-word;
}

/* ============================================================================
   Paiement en ligne d'un devis — bloc commun (Stripe, 2026-11-02)
   ----------------------------------------------------------------------------
   Etape 4 du calculateur ET page quote/confirm : meme module JS
   (theme.QuotePay), meme bloc. Fond GRIS du gabarit (celui du recap
   .calc2-q-recap) — le vert n'est pas notre fond (user 02/11) ; le vert
   reste sur l'icone de succes. Racine 10px → rem >= 1.
   ========================================================================== */

.calc2-pay {
    margin-top: 2rem;
    padding: 2rem 2.4rem;
    /*  MEME CARTE que le recapitulatif de commande (.calc2-q-prix .calc2-rc,
        user 05/11) : meme filet, meme fond de gabarit. */
    border: 1px solid #e2e2e2;
    border-radius: 1rem;
    background-color: var(--bg-item-secondary);
    color: #3f4045;
}

/*  Bouton d'envoi « en cours » : spinner + texte, aligne. */
.calc2-q-send .spinner-border { margin-right: .6rem; vertical-align: -.2rem; }

.calc2-pay-wait {
    display: flex;
    align-items: center;
    gap: 1rem;
    color: #3f4045;
    font-weight: 600;
}

.calc2-pay-head {
    display: flex;
    align-items: center;
    gap: 1rem;
    margin: 0 0 1rem;
    color: #222222;
    font-size: 1.8rem;
    font-weight: 700;
}

    .calc2-pay-head i { color: #0fb930; }

.calc2-pay-ref { margin: -.4rem 0 .8rem; color: #6b6e76; font-size: 1.3rem; }

.calc2-pay-text,
.calc2-pay-invite,
.calc2-pay-amount { margin: 0 0 .6rem; line-height: 1.5; }

.calc2-pay-invite { margin-top: 1.4rem; font-weight: 600; color: #222222; }

/*  Le formulaire Stripe (iframe) : carte BLANCHE posee sur le gris. */
/*  Largeur limitee (03/11) : au-dela de ~900px, Stripe passe en 2 colonnes
    (recapitulatif a gauche, presque vide pour une seule ligne). Etroit, il
    s'affiche en UNE colonne compacte. */
.calc2-pay-checkout {
    max-width: 56rem;
    margin: 1.4rem auto 1rem;
    padding: 1.2rem;
    border: 1px solid #ededed;
    border-radius: 1rem;
    background-color: #ffffff;
    min-height: 12rem;
}

/*  Etape 4 du calculateur : Stripe a GAUCHE, BDC (PDF) a droite — meme
    sens que la page du devis (user 05/11). */
@media (min-width: 992px) {
    .calc2-pay-split.has-pdf {
        display: grid;
        grid-template-columns: 56rem minmax(0, 1fr);
        gap: 2rem;
        align-items: start;
        margin-top: 1.4rem;
    }

        .calc2-pay-split.has-pdf .calc2-pay-checkout { margin: 0; }
}

.calc2-pay-pdf {
    width: 100%;
    height: 80rem;
    border: 1px solid #ededed;
    border-radius: 1rem;
    background-color: #ffffff;
}

.calc2-pay-later { margin: 0; color: #6b6e76; font-size: 1.3rem; }

.calc2-pay-see {
    display: inline-flex;
    align-items: center;
    gap: .8rem;
    margin-top: 1.2rem;
    color: #222222;
    font-weight: 600;
}

.calc2-pay-done i { font-size: 2.2rem; }

/*  COMMANDE PAYEE (2026-11-03) — le TAMPON « paye », en HTML + CSS et non en
    image : son mot vient des ressources (Pay_Stamp), donc traduit. Pose en
    haut a droite du bloc, penche, vert translucide — meme esprit que le
    tampon SVG de la liste admin. Partial Items/Payment/QuotePay.cshtml ET
    quote_pay.js (_paid) rendent le meme balisage. */
/*  Paye = le bloc doit RESSORTIR (user 03/11) : navy du site (#000954), texte
    blanc, tampon vert clair. Le bloc « a payer » reste gris. */
.calc2-pay.calc2-pay-paid {
    position: relative;
    min-height: 9rem;
    padding-right: 24rem;               /* le tampon penche deborde de sa boite : marge large */
    border-color: #000954;
    background-color: #000954;
    color: rgba(255, 255, 255, .85);
}

    .calc2-pay-paid .calc2-pay-head,
    .calc2-pay-paid .calc2-pay-text strong,
    .calc2-pay-paid .calc2-pay-see { color: #ffffff; }

    .calc2-pay-paid .calc2-pay-head i { color: #5ee07a; }
    .calc2-pay-paid .calc2-pay-later { color: rgba(255, 255, 255, .65); }

.pay-stamp {
    position: absolute;
    top: 50%;
    right: 2.4rem;
    display: inline-flex;
    align-items: center;
    gap: .8rem;
    padding: .6rem 1.8rem;
    border: .4rem double #5ee07a;
    border-radius: .8rem;
    color: #5ee07a;
    font-size: 2.6rem;
    font-weight: 800;
    letter-spacing: .3rem;
    text-transform: uppercase;
    line-height: 1.2;
    opacity: .85;
    transform: translateY(-50%) rotate(-10deg);
    pointer-events: none;
    user-select: none;
}

@media (max-width: 575.98px) {
    .calc2-pay-paid { padding-right: 2.4rem; padding-top: 7rem; }
    .pay-stamp { top: 1.6rem; transform: rotate(-8deg); font-size: 2rem; }
}

/*  Recapitulatif de la commande (page du devis) : references + statut. */
/*  Pas de marge propre : l'espacement entre blocs est porte par le bloc
    englobant (mb-4) — une section = container pt-5 pb-5, rien de plus. */
.quote-order { margin-bottom: 0; }
.quote-order th { font-weight: 600; color: #6b6e76; }
/* ============================================================================
   « VOS PRODUITS » — selection multi-produit (2026-10-15)
   ----------------------------------------------------------------------------
   Rendu par la page (Calculator_Selection.cshtml), HORS des widgets de calcul :
   les variables --c2-* n'y sont pas definies, d'ou les valeurs en clair
   (memes teintes : navy #000954, vert #0fb930, filet #eaeaea).

   Une CARTE a en-tete navy (couleurs de la page) et non un fanion de plus : le
   fanion vert annonce une grande section, il est garde pour « Votre devis en
   ligne » au-dessus (user, 2026-10-15).
   ========================================================================== */

/*  Une SECTION comme celles du calculateur (en-tete a rail, bouton Detail),
    et plus une carte a bandeau navy (essayee puis ecartee le 2026-10-15). Les
    regles d'en-tete sont PARTAGEES dans calculator.css (.calc-sel .calc2-*) ;
    elles lisent des variables --c2-*, definies ici puisque la selection vit
    hors des widgets. */
.calc-sel {
    --c2-heading: #222222;
    --c2-text: #3f4045;
    --c2-muted: #8a8c93;
    margin: 0 0 2.4rem;
}

.calc-sel-body { padding: 0; }

/* CALCULATEUR UNIFIE : un seul sous-calculateur visible. !important, car le
   module Stricker se revele lui-meme (hidden = false) en fin de chargement :
   masque par l'aiguillage, il ne doit pas reapparaitre. */
[data-calc-off] { display: none !important; }

.calc-sel-lead {
    margin: 0 0 16px;
    line-height: 1.6;
}

.calc-sel-lead a { color: inherit; font-weight: 600; }

/* « Plus d'infos » EN TETE, a gauche du texte (2026-10-15) : position fixe,
   quelle que soit la longueur du texte. Ouvre la fenetre Detail. */
.calc-sel-lead {
    display: flex;
    align-items: flex-start;
    gap: 14px;
}

.calc-sel-lead .calc-sel-more {
    flex: 0 0 auto;
    padding: 4px 10px;
    font-size: 1.2rem;
    white-space: nowrap;
}

.calc-sel-lead-t { flex: 1 1 auto; min-width: 0; }

@media (max-width: 575.98px) {
    .calc-sel-lead { flex-direction: column; gap: 8px; }
}

/* UNE SEULE LIGNE, toujours (user, 2026-10-15) : 10 produits doivent tenir sur
   la largeur desktop (~1 290 px). Colonnes de 110 a 150 px : a 6 produits
   elles gardent leur 150, a 10 elles se resserrent (10 x 120 + 9 x 8 tient).
   Plus etroit que ca (tablette), la ligne DEFILE au lieu de passer a la ligne. */
.calc-sel-rail {
    display: grid;
    grid-auto-flow: column;
    grid-auto-columns: minmax(110px, 150px);
    justify-content: start;
    gap: 8px;
    overflow-x: auto;
    padding-bottom: 4px;
}

.calc-sel-item,
.calc-sel-add {
    position: relative;
    display: flex;
    flex-direction: column;
    min-height: 200px;
    border: 1px solid #eaeaea;
    border-radius: 8px;
    background: #ffffff;
}

.calc-sel-item:hover { border-color: #d4d4d4; }

.calc-sel-item.is-on {
    border: 2px solid #0fb930;
}

.calc-sel-pick {
    flex: 1 1 auto;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 4px;
    padding: 10px 8px 8px;
    border: 0;
    background: none;
    cursor: pointer;
    text-align: center;
    font: inherit;
}

.calc-sel-img {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    height: 90px;
}

.calc-sel-img img {
    max-width: 100%;
    max-height: 100%;
    object-fit: contain;
}

.calc-sel-n {
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
    color: #222222;
    line-height: 1.3;
}

.calc-sel-item.is-on .calc-sel-n { color: #0b8f25; font-weight: 600; }

.calc-sel-s { color: #8a8c93; font-size: 1.2rem; }

/* Pied d'action : rempli par calc_selection.js (au panier / ajouter / retirer).
   HAUTEUR FIXE et UNE ligne par controle : sinon « Ajouter au panier » passe
   sur deux lignes et les pieds de la rangee ne s'alignent plus (retour sac
   2026-10-15). Tout controle du pied fait 30 px de haut. */
.calc-sel-act {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    height: 44px;
    padding: 0 8px;
    border-top: 1px solid #f0f0f0;
}

.calc-sel-ok {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    height: 30px;
    color: #0b8f25;
    font-weight: 600;
    white-space: nowrap;
}

.calc-sel-item .calc-sel-quote {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 4px;
    flex: 1 1 auto;
    min-width: 0;
    height: 30px;
    min-height: 0;
    padding: 0 6px;
    font-size: 1.15rem;
    line-height: 1;
    white-space: nowrap;
}

.calc-sel-del,
.calc-sel-x {
    flex: 0 0 30px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 30px;
    height: 30px;
    border: 1px solid #e6b8b8;
    border-radius: 6px;
    background: #ffffff;
    color: #c0392b;
    cursor: pointer;
}

.calc-sel-del:hover,
.calc-sel-x:hover { background: #fdf0ef; }

/* « Retirer de la SELECTION » (×) : coin haut-droit de la vignette, hors du
   pied — le pied ne porte que l'action PANIER, sinon le bouton « Ajouter au
   panier » est coupe sur les vignettes etroites. Rendu dans le pied par le JS,
   positionne par rapport a la vignette (.calc-sel-item est relative). */
/*  Bouton ROUGE plein (user, 2026-10-15) : un retrait doit se voir comme tel,
    pas comme un picto discret sur le visuel. */
.calc-sel-item .calc-sel-x {
    position: absolute;
    top: 6px;
    right: 6px;
    z-index: 1;
    width: 24px;
    height: 24px;
    border-color: #c0392b;
    background: #c0392b;
    color: #ffffff;
    font-size: 1.2rem;
}

.calc-sel-item .calc-sel-x:hover { border-color: #a5281c; background: #a5281c; }

/* « Ajouter votre produit » — toujours la derniere, en pointilles. */
.calc-sel-add {
    align-items: center;
    justify-content: center;
    gap: 10px;
    border: 2px dashed #b9bfd3;
    color: #000954;
    font: inherit;
    font-weight: 600;
    cursor: pointer;
}

.calc-sel-add > i { font-size: 2.6rem; }

.calc-sel-add:hover {
    border-color: #0fb930;
    color: #0b8f25;
}

/* ---------- Fenetre de recherche « + Ajouter votre produit » ----------
   16 resultats, pas de pagination : 4 par rangee en desktop (4 rangees), 2 en
   mobile. Le corps defile, la tete et le champ restent. */
.calc-srch-modal {
    position: fixed;
    inset: 0;
    z-index: 1060;
    display: none;
    align-items: flex-start;
    justify-content: center;
    padding: 5vh 16px;
    background: rgba(0, 9, 84, .45);
}

.calc-srch-modal.is-open { display: flex; }

body.calc-srch-lock { overflow: hidden; }

.calc-srch-box {
    display: flex;
    flex-direction: column;
    width: 100%;
    max-width: 920px;
    max-height: 90vh;
    border-radius: 12px;
    background: #ffffff;
    overflow: hidden;
}

.calc-srch-head {
    display: flex;
    align-items: center;
    padding: 12px 16px;
    background: #000954;
    color: #ffffff;
    font-weight: 700;
}

.calc-srch-title i { margin-right: 8px; }

.calc-srch-x {
    margin-left: auto;
    border: 0;
    background: none;
    color: #ffffff;
    font-size: 2.4rem;
    line-height: 1;
    cursor: pointer;
}

.calc-srch-bar { padding: 12px 16px; border-bottom: 1px solid #eef0f6; }

.calc-srch-input {
    width: 100%;
    height: 42px;
    padding: 0 12px;
    border: 1px solid #d4d4d4;
    border-radius: 8px;
    font: inherit;
}

.calc-srch-input:focus { outline: 2px solid #0fb930; outline-offset: 0; border-color: #0fb930; }

.calc-srch-res { padding: 14px 16px; overflow-y: auto; }

.calc-srch-grid {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 10px;
}

.calc-srch-item {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 6px;
    padding: 10px;
    border: 1px solid #eaeaea;
    border-radius: 8px;
    text-align: center;
}

.calc-srch-img {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    height: 100px;
}

.calc-srch-img img { max-width: 100%; max-height: 100%; object-fit: contain; }

.calc-srch-n {
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
    flex: 1 1 auto;
    color: #222222;
    line-height: 1.3;
}

/*  VERT : c'est une action qui ENGAGE (le produit rejoint la liste du devis),
    meme vert que les CTA du site (user, 2026-10-15). Specificite renforcee :
    .mk2-btn porte deja son propre habillage.
    TEINTE, pas aplat : 16 boutons pleins cote a cote = mur vert (« trop
    flashy », retour sac 2026-10-15). Contour + texte vert au repos, le plein
    arrive au survol ; le bouton ajoute garde un fond teinte. */
.calc-srch-modal .calc-srch-add {
    padding: 4px 12px;
    border: 1px solid rgb(15 185 48 / .45);
    background: rgb(15 185 48 / .06);
    color: #0b8f25;
    font-size: 1.2rem;
    font-weight: 600;
}

.calc-srch-modal .calc-srch-add:hover {
    border-color: #0fb930;
    background: #0fb930;
    color: #ffffff;
}

.calc-srch-modal .calc-srch-add:disabled {
    border-color: transparent;
    background: rgb(15 185 48 / .12);
    color: #0b8f25;
    cursor: default;
}

.calc-srch-empty { margin: 8px 0; color: #8a8c93; }

/* Fenetre Detail : memes cartes, visuels plus grands, produit ouvert entoure. */
.calc-det-img { height: 160px; }

.calc-srch-item.is-on { border: 2px solid #0fb930; }

/* MODE D'EMPLOI : 4 etapes numerotees en tete de la fenetre Detail. */
.calc-det-steps {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 10px;
    margin: 0 0 18px;
    padding: 0;
    list-style: none;
}

.calc-det-steps li {
    display: flex;
    gap: 10px;
    padding: 12px;
    border-radius: 8px;
    background: #f3f4f9;
}

.calc-det-num {
    flex: 0 0 26px;
    height: 26px;
    border-radius: 50%;
    background: #000954;
    color: #ffffff;
    font-weight: 700;
    line-height: 26px;
    text-align: center;
}

.calc-det-txt { color: #5b5e66; font-size: 1.3rem; line-height: 1.45; }

.calc-det-txt b { display: block; margin-bottom: 2px; color: #222222; }

.calc-det-good {
    margin: 0 0 18px;
    padding: 12px 14px;
    border-left: 3px solid #0fb930;
    border-radius: 0 8px 8px 0;
    background: rgb(15 185 48 / .06);
}

.calc-det-good-t { margin-bottom: 6px; color: #0b8f25; font-weight: 700; }

.calc-det-good-t i { margin-right: 6px; }

.calc-det-good ul { margin: 0; padding-left: 18px; color: #3f4045; font-size: 1.3rem; line-height: 1.6; }

.calc-det-list-t {
    display: flex;
    justify-content: space-between;
    margin: 0 0 10px;
    color: #222222;
    font-weight: 700;
}

.calc-det-list-t span { color: #8a8c93; font-weight: 400; }

@media (max-width: 991.98px) {
    .calc-det-steps { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 575.98px) {
    .calc-det-steps { grid-template-columns: 1fr; }
}

/* Carte de la liste : pastille d'etat (en cours / au devis / ajoute). */
.calc-det-item { position: relative; padding-top: 30px; }

.calc-det-badge {
    position: absolute;
    top: 8px;
    left: 8px;
    padding: 2px 8px;
    border-radius: 999px;
    background: #eef0f6;
    color: #000954;
    font-size: 1.1rem;
    font-weight: 600;
}

.calc-det-badge.is-on,
.calc-det-badge.is-ok { background: rgb(15 185 48 / .12); color: #0b8f25; }


@media (max-width: 767.98px) {
    .calc-srch-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* Mobile : un RAIL horizontal plutot qu'un gros bloc de vignettes. */
@media (max-width: 767.98px) {
    .calc-sel-rail {
        display: flex;
        overflow-x: auto;
        scroll-snap-type: x mandatory;
        padding-bottom: 6px;
    }

    .calc-sel-item,
    .calc-sel-add {
        flex: 0 0 130px;
        scroll-snap-align: start;
    }
}

.prd-card-large-item {
    border-radius: 10px;
    background-color: #fff;
    padding: 0;
    border: 1px solid #e2e2e2;
    box-shadow: 3px 3px 6px 0px rgba(0, 0, 0, 0.08);
    margin-bottom: 15px;
    cursor: pointer;
}

    .prd-card-large-item:hover {
        border-color: var(--color-primary);
    }

        .prd-card-large-item:hover img {
            -webkit-animation: policy 1.2s linear;
            animation: policy 1.2s linear;
        }

    .prd-card-large-item .thumb-box {
        position: relative;
        width: 43%;
        max-width: 43%;
        padding: 10px 10px;
        margin: auto;
        border: none;
    }


    .prd-card-large-item .prd-info {
        padding: 10px 10px;
        width: 57%;
        max-width: 57%;
        margin: 0;
        font-size: 1.3rem;
        font-weight: 700;
    }

        .prd-card-large-item .prd-info .prd-title-box {
            margin-top: 35px;
            height: 40px;
            font-weight: 700;
        }

            .prd-card-large-item .prd-info .prd-title-box a {
                line-height: 22px;
                color: var(--color-product-name);
            }

                .prd-card-large-item .prd-info .prd-title-box a:hover {
                    color: var(--color-primary);
                }

        .prd-card-large-item .prd-info .prd-price-box {
            font-weight: 400;
            margin-top: 20px;
        }

            .prd-card-large-item .prd-info .prd-price-box span {
                color: var(--color-price);
                font-weight: 700;
                display: inline-block;
            }

/* ═══════════════════════════════════════════════════════════════════════
   Product Grid Card — variante compacte carree du prd-card-large-item.
   Layout : image carree top full-width, name + prix dessous.
   Utilise par : Product_Owl.cshtml (pattern 2 rows).
   ═══════════════════════════════════════════════════════════════════════ */

/* Product_Owl pattern 2 rows : colonne Owl contient 2 cards empilees verticalement.
   Espacement entre les 2 cards de la meme colonne. */
.prd-owl-column .prd-card-grid-item + .prd-card-grid-item {
    margin-top: 15px;
}


.prd-card-grid-item {
    border-radius: 10px;
    background-color: #fff;
    padding: 0;
    border: 1px solid #e2e2e2;
    box-shadow: 3px 3px 6px 0px rgba(0, 0, 0, 0.08);
    margin-bottom: 15px;
    cursor: pointer;
    overflow: hidden;
}

    .prd-card-grid-item:hover {
        border-color: var(--color-primary);
    }

        .prd-card-grid-item:hover img {
            -webkit-animation: policy 1.2s linear;
            animation: policy 1.2s linear;
        }

    .prd-card-grid-item .thumb-box {
        position: relative;
        width: 100%;
        aspect-ratio: 1 / 1;
        padding: 15px;
        margin: 0;
        border: none;
        display: flex;
        align-items: center;
        justify-content: center;
    }

        .prd-card-grid-item .thumb-box img {
            max-width: 100%;
            max-height: 100%;
            object-fit: contain;
        }

    .prd-card-grid-item .prd-info {
        padding: 12px 15px 15px;
        width: 100%;
        max-width: 100%;
        margin: 0;
        font-size: 1.2rem;
        font-weight: 700;
    }

        .prd-card-grid-item .prd-info .prd-title-box {
            height: 44px;
            font-weight: 700;
            overflow: hidden;
            display: -webkit-box;
            -webkit-line-clamp: 2;
            -webkit-box-orient: vertical;
            line-clamp: 2;
        }

            .prd-card-grid-item .prd-info .prd-title-box a {
                line-height: 22px;
                color: var(--color-product-name);
                text-decoration: none;
            }

                .prd-card-grid-item .prd-info .prd-title-box a:hover {
                    color: var(--color-primary);
                }

        .prd-card-grid-item .prd-info .prd-price-box {
            font-weight: 400;
            margin-top: 12px;
        }

            .prd-card-grid-item .prd-info .prd-price-box span {
                color: var(--color-price);
                font-weight: 700;
                display: inline-block;
            }


.policy-card-item-content .policy-card-item {
    background-color: var(--bg-item-secondary);
    border-radius: 10px;
    padding: 30px 10px 30px 10px;
    height: 100%;
    border: 1px solid #e2e2e2;
    box-shadow: 3px 3px 6px 0px rgba(0, 0, 0, 0.08);
}

    .policy-card-item-content .policy-card-item .policy-icon {
        width: 60px;
        min-width: 60px;
        height: 60px;
        border-radius: 100%;
        overflow: hidden;
        background: #ffffff;
        margin-right: 10px;
    }

        .policy-card-item-content .policy-card-item .policy-icon:hover i {
            -webkit-animation: policy 1.2s linear;
            animation: policy 1.2s linear;
        }

        .policy-card-item-content .policy-card-item .policy-icon i {
            text-align: center;
            font-size: 25px;
        }

    .policy-card-item-content .policy-card-item .title-box {
        font-size: 1.4rem;
        font-weight: 700;
        color: #222222;
        line-height: 2.1;
        text-transform: uppercase;
    }

    .policy-card-item-content .policy-card-item .text-box {
        color: #666666;
    }

@media(max-width: 1200px) {
    .policy-card-item-content {
        margin-bottom: 15px;
    }
}

.faq-accordion {
    border-top: 1px solid var(--color-border);
    --bs-accordion-border-width: 0;
}

    .faq-accordion .faq-item .faq-header {
        border-bottom: 1px solid var(--color-border);
        position: relative;
    }

    .faq-accordion .faq-item .faq-content {
        border: 0;
        padding: 21px 0 32px;
    }

    .faq-accordion .faq-item .faq-header .faq-button {
        padding: 13px 0 10px 0;
        color: var(--color-heading);
        font-size: 16px;
        font-weight: 600;
        width: 100%;
        cursor: pointer;
        background-color: transparent;
        border: 0;
        margin: 0;
        text-align: left;
        outline: none;
        box-shadow: none;
    }

        .faq-accordion .faq-item .faq-header .faq-button .faq-active::before {
            content: "";
            display: block;
            height: 3px;
            width: 0;
            background: var(--color-body-text);
            position: absolute;
            top: -1px;
            left: 0;
            transition: all 1s;
        }

        .faq-accordion .faq-item .faq-header .faq-button:not(.collapsed) .faq-active::before {
            width: 200px;
        }
