/* ═══════════════════════════════════════════════════════════════════
   TU-MOBILE-POLISH — couche additive mobile premium (≤ 768 px)
   -----------------------------------------------------------------
   Charge APRÈS responsive-premium.css / header-premium.css /
   tu-cross-browser.css. Aucune modification HTML, aucune logique JS
   touchée. Tout est scopé par media query mobile et par sélecteurs
   stricts pour zéro régression desktop.

   Sommaire
     1. Tap highlight & touch-action — perception responsive instantanée
     2. Active state feedback — pulse tactile sur boutons / cartes / liens
     3. Sticky bottom CTA — produit-detail (qty + add-to-cart + wishlist)
     4. Sticky checkout bar — cart.html (#checkout-btn)
     5. Scroll-snap horizontaux — thumbnails / carrousels / tabs
     6. Image safety — aspect-ratio anti-CLS, no-stretch
     7. Newsletter form — stacking propre sur mobile
     8. Cookies banner — fit mobile, safe-area
     9. Back-to-top FAB — safe-area awareness
    10. Form error/success — contraste AA mobile
    11. Mini-cart drawer — slide-in safe-area + scroll fluide
    12. Bonus conversion — micro-anims subtiles, focus visible
   ═══════════════════════════════════════════════════════════════════ */

/* ─── 1. TAP HIGHLIGHT + TOUCH ACTION — universel mobile ────────────
   Supprime le rectangle gris/bleu par défaut sur tap iOS/Android et
   active l'élimination du delay 300ms (tap-to-zoom). Aucun impact
   desktop — ces propriétés sont silencieuses hors mobile. */
html {
  -webkit-tap-highlight-color: transparent;
}
:where(button, a, [role="button"], [role="tab"], [role="link"], label, summary, .tu-tap, .product-card, .nav-icon, .cart-icon, .burger-menu-btn, .dark-mode-btn, .add-to-cart-btn, .btn, .btn-primary, .btn-secondary, .btn-cart, .btn-checkout) {
  -webkit-tap-highlight-color: transparent;
  touch-action: manipulation;
}

/* ─── 2. ACTIVE STATE FEEDBACK — perception "tap a fait quelque chose"
   Sur mobile, le navigateur n'affiche pas :hover au tap. Sans :active,
   l'utilisateur ne sait pas si son tap a été pris. On ajoute une
   micro-pulsation tactile cross-site, désactivable via prefers-reduced-
   motion (déjà géré par responsive-premium.css §19). */
@media (hover: none) and (pointer: coarse) {
  /* Boutons / CTA : pulse subtile au tap */
  :where(button, .btn, .btn-primary, .btn-secondary, .btn-cart, .btn-checkout, .add-to-cart-btn, .login-btn, .nav-icon, .cart-icon, .burger-menu-btn, .password-toggle):not(:disabled):active {
    transform: scale(0.97);
    transition: transform 0.08s ease-out;
  }
  /* Cards cliquables : subtile descente au tap (pas trop, sinon ça bug le
     scroll). On évite scale qui peut déclencher des reflows lourds
     dans les grids longues. Seulement les cartes RÉELLEMENT cliquables
     (product, outfit, commande) — pas review/testimonial qui sont du
     contenu narratif non-interactif (éviterait une false affordance). */
  :where(.product-card, .tu-outfit-card, .order-card, .order-item-card):active {
    transform: translateY(1px);
    transition: transform 0.08s ease-out;
  }
  /* Liens dans header / footer : feedback couleur léger (pas de scale
     pour ne pas perturber le layout texte). */
  :where(.nav-links a, .dropdown-content a, .footer a):active {
    opacity: 0.7;
    transition: opacity 0.08s ease-out;
  }
}

/* ─── 3. STICKY BOTTOM CTA — fiche produit ─────────────────────────
   Pattern Nike/Zara : sur mobile, le bloc qty+add-to-cart+wishlist se
   colle en bas de l'écran, avec respect safe-area iPhone, fond opaque
   pour rester lisible sur n'importe quelle photo, et padding-bottom
   réservé sur le main pour ne pas masquer le bas du contenu.

   - Cible `main.product-detail-page .product-actions` (sélecteur
     existant dans produit-detail.html ligne 1963).
   - Ne touche PAS la quantité-control / add-to-cart-btn / wishlist :
     leurs styles individuels (responsive-premium.css §8 et CSS de
     produit-detail.html) restent intacts.
   - L'utilisateur garde toujours accès au bouton, même en bas de
     fiche (description, avis, recos) : c'est l'avantage UX principal. */
@media (max-width: 768px) {
  main.product-detail-page {
    /* Réserve l'espace sous le contenu pour ne pas masquer le bas du
       footer / dernier avis sous le sticky bar. La hauteur ~96 px =
       padding (12px*2) + bouton (48px) + safe-area max (~24px). */
    padding-bottom: calc(96px + env(safe-area-inset-bottom));
  }
  main.product-detail-page .product-actions {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 950; /* < modales (9999) et mini-cart (9999), > tout le reste */
    margin: 0;
    padding: 12px max(14px, env(safe-area-inset-left)) calc(12px + env(safe-area-inset-bottom)) max(14px, env(safe-area-inset-right));
    /* Background opaque à 96% : garde la lisibilité si backdrop-filter
       n'est pas supporté (Firefox Android < 103). L'effet blur est un
       bonus visuel, pas une dépendance. */
    background: rgba(255, 255, 255, 0.96);
    backdrop-filter: blur(14px) saturate(1.2);
    -webkit-backdrop-filter: blur(14px) saturate(1.2);
    border-top: 1px solid rgba(44, 62, 80, 0.08);
    box-shadow: 0 -8px 24px -8px rgba(44, 62, 80, 0.12);
    /* !important nécessaires pour battre responsive-premium.css §8 qui
       a `flex-wrap: wrap !important` + `gap: 0.6rem !important` sur
       `.product-actions` — sans ça, la sticky bar se casse en 2 lignes
       (wishlist passe sous add-to-cart) sur les écrans étroits. */
    display: flex !important;
    align-items: center !important;
    gap: 10px !important;
    flex-wrap: nowrap !important;
  }
  body.dark-mode main.product-detail-page .product-actions {
    background: rgba(20, 20, 20, 0.94);
    border-top-color: rgba(255, 255, 255, 0.08);
    box-shadow: 0 -8px 28px -8px rgba(0, 0, 0, 0.45);
  }
  /* Quantity-control : compacte à gauche, ne mange pas tout l'espace */
  main.product-detail-page .product-actions .quantity-control {
    width: auto;
    flex: 0 0 auto;
    min-height: 44px;
    gap: 4px;
  }
  /* Add-to-cart : prend l'espace restant, reste le héros */
  main.product-detail-page .product-actions .add-to-cart-btn {
    flex: 1 1 auto;
    min-height: 48px;
    margin: 0;
  }
  /* Wishlist : icône carrée à droite, pas trop grosse */
  main.product-detail-page .product-actions .wishlist-btn-detail {
    flex: 0 0 auto;
    width: 48px;
    height: 48px;
    min-height: 48px;
    padding: 0;
    border-radius: 12px;
  }
}

/* Sur écrans très étroits (≤ 380 px iPhone SE), on cache le compteur
   quantité dans la barre sticky (l'utilisateur peut toujours l'ajuster
   plus haut sur la page) pour que le bouton add-to-cart ait de la place. */
@media (max-width: 380px) {
  main.product-detail-page .product-actions .quantity-control {
    display: none;
  }
}

/* ─── 4. STICKY CHECKOUT BAR — cart.html ───────────────────────────
   Le bouton de paiement principal (`#checkout-btn`) est rendu sticky
   en bas sur mobile, hors du flow de la summary, pour une conversion
   one-tap. On garde un fallback : si le bouton n'existe pas, rien
   n'arrive. Ne se déclenche que sur cart.html via body:has(#cart-page).
   Si :has() n'est pas supporté, le sélecteur est ignoré et le bouton
   reste en place (fallback safe). */
@media (max-width: 768px) {
  body:has(#checkout-btn) {
    padding-bottom: calc(80px + env(safe-area-inset-bottom));
  }
  body:has(#checkout-btn) #checkout-btn,
  body:has(.cart-page) #checkout-btn {
    position: fixed;
    left: max(12px, env(safe-area-inset-left));
    right: max(12px, env(safe-area-inset-right));
    bottom: calc(12px + env(safe-area-inset-bottom));
    z-index: 940;
    width: auto;
    min-height: 52px;
    border-radius: 14px;
    box-shadow: 0 12px 28px -8px rgba(46, 204, 113, 0.45),
                0 4px 12px -4px rgba(44, 62, 80, 0.18);
    /* Sécurité : empêche que le bouton soit recouvert par autre chose */
    isolation: isolate;
  }
}

/* ─── 5. SCROLL-SNAP HORIZONTAL — thumbnails / tabs / carousels ───
   Ajoute le snap natif sur les listes horizontales pour une UX
   gallery iOS-like (se cale pile sur chaque vignette). Aucune
   dépendance JS, aucun changement HTML. */
@media (max-width: 768px) {
  .product-thumbnails,
  .tabs-header,
  .tabs-header-with-badges,
  .sidebar-menu,
  .account-tabs-nav {
    scroll-snap-type: x proximity;
    scroll-padding-inline: 12px;
  }
  .product-thumbnails > *,
  .tabs-header > *,
  .tabs-header-with-badges > *,
  .sidebar-menu > *,
  .account-tabs-nav > * {
    scroll-snap-align: start;
  }
}

/* ─── 6. IMAGE SAFETY — anti-CLS, no-stretch, lazy-friendly ───────
   Garantit qu'aucune image ne casse la mise en page pendant le chargement
   ni ne s'étire. Si l'image a width/height en attribut HTML, son ratio
   est déjà préservé (le navigateur calcule aspect-ratio auto). On donne
   un filet pour les images sans dimensions. */
@media (max-width: 768px) {
  :where(img):not([width]):not([height]):not(.tu-no-ratio) {
    /* Si vraiment aucune dimension fournie, on évite le stretch en
       n'imposant qu'un cap horizontal. height:auto préserve le ratio
       intrinsèque du fichier dès qu'il décode. */
    max-width: 100%;
    height: auto;
  }
  /* Évite qu'une image dans une .product-card mobile s'étire si le
     parent n'a pas la bonne hauteur. */
  .product-card img,
  .product-image img,
  .mini-cart-item-image img {
    max-width: 100%;
    height: auto;
    object-fit: cover;
  }
  /* Performance : les images chargées en lazy ne doivent pas faire
     un saut visuel quand elles arrivent. Animation discrète d'apparition. */
  img[loading="lazy"] {
    transition: opacity 0.28s ease-out;
  }
}

/* ─── 7. NEWSLETTER FORM — stacking propre mobile ─────────────────
   Beaucoup de formulaires newsletter sont en flex inline → sur mobile
   le bouton se retrouve serré contre l'input. On force un stack vertical
   propre avec un bouton pleine largeur en CTA. */
@media (max-width: 640px) {
  .newsletter-form,
  .footer-newsletter,
  .newsletter-section form {
    display: flex;
    flex-direction: column;
    gap: 10px;
    width: 100%;
  }
  .newsletter-form input[type="email"],
  .footer-newsletter input[type="email"],
  .newsletter-section form input[type="email"] {
    width: 100%;
    min-height: 48px;
    border-radius: 12px;
  }
  .newsletter-form button,
  .footer-newsletter button,
  .newsletter-section form button {
    width: 100%;
    min-height: 48px;
    border-radius: 12px;
    font-weight: 700;
  }
}

/* ─── 8. COOKIES BANNER — fit mobile + safe-area ──────────────────
   Le banner cookies est un point de friction connu sur mobile : trop
   large, pas de safe-area. On contraint sans casser la structure. */
@media (max-width: 640px) {
  .cookies-banner,
  .cookie-banner,
  #tu-cookie-banner,
  .tu-cookies {
    left: max(10px, env(safe-area-inset-left)) !important;
    right: max(10px, env(safe-area-inset-right)) !important;
    bottom: calc(10px + env(safe-area-inset-bottom)) !important;
    max-width: calc(100vw - 20px);
    border-radius: 16px;
    padding: 14px 16px;
    font-size: 0.92rem;
  }
  .cookies-banner .actions,
  .cookie-banner .actions,
  #tu-cookie-banner .actions,
  .tu-cookies .actions {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin-top: 10px;
  }
  .cookies-banner .actions > *,
  .cookie-banner .actions > *,
  #tu-cookie-banner .actions > *,
  .tu-cookies .actions > * {
    flex: 1 1 auto;
    min-height: 44px;
  }
}

/* ─── 9. BACK-TO-TOP FAB — safe-area, ne couvre pas les autres CTAs */
@media (max-width: 768px) {
  .scroll-to-top,
  .back-to-top,
  #scroll-top-btn,
  .tu-fab {
    /* Décalé pour ne PAS chevaucher la sticky CTA produit-actions
       (96px reserve). Sur les pages sans sticky CTA, reste élégant. */
    bottom: calc(20px + env(safe-area-inset-bottom)) !important;
    right: max(14px, env(safe-area-inset-right)) !important;
    width: 48px !important;
    height: 48px !important;
  }
  /* Si la page est produit-detail (sticky CTA actif), on remonte le
     FAB au-dessus pour ne pas le couvrir. */
  body main.product-detail-page ~ .scroll-to-top,
  body main.product-detail-page ~ .back-to-top,
  main.product-detail-page .scroll-to-top,
  main.product-detail-page .back-to-top {
    bottom: calc(110px + env(safe-area-inset-bottom)) !important;
  }
  /* Idem pour les pages avec sticky checkout-btn : on remonte. */
  body:has(#checkout-btn) .scroll-to-top,
  body:has(#checkout-btn) .back-to-top {
    bottom: calc(80px + env(safe-area-inset-bottom)) !important;
  }
}

/* ─── 10. FORM ERROR / SUCCESS — contraste mobile lisible ─────────
   Les messages d'état (alerte verte / rouge) doivent rester lisibles
   sur petit écran. On force un fond légèrement opaque + bordure pour
   le contraste WCAG AA. Ne touche PAS aux structures #alert existantes
   (login.html, signup.html ont leur propre style). */
@media (max-width: 768px) {
  :where(.alert, .form-error, .field-error, .error-text, .success-text):not(:empty) {
    border-radius: 12px;
    font-size: 0.94rem;
    line-height: 1.45;
    padding: 10px 14px;
    display: block;
  }
  :where(.alert.error, .alert-error, .form-error, .field-error):not(:empty) {
    background: rgba(231, 76, 60, 0.10);
    border: 1px solid rgba(231, 76, 60, 0.32);
    color: #C0392B;
  }
  body.dark-mode :where(.alert.error, .alert-error, .form-error, .field-error):not(:empty) {
    background: rgba(231, 76, 60, 0.16);
    border-color: rgba(231, 76, 60, 0.40);
    color: #FF8A7A;
  }
  :where(.alert.success, .alert-success, .success-text):not(:empty) {
    background: rgba(46, 204, 113, 0.10);
    border: 1px solid rgba(46, 204, 113, 0.32);
    color: #1E8449;
  }
  body.dark-mode :where(.alert.success, .alert-success, .success-text):not(:empty) {
    background: rgba(46, 204, 113, 0.16);
    border-color: rgba(46, 204, 113, 0.40);
    color: #5ED480;
  }
}

/* ─── 11. MINI-CART DRAWER — momentum scroll + safe-area bas ──────
   cart.css §697 fait déjà le 100% width sur mobile. On ajoute la
   gestion safe-area pour que le titre / close button du drawer ne
   passent pas sous l'encoche iPhone, et que le footer (CTAs panier/
   checkout) ne soit pas masqué par le home indicator. */
@media (max-width: 768px) {
  /* CORRECTION v2 : on pad le HEADER (gradient), pas le container.
     Padder le container .mini-cart créait une bande blanche au-dessus
     du header gradient sur iPhone à encoche (safe-area-inset-top ≈ 44px).
     En padant le header directement, le gradient s'étend jusqu'au bord
     et seul le texte est protégé. */
  .mini-cart-header {
    padding-top: calc(1.35rem + env(safe-area-inset-top)) !important;
  }
  .mini-cart-footer {
    padding-bottom: calc(1.25rem + env(safe-area-inset-bottom)) !important;
  }
  .mini-cart-items {
    -webkit-overflow-scrolling: touch;
    overscroll-behavior: contain;
  }
}

/* ─── 12. BONUS CONVERSION — micro-polish premium ─────────────────
   Détails subtils qui rendent le mobile "premium" sans changer la DA. */
@media (max-width: 768px) {
  /* Boutons : caret invisible (sinon focus visuel double sur certains
     Android Chromium qui dessinent le caret par défaut) */
  button,
  .btn,
  .login-btn,
  .add-to-cart-btn,
  .btn-checkout {
    caret-color: transparent;
  }
  /* Inputs : caret garde la couleur primaire pour cohérence DA */
  input,
  textarea,
  select {
    caret-color: var(--primary-color, #2ECC71);
  }
  /* Smooth scroll sur ancres (au-delà de html { scroll-behavior } pour
     compatibilité Safari iOS < 16) */
  html {
    scroll-padding-top: calc(60px + env(safe-area-inset-top));
  }
  /* Boutons disabled : visuellement clair qu'ils sont inactifs.
     opacity 0.55 + cursor:not-allowed suffit visuellement. On évite
     filter:saturate qui force une couche de composition GPU par
     bouton (coût mémoire + repaint sur chaque scroll/animation). */
  button:disabled,
  .btn:disabled,
  .add-to-cart-btn:disabled,
  .login-btn:disabled {
    opacity: 0.55;
    cursor: not-allowed;
  }
  /* Liens texte : underline plus marqué sur mobile pour lisibilité.
     Sélecteurs simples uniquement (compat iOS 14, qui ne supporte pas
     les :not() complexes avec combinateurs descendant CSS Selectors 4).
     Les liens dropdown/footer ont leur propre style + sont rarement
     dans des <p>/<li> de contenu narratif, donc l'exclusion n'est pas
     critique. */
  p a:not(.btn):not(.login-btn):not(.nav-icon):not([class*="btn-"]),
  li a:not(.btn):not(.nav-icon):not([class*="btn-"]) {
    text-decoration-thickness: 1.5px;
    text-underline-offset: 2px;
  }
  /* NOTE : la règle :focus-visible site-wide existe déjà à
     responsive-premium.css §1 ligne 59 avec exactement les mêmes
     valeurs (outline 2px primary, offset 2px, radius 6px). On
     n'ajoute pas de doublon ici. */
}

/* ─── 13. UTILITAIRES OPT-IN — pour usages futurs ─────────────────
   Classes que tu peux ajouter manuellement sur n'importe quel élément
   pour activer un comportement mobile premium. */
.tu-mobile-sticky {
  /* À appliquer sur n'importe quel CTA pour le coller en bas */
}
@media (max-width: 768px) {
  .tu-mobile-sticky {
    position: sticky;
    bottom: calc(8px + env(safe-area-inset-bottom));
    z-index: 50;
  }
  .tu-mobile-fullwidth {
    width: 100% !important;
  }
  .tu-mobile-stack {
    display: flex !important;
    flex-direction: column !important;
    gap: 10px !important;
  }
}

/* ═══════════════════════════════════════════════════════════════════
   §14 — PRODUIT DETAIL — DISPOSITION MOBILE PREMIUM (≤ 768 px)
   -----------------------------------------------------------------
   Refonte ciblée de la page fiche produit pour mobile uniquement.
   AUCUNE modification HTML — la disposition est reflowée via
   `display: flex` + `order` sur les enfants existants. Les hooks JS
   (#main-product-image, #gallery-prev/next, #gallery-zoom-icon,
   #size-options .option-value.selected, #color-options, #add-to-cart-btn,
   #wishlist-btn-detail, #stock-message, #product-quantity, etc.)
   restent intacts.

   Scope strict : `main.product-detail-page` UNIQUEMENT.
   Aucune fuite vers d'autres pages, zéro régression desktop.
   ═══════════════════════════════════════════════════════════════════ */

/* ─── 14.1 Container : reorder visuel sans toucher au DOM ─────────
   .product-info en flex column + `order` sur chaque enfant pour la
   séquence mobile-conversion-optimal :
     1. Badges  (ce qui qualifie le produit)
     2. Titre   (ce qui identifie)
     3. Prix    (ce qui décide)
     4. Social proof (urgence après prix)
     5. Tailles (ce qui personnalise)
     6. Couleurs
     7. Stock-message (visibilité avant CTA)
     8. Réassurance (bénéfices clés)
     9. Livraison estimée
    10. Description courte (lecture après décision)
    99. .product-actions reste en `position: fixed` via §3 — son
        order est ignoré visuellement mais reste pour la cascade.
   Note : flex désactive le margin-collapsing → les enfants gardent
   leurs margins intrinsèques, on ajoute juste un `gap: 0` neutre. */
@media (max-width: 768px) {
  main.product-detail-page .product-info {
    display: flex;
    flex-direction: column;
    gap: 0; /* on respecte les margin-bottom existants — pas de conflit */
  }
  main.product-detail-page .product-info > .product-badges       { order: 1; }
  main.product-detail-page .product-info > h1#product-name       { order: 2; }
  main.product-detail-page .product-info > .product-price        { order: 3; }
  main.product-detail-page .product-info > .social-proof         { order: 4; }
  main.product-detail-page .product-info > #size-options-group   { order: 5; }
  main.product-detail-page .product-info > #color-options-group  { order: 6; }
  main.product-detail-page .product-info > #stock-message        { order: 7; }
  main.product-detail-page .product-info > .reassurance-block    { order: 8; }
  main.product-detail-page .product-info > .delivery-estimate    { order: 9; }
  main.product-detail-page .product-info > #product-short-description { order: 10; }
  main.product-detail-page .product-info > .product-actions      { order: 99; }
}

/* ─── 14.2 Breadcrumb compact ─────────────────────────────────────
   Le fil d'Ariane prend de la place premium sur mobile. On le réduit
   en typo + padding pour qu'il reste informatif sans peser sur le LCP. */
@media (max-width: 768px) {
  main.product-detail-page .breadcrumb-nav {
    font-size: 0.78rem;
    padding: 6px 0 8px;
    line-height: 1.3;
    /* Truncate du nom produit si très long pour rester sur 1 ligne */
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }
  main.product-detail-page .breadcrumb-nav .sep {
    margin: 0 4px;
    opacity: 0.55;
  }
  main.product-detail-page .breadcrumb-nav a {
    color: rgba(127, 140, 141, 0.85);
  }
  main.product-detail-page .breadcrumb-nav .current {
    font-weight: 600;
  }
}

/* ─── 14.3 Galerie premium mobile ─────────────────────────────────
   - Aspect-ratio 4/5 réservé sur le main-image-container (anti-CLS,
     évite le saut quand l'image charge async)
   - Flèches plus discrètes mais touch-friendly (44×44, blur léger)
   - Zoom icon plus subtil
   - Thumbnails 64×64 (légèrement plus grandes), bordure douce */
@media (max-width: 768px) {
  main.product-detail-page .product-gallery {
    margin-bottom: 18px;
  }
  main.product-detail-page .main-image-container {
    aspect-ratio: 4 / 5;
    border-radius: 16px;
    background: rgba(46, 204, 113, 0.04); /* placeholder avant chargement */
  }
  body.dark-mode main.product-detail-page .main-image-container {
    background: rgba(46, 204, 113, 0.08);
  }
  main.product-detail-page #main-product-image {
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: center;
  }
  /* Désactive le hover scale sur mobile (cause un jitter au touch) */
  main.product-detail-page .main-image-container:hover #main-product-image {
    transform: none;
  }
  /* Flèches : taille touch + look discret blur */
  main.product-detail-page .gallery-nav-btn {
    width: 44px !important;
    height: 44px !important;
    background: rgba(255, 255, 255, 0.78) !important;
    backdrop-filter: blur(8px);
    -webkit-backdrop-filter: blur(8px);
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
    font-size: 0.95rem;
  }
  main.product-detail-page .gallery-nav-btn.prev { left: 8px; }
  main.product-detail-page .gallery-nav-btn.next { right: 8px; }
  body.dark-mode main.product-detail-page .gallery-nav-btn {
    background: rgba(20, 20, 20, 0.78) !important;
    color: #fff;
  }
  /* Zoom icon : plus subtil sur mobile (le tap gallery suffit souvent) */
  main.product-detail-page .zoom-icon {
    width: 36px;
    height: 36px;
    bottom: 8px;
    right: 8px;
    background: rgba(255, 255, 255, 0.78);
    backdrop-filter: blur(8px);
    -webkit-backdrop-filter: blur(8px);
    font-size: 0.8rem;
  }
  body.dark-mode main.product-detail-page .zoom-icon {
    background: rgba(20, 20, 20, 0.78);
    color: #fff;
  }
  /* Thumbnails plus larges + bordure plus douce */
  main.product-detail-page .product-thumbnails {
    margin-top: 10px;
    padding: 4px 2px 8px;
  }
  main.product-detail-page .product-thumbnails img,
  main.product-detail-page .product-thumbnails .thumbnail,
  main.product-detail-page .product-thumbnails .thumbnail-image {
    width: 64px !important;
    height: 64px !important;
    border-radius: 12px !important;
    border: 2px solid transparent;
    opacity: 0.78;
    transition: opacity 0.2s ease, border-color 0.2s ease;
  }
  main.product-detail-page .product-thumbnails .thumbnail-image.active,
  main.product-detail-page .product-thumbnails img.active,
  main.product-detail-page .product-thumbnails .thumbnail.active {
    border-color: var(--primary-color, #2ECC71) !important;
    opacity: 1;
  }
  /* Désactive le scale au hover (jitter mobile) */
  main.product-detail-page .product-thumbnails .thumbnail-image:hover {
    transform: none;
  }
}

/* ─── 14.4 Badges — alignés, lisibles, espacés ───────────────────── */
@media (max-width: 768px) {
  main.product-detail-page .product-badges {
    margin: 0 0 12px;
    gap: 6px;
  }
  main.product-detail-page .product-badges .badge {
    padding: 4px 11px;
    font-size: 0.68rem;
    border-radius: 999px;
    line-height: 1.4;
    letter-spacing: 0.06em;
  }
}

/* ─── 14.5 Titre produit — présence + line-height confortable ──── */
@media (max-width: 768px) {
  main.product-detail-page .product-info h1#product-name {
    font-size: clamp(1.5rem, 5.5vw, 2rem) !important;
    line-height: 1.18;
    letter-spacing: -0.005em;
    margin: 0 0 10px;
    font-weight: 800;
  }
  body.dark-mode main.product-detail-page .product-info h1#product-name {
    color: #FFFFFF;
  }
}

