@charset "UTF-8";
/* ═══════════════════════════════════════════════════════════════════
   boutique/scroll-doux.css — LE DÉFILEMENT PREMIUM, CÔTÉ FEUILLE.

   Deux choses vivent ici, et une seule est visible :

   1. L'ÉTAT CACHÉ DES BLOCS QUI ENTRENT. Il n'existe QUE derrière
      :root[data-doux="1"], un attribut que scroll-doux.js pose lui-même
      au démarrage. C'est la règle la plus importante de ce fichier, et
      elle a déjà été payée ici : si on écrit « .doux-entre{opacity:0} »
      en dur et que le script ne part pas — fichier bloqué, erreur
      au-dessus, navigateur sans IntersectionObserver — la boutique
      s'affiche VIDE. Avec le drapeau, pas de script = pas de règle =
      page entière visible. On part visible, on anime ; jamais l'inverse.

   2. LA COUPURE DU DÉFILEMENT NATIF PENDANT L'INERTIE.
      socle.css pose html{scroll-behavior:smooth} : sans ce garde, chaque
      window.scrollTo() de la boucle d'inertie lancerait EN PLUS une
      animation native, et les deux se battraient à chaque image. Le
      drapeau data-doux-inertie n'est posé que pendant le glissement, il
      est retiré à l'arrêt — donc les ancres du sommaire (#huiles…)
      gardent leur défilement doux natif le reste du temps.

   CE QU'ON N'ANIME PAS, ET POURQUOI :
   uniquement `opacity` et `transform`. Ce sont les deux seules
   propriétés que le compositeur traite sans refaire la mise en page.
   Un `top`, un `margin`, une `width` animés obligeraient le navigateur
   à recalculer la page à chaque image — c'est exactement ce qui fait
   tomber un téléphone d'entrée de gamme sous les 60 images/seconde.

   PAS DE will-change ICI, ET C'EST VOULU. Sur une page à 45 produits,
   un will-change permanent = autant de calques gardés en mémoire pour
   rien. Une transition d'opacité/transform fait promouvoir l'élément
   toute seule, le temps de l'animation, puis le calque est rendu.
   Pas de translate3d() non plus pour la même raison : la version 3D
   force un calque en permanence, la version 2D non.

   ACCESSIBILITÉ : on coupe le MOUVEMENT, jamais le CONTENU. Sous
   prefers-reduced-motion comme sous :root[data-calme="1"], les blocs
   sont là, entiers, lisibles — simplement immobiles.
   ═══════════════════════════════════════════════════════════════════ */

:root{
  /* La montée : assez pour qu'on la sente, assez peu pour qu'on ne
     l'attende pas. Au-delà de ~30 px le bloc « arrive en retard ». */
  --doux-montee: 22px;
  --doux-glisse: 26px;
  --doux-duree: 640ms;
  /* Sortie franche puis pose lente : la courbe des sites primés.
     C'est la même que --e-sortie de socle.css, recopiée pour que ce
     fichier reste utilisable seul. */
  --doux-e: cubic-bezier(.22,1,.36,1);
}

/* ── L'ÉTAT CACHÉ ─────────────────────────────────────────────────
   Verrouillé derrière data-doux : voir l'en-tête. */
:root[data-doux="1"] .doux-entre{
  opacity:0;
  transform:translateY(var(--doux-montee));
  transition:opacity var(--doux-duree) var(--doux-e),
             transform var(--doux-duree) var(--doux-e);
}
:root[data-doux="1"] .doux-entre.doux-vu{
  opacity:1;
  transform:none;
}

/* Variantes, posées à la main avec data-doux sur le balisage.
   « fondu » pour les grands blocs : au-delà d'une certaine surface, une
   montée devient un glissement de page entière, et ça donne le mal de
   mer. « gauche »/« droite » pour les colonnes d'un duo. */
:root[data-doux="1"] .doux-entre[data-doux="fondu"]{transform:none}
:root[data-doux="1"] .doux-entre[data-doux="gauche"]{
  transform:translateX(calc(var(--doux-glisse) * -1))}
:root[data-doux="1"] .doux-entre[data-doux="droite"]{
  transform:translateX(var(--doux-glisse))}

/* ── L'INERTIE ────────────────────────────────────────────────────
   Posé par le script au début du glissement, retiré à l'arrêt.
   :root[attr] (0,1,0,1) bat html{} (0,0,0,1) quel que soit l'ordre des
   feuilles : ce fichier n'a donc pas besoin d'être chargé après
   socle.css pour que la coupure prenne. */
:root[data-doux-inertie="1"]{scroll-behavior:auto}

/* ── LE CALME ─────────────────────────────────────────────────────
   Le script retire déjà data-doux dans ces deux cas, donc l'état caché
   n'existe plus. Ces règles sont le second filet : elles rattrapent un
   élément déjà marqué au moment où l'utilisateur appuie sur « Réduire
   les animations », et surtout elles annulent le
   « html[data-calme=1] * {transition:none!important} » de socle.css,
   qui figerait sinon un bloc à mi-fondu, invisible pour toujours. */
@media (prefers-reduced-motion:reduce) and (min-width:999999px) /* desarme 17/08 : data-calme est le seul interrupteur */{
  :root[data-doux="1"] .doux-entre,
  :root[data-doux="1"] .doux-entre.doux-vu{
    opacity:1;
    transform:none;
    transition:none;
  }
}
:root[data-calme="1"] .doux-entre,
:root[data-calme="1"] .doux-entre.doux-vu{
  opacity:1!important;
  transform:none!important;
  transition:none!important;
  transition-delay:0s!important;
}

/* ── L'IMPRESSION ─────────────────────────────────────────────────
   Un bloc jamais entré à l'écran est resté à opacity:0 ; imprimé tel
   quel, il sort blanc. Une commande imprimée doit être entière. */
@media print{
  :root[data-doux="1"] .doux-entre,
  :root[data-doux="1"] .doux-entre.doux-vu{
    opacity:1!important;
    transform:none!important;
    transition:none!important;
  }
}
