/* ════════════════════════════════════════════════════════════════════════
   PASSE ANTI IA CHEAP DU 2026-09-22 — 56 bords peints deviennent 22.

   Planches : `mockups/boutique-vitrine-publique-2026-09-21.html` (les 56
   nommés un par un, avec leur verdict) et
   `mockups/boutique-etats-et-devis-2026-09-21.html` (les états).

   LA RÈGLE, du 2026-09-20 : un trait SÉPARE DEUX NATURES. Il n'entoure pas un
   objet, il ne redit pas ce qu'un titre dit déjà, il ne dessine pas ce qu'un
   aplat dessine mieux. Trente-quatre déclarations n'en séparaient aucune :

   · CINQ CHAMPS cernés au repos (code promo, devis, commentaire d'avis, note
     au commerçant, tri du catalogue) prennent le creux `--sf-ctl`. Le contour
     reste DÉCLARÉ transparent, sinon la ligne saute d'un pixel au foyer.
   · NEUF PASTILLES ET BOUTONS cernés (« + » de la carte mobile, pagination,
     nav des pages légales, boutons des pages terminales, pastilles et
     géolocalisation du devis, bouton secondaire de la fiche) se posent sur un
     aplat. Le choix RETENU garde un liseré — deux natures — mais en ombre
     intérieure, pour ne pas déplacer la pastille d'un pixel.
   · DEUX FAMILLES DE CHOIX (options, régimes) suivent la même grammaire.
   · NEUF GROUPES ENCADRÉS (avertissement de pause, récapitulatif du panier,
     produit / formulaire / carte pro du devis, message et fiche d'avis, étape
     et bloc du tiroir) perdent leur boîte. Le récapitulatif du panier garde UN
     filet, et il est vertical : à gauche ce qu'on modifie, à droite ce qu'on
     paie, comme la page de commande.
   · SEPT FILETS DE RANGÉE (coordonnées d'À propos, rangées d'Informations,
     lignes du panier, rangées du devis, avis de la fiche, rangées
     intitulé/valeur, articles d'une commande) disparaissent : règle du
     2026-09-09, le voile de survol prend le relais.
   · DEUX TRAITS QUI NE SÉPARAIENT RIEN : la couture de 0,5 px au-dessus de la
     barre d'action du téléphone — l'ombre de ce motif avait été retirée du
     produit entier le 2026-09-20, le filet était resté — et le SECOND filet du
     pied, à 80 px du premier.
   · QUATRE AUTRES : les quatre filets empilés des sections dépliantes de la
     fiche, le filet au-dessus d'un groupe d'options qui porte déjà son
     intitulé en gras, le filet sous le code promo à l'intérieur d'un panneau
     déjà cerné, et le cadre de 0,5 px autour de la PHOTO du produit — un
     trait n'entoure pas un objet, et une photo porte déjà ses bords.

   LES 22 QUI RESTENT séparent tous deux natures : les trois barres de la
   coquille, le tiroir et ses deux coutures, le popover de recherche, la
   séparation des colonnes du panier, les quatre « lignes contre somme due »,
   le filet du pied, celui du bloc d'avis, de la réassurance, du recours, du
   fil du temps, les deux blocs de la commande confirmée, le tireté de la zone
   de dépôt (un tireté EST l'affordance d'un dépôt), et le filet de rangée de
   la liste produits MOBILE — celui-là reste, parce que sans survol sur un
   écran tactile rien d'autre ne sépare deux produits.
   ════════════════════════════════════════════════════════════════════════ */

/**
 * Storefront Scan-First — vitrine universelle Mary
 *
 * Refonte 2026-05-15 : remplace le pattern hero/nav/footer marketing par un
 * châssis unique scan-first (le client a scanné un QR, il agit, il finit).
 *
 * Préfixe : `.shop-*` (distinct de l'ancien `.sf-*` qui reste chargé pour
 * rollback safe). Quand on aura validé, supprimer storefront.css.
 *
 * Mobile-first. Breakpoint PC à 900 px (grille 3 cols + panier sidebar).
 *
 * Variables :
 *  --shop-brand        : couleur primaire (injectée inline via base template)
 *  --shop-brand-soft   : 8% du brand sur fond gris
 *  --shop-brand-shadow : ombre verte douce sur les CTAs
 */