/* ─── 14.6 Prix — héros visuel, gestion promo claire ─────────────── */
@media (max-width: 768px) {
  main.product-detail-page .product-info .product-price {
    margin: 0 0 12px;
    display: flex;
    align-items: baseline;
    gap: 10px;
    flex-wrap: wrap;
  }
  main.product-detail-page .product-info .product-price .current-price {
    font-size: 1.55rem;
    font-weight: 800;
    color: var(--primary-color, #2ECC71);
    letter-spacing: -0.01em;
    line-height: 1;
  }
  main.product-detail-page .product-info .product-price .original-price {
    font-size: 1rem;
    color: rgba(127, 140, 141, 0.85);
    text-decoration: line-through;
    text-decoration-thickness: 1.5px;
  }
  body.dark-mode main.product-detail-page .product-info .product-price .current-price {
    color: #5ED480;
  }
}

/* ─── 14.7 Social proof — pill subtile, sous le prix ─────────────── */
@media (max-width: 768px) {
  main.product-detail-page .product-info .social-proof {
    margin: 0 0 14px;
    padding: 6px 12px;
    background: rgba(230, 57, 70, 0.08);
    border-radius: 999px;
    font-size: 0.78rem;
    font-weight: 600;
    align-self: flex-start; /* ne prend pas toute la largeur */
    border: 1px solid rgba(230, 57, 70, 0.18);
  }
  body.dark-mode main.product-detail-page .product-info .social-proof {
    background: rgba(230, 57, 70, 0.14);
    border-color: rgba(230, 57, 70, 0.28);
  }
}

/* ─── 14.8 Livraison estimée — pill verte discrète ───────────────── */
@media (max-width: 768px) {
  main.product-detail-page .product-info .delivery-estimate {
    margin: 12px 0 0;
    padding: 8px 12px;
    background: rgba(46, 204, 113, 0.08);
    border-radius: 12px;
    font-size: 0.85rem;
    font-weight: 600;
    border: 1px solid rgba(46, 204, 113, 0.18);
    align-self: stretch;
  }
  body.dark-mode main.product-detail-page .product-info .delivery-estimate {
    background: rgba(46, 204, 113, 0.14);
    border-color: rgba(46, 204, 113, 0.28);
    color: #5ED480;
  }
  body.dark-mode main.product-detail-page .product-info .delivery-estimate i {
    color: #5ED480;
  }
}

/* ─── 14.9 Variantes (taille / couleur) — espacement + états ──── */
@media (max-width: 768px) {
  main.product-detail-page .option-group {
    margin: 14px 0;
  }
  main.product-detail-page .option-group label {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
    font-size: 0.85rem;
    font-weight: 700;
    margin-bottom: 10px;
    color: var(--dark-color, #2C3E50);
    letter-spacing: 0.02em;
  }
  main.product-detail-page .option-group label > span {
    font-weight: 600;
    color: rgba(127, 140, 141, 0.95);
  }
  main.product-detail-page .size-guide-link {
    margin-left: auto !important; /* aligné à droite */
    font-size: 0.78rem;
    color: var(--primary-color, #2ECC71);
    text-decoration: none;
    border-bottom: 1px dashed rgba(46, 204, 113, 0.5);
    padding-bottom: 1px;
  }
  main.product-detail-page .option-values {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
  }
  /* Tailles : mêmes dimensions, contraste sélection plus net */
  main.product-detail-page #size-options .option-value {
    min-width: 48px;
    min-height: 44px;
    padding: 0.5rem 0.85rem;
    border-radius: 12px;
    font-size: 0.92rem;
    font-weight: 700;
    border: 1.5px solid rgba(44, 62, 80, 0.14);
    background: var(--white, #FFFFFF);
    color: var(--dark-color, #2C3E50);
    transition: background 0.18s ease, border-color 0.18s ease, transform 0.12s ease;
  }
  body.dark-mode main.product-detail-page #size-options .option-value {
    background: rgba(255, 255, 255, 0.04);
    color: #FFFFFF;
    border-color: rgba(255, 255, 255, 0.12);
  }
  /* État indisponible : barré + opaque + non-tactile */
  main.product-detail-page #size-options .option-value.disabled,
  main.product-detail-page #size-options .option-value.out-of-stock,
  main.product-detail-page #size-options .option-value[disabled],
  main.product-detail-page #size-options .option-value[aria-disabled="true"] {
    opacity: 0.42;
    cursor: not-allowed;
    text-decoration: line-through;
    text-decoration-thickness: 1.5px;
    pointer-events: none; /* sécurité tactile */
  }
  /* Couleurs : pastilles + ring sélection plus visible mobile */
  main.product-detail-page #color-options .color-option {
    width: 36px;
    height: 36px;
    margin: 4px;
  }
  main.product-detail-page #color-options .color-option.selected {
    box-shadow: 0 0 0 3px var(--white, #fff),
                0 0 0 5px var(--primary-color, #2ECC71) !important;
  }
  body.dark-mode main.product-detail-page #color-options .color-option.selected {
    box-shadow: 0 0 0 3px #1A1A1A,
                0 0 0 5px #5ED480 !important;
  }
}

/* ─── 14.10 Réassurance — pills 2×2 propres avec bordures saines ── */
@media (max-width: 768px) {
  main.product-detail-page .reassurance-block {
    display: grid !important;
    grid-template-columns: repeat(2, minmax(0, 1fr)) !important;
    gap: 8px !important;
    border: none !important;
    border-radius: 0 !important;
    overflow: visible !important;
    margin: 16px 0 !important;
    padding: 0 !important;
    background: transparent !important;
  }
  main.product-detail-page .reassurance-block .reassurance-item {
    flex: 0 0 auto !important;
    padding: 12px 10px !important;
    border-right: none !important;
    border: 1px solid rgba(46, 204, 113, 0.15) !important;
    border-radius: 12px !important;
    background: rgba(46, 204, 113, 0.04);
    text-align: center;
    gap: 4px;
  }
  body.dark-mode main.product-detail-page .reassurance-block .reassurance-item {
    background: rgba(46, 204, 113, 0.08);
    border-color: rgba(46, 204, 113, 0.22) !important;
  }
  main.product-detail-page .reassurance-block .reassurance-item i {
    color: var(--primary-color, #2ECC71) !important;
    font-size: 1.15rem;
  }
  main.product-detail-page .reassurance-block .reassurance-item span {
    font-size: 0.75rem;
    color: var(--dark-color, #2C3E50);
    font-weight: 700;
  }
  body.dark-mode main.product-detail-page .reassurance-block .reassurance-item span {
    color: #FFFFFF;
  }
  main.product-detail-page .reassurance-block .reassurance-item small {
    font-size: 0.66rem;
    color: rgba(127, 140, 141, 0.95);
    line-height: 1.35;
  }
  /* Désactive le hover qui jitter au touch */
  main.product-detail-page .reassurance-block .reassurance-item:hover {
    background: rgba(46, 204, 113, 0.08);
  }
}

/* ─── 14.11 Description courte — lisible sans surcharge ──────────── */
@media (max-width: 768px) {
  main.product-detail-page .product-info #product-short-description,
  main.product-detail-page .product-info .product-description {
    margin: 16px 0 0;
    font-size: 0.95rem;
    line-height: 1.6;
    color: rgba(44, 62, 80, 0.85);
  }
  body.dark-mode main.product-detail-page .product-info .product-description {
    color: rgba(244, 255, 252, 0.78);
  }
}

/* ─── 14.12 Stock-message — pill alerte juste avant le sticky CTA ─ */
@media (max-width: 768px) {
  main.product-detail-page .product-info #stock-message {
    margin: 8px 0 0 !important;
    font-size: 0.85rem !important;
    font-weight: 700 !important;
  }
  /* On le rend visible UNIQUEMENT s'il a du contenu (le JS le remplit) */
  main.product-detail-page .product-info #stock-message:empty {
    margin: 0 !important;
  }
}

/* ─── 14.13 Sticky CTA — harmonisation prix-bouton (héritage §3) ──
   §3 a déjà fait le gros : position fixed bottom + safe-area + glass.
   Ici on raffine seulement la coordination visuelle avec le reste. */
@media (max-width: 768px) {
  /* Add-to-cart : icône moins agressive pour faire respirer le label */
  main.product-detail-page .product-actions .add-to-cart-btn i {
    font-size: 0.95rem;
  }
  /* Wishlist en sticky bar : look "ghost" pour ne pas concurrencer le CTA */
  main.product-detail-page .product-actions .wishlist-btn-detail {
    border-radius: 12px !important;
    background: rgba(255, 255, 255, 0.6) !important;
    border: 1px solid rgba(44, 62, 80, 0.10) !important;
    color: rgba(127, 140, 141, 0.95) !important;
    font-size: 1.1rem !important;
  }
  main.product-detail-page .product-actions .wishlist-btn-detail.active {
    color: #E63946 !important;
    border-color: rgba(230, 57, 70, 0.35) !important;
    background: rgba(230, 57, 70, 0.06) !important;
  }
  body.dark-mode main.product-detail-page .product-actions .wishlist-btn-detail {
    background: rgba(255, 255, 255, 0.06) !important;
    border-color: rgba(255, 255, 255, 0.10) !important;
    color: rgba(244, 255, 252, 0.78) !important;
  }
  /* Quantity-control : compacte, fond neutre cohérent avec le glass */
  main.product-detail-page .product-actions .quantity-control {
    border-radius: 12px;
    background: rgba(44, 62, 80, 0.04);
    padding: 0 4px;
  }
  main.product-detail-page .product-actions .quantity-control button {
    background: transparent;
    border: none;
    width: 36px !important;
    min-width: 36px !important;
    height: 44px;
    color: var(--dark-color, #2C3E50);
  }
  main.product-detail-page .product-actions .quantity-control input {
    width: 32px;
    text-align: center;
    background: transparent;
    border: none;
    font-weight: 700;
    color: var(--dark-color, #2C3E50);
    /* Évite le caret blinking sur le numérique mobile */
    caret-color: transparent;
  }
  body.dark-mode main.product-detail-page .product-actions .quantity-control {
    background: rgba(255, 255, 255, 0.06);
  }
  body.dark-mode main.product-detail-page .product-actions .quantity-control button,
  body.dark-mode main.product-detail-page .product-actions .quantity-control input {
    color: #FFFFFF;
  }
}

/* ─── 14.14 Tabs description/détails — espacement après sticky ──── */
@media (max-width: 768px) {
  main.product-detail-page .product-tabs-section {
    margin-top: 24px;
  }
  main.product-detail-page .tab-button {
    min-height: 44px;
    font-size: 0.95rem !important;
  }
  main.product-detail-page .tab-button.active {
    color: var(--primary-color, #2ECC71);
    border-bottom-color: var(--primary-color, #2ECC71);
  }
}

/* ═══════════════════════════════════════════════════════════════════
   §15 — PRODUIT DETAIL — CARROUSELS HORIZONTAUX + FOOTER PAYMENTS
   -----------------------------------------------------------------
   Corrections ciblées des bugs visuels reportés sur produit-detail.html :
     1. Stacking cassé sur "Dans le même univers" et "Composez votre
        silhouette" → forcer un vrai carrousel horizontal scroll-snap
     2. Trop d'icônes paiement dans le footer → garder 3 essentielles
   Aucun HTML modifié, aucun JS touché, scope strict ≤ 768 px.
   ═══════════════════════════════════════════════════════════════════ */

/* ─── 15.1 Carrousels recos — forcer le scroll horizontal ──────────
   CAUSE RACINE du bug "stacking" :
     responsive-premium.css §7 (ligne 286) force
     `.products-grid { grid-template-columns: repeat(2, minmax(0, 1fr)) !important }`
     ce qui bat le carrousel inline défini dans produit-detail.html
     (ligne 1430), et à ≤380px force même `1fr !important` (cards 1 par
     ligne empilées). Résultat : les recos s'empilent au lieu de scroller.

   FIX : override avec une spécificité plus haute (préfixe
   `main.product-detail-page` + `.tu-reco`) ET `!important` ciblé pour
   battre la cascade. Aucune autre `.products-grid` du site n'est
   affectée — le scope `main.product-detail-page` garantit l'isolation.

   Cible les 2 sections recos :
     - #suggest-section .products-grid.tu-reco-grid  ("Dans le même univers")
     - #crosssell-section .products-grid             ("Composez votre silhouette") */
@media (max-width: 768px) {
  main.product-detail-page .tu-reco .products-grid,
  main.product-detail-page #suggest-section .products-grid,
  main.product-detail-page #crosssell-section .products-grid {
    /* Carrousel horizontal natif via grid-auto-flow column */
    display: grid !important;
    grid-auto-flow: column !important;
    grid-auto-columns: 78% !important;
    grid-template-columns: unset !important;
    grid-template-rows: auto !important;
    gap: 12px !important;
    /* Scroll horizontal fluide + snap */
    overflow-x: auto !important;
    overflow-y: hidden !important;
    scroll-snap-type: x mandatory !important;
    scroll-behavior: smooth;
    -webkit-overflow-scrolling: touch;
    overscroll-behavior-x: contain;
    /* Padding gauche/droite pour effet "première carte décolle du bord" */
    padding: 6px 16px 16px !important;
    margin: 0 -16px !important; /* compense le padding parent .container */
    /* Scrollbar masquée pour un look premium (snap est l'indicateur visuel) */
    scrollbar-width: none;
  }
  main.product-detail-page .tu-reco .products-grid::-webkit-scrollbar,
  main.product-detail-page #suggest-section .products-grid::-webkit-scrollbar,
  main.product-detail-page #crosssell-section .products-grid::-webkit-scrollbar {
    display: none;
    width: 0;
    height: 0;
  }
  /* Chaque carte occupe sa colonne auto (78%), snap-align start */
  main.product-detail-page .tu-reco .products-grid > .product-card,
  main.product-detail-page #suggest-section .products-grid > .product-card,
  main.product-detail-page #crosssell-section .products-grid > .product-card {
    scroll-snap-align: start;
    min-width: 0;
    width: auto !important; /* cancelle d'éventuels width fixes */
    margin: 0 !important;   /* le gap du grid gère l'espacement */
  }
  /* Hauteur d'image stabilisée — anti-CLS dans le scroll horizontal */
  main.product-detail-page .tu-reco .products-grid .product-card .product-image-wrapper,
  main.product-detail-page .tu-reco .products-grid .product-card .product-image-link,
  main.product-detail-page .tu-reco .products-grid .product-card .product-image-link img {
    aspect-ratio: 3 / 4;
    height: auto !important;
    min-height: 0 !important;
    width: 100%;
    object-fit: cover;
  }
}

/* Sur très petits écrans (≤480px), cartes plus larges (84%) :
   l'utilisateur voit 1 carte complète + un teasing de la suivante. */
@media (max-width: 480px) {
  main.product-detail-page .tu-reco .products-grid,
  main.product-detail-page #suggest-section .products-grid,
  main.product-detail-page #crosssell-section .products-grid {
    grid-auto-columns: 84% !important;
    padding: 6px 14px 14px !important;
    margin: 0 -14px !important;
  }
}

/* §15.2 — REMPLACÉE par §16 (système site-wide multi-structures).
   Voir §16 PAYMENT ICONS HARMONISÉS plus bas. */

/* ─── 15.3 Galerie thumbnails — sécurité visuelle si élément orphelin
   Si le carrousel produit ne contient qu'1 thumbnail (single image),
   on cache le strip vide pour éviter l'apparence de "barre parasite".
   Détection : le strip thumbnails sans children ou avec 1 seul. */
@media (max-width: 768px) {
  main.product-detail-page .product-thumbnails:empty {
    display: none !important;
  }
  /* Si exactement 1 thumbnail, le strip n'a pas de valeur navigationnelle */
  main.product-detail-page .product-thumbnails:has(> :only-child) {
    display: none !important;
  }
}

/* ═══════════════════════════════════════════════════════════════════
   §16 — PAYMENT ICONS — PATCH FORCÉ v2 (anti-cascade)
   -----------------------------------------------------------------
   POURQUOI v2 :
     v1 perdait la cascade contre `.footer .payment-icon { height:30px }`
     de style.css:3315 (spécificité 0,2,0). Mes sélecteurs `:is()`
     atteignaient seulement (0,1,2) — `:is()` prend la spécificité du
     plus spécifique de ses arguments, pas la somme.

   STRATÉGIE v2 :
     1. !important partout sur les propriétés critiques (height/width/
        max-height/max-width/display) → bat n'importe quelle cascade
        sans !important
     2. Sélecteurs explicites multi-variantes (pas de :is() qui peut
        diluer la spécificité)
     3. Spec montée à (0,2,2) via `footer.footer .payment-X img/svg`
     4. Catch-all `[class*="payment"]` pour couvrir tout naming futur
     5. Scope strict `footer` ou `footer.footer` → n'affecte JAMAIS
        les trust banners dans <aside> de cart/checkout/paiement

   COUVERTURE :
     - <img class="payment-icon"> (footer site-wide, 40+ pages)
     - <img class="payment-logo"> (si jamais utilisé en footer)
     - <svg class="payment-icon"> (compat future si SVG inline)
     - Tout élément avec "payment" dans son class
   ═══════════════════════════════════════════════════════════════════ */

/* ─── 16.1 Conteneur footer — layout flex centré (tous viewports) ─
   Spec : (0,2,0) via `footer.footer .payment-methods` + !important. */
footer.footer .payment-methods,
footer.footer .payment-logos,
footer.footer .payment-icons,
footer.footer [class*="payment-method"],
footer.footer [class*="payment-logo"]:not(img):not(svg),
footer.footer [class*="payment-icons"],
.footer .payment-methods,
.footer .payment-logos,
.footer .payment-icons {
  display: flex !important;
  flex-wrap: wrap !important;
  align-items: center !important;
  justify-content: center !important;
  gap: 12px !important;
  margin-top: 12px !important;
  padding: 4px 0 !important;
  width: auto !important;
  max-width: 100% !important;
}

/* ─── 16.2 Items (img + svg) — taille FORCÉE, !important partout ──
   Spec : (0,2,2) via `footer.footer .payment-methods img` — bat
   `.footer .payment-icon` (0,2,0) ET pas besoin de spécificité plus
   haute grâce au !important. On liste exhaustivement TOUS les
   sélecteurs possibles pour ne rater aucune variante. */
footer.footer .payment-methods img,
footer.footer .payment-methods svg,
footer.footer .payment-logos img,
footer.footer .payment-logos svg,
footer.footer .payment-icons img,
footer.footer .payment-icons svg,
footer.footer .payment-icon,
footer.footer .payment-logo,
footer.footer img.payment-icon,
footer.footer img.payment-logo,
footer.footer svg.payment-icon,
footer.footer svg.payment-logo,
footer.footer img[class*="payment"],
footer.footer svg[class*="payment"],
footer.footer [class*="payment"] img,
footer.footer [class*="payment"] svg,
.footer .payment-methods img,
.footer .payment-methods svg,
.footer .payment-logos img,
.footer .payment-icons img,
.footer .payment-icon,
.footer .payment-logo,
.footer img.payment-icon,
.footer img.payment-logo,
.footer img[class*="payment"],
.footer svg[class*="payment"],
.footer [class*="payment"] img,
.footer [class*="payment"] svg {
  height: 26px !important;
  max-height: 26px !important;
  min-height: 0 !important;
  width: auto !important;
  max-width: 56px !important;
  min-width: 0 !important;
  object-fit: contain !important;
  flex-shrink: 0 !important;
  display: inline-block !important;
  /* Reset background/border/padding qu'aurait pu poser cart-page.css */
  background: transparent !important;
  border: 0 !important;
  border-radius: 0 !important;
  padding: 0 !important;
  /* Reset transform pour neutraliser tout scale appliqué ailleurs */
  transform: none !important;
  vertical-align: middle;
  opacity: 0.85;
  transition: opacity 0.2s ease;
  /* Anti-blur cross-browser */
  image-rendering: -webkit-optimize-contrast;
}
footer.footer .payment-methods img:hover,
footer.footer .payment-methods svg:hover,
footer.footer img[class*="payment"]:hover,
footer.footer [class*="payment"] img:hover,
.footer img[class*="payment"]:hover,
.footer [class*="payment"] img:hover {
  opacity: 1 !important;
}

/* ─── 16.3 MOBILE (≤ 768 px) — taille réduite + masquage 3 essentiels
   Garde Visa + Mastercard + Apple Pay. Hide Amex/Stripe/Google Pay. */
@media (max-width: 768px) {
  footer.footer .payment-methods,
  footer.footer .payment-logos,
  footer.footer .payment-icons,
  .footer .payment-methods,
  .footer .payment-logos,
  .footer .payment-icons {
    gap: 14px !important;
    margin-top: 12px !important;
  }
  footer.footer .payment-methods img,
  footer.footer .payment-methods svg,
  footer.footer .payment-logos img,
  footer.footer .payment-logos svg,
  footer.footer .payment-icons img,
  footer.footer .payment-icons svg,
  footer.footer .payment-icon,
  footer.footer .payment-logo,
  footer.footer img.payment-icon,
  footer.footer img.payment-logo,
  footer.footer img[class*="payment"],
  footer.footer svg[class*="payment"],
  footer.footer [class*="payment"] img,
  footer.footer [class*="payment"] svg,
  .footer .payment-methods img,
  .footer .payment-methods svg,
  .footer .payment-icon,
  .footer .payment-logo,
  .footer img.payment-icon,
  .footer img.payment-logo,
  .footer img[class*="payment"],
  .footer svg[class*="payment"],
  .footer [class*="payment"] img,
  .footer [class*="payment"] svg {
    height: 22px !important;
    max-height: 22px !important;
    max-width: 48px !important;
    min-height: 0 !important;
    min-width: 0 !important;
  }
  /* Hide par alt (case-insensitive, ordre-indépendant) */
  footer.footer [alt="American Express" i],
  footer.footer [alt="Amex" i],
  footer.footer [alt="Stripe" i],
  footer.footer [alt="Google Pay" i],
  footer.footer [alt="GooglePay" i],
  .footer [alt="American Express" i],
  .footer [alt="Amex" i],
  .footer [alt="Stripe" i],
  .footer [alt="Google Pay" i],
  .footer [alt="GooglePay" i] {
    display: none !important;
  }
}

/* ─── 16.4 Très petits écrans (≤ 380 px iPhone SE / Galaxy S8) ──── */
@media (max-width: 380px) {
  footer.footer .payment-methods img,
  footer.footer .payment-methods svg,
  footer.footer .payment-icon,
  footer.footer img.payment-icon,
  footer.footer img[class*="payment"],
  footer.footer [class*="payment"] img,
  footer.footer [class*="payment"] svg,
  .footer .payment-methods img,
  .footer .payment-icon,
  .footer img.payment-icon,
  .footer img[class*="payment"],
  .footer [class*="payment"] img,
  .footer [class*="payment"] svg {
    height: 20px !important;
    max-height: 20px !important;
    max-width: 44px !important;
  }
  footer.footer .payment-methods,
  footer.footer .payment-logos,
  footer.footer .payment-icons,
  .footer .payment-methods,
  .footer .payment-logos,
  .footer .payment-icons {
    gap: 10px !important;
  }
}

/* ─── 16.5 Opt-in scroll horizontal pour cas >5 icônes futur ────── */
@media (max-width: 768px) {
  footer.footer .payment-icons--scroll,
  .footer .payment-icons--scroll {
    flex-wrap: nowrap !important;
    overflow-x: auto !important;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
    justify-content: flex-start !important;
    padding-inline: max(14px, env(safe-area-inset-left)) !important;
  }
  footer.footer .payment-icons--scroll::-webkit-scrollbar,
  .footer .payment-icons--scroll::-webkit-scrollbar {
    display: none;
  }
}

/* ═══════════════════════════════════════════════════════════════════
   §17 — ANTI-FLASH BLANC inter-pages — fallback navigateurs anciens
   -----------------------------------------------------------------
   La solution principale est le `@view-transition` ajouté à style.css
   (Phase 6.2) qui élimine totalement le flash sur Chrome 126+ /
   Safari 18+. Cette section §17 est le FILET pour les navigateurs
   plus anciens : background defensive + body fade-in subtle pour
   masquer la transition brute entre pages.

   Pas de !important ici sauf sur les propriétés critiques pour
   éviter les bagarres avec body{background} customisé par page.
   ═══════════════════════════════════════════════════════════════════ */

/* ─── 17.1 Background defensive html (filet anti-flash) ──────────
   Si pour une raison X le boot block <style> en <head> n'a pas eu
   le temps de s'appliquer (cache, network slow), on garantit qu'au
   moins html a un background-color défini. */
/* [GLOBAL-PAGE-FLASH-ROOT-CAUSE-08 2026-05-15] Correction valeurs dark mode.
   Les 3 valeurs blanches (#ffffff / #fffcfc / #F8F9FA en light) en dark
   mode forçaient html ET body en blanc en mode sombre + OS sombre, ce qui
   causait le flash blanc inter-pages. Le traceur a confirmé que la page
   d'arrivée a `html.dark + data-tu-theme="dark"` mais que cette règle
   tu-mobile-polish.css §17.1 et §17.3 écrasait le fond avec du blanc.
   Light par défaut aligné #F3EFE7 (lot 04). Dark mode = #0A0A0A cohérent. */
html {
  background-color: #F3EFE7;
}
@media (prefers-color-scheme: dark) {
  html:not([data-tu-theme="light"]) {
    background-color: #0A0A0A;
  }
}
html.dark,
html[data-tu-theme="dark"] {
  background-color: #0A0A0A;
}

/* ─── 17.2 Body fade-in subtle — navigateurs sans view-transitions
   Sur Firefox / Chrome <126 / Safari <18, les view-transitions ne
   marchent pas. On joue une micro-animation fade pour adoucir la
   première peinture du body (masque le brief flash inter-pages).
   Désactivé si view-transitions actives (le browser gère mieux). */
@supports not (view-transition-name: a) {
  body {
    animation: tu-page-fade-in 240ms cubic-bezier(0.22, 0.61, 0.36, 1) both;
  }
  @keyframes tu-page-fade-in {
    from { opacity: 0; }
    to   { opacity: 1; }
  }
}

/* Reduced motion : désactive le fade pour les utilisateurs sensibles */
@media (prefers-reduced-motion: reduce) {
  body {
    animation: none !important;
  }
}

/* ─── 17.3 Empêcher tout body { background: white } résiduel ─────
   Certains CSS de page (login.css, signup.css) posent
   body { background: var(--light-bg) }. C'est correct en light mode,
   mais en dark mode il faut s'assurer que ces overrides ne reviennent
   pas par-dessus html.dark body { bg: #0A0A0A } (style.css §6.1). */
html.dark body,
html[data-tu-theme="dark"] body {
  background-color: #0A0A0A;
}
/* [GLOBAL-PAGE-FLASH-ROOT-CAUSE-08 2026-05-15] #fffcfc (presque-blanc) en
   dark OS était un bug : body devenait clair en dark mode quand OS dark.
   Corrigé à #0A0A0A pour cohérence avec le reste du dark mode. */
@media (prefers-color-scheme: dark) {
  html:not([data-tu-theme="light"]) body {
    background-color: #0A0A0A;
  }
}

/* ═══════════════════════════════════════════════════════════════════
   §18 — ICÔNES RONDES HARMONISÉES MOBILE (≤ 768 px)
   -----------------------------------------------------------------
   Garantit que TOUS les conteneurs d'icônes BUTTON connus du site
   rendent un cercle parfait sur mobile. Couvre les cas d'ovales causés
   par : width ≠ height, padding asymétrique, line-height parasite,
   min-width/min-height conflictuels, flex mal centré.

   STRATÉGIE :
     - aspect-ratio: 1/1 → empêche tout ovale même si une dim seulement
       est définie ailleurs
     - border-radius: 50% !important → force le cercle (over toute cascade)
     - padding: 0 + flex centering → contenu centré sans déformation
     - SVG/img/i internes : flex-shrink:0 + max-width:60% → jamais étirés

   SCOPE STRICT : ne cible QUE les classes/IDs connus comme circulaires
   par design. AUCUN sélecteur générique type `button svg` ou `.icon`
   qui aurait cassé les boutons texte, pills, badges, payment-icons,
   logos, etc. Voir EXCLUSIONS ci-dessous.

   EXCLUSIONS EXPLICITES (NE doivent PAS être circulaires) :
     - .wishlist-btn-detail dans sticky CTA produit (square pill 12px, §14.13)
     - .password-toggle (rectangulaire dans input password)
     - .quantity-control button du produit-detail (transparent rect, §14.13)
     - .btn / .btn-primary / .btn-secondary / .add-to-cart-btn / .btn-next /
       .btn-checkout / .login-btn (boutons texte)
     - .tab-button (onglets)
     - .product-badge / .cart-badge / .badge (pills intentionnels)
     - .payment-icon / .payment-logo (logos rectangulaires)
   ═══════════════════════════════════════════════════════════════════ */

@media (max-width: 768px) {
  /* ─── 18.1 Force perfect circle sur conteneurs d'icônes BUTTON ─── */
  .nav-icon,
  .cart-icon,
  .dark-mode-btn,
  .burger-menu-btn,
  .wishlist-icon,
  .product-wishlist,
  .btn-wishlist,
  .scroll-to-top,
  .back-to-top,
  #scroll-top-btn,
  .tu-fab,
  .gallery-nav-btn,
  .zoom-icon,
  .close-mini-cart,
  .modal-close,
  .popup-close,
  .lightbox-close,
  .lightbox-prev,
  .lightbox-next,
  .tu-modal-close,
  .qty-btn,
  .tu-icon-circle {
    /* aspect-ratio 1/1 : si seule width OU height est définie, l'autre est
       calculée pour matcher → impossible d'avoir un ovale par négligence. */
    aspect-ratio: 1 / 1 !important;
    border-radius: 50% !important;
    box-sizing: border-box !important;
    /* Centrage parfait du SVG/i/img interne via flexbox */
    display: inline-flex !important;
    align-items: center !important;
    justify-content: center !important;
    /* Reset des sources d'asymétrie visuelle */
    padding: 0 !important;
    line-height: 1 !important;
    text-align: center;
    /* Anti déformation par overflow d'un contenu inattendu */
    overflow: hidden;
  }

  /* ─── 18.2 SVG / icône / image interne — centrés, jamais étirés ── */
  .nav-icon > :is(svg, i, img),
  .cart-icon > :is(svg, i, img),
  .dark-mode-btn > :is(svg, i, img),
  .burger-menu-btn > :is(svg, i, img),
  .wishlist-icon > :is(svg, i, img),
  .product-wishlist > :is(svg, i, img),
  .btn-wishlist > :is(svg, i, img),
  .scroll-to-top > :is(svg, i, img),
  .back-to-top > :is(svg, i, img),
  #scroll-top-btn > :is(svg, i, img),
  .tu-fab > :is(svg, i, img),
  .gallery-nav-btn > :is(svg, i, img),
  .zoom-icon > :is(svg, i, img),
  .close-mini-cart > :is(svg, i, img),
  .modal-close > :is(svg, i, img),
  .popup-close > :is(svg, i, img),
  .lightbox-close > :is(svg, i, img),
  .lightbox-prev > :is(svg, i, img),
  .lightbox-next > :is(svg, i, img),
  .tu-modal-close > :is(svg, i, img),
  .qty-btn > :is(svg, i, img),
  .tu-icon-circle > :is(svg, i, img) {
    flex-shrink: 0;
    line-height: 1;
    /* Plafond pour éviter qu'un SVG sans dimensions internes n'occupe
       toute la surface du cercle (rappel anti-géant tour 1) */
    max-width: 60%;
    max-height: 60%;
    object-fit: contain;
    vertical-align: middle;
  }

  /* ─── 18.3 Lightbox prev/next — taille touch minimum ──────────── */
  .lightbox-prev,
  .lightbox-next {
    min-width: 44px !important;
    min-height: 44px !important;
  }

  /* ─── 18.4 Cart badge — reste pilule ovale (intentionnel) ──────
   .cart-badge est un compteur numérique en pill — ne doit PAS être
   forcé en cercle 1:1 (perdrait sa lisibilité avec >9 items). */
  .cart-badge,
  .product-badge,
  .badge,
  .tu-badge {
    aspect-ratio: auto !important;
  }

  /* ─── 18.5 EXCLUSIONS — réaffirme les square pills intentionnels
   Si §18.1 par erreur de spécificité touche un de ces éléments,
   on ré-impose le radius square. */
  main.product-detail-page .product-actions .wishlist-btn-detail {
    aspect-ratio: auto !important;
    border-radius: 12px !important;
  }
  .password-toggle {
    aspect-ratio: auto !important;
    border-radius: 8px !important;
  }
  /* Quantity-control buttons dans le sticky CTA produit (§14.13) restent
     transparents et rectangulaires — déjà couvert par leur sélecteur 0,4,2 */
}

/* ═══════════════════════════════════════════════════════════════════
   §19 — RONDS RÉSIDUELS — Wishlist forte + Réassurance icon-pills
   -----------------------------------------------------------------
   §18 a couvert les conteneurs button standards. §19 cible deux cas
   spécifiquement signalés comme encore "ovales / non ronds" :

   CAS A — .product-wishlist sur les CARDS de listing (index, produits,
   recherche, catalogues Streetwear/Tropical/Chic Urbain/Classique).
   Cause potentielle d'écart : style.css ligne 3473 a `border-radius: 999px`
   (qui rend rond mais peut être perçu comme pill si le ratio n'est pas
   exactement 1:1). On RÉAFFIRME le cercle avec spécificité plus haute
   et !important explicite sur w/h pour neutraliser tout override.

   CAS B — Icônes des blocs de réassurance (Livraison, Paiement,
   Retours, Service client). Actuellement ce sont des <i> FontAwesome
   bruts SANS conteneur circulaire. Pour répondre à la demande "icônes
   rondes", on les habille d'un fond circulaire premium.
   ═══════════════════════════════════════════════════════════════════ */

@media (max-width: 768px) {

  /* ─── 19.1 WISHLIST sur product-cards : cercle absolu garanti ──── */
  /* Spécificité montée à (0,2,1) via `body .product-wishlist`
     pour battre style.css `.product-wishlist` (0,1,0). w/h forcés
     identiques. border-radius 50% (pas 999px) pour éviter toute
     ambiguïté sur très petits écrans.
     PAS de @media imbriqué (CSS Nesting non supporté universellement
     en 2026). Le bloc ≤480px est posé séparément hors de ce bloc. */
  body .product-wishlist,
  body .btn-wishlist,
  body .wishlist-icon,
  body button.product-wishlist,
  body button.btn-wishlist {
    width: 38px !important;
    height: 38px !important;
    aspect-ratio: 1 / 1 !important;
    border-radius: 50% !important;
    padding: 0 !important;
    display: inline-flex !important;
    align-items: center !important;
    justify-content: center !important;
    line-height: 1 !important;
    box-sizing: border-box !important;
  }
  /* Icône <i> interne : taille raisonnable, vraiment centrée */
  body .product-wishlist > i,
  body .btn-wishlist > i,
  body .wishlist-icon > i {
    font-size: 15px !important;
    line-height: 1 !important;
    width: auto !important;
    height: auto !important;
    max-width: none !important;
    max-height: none !important;
  }

  /* ─── 19.2 RÉASSURANCE ICONS — cercle premium autour des glyphes ─
   Pattern visible sur produit-detail.html (.reassurance-block .reassurance-item i)
   et potentiellement sur d'autres pages avec des blocs avantages.
   On habille le <i> FontAwesome d'un fond circulaire vert primary
   light pour cohérence avec la DA Tropical Urban. */

  /* Cible : tout <i> qui est ENFANT DIRECT d'un .reassurance-item, .feature-item,
     ou .benefit-item (patterns courants de blocs avantages e-commerce) */
  .reassurance-item > i,
  .reassurance-item > .reassurance-icon,
  .reassurance-item > svg,
  .feature-item > i,
  .feature-item > .feature-icon,
  .feature-item > svg,
  .benefit-item > i,
  .benefit-item > .benefit-icon,
  .benefit-item > svg,
  .advantage-item > i,
  .advantage-item > svg {
    /* Cercle premium : 44×44 vert primary 8% / bordure 18% */
    width: 44px !important;
    height: 44px !important;
    aspect-ratio: 1 / 1 !important;
    border-radius: 50% !important;
    background: rgba(46, 204, 113, 0.10) !important;
    border: 1px solid rgba(46, 204, 113, 0.20) !important;
    display: inline-flex !important;
    align-items: center !important;
    justify-content: center !important;
    box-sizing: border-box !important;
    color: var(--primary-color, #1E8449) !important;
    font-size: 1.1rem !important;
    line-height: 1 !important;
    margin: 0 auto 6px !important;
    padding: 0 !important;
    flex-shrink: 0 !important;
  }
  body.dark-mode .reassurance-item > i,
  body.dark-mode .feature-item > i,
  body.dark-mode .benefit-item > i,
  body.dark-mode .advantage-item > i {
    background: rgba(46, 204, 113, 0.16) !important;
    border-color: rgba(46, 204, 113, 0.28) !important;
    color: #5ED480 !important;
  }
  /* SVG interne (rare mais possible) — assure qu'il reste contenu */
  .reassurance-item > svg,
  .feature-item > svg,
  .benefit-item > svg {
    padding: 10px !important;
  }

  /* ─── 19.3 RÉASSURANCE — sur produit-detail, les items ont déjà
   un styling pill (§14.10). On réaffirme juste le cercle pour l'icône
   sans toucher au pill du conteneur. */
  main.product-detail-page .reassurance-block .reassurance-item > i {
    /* Hérite de §19.2 — cercle 44×44 vert primary. La pill du
       container (§14.10) reste inchangée (border-radius:12px). */
    margin: 0 auto 4px !important;
  }

  /* ─── 19.4 EXCLUSIONS — éviter de casser les zones intentionnellement
   non-circulaires qui pourraient matcher les sélecteurs ci-dessus. */

  /* Si un .reassurance-item a un texte INLINE avec icône (pas dans une
     card avec icône au-dessus), on ne veut pas circulariser l'icône. */
  /* Cible le pattern : <span class="reassurance-item"><i>...</i> Texte</span>
     vs <div class="reassurance-item"><i>...</i><span>Titre</span><small>...</small></div>
     Le 1er n'a pas .reassurance-item comme div bloc → on cible seulement
     les .reassurance-item ayant flex-direction:column ou un span enfant. */
  .reassurance-item:not(:has(> span:not([class])))  > i {
    /* Heuristic : si pas de span enfant texte, garde le glyphe inline */
    /* (no-op safety, le rule §19.2 est plus spécifique de toute façon) */
  }
}

/* §19.1 bis — Wishlist ≤480 px (flat @media, pas de nesting CSS) */
@media (max-width: 480px) {
  body .product-wishlist,
  body .btn-wishlist,
  body .wishlist-icon,
  body button.product-wishlist,
  body button.btn-wishlist {
    width: 34px !important;
    height: 34px !important;
    aspect-ratio: 1 / 1 !important;
    border-radius: 50% !important;
    padding: 0 !important;
    display: inline-flex !important;
    align-items: center !important;
    justify-content: center !important;
    line-height: 1 !important;
    box-sizing: border-box !important;
  }
}

/* ═══════════════════════════════════════════════════════════════════
   §20. INDEX.HTML HOME MOBILE POLISH (fusionné le 2026-05-02)
   -------------------------------------------------------------------
   Origine : ex-fichier css/tu-mobile-polish-home-additive.css fusionné
            ici après validation utilisateur sur 5 résolutions :
              ✅ 320×568 (iPhone SE 1)
              ✅ 360×800 (Galaxy S20)
              ✅ 375×667 (iPhone SE 2/3)
              ✅ 390×844 (iPhone 12/13/14)
              ✅ 768×1024 (iPad Mini)
   Scope :  body.home-page (presque tout) + 1 bloc burger dropdown
            global strictement justifié (overflow vertical iOS Safari).
   ═══════════════════════════════════════════════════════════════════ */

/* WHY: nouveaux tokens locaux uniquement (NE redéfinit PAS --tu-touch,
   --tu-touch-lg, --tu-safe-bottom déjà exposés par responsive-premium.css §0). */
:root {
  --tu-mp-radius: 14px;
  --tu-mp-radius-sm: 10px;
}

/* §20.1) BREAKPOINT GLOBAL — max-width: 768px ============================ */
@media (max-width: 768px) {

  /* ---------- Burger dropdown (SEULE règle gardée en GLOBAL) ----------
     WHY: amélioration utile sur TOUTES les pages (le menu burger est
     dans le header partagé). Pas dans tu-mobile-polish.css §1-19 ni
     dans header-premium.css. La 100dvh évite la coupure du dernier
     item sur iOS Safari quand la barre URL est visible. Aucune autre
     règle ne sort du scope body.home-page. */
  #burger-dropdown,
  .dropdown-content {
    max-width: calc(100vw - 16px);
    max-height: calc(100vh - 80px);
    max-height: calc(100dvh - 80px);
    overflow-y: auto;
    overscroll-behavior: contain;
    -webkit-overflow-scrolling: touch;
    box-sizing: border-box;
  }
  #burger-dropdown .dropdown-section h4,
  .dropdown-content .dropdown-section h4 {
    font-size: 13px;
    margin-bottom: 6px;
  }
  #burger-dropdown .dropdown-section a,
  .dropdown-content .dropdown-section a {
    padding: 12px 14px;
    font-size: 14px;
    line-height: 1.3;
  }

  /* ---------- Hero (priorité 1) ---------- */
  body.home-page .hero {
    min-height: 78vh;
    min-height: 78dvh;
    padding: 80px 16px 60px;
    text-align: center;
  }
  body.home-page .hero-content {
    width: 100%;
    max-width: 560px;
    margin: 0 auto;
  }
  body.home-page .hero-eyebrow {
    font-size: 11px;
    letter-spacing: 1.5px;
    gap: 8px;
  }
  body.home-page .hero-title {
    font-size: clamp(40px, 11vw, 64px);
    line-height: 1.05;
    margin-bottom: 14px;
    text-wrap: balance;
  }
  body.home-page .hero-subtitle {
    font-size: 15px;
    line-height: 1.55;
    max-width: 36ch;
    margin: 0 auto 22px;
    text-wrap: pretty;
  }
  body.home-page .hero-actions {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: 10px;
    width: 100%;
    max-width: 320px;
    margin: 0 auto 22px;
  }
  body.home-page .hero-actions .btn,
  body.home-page .hero-actions .btn-hero {
    width: 100%;
    min-height: var(--tu-touch-lg);
    justify-content: center;
  }
  body.home-page .hero-meta {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    align-items: center;
    gap: 8px 12px;
    font-size: 12px;
    line-height: 1.4;
    max-width: 100%;
  }
  body.home-page .hero-meta > span:not(.dot) {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    white-space: nowrap;
  }
  body.home-page .hero-meta .dot {
    opacity: .5;
  }

  /* ---------- Features (priorité 3) ---------- */
  body.home-page .features-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 14px;
  }
  body.home-page .feature-card {
    padding: 22px 16px;
    border-radius: var(--tu-mp-radius);
    text-align: center;
  }
  body.home-page .feature-card h3 {
    font-size: 15px;
    line-height: 1.3;
    margin: 10px 0 6px;
  }
  body.home-page .feature-card p {
    font-size: 13px;
    line-height: 1.45;
    margin: 0;
  }
  body.home-page .feature-icon {
    font-size: 26px;
  }

  /* ---------- Section headers (scope home : .section-* utilisé aussi
     sur account.html / a-propos.html — on ne touche PAS hors home) */
  body.home-page .section-header {
    margin-bottom: 24px;
    padding: 0 4px;
  }
  body.home-page .section-title {
    font-size: clamp(26px, 7vw, 36px);
    line-height: 1.15;
    text-wrap: balance;
  }
  body.home-page .section-subtitle {
    font-size: 14px;
    line-height: 1.55;
    text-wrap: pretty;
  }
  body.home-page .h-chapter {
    font-size: 11px;
    letter-spacing: 1.5px;
  }

  /* ---------- Produits (priorité 4) ----------
     CRITIQUE : .product-card est utilisé sur 19 pages live (produit-detail,
     produits, vip/*, Tropical, Streetwear, Classique, Chic Urbain,
     recherche, search-results, account, etc.). On scope strictement
     body.home-page pour ne JAMAIS toucher aux autres catalogues. */
  body.home-page .products-grid,
  body.home-page #featured-products-grid,
  body.home-page #bestsellers-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 14px;
  }
  body.home-page .product-card {
    border-radius: var(--tu-mp-radius);
    overflow: hidden;
    position: relative;
    display: flex;
    flex-direction: column;
  }
  body.home-page .product-card img,
  body.home-page .product-card .product-image,
  body.home-page .product-card .product-image img {
    aspect-ratio: 1 / 1;
    width: 100%;
    height: auto;
    object-fit: cover;
    display: block;
  }
  body.home-page .product-card .product-name,
  body.home-page .product-card .product-title,
  body.home-page .product-card h3 {
    font-size: 14px;
    line-height: 1.35;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
    min-height: calc(2 * 1.35em);
    margin: 8px 0 4px;
  }
  body.home-page .product-card .product-price,
  body.home-page .product-card .price {
    font-size: 15px;
    font-weight: 700;
  }
  body.home-page .product-card .product-badge,
  body.home-page .product-card .badge {
    top: 8px;
    left: 8px;
    right: auto;
    font-size: 11px;
    padding: 4px 8px;
    z-index: 2;
  }
  body.home-page .product-card .product-wishlist,
  body.home-page .product-card .wishlist-btn {
    top: 8px;
    right: 8px;
    left: auto;
    width: var(--tu-touch);
    height: var(--tu-touch);
    border-radius: 999px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    z-index: 3;
  }
  body.home-page .product-card .btn-add-to-cart,
  body.home-page .product-card .add-to-cart,
  body.home-page .product-card .btn-add {
    min-height: var(--tu-touch);
    width: 100%;
    border-radius: var(--tu-mp-radius-sm);
    font-size: 13px;
    font-weight: 600;
    padding: 0 12px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
  }
  body.home-page .product-card .product-info,
  body.home-page .product-card .product-content {
    padding: 10px 12px 12px;
    display: flex;
    flex-direction: column;
    gap: 4px;
  }

  /* ---------- Univers (priorité 5) ---------- */
  body.home-page .universe-grid {
    grid-template-columns: 1fr;
    gap: 24px;
  }
  body.home-page .universe-text {
    text-align: center;
  }
  body.home-page .universe-text h2 {
    font-size: clamp(28px, 7.5vw, 40px);
    line-height: 1.15;
  }
  body.home-page .universe-pillars {
    display: flex;
    flex-direction: column;
    gap: 12px;
  }
  body.home-page .universe-pillar {
    display: flex;
    align-items: flex-start;
    gap: 14px;
    padding: 16px;
    border-radius: var(--tu-mp-radius);
  }
  body.home-page .universe-pillar-icon {
    flex: 0 0 auto;
    width: 44px;
    height: 44px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: 999px;
    font-size: 18px;
  }
  body.home-page .universe-pillar h4 {
    font-size: 15px;
    margin: 0 0 4px;
  }
  body.home-page .universe-pillar p {
    font-size: 13.5px;
    line-height: 1.5;
    margin: 0;
  }

  /* ---------- Collections (priorité 6) ---------- */
  body.home-page .collections-grid {
    grid-template-columns: 1fr;
    gap: 16px;
  }
  body.home-page .collection-card {
    height: 320px;
    border-radius: var(--tu-mp-radius);
    overflow: hidden;
    position: relative;
    display: block;
  }
  body.home-page .collection-card .collection-bg {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
  }
  body.home-page .collection-content {
    padding: 18px;
  }
  body.home-page .collection-title {
    font-size: 22px;
    line-height: 1.2;
    margin: 0 0 6px;
  }
  body.home-page .collection-description {
    font-size: 13.5px;
    line-height: 1.45;
    margin: 0 0 12px;
  }
  body.home-page .collection-card .btn-outline-white {
    min-height: var(--tu-touch);
    padding: 0 18px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
  }

  /* ---------- Testimonials (priorité 7) ---------- */
  body.home-page .testimonials-grid {
    grid-template-columns: 1fr;
    gap: 14px;
  }
  body.home-page .testimonials-grid .testimonial-card {
    padding: 18px 16px;
    border-radius: var(--tu-mp-radius);
    box-sizing: border-box;
    width: 100%;
    max-width: 100%;
  }
  /* WHY: les styles inline générés par le JS index.html (l. 600+) imposent
     min-height: 60px et line-height inline → spécificité plus haute que
     classe. !important est la SEULE manière propre d'override mobile. */
  body.home-page .testimonials-grid .testimonial-card .testimonial-text {
    line-height: 1.6 !important;
    min-height: 0 !important;
  }
  body.home-page .testimonials-grid .testimonial-card .testimonial-author {
    flex-wrap: wrap;
    row-gap: 4px;
  }
  /* WHY: trust bar — les inline styles JS (l. 408+) imposent padding
     12px 28px et gap 12px → !important sur cibles mobile. */
  body.home-page #tu-trust-bar > div {
    flex-wrap: wrap;
    justify-content: center;
    padding: 10px 16px !important;
    gap: 8px !important;
  }

  /* ---------- Instagram ---------- */
  body.home-page .instagram-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 8px;
  }
  body.home-page .instagram-post {
    border-radius: var(--tu-mp-radius-sm);
    overflow: hidden;
  }
  body.home-page .instagram-post img {
    width: 100%;
    height: 100%;
    aspect-ratio: 1 / 1;
    object-fit: cover;
  }

  /* ---------- CTA Final ---------- */
  body.home-page .home-final-cta {
    padding: 56px 16px;
    text-align: center;
  }
  body.home-page .home-final-cta h2 {
    font-size: clamp(28px, 8vw, 42px);
    line-height: 1.15;
  }
  body.home-page .home-final-cta p {
    font-size: 15px;
    line-height: 1.55;
    max-width: 40ch;
    margin: 12px auto 22px;
  }
  body.home-page .cta-actions {
    display: flex;
    flex-direction: column;
    gap: 10px;
    align-items: stretch;
    max-width: 320px;
    margin: 0 auto;
  }
  body.home-page .cta-actions .btn {
    min-height: var(--tu-touch-lg);
    justify-content: center;
  }

  /* ---------- Newsletter (scope home : about.html utilise aussi
     .newsletter ; le §7 de tu-mobile-polish gère déjà la version
     site-wide, on ne l'écrase pas hors home) ---------- */
  body.home-page .newsletter {
    padding: 48px 16px;
  }
  body.home-page .newsletter-form {
    display: flex;
    flex-direction: column;
    gap: 10px;
    width: 100%;
    max-width: 360px;
    margin: 16px auto 0;
  }
  body.home-page .newsletter-form input,
  body.home-page .newsletter-form button {
    width: 100%;
    min-height: var(--tu-touch-lg);
    box-sizing: border-box;
  }

  /* ---------- Footer (priorité 8) ----------
     Scope home : §16.1-16.5 ci-dessus reste source de vérité site-wide.
     On ne fait qu'ajouter une variante 1 col stricte pour la home. */
  body.home-page .footer {
    padding-bottom: calc(32px + var(--tu-safe-bottom));
  }
  body.home-page .footer-grid {
    grid-template-columns: 1fr;
    gap: 24px;
    text-align: left;
  }
  body.home-page .footer-column h3 {
    font-size: 15px;
    margin-bottom: 10px;
  }
  body.home-page .footer-column ul {
    display: flex;
    flex-direction: column;
    gap: 4px;
  }
  body.home-page .footer-column a {
    display: inline-flex;
    align-items: center;
    min-height: 36px;
    font-size: 14px;
    line-height: 1.4;
  }
  body.home-page .social-links {
    display: flex;
    gap: 10px;
    flex-wrap: wrap;
  }
  body.home-page .social-links a {
    width: var(--tu-touch);
    height: var(--tu-touch);
    border-radius: 999px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 16px;
  }
  body.home-page .payment-methods {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin-top: 14px;
  }
  body.home-page .payment-icon {
    height: 22px;
    width: auto;
  }
  body.home-page .footer-bottom {
    margin-top: 24px;
    padding-top: 16px;
    text-align: center;
    font-size: 12px;
    line-height: 1.5;
  }
  body.home-page .tu-brand-tagline {
    display: block;
    margin-top: 4px;
    opacity: .8;
  }

  /* ---------- Welcome popup (priorité 9) — exclusif index.html ---------- */
  body.home-page .welcome-modal-container {
    width: calc(100vw - 24px);
    max-width: 460px;
    max-height: calc(100dvh - 24px);
    overflow-y: auto;
    overscroll-behavior: contain;
    -webkit-overflow-scrolling: touch;
    border-radius: var(--tu-mp-radius);
  }
  body.home-page .welcome-modal-content {
    display: flex;
    flex-direction: column;
  }
  body.home-page .welcome-modal-image {
    width: 100%;
    aspect-ratio: 16 / 9;
    max-height: 200px;
    overflow: hidden;
  }
  body.home-page .welcome-modal-image .image-frame,
  body.home-page .welcome-modal-image .modal-image {
    width: 100%;
    height: 100%;
    object-fit: cover;
  }
  body.home-page .welcome-modal-body {
    padding: 20px 18px calc(20px + var(--tu-safe-bottom));
  }
  body.home-page .welcome-modal-title {
    font-size: 26px;
    line-height: 1.1;
    margin: 0 0 8px;
  }
  body.home-page .welcome-modal-intro .intro-main {
    font-size: 14px;
    line-height: 1.55;
  }
  body.home-page .welcome-modal-intro .intro-sub {
    font-size: 13px;
    line-height: 1.5;
  }
  body.home-page .welcome-badges {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 8px;
    margin: 14px 0;
  }
  body.home-page .welcome-badge {
    padding: 10px 6px;
    text-align: center;
  }
  body.home-page .welcome-badge .badge-number {
    font-size: 16px;
  }
  body.home-page .welcome-badge .badge-label {
    font-size: 10.5px;
    line-height: 1.3;
  }
  body.home-page .welcome-modal-btn {
    width: 100%;
    min-height: var(--tu-touch-lg);
    font-size: 14px;
    padding: 0 16px;
    margin-top: 8px;
  }
  body.home-page .welcome-modal-perks {
    display: flex;
    flex-direction: column;
    gap: 6px;
    margin-top: 14px;
  }
  body.home-page .welcome-modal-perks .perk {
    font-size: 13px;
    line-height: 1.4;
  }
  body.home-page .welcome-modal-close {
    width: var(--tu-touch);
    height: var(--tu-touch);
    top: 8px;
    right: 8px;
    z-index: 5;
  }

  /* ---------- Payment failed modal (exclusif index.html) ---------- */
  body.home-page .payment-failed-modal {
    width: calc(100vw - 24px);
    max-width: 420px;
    max-height: calc(100dvh - 24px);
    overflow-y: auto;
  }
  body.home-page .payment-failed-actions {
    display: flex;
    flex-direction: column;
    gap: 8px;
  }
  body.home-page .payment-failed-actions .btn {
    width: 100%;
    min-height: var(--tu-touch-lg);
    justify-content: center;
  }

  /* ---------- Mini-cart : SKIP volontaire — déjà géré par §11
     ci-dessus. Aucune règle ici pour éviter un double-application
     qui casserait le drawer iOS-safe. ---------- */
}

/* §20.2) BREAKPOINT — max-width: 480px (scope home) ====================== */
@media (max-width: 480px) {
  body.home-page .hero {
    padding: 70px 14px 50px;
    min-height: 72vh;
    min-height: 72dvh;
  }
  body.home-page .hero-title { font-size: clamp(36px, 12vw, 56px); }
  body.home-page .hero-subtitle { font-size: 14.5px; }
  body.home-page .hero-meta { font-size: 11.5px; gap: 6px 10px; }

  body.home-page .features-grid { gap: 10px; }
  body.home-page .feature-card { padding: 18px 12px; }
  body.home-page .feature-card h3 { font-size: 14px; }
  body.home-page .feature-card p { font-size: 12.5px; }

  body.home-page .products-grid,
  body.home-page #featured-products-grid,
  body.home-page #bestsellers-grid { gap: 10px; }
  body.home-page .product-card .product-info,
  body.home-page .product-card .product-content { padding: 8px 10px 10px; }
  body.home-page .product-card .btn-add-to-cart,
  body.home-page .product-card .add-to-cart { font-size: 12.5px; }

  body.home-page .section-title { font-size: clamp(24px, 7.5vw, 32px); }
  body.home-page .collection-card { height: 280px; }
  body.home-page .instagram-grid { gap: 6px; }
  body.home-page .payment-icon { height: 20px; }

  body.home-page .welcome-badges { gap: 6px; }
  body.home-page .welcome-badge { padding: 8px 4px; }
  body.home-page .welcome-badge .badge-number { font-size: 15px; }
  body.home-page .welcome-badge .badge-label { font-size: 10px; }
}