:root {
    --shop-brand: #10b981;
    --shop-brand-soft: color-mix(in srgb, var(--shop-brand) 8%, #f5f5f7);
    --shop-brand-shadow: color-mix(in srgb, var(--shop-brand) 30%, transparent);
    --shop-text: #1d1d1f;
    --shop-text-muted: #6b7280;
    --shop-text-quiet: #9ca3af;
    --shop-bg: #fff;          /* la vitrine se délimite par des filets, pas par un fond gris */
    --shop-surface: #fff;
    --shop-border: rgba(0, 0, 0, 0.06);
    --shop-radius-card: 14px;
    --shop-shadow-card: 0 1px 3px rgba(0,0,0,0.04);
}

/* ===== RESET LOCAL ===== */
.shop-storefront *,
.shop-storefront *::before,
.shop-storefront *::after { box-sizing: border-box; }

/* Un conteneur à display: explicite écrase l'attribut [hidden] : une règle
   d'auteur bat la feuille du navigateur. Sans cette ligne, un bloc masqué
   (message d'erreur, section repliée) reste affiché, vide. */
.shop-storefront [hidden] { display: none; }

/* Réglages de base de la vitrine.

   Ils vivaient dans `storefront.css`, supprimé le 2026-07-28 : la feuille
   portait un `a { color: inherit; text-decoration: none }` NON scopé dont
   toute la vitrine dépendait sans le déclarer. Sa disparition a fait
   réapparaître le soulignement des cartes rendues par un <a> (formules).
   Ils sont ici, scopés, donc visibles. */
/* `:where()` ne pèse rien dans le calcul de spécificité : ces règles valent
   donc (0,0,1), exactement comme les sélecteurs d'élément nus qu'elles
   remplacent. Écrire `.shop-storefront a` les ferait passer à (0,1,1) et
   l'emporter sur `.shop-h__icon--cart` — le bouton panier repasserait en
   texte sombre sur fond vert. Scoper ne doit pas vouloir dire alourdir. */
:where(.shop-storefront) a {
    color: inherit;
    text-decoration: none;
}
:where(.shop-storefront) img {
    max-width: 100%;
    height: auto;
    display: block;
}
:where(.shop-storefront) button {
    font-family: inherit;
    cursor: pointer;
}
:where(.shop-storefront) input,
:where(.shop-storefront) textarea,
:where(.shop-storefront) select {
    font-family: inherit;
    font-size: inherit;
}

.shop-storefront {
    margin: 0;
    background: var(--shop-bg);
    color: var(--shop-text);
    font-family: -apple-system, BlinkMacSystemFont, 'SF Pro Display', 'SF Pro Text', 'Inter', 'Helvetica Neue', Arial, sans-serif;
    letter-spacing: -0.01em;
    -webkit-font-smoothing: antialiased;

    /* LE PIED DE PAGE RESTE EN BAS (22/09/2026).

       Il n'y avait aucune règle pour l'y tenir : le pied suivait simplement
       le contenu. Sur toute page plus courte que la fenêtre — la page de
       commande, le panier vide, le suivi, « À propos », la demande de devis,
       une boutique de trois produits — il remontait au milieu de l'écran,
       avec son filet supérieur en travers de la page et six cents pixels de
       blanc en dessous. Signalé par le fondateur le 22/09 sur
       `/boutique/marydesk/commander/`, et visible sur douze des dix-huit
       captures de la passe du matin, que j'ai regardées sans le nommer.

       Le corps devient une colonne d'au moins une hauteur de fenêtre, et
       `<main>` prend tout ce qui reste. `100dvh` suit la barre d'adresse des
       navigateurs mobiles, qui la rétractent au défilement ; `100vh` reste
       en repli pour les moteurs qui ignorent l'unité dynamique.

       Les tiroirs (panier, formule) et le CTA collant sont en
       `position: fixed` : ils sortent du flux et ne deviennent pas des
       éléments de cette colonne. */
    display: flex;
    flex-direction: column;
    min-height: 100vh;
    min-height: 100dvh;
}
.shop-storefront > #shop-content { flex: 1 0 auto; }
.shop-storefront > .shop-foot { flex-shrink: 0; }

/* ============================================================
   HEADER (44px mobile / 56px desktop)
   ============================================================ */
.shop-h {
    background: rgba(255, 255, 255, 0.92);
    backdrop-filter: blur(20px);
    -webkit-backdrop-filter: blur(20px);
    border-bottom: 0.5px solid var(--shop-border);
    padding: 8px 14px;
    display: flex;
    align-items: center;
    gap: 10px;
    position: sticky;
    top: 0;
    z-index: 30;
    min-height: 44px;
}
@media (min-width: 900px) {
    .shop-h { padding: 12px 32px; min-height: 56px; gap: 14px; }
}

.shop-h__brand {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    text-decoration: none;
    color: var(--shop-text);
    min-width: 0;
}
@media (min-width: 900px) {
    .shop-h__brand { gap: 12px; }
}

.shop-h__mark {
    width: 28px; height: 28px;
    border-radius: 8px;
    background: var(--shop-brand);
    color: #fff;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 11px; font-weight: 700;
    flex-shrink: 0;
    letter-spacing: -0.005em;
}
.shop-h__mark img {
    width: 100%; height: 100%;
    object-fit: cover;
    border-radius: 8px;
}
@media (min-width: 900px) {
    .shop-h__mark { width: 36px; height: 36px; font-size: 13px; border-radius: 10px; }
    .shop-h__mark img { border-radius: 10px; }
}

.shop-h__title {
    display: flex; flex-direction: column;
    min-width: 0;
    line-height: 1.15;
}
.shop-h__name {
    font-size: 14px; font-weight: 700;
    color: var(--shop-text);
    letter-spacing: -0.012em;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
@media (min-width: 900px) { .shop-h__name { font-size: 17px; letter-spacing: -0.015em; } }
.shop-h__sub {
    font-size: 10px;
    color: var(--shop-text-muted);
    margin-top: 1px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
@media (min-width: 900px) { .shop-h__sub { font-size: 12px; } }

.shop-h__spacer { flex: 1; }

.shop-h__badge {
    padding: 4px 10px;
    background: var(--shop-brand);
    color: #fff;
    border-radius: 999px;
    font-size: 11px; font-weight: 600;
    flex-shrink: 0;
    letter-spacing: -0.005em;
}
@media (min-width: 900px) { .shop-h__badge { padding: 5px 12px; font-size: 12px; } }

/* Le formulaire ne doit rien peser dans la barre : ses enfants s'y rangent
   comme s'il n'existait pas. La règle vivait en style ÉCRIT DANS LE GABARIT,
   et cette classe n'avait donc aucune définition ici : on pouvait la lire dix
   fois dans la feuille sans jamais comprendre d'où venait la mise en page. */
.shop-h__search-form {
    display: contents;
}

/* Enveloppe du champ de recherche · elle porte la MISE EN PAGE (le <form> est
   en `display: contents`, donc pas un bloc conteneur : la liste de suggestions
   en position absolue s'accrocherait à l'en-tête, pas au champ) et sert
   d'ancrage à cette liste. Le champ la remplit. */
.shop-h__search-wrap {
    display: none;
    position: relative;
}

/* Search input — PC seulement (mobile passe par l'icône) */
.shop-h__search {
    display: none;
}
@media (min-width: 900px) {
    .shop-h__search-wrap { display: block; width: 220px; }
    .shop-h__search {
        display: block;
        width: 100%;
        box-sizing: border-box;
        padding: 7px 12px 7px 32px;
        background-color: rgba(120, 120, 128, 0.10);
        background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='none' stroke='%238a8a8e' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' viewBox='0 0 24 24'%3E%3Ccircle cx='11' cy='11' r='8'/%3E%3Cline x1='21' y1='21' x2='16.65' y2='16.65'/%3E%3C/svg%3E");
        background-repeat: no-repeat;
        background-position: 11px center;
        background-size: 14px;
        border: 0;
        border-radius: 999px;
        color: var(--shop-text);
        font-size: 13px;
        font-family: inherit;
        letter-spacing: -0.005em;
    }
    .shop-h__search::placeholder { color: var(--shop-text-muted); }
    .shop-h__search:focus {
        outline: 2px solid var(--shop-brand-shadow);
        background-color: #fff;
    }
}

/* Recherche mobile : barre pleine largeur sous la ligne d'en-tête (CSS only). */
@media (max-width: 899px) {
    .shop-h { flex-wrap: wrap; }
    /* La marque grandit pour pousser les actions (Devis/panier) à droite ; pas de
       spacer qui « mangerait » la place du panier (sinon il passe à la ligne). */
    .shop-h__brand { flex: 1 1 auto; min-width: 0; }
    .shop-h__spacer { display: none; }
    .shop-h__search-wrap {
        display: block;
        order: 99;
        flex-basis: 100%;
        width: 100%;
        margin-top: 8px;
    }
    .shop-h__search {
        display: block;
        width: 100%;
        box-sizing: border-box;
        padding: 9px 14px 9px 38px;
        background-color: rgba(120, 120, 128, 0.10);
        background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='none' stroke='%238a8a8e' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' viewBox='0 0 24 24'%3E%3Ccircle cx='11' cy='11' r='8'/%3E%3Cline x1='21' y1='21' x2='16.65' y2='16.65'/%3E%3C/svg%3E");
        background-repeat: no-repeat;
        background-position: 14px center;
        background-size: 15px;
        border: 0;
        border-radius: 999px;
        color: var(--shop-text);
        font-size: 14px;
        font-family: inherit;
    }
    .shop-h__search::placeholder { color: var(--shop-text-muted); }
}

.shop-h__icon {
    width: 36px; height: 36px;
    border-radius: 10px;
    background: rgba(120, 120, 128, 0.10);
    color: #4b5563;
    border: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    position: relative;
    flex-shrink: 0;
}
.shop-h__icon:hover { background: rgba(120, 120, 128, 0.18); }
.shop-h__icon svg { display: block; }
.shop-h__icon-badge {
    position: absolute;
    top: -2px; right: -2px;
    min-width: 18px; height: 18px;
    border-radius: 9px;
    background: var(--shop-brand);
    color: #fff;
    font-size: 10px; font-weight: 700;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0 5px;
    box-shadow: 0 0 0 2px #fff;
    font-variant-numeric: tabular-nums;
}

/* ============================================================
   BANDEAU D'ANNONCE — une seule cause : les commandes sont suspendues
   ============================================================ */
/* Plus d'aplat de couleur : sur fond teinté, pleine largeur et collé sous la
   barre du haut, le bandeau se lisait comme une SECONDE barre d'outils. Un
   filet et un texte sobre disent l'exception sans imiter une barre. */
.shop-strip {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    padding: 9px 16px;
    font-size: 12px;
    line-height: 1.4;
    text-align: center;
    background: var(--shop-surface);
    color: var(--shop-text-muted);
    border-bottom: 1px solid var(--shop-border);
}

/* ============================================================
   PAGE « À PROPOS » (.shop-apropos) — la présentation a quitté l'accueil
   ============================================================ */
/* `.shop-hero*` a été supprimé le 2026-07-29 avec l'en-tête de boutique qu'il
   habillait : la présentation vit maintenant sur sa propre page, où l'histoire
   s'affiche entière au lieu d'être coupée à 34 mots. */
/* ── UN SEUL AXE GAUCHE POUR TOUTE LA VITRINE (22/09/2026) ──────────────
   Relevé à l'écran, sur le serveur local, à 1366 px : le catalogue commençait
   à 57 px, la fiche produit et le panier à 83, la demande de devis à 133, la
   page « À propos » à 289 et le suivi de commande à 303 — CINQ axes gauches
   pour cinq pages du même site, sous un en-tête et un pied qui, eux, ne
   bougent pas. L'œil repart d'un endroit différent à chaque page ; c'est ce
   qui fait qu'un site paraît assemblé plutôt que dessiné.

   Toutes les pages partagent désormais la largeur de `.shop-content` et de
   `.co-wrap` : 1280 px. Une page de LECTURE garde sa mesure courte — soixante
   à quatre-vingts signes par ligne, sans quoi elle devient illisible — mais
   elle la prend à GAUCHE de l'axe commun, elle ne se recentre pas.

   Seule exception assumée : `.shop-terminal` (confirmation de commande, devis
   envoyé) reste une colonne centrée. La page est une annonce, elle n'a pas de
   suite, et son axe est le milieu. Son état « je cherche ma commande », lui,
   est un formulaire et prend l'axe commun (`--form`). */
.shop-apropos {
    max-width: 1280px;
    margin: 0 auto;
    padding: 16px 16px 72px;
}
/* La MESURE de lecture, dans l'axe, pas centrée. */
.shop-apropos > * { max-width: 680px; }
@media (min-width: 900px) { .shop-apropos { padding: 32px 32px 80px; } }
.shop-apropos__back {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: 12.5px;
    color: var(--shop-text-muted);
    text-decoration: none;
    margin-bottom: 18px;
}
.shop-apropos__back:hover { color: var(--shop-text); }
/* La bannière est une BANDE pleine largeur : pensée en 1600 × 500, une vignette
   la rognerait sauvagement. */
.shop-apropos__img {
    width: 100%;
    aspect-ratio: 1600 / 500;
    max-height: 260px;
    border-radius: 12px;
    background: #f0f0f2;
    overflow: hidden;
    margin-bottom: 22px;
}
.shop-apropos__img img { width: 100%; height: 100%; object-fit: cover; display: block; }
@media (max-width: 599px) {
    .shop-apropos__img { aspect-ratio: 16 / 9; max-height: 180px; }
}
.shop-apropos__title {
    font-size: 24px; font-weight: 680;
    letter-spacing: -0.03em;
    line-height: 1.15;
    margin: 0;
}
@media (min-width: 900px) { .shop-apropos__title { font-size: 30px; } }
.shop-apropos__slogan {
    font-size: 14px;
    color: var(--shop-text-muted);
    margin: 8px 0 0;
    line-height: 1.5;
}
.shop-apropos__story {
    font-size: 14.5px;
    line-height: 1.65;
    color: var(--shop-text);
    margin-top: 22px;
}
.shop-apropos__story p { margin: 0 0 12px; }
.shop-apropos__story p:last-child { margin-bottom: 0; }
/* Sélecteur descendant (0,2,0) : la signature est un <p> DANS .__story, dont la
   règle `p { margin: 0 0 12px }` vaut (0,1,1) et l'emporterait sur une classe
   seule. On gagne par la spécificité, pas par !important. */
.shop-apropos__story .shop-apropos__author {
    margin: 16px 0 0;
    font-size: 13px;
    font-weight: 600;
    color: var(--shop-text);
}
.shop-apropos__author span {
    display: block;
    font-size: 12px;
    font-weight: 400;
    color: var(--shop-text-muted);
    margin-top: 1px;
}
.shop-apropos__h2 {
    font-size: 12px;
    font-weight: 600;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--shop-text-quiet);
    margin: 0 0 4px;
}
.shop-apropos__contact { margin-top: 34px; }
.shop-apropos__rows { margin: 0; }
.shop-apropos__row {
    display: flex;
    gap: 16px;
    padding: 9px 0;
    font-size: 13.5px;
    line-height: 1.5;
}
.shop-apropos__row dt {
    flex: 0 0 96px;
    color: var(--shop-text-muted);
    font-size: 12.5px;
}
.shop-apropos__row dd { margin: 0; min-width: 0; }
.shop-apropos__row a { color: var(--shop-text); text-decoration: none; }
.shop-apropos__row a:hover { text-decoration: underline; }
.shop-apropos__social {
    display: flex;
    flex-wrap: wrap;
    gap: 8px 18px;
    margin-top: 22px;
    font-size: 13px;
}
.shop-apropos__social a { color: var(--shop-text-muted); text-decoration: none; }
.shop-apropos__social a:hover { color: var(--shop-text); }
.shop-apropos__cta {
    display: inline-block;
    margin-top: 34px;
    padding: 12px 22px;
    border-radius: 999px;
    background: var(--shop-brand);
    color: #fff;
    font-size: 14px;
    font-weight: 600;
    text-decoration: none;
}

/* ============================================================
   TABS CATÉGORIES (onglets à filet, jamais des pastilles colorées)
   ============================================================ */
.shop-tabs {
    background: rgba(255, 255, 255, 0.94);
    backdrop-filter: blur(20px);
    -webkit-backdrop-filter: blur(20px);
    border-bottom: 0.5px solid var(--shop-border);
    padding: 0 12px;
    display: flex;
    align-items: center;
    gap: 2px;
    overflow-x: auto;
    scrollbar-width: none;
    position: sticky;
    top: 44px;
    z-index: 25;
}
@media (min-width: 900px) {
    .shop-tabs { padding: 0 32px; top: 56px; }
}
.shop-tabs::-webkit-scrollbar { display: none; }
.shop-tabs__btn {
    flex-shrink: 0;
    padding: 11px 13px;
    background: none;
    border: 0;
    border-bottom: 2px solid transparent;
    margin-bottom: -1px;
    color: var(--shop-text-muted);
    font-size: 12.5px; font-weight: 500;
    letter-spacing: -0.008em;
    cursor: pointer;
    font-family: inherit;
    text-decoration: none;
    white-space: nowrap;
}
.shop-tabs__btn:hover { color: var(--shop-text); }
.shop-tabs__btn--active {
    color: var(--shop-text);
    font-weight: 600;
    border-bottom-color: var(--shop-brand);
}

/* ============================================================
   MAIN LAYOUT (grille pleine largeur, centrée)
   ============================================================ */
.shop-main { display: flex; flex-direction: column; }
@media (min-width: 900px) { .shop-main { display: block; } }

.shop-content {
    padding: 14px 12px 100px;  /* padding-bottom mobile = place pour la barre panier */
}
@media (min-width: 900px) {
    .shop-content {
        padding: 20px 32px 60px;
        max-width: 1280px;
        margin: 0 auto;
    }
}

/* Section header inline (Formules, Tout le catalogue…) */
.shop-section-h {
    font-size: 10px; font-weight: 700;
    color: var(--shop-text-quiet);
    letter-spacing: 0.11em;
    text-transform: uppercase;
    margin: 0 0 10px;
}
.shop-section-h:not(:first-child) { margin-top: 24px; }
@media (min-width: 900px) {
    .shop-section-h { font-size: 10.5px; margin-bottom: 12px; }
    .shop-section-h:not(:first-child) { margin-top: 28px; }
}

/* ============================================================
   ARTICLES DU CATALOGUE

   PC : une grille d'IMAGES — le produit porte, pas le cadre. Aucune carte
   (ni fond, ni bordure, ni ombre) : c'est la photo qui délimite.
   Mobile : une LISTE À FILET, pas une grille de cartes (règle actée).
   ============================================================ */
.shop-grid {
    display: grid;
    grid-template-columns: 1fr;
    gap: 0;
}
@media (min-width: 600px) {
    .shop-grid { grid-template-columns: 1fr 1fr 1fr; gap: 22px 18px; }
}
@media (min-width: 900px) { .shop-grid { grid-template-columns: 1fr 1fr 1fr; gap: 24px 20px; } }
@media (min-width: 1200px) { .shop-grid { grid-template-columns: repeat(4, 1fr); } }

.shop-item {
    position: relative;
    min-width: 0;
    background: none;
    border: 0;
    border-radius: 0;
    box-shadow: none;
    display: flex;
    flex-direction: column;
    cursor: pointer;
}
.shop-item__link {
    display: flex;
    flex-direction: column;
    text-decoration: none;
    color: inherit;
    min-width: 0;
}
.shop-item__add-form { display: inline-flex; margin: 0; }

.shop-item__media {
    aspect-ratio: 4 / 3;
    border-radius: 11px;
    background: #f0f0f2;
    color: var(--shop-text-quiet);
    display: flex;
    align-items: center;
    justify-content: center;
    position: relative;
    overflow: hidden;
    transition: background 0.15s ease;
}
.shop-item:hover .shop-item__media { background: #e9e9ec; }
.shop-item__media img { width: 100%; height: 100%; object-fit: cover; display: block; }
.shop-item__placeholder { font-size: 24px; font-weight: 700; opacity: 0.35; }

.shop-item__badge {
    position: absolute;
    top: 8px; left: 8px;
    padding: 2px 9px;
    background: rgba(255, 255, 255, 0.96);
    color: var(--shop-brand);
    border-radius: 999px;
    font-size: 10.5px; font-weight: 600;
    letter-spacing: 0.01em;
    backdrop-filter: blur(4px);
}
.shop-item__badge--promo { background: #c81e1e; color: #fff; }
.shop-item__badge--rupture { background: rgba(120, 120, 128, 0.16); color: #4b5563; }

.shop-item__body { padding: 9px 0 0; min-width: 0; }
.shop-item__name {
    font-size: 13px; font-weight: 600;
    color: var(--shop-text);
    line-height: 1.35;
    letter-spacing: -0.008em;
    margin: 0;
}
.shop-item__sub {
    font-size: 11.5px;
    color: var(--shop-text-quiet);
    margin-top: 2px;
    line-height: 1.45;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

.shop-item__foot {
    padding: 6px 0 0;
    display: flex;
    align-items: baseline;
    gap: 8px;
}
.shop-item__price {
    font-size: 13px; font-weight: 700;
    color: var(--shop-text);
    font-variant-numeric: tabular-nums;
    letter-spacing: -0.012em;
}
/* « TTC » : discret, il informe sans concurrencer le prix. Une mention légale
   n'a pas à crier, elle a à être lisible. */
.shop-item__price-tax {
    font-size: 9.5px; font-weight: 500; margin-left: 4px;
    color: var(--shop-text-quiet); letter-spacing: 0;
}
.shop-detail__price-tax {
    font-size: 11.5px; font-weight: 500;
    color: var(--shop-text-quiet); letter-spacing: 0;
}
.shop-item__price--old {
    font-size: 11.5px; font-weight: 400;
    color: var(--shop-text-quiet);
    text-decoration: line-through;
    margin-right: 0;
}
.shop-item__price--devis {
    font-size: 12px; font-weight: 600;
    color: var(--shop-text-muted);
    letter-spacing: -0.005em;
}
.shop-item__stock {
    margin-left: auto;
    font-size: 10.5px;
    color: var(--shop-text-quiet);
    white-space: nowrap;
}
.shop-item__stock--low { color: #b45309; }
.shop-item__stock--out { color: #c81e1e; }

/* Le bouton d'ajout vit SUR la photo et n'apparaît qu'au survol. */
.shop-item__add {
    -webkit-appearance: none;
    appearance: none;
    width: 30px; height: 30px;
    min-width: 30px; min-height: 30px;
    padding: 0;
    box-sizing: border-box;
    border-radius: 50%;
    background: #fff;
    color: var(--shop-text);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 17px; font-weight: 400;
    border: 0;
    box-shadow: 0 1px 5px rgba(0, 0, 0, 0.2);
    line-height: 1;
    cursor: pointer;
    opacity: 0;
    transition: opacity 0.12s ease, background 0.12s ease, color 0.12s ease;
    flex-shrink: 0;
    z-index: 2;
}
.shop-item:hover .shop-item__add,
.shop-item__add:focus-visible { opacity: 1; }
.shop-item__add:hover { background: var(--shop-brand); color: #fff; }
.shop-item__add:disabled {
    background: rgba(255, 255, 255, 0.9);
    color: var(--shop-text-quiet);
    cursor: not-allowed;
    box-shadow: none;
}
/* Produit à déclinaisons ou à choix obligatoire : le geste ouvre la fiche, il
   n'ajoute pas. Le chevron le dit ; reste à retirer le soulignement du lien. */
.shop-item__add--choose { text-decoration: none; }

/* Retour visuel après un ajout au panier. */
.shop-item--added .shop-item__media { background: var(--shop-brand-soft); }

/* ── Mobile : la grille devient une liste à filet ─────────────────────── */
@media (max-width: 599px) {
    .shop-item {
        flex-direction: row;
        align-items: center;
        gap: 12px;
        padding: 11px 0;
        border-bottom: 0.5px solid var(--shop-border);
    }
    .shop-item__link {
        flex-direction: row;
        align-items: center;
        gap: 12px;
        flex: 1;
        min-width: 0;
    }
    .shop-item__media {
        width: 56px; height: 56px;
        aspect-ratio: auto;
        border-radius: 10px;
        flex-shrink: 0;
    }
    .shop-item__placeholder { font-size: 17px; }
    .shop-item__badge {
        top: 3px; left: 3px;
        padding: 1px 5px;
        font-size: 9px;
    }
    .shop-item__body { padding: 0; flex: 1; min-width: 0; }
    .shop-item__foot {
        padding: 0 40px 0 0;   /* place pour le bouton d'ajout, calé à droite */
        flex-direction: column;
        align-items: flex-end;
        gap: 4px;
        flex-shrink: 0;
    }
    .shop-item__stock { margin-left: 0; }
    /* Le bouton vit dans la photo (56 px sur mobile) : il en sort pour se
       caler au bord droit de la LIGNE, qui est le bloc positionné.
       Le calage lui-même est plus bas dans le fichier (bloc « carte produit
       cliquable ») : les règles desktop `right/bottom` y sont posées APRÈS
       celles-ci et gagnaient à spécificité égale. */
    .shop-item__media { position: static; overflow: visible; }
    .shop-item__media img { border-radius: 10px; }
    .shop-item__add {
        opacity: 1;
        width: 28px; height: 28px;
        min-width: 28px; min-height: 28px;
        background: var(--shop-surface);
        box-shadow: 0 1px 3px rgba(0, 0, 0, .18);
        font-size: 15px;
    }
    .shop-item__add-form .shop-item__add { transform: none; }
}
/* ============================================================
   PANIER (mobile = CTA sticky bottom ; desktop = sidebar)
   ============================================================ */

/* MOBILE : CTA sticky qui ouvre une sheet/route panier */
.shop-cta-mobile {
    position: fixed;
    left: 0; right: 0; bottom: 0;
    padding: 10px 12px calc(10px + env(safe-area-inset-bottom, 0px));
    background: rgba(255, 255, 255, 0.92);
    backdrop-filter: blur(20px);
    -webkit-backdrop-filter: blur(20px);
    z-index: 20;
    display: block;
}
@media (min-width: 900px) { .shop-cta-mobile { display: none; } }

.shop-cta-mobile__btn {
    width: 100%;
    height: 48px;
    background: var(--shop-brand);
    color: #fff;
    border: 0;
    border-radius: 14px;
    font-size: 15px; font-weight: 600;
    letter-spacing: -0.012em;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 10px;
    box-shadow:
        0 1px 0 rgba(255, 255, 255, 0.25) inset,
        0 8px 20px var(--shop-brand-shadow);
    cursor: pointer;
    font-family: inherit;
    text-decoration: none;
    transition: transform 0.1s ease;
}
.shop-cta-mobile__btn:active { transform: translateY(1px); }
.shop-cta-mobile__btn--empty {
    background: rgba(120, 120, 128, 0.18);
    color: var(--shop-text-muted);
    box-shadow: none;
    cursor: default;
}
.shop-cta-mobile__sep { opacity: 0.6; }

/* DESKTOP : panier sidebar 380 px à droite */
.shop-cart {
    display: none;
    background: var(--shop-surface);
    border-left: 1px solid var(--shop-border);
    flex-direction: column;
    position: sticky;
    top: 56px;
    align-self: start;
    /* hauteur = contenu (pas de grand vide quand peu d'articles), plafonnée au viewport */
    max-height: calc(100vh - 56px);
}
@media (min-width: 900px) { .shop-cart { display: flex; } }

.shop-cart__head {
    padding: 20px 24px 14px;
    border-bottom: 1px solid var(--shop-border);
    flex-shrink: 0;
}
.shop-cart__title {
    font-size: 17px; font-weight: 700;
    letter-spacing: -0.015em;
    color: var(--shop-text);
    margin: 0;
}
.shop-cart__sub {
    font-size: 12px;
    color: var(--shop-text-muted);
    margin-top: 2px;
}
.shop-cart__list {
    flex: 0 1 auto;
    min-height: 0;
    overflow-y: auto;
    padding: 12px 16px;
}
.shop-cart__row {
    display: flex;
    gap: 10px;
    padding: 10px 8px;
    border-radius: 10px;
    align-items: center;
}
.shop-cart__row:hover { background: var(--shop-bg); }
.shop-cart__row-qty {
    min-width: 28px;
    font-size: 13px; font-weight: 700;
    color: var(--shop-brand);
    font-variant-numeric: tabular-nums;
}
.shop-cart__row-body { flex: 1; min-width: 0; }
.shop-cart__row-name {
    font-size: 13px; font-weight: 500;
    color: var(--shop-text);
    letter-spacing: -0.005em;
}
.shop-cart__row-meta {
    font-size: 11px;
    color: var(--shop-text-quiet);
    margin-top: 1px;
}
.shop-cart__row-price {
    font-size: 13px; font-weight: 600;
    color: var(--shop-text);
    font-variant-numeric: tabular-nums;
}
.shop-cart__empty {
    padding: 30px 2px 12px;
    color: var(--shop-text-quiet);
}
.shop-cart__empty-icon { display: none; }
.shop-cart__empty-title {
    font-size: 14px; font-weight: 650;
    letter-spacing: -0.018em;
    color: var(--shop-text);
    margin: 0 0 4px;
}
.shop-cart__empty-sub {
    font-size: 12.5px;
    color: var(--shop-text-muted);
    line-height: 1.6;
}

.shop-cart__foot {
    padding: 16px 24px 20px;
    border-top: 1px solid var(--shop-border);
    background: var(--shop-surface);
    flex-shrink: 0;
}
.shop-cart__totals { padding: 4px 0 14px; }
.shop-cart__total-row {
    display: flex;
    justify-content: space-between;
    font-size: 12px;
    color: var(--shop-text-muted);
    padding: 3px 0;
    font-variant-numeric: tabular-nums;
}
.shop-cart__total-row--main {
    font-size: 17px; font-weight: 700;
    color: var(--shop-text);
    padding-top: 10px;
    margin-top: 8px;
    border-top: 1px solid var(--shop-border);
    letter-spacing: -0.015em;
}

.shop-cart__cta {
    width: 100%;
    height: 48px;
    background: var(--shop-brand);
    color: #fff;
    border: 0;
    border-radius: 12px;
    font-size: 15px; font-weight: 600;
    letter-spacing: -0.012em;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 10px;
    box-shadow:
        0 1px 0 rgba(255, 255, 255, 0.25) inset,
        0 6px 18px var(--shop-brand-shadow);
    cursor: pointer;
    font-family: inherit;
    text-decoration: none;
    transition: transform 0.1s ease;
}
.shop-cart__cta:hover { transform: translateY(-1px); }
.shop-cart__cta:active { transform: translateY(0); }
.shop-cart__cta--empty {
    background: rgba(120, 120, 128, 0.18);
    color: var(--shop-text-muted);
    box-shadow: none;
    cursor: default;
    pointer-events: none;
}
.shop-cart__cta-sep { opacity: 0.6; }
.shop-cart__hint {
    text-align: center;
    font-size: 11px;
    color: var(--shop-text-quiet);
    margin-top: 10px;
    letter-spacing: 0.02em;
}

/* ============================================================
   EMPTY STATE (grille vide)
   ============================================================ */
/* ── L'ÉTAT VIDE. Une forme, et la même aux trois endroits où la vitrine en
      sert un : la grille du catalogue, le tiroir panier, la page panier.
      Elles en avaient TROIS, toutes centrées, deux avec une illustration.

      Un titre, une phrase, un geste, ALIGNÉS À GAUCHE comme le reste de la
      page. Pas d'icône de 40 px : le dessin d'un panier barré n'apprend rien à
      qui vient de voir son panier se vider, et centrer trois lignes au milieu
      d'une page alignée à gauche fabrique un bloc qui flotte. La phrase dit
      POURQUOI c'est vide, la seule chose que le client ignore. Le geste est le
      seul de la zone : il n'a pas besoin d'être vert. */
.shop-empty {
    grid-column: 1 / -1;
    padding: 34px 2px 12px;
    max-width: 46ch;
    color: var(--shop-text-muted);
}
.shop-empty p { font-size: 13px; line-height: 1.6; margin: 0 0 13px; }
.shop-empty a {
    display: inline-block;
    padding: 7px 13px;
    background: var(--sf-ctl);
    color: var(--shop-text);
    border-radius: 8px;
    font-size: 12.5px; font-weight: 600;
    text-decoration: none;
}
.shop-empty a:hover { background: var(--sf-ctl-hover); }

/* ============================================================
   PAGINATION (centrée discrète, scan-first = peu de pages)
   ============================================================ */
.shop-pagination {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    padding: 24px 0;
    margin-top: 16px;
}
.shop-pagination__btn {
    padding: 6px 12px;
    background: var(--sf-ctl);
    border-radius: 999px;
    font-size: 13px; font-weight: 500;
    color: var(--shop-text);
    text-decoration: none;
    font-variant-numeric: tabular-nums;
}
.shop-pagination__btn--current {
    background: var(--shop-text);
    color: #fff;
    border-color: var(--shop-text);
    font-weight: 600;
}
.shop-pagination__btn:hover:not(.shop-pagination__btn--current) {
    background: var(--shop-bg);
}

/* ============================================================
   TOAST (notifications éphémères)
   ============================================================ */
.shop-toast-container {
    position: fixed;
    bottom: 80px;
    left: 12px; right: 12px;
    z-index: 100;
    display: flex; flex-direction: column;
    gap: 8px;
    pointer-events: none;
}
@media (min-width: 900px) {
    .shop-toast-container {
        bottom: 20px;
        left: auto;
        right: 20px;
        max-width: 360px;
    }
}
.shop-toast {
    background: var(--shop-text);
    color: #fff;
    padding: 12px 16px;
    border-radius: 10px;
    font-size: 13px;
    line-height: 1.4;
    box-shadow: 0 8px 24px rgba(0,0,0,0.18);
    pointer-events: auto;
    animation: shopToastIn .25s ease-out;
}
.shop-toast--success { background: var(--shop-brand); }
.shop-toast--error { background: #dc2626; }
.shop-toast-hide { animation: shopToastOut .2s ease-in forwards; }
@keyframes shopToastIn {
    from { transform: translateY(20px); opacity: 0; }
    to { transform: translateY(0); opacity: 1; }
}
@keyframes shopToastOut {
    from { transform: translateY(0); opacity: 1; }
    to { transform: translateY(20px); opacity: 0; }
}

/* ============================================================
   FICHE PRODUIT (.shop-detail)
   ============================================================ */
.shop-detail {
    padding: 0 0 100px;  /* place pour CTA sticky mobile */
}
@media (min-width: 900px) {
    .shop-detail {
        display: grid;
        grid-template-columns: 1fr 1fr;
        gap: 32px;
        max-width: 1280px;
        margin: 0 auto;
        padding: 24px 32px;
        align-items: start;
    }
}

/* ─── Média : photo + galerie + back button ─── */
.shop-detail__media {
    position: relative;
    background: var(--shop-surface);
}
@media (min-width: 900px) {
    .shop-detail__media {
        position: sticky;
        top: 72px;  /* sous le header 56px + marge */
        border-radius: var(--shop-radius-card);
        overflow: hidden;
    }
}

.shop-detail__back {
    position: absolute;
    top: 12px; left: 12px;
    width: 36px; height: 36px;
    border-radius: 50%;
    background: rgba(255, 255, 255, 0.92);
    backdrop-filter: blur(20px);
    -webkit-backdrop-filter: blur(20px);
    color: var(--shop-text);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    text-decoration: none;
    z-index: 5;
    box-shadow: 0 2px 6px rgba(0,0,0,0.08);
}
@media (min-width: 900px) { .shop-detail__back { display: none; } }

.shop-detail__hero {
    position: relative;
    aspect-ratio: 1 / 1;
    background: #f0f0f2;
    border-radius: 13px;
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
}
@media (min-width: 900px) { .shop-detail__hero { aspect-ratio: 4 / 3; } }
.shop-detail__hero-img {
    width: 100%; height: 100%;
    object-fit: cover;
    display: block;
}
.shop-detail__hero-placeholder {
    font-size: 72px;
    font-weight: 700;
    color: var(--shop-text-quiet);
    opacity: 0.35;
    letter-spacing: -0.04em;
}

.shop-detail__badge {
    position: absolute;
    top: 12px; right: 12px;
    padding: 4px 10px;
    background: rgba(255, 255, 255, 0.95);
    color: var(--shop-brand);
    border-radius: 999px;
    font-size: 11px; font-weight: 700;
    letter-spacing: 0.02em;
    z-index: 4;
}
.shop-detail__badge--promo { background: #dc2626; color: #fff; }
.shop-detail__badge--rupture { background: rgba(120, 120, 128, 0.16); color: #4b5563; }

.shop-detail__gallery {
    display: flex;
    gap: 6px;
    padding: 10px;
    overflow-x: auto;
    scrollbar-width: none;
    background: var(--shop-surface);
}
.shop-detail__gallery::-webkit-scrollbar { display: none; }
.shop-detail__thumb {
    flex-shrink: 0;
    width: 64px; height: 64px;
    border-radius: 8px;
    overflow: hidden;
    border: 2px solid transparent;
    padding: 0;
    background: transparent;
    cursor: pointer;
}
.shop-detail__thumb img {
    width: 100%; height: 100%;
    object-fit: cover;
    display: block;
}
.shop-detail__thumb--active { border-color: var(--shop-brand); }
@media (min-width: 900px) {
    .shop-detail__thumb { width: 72px; height: 72px; }
}

/* ─── Info : nom, prix, desc, sections ─── */
.shop-detail__info {
    padding: 20px 16px 0;
}
@media (min-width: 900px) {
    .shop-detail__info {
        padding: 0;
        max-width: 520px;
    }
}

.shop-detail__name {
    font-size: 22px;
    font-weight: 700;
    color: var(--shop-text);
    letter-spacing: -0.02em;
    line-height: 1.2;
    margin: 0 0 4px;
}
@media (min-width: 900px) { .shop-detail__name { font-size: 32px; letter-spacing: -0.025em; } }

.shop-detail__category {
    font-size: 12px;
    color: var(--shop-text-muted);
    margin: 0 0 14px;
}
.shop-detail__category a {
    color: var(--shop-text-muted);
    text-decoration: none;
}
.shop-detail__category a:hover { color: var(--shop-text); }

.shop-detail__price {
    display: flex;
    align-items: baseline;
    gap: 10px;
    margin-bottom: 16px;
}
.shop-detail__price-current {
    font-size: 24px;
    font-weight: 700;
    color: var(--shop-text);
    font-variant-numeric: tabular-nums;
    letter-spacing: -0.02em;
}
@media (min-width: 900px) { .shop-detail__price-current { font-size: 28px; } }
.shop-detail__price-old {
    font-size: 14px;
    font-weight: 500;
    color: var(--shop-text-muted);
    text-decoration: line-through;
    font-variant-numeric: tabular-nums;
}

.shop-detail__desc {
    font-size: 14px;
    color: #374151;
    line-height: 1.6;
    margin-bottom: 16px;
}
.shop-detail__desc p { margin: 0 0 10px; }
.shop-detail__desc p:last-child { margin-bottom: 0; }

.shop-detail__stock {
    font-size: 12px;
    color: var(--shop-brand);
    font-weight: 600;
    margin: 0 0 16px;
    letter-spacing: -0.005em;
}
.shop-detail__stock--low { color: #d97706; }
.shop-detail__stock--out { color: #dc2626; }

/* ─── Variants ─── */
.shop-detail__variants { margin-bottom: 16px; }
.shop-detail__variant-group { margin-bottom: 12px; }
.shop-detail__variant-label {
    display: block;
    font-size: 11px;
    font-weight: 700;
    color: var(--shop-text-muted);
    letter-spacing: 0.04em;
    text-transform: uppercase;
    margin-bottom: 6px;
}
.shop-detail__variant-options {
    display: flex; flex-wrap: wrap;
    gap: 6px;
}
.shop-detail__variant-btn {
    padding: 8px 14px;
    background: rgba(120, 120, 128, 0.10);
    color: var(--shop-text);
    border: 0;
    border-radius: 999px;
    font-size: 13px; font-weight: 500;
    cursor: pointer;
    font-family: inherit;
    letter-spacing: -0.008em;
}
.shop-detail__variant-btn:hover { background: rgba(120, 120, 128, 0.18); }
.shop-detail__variant-btn--active {
    background: var(--shop-text);
    color: #fff;
    font-weight: 600;
}
.shop-detail__variant-status {
    font-size: 12px;
    color: var(--shop-text-muted);
    margin: 8px 0 0;
}

/* ─── CTA form (qty + bouton ajouter) ─── */
/* LE FORMULAIRE D'AJOUT EST UNE COLONNE, la RANGÉE n'est que le compteur et
   le bouton. Corrigé le 22/09/2026, vu à l'écran à 1366 px.

   La règle disait `display:flex` sans direction — une rangée. Elle avait été
   écrite pour les deux seuls enfants du formulaire d'alors : le compteur de
   quantité et le bouton d'ajout. Deux choses s'y sont ajoutées depuis, sans
   que la règle bouge, et sont donc devenues des items de cette rangée :

     · la REMARQUE (« Une remarque ? »), sur la fiche produit, dès que le
       produit a des options. Le champ se retrouvait à 150 px de large, à
       gauche du compteur, et « Ajouter au panier » passait à la ligne dans
       son propre bouton ;
     · les ÉTAPES DE COMPOSITION, sur la page publique d'une formule. Les cinq
       étapes d'un menu, la remarque, le compteur et le bouton tenaient sur
       une seule rangée : les choix tombaient dans une colonne de 145 px, et
       le compteur, étiré sur toute la hauteur des étapes par l'alignement par
       défaut, devenait une dalle grise de 650 px de haut.

   Le formulaire redevient une colonne ; `.shop-detail__cta-row` porte la
   rangée, et elle ne contient que ce pour quoi elle a été écrite. */
.shop-detail__cta-form {
    display: block;
    margin-bottom: 14px;
}
.shop-detail__cta-row {
    display: flex;
    gap: 10px;
}

.shop-detail__qty {
    display: inline-flex;
    align-items: center;
    background: rgba(120, 120, 128, 0.10);
    border-radius: 12px;
    padding: 2px;
    flex-shrink: 0;
}
.shop-detail__qty-btn {
    width: 36px; height: 40px;
    background: transparent;
    border: 0;
    color: var(--shop-text);
    font-size: 18px; font-weight: 600;
    cursor: pointer;
    border-radius: 10px;
    font-family: inherit;
}
.shop-detail__qty-btn:hover { background: rgba(255, 255, 255, 0.6); }
.shop-detail__qty-input {
    width: 36px;
    height: 40px;
    background: transparent;
    border: 0;
    text-align: center;
    font-size: 15px; font-weight: 700;
    color: var(--shop-text);
    font-family: inherit;
    font-variant-numeric: tabular-nums;
    pointer-events: none;
}

.shop-detail__cta {
    flex: 1;
    height: 44px;
    background: var(--shop-brand);
    color: #fff;
    border: 0;
    border-radius: 12px;
    font-size: 14px; font-weight: 600;
    letter-spacing: -0.012em;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    box-shadow:
        0 1px 0 rgba(255, 255, 255, 0.25) inset,
        0 6px 16px var(--shop-brand-shadow);
    cursor: pointer;
    font-family: inherit;
    text-decoration: none;
    transition: transform 0.1s ease;
}
.shop-detail__cta:hover { transform: translateY(-1px); }
.shop-detail__cta:active { transform: translateY(0); }
.shop-detail__cta:disabled {
    background: rgba(120, 120, 128, 0.18);
    color: var(--shop-text-muted);
    box-shadow: none;
    cursor: not-allowed;
    transform: none;
}
.shop-detail__cta-sep { opacity: 0.6; }
.shop-detail__cta--outline {
    background: var(--sf-ctl);
    color: var(--shop-text);
    border: 0;
    box-shadow: none;
    width: 100%;
    margin-bottom: 14px;
}
.shop-detail__cta--outline:hover { background: var(--sf-ctl-hover); transform: none; }

/* ─── Sections expandables (<details>) ─── */
.shop-detail__details {
    padding: 9px 0 0;
}
.shop-detail__details summary {
    cursor: pointer;
    list-style: none;
    font-size: 14px;
    font-weight: 600;
    color: var(--shop-text);
    display: flex;
    align-items: center;
    justify-content: space-between;
    letter-spacing: -0.008em;
}
.shop-detail__details summary::-webkit-details-marker { display: none; }
/* Le repli se DESSINE. C'étaient un « + » et un « − » tapés au clavier, dont
   la chasse et l'alignement suivaient la police du système, sur les quatre
   sections de la fiche et sur le code promo du panier. Un chevron en masque
   SVG, qui pivote : le même dessin dit les deux états. */
.shop-detail__details summary::after {
    content: "";
    width: 13px; height: 13px;
    margin-left: 12px;
    flex-shrink: 0;
    background: var(--shop-text-muted);
    -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E") center / contain no-repeat;
    mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E") center / contain no-repeat;
    transition: transform .15s ease;
}
.shop-detail__details[open] summary::after { transform: rotate(180deg); }

.shop-detail__details-body {
    padding-top: 10px;
    font-size: 13px;
    color: #374151;
    line-height: 1.55;
}
.shop-detail__details-body p { margin: 0 0 8px; }
.shop-detail__details-row {
    display: flex;
    justify-content: space-between;
    padding: 6px 0;
    font-size: 13px;
    color: var(--shop-text);
}
.shop-detail__details-row:first-child { border-top: 0; }
.shop-detail__details-row span:first-child { color: var(--shop-text-muted); }

/* CTA sticky mobile sur la fiche : masqué PC */
.shop-cta-mobile--detail { display: block; }
@media (min-width: 900px) { .shop-cta-mobile--detail { display: none; } }

/* ============================================================
   PAGE PANIER (.shop-cart-page) — vue dédiée /panier/
   ============================================================ */
.shop-cart-page {
    padding: 16px 16px 100px;
}
@media (min-width: 900px) {
    .shop-cart-page {
        display: grid;
        grid-template-columns: 1fr 360px;
        gap: 32px;
        /* 1280, comme `.shop-content` et `.co-wrap` : voir le commentaire
           « un seul axe » sous `.shop-apropos`. */
        max-width: 1280px;
        margin: 0 auto;
        padding: 32px;
        align-items: start;
    }
}

.shop-cart-page__items-col { min-width: 0; }

.shop-cart-page__head {
    margin-bottom: 18px;
}
.shop-cart-page__title {
    font-size: 24px;
    font-weight: 700;
    color: var(--shop-text);
    letter-spacing: -0.022em;
    margin: 0 0 4px;
}
@media (min-width: 900px) { .shop-cart-page__title { font-size: 32px; } }
.shop-cart-page__count {
    font-size: 13px;
    color: var(--shop-text-muted);
    margin: 0;
}

/* ─── Items list ─── */
.shop-cart-page__items {
    list-style: none;
    padding: 0;
    margin: 0 0 16px;
    background: none;
    border: 0;
    border-radius: 0;
}
.shop-cart-page__item {
    display: grid;
    grid-template-columns: 72px 1fr auto;
    gap: 12px;
    padding: 13px 8px;
    margin: 0 -8px;
    border-radius: 9px;
    align-items: center;
}
.shop-cart-page__item:hover { background: var(--sf-2); }
@media (min-width: 600px) {
    .shop-cart-page__item { grid-template-columns: 64px 1fr auto; gap: 14px; padding: 14px 2px; }
}

.shop-cart-page__item-img {
    width: 72px;
    height: 72px;
    border-radius: 10px;
    overflow: hidden;
    background: #f0f0f2;
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--shop-text-quiet);
    font-size: 20px; font-weight: 700;
    text-decoration: none;
    flex-shrink: 0;
}
@media (min-width: 600px) {
    .shop-cart-page__item-img { width: 64px; height: 64px; }
}
.shop-cart-page__item-img img {
    width: 100%; height: 100%;
    object-fit: cover;
    display: block;
}

.shop-cart-page__item-body { min-width: 0; }
/* Deux lignes, pas une : « Baguette tradition française c… » ne se reconnaît
   pas. Le panier est l'écran où le client vérifie ce qu'il achète. */
.shop-cart-page__item-name {
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    line-clamp: 2;
    font-size: 14px;
    font-weight: 600;
    color: var(--shop-text);
    text-decoration: none;
    letter-spacing: -0.008em;
    line-height: 1.3;
    margin-bottom: 2px;
    overflow: hidden;
}
.shop-cart-page__item-name:hover { color: var(--shop-brand); }
.shop-cart-page__item-unit {
    font-size: 12px;
    color: var(--shop-text-muted);
    margin: 0 0 8px;
    font-variant-numeric: tabular-nums;
}

.shop-cart-page__item-qty {
    display: inline-flex;
    align-items: center;
    background: rgba(120, 120, 128, 0.10);
    border-radius: 10px;
    padding: 2px;
    width: fit-content;
}
.shop-cart-page__qty-form { margin: 0; display: contents; }
.shop-cart-page__item-qty button {
    width: 30px; height: 32px;
    background: transparent;
    border: 0;
    color: var(--shop-text);
    font-size: 16px; font-weight: 600;
    cursor: pointer;
    border-radius: 8px;
    font-family: inherit;
}
.shop-cart-page__item-qty button:hover:not(:disabled) { background: rgba(255, 255, 255, 0.6); }
.shop-cart-page__item-qty button:disabled { opacity: 0.4; cursor: not-allowed; }
.shop-cart-page__qty-value {
    width: 40px;
    min-width: 40px;
    height: 32px;
    text-align: center;
    font-size: 14px;
    font-weight: 700;
    color: var(--shop-text);
    font-variant-numeric: tabular-nums;
    background: transparent;
    border: 0;
    border-radius: 8px;
    padding: 0;
    font-family: inherit;
    -moz-appearance: textfield;
    appearance: textfield;
}
.shop-cart-page__qty-value::-webkit-outer-spin-button,
.shop-cart-page__qty-value::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.shop-cart-page__qty-value:focus { outline: 2px solid var(--shop-brand-shadow); background: var(--shop-surface); }

.shop-cart-page__item-variant {
    font-size: 12px;
    font-weight: 500;
    color: var(--shop-text-muted);
    margin: 0 0 2px;
}
.shop-cart-page__item-stock {
    font-size: 11.5px;
    font-weight: 500;
    color: #b45309;
    margin: 6px 0 0;
}
.shop-cart-page__item-stock--max { color: #dc2626; }

.shop-cart-page__item-actions {
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: 6px;
}
.shop-cart-page__item-total {
    font-size: 15px;
    font-weight: 700;
    color: var(--shop-text);
    font-variant-numeric: tabular-nums;
    letter-spacing: -0.012em;
}
@media (min-width: 600px) { .shop-cart-page__item-total { font-size: 17px; } }
.shop-cart-page__remove-form { margin: 0; }
/* 40 px de cible : à 26 px (icône 18 + 4 de padding) on visait la poubelle au
   pouce et on touchait la ligne à côté. */
.shop-cart-page__remove {
    background: transparent;
    border: 0;
    color: var(--shop-text-quiet);
    cursor: pointer;
    width: 40px;
    height: 40px;
    margin: -4px -8px -4px 0;
    padding: 0;
    border-radius: 10px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}
.shop-cart-page__remove:hover { color: #dc2626; background: rgba(220, 38, 38, 0.08); }

.shop-cart-page__continue {
    display: inline-block;
    font-size: 13px;
    color: var(--shop-text-muted);
    text-decoration: none;
    margin-top: 14px;
}
@media (min-width: 900px) { .shop-cart-page__continue { grid-column: 1; margin-top: 0; } }
.shop-cart-page__continue:hover { color: var(--shop-text); }

/* ─── Summary (aside droite PC / inline bas mobile) ─── */
.shop-cart-page__summary {
    background: var(--shop-surface);
    padding: 16px 0 0;
    margin-top: 20px;
    border-top: 1px solid var(--shop-border);
}
@media (min-width: 900px) {
    .shop-cart-page__summary {
        /* À gauche ce qu'on modifie, à droite ce qu'on paie : UN filet, et il
           est vertical. C'est déjà la forme de la page de commande. */
        border-top: 0;
        border-left: 1px solid var(--shop-border);
        padding: 0 0 0 22px;
        position: sticky;
        top: 72px;
        margin-top: 0;
    }
}

.shop-cart-page__coupon {
    padding-bottom: 6px;
    margin-bottom: 12px;
}
.shop-cart-page__coupon summary {
    cursor: pointer;
    font-size: 13px;
    font-weight: 600;
    color: var(--shop-text);
    list-style: none;
    display: flex;
    align-items: center;
    justify-content: space-between;
    letter-spacing: -0.005em;
}
.shop-cart-page__coupon summary::-webkit-details-marker { display: none; }
.shop-cart-page__coupon summary::after {
    content: ""; width: 12px; height: 12px; flex-shrink: 0;
    background: var(--shop-text-muted);
    -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E") center / contain no-repeat;
    mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E") center / contain no-repeat;
    transition: transform .15s ease;
}
.shop-cart-page__coupon[open] summary::after { transform: rotate(180deg); }

.shop-cart-page__coupon-body { padding-top: 12px; }
.shop-cart-page__coupon-form {
    display: flex;
    gap: 6px;
    margin: 0;
}
.shop-cart-page__coupon-input {
    flex: 1;
    padding: 9px 12px;
    background: var(--sf-ctl);
    border: 1px solid transparent;
    border-radius: 10px;
    font-size: 13px;
    color: var(--shop-text);
    font-family: inherit;
}
.shop-cart-page__coupon-input:hover { background: var(--sf-ctl-hover); }
.shop-cart-page__coupon-input:focus { outline: 2px solid var(--shop-brand-shadow); border-color: var(--shop-brand); background: var(--shop-surface); }
.shop-cart-page__coupon-apply {
    padding: 9px 14px;
    background: var(--shop-text);
    color: #fff;
    border: 0;
    border-radius: 10px;
    font-size: 13px; font-weight: 600;
    cursor: pointer;
    font-family: inherit;
}
.shop-cart-page__coupon-applied {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 8px 12px;
    background: color-mix(in srgb, var(--shop-brand) 8%, transparent);
    color: var(--shop-brand);
    border-radius: 10px;
    font-size: 13px; font-weight: 600;
    margin: 0;
}
.shop-cart-page__coupon-remove {
    background: transparent;
    border: 0;
    color: var(--shop-brand);
    font-size: 18px;
    cursor: pointer;
    line-height: 1;
    padding: 0 4px;
}

.shop-cart-page__totals { margin-bottom: 16px; }
.shop-cart-page__total-row {
    display: flex;
    justify-content: space-between;
    padding: 4px 0;
    font-size: 13px;
    color: var(--shop-text-muted);
    font-variant-numeric: tabular-nums;
}
.shop-cart-page__total-row--discount { color: var(--shop-brand); font-weight: 500; }
.shop-cart-page__total-row--main {
    font-size: 17px;
    font-weight: 700;
    color: var(--shop-text);
    padding-top: 10px;
    margin-top: 8px;
    border-top: 1px solid var(--shop-border);
    letter-spacing: -0.015em;
}
/* Seule ligne du bloc (aucune remise) : son filet doublerait celui du coupon. */
.shop-cart-page__total-row--main:first-child {
    border-top: 0;
    padding-top: 0;
    margin-top: 0;
}

.shop-cart-page__cta {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    width: 100%;
    height: 48px;
    background: var(--shop-brand);
    color: #fff;
    border: 0;
    border-radius: 12px;
    font-size: 15px;
    font-weight: 600;
    letter-spacing: -0.012em;
    text-decoration: none;
    box-shadow:
        0 1px 0 rgba(255, 255, 255, 0.25) inset,
        0 6px 16px var(--shop-brand-shadow);
    cursor: pointer;
    transition: transform 0.1s ease;
}
.shop-cart-page__cta:hover { transform: translateY(-1px); }
.shop-cart-page__cta-sep { opacity: 0.6; }
/* Commande impossible (pause, stock, minimum) : le bouton reste à sa place mais
   ne promet plus rien — la raison est écrite juste au-dessus. */
.shop-cart-page__cta--off {
    background: rgba(120, 120, 128, 0.18);
    color: var(--shop-text-muted);
    box-shadow: none;
    cursor: default;
}
.shop-cart-page__cta--off:hover { transform: none; }

/* Ce qui bloque (ou débloque) la commande, dit avant le bouton. */
/* CE QUI S'ANNONCE EST UNE LIGNE, pas un aplat de couleur (22/09/2026).

   Ces trois phrases du panier — « plus que 9,50 € pour la livraison
   offerte », « livraison offerte pour cette commande », « commande minimum,
   encore X à ajouter » — étaient posées sur un aplat vert ou ambre à coins
   ronds de 10 px, sur une colonne qui ne contient aucun autre objet.
   C'est la bande de couleur que le produit s'interdit partout ailleurs, et
   c'est la même règle que l'empêchement de la vitrine et celui de la gestion :
   ce qui s'annonce n'est pas un objet, c'est un fait.

   La gravité reste lisible : elle est dans l'ENCRE. Le filet du haut sépare
   l'annonce du récapitulatif sur lequel elle porte — un trait qui travaille. */
.shop-cart-page__block {
    font-size: 12.5px;
    line-height: 1.4;
    font-weight: 500;
    color: var(--shop-brand);
    padding: 8px 0 0;
    border-top: 1px solid var(--shop-border);
    margin: 0 0 12px;
}
.shop-cart-page__block--warn { color: #b45309; }
/* Sur mobile, la barre sticky bas couvre déjà le CTA : on masque celui de l'aside
   pour éviter deux boutons « Commander » empilés (le récap chiffré reste utile). */
@media (max-width: 899px) { .shop-cart-page__cta { display: none; } }

.shop-cart-page__delivery-note {
    font-size: 11.5px;
    color: var(--shop-text-muted);
    text-align: center;
    margin: 10px 0 0;
}

.shop-cta-mobile--cart { display: block; }
@media (min-width: 900px) { .shop-cta-mobile--cart { display: none; } }

/* ============================================================
   DEMANDE DE DEVIS (.shop-devis)
   ============================================================

   MISE EN PAGE, 22/09/2026. Les boîtes étaient déjà tombées (le formulaire,
   les groupes et la carte du commerçant sont à `border:0` depuis la passe du
   21) — restait la HAUTEUR. Étiquette au-dessus du champ, champs de 41 px,
   bouton de 48, titre de 32 : la demande de devis générale mesurait plus de
   deux écrans et demi, pour onze champs dont sept facultatifs. On ne voyait
   jamais en même temps ce qu'on écrit et à qui on l'envoie.

   La page prend donc la grammaire de la page de commande : l'intitulé à
   gauche sur 104 px, le champ à droite, une rangée de 29 px. Cette mesure
   n'est pas reprise ici par goût — c'est CELLE de `checkout.css`
   (`.co-f`/`.co-in`, lignes 134-176), et les deux pages sont le même geste :
   on remplit, on envoie au commerçant. Deux feuilles, une mesure : si l'une
   bouge, l'autre doit bouger, et ce commentaire est là pour qu'on le sache.

   Le SEUL trait de la page est celui qui sépare les deux colonnes : à gauche
   ce qu'on écrit, à droite qui le reçoit. */
.shop-devis {
    padding: 16px 16px 100px;
    display: flex;
    flex-direction: column;
    gap: 18px;
}
@media (min-width: 900px) {
    .shop-devis {
        display: grid;
        grid-template-columns: minmax(0, 1fr) 318px;
        gap: 0 26px;
        max-width: 1280px;
        margin: 0 auto;
        padding: 28px 32px;
        align-items: start;
    }
}

.shop-devis__form-col { min-width: 0; }

/* ─── La rangée de saisie ─────────────────────────────────────────────
   Elle ne vaut QUE dans cette page : le suivi de commande partage la même
   grammaire `.shop-devis__*` (deux champs, un bouton) et n'a rien à gagner à
   des rangées de 29 px. Les surcharges sont donc toutes descendues sous
   `.shop-devis__f`, et les règles de base restent ce qu'elles étaient. */
.shop-devis__f {
    display: grid;
    grid-template-columns: 104px minmax(0, 1fr);
    align-items: center;
    gap: 8px;
    min-height: 29px;
    margin: 0 -6px;
    padding: 0 6px;
    border-radius: 6px;
}
/* Pas de filet entre deux rangées : une rangée d'une seule assise n'en a pas,
   le voile de survol suffit à dire où elle commence. */
.shop-devis__f:hover { background: var(--sf-2); }
.shop-devis__f--haut { align-items: start; min-height: 0; padding-top: 4px; padding-bottom: 4px; }
.shop-devis__f > .shop-devis__label {
    margin-bottom: 0;
    font-size: 11.5px;
    font-weight: 400;
    color: var(--fg-3);
    line-height: 1.25;
}
.shop-devis__v { min-width: 0; display: flex; align-items: center; gap: 6px; }
.shop-devis__v--libre { display: block; }
.shop-devis__duo { display: grid; grid-template-columns: 1fr 1fr; gap: 6px; width: 100%; min-width: 0; }
.shop-devis__duo--court { grid-template-columns: minmax(0, 1fr) 118px; }
/* `[hidden]` vient de la feuille du NAVIGATEUR : n'importe quelle règle
   d'auteur qui pose un `display` l'emporte sur lui. Trois éléments de cette
   page sont posés `hidden` dans le gabarit et révélés par `devis.js`. Deux
   d'entre eux s'affichaient DÉJÀ tout le temps avant le 22/09, et depuis que
   les tiroirs existent (28/07) :

     · « Position enregistrée » (`__geook`, `display:inline-flex`), soit la
       confirmation d'une géolocalisation que personne n'avait demandée ;
     · le bouton « Ajouter le lieu de l'intervention » (`__more`, même cause),
       qui restait affiché sous le tiroir qu'il venait d'ouvrir.

   Le troisième est neuf : la rangée « Date souhaitée » prend `display:grid`
   avec la nouvelle grammaire. Les trois sont rendus muets ici. */
.shop-devis__f[hidden],
.shop-devis__geook[hidden],
.shop-devis__more[hidden] { display: none; }

/* Le bouton de géolocalisation tient dans une rangée de 29 px : 8 px de
   rembourrage vertical la faisaient grandir de quatre pixels, et une seule
   rangée sur onze décalait tout ce qui suit. */
.shop-devis__f .shop-devis__geo { padding: 4px 11px; font-size: 12px; }
.shop-devis__unite { font-size: 11px; color: var(--fg-4); white-space: nowrap; }

.shop-devis__f .shop-devis__input,
.shop-devis__f .shop-devis__textarea {
    /* PAS de hauteur fixe : un champ qui remplit sa rangée soude son creux à
       celui de la rangée voisine, et deux champs deviennent une dalle grise.
       Relevé sur la page de commande le 22/09, corrigé là-bas de la même
       façon. */
    padding: 4px 8px;
    border-radius: 7px;
    font-size: 12.5px;
}
.shop-devis__f .shop-devis__textarea {
    min-height: 58px;
    padding: 6px 8px;
    line-height: 1.45;
}
.shop-devis__f:hover .shop-devis__input,
.shop-devis__f:hover .shop-devis__textarea { background: var(--sf-ctl-hover); }
.shop-devis__input--court { max-width: 96px; flex: 0 0 auto; }

@media (max-width: 899px) {
    /* Sur téléphone, 104 px d'intitulé ne laissent pas de quoi écrire une
       adresse. La rangée se remet en pile. */
    .shop-devis__f { grid-template-columns: 1fr; gap: 3px; margin: 0; padding: 0 0 10px; }
    .shop-devis__f:hover { background: none; }
    .shop-devis__f > .shop-devis__label { font-size: 12px; font-weight: 600; color: var(--shop-text); }
    .shop-devis__f .shop-devis__input,
    .shop-devis__f .shop-devis__textarea { padding: 10px 12px; font-size: 14px; border-radius: 10px; }
}

.shop-devis__back {
    display: inline-block;
    font-size: 13px;
    color: var(--shop-text-muted);
    text-decoration: none;
    margin-bottom: 14px;
}
.shop-devis__back:hover { color: var(--shop-text); }

.shop-devis__head {
    margin-bottom: 16px;
}
.shop-devis__title {
    font-size: 22px;
    font-weight: 700;
    color: var(--shop-text);
    letter-spacing: -0.022em;
    margin: 0 0 3px;
}
/* 32 px pour trois mots : le titre mangeait à lui seul la moitié de la
   première rangée, et il était suivi d'un sous-titre qui le redisait. */
@media (min-width: 900px) { .shop-devis__title { font-size: 19px; letter-spacing: -0.02em; } }
.shop-devis__subtitle {
    font-size: 14px;
    color: var(--shop-text-muted);
    margin: 0;
    line-height: 1.5;
}

/* ─── Carte produit concerné ─── */
/* Le produit concerné : une RANGÉE de la même famille que les autres, avec
   son voile de survol, pas une carte de 80 px posée avant le formulaire. */
.shop-devis__product {
    display: flex;
    gap: 10px;
    align-items: center;
    min-height: 29px;
    padding: 5px 6px;
    margin: 0 -6px;
    border-radius: 6px;
}
.shop-devis__product:hover { background: var(--sf-2); }
.shop-devis__product-img {
    width: 40px; height: 40px;
    border-radius: 8px;
    overflow: hidden;
    background: var(--shop-brand-soft);
    color: var(--shop-brand);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 15px; font-weight: 700;
    flex-shrink: 0;
}
.shop-devis__product-img img {
    width: 100%; height: 100%;
    object-fit: cover;
}
.shop-devis__product-body { flex: 1; min-width: 0; }
.shop-devis__product-name {
    font-size: 13px;
    font-weight: 600;
    color: var(--shop-text);
    letter-spacing: -0.008em;
    margin-bottom: 2px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.shop-devis__product-price {
    font-size: 12px;
    font-weight: 600;
    color: var(--shop-text);
    font-variant-numeric: tabular-nums;
    display: flex;
    align-items: baseline;
    gap: 8px;
}
.shop-devis__product-unit {
    font-size: 11px;
    color: var(--shop-text-quiet);
    font-weight: 400;
}
.shop-devis__product-price--devis {
    color: var(--shop-text-muted);
    font-weight: 500;
}

/* ─── Form ─── */
.shop-devis__form {
    background: var(--shop-surface);
    border: 0;
    padding: 0;
}

.shop-devis__fieldset {
    border: 0;
    padding: 0;
    margin: 0 0 18px;
}
.shop-devis__fieldset:last-of-type { margin-bottom: 0; }

.shop-devis__legend {
    font-size: 11px;
    font-weight: 700;
    color: var(--shop-text-muted);
    letter-spacing: 0.06em;
    text-transform: uppercase;
    margin-bottom: 12px;
    padding: 0;
}

.shop-devis__field {
    margin-bottom: 12px;
}
.shop-devis__field:last-child { margin-bottom: 0; }

.shop-devis__row {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 12px;
    margin-bottom: 12px;
}
@media (max-width: 480px) {
    .shop-devis__row { grid-template-columns: 1fr; gap: 0; }
    .shop-devis__row .shop-devis__field { margin-bottom: 12px; }
}

.shop-devis__label {
    display: block;
    font-size: 12px;
    font-weight: 600;
    color: var(--shop-text);
    margin-bottom: 6px;
    letter-spacing: -0.005em;
}
.shop-devis__req { color: #dc2626; font-weight: 600; }
.shop-devis__optional {
    color: var(--shop-text-quiet);
    font-weight: 400;
    font-size: 11px;
}

.shop-devis__input,
.shop-devis__textarea {
    width: 100%;
    padding: 11px 14px;
    background: var(--sf-ctl);
    border: 1px solid transparent;
    border-radius: 10px;
    font-size: 14px;
    color: var(--shop-text);
    font-family: inherit;
    letter-spacing: -0.005em;
    transition: border-color 0.15s, background 0.15s;
}
.shop-devis__input:hover,
.shop-devis__textarea:hover { background: var(--sf-ctl-hover); }
.shop-devis__textarea {
    min-height: 100px;
    line-height: 1.5;
    resize: vertical;
}
.shop-devis__input:focus,
.shop-devis__textarea:focus {
    outline: 2px solid var(--shop-brand-shadow);
    border-color: var(--shop-brand);
    background: var(--shop-surface);
}
.shop-devis__input::placeholder,
.shop-devis__textarea::placeholder { color: var(--shop-text-quiet); }
.shop-devis__input--narrow { max-width: 160px; }

/* Le bouton est VISIBLE par défaut, à toutes les largeurs. Il était masqué
   sous 900 px « remplacé par un CTA sticky » — sauf que seule la demande de
   devis produit en a un : le suivi de commande et la demande de devis
   générale se retrouvaient sans aucun bouton d'envoi sur téléphone. Un
   formulaire qui oublie le modifieur reste maintenant utilisable ; c'est
   celui qui a un CTA sticky qui doit se signaler. */
.shop-devis__submit {
    display: block;
    width: 100%;
    height: 48px;
    background: var(--shop-brand);
    color: #fff;
    border: 0;
    border-radius: 12px;
    font-size: 15px;
    font-weight: 600;
    letter-spacing: -0.012em;
    cursor: pointer;
    font-family: inherit;
    /* Le liseré blanc interne, l'ombre colorée de 16 px et le soulèvement au
       survol faisaient le bouton brillant de gabarit. Un bouton d'envoi n'a
       besoin ni de relief ni de mouvement pour se faire cliquer. */
    margin-top: 18px;
    transition: background 0.12s ease;
}
/* `--cta-mobile` a été retiré le 22/09 : les deux demandes de devis envoient
   maintenant depuis le bouton de la colonne de droite (`.shop-devis__go`), et
   plus personne ne portait le modificateur. Seul le suivi de commande se sert
   encore de `.shop-devis__submit`, dans son flux, à toutes les largeurs. */
.shop-devis__submit:hover { filter: brightness(0.94); }

/* ─── La colonne de droite : qui reçoit la demande ─────────────────────
   LE SEUL TRAIT PERMANENT DE LA PAGE. Il sépare deux natures : à gauche ce
   qu'on écrit, à droite chez qui cela part. C'est le même trait que sur la
   page de commande, au jeton près. */
@media (min-width: 900px) {
    .shop-devis__aside {
        padding-left: 26px;
        border-left: 1px solid var(--sf-line);
        align-self: stretch;
        position: sticky;
        top: 72px;
    }
}

.shop-devis__pan-title {
    font-size: 10px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.11em;
    color: var(--fg-4);
    margin: 0 0 7px;
}
.shop-devis__pro-card {
    background: var(--shop-surface);
    padding: 0;
}
.shop-devis__pro-name {
    font-size: 15px;
    font-weight: 700;
    color: var(--shop-text);
    margin: 0 0 4px;
    letter-spacing: -0.012em;
}
.shop-devis__pro-tagline {
    font-size: 12px;
    color: var(--shop-text-muted);
    margin: 0 0 14px;
    line-height: 1.4;
}

.shop-devis__pro-list {
    list-style: none;
    padding: 0;
    margin: 0;
}
.shop-devis__pro-row {
    display: flex;
    align-items: flex-start;
    gap: 9px;
    padding: 6px 0;
    font-size: 12.5px;
}
.shop-devis__pro-row:first-child { padding-top: 0; }
.shop-devis__pro-row-title {
    font-weight: 600;
    color: var(--shop-text);
    letter-spacing: -0.005em;
}
.shop-devis__pro-row-title a {
    color: var(--shop-text);
    text-decoration: none;
}
.shop-devis__pro-row-title a:hover { color: var(--shop-brand); }
.shop-devis__pro-row-sub {
    font-size: 11px;
    color: var(--shop-text-muted);
    margin-top: 1px;
}

/* Le bouton d'envoi vit dans la colonne de droite, sous ce qu'il envoie et
   chez qui — il reste à l'écran pendant toute la saisie, la colonne étant
   collante. Sous 900 px, la colonne passe SOUS le formulaire : c'est le CTA
   collant du bas qui prend le relais, et ce bouton-ci s'efface pour ne pas
   faire deux boutons d'envoi à trente pixels l'un de l'autre. */
.shop-devis__go { display: none; }
@media (min-width: 900px) {
    .shop-devis__go {
        display: block;
        width: 100%;
        margin-top: 14px;
        height: 34px;
        background: var(--shop-brand);
        color: #fff;
        border: 0;
        border-radius: 8px;
        font-size: 13px;
        font-weight: 600;
        letter-spacing: -0.01em;
        font-family: inherit;
        cursor: pointer;
        transition: background 0.12s ease;
    }
    .shop-devis__go:hover { filter: brightness(0.94); }
}
.shop-devis__note {
    font-size: 11px;
    color: var(--fg-4);
    line-height: 1.45;
    margin: 10px 0 0;
}
.shop-devis__note b { color: var(--shop-text); font-weight: 500; }

.shop-cta-mobile--devis { display: block; }
@media (min-width: 900px) { .shop-cta-mobile--devis { display: none; } }

/* ─── Empty state ─── */
/* Le panier vide reprend le conteneur de la page — même axe gauche, même
   largeur maximale — mais pas sa grille : il n'y a pas de récapitulatif à
   poser dans la seconde colonne. Sans ce modificateur, l'état vide occupait
   la colonne de 1fr d'une grille dont la seconde restait vide, et se
   retrouvait poussé d'un tiers de page vers la gauche. */
@media (min-width: 900px) {
    .shop-cart-page--vide {
        display: block;
        max-width: 1200px;
    }
}
.shop-cart-page__empty {
    padding: 18px 0 12px;
    max-width: 46ch;
}
.shop-cart-page__empty-icon { display: none; }
.shop-cart-page__empty-title {
    font-size: 15px;
    font-weight: 650;
    color: var(--shop-text);
    letter-spacing: -0.018em;
    margin: 0 0 5px;
}
.shop-cart-page__empty-sub {
    font-size: 13px;
    color: var(--shop-text-muted);
    margin: 0 0 14px;
    line-height: 1.6;
}
.shop-cart-page__empty-cta {
    display: inline-block;
    padding: 7px 13px;
    background: var(--sf-ctl);
    color: var(--shop-text);
    border-radius: 8px;
    font-size: 12.5px;
    font-weight: 600;
    text-decoration: none;
    box-shadow: 0 6px 16px var(--shop-brand-shadow);
}

/* ============================================================
   FOOTER (minimal — scan-first = pas de découverte tunnel)
   ============================================================ */
/* Deux étages, une seule laisse (1200 px) : identité + accès rapides en haut,
   filet légal + propriété en bas. Avant, les mentions légales étaient centrées
   sous une rangée justifiée gauche/droite — trois alignements pour trois
   lignes. */
.shop-foot {
    padding: 30px 16px 0;
    background: var(--shop-surface);
    border-top: 1px solid var(--shop-border);
    color: var(--shop-text-muted);
    font-size: 12px;
    line-height: 1.6;
}
.shop-foot__inner {
    max-width: 1200px;
    margin: 0 auto;
    padding-bottom: 22px;
    display: flex;
    flex-direction: column;
    gap: 18px;
}
@media (min-width: 900px) {
    .shop-foot {
        padding: 38px 32px 0;
    }
    .shop-foot__inner {
        flex-direction: row;
        align-items: flex-start;
        justify-content: space-between;
        gap: 40px;
    }
}
.shop-foot__brand {
    font-size: 14px;
    font-weight: 600;
    color: var(--shop-text);
}
.shop-foot__contact {
    display: flex; flex-wrap: wrap;
    gap: 2px 14px;
    margin-top: 3px;
}
.shop-foot__contact a {
    color: var(--shop-text-muted);
    text-decoration: none;
}
.shop-foot__contact a:hover { color: var(--shop-text); }

/* Les portes de la top bar, répétées ici : sans elles, arrivé en bas de la
   grille le client n'a plus qu'à remonter chercher « RDV » ou « Mon espace ». */
.shop-foot__nav {
    display: flex; flex-wrap: wrap;
    gap: 2px 18px;
}
.shop-foot__nav a {
    font-size: 12.5px;
    color: var(--shop-text-muted);
    text-decoration: none;
}
.shop-foot__nav a:hover { color: var(--shop-text); }
@media (min-width: 900px) {
    /* Une seule ligne alignée à droite, pas une colonne : cinq liens empilés
       creusaient un pied de page de cinq lignes pour une vitrine qui tient en
       deux. */
    .shop-foot__nav {
        justify-content: flex-end;
        max-width: 62%;
        gap: 6px 20px;
    }
}

.shop-foot__bar {
    max-width: 1200px;
    margin: 0 auto;
    padding: 4px 0 18px;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 7px;
    text-align: center;
}
@media (min-width: 900px) {
    .shop-foot__bar {
        flex-direction: row;
        align-items: center;
        justify-content: space-between;
        text-align: left;
    }
}
.shop-foot__powered {
    font-size: 11.5px;
    color: var(--shop-text-quiet);
}
.shop-foot__powered a {
    color: var(--shop-text-muted);
    text-decoration: none;
}
.shop-foot__powered a:hover { color: var(--shop-text); }
.shop-foot__powered strong { color: var(--shop-text); font-weight: 600; }

/* ============================================================
   POWERED BY MARY (badge flottant — discret)
   ============================================================ */
.shop-powered {
    display: none;  /* la mention en footer suffit, pas de badge flottant */
}

/* ============================================================
   ACCESSIBILITY
   ============================================================ */
.shop-sr-only {
    position: absolute;
    width: 1px; height: 1px;
    padding: 0; margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}
.shop-skip-link {
    position: absolute;
    top: -40px;
    left: 8px;
    background: var(--shop-text);
    color: #fff;
    padding: 8px 16px;
    border-radius: 8px;
    text-decoration: none;
    z-index: 100;
    font-size: 13px; font-weight: 600;
}
.shop-skip-link:focus { top: 8px; }

/* Reduce motion */
@media (prefers-reduced-motion: reduce) {
    .shop-item,
    .shop-item__add,
    .shop-cart__cta,
    .shop-cta-mobile__btn,
    .shop-toast { transition: none; animation: none; }
}

/* ============================================================
   Pages légales (CGV, mentions, confidentialité, rétractation)
   + liens légaux du footer. 2026-06-11.
   ============================================================ */
.shop-legal { max-width: 1280px; margin: 0 auto; padding: 24px 16px 60px; font-size: 14.5px; line-height: 1.65; color: #3a3a3c; }
/* Même chose que « À propos » : la mesure de lecture reste courte, dans
   l'axe commun. Voir le commentaire « un seul axe » plus haut. */
.shop-legal > * { max-width: 760px; }
@media (min-width: 900px) { .shop-legal { padding: 24px 32px 60px; } }
.shop-legal h1 { font-size: 24px; font-weight: 700; letter-spacing: -0.02em; color: #1d1d1f; margin: 18px 0 6px; }
.shop-legal h2 { font-size: 15.5px; font-weight: 650; color: #1d1d1f; margin: 26px 0 8px; }
.shop-legal section { margin-bottom: 6px; }
/* Le reset global met les marges de <p> à 0 : sans ça, deux paragraphes
   juridiques consécutifs forment un seul pavé illisible. */
.shop-legal p { margin: 0 0 12px; }
.shop-legal ul { padding-left: 22px; margin: 0 0 12px; }
.shop-legal li { margin-bottom: 6px; }
.shop-legal a { color: var(--shop-brand, #10b981); text-decoration: underline; text-underline-offset: 2px; }
.shop-legal__nav { display: flex; gap: 6px; flex-wrap: wrap; margin-bottom: 8px; }
.shop-legal__nav a { font-size: 12.5px; font-weight: 500; color: #6e6e73; text-decoration: none; padding: 6px 12px; background: var(--sf-ctl); border-radius: 999px; }
.shop-legal__nav a:hover { background: var(--sf-ctl-hover); color: var(--shop-text); }
.shop-legal__nav a.on { background: #1d1d1f; color: #fff; }
.shop-legal__vendor { background: #f5f5f7; border-radius: 14px; padding: 16px 18px; margin: 14px 0 4px; }
.shop-legal__vendor h2 { margin-top: 0; }
/* Encadré neutre (même vocabulaire que .shop-legal__vendor) — pas de bande de
   couleur à gauche : le fond suffit à détacher le formulaire type du texte. */
.shop-legal__form-type { background: #f5f5f7; border-radius: 14px; margin: 12px 0; padding: 14px 18px; color: #5a5a5e; }
.shop-legal__form-type p { margin: 0 0 10px; }
.shop-legal__form-type p:last-child { margin-bottom: 0; }
.shop-legal__updated { margin-top: 34px; font-size: 12px; color: #8a8a8e; }

/* Le filet légal vit désormais DANS .shop-foot__bar : plus de padding propre
   (il posait une 3ᵉ marge sous une rangée déjà espacée). */
.shop-foot__legal { display: flex; gap: 6px 18px; flex-wrap: wrap; justify-content: center; }
.shop-foot__legal a { font-size: 11.5px; color: #8a8a8e; text-decoration: none; }
.shop-foot__legal a:hover { color: #1d1d1f; text-decoration: underline; }

/* Consentement CGV au checkout */
.sf-cgv-consent { display: flex; align-items: flex-start; gap: 10px; margin: 0 0 14px; font-size: 13px; line-height: 1.5; color: #3a3a3c; cursor: pointer; }
.sf-cgv-consent input { width: 17px; height: 17px; margin-top: 1px; flex-shrink: 0; accent-color: var(--shop-brand, #10b981); }
.sf-cgv-consent a { color: var(--shop-brand, #10b981); text-decoration: underline; }

/* ============================================================
   Avis clients — dépôt public (.shop-avis) + bloc fiche produit.
   ============================================================ */
.shop-avis { max-width: 640px; margin: 0 auto; padding: 24px 18px 60px; }
.shop-avis h1 { font-size: 22px; font-weight: 700; letter-spacing: -0.02em; margin: 6px 0; }
.shop-avis__sub { font-size: 13.5px; color: #6e6e73; line-height: 1.55; margin: 0 0 18px; }
/* Le message portait un aplat teinté ET un contour de la même teinte : deux
   fois le même signal. L'encre suffit à dire de quoi il s'agit. */
.shop-avis__msg { color: var(--shop-brand); font-size: 13px; font-weight: 500; margin-bottom: 14px; }
.shop-avis__msg--err { background: none; color: #c81e1e; }
/* `border: 0` EXPLICITE et non pas l'absence de règle : `.shop-avis__card` est
   un `<fieldset>`, et retirer son contour déclaré rend la main au `2px groove`
   du navigateur. Vu au rendu : une boîte noire autour de chaque produit à
   noter, pire que celle qu'on venait d'enlever. */
.shop-avis__card { background: #fff; border: 0; padding: 0; margin: 0 0 20px; }
.shop-avis__produit { display: flex; align-items: center; gap: 10px; font-size: 14.5px; font-weight: 600; padding: 0; }
.shop-avis__produit img { border-radius: 8px; object-fit: cover; }
.shop-avis__stars { display: flex; flex-direction: row-reverse; justify-content: flex-end; gap: 2px; margin: 10px 0; }
.shop-avis__star { cursor: pointer; }
.shop-avis__star input { position: absolute; opacity: 0; pointer-events: none; }
/* L'étoile est DESSINÉE. C'était un « ★ » de police sur cinq surfaces de la
   vitrine, toléré en dette héritée depuis le 2026-09-06 : son épaisseur et son
   alignement dépendaient de la machine du client, et la même note s'écrivait
   « ★ 4,7 » ici et « 4/5 ★ » deux blocs plus bas. */
.shop-avis__etoile { width: 26px; height: 26px; display: block; fill: #d9d9de; transition: fill .1s; }
.shop-avis__star:hover .shop-avis__etoile,
.shop-avis__star:hover ~ .shop-avis__star .shop-avis__etoile,
.shop-avis__star input:checked ~ .shop-avis__etoile,
.shop-avis__star:has(input:checked) ~ .shop-avis__star .shop-avis__etoile { fill: #f6b83c; }
.shop-etoile { width: 1em; height: 1em; fill: currentColor; vertical-align: -0.12em; }
.shop-avis__card textarea { width: 100%; background: var(--sf-ctl); border: 1px solid transparent; border-radius: 10px; padding: 9px 12px; font: inherit; font-size: 13.5px; resize: vertical; }
.shop-avis__card textarea:hover { background: var(--sf-ctl-hover); }
.shop-avis__card textarea:focus { outline: none; border-color: var(--shop-brand); background: var(--shop-surface); box-shadow: 0 0 0 3px var(--shop-brand-shadow); }
.shop-avis__submit { display: block; width: 100%; background: var(--shop-brand, #10b981); color: #fff; border: none; border-radius: 12px; padding: 13px; font-size: 15px; font-weight: 600; cursor: pointer; margin-top: 6px; }
.shop-avis__back { display: inline-block; margin-top: 8px; color: var(--shop-brand, #10b981); text-decoration: none; font-weight: 500; }
.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0,0,0,0); border: 0; }

/* Bloc avis sur la fiche produit */
.shop-avis-bloc { margin: 4px 0 0; padding: 14px 0 0; background: none; border: 0; border-top: 1px solid var(--shop-border); border-radius: 0; }
.shop-avis-bloc__head { display: flex; align-items: baseline; gap: 9px; margin-bottom: 4px; font-size: 10.5px; font-weight: 600; text-transform: uppercase; letter-spacing: .11em; color: var(--shop-text-quiet); }
.shop-avis-bloc__note { font-size: 15px; font-weight: 700; color: #b45309; font-variant-numeric: tabular-nums; }
.shop-avis-bloc__count { font-size: 12.5px; color: #6e6e73; }
.shop-avis-bloc__item { padding: 10px 8px; margin: 0 -8px; border-radius: 9px; }
.shop-avis-bloc__item:hover { background: var(--sf-2); }
.shop-avis-bloc__meta { font-size: 12px; color: #6e6e73; margin-bottom: 3px; }
.shop-avis-bloc__item p { margin: 0; font-size: 13.5px; line-height: 1.5; color: #3a3a3c; }

/* ── Fil d'ariane fiche produit ── */
.shop-detail__crumb {
    display: flex;
    align-items: center;
    gap: 7px;
    flex-wrap: wrap;
    font-size: 12.5px;
    color: var(--shop-text-muted);
    margin-bottom: 10px;
}
.shop-detail__crumb a { color: var(--shop-text-muted); text-decoration: none; }
.shop-detail__crumb a:hover { color: var(--shop-brand); }
.shop-detail__crumb span { color: var(--shop-border, #d2d2d7); }

/* ── Réassurance fiche produit ── */
.shop-detail__trust {
    list-style: none;
    margin: 18px 0 0;
    padding: 14px 0 0;
    border-top: 1px solid var(--shop-border, #ececec);
    display: flex;
    flex-direction: column;
    gap: 9px;
}
.shop-detail__trust li {
    display: flex;
    align-items: center;
    gap: 10px;
    font-size: 13px;
    color: var(--shop-text-secondary, #5a5a5e);
}

/* Pied du panier sidebar : toujours visible (la liste scrolle au-dessus). */
.shop-cart__foot { flex-shrink: 0; }

/* ════════════════════════════════════════════════════════════
   REFONTE « clic = ajout » 2026-06-20 — header actions, carte
   cliquable, tiroir panier, barre panier mobile.
   ════════════════════════════════════════════════════════════ */

/* Actions du header (rendez-vous / devis / compte) — refonte 2026-09-02.

   Étaient trois pastilles bordées de poids identique, chacune doublée d'une
   icône de contour qui redisait le libellé, et l'une d'elles abrégée en
   « RDV ». Quatre objets se partageaient alors le même poids à droite du champ
   de recherche, dont un seul, le panier, fait le commerce.

   Ce qui remplace la boîte, c'est le BLANC : 22 px entre les deux offres,
   10 px de plus avant le compte, qui n'est pas une offre mais un retour. La
   couleur reste une annotation — aucun fond, aucune bordure au repos ; le
   survol souligne le mot, il ne dessine pas de cadre autour. */
.shop-h__links {
    display: flex; align-items: center; gap: 22px; min-width: 0;
}
.shop-h__lnk {
    display: inline-flex; align-items: center;
    padding: 6px 0; flex-shrink: 0;
    font-size: 13.5px; font-weight: 500; white-space: nowrap;
    color: var(--shop-text-secondary, #5a5a5e);
    text-decoration: none;
    border-bottom: 1px solid transparent;
    transition: color .14s, border-color .14s;
}
.shop-h__lnk:hover { color: var(--shop-text, #1d1d1f); border-bottom-color: var(--shop-text, #1d1d1f); }
.shop-h__lnk:focus-visible { outline: 2px solid var(--shop-brand); outline-offset: 3px; }
.shop-h__lnk--account { margin-left: 10px; color: var(--shop-text-muted, #6b7280); }
.shop-h__lnk-short, .shop-h__lnk-ic { display: none; }

/* Sous 900 px, le libellé raccourcit ; il ne tombe JAMAIS à une icône muette,
   c'est la même destination écrite plus court. */
@media (max-width: 899px) {
    .shop-h__links { gap: 16px; }
    .shop-h__links .shop-h__lnk-long { display: none; }
    .shop-h__links .shop-h__lnk-short { display: inline; }
    .shop-h__lnk { font-size: 13px; }
}

/* Sous 560 px, le compte redevient la silhouette : une icône seule ne se
   comprend que collée au panier, dans le coin où tout le web range ces deux
   objets. Les deux offres, elles, gardent leur mot. */
/* Le téléphone est l'écran majoritaire d'une vitrine ouverte au comptoir : les
   deux offres y GARDENT leur mot, elles ne retombent pas à une icône. Le prix
   est le nom de boutique, qui se coupe (il porte déjà son ellipse) ; en
   échange, deux actions restent lisibles au lieu de deux pictogrammes muets. */
@media (max-width: 559px) {
    .shop-h__links { gap: 10px; }
    .shop-h__lnk { font-size: 12px; }
    .shop-h__lnk--account { margin-left: 2px; padding: 8px 2px; border-bottom: 0; }
    .shop-h__lnk--account .shop-h__lnk-long { display: none; }
    .shop-h__lnk--account .shop-h__lnk-ic { display: block; }
}
.shop-h__icon--cart { background: var(--shop-brand); color: #fff; border: 0; }
.shop-h__icon--cart:hover { filter: brightness(.94); }

/* Carte produit cliquable : pastille détail + flash « Ajouté »

   La pastille et le bouton d'ajout vivent SUR la photo et ne se révèlent
   qu'au survol : au repos, la grille ne montre que des produits.
   Sur mobile (liste à filet) il n'y a pas de survol — la pastille disparaît
   et c'est le NOM qui devient le lien vers la fiche. */
.shop-item__details {
    position: absolute; top: 8px; right: 8px; z-index: 3;
    width: 28px; height: 28px; border-radius: 50%;
    display: grid; place-items: center; text-decoration: none;
    background: rgba(255,255,255,.96); color: var(--shop-text-secondary, #5a5a5e);
    box-shadow: 0 1px 5px rgba(0,0,0,.2);
    opacity: 0; transition: opacity .12s ease, color .12s ease;
}
.shop-item:hover .shop-item__details,
.shop-item__details:focus-visible { opacity: 1; }
.shop-item__details:hover { color: var(--shop-text, #1d1d1f); }
.shop-item__details svg { width: 15px; height: 15px; }

/* Quand l'ajout passe par un <form> (fallback sans JS), c'est le formulaire
   qui porte le positionnement et le bouton redevient un enfant normal, donc
   utilisable au clavier. Le « + » décoratif des formules, lui, est seul. */
/* Le bouton est ancré au COIN BAS-DROIT DE LA PHOTO, pas à un pourcentage de
   la carte : il suivait sinon le ratio de l'image et décrochait dès qu'un
   nom passait sur deux lignes. */
.shop-item__add,
.shop-item__add-form {
    position: absolute;
    right: 8px;
    bottom: 8px;
    z-index: 2;
}
.shop-item__add-form .shop-item__add { position: static; right: auto; bottom: auto; }

.shop-item__namelink { color: inherit; text-decoration: none; }
.shop-item__namelink:hover { text-decoration: underline; }

@media (max-width: 599px) {
    .shop-item__details { display: none; }
    /* Le « + » reste HORS FLUX et se cale au bord droit de la ligne.
       En `position: static` il redevenait un item de flex de la vignette
       (56 px) : la ligne de flex mesurait 56 + 28 px, le débordement se
       répartissait de part et d'autre et la PHOTO partait 14 px à gauche,
       hors de son cadre. C'est ici, et pas dans le bloc mobile plus haut,
       que le calage doit vivre : les `right: 8px` / `bottom: 8px` du bureau
       sont déclarés juste au-dessus et gagnaient à spécificité égale. */
    .shop-item__add,
    .shop-item__add-form {
        position: absolute;
        right: 0;
        top: 50%;
        bottom: auto;
        transform: translateY(-50%);
    }
    /* Le bouton d'un <form> reste enfant normal : c'est le formulaire qui
       porte le calage (cf. règle sans média juste au-dessus). */
    .shop-item__add-form .shop-item__add { transform: none; }
}

.shop-item--added .shop-item__media::after {
    /* Le « ✓ » de police est parti sans rien perdre : l'aplat vert plein
       écran dit déjà que c'est fait, le crochet le redisait. */
    content: "Ajouté"; position: absolute; inset: 0;
    background: var(--shop-brand); color: #fff;
    display: grid; place-items: center; font-size: 15px; font-weight: 700;
    animation: shopFade .18s ease;
}
@keyframes shopFade { from { opacity: 0; } to { opacity: 1; } }

/* Tiroir panier */
.shop-noscroll { overflow: hidden; }
.shop-drawer-scrim { position: fixed; inset: 0; background: rgba(0,0,0,.34); z-index: 90; animation: shopFade .2s ease; }
.shop-drawer {
    position: fixed; top: 0; right: 0; bottom: 0; z-index: 100;
    width: 390px; max-width: 92vw; background: #fff;
    display: flex; flex-direction: column; box-shadow: -14px 0 44px rgba(0,0,0,.16);
    transform: translateX(100%); transition: transform .24s cubic-bezier(.16,1,.3,1);
}
.shop-drawer.is-open { transform: none; }
.shop-drawer__head { display: flex; align-items: center; justify-content: space-between; padding: 18px 20px; border-bottom: 1px solid var(--shop-border, #ececec); }
.shop-drawer__title { font-size: 17px; font-weight: 700; letter-spacing: -.02em; margin: 0; }
.shop-drawer__close { width: 34px; height: 34px; border-radius: 50%; border: 0; cursor: pointer; background: var(--shop-bg, #f5f5f7); color: var(--shop-text-secondary, #5a5a5e); display: grid; place-items: center; }
.shop-drawer__content { flex: 1; display: flex; flex-direction: column; min-height: 0; }
.shop-drawer__list { flex: 1; overflow-y: auto; padding: 10px 14px; }
.shop-drawer__row { display: flex; gap: 11px; align-items: center; padding: 11px 8px; border-radius: 12px; }
.shop-drawer__row:hover { background: var(--shop-bg, #f7f8f7); }
.shop-drawer__img { width: 48px; height: 48px; border-radius: 10px; flex-shrink: 0; overflow: hidden; background: var(--shop-brand-soft); color: var(--shop-brand); display: grid; place-items: center; font-weight: 700; font-size: 15px; }
.shop-drawer__img img { width: 100%; height: 100%; object-fit: cover; }
.shop-drawer__b { flex: 1; min-width: 0; }
.shop-drawer__n { font-size: 13.5px; font-weight: 600; letter-spacing: -.005em; }
.shop-drawer__m { font-size: 12px; color: var(--shop-text-muted, #9a9a9e); margin-top: 1px; }
.shop-drawer__step { display: inline-flex; align-items: center; gap: 10px; margin-top: 6px; background: var(--sf-ctl); border-radius: 999px; padding: 3px 4px; }
.shop-drawer__step button { width: 23px; height: 23px; border-radius: 50%; border: 0; cursor: pointer; background: var(--shop-bg, #f5f5f7); color: var(--shop-text, #1d1d1f); font-size: 15px; line-height: 1; }
.shop-drawer__step button:hover { background: var(--shop-brand-soft); color: var(--shop-brand); }
.shop-drawer__step span { font-size: 13px; font-weight: 600; min-width: 16px; text-align: center; font-variant-numeric: tabular-nums; }
.shop-drawer__price { font-size: 14px; font-weight: 700; white-space: nowrap; font-variant-numeric: tabular-nums; }
.shop-drawer__foot { border-top: 1px solid var(--shop-border, #ececec); padding: 16px 18px; }
.shop-drawer__tot { display: flex; align-items: center; justify-content: space-between; margin-bottom: 13px; }
.shop-drawer__tot b { font-size: 18px; font-variant-numeric: tabular-nums; }
.shop-drawer__cta { display: flex; align-items: center; justify-content: center; gap: 9px; width: 100%; padding: 15px; border-radius: 14px; background: var(--shop-brand); color: #fff; font-size: 15.5px; font-weight: 700; text-decoration: none; }
.shop-drawer__cta:hover { filter: brightness(.95); }
.shop-drawer__seeall { display: block; text-align: center; margin-top: 11px; font-size: 13px; font-weight: 600; color: var(--shop-text-secondary, #5a5a5e); text-decoration: none; }
.shop-drawer__empty { flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; text-align: center; padding: 40px 24px; }
.shop-drawer__empty-ic { font-size: 34px; color: var(--shop-text-muted, #c7c7cc); }
.shop-drawer__empty-t { font-size: 15px; font-weight: 600; margin: 12px 0 4px; }
.shop-drawer__empty-s { font-size: 13px; color: var(--shop-text-muted, #9a9a9e); }

/* Barre panier mobile (ouvre le tiroir) */
.shop-cartbar { position: fixed; left: 12px; right: 12px; bottom: 12px; z-index: 80; display: none; align-items: center; justify-content: center; gap: 9px; padding: 15px; border: 0; border-radius: 15px; cursor: pointer; background: var(--shop-brand); color: #fff; font-size: 15px; font-weight: 700; box-shadow: 0 8px 26px var(--shop-brand-shadow, rgba(0,0,0,.2)); }
@media (max-width: 899px) { .shop-cartbar:not([hidden]) { display: flex; } }

/* ════════════════════════════════════════════════════════════
   ÉTATS TERMINAUX, SUIVI DE COMMANDE, EXTENSIONS DEVIS
   Refonte 2026-07-28 : ces quatre pages (commande confirmée, suivi,
   demande de devis générale, 404) vivaient sur `storefront.css` et sur
   ~980 lignes de <style> écrites dans les gabarits. Leur grammaire
   rejoint ici les autres, une bonne fois.
   ════════════════════════════════════════════════════════════ */

/* ---- État terminal (confirmation, 404, devis envoyé, lien de paiement) ---- */
.shop-terminal {
    max-width: 640px;
    margin: 0 auto;
    padding: 0 16px 48px;
}
@media (min-width: 900px) { .shop-terminal { padding: 0 32px 48px; } }
/* Une colonne CENTRÉE de 640 px convient à une fin de parcours : la page est
   une annonce, elle n'a pas de suite. Elle ne convient pas à un formulaire,
   qui doit partager l'axe gauche de l'en-tête et du pied.

   `margin-left: 0` ne suffisait pas : le conteneur retombait alors sur la
   gouttière de 16 px, et le formulaire commençait à 13 px quand les autres
   pages commencent à 57. C'était un sixième axe, créé en corrigeant le
   cinquième. La page prend donc le conteneur commun, exactement comme
   « À propos » et les pages légales, et borne sa MESURE à l'intérieur. */
.shop-terminal--form { max-width: 1280px; }
.shop-terminal--form > * { max-width: 720px; }
.shop-terminal__card {
    padding: 44px 0 8px;
    text-align: center;
    background: none;
    border: 0;
    box-shadow: none;
}
/* L'en-tête d'un écran où il reste QUELQUE CHOSE À FAIRE. Même famille que
   `__card`, mais sans l'axe centré ni l'image : la recherche d'une commande
   n'est pas une fin de parcours. Voir le commentaire d'`order_tracking.html`. */
.shop-terminal__head {
    padding: 26px 0 4px;
    text-align: left;
}
.shop-terminal__head .shop-terminal__title { font-size: 20px; }
.shop-terminal__head .shop-terminal__msg { margin-left: 0; margin-right: 0; }
/* Le bouton d'un formulaire à deux champs n'a pas besoin des 486 px de sa
   colonne. `.shop-devis__submit` reste pleine largeur là où il est le geste
   d'une page entière ; ici il se dimensionne sur son texte. */
.shop-terminal .shop-devis__submit {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: auto;
    min-width: 160px;
    height: 38px;
    padding: 0 20px;
    border-radius: 9px;
    font-size: 14px;
}
.shop-terminal__retour {
    display: inline-block;
    font-size: 13px;
    color: var(--shop-text-muted);
    text-decoration: none;
}
.shop-terminal__retour:hover { color: var(--shop-text); text-decoration: underline; }
.shop-terminal__title {
    font-size: 21px; font-weight: 680;
    letter-spacing: -0.025em;
    margin: 0;
}
.shop-terminal__msg {
    font-size: 13px;
    color: var(--shop-text-muted);
    line-height: 1.6;
    margin: 8px 0 0;
}
.shop-terminal__extra {
    font-size: 12px;
    color: var(--shop-text-quiet);
    margin: 6px 0 0;
}
.shop-terminal__actions {
    margin-top: 20px;
    display: flex; gap: 10px; justify-content: center; flex-wrap: wrap;
}
/* L'axe centré vaut pour une FIN de parcours, où la page est une annonce.
   Tant qu'on cherche sa commande, la page est un formulaire aligné à gauche,
   et son retour au catalogue l'est avec. */
.shop-terminal__actions--gauche { justify-content: flex-start; margin-top: 14px; }
.shop-terminal__btn {
    display: inline-flex; align-items: center; justify-content: center; gap: 8px;
    padding: 11px 20px;
    border-radius: 999px;
    border: 0;
    background: var(--sf-ctl);
    color: var(--shop-text);
    font-size: 13.5px; font-weight: 600;
    text-decoration: none;
}
.shop-terminal__btn:hover { background: var(--sf-ctl-hover); }
.shop-terminal__btn--primary {
    background: var(--shop-brand); color: #fff;
}
.shop-terminal__btn--primary:hover { background: var(--shop-brand); }
.shop-terminal__btn--primary:hover { filter: brightness(.94); }
.shop-terminal__contact {
    margin-top: 22px; padding-top: 14px;
    border-top: 1px solid var(--shop-border);
    display: flex; flex-direction: column; gap: 4px;
    font-size: 12.5px;
}
.shop-terminal__contact-label { color: var(--shop-text-quiet); }
.shop-terminal__contact a { color: var(--shop-brand); font-weight: 600; text-decoration: none; }

/* ---- Bloc de page (mêmes filets que le tunnel) ---- */
.shop-block {
    padding: 18px 0;
    border-bottom: 1px solid var(--shop-border);
}
.shop-block:last-child { border-bottom: 0; }
.shop-block__h {
    display: flex; align-items: center; gap: 8px;
    font-size: 10.5px; font-weight: 600;
    text-transform: uppercase; letter-spacing: 0.11em;
    color: var(--shop-text-quiet);
    margin: 0 0 10px;
}

/* ---- Paires libellé / valeur ---- */
.shop-dl { margin: 0; }
.shop-dl__row {
    display: grid;
    grid-template-columns: 148px 1fr;
    gap: 8px;
    align-items: baseline;
    padding: 7px 8px;
    margin: 0 -8px;
    border-radius: 8px;
    font-size: 12.5px;
}
.shop-dl__row:hover { background: var(--sf-2); }
.shop-dl__row:last-child { border-bottom: 0; }
.shop-dl__k { font-size: 11.5px; color: var(--shop-text-quiet); margin: 0; }
.shop-dl__v { margin: 0; font-variant-numeric: tabular-nums; }
.shop-dl__v--warn { color: #b45309; font-weight: 600; }
@media (max-width: 599px) {
    .shop-dl__row { grid-template-columns: 1fr; gap: 2px; }
}

/* ---- Ligne d'article récapitulée ---- */
.shop-line {
    display: flex; align-items: center; gap: 12px;
    padding: 10px 8px;
    margin: 0 -8px;
    border-radius: 9px;
}
.shop-line:hover { background: var(--sf-2); }
.shop-line__img {
    width: 44px; height: 44px;
    border-radius: 9px;
    background: #f0f0f2;
    color: var(--shop-text-quiet);
    display: grid; place-items: center;
    font-size: 15px; font-weight: 700;
    flex-shrink: 0; overflow: hidden;
}
.shop-line__img img { width: 100%; height: 100%; object-fit: cover; }
.shop-line__m { flex: 1; min-width: 0; }
.shop-line__t { font-size: 12.5px; font-weight: 600; margin: 0; }
.shop-line__s { font-size: 11.5px; color: var(--shop-text-quiet); margin: 2px 0 0; line-height: 1.45; }
.shop-line__p {
    font-size: 12.5px; font-weight: 600;
    font-variant-numeric: tabular-nums;
    white-space: nowrap; flex-shrink: 0;
}

/* ---- Totaux ---- */
.shop-tot {
    display: flex; justify-content: space-between; align-items: baseline;
    gap: 12px;
    padding: 7px 0;
    font-size: 12.5px;
    color: var(--shop-text-muted);
}
.shop-tot__v { font-variant-numeric: tabular-nums; color: var(--shop-text); }
.shop-tot--free .shop-tot__v { color: var(--shop-brand); }
.shop-tot--warn, .shop-tot--warn .shop-tot__v { color: #b45309; font-weight: 600; }
.shop-tot--grand {
    border-top: 1px solid var(--shop-border);
    margin-top: 6px; padding-top: 11px;
    font-size: 14px; font-weight: 650;
    color: var(--shop-text);
}
.shop-tot--grand .shop-tot__v { font-size: 19px; font-weight: 700; letter-spacing: -0.02em; }

/* ---- Frise de suivi de commande ----
   Les étapes non atteintes restent grises et SANS date estimée : le texte
   reste vrai que la préparation prenne dix minutes ou trois jours. */
.shop-track {
    display: flex;
    align-items: flex-start;
    text-align: left;
    padding: 18px 0;
    border-bottom: 1px solid var(--shop-border);
}
.shop-track__step {
    flex: 1;
    position: relative;
    padding: 0 6px;
    min-width: 0;
}
/* Le filet relie CE point au point suivant. Il partait des bords de l'étape
   (`left: 0; right: 0`) en supposant une pastille centrée : elle est alignée
   à gauche, si bien qu'un vide restait après « Reçue » et que le dernier
   segment s'arrêtait au milieu de rien. Le point est à 6 px de padding
   + 5,5 px de rayon = 11,5 px du bord de l'étape ; les étapes ayant toutes
   la même largeur, dépasser de 11,5 px à droite tombe pile sur le suivant. */
.shop-track__step::before {
    content: "";
    position: absolute;
    top: 5px;
    left: 11.5px; right: -11.5px;
    height: 1px;
    background: rgba(0, 0, 0, .12);
}
.shop-track__step:last-child::before { display: none; }
.shop-track__dot {
    /* Un <span> reste `inline` : width/height n'y avaient aucun effet, la
       pastille faisait 0 × 0 (invisible sur PC) et le libellé remontait sous
       le filet. Sur mobile la règle `position: absolute` la « blockifiait »
       par accident — d'où un point visible sur téléphone seulement. */
    display: block;
    position: relative;
    width: 11px; height: 11px;
    border-radius: 999px;
    background: rgba(0, 0, 0, .12);
    margin-bottom: 9px;
    outline: 3px solid #fff;
}
.shop-track__step--done .shop-track__dot { background: var(--shop-brand); }
.shop-track__step--now .shop-track__dot { background: var(--shop-text); }
.shop-track__t { font-size: 11.5px; font-weight: 600; }
.shop-track__step--pending .shop-track__t { color: var(--shop-text-quiet); font-weight: 400; }
.shop-track__s { font-size: 10.5px; color: var(--shop-text-quiet); margin-top: 2px; }
@media (max-width: 599px) {
    .shop-track { flex-direction: column; padding-left: 2px; }
    .shop-track__step { padding: 0 0 14px 20px; width: 100%; flex: none; }
    .shop-track__step::before {
        top: 0; bottom: 0; left: 5px; right: auto;
        width: 1px; height: auto;
    }
    .shop-track__step:first-child::before { top: 5px; left: 5px; }
    /* En colonne le filet remonte vers l'étape précédente : la dernière
       étape en garde donc un moignon, là où la frise horizontale n'en a pas. */
    .shop-track__step:last-child::before { display: block; bottom: auto; height: 5px; }
    .shop-track__dot { position: absolute; left: 0; top: 1px; margin: 0; }
}

/* ---- Extensions du formulaire de devis (demande générale) ---- */
/* `.shop-devis__pills` / `__pill` (les arguments « Gratuit » et « Sans
   engagement » posés sur un aplat de couleur de marque) et `.shop-devis__step`
   (les pastilles numérotées 1-2-3, qui ne comptaient que trois des cinq blocs
   du formulaire) sont retirés avec le balisage qui les portait, le 2026-09-02.
   Aucun autre gabarit ne les appelait. */
.shop-devis__hint {
    font-size: 11.5px;
    color: var(--shop-text-quiet);
    line-height: 1.5;
    margin: 0 0 10px;
}
.shop-devis__err {
    font-size: 11.5px;
    color: #c81e1e;
    margin-top: 5px;
}
/* ── L'EMPÊCHEMENT. Ce qui empêche n'est pas un objet : c'est un fait. Une
      ligne en tête de la zone concernée, et un filet qui la sépare de ce sur
      quoi elle porte — jamais un aplat teinté dans une boîte à coins ronds.
      C'était un rectangle rouge pâle, et il servait AUSSI à dire « cette
      commande est annulée », qui n'est pas une erreur mais un état. */
.shop-devis__banner {
    padding: 0 0 10px;
    margin-bottom: 14px;
    border-bottom: 1px solid var(--shop-border);
    color: var(--ac-danger);
    font-size: 12.5px;
    font-weight: 500;
    line-height: 1.5;
}
.shop-devis__banner--neutre { color: var(--shop-text-muted); font-weight: 400; }
.shop-devis__reassure {
    font-size: 11.5px;
    color: var(--shop-text-quiet);
    line-height: 1.55;
    margin-top: 10px;
    text-align: center;
}

.shop-devis__files { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 4px; }
.shop-devis__file {
    display: inline-flex; align-items: center; gap: 7px;
    padding: 9px 13px;
    border: 1px dashed rgba(0, 0, 0, .18);
    border-radius: 11px;
    font-size: 12px;
    color: var(--shop-text-muted);
    cursor: pointer;
}
.shop-devis__file:hover { border-color: var(--shop-text-muted); color: var(--shop-text); }
.shop-devis__file input[type="file"] { display: none; }
.shop-devis__file--filled {
    border-style: solid;
    border-color: var(--shop-brand);
    color: var(--shop-brand);
}

.shop-devis__chips { display: flex; flex-wrap: wrap; gap: 7px; }
.shop-devis__chip {
    padding: 7px 14px;
    border: 0;
    border-radius: 999px;
    background: var(--sf-ctl);
    color: var(--shop-text-muted);
    font-size: 12.5px;
    font-family: inherit;
    cursor: pointer;
}
.shop-devis__chip:hover { background: var(--sf-ctl-hover); color: var(--shop-text); }
.shop-devis__chip--active {
    background: var(--shop-brand-soft);
    color: var(--shop-text);
    font-weight: 600;
}

.shop-devis__more {
    display: inline-flex; align-items: center; gap: 7px;
    padding: 0;
    border: 0;
    background: none;
    color: var(--shop-text-muted);
    font-size: 12.5px;
    font-family: inherit;
    cursor: pointer;
}
.shop-devis__more:hover { color: var(--shop-text); }

.shop-devis__amount { position: relative; }
.shop-devis__amount .shop-devis__cur {
    position: absolute; left: 12px; top: 50%;
    transform: translateY(-50%);
    color: var(--shop-text-quiet);
    font-size: 13px;
    pointer-events: none;
}
.shop-devis__amount .shop-devis__input { padding-left: 28px; }

.shop-devis__geo {
    display: inline-flex; align-items: center; gap: 7px;
    padding: 8px 14px;
    border: 0;
    border-radius: 999px;
    background: var(--sf-ctl);
    color: var(--shop-text-muted);
    font-size: 12.5px;
    font-family: inherit;
    cursor: pointer;
    margin-bottom: 10px;
}
.shop-devis__geo:hover { background: var(--sf-ctl-hover); color: var(--shop-text); }
.shop-devis__geook {
    display: inline-flex; align-items: center; gap: 7px;
    font-size: 12px;
    color: var(--shop-brand);
    margin-bottom: 10px;
}

/* ---- Page « boutique introuvable » ---- */
.shop-404 {
    max-width: 520px;
    margin: 0 auto;
    padding: 64px 20px;
    text-align: center;
}
.shop-404__code {
    font-size: 11px; font-weight: 700;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--shop-text-quiet);
}
.shop-404__title {
    font-size: 21px; font-weight: 680;
    letter-spacing: -0.025em;
    margin: 10px 0 0;
}
.shop-404__text {
    font-size: 13px;
    color: var(--shop-text-muted);
    line-height: 1.6;
    margin: 8px 0 0;
}

/* Rotation du témoin d'attente (paiement en cours). Déclarée ici plutôt que
   dans deux gabarits de paiement, qui la répétaient chacun de son côté. */
@keyframes shopSpin { to { transform: rotate(360deg); } }
@keyframes spin { to { transform: rotate(360deg); } }


/* ── Ajouts du 2026-08-20 ───────────────────────────────────────────────── */

/* Commandes en pause : le mot qui remplace le bouton d'ajout sur la fiche.
   Un filet et de l'encre discrète, pas d'aplat (règle de la maison). */
.shop-detail__paused {
    margin: 14px 0 0;
    padding: 11px 0 0;
    font-size: 13.5px;
    line-height: 1.45;
    color: var(--shop-text-muted);
}

/* Tri du catalogue, posé à droite des rayons dans la même barre collante. */
.shop-tabs__sort { margin-left: auto; display: flex; align-items: center; flex-shrink: 0; }
.shop-tabs__sort select {
    -webkit-appearance: none;
    appearance: none;
    border: 1px solid transparent;
    border-radius: 999px;
    background: var(--sf-ctl);
    color: var(--shop-text-muted);
    font: inherit;
    font-size: 12.5px;
    padding: 5px 26px 5px 12px;
    cursor: pointer;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='10' viewBox='0 0 24 24' fill='none' stroke='%23888' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 10px center;
}
.shop-tabs__sort select:focus-visible { outline: 2px solid var(--shop-brand); outline-offset: 1px; }

/* Tiroir panier : états ajoutés en même temps que sa mise en commun. */
.shop-drawer__loading { padding: 28px 18px; text-align: center; color: var(--shop-text-quiet); font-size: 13.5px; }
.shop-drawer__warn { margin-top: 4px; font-size: 11.5px; color: #c81e1e; }
.shop-drawer__block {
    margin: 0 0 10px;
    padding: 9px 0;
    font-size: 12.5px;
    line-height: 1.4;
    color: var(--shop-text-muted);
}
.shop-drawer__block--soft { color: var(--shop-text-quiet); }
.shop-drawer__tot--sub,
.shop-drawer__tot--disc { font-size: 12.5px; color: var(--shop-text-muted); }
.shop-drawer__cta--off {
    opacity: 0.55;
    cursor: not-allowed;
    pointer-events: none;
}
.shop-drawer__step--del { border: 0; padding: 0; background: none; }

/* Barre panier mobile : le séparateur entre le libellé et le montant. */
.shop-cartbar__sep {
    width: 1px;
    height: 13px;
    margin: 0 4px;
    background: currentColor;
    opacity: 0.4;
    display: inline-block;
}


/* Suggestions de recherche · liste ancrée sous le champ (voir
   `.shop-h__search-wrap`). Le moteur existait depuis toujours
   (`storefront:search_autocomplete`) ; c'est l'interface qui manquait. */
.shop-h__suggest {
    position: absolute;
    top: calc(100% + 6px);
    left: 0;
    right: 0;
    z-index: 120;
    margin: 0;
    padding: 5px;
    list-style: none;
    background: var(--shop-surface);
    border: 1px solid var(--shop-border);
    border-radius: 13px;
    box-shadow: 0 10px 30px rgba(0, 0, 0, 0.10);
    max-height: 60vh;
    overflow-y: auto;
}
.shop-h__suggest-i {
    display: flex;
    align-items: center;
    gap: 9px;
    padding: 7px 9px;
    border-radius: 9px;
    cursor: pointer;
    font-size: 13px;
    color: var(--shop-text);
}
.shop-h__suggest-i:hover,
.shop-h__suggest-i.is-on { background: rgba(120, 120, 128, 0.10); }
.shop-h__suggest-i img {
    width: 30px; height: 30px;
    border-radius: 7px;
    object-fit: cover;
    flex-shrink: 0;
}
.shop-h__suggest-b { display: flex; flex-direction: column; min-width: 0; flex: 1 1 auto; }
.shop-h__suggest-n { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.shop-h__suggest-c { font-size: 11px; color: var(--shop-text-quiet); }
.shop-h__suggest-p { font-size: 12.5px; color: var(--shop-text-muted); flex-shrink: 0; }

/* ── Annonce des promotions en cours ──────────────────────────────────────
   Posée entre l'en-tête et le contenu, dans le flux : un bandeau collant
   mangerait la hauteur utile sur un téléphone, là où la vitrine se consulte.
   Fond de marque adouci, jamais un aplat plein : c'est une information, pas
   une alerte. */
.shop-promo{background:var(--shop-brand-soft);border-bottom:1px solid color-mix(in srgb, var(--shop-brand) 18%, transparent);
            padding:9px 16px;display:flex;flex-direction:column;gap:3px;align-items:center;text-align:center;}
.shop-promo__t{margin:0;font-size:13px;font-weight:550;color:var(--shop-text);line-height:1.4;}
@media (max-width:640px){.shop-promo{padding:8px 12px;}.shop-promo__t{font-size:12.5px;}}

/* ═══════════════════════════════════════════════════════════════════════════
   FICHE PRODUIT · options de personnalisation, régimes, note, prix du bouton

   Dix-neuf classes de `produit_detail.html` n'avaient AUCUNE règle, dans aucune
   feuille du dépôt (audit du 2026-09-01). Tout le bloc où un client de
   restaurant choisit sa cuisson et ses accompagnements sortait donc avec les
   styles par défaut du navigateur : cadre gris de `<fieldset>`, boutons radio
   nus, suppléments collés au libellé.

   Le plus visible : `shop-detail__sr` porte le mot « obligatoire », destiné aux
   seuls lecteurs d'écran. Sans règle, il s'affichait en toutes lettres à côté de
   l'astérisque — « Cuisson * obligatoire ».

   Le vocabulaire suit celui des variantes juste au-dessus : pastilles à coins
   ronds, encre de la marque sur la sélection, filet plutôt qu'aplat.
   ═══════════════════════════════════════════════════════════════════════════ */

.shop-detail__sr {
    position: absolute; width: 1px; height: 1px;
    padding: 0; margin: -1px; overflow: hidden;
    clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
}

.shop-detail__options { margin: 0 0 16px; }

.shop-detail__option-group {
    border: 0;                       /* le cadre par défaut du fieldset */
    margin: 0;
    padding: 14px 0 0;
}
.shop-detail__option-group + .shop-detail__option-group { margin-top: 14px; }

.shop-detail__option-label {
    display: flex; align-items: baseline; gap: 6px;
    padding: 0;
    font-size: 13px; font-weight: 600;
    color: var(--shop-text);
    letter-spacing: -0.01em;
}
.shop-detail__option-req { color: #dc2626; font-weight: 700; }
.shop-detail__option-opt {
    font-size: 11px; font-weight: 400;
    color: var(--shop-text-quiet);
}

.shop-detail__option-list {
    display: flex; flex-wrap: wrap; gap: 8px;
    margin-top: 10px;
}

/* La pastille EST le label : la case reste dans le flux pour le clavier et les
   lecteurs d'écran, elle est seulement rendue invisible. */
.shop-detail__option {
    display: inline-flex; align-items: center; gap: 6px;
    padding: 8px 14px;
    border: 0;
    border-radius: 999px;
    font-size: 13px;
    color: var(--shop-text);
    cursor: pointer;
    background: var(--sf-ctl);
}
.shop-detail__option:hover { background: var(--sf-ctl-hover); }
.shop-detail__option-input {
    position: absolute; opacity: 0;
    width: 1px; height: 1px;
    pointer-events: none;
}
.shop-detail__option-input:checked + .shop-detail__option-text { font-weight: 600; }
/* Le choix RETENU se distingue des autres : deux natures, donc un trait. Il est
   posé en ombre intérieure pour ne pas déplacer la pastille d'un pixel. */
.shop-detail__option:has(.shop-detail__option-input:checked) {
    box-shadow: inset 0 0 0 1px var(--shop-brand);
    background: var(--shop-brand-soft);
    color: var(--shop-brand-strong, var(--shop-text));
}
/* Le focus clavier doit se voir : la case est masquée, c'est la pastille qui
   porte l'anneau. */
.shop-detail__option:has(.shop-detail__option-input:focus-visible) {
    outline: 2px solid var(--shop-brand);
    outline-offset: 2px;
}
.shop-detail__option-delta {
    font-size: 12px;
    color: var(--shop-text-muted);
    font-variant-numeric: tabular-nums;
}

/* Message d'options manquantes, et échec d'ajout au panier : même emplacement
   visuel, deux emplacements dans le DOM (celui-ci vit dans le bloc options,
   qui n'existe pas pour un produit simple). */
.shop-detail__option-status,
.shop-detail__add-status {
    margin: 10px 0 0;
    font-size: 12.5px;
    line-height: 1.45;
    color: #dc2626;
}
.shop-detail__add-status { margin: -6px 0 14px; }

/* ─── Régimes alimentaires (végétarien, sans gluten…) ─── */
.shop-detail__diets {
    display: flex; flex-wrap: wrap; gap: 6px;
    margin: 0 0 14px;
    padding: 0; list-style: none;
}
.shop-detail__diet {
    display: inline-flex; align-items: center; gap: 5px;
    padding: 4px 10px;
    border: 0;
    border-radius: 999px;
    background: var(--sf-ctl);
    font-size: 11.5px;
    color: var(--shop-text-muted);
}

/* ─── Note libre du client (« sans oignons ») ─── */
.shop-detail__note { margin: 0 0 14px; }
.shop-detail__note-label {
    display: block;
    font-size: 12px; font-weight: 600;
    color: var(--shop-text);
    margin-bottom: 6px;
}
.shop-detail__note-input {
    width: 100%;
    padding: 10px 12px;
    border: 1px solid transparent;
    border-radius: 12px;
    font-family: inherit; font-size: 13px;
    color: var(--shop-text);
    background: var(--sf-ctl);
    resize: vertical;
}
.shop-detail__note-input:hover { background: var(--sf-ctl-hover); }
.shop-detail__note-input:focus {
    outline: 2px solid var(--shop-brand-shadow);
    border-color: var(--shop-brand);
}

/* ─── Prix logé dans le bouton d'ajout ─── */
.shop-detail__cta-price {
    font-variant-numeric: tabular-nums;
    font-weight: 600;
}

/* ═══════════════════════════════════════════════════════════════════════════
   LES DIX DERNIÈRES CLASSES ORPHELINES DE LA VITRINE (audit du 2026-09-01)

   Relevées mécaniquement en comparant les `class="…"` des gabarits publics aux
   sélecteurs des trois feuilles que la vitrine sert. Chacune sortait avec les
   styles par défaut du navigateur, sans erreur ni trace.

   La plus visible : `shop-drawer__del` sur une ligne à options ou une formule
   vit HORS de `.shop-drawer__step` — dont la règle habille déjà le « × » d'une
   ligne simple. Le même geste avait donc deux rendus dans le même tiroir : une
   pastille ronde ici, un bouton système gris à bordure là.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ─── Pied de page : bloc d'identité du commerce ─── */
.shop-foot__id { display: flex; flex-direction: column; gap: 6px; }

/* ─── Ligne de panier : options retenues et note du client ───
   Page panier et tiroir partagent le même besoin, deux échelles. */
.shop-cart-page__item-opt,
.shop-cart-page__item-note {
    margin: 2px 0 0;
    font-size: 12px;
    line-height: 1.45;
    color: var(--shop-text-muted);
}
.shop-cart-page__item-note { font-style: normal; }

.shop-drawer__opt,
.shop-drawer__note {
    margin-top: 2px;
    font-size: 11.5px;
    line-height: 1.4;
    color: var(--shop-text-muted);
}

/* Le champ de quantité saisi à la main : son formulaire ne doit pas casser la
   ligne des boutons − / +. */
.shop-cart-page__qty-form--input { display: inline-flex; align-items: center; }

/* ─── Retirer une ligne du tiroir ───
   Même pastille que le « − » d'une ligne simple, que `.shop-drawer__step
   button` habille déjà : le geste est le même, l'aspect aussi. */
.shop-drawer__del {
    width: 23px; height: 23px;
    border: 0; border-radius: 50%;
    cursor: pointer;
    background: var(--shop-bg, #f5f5f7);
    color: var(--shop-text-muted);
    font-size: 15px; line-height: 1;
    font-family: inherit;
    flex-shrink: 0;
}
.shop-drawer__del:hover { background: var(--shop-brand-soft); color: var(--shop-brand); }

/* ─── Devis : prix barré d'une promotion ─── */
.shop-devis__product-price-old {
    text-decoration: line-through;
    color: var(--shop-text-quiet);
    font-weight: 400;
    margin-right: 6px;
}

/* Note d'accompagnement d'une page légale (source d'un formulaire type, renvoi
   d'article). L'italique disait cette mise à distance ; elle est bannie du
   produit, c'est donc l'encre qui la porte. */
.shop-legal__note {
    font-size: 12.5px;
    color: var(--shop-text-muted);
    margin: 6px 0 14px;
}

/* ════ MODE « SUR PLACE » (QR code de table) ════
   Même place et même grammaire que le bandeau des promotions : une ligne dans
   le flux, sous l'en-tête. Le client doit savoir qu'il commande pour SA table. */
.shop-table-bandeau{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:8px;
    padding:10px 16px;background:var(--shop-brand-soft);border-bottom:1px solid color-mix(in srgb, var(--shop-brand) 18%, transparent);
    font-size:13px;color:var(--shop-text);}
.shop-table-bandeau form{margin:0;}
.shop-table-bandeau__lien{background:none;border:0;padding:0;font:inherit;font-size:13px;color:var(--shop-text-muted);
    text-decoration:underline;cursor:pointer;}
.shop-table-quitter{margin:24px 0 0;text-align:center;}

/* ════ AUDIT MOBILE 2026-09-25 — vitrine au téléphone (< 900 px) ════
   Rien ici ne touche le bureau : tout vit sous le même point de rupture que
   le reste de la feuille. */
@media (max-width: 899px) {
    /* La barre « Voir mon panier » (z-index 80) se posait PAR-DESSUS la barre
       d'action propre de la page (z-index 20 à 40) : sur /commander/ elle
       masquait le bouton « Commander », sur /panier/ le « Commander » du
       panier, sur la fiche l'« Ajouter ». Le client tapait « Voir mon panier »
       au lieu de valider. Une page qui porte sa propre action n'a pas besoin
       de la porte vers le panier : l'icône du haut y mène toujours. */
    body:has(.shop-cta-mobile, .co-sticky) .shop-cartbar { display: none; }
    /* Encoche iOS : la barre flottait sur l'indicateur d'accueil. */
    .shop-cartbar { bottom: calc(12px + env(safe-area-inset-bottom, 0px)); }
    /* Sous une barre fixe (panier, « Commander », « Envoyer ma demande »), le
       bas du pied de page — CGV, mentions légales — restait dessous,
       impossible à atteindre : le 100 px réservé par le contenu ne protège
       que le contenu, le pied vient après. */
    body:has(.shop-cta-mobile, .co-sticky, .shop-cartbar:not([hidden])) .shop-foot {
        padding-bottom: calc(84px + env(safe-area-inset-bottom, 0px));
    }
    /* Tiroir fermé : son ombre portée (−14 px, flou 44 px) débordait de 30 px
       dans l'écran et grisait le bord droit de toutes les pages. */
    .shop-drawer:not(.is-open) { box-shadow: none; }

    /* Cibles tactiles — la zone grandit, pas le dessin. */
    .shop-h__lnk,
    .shop-h__brand { min-height: 40px; }
    .shop-detail__crumb a,
    .shop-foot__nav a,
    .shop-foot__legal a,
    .shop-foot__powered a {
        display: inline-flex; align-items: center; min-height: 32px;
    }
    .shop-foot__nav { gap: 0 18px; }
    .shop-foot__legal { gap: 0 18px; }
    .shop-detail__crumb { margin-top: -8px; margin-bottom: 2px; }
    .shop-pagination__btn {
        display: inline-flex; align-items: center; justify-content: center;
        min-width: 40px; min-height: 40px; box-sizing: border-box;
    }
    /* Le « + » de la carte (28 px dessinés) et les − / + / × du tiroir
       (23 px) : la zone de toucher s'étend par un pseudo-élément. */
    .shop-item__add,
    .shop-drawer__step button,
    .shop-drawer__del { position: relative; }
    .shop-item__add::after,
    .shop-drawer__step button::after,
    .shop-drawer__del::after { content: ''; position: absolute; inset: -8px; }
    .shop-item__namelink { display: inline-block; padding: 8px 0; margin: -8px 0; }
    .shop-drawer__seeall { padding: 10px 0; margin-top: 1px; }
    .shop-cart-page__item-name { padding: 4px 0; }
    .shop-cart-page__coupon summary { min-height: 44px; }
    .shop-cart-page__continue,
    .shop-devis__back { padding: 12px 0; margin-top: 2px; }
    .shop-devis__back { margin-bottom: 2px; }
    .shop-cart-page__empty-cta { min-height: 44px; box-sizing: border-box; display: inline-flex; align-items: center; }
    .shop-terminal__retour { display: inline-flex; align-items: center; min-height: 36px; }

    /* Texte porteur d'information sous 11 px. */
    .shop-item__price-tax,
    .shop-item__stock { font-size: 11px; }
    .shop-h__icon-badge { font-size: 11px; }
    .shop-devis__pan-title { font-size: 11px; }
}