/* §20.3) BREAKPOINT — max-width: 380px (iPhone SE / Galaxy Fold, scope home) === */
@media (max-width: 380px) {
  body.home-page .hero-meta { flex-direction: column; gap: 6px; }
  body.home-page .hero-meta .dot { display: none; }
  body.home-page .hero { padding: 64px 12px 44px; }
  body.home-page .hero-title { font-size: clamp(32px, 13vw, 48px); }
  body.home-page .hero-subtitle { font-size: 14px; }
  body.home-page .hero-eyebrow { font-size: 10.5px; letter-spacing: 1px; }

  body.home-page .features-grid { grid-template-columns: 1fr; gap: 10px; }
  body.home-page .feature-card {
    display: flex;
    align-items: center;
    text-align: left;
    gap: 14px;
    padding: 14px 14px;
  }
  body.home-page .feature-card .feature-icon { flex: 0 0 auto; font-size: 22px; }
  body.home-page .feature-card h3 { margin: 0 0 2px; }
  body.home-page .feature-card p { margin: 0; }

  body.home-page .products-grid,
  body.home-page #featured-products-grid,
  body.home-page #bestsellers-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 8px;
  }
  body.home-page .product-card .product-name,
  body.home-page .product-card .product-title,
  body.home-page .product-card h3 { font-size: 13px; }
  body.home-page .product-card .btn-add-to-cart {
    font-size: 12px;
    padding: 0 8px;
    min-height: var(--tu-touch);
  }

  body.home-page .section-title { font-size: clamp(22px, 8vw, 28px); }
  body.home-page .collection-card { height: 240px; }
  body.home-page .collection-title { font-size: 20px; }

  body.home-page .welcome-modal-body { padding: 16px 14px; }
  body.home-page .welcome-modal-title { font-size: 22px; }
  body.home-page .welcome-badges {
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 4px;
  }
  body.home-page .welcome-badge .badge-label { font-size: 9.5px; }

  body.home-page #tu-trust-bar > div { padding: 8px 12px !important; }
  body.home-page .payment-icon { height: 18px; }
  body.home-page .social-links a { width: 40px; height: 40px; }
}

/* §20.4) MOBILE PAYSAGE — max-height: 500px AND orientation: landscape ===== */
@media (max-height: 500px) and (orientation: landscape) {
  body.home-page .hero {
    min-height: auto;
    padding: 56px 16px 32px;
  }
  body.home-page .hero-title {
    font-size: clamp(28px, 6vw, 42px);
    margin-bottom: 8px;
  }
  body.home-page .hero-subtitle { font-size: 13.5px; margin-bottom: 14px; }
  body.home-page .hero-actions {
    flex-direction: row;
    max-width: 520px;
    gap: 10px;
  }
  body.home-page .hero-actions .btn,
  body.home-page .hero-actions .btn-hero { width: auto; flex: 1 1 0; }
  body.home-page .hero-meta {
    flex-direction: row;
    flex-wrap: wrap;
    gap: 6px 10px;
    font-size: 11.5px;
  }
  body.home-page .hero-meta .dot { display: inline-block; }
  body.home-page .hero-scroll { display: none; }

  body.home-page .welcome-modal-container {
    max-height: calc(100dvh - 16px);
    width: calc(100vw - 24px);
    max-width: 720px;
  }
  body.home-page .welcome-modal-content { flex-direction: row; }
  body.home-page .welcome-modal-image {
    width: 40%;
    max-height: none;
    aspect-ratio: auto;
    flex: 0 0 40%;
  }
  body.home-page .welcome-modal-body {
    flex: 1 1 60%;
    padding: 14px 16px;
    overflow-y: auto;
    max-height: calc(100dvh - 16px);
  }
  body.home-page .welcome-modal-title { font-size: 20px; margin-bottom: 4px; }
  body.home-page .welcome-modal-intro .intro-main { font-size: 13px; }
  body.home-page .welcome-modal-intro .intro-sub { font-size: 12.5px; }
  body.home-page .welcome-badges { margin: 8px 0; }
  body.home-page .welcome-modal-btn { margin-top: 4px; min-height: 44px; }
  body.home-page .welcome-modal-perks {
    flex-direction: row;
    flex-wrap: wrap;
    gap: 6px 12px;
  }
  body.home-page .welcome-modal-perks .perk { font-size: 12px; }
  body.home-page .modal-leaf { display: none; }
}

/* §20.5) DARK MODE — préservation des surfaces (scope home) ============== */
@media (max-width: 768px) {
  body.home-page.dark-mode .feature-card,
  html.dark body.home-page .feature-card,
  html[data-tu-theme="dark"] body.home-page .feature-card,
  body.home-page.dark-mode .universe-pillar,
  html.dark body.home-page .universe-pillar,
  html[data-tu-theme="dark"] body.home-page .universe-pillar,
  body.home-page.dark-mode .testimonials-grid .testimonial-card,
  html.dark body.home-page .testimonials-grid .testimonial-card,
  html[data-tu-theme="dark"] body.home-page .testimonials-grid .testimonial-card {
    background-color: var(--tu-bg, #1E1E1E);
    color: var(--tu-fg, #FFFFFF);
  }
}

/* §20.6) ACCESSIBILITÉ — reduced-motion (scope home) ===================== */
@media (max-width: 768px) and (prefers-reduced-motion: reduce) {
  body.home-page .testimonials-grid .testimonial-card { animation: none !important; }
}

/* §20.7) FIX-PACK — corrections après tests visuels (validés 2026-05-02) ==
   Suite aux tests utilisateur + validation finale des 5 résolutions :
     ✅ 320×568 / 360×800 / 375×667 / 390×844 / 768×1024
   ========================================================================= */

/* §20.7.1 FIX P1 — Features bloc équilibre à 390×844 ----------------------
   À 390px (entre 381 et 480), les .feature-card étaient déséquilibrées :
   - mon @media ≤480 mettait padding 18px 12px sans aligner verticalement
   - home.css ≤640 imposait .feature-icon 48×48 + 1.15rem
   → cards 2 col mais contenu mal équilibré, icônes disproportionnées vs
     largeur de carte ≈170px, hauteurs cards inégales.
   Solution : breakpoint chirurgical 381-480px qui reformate proprement. */
@media (min-width: 381px) and (max-width: 480px) {
  body.home-page .features-grid {
    align-items: stretch;             /* cards de même hauteur dans la grille */
  }
  body.home-page .feature-card {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: flex-start;
    gap: 8px;
    padding: 16px 10px;
    text-align: center;
    min-height: 0;
  }
  body.home-page .feature-card .feature-icon {
    width: 44px;
    height: 44px;
    font-size: 22px;
    margin: 0;
    flex: 0 0 auto;
  }
  body.home-page .feature-card h3 {
    font-size: 13.5px;
    line-height: 1.25;
    margin: 0;
  }
  body.home-page .feature-card p {
    font-size: 12px;
    line-height: 1.4;
    margin: 0;
  }
}

/* §20.7.2 FIX P2 v1 — Burger : garde défensive de visibilité --------------
   Garde générique sur ≤768 : empêche toute compression/masquage du burger
   par flex-shrink ou stacking context inattendu. Scope body.home-page. */
@media (max-width: 768px) {
  body.home-page header .dropdown-burger {
    display: inline-flex;
    flex: 0 0 auto;                   /* ne se comprime jamais */
    visibility: visible;
  }
  body.home-page header .burger-menu-btn {
    display: inline-flex !important;
    visibility: visible !important;
    opacity: 1 !important;
    flex: 0 0 auto;
    position: relative;
    z-index: 5;
  }
}

/* §20.7.3 FIX P3 — Dark-mode toggle visible à 768×1024 (iPad Mini) --------
   header-premium.css l. 499-505 masque #dark-mode-toggle à ≤768px. Sur
   iPad Mini portrait il y a la place de le garder. On le réactive entre
   700 et 768px. Scope body.home-page (preview historique). */
@media (max-width: 768px) and (min-width: 700px) {
  body.home-page header #dark-mode-toggle,
  body.home-page header .dark-mode-btn {
    display: inline-flex !important;
    align-items: center !important;
    justify-content: center !important;
  }
}

/* §20.7.4 FIX P2 v3 — Burger ET recherche tous deux visibles à 360 -------
   Le précédent essai v2 masquait la recherche pour libérer la place du
   burger. Refusé par l'utilisateur. v3 = compactage chirurgical des
   icônes + du logo à ≤480 puis ≤380 pour faire tenir LES 5 ÉLÉMENTS
   (logo + search + account + cart + burger) sans masquer aucun. */

/* (a) Couche ≤480 — anti-overflow + logo compressible */
@media (max-width: 480px) {
  body.home-page header .nav-actions {
    display: flex;
    flex-wrap: nowrap;
    flex-shrink: 0;
    min-width: 0;
    /* override le padding-inline-end safe-area parasite de header-premium.css
       ≤768. Android Galaxy S20 n'a pas d'encoche, on libère ces 2-3px. */
    padding-inline-end: 0 !important;
  }
  body.home-page header .nav-actions > * {
    flex-shrink: 0;                   /* icônes jamais comprimées */
  }
  body.home-page header .logo {
    flex-shrink: 1;                   /* logo se comprime au lieu de pousser */
    min-width: 0;
  }
  body.home-page header .nav-container {
    padding-left: clamp(8px, 2.5vw, 14px) !important;
    padding-right: clamp(8px, 2.5vw, 14px) !important;
  }
}

/* (b) Couche ≤380 — compactage 4 icônes + logo dans 320-375px */
@media (max-width: 380px) {
  body.home-page header .nav-container {
    padding-left: 8px !important;
    padding-right: 8px !important;
    gap: 4px !important;
  }
  body.home-page header .nav-actions {
    gap: 3px !important;
  }
  /* Icônes compactes 34×34. Sous Apple HIG 44px mais compromis nécessaire
     pour faire tenir 4 icônes + logo dans 320-375px. */
  body.home-page header .nav-icon,
  body.home-page header .cart-icon,
  body.home-page header .burger-menu-btn {
    width: 34px !important;
    height: 34px !important;
    min-width: 34px !important;
    font-size: 0.9rem !important;
    flex: 0 0 34px !important;
  }
  body.home-page header .dropdown-burger {
    flex: 0 0 auto !important;
  }
  body.home-page header .logo {
    font-size: 0.95rem !important;
    gap: 4px !important;
  }
  body.home-page header .logo img {
    width: 26px !important;
    height: 26px !important;
  }
  /* Garde Font Awesome : icônes internes burger + recherche toujours visibles */
  body.home-page header .burger-menu-btn > i,
  body.home-page header .burger-menu-btn > svg {
    display: inline-block !important;
    visibility: visible !important;
    opacity: 1 !important;
    font-size: 0.95rem !important;
    line-height: 1 !important;
  }
  body.home-page header .nav-actions > a[href="recherche.html"] > i,
  body.home-page header .nav-actions > a[href="recherche.html"] > svg {
    display: inline-block !important;
    visibility: visible !important;
    opacity: 1 !important;
    font-size: 0.95rem !important;
  }
}

/* §20.7.5 FIX P4 — Bouton hero "Explorer les collections" trop gros à 320 -
   Sur iPhone SE 1, le bouton primaire occupait quasi toute la largeur
   (.hero-actions max-width 320px). Réduction visuelle ≤340 uniquement. */
@media (max-width: 340px) {
  body.home-page .hero-actions {
    max-width: 260px;
  }
  body.home-page .hero-actions .btn,
  body.home-page .hero-actions .btn-hero,
  body.home-page .hero-actions .btn-hero--ghost {
    min-height: 44px;
    padding: 0 0.9rem;
    font-size: 0.85rem;
  }
}

/* ═══════════════════════════════════════════════════════════════════
   §21. SOCLE MOBILE GLOBAL (LOT 1) — extension site-wide des FIX validés
   -------------------------------------------------------------------
   Origine : règles du §20 (homepage) qui sont DOM-identiques sur toutes
            les pages publiques (header partagé, footer partagé) → on
            les desCOPE de body.home-page pour qu'elles s'appliquent
            partout.

   Vérification structurelle (audit du 2026-05-02, 21 pages testées) :
     - Header `<header>` + `<nav class="navbar">` + `.nav-container`
       + `.logo` + `.nav-links` + `.nav-actions` (search/account/cart/
       dark/burger) : présent à 100% sur 21 pages testées.
     - Footer `<footer class="footer">` + `.footer-grid` + `.footer-column`
       + `.payment-methods` : présent à 95%+ (sample 21 pages).
     - DIVERGENCE notée : account.html utilise `.burger-dropdown-content`
       au lieu de `.dropdown-content` → on cible `#burger-dropdown`
       (ID commun) pour rester compatible. La règle dropdown overflow
       du §20 (ID-based) couvre déjà account.html.

   Scope STRICT : header / footer / safe-area uniquement.
   PAS GLOBALISÉS (restent §20 home-page) :
     .product-card, .products-grid, .section-title, .btn, .feature-card,
     .container, .hero, .universe-*, .collections-*, .testimonials-*,
     .welcome-modal-*, .payment-failed-modal.
   ═══════════════════════════════════════════════════════════════════ */

/* §21.1) HEADER MOBILE ANTI-OVERFLOW + COMPACTAGE (≤480px / ≤380px) ===
   WHY: appliquer site-wide les FIX P2 v3 validés sur home (couches a+b).
        Garantit que les 5 icônes header (search, account, cart, dark,
        burger) tiennent dans 320-480px sans débordement, sur TOUTES
        les pages publiques. */
@media (max-width: 480px) {
  /* WHY: empêcher l'overflow horizontal de .nav-actions site-wide */
  header .nav-actions {
    display: flex;
    flex-wrap: nowrap;
    flex-shrink: 0;
    min-width: 0;
    /* override le padding-inline-end safe-area parasite (header-premium ≤768)
       sur Android (pas d'encoche) — libère 2-3px critiques à 360px */
    padding-inline-end: 0 !important;
  }
  /* WHY: icônes header jamais comprimées (display garde défensive) */
  header .nav-actions > * {
    flex-shrink: 0;
  }
  /* WHY: logo compressible plutôt que de pousser le burger hors écran */
  header .logo {
    flex-shrink: 1;
    min-width: 0;
  }
  /* WHY: padding nav-container raisonnable même à 360 */
  header .nav-container {
    padding-left: clamp(8px, 2.5vw, 14px) !important;
    padding-right: clamp(8px, 2.5vw, 14px) !important;
  }
}

@media (max-width: 380px) {
  /* WHY: compactage chirurgical pour 320 (iPhone SE 1) et 360 (Galaxy S20) */
  header .nav-container {
    padding-left: 8px !important;
    padding-right: 8px !important;
    gap: 4px !important;
  }
  header .nav-actions {
    gap: 3px !important;
  }
  /* WHY: icônes 34×34 (sous Apple HIG 44px mais nécessaire pour faire
     tenir 4-5 icônes + logo dans 320-375px). Touch reste OK via
     padding-inline-flex naturel + min-width. */
  header .nav-icon,
  header .cart-icon,
  header .burger-menu-btn {
    width: 34px !important;
    height: 34px !important;
    min-width: 34px !important;
    font-size: 0.9rem !important;
    flex: 0 0 34px !important;
  }
  header .dropdown-burger {
    flex: 0 0 auto !important;
  }
  /* WHY: logo compact pour libérer 30-40px aux icônes */
  header .logo {
    font-size: 0.95rem !important;
    gap: 4px !important;
  }
  header .logo img {
    width: 26px !important;
    height: 26px !important;
  }
  /* WHY: garde Font Awesome icônes interne burger + recherche (toutes pages) */
  header .burger-menu-btn > i,
  header .burger-menu-btn > svg {
    display: inline-block !important;
    visibility: visible !important;
    opacity: 1 !important;
    font-size: 0.95rem !important;
    line-height: 1 !important;
  }
  header .nav-actions > a[href="recherche.html"] > i,
  header .nav-actions > a[href="recherche.html"] > svg {
    display: inline-block !important;
    visibility: visible !important;
    opacity: 1 !important;
    font-size: 0.95rem !important;
  }
}

/* §21.2) BURGER GARDE DÉFENSIVE GLOBALE (≤768px) ======================
   WHY: garantir que le bouton burger reste cliquable site-wide,
        quelle que soit la cascade des CSS specifiques de chaque page.
        Identique au FIX P2 v1 du §20.7.2 mais désCOPÉ pour appliquer
        sur toutes les pages publiques (header partagé). */
@media (max-width: 768px) {
  header .dropdown-burger {
    display: inline-flex;
    flex: 0 0 auto;
    visibility: visible;
  }
  header .burger-menu-btn {
    display: inline-flex !important;
    visibility: visible !important;
    opacity: 1 !important;
    flex: 0 0 auto;
    position: relative;
    z-index: 5;
  }
}

/* §21.3) FOOTER MOBILE 1 COL + SAFE-AREA (≤768px) =====================
   WHY: footer DOM identique sur 100% des pages publiques testées
        (vérifié sur 21 pages). Le §16 du fichier original gère déjà
        les paiements icons et le centrage flex. Cette section ajoute
        le passage 1 col strict + le padding-bottom safe-area iPhone.
        Sélecteur `footer.footer` (avec tag + class) pour spécificité
        plus haute que `.footer` seul, sans risque sur autres footers
        hypothétiques. */
@media (max-width: 768px) {
  /* WHY: padding-bottom safe-area pour iPhone XS+ (notch + home indicator) */
  footer.footer {
    padding-bottom: calc(32px + var(--tu-safe-bottom));
  }
  /* WHY: 1 col strict (vs 4 col desktop) — site-wide propre */
  footer.footer .footer-grid {
    grid-template-columns: 1fr;
    gap: 24px;
    text-align: left;
  }
  footer.footer .footer-column h3 {
    font-size: 15px;
    margin-bottom: 10px;
  }
  footer.footer .footer-column ul {
    display: flex;
    flex-direction: column;
    gap: 4px;
  }
  /* WHY: liens footer min-height 36 pour touch (sous 44 mais lisible) */
  footer.footer .footer-column a {
    display: inline-flex;
    align-items: center;
    min-height: 36px;
    font-size: 14px;
    line-height: 1.4;
  }
  /* WHY: social-links 44×44 cercles (touch HIG strict) */
  footer.footer .social-links {
    display: flex;
    gap: 10px;
    flex-wrap: wrap;
  }
  footer.footer .social-links a {
    width: var(--tu-touch);
    height: var(--tu-touch);
    border-radius: 999px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 16px;
  }
  /* WHY: payment-methods wrap propre (déjà §16.3 mais sans 1col forcée) */
  footer.footer .payment-methods {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin-top: 14px;
  }
  footer.footer .footer-bottom {
    margin-top: 24px;
    padding-top: 16px;
    text-align: center;
    font-size: 12px;
    line-height: 1.5;
  }
  footer.footer .tu-brand-tagline {
    display: block;
    margin-top: 4px;
    opacity: .8;
  }
}

/* §21.4) PAYMENT-ICONS RESPONSIVE (≤480 / ≤380) =======================
   WHY: tailles déjà ajustées dans §16.3 du fichier mais on harmonise
        avec ce que le §20 a posé pour la home (22→20→18 px). */
@media (max-width: 480px) {
  footer.footer .payment-icon {
    height: 20px;
    width: auto;
  }
}
@media (max-width: 380px) {
  footer.footer .payment-icon {
    height: 18px;
  }
  footer.footer .social-links a {
    width: 40px;
    height: 40px;
  }
}

/* §21.5) DARK-MODE TOGGLE VISIBLE TABLETTE 700-768px (LOT 1 patch) ====
   CAUSE EXACTE :
     header-premium.css l. 499-505 fait :
       @media (max-width: 768px) {
         header #dark-mode-toggle,
         header .dark-mode-btn { display: none !important; }
       }
     C'est intentionnel pour gain de place mobile pur. Le FIX P3 §20.7.3
     a réactivé le toggle UNIQUEMENT sur body.home-page (scope preview).
     Apres LOT 1, les autres pages publiques (produits, cart, etc.)
     restent avec le toggle caché a 768x1024 (iPad Mini portrait) où
     il y a pourtant largement la place de l'afficher.

   SELECTEUR RESPONSABLE :
     header-premium.css : `header #dark-mode-toggle, header .dark-mode-btn`
     spécificité (0,1,0,1) avec !important.

   SOLUTION GLOBALE LOT 1 :
     Réactiver le toggle entre 700 et 768px sur TOUTES les pages
     publiques (header DOM identique partout). Limiter strictement a
     700-768px pour ne pas casser le mobile pur (≤699px) ou le toggle
     reste cache.

   SPECIFICITE / CASCADE :
     Mon override = (0,1,0,1) avec !important — spécificité égale.
     L'ordre source decide : tu-mobile-polish.css est injecté par
     global.js APRES header-premium.css → mon override gagne.

   IMPACT NUL sur les autres breakpoints :
     - ≤699 (mobile pur) : toggle reste cache (header-premium ≤768
       continue d'appliquer, on n'est pas dans 700-768).
     - >768 (desktop) : toggle deja visible (header-premium ne
       s'applique pas).
     - 700-768 (iPad Mini portrait, petites tablettes) : toggle visible. */
@media (max-width: 768px) and (min-width: 700px) {
  header #dark-mode-toggle,
  header .dark-mode-btn {
    display: inline-flex !important;
    align-items: center !important;
    justify-content: center !important;
  }
}

/* ═══════════════════════════════════════════════════════════════════
   FIN §21 SOCLE MOBILE GLOBAL (LOT 1)
   ═══════════════════════════════════════════════════════════════════ */

/* ═══════════════════════════════════════════════════════════════════
   §22. CATALOGUE MOBILE PRODUCT CARDS — LOT 2 MINIMAL
   -------------------------------------------------------------------
   Origine : audit comparatif 2026-05-02 + validation utilisateur Option A.
   Date application : 2026-05-02.

   Pages cibles (Pattern A scopées body class) — vérifié au moment de
   l'application :
     - produits.html       (body.catalogue-page    + #products-grid)
     - Tropical.html       (body.tropical-page     + #products-container)
     - Streetwear.html     (body.streetwear-page   + #products-container)
     - recherche.html      (body.recherche-page    + #search-results-grid)

   Pages EXCLUES (sécurité — vérifié) :
     - index.html          : déjà géré §20 (body.home-page)
     - search-results.html : pas de body class
     - Classique.html / Chic Urbain.html : Pattern B incompatible
     - produit-detail.html : recos Pattern D, déjà 15 règles produit-detail.css
     - vip/*.html          : Pattern C / structures différentes
     - cart, checkout, paiement, account : aucune body class match

   Stratégie cascade :
     - catalogue.css / tropical-premium.css / streetwear-premium.css /
       recherche-premium.css gèrent déjà ≤640 mobile (padding, font-size).
     - mon §22 ajoute la VALEUR AJOUTÉE manquante : aspect-ratio image
       1:1, line-clamp 2 nom produit, min-height 44px touch HIG, wishlist
       44px anti-chevauchement, border-radius cohérent --tu-mp-radius.
     - mes règles ciblent ≤480 et ≤380 (zones sans règles spécifiques
       à ces pages dans les CSS existants → enrichissement, pas conflit).
   ═══════════════════════════════════════════════════════════════════ */

/* §22.1) GRILLE 2 COL MOBILE (≤480px) ================================
   WHY: harmoniser la grille catalogue à 2 colonnes sur mobile.
        Les CSS pages ont déjà ≤640 mais à ≤480 on resserre encore le
        gap pour densifier proprement sans casser la lisibilité.
        IDs uniques par page, pas de risque de conflit cross-page. */
@media (max-width: 480px) {
  body.catalogue-page #products-grid,
  body.tropical-page #products-container,
  body.streetwear-page #products-container,
  body.recherche-page #search-results-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 12px;
  }
}

/* §22.2) PRODUCT-CARD CONTAINER (≤480px) =============================
   WHY: structure flex column + border-radius cohérent --tu-mp-radius +
        overflow contenu. Renforce le rendu premium sans toucher au
        padding existant des CSS pages (qui restent à ≤640 dans leur
        fichier). */
@media (max-width: 480px) {
  body.catalogue-page .product-card,
  body.tropical-page .product-card,
  body.streetwear-page .product-card,
  body.recherche-page .product-card {
    border-radius: var(--tu-mp-radius);
    overflow: hidden;
    position: relative;
    display: flex;
    flex-direction: column;
  }
}

/* §22.3) PRODUCT-IMAGE-WRAPPER + IMAGE ASPECT-RATIO 1:1 (≤480px) =====
   WHY: image carrée garantit cohérence visuelle mobile et évite le CLS
        (Cumulative Layout Shift). Manquant dans tous les CSS pages
        existants — pas une seule règle aspect-ratio sur .product-image.
        Aspect-ratio sur le wrapper ET sur l'image (double sécurité)
        pour éviter CLS si l'image n'a pas chargé encore. */
@media (max-width: 480px) {
  body.catalogue-page .product-image-wrapper,
  body.tropical-page .product-image-wrapper,
  body.streetwear-page .product-image-wrapper,
  body.recherche-page .product-image-wrapper {
    position: relative;
    overflow: hidden;
    aspect-ratio: 1 / 1;
  }
  body.catalogue-page .product-image,
  body.tropical-page .product-image,
  body.streetwear-page .product-image,
  body.recherche-page .product-image {
    aspect-ratio: 1 / 1;
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
  }
}

/* §22.4) PRODUCT-INFO PADDING MOBILE (≤480px) ========================
   WHY: padding mobile cohérent. Les CSS existants à ≤640 mettent
        0.85rem 0.85rem 1rem (≈13.6/13.6/16). À ≤480 on resserre à
        10/12/12 pour densifier. Cascade : mes règles ≤480 écrasent
        celles ≤640 par ordre source plus tardif. */
@media (max-width: 480px) {
  body.catalogue-page .product-info,
  body.tropical-page .product-info,
  body.streetwear-page .product-info,
  body.recherche-page .product-info {
    padding: 10px 12px 12px;
    display: flex;
    flex-direction: column;
    gap: 4px;
  }
}

/* §22.5) PRODUCT-NAME LINE-CLAMP 2 (≤480px) ==========================
   WHY: limite à 2 lignes pour hauteurs cards uniformes. Manquant dans
        TOUS les CSS pages — actuellement le nom peut wrapper sur 3-4
        lignes selon le produit, créant des cards inégales. min-height
        assure la stabilité layout même quand le nom est court. */
@media (max-width: 480px) {
  body.catalogue-page .product-name,
  body.tropical-page .product-name,
  body.streetwear-page .product-name,
  body.recherche-page .product-name {
    font-size: 14px;
    line-height: 1.35;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
    min-height: calc(2 * 1.35em);
    margin: 8px 0 4px;
  }
}

/* §22.6) PRODUCT-PRICE + CURRENT/ORIGINAL (≤480px) ===================
   WHY: hierarchie current-price (gros + bold) vs original-price
        (barré, plus petit, opacity réduite). Les CSS pages gèrent
        partiellement — ici on harmonise sur les 4 pages.
        flex-wrap garantit qu'à très petit écran les 2 prix peuvent
        passer en stack si nécessaire. */
@media (max-width: 480px) {
  body.catalogue-page .product-price,
  body.tropical-page .product-price,
  body.streetwear-page .product-price,
  body.recherche-page .product-price {
    display: flex;
    align-items: baseline;
    gap: 8px;
    flex-wrap: wrap;
    font-size: 15px;
    font-weight: 700;
  }
  body.catalogue-page .current-price,
  body.tropical-page .current-price,
  body.streetwear-page .current-price,
  body.recherche-page .current-price {
    font-size: 15px;
    font-weight: 700;
  }
  body.catalogue-page .original-price,
  body.tropical-page .original-price,
  body.streetwear-page .original-price,
  body.recherche-page .original-price {
    font-size: 12px;
    text-decoration: line-through;
    opacity: 0.6;
  }
}

/* §22.7) PRODUCT-BADGE POSITIONNEMENT GAUCHE (≤480px) ================
   WHY: badge gauche en haut, anti-chevauchement avec wishlist (qui
        ira à droite §22.8). Les CSS pages gèrent la couleur via
        .new/.promo modifiers — on assure ici uniquement le
        positionnement cohérent et la taille tactile. */
@media (max-width: 480px) {
  body.catalogue-page .product-badge,
  body.tropical-page .product-badge,
  body.streetwear-page .product-badge,
  body.recherche-page .product-badge {
    position: absolute;
    top: 8px;
    left: 8px;
    right: auto;
    font-size: 11px;
    padding: 4px 8px;
    z-index: 2;
  }
}

/* §22.8) PRODUCT-WISHLIST 44px ANTI-CHEVAUCHEMENT (≤480px) ===========
   WHY: SEULEMENT pour les 2 pages qui ont la wishlist dans le markup
        (catalogue + recherche). Tropical/Streetwear n'ont pas de
        wishlist dans leur template — on n'écrit AUCUNE règle pour eux
        pour éviter une affordance fantôme.
        Position droite (right:8px) garantit anti-chevauchement avec
        badge à gauche (§22.7). 44px = touch target Apple HIG strict. */
@media (max-width: 480px) {
  body.catalogue-page .product-wishlist,
  body.recherche-page .product-wishlist {
    position: absolute;
    top: 8px;
    right: 8px;
    left: auto;
    width: var(--tu-touch);
    height: var(--tu-touch);
    border-radius: 999px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    z-index: 3;
  }
}

/* §22.9) BTN-ADD-TO-CART 44PX TOUCH (≤480px) =========================
   WHY: bouton ajout panier touch HIG strict (--tu-touch=44px). Les CSS
        pages ont des padding et font-size à ≤640 mais AUCUN min-height
        explicite. Sans min-height, le bouton peut faire 30-35px selon
        le font-size, sous le seuil tactile. On garantit la zone
        cliquable minimum sans toucher au texte ni à la couleur. */
@media (max-width: 480px) {
  body.catalogue-page .btn-add-to-cart,
  body.tropical-page .btn-add-to-cart,
  body.streetwear-page .btn-add-to-cart,
  body.recherche-page .btn-add-to-cart {
    min-height: var(--tu-touch);
    width: 100%;
    border-radius: var(--tu-mp-radius-sm);
    font-size: 13px;
    font-weight: 600;
    padding: 0 12px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
  }
}

/* §22.10) RAFFINEMENTS ≤380px (iPhone SE 1, Galaxy Fold ouvert) ======
   WHY: serrage supplémentaire pour les très petits écrans : gap grid
        plus serré, padding info compact, font-size descendue, bouton
        légèrement réduit en font-size mais 44px touch préservé via
        min-height hérité du §22.9. */
@media (max-width: 380px) {
  body.catalogue-page #products-grid,
  body.tropical-page #products-container,
  body.streetwear-page #products-container,
  body.recherche-page #search-results-grid {
    gap: 8px;
  }
  body.catalogue-page .product-info,
  body.tropical-page .product-info,
  body.streetwear-page .product-info,
  body.recherche-page .product-info {
    padding: 8px 10px 10px;
  }
  body.catalogue-page .product-name,
  body.tropical-page .product-name,
  body.streetwear-page .product-name,
  body.recherche-page .product-name {
    font-size: 13px;
  }
  body.catalogue-page .btn-add-to-cart,
  body.tropical-page .btn-add-to-cart,
  body.streetwear-page .btn-add-to-cart,
  body.recherche-page .btn-add-to-cart {
    font-size: 12px;
    padding: 0 8px;
    /* min-height: var(--tu-touch) hérité du §22.9 — touch préservé */
  }
}

/* ═══════════════════════════════════════════════════════════════════
   FIN §22 CATALOGUE MOBILE PRODUCT CARDS — LOT 2 MINIMAL
   ═══════════════════════════════════════════════════════════════════ */

/* ═══════════════════════════════════════════════════════════════════
   §23. POLISH MOBILE CIBLÉ — 4 PAGES (produits / recherche / Tropical / Streetwear)
   -------------------------------------------------------------------
   Date : 2026-05-02. Application directe (pas de preview).
   Objectifs ciblés par page :
     - produits.html @ 360×800   : zone filtres/tri plus propre, tabs scrollables
     - recherche.html @ 360×800  : hero centré + toggle mobile filtres (CSS+JS)
     - Tropical.html @ 390×844   : stats allégées + chips peaufinées
     - Streetwear.html @ 390×844 : stats allégées + chips peaufinées
   Scope strict : body.X-page (jamais global).
   Sélecteurs stats/chips : utilisent les wrappers parents identifiés
     (.collection-hero, .collection-stats, .stat-item, .quick-filters).
   ═══════════════════════════════════════════════════════════════════ */

/* §23.1) PRODUITS.HTML — Zone filtres / tri compact (≤480px) ===========
   WHY: à 360×800, les .filter-btn et le sort-wrap occupent trop de
        place verticale. On stack proprement (tabs en row scrollables,
        sort en row compact dessous), réduit padding et font-size,
        active scroll horizontal sur les tabs avec scroll-snap. */
@media (max-width: 480px) {
  body.catalogue-page .catalogue-filters {
    padding: 12px 0;
  }
  body.catalogue-page .catalogue-filters .container {
    padding-left: 12px;
    padding-right: 12px;
  }
  body.catalogue-page .filters-inner {
    display: flex;
    flex-direction: column;
    gap: 10px;
    align-items: stretch;
  }
  /* Tabs horizontaux scrollables — accueille les 5 boutons sans wrap */
  body.catalogue-page .filters-tags {
    display: flex;
    gap: 6px;
    overflow-x: auto;
    overflow-y: hidden;
    scroll-snap-type: x mandatory;
    -webkit-overflow-scrolling: touch;
    /* Cache la scrollbar visuelle sans casser le scroll */
    scrollbar-width: none;
    -ms-overflow-style: none;
    padding-bottom: 2px;
    margin: 0 -12px;
    padding-left: 12px;
    padding-right: 12px;
  }
  body.catalogue-page .filters-tags::-webkit-scrollbar {
    display: none;
  }
  body.catalogue-page .filters-tags .filter-btn {
    flex: 0 0 auto;
    scroll-snap-align: start;
    padding: 8px 14px;
    font-size: 13px;
    border-radius: 999px;
    gap: 6px;
    min-height: 36px;
  }
  body.catalogue-page .filters-tags .filter-btn i {
    font-size: 0.85rem;
  }
  /* Sort en row compact sous les tabs */
  body.catalogue-page .filters-sort {
    display: flex;
    align-items: center;
    gap: 8px;
    width: 100%;
  }
  body.catalogue-page .filters-sort label {
    flex: 0 0 auto;
    font-size: 13px;
    margin: 0;
    white-space: nowrap;
  }
  body.catalogue-page .filters-sort .sort-wrap {
    flex: 1 1 auto;
    min-width: 0;
  }
  body.catalogue-page .filters-sort #sort-select {
    width: 100%;
    min-height: 40px;
    padding: 6px 10px;
    font-size: 13px;
    border-radius: 10px;
  }
}
@media (max-width: 380px) {
  body.catalogue-page .filters-tags .filter-btn {
    padding: 7px 12px;
    font-size: 12.5px;
  }
  body.catalogue-page .filters-sort #sort-select {
    font-size: 12.5px;
  }
}

/* §23.2) TROPICAL/STREETWEAR — Stats allégées (≤480px / ≤390px) ========
   WHY: à 390×844, les .stat-item paraissent trop massifs (padding et
        font trop gros). On allège proprement sans changer la palette.
        Wrapper parent confirmé : .collection-hero .collection-stats. */
@media (max-width: 480px) {
  body.tropical-page .collection-hero .collection-stats,
  body.streetwear-page .collection-hero .collection-stats {
    display: grid;
    gap: 8px;
    margin-top: 18px;
    padding: 0 4px;
  }
  body.tropical-page .collection-hero .collection-stats {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }
  body.streetwear-page .collection-hero .collection-stats {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
  body.tropical-page .collection-hero .stat-item,
  body.streetwear-page .collection-hero .stat-item {
    padding: 12px 6px;
    border-radius: 12px;
    min-height: auto;
    text-align: center;
  }
  body.tropical-page .collection-hero .stat-item .stat-number,
  body.streetwear-page .collection-hero .stat-item .stat-number {
    font-size: 1.05rem;
    line-height: 1.1;
    margin-bottom: 2px;
  }
  body.tropical-page .collection-hero .stat-item .stat-number i,
  body.streetwear-page .collection-hero .stat-item .stat-number i {
    font-size: 1rem;
  }
  body.tropical-page .collection-hero .stat-item .stat-label,
  body.streetwear-page .collection-hero .stat-item .stat-label {
    font-size: 0.7rem;
    line-height: 1.2;
    letter-spacing: 0.04em;
  }
}
@media (max-width: 380px) {
  body.tropical-page .collection-hero .stat-item,
  body.streetwear-page .collection-hero .stat-item {
    padding: 10px 4px;
    border-radius: 10px;
  }
  body.tropical-page .collection-hero .stat-item .stat-label,
  body.streetwear-page .collection-hero .stat-item .stat-label {
    font-size: 0.65rem;
  }
}

/* §23.3) TROPICAL/STREETWEAR — Chips collection peaufinées (≤480px) ====
   WHY: les chips .filter-btn (Tout voir / Chemises / T-Shirts / etc.)
        sont trop gros sur mobile. On les rend plus pill premium,
        scrollables horizontalement (anti-wrap moche), padding équilibré.
        Wrapper parent confirmé : .quick-filters. */
@media (max-width: 480px) {
  body.tropical-page .quick-filters,
  body.streetwear-page .quick-filters {
    display: flex;
    gap: 8px;
    overflow-x: auto;
    overflow-y: hidden;
    scroll-snap-type: x mandatory;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
    -ms-overflow-style: none;
    padding-bottom: 4px;
    margin: 0 -12px 16px;
    padding-left: 12px;
    padding-right: 12px;
  }
  body.tropical-page .quick-filters::-webkit-scrollbar,
  body.streetwear-page .quick-filters::-webkit-scrollbar {
    display: none;
  }
  body.tropical-page .quick-filters .filter-btn,
  body.streetwear-page .quick-filters .filter-btn {
    flex: 0 0 auto;
    scroll-snap-align: start;
    padding: 8px 14px;
    font-size: 13px;
    border-radius: 999px;
    gap: 6px;
    min-height: 36px;
    white-space: nowrap;
  }
  body.tropical-page .quick-filters .filter-btn i,
  body.streetwear-page .quick-filters .filter-btn i {
    font-size: 0.85rem;
  }
}
@media (max-width: 380px) {
  body.tropical-page .quick-filters .filter-btn,
  body.streetwear-page .quick-filters .filter-btn {
    padding: 7px 12px;
    font-size: 12.5px;
  }
}

/* §23.4) RECHERCHE.HTML — Hero centré + bar large mobile (≤480px) ======
   WHY: à 360×800, .search-hero h1 + .search-bar-large + .search-suggestions
        sont mal centrés. On centre everything, stack bar input + bouton,
        bouton 48px touch, suggestions wrap propre. */
@media (max-width: 480px) {
  body.recherche-page .search-hero {
    text-align: center;
    padding: 24px 12px 18px;
  }
  body.recherche-page .search-hero h1 {
    font-size: clamp(1.3rem, 5.5vw, 1.7rem);
    margin: 0 auto 16px;
    display: inline-flex;
    align-items: center;
    gap: 10px;
    justify-content: center;
  }
  body.recherche-page .search-bar-large {
    display: flex;
    flex-direction: column;
    gap: 8px;
    width: 100%;
    max-width: 420px;
    margin: 0 auto 14px;
  }
  body.recherche-page .search-input-large {
    width: 100%;
    min-height: 44px;
    padding: 10px 14px;
    font-size: 15px;
    border-radius: 12px;
    box-sizing: border-box;
  }
  body.recherche-page .search-btn-large {
    width: 100%;
    min-height: 48px;
    padding: 0 16px;
    font-size: 14px;
    border-radius: 12px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
  }
  body.recherche-page .search-suggestions {
    text-align: center;
    margin-top: 8px;
  }
  body.recherche-page .search-suggestions small {
    display: block;
    margin-bottom: 6px;
    font-size: 12px;
    opacity: 0.8;
  }
  body.recherche-page .search-suggestions .suggestion-tag {
    display: inline-block;
    margin: 3px 3px;
    padding: 6px 10px;
    font-size: 12px;
    border-radius: 999px;
  }
}

/* §23.5) RECHERCHE.HTML — Toggle filtres mobile (≤768px) ===============
   WHY: à mobile, .filters-sidebar prend trop de place verticale avant
        d'arriver aux résultats. On masque par défaut + bouton toggle
        injecté par js/tu-search-filters-toggle.js. La sidebar reste
        intacte sur desktop (>768).
   Le bouton est injecté en JS avec class .tu-search-filters-toggle.
   La sidebar reçoit la classe .tu-filters-open au clic. */
@media (max-width: 768px) {
  /* Bouton toggle — style pill premium, pleine largeur mobile */
  body.recherche-page .tu-search-filters-toggle {
    display: inline-flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    width: 100%;
    max-width: 420px;
    margin: 0 auto 12px;
    padding: 10px 16px;
    min-height: 44px;
    background: transparent;
    border: 1px solid rgba(44, 62, 80, 0.22);
    border-radius: 12px;
    color: var(--dark-color, #2C3E50);
    font-size: 14px;
    font-weight: 600;
    cursor: pointer;
    transition: background 0.15s ease, border-color 0.15s ease, color 0.15s ease;
    -webkit-tap-highlight-color: rgba(46, 204, 113, 0.15);
  }
  body.recherche-page .tu-search-filters-toggle > span {
    flex: 1 1 auto;
    text-align: left;
  }
  body.recherche-page .tu-search-filters-toggle .tu-toggle-arrow {
    transition: transform 0.2s ease;
    font-size: 0.8rem;
  }
  body.recherche-page .tu-search-filters-toggle.tu-toggle-active .tu-toggle-arrow {
    transform: rotate(180deg);
  }
  body.recherche-page .tu-search-filters-toggle:hover {
    background: rgba(46, 204, 113, 0.06);
    border-color: rgba(46, 204, 113, 0.35);
    color: var(--primary-color, #2ECC71);
  }
  body.dark-mode.recherche-page .tu-search-filters-toggle {
    border-color: rgba(255, 255, 255, 0.18);
    color: var(--text-primary, #FFFFFF);
  }
  body.dark-mode.recherche-page .tu-search-filters-toggle:hover {
    background: rgba(46, 204, 113, 0.12);
    border-color: rgba(46, 204, 113, 0.4);
    color: #3DDC84;
  }
  /* Sidebar masquée par défaut mobile, visible quand .tu-filters-open */
  body.recherche-page .filters-sidebar {
    display: none;
  }
  body.recherche-page .filters-sidebar.tu-filters-open {
    display: block;
    margin-bottom: 16px;
  }
  /* Layout search-layout : column propre mobile */
  body.recherche-page .search-layout {
    display: flex;
    flex-direction: column;
    gap: 0;
  }
}

/* §23.6) CORRECTIFS VISUELS POST-TEST UTILISATEUR (2026-05-02 bis) =====
   3 ajustements ciblés après tests visuels utilisateur :

     1. Tropical/Streetwear : pastilles avec padding horizontal large
        demandé par l'user (12px 40px Tropical / 12px 55px Streetwear).
        ⚠️ Ces valeurs sont INCOMPATIBLES avec le grid 4col/3col mis en
        place dans §23.2 (à 390px viewport, 4 cells ≈ 85px chacune et
        un padding horizontal 80px écrase le contenu à 5px restants).
        Solution : passage de `display: grid` à `display: flex; flex-wrap:
        wrap; justify-content: center` — chaque stat-item prend sa
        largeur naturelle (padding + contenu intrinsèque), wrap si
        nécessaire sur écran étroit. Pas de débordement, pas d'écrasement.

     2. recherche.html : bouton toggle filtres allégé.
        - Texte "Filtres" retiré du JS (span supprimé) → icône seule
        - Suppression du fond/bordure circulaire (transparent + border:none)
        - Conserve aria-label="Afficher / masquer les filtres" (accessibilité)
        - Garde icône filtre + chevron + comportement open/close intact.

     3. produits.html : aucune modification requise. Vérifié : produits.html
        n'utilise PAS .collection-hero .stat-item (0 occurrence). Le règlage
        proposé pour stat-item ne concerne que Tropical/Streetwear.
   ===================================================================== */

/* §23.6.1) Tropical/Streetwear stat-item — flex-wrap centré (≤480px) ==
   WHY: override §23.2 (grid 4col/3col) pour permettre les paddings
        horizontaux larges sans écraser le contenu. Chaque pastille
        respire avec sa largeur naturelle, wrap propre sur écran étroit. */
@media (max-width: 480px) {
  body.tropical-page .collection-hero .collection-stats,
  body.streetwear-page .collection-hero .collection-stats {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 8px;
    margin-top: 18px;
    padding: 0 8px;
    /* override les grid-template-columns du §23.2 (cascade ordre source) */
    grid-template-columns: none;
  }
  body.tropical-page .collection-hero .stat-item {
    padding: 12px 40px;          /* WHY: valeur demandée user — pastille respirante */
    border-radius: 12px;
    min-height: auto;
    text-align: center;
    flex: 0 0 auto;              /* largeur naturelle, ne s'étire pas */
    box-sizing: border-box;
  }
  body.streetwear-page .collection-hero .stat-item {
    padding: 12px 55px;          /* WHY: valeur demandée user (Streetwear plus large) */
    border-radius: 12px;
    min-height: auto;
    text-align: center;
    flex: 0 0 auto;
    box-sizing: border-box;
  }
}
@media (max-width: 380px) {
  body.tropical-page .collection-hero .stat-item,
  body.streetwear-page .collection-hero .stat-item {
    padding: 10px 50px;          /* WHY: ≤380 valeur user */
    border-radius: 10px;
  }
}

/* §23.6.2) recherche.html — bouton toggle filtres allégé (≤768px) =====
   WHY: l'utilisateur trouve le bouton avec texte "Filtres" + fond
        bordé circulaire trop lourd visuellement. On ne garde que
        l'icône filtre + chevron, sans aucun fond/bordure.
        L'aria-label injecté côté JS (modif tu-search-filters-toggle.js
        bumpée v2) garantit l'accessibilité même sans texte visible. */
@media (max-width: 768px) {
  /* Override complet du style §23.5 — bouton minimal sans rond */
  body.recherche-page .tu-search-filters-toggle {
    background: transparent !important;
    border: none !important;
    box-shadow: none !important;
    width: auto !important;
    max-width: none !important;
    padding: 8px 4px !important;
    margin: 0 auto 12px !important;
    min-height: 40px;
    color: var(--dark-color, #2C3E50);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    font-size: 14px;
    cursor: pointer;
  }
  /* Au cas où le span est encore présent (cache JS pas refresh),
     on le masque côté CSS — défense en profondeur */
  body.recherche-page .tu-search-filters-toggle > span {
    display: none !important;
  }
  /* Icône filtre — taille premium, sans cercle autour */
  body.recherche-page .tu-search-filters-toggle > i:first-child {
    font-size: 1.1rem;
  }
  /* Chevron discret pour signaler l'état ouvert/fermé */
  body.recherche-page .tu-search-filters-toggle .tu-toggle-arrow {
    font-size: 0.75rem;
    opacity: 0.7;
  }
  /* Hover : juste un changement de couleur, pas de fond */
  body.recherche-page .tu-search-filters-toggle:hover {
    background: transparent !important;
    border: none !important;
    color: var(--primary-color, #2ECC71);
  }
  /* Dark-mode : couleur claire, toujours sans fond */
  body.dark-mode.recherche-page .tu-search-filters-toggle {
    color: var(--text-primary, #FFFFFF);
    background: transparent !important;
    border: none !important;
  }
  body.dark-mode.recherche-page .tu-search-filters-toggle:hover {
    color: #3DDC84;
    background: transparent !important;
    border: none !important;
  }
}

/* §23.7) CORRECTIFS POST-TEST — SCROLL FILTRES + RECHERCHE TOGGLE ======
   3 problèmes signalés après §23.6 :

     1. produits.html : filtres ne scrollent PAS (figés sur place).
        CAUSE EXACTE : catalogue.css l. 281 définit en BASE (hors @media)
        `body.catalogue-page .filters-tags { flex-wrap: wrap }`. Mon §23.1
        n'avait pas `flex-wrap: nowrap` explicite → wrap persiste à 480px,
        les boutons wrappent au lieu de défiler en row.

     2. Tropical.html : chips ne scrollent PAS (même cause).
        CAUSE EXACTE : tropical-premium.css l. 501 définit en BASE
        `body.tropical-page .quick-filters { flex-wrap: wrap }`. Mon §23.3
        n'avait pas `flex-wrap: nowrap` explicite → idem.

     3. recherche.html : bouton toggle visuellement "trop brut" / "pas
        assez intégré". Le span "Filtres" est bien retiré (JS v2 OK), mais
        mon §23.6.2 mettait `padding: 8px 4px; width: auto` → bouton trop
        petit/perdu. L'utilisateur veut un design icon-button compact 52×44
        centré, plus polish.

   SOLUTION : flex-wrap:nowrap !important + flex-shrink:0 sur les boutons
              pour scroll horizontal garanti site-wide. Bouton recherche
              en icon-button 52×44 centré, fond toujours transparent.
   ===================================================================== */

/* §23.7.1) PRODUITS.HTML — Scroll horizontal filtres FORCÉ (≤480px) ====
   WHY: override le `flex-wrap: wrap` de catalogue.css ligne 281 (base
        sans @media). Spécificité égale → on ajoute `!important` pour
        garantir le `nowrap` à mobile. flex-shrink:0 sur les boutons
        évite qu'ils se compriment au lieu de défiler. */
@media (max-width: 480px) {
  body.catalogue-page .filters-tags {
    flex-wrap: nowrap !important;
    overflow-x: auto !important;
    overflow-y: hidden !important;
    -webkit-overflow-scrolling: touch !important;
    scroll-snap-type: x proximity;
    touch-action: pan-x;
    max-width: 100%;
  }
  /* Boutons jamais comprimés, white-space nowrap pour ne pas casser
     le label sur 2 lignes — sélecteur double pour matcher avec ou sans
     parent .filters-tags */
  body.catalogue-page .filters-tags > .filter-btn,
  body.catalogue-page .filters-tags .filter-btn {
    flex: 0 0 auto !important;
    flex-shrink: 0 !important;
    white-space: nowrap !important;
  }
}

/* §23.7.2) TROPICAL.HTML — Scroll horizontal chips FORCÉ (≤480px) ======
   WHY: override le `flex-wrap: wrap` de tropical-premium.css ligne 501
        (base sans @media). Même approche que §23.7.1. */
@media (max-width: 480px) {
  body.tropical-page .quick-filters {
    flex-wrap: nowrap !important;
    overflow-x: auto !important;
    overflow-y: hidden !important;
    -webkit-overflow-scrolling: touch !important;
    scroll-snap-type: x proximity;
    touch-action: pan-x;
    max-width: 100%;
  }
  body.tropical-page .quick-filters > .filter-btn,
  body.tropical-page .quick-filters .filter-btn {
    flex: 0 0 auto !important;
    flex-shrink: 0 !important;
    white-space: nowrap !important;
  }
}

/* §23.7.3) STREETWEAR.HTML — Same garde défensive (≤480px) =============
   WHY: l'utilisateur dit "OK actuellement" mais on harmonise par
        défense (au cas où le rendu serait variable selon le device).
        Streetwear utilise aussi `.quick-filters` avec même structure CSS
        que Tropical (streetwear-premium.css définit aussi flex-wrap: wrap
        en base). Cette garde n'écrase RIEN si déjà OK, juste verrouille
        le nowrap au cas où. */
@media (max-width: 480px) {
  body.streetwear-page .quick-filters {
    flex-wrap: nowrap !important;
    overflow-x: auto !important;
    overflow-y: hidden !important;
    -webkit-overflow-scrolling: touch !important;
    scroll-snap-type: x proximity;
    touch-action: pan-x;
    max-width: 100%;
  }
  body.streetwear-page .quick-filters > .filter-btn,
  body.streetwear-page .quick-filters .filter-btn {
    flex: 0 0 auto !important;
    flex-shrink: 0 !important;
    white-space: nowrap !important;
  }
}

/* §23.7.4) RECHERCHE.HTML — Bouton toggle icon-button 52×44 (≤768px) ===
   WHY: §23.6.2 mettait padding:8px 4px + width:auto → bouton "perdu".
        On force un design icon-button compact 52×44 centré, fond toujours
        transparent (pas de rond), couleur theme-aware. Override §23.6.2
        par !important sur les valeurs critiques. */
@media (max-width: 768px) {
  body.recherche-page .tu-search-filters-toggle {
    /* Centre + espace respiration */
    margin: 18px auto 10px !important;
    /* Icon-button compact 52×44 */
    width: 52px !important;
    min-width: 52px !important;
    max-width: 52px !important;
    height: 44px !important;
    padding: 0 !important;
    /* Layout interne icône + chevron */
    display: inline-flex !important;
    align-items: center !important;
    justify-content: center !important;
    gap: 6px !important;
    /* Apparence : transparent (override §23.6.2 par sécurité) */
    background: transparent !important;
    border: none !important;
    box-shadow: none !important;
    color: var(--dark-color, #2C3E50) !important;
    cursor: pointer;
  }
  /* Garde anti-span (au cas où le JS v2 ne serait pas chargé) */
  body.recherche-page .tu-search-filters-toggle > span,
  body.recherche-page .tu-search-filters-toggle .tu-search-filters-toggle-label {
    display: none !important;
  }
  /* Icône filtre — taille premium */
  body.recherche-page .tu-search-filters-toggle > i:first-child {
    font-size: 1.25rem !important;
  }
  /* Chevron discret pour l'état ouvert/fermé */
  body.recherche-page .tu-search-filters-toggle .tu-toggle-arrow {
    font-size: 0.7rem !important;
    opacity: 0.75;
  }
  /* Hover : changement couleur, toujours sans fond */
  body.recherche-page .tu-search-filters-toggle:hover {
    background: transparent !important;
    border: none !important;
    box-shadow: none !important;
    color: var(--primary-color, #2ECC71) !important;
  }
  /* Dark-mode : icône claire */
  body.dark-mode.recherche-page .tu-search-filters-toggle {
    color: var(--text-primary, #FFFFFF) !important;
    background: transparent !important;
    border: none !important;
  }
  body.dark-mode.recherche-page .tu-search-filters-toggle:hover {
    color: #3DDC84 !important;
    background: transparent !important;
    border: none !important;
  }
  /* Sidebar : masquée par défaut, visible quand .tu-filters-open
     (déjà géré §23.5 mais on rappelle pour cohérence) */
  body.recherche-page .filters-sidebar {
    display: none;
  }
  body.recherche-page .filters-sidebar.tu-filters-open {
    display: block;
    margin-bottom: 16px;
  }
}

/* §23.8) CORRECTIFS POST-CACHE CONFIRMÉ — RAILS SCROLL + TOGGLE POLISH ===
   CAUSE RACINE de l'échec §23.7 (utilisateur a confirmé v7 chargé) :

     1. produits.html — `.filters-tags` est un FLEX ITEM dans `.filters-inner`
        (flex column à mobile, catalogue.css l. 738-744). Par défaut un
        flex item a `min-width: auto` (= largeur intrinsèque du contenu).
        Quand les 5 boutons dépassent, le flex item s'ÉTIRE au lieu de
        respecter sa width → `overflow-x: auto` n'a rien à scroller.

     2. Tropical.html — `.quick-filters` est posé comme une CARD PILL
        décorative (tropical-premium.css l. 496-510 :
        `padding: 0.85rem 1rem; background; border; border-radius: 999px;
        box-shadow; backdrop-filter; max-width: 900px`). Le `flex-wrap:
        wrap` en BASE + ces contraintes empêchent le scroll horizontal.

     3. recherche.html — bouton trop "brut", pas assez intégré. Solution :
        capsule fine 56×42 avec backdrop-filter blur, bordure très
        discrète, transition chevron rotate.

   FIX essentiels manquants en §23.7 :
     - `min-width: 0 !important` sur `.filters-tags` / `.quick-filters`
       (permet au flex item de SHRINK en dessous de la largeur intrinsèque)
     - `min-width: max-content !important` sur les `.filter-btn` enfants
       (préserve leur taille naturelle dans le rail)
     - Reset des contraintes décoratives card pill Tropical (background:
       transparent + border:none + border-radius:0 + backdrop-filter:none
       sur mobile uniquement)
     - Parents `.catalogue-filters` / `.collection-section` + leur
       `.container` : `overflow: visible !important` pour ne pas clipper
       le rail enfant.
   ===================================================================== */

/* §23.8.1) PRODUITS.HTML — Rail scroll FORCÉ avec min-width:0 (≤480px) =
   WHY: cassage des contraintes flex parent + min-width 0 pour permettre
        au scroll horizontal de fonctionner réellement. */
@media (max-width: 480px) {
  /* Parents : autoriser overflow + permettre shrink */
  body.catalogue-page .catalogue-filters,
  body.catalogue-page .catalogue-filters .container,
  body.catalogue-page .filters-inner {
    overflow: visible !important;
    max-width: 100% !important;
    min-width: 0 !important;
  }
  body.catalogue-page .filters-inner {
    width: 100% !important;
  }
  /* Le rail scroll lui-même — min-width:0 CRITIQUE pour le shrink flex */
  body.catalogue-page .filters-tags {
    display: flex !important;
    flex-direction: row !important;
    flex-wrap: nowrap !important;
    align-items: center !important;
    justify-content: flex-start !important;
    gap: 8px !important;
    overflow-x: auto !important;
    overflow-y: hidden !important;
    width: 100% !important;
    max-width: 100% !important;
    min-width: 0 !important;
    padding: 0 4px 10px !important;
    margin: 0 !important;
    -webkit-overflow-scrolling: touch !important;
    scroll-snap-type: x proximity !important;
    touch-action: pan-x !important;
    overscroll-behavior-x: contain !important;
    scrollbar-width: none !important;
  }
  body.catalogue-page .filters-tags::-webkit-scrollbar {
    display: none !important;
  }
  /* Boutons : min-width max-content pour préserver largeur naturelle
     dans un flex container shrinkable */
  body.catalogue-page .filters-tags .filter-btn,
  body.catalogue-page .filters-tags > .filter-btn {
    flex: 0 0 auto !important;
    min-width: max-content !important;
    white-space: nowrap !important;
    scroll-snap-align: start !important;
  }
}

/* §23.8.2) TROPICAL.HTML — Rail scroll FORCÉ + reset card pill (≤480px) =
   WHY: tropical-premium.css fait `.quick-filters` une card pill
        décorative avec background/border/border-radius:999px/box-shadow/
        backdrop-filter. Sur mobile on doit casser ces contraintes pour
        avoir un VRAI rail scroll horizontal. La card décorative restera
        intacte sur desktop (>480px). */
@media (max-width: 480px) {
  body.tropical-page .collection-section,
  body.tropical-page .collection-section .container {
    overflow: visible !important;
    max-width: 100% !important;
    min-width: 0 !important;
  }
  body.tropical-page .quick-filters {
    display: flex !important;
    flex-direction: row !important;
    flex-wrap: nowrap !important;
    align-items: center !important;
    justify-content: flex-start !important;
    gap: 8px !important;
    overflow-x: auto !important;
    overflow-y: hidden !important;
    width: 100% !important;
    max-width: 100% !important;
    min-width: 0 !important;
    padding: 0 4px 10px !important;
    margin: 0 0 16px !important;
    -webkit-overflow-scrolling: touch !important;
    scroll-snap-type: x proximity !important;
    touch-action: pan-x !important;
    overscroll-behavior-x: contain !important;
    scrollbar-width: none !important;
    /* RESET des décorations card pill desktop (tropical-premium.css l. 503+) */
    background: transparent !important;
    border: none !important;
    box-shadow: none !important;
    border-radius: 0 !important;
    backdrop-filter: none !important;
    -webkit-backdrop-filter: none !important;
  }
  body.tropical-page .quick-filters::-webkit-scrollbar {
    display: none !important;
  }
  body.tropical-page .quick-filters .filter-btn,
  body.tropical-page .quick-filters > .filter-btn {
    flex: 0 0 auto !important;
    min-width: max-content !important;
    white-space: nowrap !important;
    scroll-snap-align: start !important;
  }
}

/* §23.8.3) STREETWEAR.HTML — Garde défensive identique (≤480px) =========
   WHY: l'utilisateur dit "OK actuellement" → on ne casse pas le rendu
        validé. La garde n'écrase RIEN si Streetwear scrolle déjà OK,
        elle verrouille juste la même structure de rail au cas où. */
@media (max-width: 480px) {
  body.streetwear-page .collection-section,
  body.streetwear-page .collection-section .container {
    overflow: visible !important;
    max-width: 100% !important;
    min-width: 0 !important;
  }
  body.streetwear-page .quick-filters {
    display: flex !important;
    flex-wrap: nowrap !important;
    align-items: center !important;
    gap: 8px !important;
    overflow-x: auto !important;
    overflow-y: hidden !important;
    width: 100% !important;
    max-width: 100% !important;
    min-width: 0 !important;
    -webkit-overflow-scrolling: touch !important;
    touch-action: pan-x !important;
    scrollbar-width: none !important;
    background: transparent !important;
    border: none !important;
    box-shadow: none !important;
    border-radius: 0 !important;
    backdrop-filter: none !important;
    -webkit-backdrop-filter: none !important;
  }
  body.streetwear-page .quick-filters::-webkit-scrollbar {
    display: none !important;
  }
  body.streetwear-page .quick-filters .filter-btn {
    flex: 0 0 auto !important;
    min-width: max-content !important;
    white-space: nowrap !important;
  }
}

/* §23.8.4) RECHERCHE.HTML — Bouton toggle capsule fine premium (≤768px) ==
   WHY: §23.7.4 mettait un bouton 52×44 transparent → trop "perdu". On
        passe à une capsule 56×42 avec fond très subtle + bordure
        discrète + backdrop-filter blur pour un rendu mini-premium
        intégré (pattern Apple/Nike "compact filter button"). */
@media (max-width: 768px) {
  body.recherche-page .tu-search-filters-toggle {
    margin: 14px auto 12px !important;
    width: 56px !important;
    min-width: 56px !important;
    max-width: 56px !important;
    height: 42px !important;
    padding: 0 !important;
    display: inline-flex !important;
    align-items: center !important;
    justify-content: center !important;
    gap: 7px !important;
    border-radius: 14px !important;
    box-shadow: none !important;
    backdrop-filter: blur(10px);
    -webkit-backdrop-filter: blur(10px);
    cursor: pointer;
    /* Light mode défaut — fond très subtle, bordure discrète */
    background: rgba(0, 0, 0, 0.02) !important;
    border: 1px solid rgba(44, 62, 80, 0.12) !important;
    color: var(--dark-color, #2C3E50) !important;
  }
  /* Dark mode : adapter le fond/bordure */
  body.dark-mode.recherche-page .tu-search-filters-toggle {
    background: rgba(255, 255, 255, 0.04) !important;
    border-color: rgba(255, 255, 255, 0.10) !important;
    color: var(--text-primary, #FFFFFF) !important;
  }
  /* Garde anti-span (au cas où JS pas v2/v3) */
  body.recherche-page .tu-search-filters-toggle > span,
  body.recherche-page .tu-search-filters-toggle .tu-search-filters-toggle-label {
    display: none !important;
  }
  /* Icône filtre principale */
  body.recherche-page .tu-search-filters-toggle > i:first-child {
    font-size: 1.15rem !important;
  }
  /* Chevron : transition rotate quand ouvert */
  body.recherche-page .tu-search-filters-toggle .tu-toggle-arrow {
    font-size: 0.7rem !important;
    opacity: 0.75 !important;
    transition: transform 0.18s ease, opacity 0.18s ease;
  }
  body.recherche-page .tu-search-filters-toggle.tu-toggle-active .tu-toggle-arrow {
    transform: rotate(180deg);
    opacity: 1 !important;
  }
  /* Hover light */
  body.recherche-page .tu-search-filters-toggle:hover,
  body.recherche-page .tu-search-filters-toggle:focus-visible {
    color: var(--primary-color, #2ECC71) !important;
    border-color: rgba(46, 204, 113, 0.35) !important;
    background: rgba(46, 204, 113, 0.06) !important;
  }
  /* Hover dark */
  body.dark-mode.recherche-page .tu-search-filters-toggle:hover,
  body.dark-mode.recherche-page .tu-search-filters-toggle:focus-visible {
    color: #3DDC84 !important;
    border-color: rgba(46, 204, 113, 0.40) !important;
    background: rgba(46, 204, 113, 0.10) !important;
  }
}

/* §23.9) CORRECTIF DESKTOP — TOGGLE MOBILE-ONLY + RESTAURATION FILTRES =
   CAUSE EXACTE de la régression desktop signalée :

     Le JS `tu-search-filters-toggle.js` injecte le bouton
     `.tu-search-filters-toggle` dans le DOM SANS condition de viewport
     (auto-init au DOMContentLoaded). Donc le bouton existe sur DESKTOP
     aussi, dans le DOM.

     Mes règles CSS §23.5 / §23.6 / §23.7 / §23.8 stylent ce bouton
     UNIQUEMENT à `@media (max-width: 768px)`. À DESKTOP (>768px), le
     bouton n'a aucun style CSS appliqué → il prend le STYLE DEFAULT
     BROWSER (button avec fond gris natif `rgb(239, 239, 239)` + bordure
     system) → c'est ÇA le "carré/barre gris parasite" que l'utilisateur
     voit.

     Le `.search-bar-large border-radius: 1px` vient de recherche-premium.css
     ligne 176-194 (CSS d'origine du projet) — non causé par §23.

     Mon §23.4 `.search-bar-large` est correctement scopé
     @media (max-width: 480px) — ne fuit pas sur desktop.

   SOLUTION CHIRURGICALE :
     1. Cacher complètement le bouton toggle à >768px (display: none)
     2. Garantir explicite que .filters-sidebar reste visible à desktop
        (au cas où une cascade aurait mis display: none parasite)
     3. Annuler l'effet de .tu-filters-open sur desktop (toujours visible)

   POURQUOI on ne modifie PAS le JS :
     - Le JS doit continuer à injecter le bouton car au resize desktop→mobile
       (rotation device, devtools mobile), le bouton doit apparaître.
     - Si le JS testait window.matchMedia une seule fois, il faudrait un
       resize listener → complexité inutile.
     - Solution CSS-only `display: none` à desktop = idempotent + safe +
       pas d'effet de bord JS.
   ===================================================================== */

/* §23.9.1) RECHERCHE.HTML — Toggle mobile-only à desktop (>768px) =======
   WHY: empêche le rendu default browser du bouton sur desktop. */
@media (min-width: 769px) {
  /* Cacher complètement le bouton toggle filtres mobile sur desktop */
  body.recherche-page .tu-search-filters-toggle {
    display: none !important;
  }
  /* Garantir explicite que la sidebar filtres reste visible à desktop
     (au cas où une cascade ou un état JS mettrait display:none) */
  body.recherche-page .filters-sidebar {
    display: block !important;
    visibility: visible !important;
    opacity: 1 !important;
  }
  /* La classe .tu-filters-open ajoutée par le JS au clic mobile ne
     doit PAS affecter desktop (sidebar toujours visible) */
  body.recherche-page .filters-sidebar.tu-filters-open {
    display: block !important;
  }
}

/* §23.9.2) PRODUITS.HTML — Garde desktop défensive (≥769px) ============
   WHY: par sécurité, on confirme que les rails scroll mobiles §23.7/§23.8
        n'affectent PAS desktop. Mes règles sont déjà scope ≤480px donc
        ne devraient pas fuir, mais cette garde explicite annule tout
        effet résiduel sur les parents (au cas où). */
@media (min-width: 769px) {
  /* Ne PAS forcer overflow:visible sur desktop (laisser le CSS d'origine
     catalogue.css gérer). Cette section est volontairement vide pour
     marquer que rien ne doit être touché. Si une régression apparaît,
     on ajoutera des reset ciblés ici plus tard. */
}

/* §23.9.3) TROPICAL.HTML / STREETWEAR.HTML — Garde desktop pour card pill (≥481px)
   WHY: Tropical/Streetwear ont une CARD PILL décorative sur .quick-filters
        (tropical-premium.css l. 503-510 / streetwear-premium.css idem).
        Mes §23.8.2/§23.8.3 reset cette card à mobile (≤480px) avec
        `background: transparent !important` + `border: none !important`
        + `border-radius: 0 !important` + `backdrop-filter: none !important`.
        À ≥481px, ces reset ne s'appliquent pas (en dehors du @media)
        donc la card pill décorative est restaurée naturellement. Garde
        explicite ici par sécurité. */
@media (min-width: 481px) {
  /* Volontairement vide — la cascade naturelle restaure la card pill
     à >480px. Si jamais elle ne se restaure pas (cascade cassée par
     un autre CSS), ajouter ici les reset back :
       body.tropical-page .quick-filters {
         background: var(--t-surface-card);
         border: 1px solid var(--t-border);
         border-radius: 999px;
         box-shadow: var(--t-shadow);
         backdrop-filter: blur(6px);
       }
     Pour l'instant on fait confiance à la cascade. */
}

/* §23.10) RECHERCHE.HTML — Toggle filtres SANS FOND mobile (≤768px) =====
   CAUSE EXACTE de la capsule sombre restante :

     Mon §23.8.4 (lignes 3901+) a posé un design "capsule fine premium" :
       background: rgba(0,0,0,0.02) light  /  rgba(255,255,255,0.04) dark
       border: 1px solid rgba(44,62,80,0.12) / rgba(255,255,255,0.10)
       border-radius: 14px
       backdrop-filter: blur(10px)
     L'utilisateur préfère maintenant ZÉRO habillage (juste icône+chevron).

   SOLUTION : override §23.8.4 pour supprimer TOUT habillage visuel
   (background, border, box-shadow, backdrop-filter, border-radius) sur
   le bouton ET tous ses états (hover, focus, focus-visible, active).
   Le bouton reste pleinement cliquable et accessible (44×44 touch HIG,
   aria-* préservés par le JS).

   Scope strict mobile : @media (max-width: 768px).
   Desktop intact : §23.9.1 cache complètement le bouton à >768px,
                    donc desktop n'est pas concerné par ces règles.
   ===================================================================== */
@media (max-width: 768px) {
  /* État de base : aucun habillage, juste layout flex centré */
  body.recherche-page .tu-search-filters-toggle {
    background: transparent !important;
    border: 0 !important;
    box-shadow: none !important;
    backdrop-filter: none !important;
    -webkit-backdrop-filter: none !important;
    border-radius: 0 !important;
    outline: none;
    /* Layout : largeur naturelle (auto), min 44 touch HIG */
    width: auto !important;
    min-width: 44px !important;
    max-width: none !important;
    height: 44px !important;
    padding: 0 6px !important;
    margin: 14px auto 12px !important;
    display: inline-flex !important;
    align-items: center !important;
    justify-content: center !important;
    gap: 8px !important;
    color: var(--dark-color, #2C3E50) !important;
  }

  /* Tous les états interactifs : aucun fond non plus */
  body.recherche-page .tu-search-filters-toggle:hover,
  body.recherche-page .tu-search-filters-toggle:focus,
  body.recherche-page .tu-search-filters-toggle:focus-visible,
  body.recherche-page .tu-search-filters-toggle:active,
  body.recherche-page .tu-search-filters-toggle.tu-toggle-active {
    background: transparent !important;
    border: 0 !important;
    box-shadow: none !important;
    backdrop-filter: none !important;
    -webkit-backdrop-filter: none !important;
    color: var(--primary-color, #2ECC71) !important;
  }

  /* Garde anti-span (label "Filtres" si JS pas v2/v3) */
  body.recherche-page .tu-search-filters-toggle > span,
  body.recherche-page .tu-search-filters-toggle .tu-search-filters-toggle-label {
    display: none !important;
  }

  /* Icônes internes : pas d'habillage non plus */
  body.recherche-page .tu-search-filters-toggle > i {
    background: transparent !important;
    box-shadow: none !important;
    border: 0 !important;
  }

  /* Dark mode : couleur claire (icône lisible sur fond dark) */
  body.dark-mode.recherche-page .tu-search-filters-toggle {
    color: var(--text-primary, #FFFFFF) !important;
  }
  body.dark-mode.recherche-page .tu-search-filters-toggle:hover,
  body.dark-mode.recherche-page .tu-search-filters-toggle:focus-visible,
  body.dark-mode.recherche-page .tu-search-filters-toggle.tu-toggle-active {
    color: #3DDC84 !important;
  }
}

/* §23.11) RECHERCHE.HTML — Search bar moins ronde mobile (≤768px) =======
   NOTE numérotation : §23.10 a été utilisé au tour précédent pour le
   "toggle sans fond". On utilise §23.11 pour cette nouvelle correction.

   CAUSE EXACTE de la "capsule massive" sur mobile :

     recherche-premium.css ligne 176-194 (CSS d'origine du projet) :
       body.recherche-page .search-bar-large {
         border-radius: 999px;     ← capsule pill desktop OK, trop rond mobile
         padding: 0.4rem 0.4rem 0.4rem 1.3rem;
         background: var(--rc-surface-card);
         border: 1px solid var(--rc-border-strong);
         backdrop-filter: blur(8px);
         ...
       }

     Mon §23.4 (≤480px, ligne 3320+) override le layout pour mobile :
       display: flex;
       flex-direction: column;     ← input + bouton en COLONNE
       max-width: 420px;
       ...

     Résultat à mobile : le wrapper `.search-bar-large` devient HAUT
     (input stacké au-dessus du bouton) MAIS garde le `border-radius:
     999px` de recherche-premium.css → capsule VERTICALE massive
     disgracieuse derrière les 2 éléments empilés.

   SOLUTION : override uniquement le `border-radius` mobile à 18px
   (rectangulaire arrondi premium, harmonisé avec input/bouton à 12px
   du §23.4). Pas de touche au background/border/blur — uniquement le
   radius pour casser l'effet capsule.

   Scope strict : @media (max-width: 768px) → desktop (>768) garde le
   pill 999px d'origine recherche-premium.css.
   ===================================================================== */
@media (max-width: 768px) {
  /* WHY: casser l'effet capsule pill (999px) sur mobile, garder fond +
     bordure + blur pour rester premium */
  body.recherche-page .search-bar-large {
    border-radius: 18px !important;
  }
  /* WHY: bouton interne à 14px pour cohérence visuelle vs input à 12px
     (§23.4) — légère différence pour faire ressortir le CTA */
  body.recherche-page .search-btn-large {
    border-radius: 14px !important;
  }
}

/* §23.12) RECHERCHE.HTML — Centrage input + bouton search mobile (≤768px)
   NOTE numérotation : §23.10 (toggle sans fond) et §23.11 (radius 18px)
   sont déjà validés. On utilise §23.12 pour cette nouvelle correction.

   CAUSE EXACTE du désalignement :

     1. Mon §23.4 (ligne 3320+, ≤480px) met :
          display: flex;
          flex-direction: column;
          gap: 8px;
          width: 100%;
          max-width: 420px;
          margin: 0 auto 14px;
        MAIS NE PRÉCISE PAS `align-items: center`.

     2. recherche-premium.css ligne 176 (BASE, hors @media) met :
          padding: 0.4rem 0.4rem 0.4rem 1.3rem;
        → padding-LEFT 1.3rem (~20.8px) vs padding-RIGHT 0.4rem (~6.4px)
        → ASYMÉTRIE horizontale conçue pour le layout pill horizontal
          desktop (icône recherche à gauche). En mobile column, cette
          asymétrie décale le bouton vers la gauche.

     3. L'input n'a pas de `text-align: center` → texte aligné à gauche
        par défaut.

     4. Le bouton avec `width: 100%` (§23.4) s'étire dans le wrapper
        column avec padding asymétrique → décalage visuel.

   SOLUTION : padding symétrique 12px + align-items center + input/btn
   centrés text et width controllée. Conserve le radius 18px (§23.11)
   et tout le reste du design.

   Scope strict : @media (max-width: 768px). Desktop intact.
   ===================================================================== */
@media (max-width: 768px) {
  /* Wrapper search-bar : centrage flex + padding symétrique
     WHY: override le padding asymétrique 0.4/0.4/0.4/1.3 de
          recherche-premium.css ligne 176 + ajout align-items:center
          pour centrer les enfants empilés en column */
  body.recherche-page .search-bar-large {
    display: flex !important;
    flex-direction: column !important;
    align-items: center !important;
    justify-content: center !important;
    gap: 10px !important;
    padding: 12px !important;          /* symétrique 4 côtés */
    /* border-radius: 18px déjà appliqué par §23.11 — héritage cascade */
  }

  /* Input : pleine largeur + texte centré */
  body.recherche-page .search-input-large {
    width: 100% !important;
    max-width: 100% !important;
    text-align: center !important;
    margin: 0 auto !important;
    padding-left: 12px !important;     /* symétrique vs droite */
    padding-right: 12px !important;
    box-sizing: border-box !important;
  }
  /* Placeholder centré aussi (sinon il reste aligné à gauche selon
     le navigateur, cassant la symétrie visuelle) */
  body.recherche-page .search-input-large::placeholder {
    text-align: center !important;
  }
  /* Compatibilité navigateurs anciens (vendor prefixes) */
  body.recherche-page .search-input-large::-webkit-input-placeholder {
    text-align: center !important;
  }
  body.recherche-page .search-input-large::-moz-placeholder {
    text-align: center !important;
  }
  body.recherche-page .search-input-large:-ms-input-placeholder {
    text-align: center !important;
  }

  /* Bouton "Rechercher" : centré + max-width 280 pour ne pas s'étirer
     totalement (rendu plus premium qu'un bouton qui prend toute la largeur) */
  body.recherche-page .search-btn-large {
    width: 100% !important;
    max-width: 280px !important;
    margin: 0 auto !important;
    display: inline-flex !important;
    align-items: center !important;
    justify-content: center !important;
    text-align: center !important;
    /* border-radius: 14px déjà appliqué par §23.11 — héritage cascade */
  }
}

/* §23.13) RECHERCHE.HTML — Centrage tags + tri + cards mobile (≤768px) ==
   NOTE numérotation : §23.10 (toggle sans fond), §23.11 (radius 18px),
   §23.12 (centrage input/bouton search) sont déjà validés. On utilise
   §23.13 pour cette nouvelle correction.

   CLASSES EXACTES vérifiées dans recherche.html (l. 145-260, 717-741) :

     1. Tags populaires :
        .search-suggestions > .suggestion-tag (4× Hoodie, Streetwear,
        Chemise, T-shirt tropical) — précédé d'un <small>Recherches
        populaires:</small><br>

     2. Zone tri :
        .results-header > .results-count + .sort-dropdown
        .sort-dropdown contient <label for="sort-select">Trier par:</label>
        + <select id="sort-select" class="sort-select"> avec options
        Pertinence/Prix asc/Prix desc/Nom A-Z/Nouveautés

     3. Cartes produit (markup template inline JS l. 717+) :
        .product-card > .product-image-wrapper (image + badge + wishlist)
                      + .product-info > .product-name (h3)
                                      + .product-price (.current-price
                                                       + .original-price)
                                      + .product-rating (étoiles + avis)
                                      + .btn-add-to-cart

   STRATÉGIE :
     - Centrage UNIQUEMENT dans #search-results-grid pour ne pas toucher
       aux cartes produit des autres pages (le scope body.recherche-page
       suffit déjà mais on ajoute #search-results-grid pour défense).
     - Image-wrapper, badge gauche et wishlist droite restent intacts
       (positionnement absolu géré par §22 + §23.8.1).
     - Bouton btn-add-to-cart reste full-width (§22) — pas centré comme
       texte mais déjà centré naturellement par width:100%.
   ===================================================================== */
@media (max-width: 768px) {

  /* §23.13.1 — Tags recherches populaires
     WHY: .search-suggestions est un div bloc inline-html par défaut.
          Centrer le bloc + les tags inline-block. */
  body.recherche-page .search-suggestions {
    text-align: center !important;
    margin-top: 8px !important;
  }
  body.recherche-page .search-suggestions small {
    display: block !important;
    text-align: center !important;
    margin-bottom: 8px !important;
    font-size: 12px !important;
  }
  body.recherche-page .search-suggestions .suggestion-tag {
    display: inline-block !important;
    margin: 4px 4px !important;
    text-align: center !important;
  }

  /* §23.13.2 — Zone résultats / tri
     WHY: .results-header est probablement flex row desktop. À mobile
          on stack en column centrée pour symétrie. */
  body.recherche-page .results-header {
    display: flex !important;
    flex-direction: column !important;
    align-items: center !important;
    justify-content: center !important;
    text-align: center !important;
    gap: 10px !important;
    margin-bottom: 14px !important;
  }
  body.recherche-page .results-count {
    text-align: center !important;
    width: 100% !important;
  }
  body.recherche-page .sort-dropdown {
    display: flex !important;
    align-items: center !important;
    justify-content: center !important;
    gap: 8px !important;
    width: 100% !important;
    max-width: 320px !important;
    margin: 0 auto !important;
  }
  body.recherche-page .sort-dropdown label {
    flex: 0 0 auto !important;
    text-align: center !important;
    margin: 0 !important;
  }
  body.recherche-page #sort-select,
  body.recherche-page .sort-select {
    text-align: center !important;
    text-align-last: center !important;
    margin-inline: auto !important;
    flex: 1 1 auto !important;
    min-width: 0 !important;
  }

  /* §23.13.3 — Cartes produit recherche : nom / prix / rating centrés
     WHY: scope #search-results-grid pour ne PAS impacter les cartes
          des autres pages (catalogue, vip, etc.). Le scope
          body.recherche-page suffit techniquement, mais on ajoute
          l'ID pour défense supplémentaire. */
  body.recherche-page #search-results-grid .product-card .product-info {
    text-align: center !important;
    align-items: center !important;
  }
  body.recherche-page #search-results-grid .product-card .product-name {
    text-align: center !important;
    margin-left: auto !important;
    margin-right: auto !important;
  }
  body.recherche-page #search-results-grid .product-card .product-price {
    display: flex !important;
    justify-content: center !important;
    align-items: baseline !important;
    text-align: center !important;
    margin-left: auto !important;
    margin-right: auto !important;
  }
  body.recherche-page #search-results-grid .product-card .current-price,
  body.recherche-page #search-results-grid .product-card .original-price {
    text-align: center !important;
  }
  body.recherche-page #search-results-grid .product-card .product-rating {
    display: flex !important;
    justify-content: center !important;
    align-items: center !important;
    text-align: center !important;
    flex-wrap: wrap !important;
    gap: 4px !important;
    margin-left: auto !important;
    margin-right: auto !important;
  }
  body.recherche-page #search-results-grid .product-card .product-rating-empty {
    text-align: center !important;
  }
  /* IMPORTANT : .product-image-wrapper et .product-wishlist conservent
     leur layout (position absolute) — on ne les touche PAS pour ne pas
     casser badge gauche / wishlist droite (§22 + §23.8.1). */
}

/* §23.14) RECHERCHE.HTML — Tags populaires alignés grille 2x2 (≤480px) ==
   NOTE numérotation : §23.10/11/12/13 déjà utilisés. On utilise §23.14.

   CAUSE EXACTE du désalignement :

     Le markup recherche.html l. 145-151 :
       <div class="search-suggestions">
         <small>Recherches populaires:</small><br>
         <span class="suggestion-tag" data-query="t-shirt tropical">T-shirt tropical</span>
         <span class="suggestion-tag" data-query="chemise">Chemise</span>
         <span class="suggestion-tag" data-query="streetwear">Streetwear</span>
         <span class="suggestion-tag" data-query="hoodie">Hoodie</span>
       </div>

     Les 4 tags ont des largeurs très différentes :
       - "T-shirt tropical" ≈ 130-140px
       - "Chemise"          ≈ 80px
       - "Streetwear"       ≈ 95px
       - "Hoodie"           ≈ 75px

     Mon §23.13.1 met `display: inline-block + margin: 4px 4px` sur
     chaque tag. À 360px viewport, le wrap par défaut donne :
       Ligne 1 : "T-shirt tropical" + "Chemise" (~220px utilisés)
       Ligne 2 : "Streetwear" + "Hoodie" (~180px utilisés, décalés à gauche)
     → "Hoodie" semble visuellement décalé par rapport à "Chemise"
     parce que les colonnes ne sont PAS alignées (inline-block + wrap
     gère chaque ligne indépendamment).

   SOLUTION : grille 2x2 STRICTE avec cells égales
   `repeat(2, minmax(0, 1fr))`. Chaque tag prend la pleine largeur de
   sa cell → 2 colonnes parfaitement alignées. Le `<small>` span sur
   les 2 colonnes (grid-column: 1/-1). Le `<br>` est masqué (inutile
   en grid).

   Scope strict : @media (max-width: 480px). Desktop intact.
   ===================================================================== */
@media (max-width: 480px) {
  /* Container : grid 2x2 stricte */
  body.recherche-page .search-suggestions {
    display: grid !important;
    grid-template-columns: repeat(2, minmax(0, 1fr)) !important;
    gap: 8px 10px !important;
    justify-items: center !important;
    align-items: center !important;
    max-width: 320px !important;
    margin: 8px auto 0 !important;
    padding: 0 !important;
  }

  /* <small> "Recherches populaires:" : span sur 2 colonnes, centré */
  body.recherche-page .search-suggestions small {
    grid-column: 1 / -1 !important;
    text-align: center !important;
    display: block !important;
    margin: 0 0 6px !important;
    font-size: 12px !important;
    width: 100% !important;
  }

  /* <br> : masqué en grid (inutile, le grid gère les sauts de ligne) */
  body.recherche-page .search-suggestions br {
    display: none !important;
  }

  /* Tags : pleine largeur de leur cell, centrés, taille uniforme */
  body.recherche-page .search-suggestions .suggestion-tag {
    display: inline-flex !important;
    align-items: center !important;
    justify-content: center !important;
    width: 100% !important;
    max-width: 140px !important;
    margin: 0 !important;
    padding: 6px 10px !important;
    font-size: 12px !important;
    text-align: center !important;
    white-space: nowrap !important;
    box-sizing: border-box !important;
  }
}

/* §23.15) TROPICAL.HTML — Stats 2x2 + cards centrées mobile (≤480/768px)
   NOTE numérotation : §23.10-§23.14 déjà utilisés (recherche + autres).
   On utilise §23.15 pour Tropical UNIQUEMENT.

   CLASSES EXACTES vérifiées dans Tropical.html (l. 177-194, 459-485) :

     1. Stats hero (4 items dans .collection-hero) :
        .collection-hero .collection-stats > .stat-item × 4
          > .stat-number (id=product-count pour le 1er, <i> Font Awesome
                          pour les 3 autres)
          > .stat-label (Pièces / Coton bio / Esprit été / 974)

     2. Cards produits (template JS l. 459+, rendu dans #products-container) :
        .product-card > .product-image-wrapper (image + badge)
                      + .product-info > .product-name (h3)
                                      + .product-price (.current-price
                                                       + .original-price)
                                      + .product-rating (étoiles + avis)
                                      + .btn-add-to-cart
        ⚠️ Tropical n'a PAS de wishlist dans son template (vs recherche
        qui en a une). Pas besoin de gérer la wishlist ici.

   STRATÉGIE :
     - Override §23.6.1 (flex-wrap centré + padding 12px 40px) pour
       passer en grille 2x2 stricte sur TROPICAL UNIQUEMENT.
     - Streetwear garde son §23.6.1 actuel (flex-wrap, padding 12px 55px)
       car non concerné par cette demande user.
     - Centrer nom/prix/avis dans les cards via scope #products-container
       (cohérent avec §23.13.3 qui scope #search-results-grid).
     - Image-wrapper, badge, btn-add-to-cart inchangés (gérés §22).

   NOTE override §23.6.1 :
     §23.6.1 utilise `display: flex` SANS !important, donc mon
     `display: grid !important` gagne par !important + cascade ordre
     source plus tardif.
   ===================================================================== */

/* §23.15.1) STATS HERO TROPICAL — grille 2x2 stricte (≤480px) ==========
   WHY: 4 stats sur mobile présentent mieux en grille 2x2 (comme les tags
        recherche §23.14) qu'en flex-wrap libre (qui peut wrap inégalement
        si "Coton bio"/"Esprit été" sont plus larges que les autres).
        Chaque cell prend la même largeur → rendu équilibré et premium. */
@media (max-width: 480px) {
  body.tropical-page .collection-hero .collection-stats {
    display: grid !important;
    grid-template-columns: repeat(2, minmax(118px, 1fr)) !important;
    justify-content: center !important;
    align-items: stretch !important;
    gap: 10px !important;
    max-width: 280px !important;
    margin-left: auto !important;
    margin-right: auto !important;
    margin-top: 18px !important;
    padding: 0 !important;
    /* override flex de §23.6.1 par display: grid !important */
    flex-wrap: unset !important;
  }
  body.tropical-page .collection-hero .stat-item {
    width: 100% !important;
    min-width: 0 !important;
    max-width: none !important;
    padding: 10px 8px !important;          /* override 12px 40px de §23.6.1 */
    border-radius: 14px !important;
    min-height: 58px !important;
    display: flex !important;
    flex-direction: column !important;     /* number/icône au-dessus, label en dessous */
    align-items: center !important;
    justify-content: center !important;
    gap: 4px !important;
    text-align: center !important;
    flex: unset !important;                /* annule flex: 0 0 auto de §23.6.1 */
    box-sizing: border-box !important;
  }
  body.tropical-page .collection-hero .stat-item .stat-number,
  body.tropical-page .collection-hero .stat-item .stat-label {
    text-align: center !important;
    width: 100% !important;
  }
}

/* §23.15.2) STATS HERO TROPICAL — raffinement très petit écran (≤380px)
   WHY: à 360 (Galaxy S20), resserrer encore légèrement la grille pour
        ne pas occuper trop de hauteur verticale dans le hero. */
@media (max-width: 380px) {
  body.tropical-page .collection-hero .collection-stats {
    max-width: 260px !important;
    gap: 8px !important;
  }
  body.tropical-page .collection-hero .stat-item {
    padding: 9px 6px !important;
    min-height: 54px !important;
    border-radius: 12px !important;
  }
}

/* §23.15.3) CARDS PRODUITS TROPICAL — centrage nom/prix/avis (≤768px) ==
   WHY: scope #products-container pour ne PAS impacter les cartes des
        autres pages (Streetwear, vip, etc. ont leur propre layout).
        Pattern identique à §23.13.3 (recherche.html cards centrées). */
@media (max-width: 768px) {
  body.tropical-page #products-container .product-card .product-info {
    text-align: center !important;
    align-items: center !important;
  }
  body.tropical-page #products-container .product-card .product-name {
    text-align: center !important;
    margin-left: auto !important;
    margin-right: auto !important;
  }
  body.tropical-page #products-container .product-card .product-price {
    display: flex !important;
    justify-content: center !important;
    align-items: baseline !important;
    text-align: center !important;
    margin-left: auto !important;
    margin-right: auto !important;
  }
  body.tropical-page #products-container .product-card .current-price,
  body.tropical-page #products-container .product-card .original-price {
    text-align: center !important;
  }
  body.tropical-page #products-container .product-card .product-rating {
    display: flex !important;
    justify-content: center !important;
    align-items: center !important;
    text-align: center !important;
    flex-wrap: wrap !important;
    gap: 4px !important;
    margin-left: auto !important;
    margin-right: auto !important;
  }
  body.tropical-page #products-container .product-card .product-rating-empty {
    text-align: center !important;
  }
  /* IMPORTANT : .product-image-wrapper et .btn-add-to-cart conservent
     leur layout natif (gérés par §22). Pas touchés ici. */
}

/* §23.16) STREETWEAR + PRODUITS — Stats grille + cards mobile (≤480/768)
   NOTE numérotation : §23.10-§23.15 déjà utilisés. On utilise §23.16.

   CLASSES EXACTES vérifiées :

     A. Streetwear.html (l. 145-160) — 3 stats :
        .collection-hero .collection-stats > .stat-item × 3
          (Produits / Tendance / Nouveautés)
        ⚠️ Streetwear cards (template JS l. 326+) : PAS de wishlist
        (vs produits.html qui en a une).

     B. produits.html (l. 438+) — cards avec WISHLIST :
        .product-card > .product-image-wrapper
                          > img.product-image
                          > .product-badge (.new ou .promo)
                          > .product-wishlist (button absolute droite §22)
                      + .product-info > .product-name + .product-price
                                      + .product-rating + .btn-add-to-cart

   STRATÉGIE :
     - Streetwear stats : grille 2 cols, 3ème stat (Nouveautés) centrée
       seule sur ligne 2 via `grid-column: 1/-1` + `max-width: 140px`.
       Override §23.6.1 (flex-wrap centré) + §23.15 (qui ne touche pas
       Streetwear).
     - Streetwear cards : centrage nom/prix/avis (scope #products-container).
       Pattern identique à §23.15.3 mais scope `body.streetwear-page`.
     - produits.html cards : compactes (max-width 92%, gap 10px, padding
       info réduit) + centrage. ⚠️ NE PAS toucher .product-wishlist
       (position absolute droite §22 préservée).
   ===================================================================== */

/* §23.16.1) STREETWEAR — Stats grille 2+1 centrée (≤480px) =============
   WHY: 3 stats → grille 2 col avec le 3ème (Nouveautés) seul sur ligne 2,
        centré et limité à 140px. Override §23.6.1 (flex-wrap centré
        avec padding 12px 55px) par display:grid !important. */
@media (max-width: 480px) {
  body.streetwear-page .collection-hero .collection-stats {
    display: grid !important;
    grid-template-columns: repeat(2, minmax(118px, 1fr)) !important;
    justify-content: center !important;
    align-items: stretch !important;
    gap: 10px !important;
    max-width: 280px !important;
    margin-left: auto !important;
    margin-right: auto !important;
    margin-top: 18px !important;
    padding: 0 !important;
    flex-wrap: unset !important;          /* annule §23.6.1 flex-wrap */
  }
  body.streetwear-page .collection-hero .collection-stats .stat-item {
    width: 100% !important;
    min-width: 0 !important;
    max-width: none !important;
    padding: 10px 8px !important;          /* override 12px 55px de §23.6.1 */
    border-radius: 14px !important;
    min-height: 58px !important;
    display: flex !important;
    flex-direction: column !important;     /* number/icône au-dessus, label en dessous */
    align-items: center !important;
    justify-content: center !important;
    gap: 6px !important;
    text-align: center !important;
    flex: unset !important;                /* annule flex: 0 0 auto §23.6.1 */
    box-sizing: border-box !important;
  }
  /* 3ème stat (Nouveautés) seule sur ligne 2 → span 2 cols + max-width 140
     pour rester de même taille que les autres cellules */
  body.streetwear-page .collection-hero .collection-stats .stat-item:nth-child(3) {
    grid-column: 1 / -1 !important;
    max-width: 140px !important;
    justify-self: center !important;
  }
  body.streetwear-page .collection-hero .stat-number,
  body.streetwear-page .collection-hero .stat-label {
    text-align: center !important;
    width: 100% !important;
  }
}

/* §23.16.2) STREETWEAR — Stats raffinement très petit écran (≤380px) ===
   WHY: à 360 (Galaxy S20), resserrer encore légèrement. */
@media (max-width: 380px) {
  body.streetwear-page .collection-hero .collection-stats {
    max-width: 260px !important;
    gap: 8px !important;
  }
  body.streetwear-page .collection-hero .collection-stats .stat-item {
    min-height: 54px !important;
    padding: 9px 6px !important;
    border-radius: 12px !important;
  }
}

/* §23.16.3) STREETWEAR — Cards produits centrées (≤768px) ==============
   WHY: scope #products-container pour ne PAS impacter les autres pages.
        Pattern identique à §23.15.3 (Tropical) mais scope streetwear.
        Streetwear cards SANS wishlist → pas besoin de la gérer. */
@media (max-width: 768px) {
  body.streetwear-page #products-container .product-card .product-info {
    text-align: center !important;
    align-items: center !important;
  }
  body.streetwear-page #products-container .product-card .product-name {
    text-align: center !important;
    margin-left: auto !important;
    margin-right: auto !important;
  }
  body.streetwear-page #products-container .product-card .product-price {
    display: flex !important;
    justify-content: center !important;
    align-items: baseline !important;
    text-align: center !important;
    margin-left: auto !important;
    margin-right: auto !important;
  }
  body.streetwear-page #products-container .product-card .current-price,
  body.streetwear-page #products-container .product-card .original-price {
    text-align: center !important;
  }
  body.streetwear-page #products-container .product-card .product-rating {
    display: flex !important;
    justify-content: center !important;
    align-items: center !important;
    text-align: center !important;
    flex-wrap: wrap !important;
    gap: 4px !important;
    margin-left: auto !important;
    margin-right: auto !important;
  }
  body.streetwear-page #products-container .product-card .product-rating-empty {
    text-align: center !important;
  }
  /* IMPORTANT : .product-image-wrapper et .btn-add-to-cart inchangés (§22) */
}

/* §23.16.4) PRODUITS.HTML — Cards compactes + centrées (≤480px) ========
   WHY: cartes légèrement réduites en largeur (max-width 92% du grid) +
        contenu centré. ⚠️ .product-wishlist NON touchée (position
        absolute droite gérée par §22). Le btn-add-to-cart est limité
        à 92% pour respiration interne. */
@media (max-width: 480px) {
  body.catalogue-page #products-grid {
    max-width: 92% !important;
    margin-left: auto !important;
    margin-right: auto !important;
    gap: 10px !important;
  }
  body.catalogue-page #products-grid .product-card {
    border-radius: 14px !important;
  }
  body.catalogue-page #products-grid .product-image-wrapper {
    border-radius: 14px 14px 0 0 !important;
    overflow: hidden !important;
  }
  body.catalogue-page #products-grid .product-info {
    text-align: center !important;
    align-items: center !important;
    padding: 9px 10px 11px !important;
  }
  body.catalogue-page #products-grid .product-name {
    text-align: center !important;
    margin-left: auto !important;
    margin-right: auto !important;
  }
  body.catalogue-page #products-grid .product-price {
    display: flex !important;
    justify-content: center !important;
    align-items: baseline !important;
    text-align: center !important;
    margin-left: auto !important;
    margin-right: auto !important;
  }
  body.catalogue-page #products-grid .current-price,
  body.catalogue-page #products-grid .original-price {
    text-align: center !important;
  }
  body.catalogue-page #products-grid .product-rating {
    display: flex !important;
    justify-content: center !important;
    align-items: center !important;
    text-align: center !important;
    flex-wrap: wrap !important;
    gap: 4px !important;
    margin-left: auto !important;
    margin-right: auto !important;
  }
  body.catalogue-page #products-grid .product-rating-empty {
    text-align: center !important;
  }
  body.catalogue-page #products-grid .btn-add-to-cart {
    max-width: 92% !important;
    margin-left: auto !important;
    margin-right: auto !important;
  }
  /* IMPORTANT : .product-wishlist (position: absolute right §22) NON
     touchée — reste en haut-droite de l'image-wrapper. */
}

/* §23.16.5) PRODUITS.HTML — Raffinement très petit écran (≤380px) ======
   WHY: à 360 (Galaxy S20), encore légèrement plus compact. */
@media (max-width: 380px) {
  body.catalogue-page #products-grid {
    max-width: 94% !important;
    gap: 8px !important;
  }
  body.catalogue-page #products-grid .product-info {
    padding: 8px 9px 10px !important;
  }
}

/* §23.17) PRODUITS.HTML — Centrage select tri mobile (≤480px) ==========
   NOTE numérotation : §23.10-§23.16 déjà utilisés. On utilise §23.17.

   CAUSE EXACTE :
     Mon §23.1 (≤480px) met sur le select tri :
       width: 100%; min-height: 40px; padding: 6px 10px;
       font-size: 13px; border-radius: 10px
     MAIS NE PRÉCISE PAS `text-align: center`.
     Par défaut, un <select> HTML aligne son texte à GAUCHE.
     Résultat : "Par défaut" (option visible) collé à gauche du select
     plein largeur 100%, déséquilibré visuellement.

   SOLUTION : text-align: center + text-align-last: center sur le select.
   La propriété `text-align-last: center` est CRITIQUE pour les <select>
   car `text-align` seul ne centre pas le texte de l'option visible
   (control native browser). `text-align-last` est supportée par tous
   les navigateurs modernes (Chrome, Firefox, Safari, Edge).

   Padding ajusté pour laisser place à la flèche dropdown native droite :
   padding-right: 32px (espace flèche), padding-left: 0 (compense pour
   centrage visuel équilibré).

   Scope strict : @media (max-width: 480px). Desktop intact.
   ===================================================================== */
@media (max-width: 480px) {
  body.catalogue-page #sort-select,
  body.catalogue-page .sort-select {
    text-align: center !important;
    text-align-last: center !important;
    /* Padding asymétrique : 0 gauche + 32 droite pour compenser la
       flèche native du select et garder l'option visible centrée
       visuellement dans la zone effective */
    padding-left: 0 !important;
    padding-right: 32px !important;
  }
  /* Options dans le menu déroulant : centrées aussi (cosmétique, certains
     navigateurs respectent) */
  body.catalogue-page #sort-select option,
  body.catalogue-page .sort-select option {
    text-align: center;
  }
}

/* ═══════════════════════════════════════════════════════════════════
   FIN §23 POLISH MOBILE CIBLÉ — 4 PAGES
   ═══════════════════════════════════════════════════════════════════ */

/* ═══════════════════════════════════════════════════════════════════
   §24. PRODUIT-DETAIL MOBILE POLISH (2026-05-02)
   -------------------------------------------------------------------
   Page cible : produit-detail.html (body.product-detail-page).

   CLASSES EXACTES vérifiées dans produit-detail.html + tu-reviews-v2.css :

     1. Select tri avis :
        .tu-rv-sort#reviews-sortbar > .tu-rv-sort__label "Trier"
        + select#reviews-sort.tu-rv-select (option visible "Meilleurs avis")

     2-4. Cartes avis (templating JS, classes confirmées tu-reviews.css) :
        .tu-rv-card (carte principale)
          > .tu-rv-card__head > .tu-rv-avatar + .tu-rv-card__who
                                                > .tu-rv-card__name (auteur "Tony G.")
                                                + .tu-rv-card__date (date/heure)
          > .tu-rv-card__rating (étoiles)
          > .tu-rv-card__quote (citation/commentaire)
          > .tu-rv-card__body (corps avis)
          > .tu-rv-card__foot ("Avis utile" etc.)
        Legacy aussi : .review-card dans #reviews-list / #popup-reviews-list

     5. Recos "Dans le même univers" :
        section.suggested-products-section.tu-reco--suggest#suggest-section
          > #suggested-products.products-grid.tu-reco-grid
          (cards = .product-card standard)
        + crosssell : section#crosssell-section + #crosssell-products

     6. Bouton "Ajouter cette pièce" / sticky CTA bundle :
        .tu-outfit-cta (et .tu-suggest-cta variant) >
          > .tu-outfit-cta-title (kicker + main + sub)
          > .tu-outfit-cta-action (button) >
              > .tu-outfit-cta-action-price (label + value gauche)
              > .tu-outfit-cta-action-text (texte droite + .tu-outfit-cta-action-icon)
        Texte change selon nombre sélectionné : "Sélectionnez des pièces" /
        "Une pièce prête à ajouter" / etc. (vu JS l. 8024-8030)

     7. Bloc "Composez votre silhouette" / "Pièce sélectionnée" :
        .tu-outfit-board (role=group) >
          > .tu-outfit-board-label "Pièces à associer"
          > .tu-outfit-board-pieces#tu-outfit-pieces (chips JS-injectés)
              chips: .tu-outfit-board-chip > .tu-outfit-board-chip-dot + texte
              empty: .tu-outfit-board-empty
          > .tu-outfit-board-total > -label + -value

   STRATÉGIE :
     Tout scopé body.product-detail-page (jamais global).
     Hooks IDs uniques utilisés quand possible (#reviews-sort,
     #suggested-products, #crosssell-products, #tu-outfit-pieces).
     Aucune règle globale sur .product-card / .review-card / .btn.
   ═══════════════════════════════════════════════════════════════════ */

/* §24.1) Select tri avis — "Meilleurs avis" centré (≤768px) ============
   WHY: §23.17 a déjà résolu le centrage du select tri produits
        (.sort-select catalogue-page). Ici on applique le même pattern
        au select tri avis (#reviews-sort) sur produit-detail. */
@media (max-width: 768px) {
  body.product-detail-page #reviews-sort,
  body.product-detail-page .tu-rv-select {
    text-align: center !important;
    text-align-last: center !important;
    padding-left: 0 !important;
    padding-right: 32px !important;          /* espace flèche dropdown native */
  }
  body.product-detail-page #reviews-sort option,
  body.product-detail-page .tu-rv-select option {
    text-align: center;
  }
  /* La sortbar elle-même : centrée sur mobile */
  body.product-detail-page .tu-rv-sort,
  body.product-detail-page #reviews-sortbar {
    justify-content: center !important;
    flex-wrap: wrap !important;
    gap: 8px !important;
  }
}

/* §24.2/3/4) Cartes avis — auteur/date/étoiles/badge/commentaire centrés
   (≤768px) WHY: tu-reviews.css ligne 522+ pose .tu-rv-card__head en flex
        row avec text-align left par défaut. À mobile on stack en column
        centrée pour un rendu plus premium et symétrique. */
@media (max-width: 768px) {
  /* Header avec avatar : passe en column, avatar au-dessus, infos en
     dessous, le tout centré */
  body.product-detail-page .tu-product-reviews .tu-rv-card__head {
    flex-direction: column !important;
    align-items: center !important;
    text-align: center !important;
    gap: 8px !important;
  }
  /* Wrapper "who" (nom + date) centré */
  body.product-detail-page .tu-product-reviews .tu-rv-card__who {
    text-align: center !important;
    align-items: center !important;
    width: 100% !important;
    display: flex !important;
    flex-direction: column !important;
    gap: 4px !important;
  }
  /* Nom auteur "Tony G." centré */
  body.product-detail-page .tu-product-reviews .tu-rv-card__name {
    text-align: center !important;
    margin-left: auto !important;
    margin-right: auto !important;
    width: 100% !important;
  }
  /* Date / heure centrées */
  body.product-detail-page .tu-product-reviews .tu-rv-card__date {
    text-align: center !important;
    margin-left: auto !important;
    margin-right: auto !important;
    justify-content: center !important;
    display: flex !important;
    align-items: center !important;
    flex-wrap: wrap !important;
    gap: 4px !important;
  }
  /* Étoiles notation centrées */
  body.product-detail-page .tu-product-reviews .tu-rv-card__rating {
    display: flex !important;
    justify-content: center !important;
    align-items: center !important;
    text-align: center !important;
    margin-left: auto !important;
    margin-right: auto !important;
    flex-wrap: wrap !important;
    gap: 4px !important;
  }
  /* Commentaire / quote centré */
  body.product-detail-page .tu-product-reviews .tu-rv-card__quote,
  body.product-detail-page .tu-product-reviews .tu-rv-card__body {
    text-align: center !important;
  }
  /* Footer carte (Avis utile, signaler, etc.) centré */
  body.product-detail-page .tu-product-reviews .tu-rv-card__foot {
    justify-content: center !important;
    text-align: center !important;
    flex-wrap: wrap !important;
  }
  /* Legacy .review-card aussi (markup mixte vu tu-reviews-v2.css) */
  body.product-detail-page #reviews-list .review-card,
  body.product-detail-page #popup-reviews-list .review-card {
    text-align: center !important;
  }
  body.product-detail-page #reviews-list .review-card .review-header,
  body.product-detail-page #popup-reviews-list .review-card .review-header {
    flex-direction: column !important;
    align-items: center !important;
    text-align: center !important;
  }
}

/* §24.5) Recos "Dans le même univers" + Crosssell — noms/prix centrés
   (≤768px) WHY: scope ID strict (#suggested-products, #crosssell-products)
   pour ne PAS impacter les .product-card des autres pages. */
@media (max-width: 768px) {
  /* Suggested products (Dans le même univers) */
  body.product-detail-page #suggested-products .product-card .product-info {
    text-align: center !important;
    align-items: center !important;
  }
  body.product-detail-page #suggested-products .product-card .product-name {
    text-align: center !important;
    margin-left: auto !important;
    margin-right: auto !important;
  }
  body.product-detail-page #suggested-products .product-card .product-price {
    display: flex !important;
    justify-content: center !important;
    align-items: baseline !important;
    text-align: center !important;
    margin-left: auto !important;
    margin-right: auto !important;
    flex-wrap: wrap !important;
    gap: 6px !important;
  }
  body.product-detail-page #suggested-products .product-card .current-price,
  body.product-detail-page #suggested-products .product-card .original-price {
    text-align: center !important;
  }
  body.product-detail-page #suggested-products .product-card .product-rating {
    display: flex !important;
    justify-content: center !important;
    text-align: center !important;
    margin-left: auto !important;
    margin-right: auto !important;
    flex-wrap: wrap !important;
  }

  /* Crosssell products (Complétez votre tenue) */
  body.product-detail-page #crosssell-products .product-card .product-info {
    text-align: center !important;
    align-items: center !important;
  }
  body.product-detail-page #crosssell-products .product-card .product-name {
    text-align: center !important;
    margin-left: auto !important;
    margin-right: auto !important;
  }
  body.product-detail-page #crosssell-products .product-card .product-price {
    display: flex !important;
    justify-content: center !important;
    align-items: baseline !important;
    text-align: center !important;
    margin-left: auto !important;
    margin-right: auto !important;
    flex-wrap: wrap !important;
    gap: 6px !important;
  }
  body.product-detail-page #crosssell-products .product-card .current-price,
  body.product-detail-page #crosssell-products .product-card .original-price {
    text-align: center !important;
  }
}

/* §24.6) Bouton "Ajouter cette pièce" / .tu-outfit-cta — anti-overflow
   (≤768px) WHY: le bouton .tu-outfit-cta-action contient 2 colonnes
   (price gauche + text droite). À mobile, le texte "Ajouter cette pièce"
   peut déborder du conteneur. Solution : flex-wrap + min-width:0 + text
   wrap propre + font-size réduit pour rester dans le cadre. */
@media (max-width: 768px) {
  /* Conteneur outfit-cta : empêche overflow horizontal */
  body.product-detail-page .tu-outfit-cta {
    overflow: hidden !important;
    box-sizing: border-box !important;
    max-width: 100% !important;
  }
  body.product-detail-page .tu-outfit-cta-title {
    text-align: center !important;
    width: 100% !important;
  }
  /* Bouton CTA : flex wrap pour empêcher overflow */
  body.product-detail-page .tu-outfit-cta-action {
    display: flex !important;
    flex-wrap: wrap !important;
    align-items: center !important;
    justify-content: center !important;
    width: 100% !important;
    max-width: 100% !important;
    min-width: 0 !important;
    box-sizing: border-box !important;
    padding: 10px 12px !important;
    gap: 6px 10px !important;
  }
  /* Zone prix gauche : peut shrink */
  body.product-detail-page .tu-outfit-cta-action-price {
    min-width: 0 !important;
    flex: 0 1 auto !important;
    text-align: center !important;
  }
  /* Zone texte droite : wrap propre, font compact */
  body.product-detail-page .tu-outfit-cta-action-text {
    min-width: 0 !important;
    flex: 1 1 auto !important;
    white-space: normal !important;
    text-align: center !important;
    font-size: 13px !important;
    line-height: 1.3 !important;
    display: inline-flex !important;
    align-items: center !important;
    justify-content: center !important;
    gap: 6px !important;
    word-break: break-word !important;
  }
  /* Icône cart panier : taille fixe, ne shrink pas */
  body.product-detail-page .tu-outfit-cta-action-icon {
    flex: 0 0 auto !important;
    width: 16px !important;
    height: 16px !important;
  }
}

/* §24.7) Bloc "Composez votre silhouette" / "Pièce sélectionnée" —
   chips et noms centrés (≤768px) WHY: .tu-outfit-board contient des
   chips JS-injectés (.tu-outfit-board-chip) + label + total. À mobile,
   tout doit être centré pour un rendu cohérent avec le reste du site. */
@media (max-width: 768px) {
  body.product-detail-page .tu-outfit-board {
    text-align: center !important;
    align-items: center !important;
  }
  body.product-detail-page .tu-outfit-board-label,
  body.product-detail-page #tu-outfit-board-label {
    text-align: center !important;
    width: 100% !important;
    display: block !important;
  }
  /* Chips collections : flex-wrap centré */
  body.product-detail-page .tu-outfit-board-pieces,
  body.product-detail-page #tu-outfit-pieces {
    display: flex !important;
    flex-wrap: wrap !important;
    justify-content: center !important;
    align-items: center !important;
    gap: 8px !important;
    text-align: center !important;
  }
  body.product-detail-page .tu-outfit-board-chip {
    display: inline-flex !important;
    align-items: center !important;
    justify-content: center !important;
    gap: 6px !important;
    text-align: center !important;
    flex: 0 0 auto !important;
    white-space: nowrap !important;
  }
  body.product-detail-page .tu-outfit-board-empty {
    display: block !important;
    text-align: center !important;
    width: 100% !important;
  }
  /* Total sélection centré */
  body.product-detail-page .tu-outfit-board-total {
    display: flex !important;
    flex-direction: column !important;
    align-items: center !important;
    justify-content: center !important;
    text-align: center !important;
    gap: 4px !important;
  }
  body.product-detail-page .tu-outfit-board-total-label,
  body.product-detail-page .tu-outfit-board-total-value {
    text-align: center !important;
  }
}

/* §24.8) FORCE CENTERING POST-TEST — spécificité ID renforcée (≤768px)
   CAUSE EXACTE de l'échec §24 :

     Mes sélecteurs §24 utilisaient :
       body.product-detail-page .tu-product-reviews .tu-rv-card__name
       = spécificité (0,0,3,1) — 3 classes + 1 element

     Mais tu-reviews-v2.css contient :
       body.product-detail-page .tu-product-reviews .tu-rv-card .tu-rv-card__quote
       = spécificité (0,0,4,1) — 4 classes + 1 element → GAGNE

     Mon `!important` ne suffit pas car tu-reviews-v2.css a aussi des
     règles avec ses propres props (background, padding, display) qui
     gardent leur impact même si mes !important match les mêmes props.

   SOLUTION : passer en spécificité ID en utilisant #reviews-section
   (ID parent unique de la zone avis). ID compte +1 niveau spécificité.

     body.product-detail-page #reviews-section .tu-rv-card__name
     = spécificité (0,1,2,1) → BAT (0,0,4,1)

   Idem pour recos : utiliser #suggested-products / #crosssell-products
   en sélecteur direct + renforcer flex-direction column sur .product-info.
   ===================================================================== */

/* §24.8.1) Avis cartes — force centering avec spécificité ID (≤768px)
   WHY: utiliser #reviews-section pour battre tu-reviews-v2.css. */
@media (max-width: 768px) {
  /* Cartes principales : centrage de tous les enfants */
  body.product-detail-page #reviews-section .tu-rv-card,
  body.product-detail-page #reviews-section .tu-rv-card__head,
  body.product-detail-page #reviews-section .tu-rv-card__who,
  body.product-detail-page #reviews-section .tu-rv-card__body,
  body.product-detail-page #reviews-section .tu-rv-card__foot {
    text-align: center !important;
    align-items: center !important;
    justify-content: center !important;
  }

  /* Header carte avis : column stack avec avatar au-dessus */
  body.product-detail-page #reviews-section .tu-rv-card__head {
    display: flex !important;
    flex-direction: column !important;
    gap: 10px !important;
  }

  /* Wrapper "who" (nom + date) en column centré */
  body.product-detail-page #reviews-section .tu-rv-card__who {
    display: flex !important;
    flex-direction: column !important;
    width: 100% !important;
    max-width: 100% !important;
    margin-inline: auto !important;
  }

  /* Texte du nom, date, commentaire : block + 100% width + center */
  body.product-detail-page #reviews-section .tu-rv-card__name,
  body.product-detail-page #reviews-section .tu-rv-card__date,
  body.product-detail-page #reviews-section .tu-rv-card__quote,
  body.product-detail-page #reviews-section .tu-rv-card__body,
  body.product-detail-page #reviews-section .tu-rv-card__body p {
    display: block !important;
    width: 100% !important;
    text-align: center !important;
    margin-left: auto !important;
    margin-right: auto !important;
  }

  /* Étoiles + badge "Achat vérifié" : flex centré, fit-content pour
     ne pas étirer le bloc, margin auto pour centrage horizontal.
     Sélecteur attribut [class*="star"] couvre toutes variantes star/stars. */
  body.product-detail-page #reviews-section .tu-rv-card__rating,
  body.product-detail-page #reviews-section .tu-rv-card__verified,
  body.product-detail-page #reviews-section .tu-rv-card__badge,
  body.product-detail-page #reviews-section .tu-rv-verified,
  body.product-detail-page #reviews-section .tu-rv-stars,
  body.product-detail-page #reviews-section .tu-rv-card .stars,
  body.product-detail-page #reviews-section .tu-rv-card [class*="star"] {
    display: flex !important;
    justify-content: center !important;
    align-items: center !important;
    width: fit-content !important;
    max-width: 100% !important;
    margin-left: auto !important;
    margin-right: auto !important;
    text-align: center !important;
  }

  /* Legacy .review-card (vu tu-reviews-v2.css l. 73-85) — couverture aussi */
  body.product-detail-page #reviews-section .review-card,
  body.product-detail-page #reviews-section .review-card .review-header,
  body.product-detail-page #reviews-section .review-card .review-body,
  body.product-detail-page #reviews-section .review-card .review-footer {
    text-align: center !important;
    align-items: center !important;
    justify-content: center !important;
  }
  body.product-detail-page #reviews-section .review-card .review-header {
    display: flex !important;
    flex-direction: column !important;
  }
}

/* §24.8.2) Recos — force centering noms/prix avec spécificité (≤768px)
   WHY: tu-product-enhance.css ou autres CSS catalogue.css peuvent avoir
        leur propres règles sur .tu-reco-grid .product-card. On force
        avec ID + flex column sur .product-info pour battre. */
@media (max-width: 768px) {
  /* Card containers : text-align center sur la card et l'info */
  body.product-detail-page #suggested-products .product-card,
  body.product-detail-page #crosssell-products .product-card {
    text-align: center !important;
  }

  body.product-detail-page #suggested-products .product-card .product-info,
  body.product-detail-page #crosssell-products .product-card .product-info {
    text-align: center !important;
    align-items: center !important;
    justify-content: center !important;
    display: flex !important;
    flex-direction: column !important;
  }

  /* Nom / current-price / original-price : block + 100% + center */
  body.product-detail-page #suggested-products .product-card .product-name,
  body.product-detail-page #crosssell-products .product-card .product-name,
  body.product-detail-page #suggested-products .product-card .current-price,
  body.product-detail-page #crosssell-products .product-card .current-price,
  body.product-detail-page #suggested-products .product-card .original-price,
  body.product-detail-page #crosssell-products .product-card .original-price {
    display: block !important;
    width: 100% !important;
    text-align: center !important;
    margin-left: auto !important;
    margin-right: auto !important;
  }

  /* product-price : flex baseline pour aligner current + original sur
     même ligne mais centré */
  body.product-detail-page #suggested-products .product-card .product-price,
  body.product-detail-page #crosssell-products .product-card .product-price {
    display: flex !important;
    justify-content: center !important;
    align-items: baseline !important;
    flex-wrap: wrap !important;
    gap: 6px !important;
    text-align: center !important;
    width: 100% !important;
    margin-left: auto !important;
    margin-right: auto !important;
  }

  /* Rating si présent */
  body.product-detail-page #suggested-products .product-card .product-rating,
  body.product-detail-page #crosssell-products .product-card .product-rating {
    display: flex !important;
    justify-content: center !important;
    align-items: center !important;
    text-align: center !important;
    flex-wrap: wrap !important;
    gap: 4px !important;
    margin-left: auto !important;
    margin-right: auto !important;
  }
}

/* §24.8.3) Bouton "Ajouter cette pièce" — anti-overflow renforcé (≤768px)
   WHY: §24.6 mettait flex-wrap mais le texte peut encore déborder.
        On ajoute overflow-wrap: anywhere + word-break: break-word pour
        forcer le wrap à n'importe quel point. */
@media (max-width: 768px) {
  body.product-detail-page .tu-outfit-cta-action {
    overflow: hidden !important;
    max-width: 100% !important;
  }
  body.product-detail-page .tu-outfit-cta-action-text {
    min-width: 0 !important;
    max-width: 100% !important;
    white-space: normal !important;
    overflow-wrap: anywhere !important;
    word-break: break-word !important;
    text-align: center !important;
  }
}

/* §24.8.4) Pièce sélectionnée — renforcement chips (≤768px) =============
   WHY: §24.7 mettait flex-wrap centré mais peut être écrasé par CSS
        spécifique. On renforce avec display flex !important. */
@media (max-width: 768px) {
  body.product-detail-page #tu-outfit-pieces,
  body.product-detail-page .tu-outfit-board-pieces {
    display: flex !important;
    flex-wrap: wrap !important;
    justify-content: center !important;
    align-items: center !important;
    text-align: center !important;
  }
  body.product-detail-page .tu-outfit-board-chip {
    display: inline-flex !important;
    justify-content: center !important;
    align-items: center !important;
    text-align: center !important;
  }
}

/* ═══════════════════════════════════════════════════════════════════
   FIN §24 PRODUIT-DETAIL MOBILE POLISH
   ═══════════════════════════════════════════════════════════════════ */

/* ═══════════════════════════════════════════════════════════════════
   §25 — PRÉ-BÊTA POLISH 2026-05-05 — produit-detail.html
   -----------------------------------------------------------------
   Polish minimum pré-bêta. Tunnel client (panier, wishlist, stock,
   checkout, paiement, success, facture) déjà validé OK — ce bloc
   ne touche AUCUN sélecteur métier critique :
   ✓ aucune modif sur .add-to-cart-btn / #add-to-cart-btn behavior
   ✓ aucune modif sur .wishlist-btn-detail behavior
   ✓ aucune modif sur #size-options / #color-options state classes
     (.selected / .disabled / .out-of-stock / .tuv-disabled)
   ✓ aucune modif sur .quantity-control values
   ✓ aucune modif sur .sticky-mobile-bar / #sticky-mobile-cart-btn
   Scope strict : body.product-detail-page (≤768px).

   Trois ajouts purement défensifs :
   §25.1) :focus-visible unifié sur les boutons critiques mobile
          (a11y clavier — Bluetooth/iPad — outline lisible).
   §25.2) Labels tailles longues : wrap propre au lieu d'overflow
          horizontal si une variante a un nom étendu.
   §25.3) Touch-action manipulation sur les inputs numériques pour
          retirer le double-tap zoom indésirable iOS sur le compteur
          quantité (pertinent même si la qty n'est pas visible mobile,
          futur-proof si le sticky bar évolue).

   Aucun `!important` introduit ; on s'appuie sur la spécificité
   body.product-detail-page (0,1,1) qui suffit à matcher ou battre
   les règles existantes sans escalation.
   ═══════════════════════════════════════════════════════════════════ */
@media (max-width: 768px) {
  /* §25.1) :focus-visible — outline lisible sur boutons critiques */
  body.product-detail-page #add-to-cart-btn:focus-visible,
  body.product-detail-page #sticky-mobile-cart-btn:focus-visible,
  body.product-detail-page #wishlist-btn-detail:focus-visible,
  body.product-detail-page #size-options .option-value:focus-visible,
  body.product-detail-page #color-options .color-option:focus-visible,
  body.product-detail-page .product-thumbnails .thumbnail-image:focus-visible,
  body.product-detail-page .gallery-nav-btn:focus-visible,
  body.product-detail-page .tab-button:focus-visible {
    outline: 2px solid var(--primary-color, #2ECC71);
    outline-offset: 2px;
    /* On retire l'outline default (tab focus auto) seulement quand
       :focus-visible match — le focus tactile reste "invisible". */
  }
  body.dark-mode body.product-detail-page #add-to-cart-btn:focus-visible,
  body.dark-mode body.product-detail-page #sticky-mobile-cart-btn:focus-visible,
  body.dark-mode body.product-detail-page #wishlist-btn-detail:focus-visible,
  body.dark-mode body.product-detail-page #size-options .option-value:focus-visible,
  body.dark-mode body.product-detail-page #color-options .color-option:focus-visible,
  body.dark-mode body.product-detail-page .product-thumbnails .thumbnail-image:focus-visible,
  body.dark-mode body.product-detail-page .gallery-nav-btn:focus-visible,
  body.dark-mode body.product-detail-page .tab-button:focus-visible {
    outline-color: #5ED480;
  }

  /* §25.2) Labels tailles longues — wrap propre + line-height tight.
     §21 (L741) ne pose pas de white-space → comportement par défaut
     `normal` qui peut couper en ligne 2. On garantit un alignement
     vertical correct si ça arrive (variantes long-name). */
  body.product-detail-page #size-options .option-value {
    white-space: normal;
    line-height: 1.18;
    word-break: keep-all;
  }

  /* §25.3) Anti double-tap zoom iOS sur le compteur quantité.
     Même si .product-actions est display:none mobile (cf
     #tu-pd-mobile-cleanup ligne 7188), on prépare le futur en cas
     de réintroduction du compteur dans la sticky bar. No-op visuel,
     pas de risque de régression. */
  body.product-detail-page .quantity-control input,
  body.product-detail-page .quantity-control button {
    touch-action: manipulation;
  }
}

/* ═══════════════════════════════════════════════════════════════════
   FIN §25 PRÉ-BÊTA POLISH 2026-05-05
   ═══════════════════════════════════════════════════════════════════ */

/* ═══════════════════════════════════════════════════════════════════
   FIN tu-mobile-polish.css
   ═══════════════════════════════════════════════════════════════════ */
