/* Animation au défilement des fiches produit (bloc .an, build.py anim_html, données data_src/animations/<réf.>.json).
   Rudy, 26/10/2026 : seulement la boîte qui s'ouvre et les sachets qui sortent, sans blocage du défilement
   (pas de scène collante : l'animation se joue pendant que la scène traverse l'écran). Les textes sont en dessous (.an-txt).
   Sans .is-live (pas de JS, « Réduire les animations ») : image fixe de la boîte ouverte, sachets en éventail.
   Seules transform et opacity sont animées. */
.an{margin:4px 0 18px}
.an-scene{position:relative;margin:0 auto;width:100%;max-width:460px;background:none;border:0;border-radius:0;padding:0;overflow:hidden;-webkit-user-select:none;user-select:none;-webkit-touch-callout:none}
.an-board{position:relative;width:100%;aspect-ratio:828/835;margin:0 auto}
.an-board img{position:absolute;inset:0;width:100%;height:100%;max-width:none;pointer-events:none;-webkit-user-drag:none}
.an-lid{opacity:0}
.an-lid.an-l-last{opacity:1}
.an-fan{position:absolute;inset:0;z-index:0}
.an-fan img{inset:auto;transform-origin:50% 135%;transform:translateY(var(--up)) rotate(var(--a))}
.an-logo{position:absolute;top:12px;right:14px;display:flex;align-items:center;gap:6px;font-family:var(--display);font-weight:900;font-size:12px;letter-spacing:-.01em;color:var(--ink);opacity:.55;pointer-events:none;z-index:3}
.an-logo img{width:20px;height:20px}
/* textes d'information : blocs statiques, dans le corps de la fiche */
.an-txt{margin:0 0 22px;display:grid;gap:14px}
.an-i h3{font-size:20px;margin:0 0 6px;color:var(--ink)}
.an-i p{margin:0;font-size:17px;line-height:1.5}
.an-i .an-small{margin-top:4px;font-size:15px;color:var(--muted)}
.an .an-pills,.an-txt .an-pills{display:flex;flex-wrap:wrap;gap:6px;margin:0 0 8px;padding:0;list-style:none}
.an-pills li{margin:0;font-size:13px;font-weight:700;background:#eef4ef;color:var(--accent);border-radius:999px;padding:3px 10px}
.an-note{margin:0;font-size:12px;color:var(--muted)}

/* ---- version animée (avancement réglé par anim.js) ---- */
.an.is-live .an-anim{animation-timing-function:linear;animation-fill-mode:both;animation-play-state:paused;animation-duration:var(--u);animation-delay:var(--d)}
.an.is-live .an-out{animation-name:an-out}
.an.is-live .an-flash{animation-name:an-flash}
.an.is-live .an-in{animation-name:an-in}
.an.is-live .an-fan img{animation-name:an-fan;animation-timing-function:cubic-bezier(.2,.7,.2,1)}
.an.is-live .an-board{animation-name:an-zoom}
@keyframes an-out{from{opacity:1}to{opacity:0}}
@keyframes an-in{from{opacity:0}to{opacity:1}}
@keyframes an-flash{0%{opacity:0}40%{opacity:1}99.9%{opacity:1}100%{opacity:0}}
/* sachets invisibles tant que le couvercle n'est pas ouvert (Rudy, 26/10/2026 : aucun sachet visible sur la boîte fermée) */
@keyframes an-fan{0%{opacity:0;transform:translateY(0) rotate(0deg)}8%{opacity:1}100%{opacity:1;transform:translateY(var(--up)) rotate(var(--a))}}
@keyframes an-zoom{from{transform:scale(.94) translateY(3%)}to{transform:none}}
@media (max-width:900px){.an-i h3{font-size:19px}.an-i p{font-size:16px}.an-i .an-small{font-size:14px}}
@media (prefers-reduced-motion:reduce){.an .an-anim{animation:none!important}}

/* ---- calques 2D (build.py anim_calques : 815, 834, 877, C9) ----
   Rudy, 26/10/2026 : feuilles d'aloe floues, halo, gouttes et produit en parallaxe, pastilles en cascade sous la scène.
   État de base = image finale (sans JavaScript ou avec « Réduire les animations », tout est en place et lisible). */
.an-2d .an-scene{max-width:440px;border-radius:26px;background:linear-gradient(170deg,var(--fond0,#f1f7ec) 0%,var(--fond1,#e3efd9) 100%);isolation:isolate}
.an-2d .an-board{overflow:hidden;border-radius:inherit}
.an-2d .an-board img{inset:auto;height:auto}
.an-2d .an-feuilles{left:-8%;top:-8%;width:116%!important;opacity:.5;-webkit-mask-image:radial-gradient(closest-side,#000 40%,transparent 100%);mask-image:radial-gradient(closest-side,#000 40%,transparent 100%)}
.an-halo{position:absolute;left:50%;width:84%;aspect-ratio:1;margin:-42% 0 0 -42%;border-radius:50%;background:radial-gradient(closest-side,var(--halo) 0%,transparent 100%)}
.an-ombre{position:absolute;left:30%;width:40%;height:7%;border-radius:50%;background:radial-gradient(closest-side,rgba(30,60,30,.28),transparent);z-index:1}
.an-gouttes{position:absolute;inset:0;z-index:1}
.an-gouttes.an-devant{z-index:3}
.an-goutte{position:absolute;aspect-ratio:1;border-radius:50% 50% 50% 50%/60% 60% 40% 40%;background:radial-gradient(circle at 34% 30%,rgba(255,255,255,.95) 0 14%,rgba(255,255,255,.45) 34%,rgba(176,214,150,.28) 72%,rgba(120,170,100,.18) 100%);box-shadow:inset 0 -1px 2px rgba(60,110,50,.25),0 2px 6px rgba(40,80,40,.12)}
.an-2d .an-prod{position:absolute;z-index:2;max-width:none}
/* pastilles et jours : vrai texte, sous la scène */
.an-chips{display:flex;flex-wrap:wrap;justify-content:center;gap:8px;max-width:520px;margin:14px auto 0;padding:0;list-style:none}
.an-chips li{margin:0;font-size:14px;font-weight:700;line-height:1.25;background:#fff;color:var(--accent);border:1px solid #d6e6d2;border-radius:999px;padding:6px 12px;box-shadow:0 1px 2px rgba(20,60,30,.06)}
.an-jours{display:flex;flex-direction:column;align-items:center;gap:8px;margin:14px auto 0}
.an-jours b{font-family:var(--display);font-weight:900;font-size:16px;color:var(--ink)}
.an-jours ol{display:flex;gap:6px;margin:0;padding:0;list-style:none}
.an-jours li{position:relative;display:flex;align-items:center;justify-content:center;width:28px;height:28px;border-radius:50%;border:1.5px solid #7e57c2;color:#4b2c8a;font-size:13px;font-weight:700;overflow:hidden;z-index:0}
.an-jours li span{position:absolute;inset:0;border-radius:50%;background:#ece4f8;z-index:-1}
.an.is-live .an-feuilles{animation-name:an-par}
.an.is-live .an-halo{animation-name:an-halo;animation-timing-function:cubic-bezier(.2,.7,.2,1)}
.an.is-live .an-ombre{animation-name:an-ombre;animation-timing-function:cubic-bezier(.2,.7,.2,1)}
.an.is-live .an-prod{animation-name:an-monte;animation-timing-function:cubic-bezier(.2,.7,.2,1)}
.an.is-live .an-goutte{animation-name:an-goutte}
.an.is-live .an-chips li{animation-name:an-chip;animation-timing-function:cubic-bezier(.2,.7,.2,1)}
.an.is-live .an-jours li span{animation-name:an-jour}
@keyframes an-par{from{transform:translateY(6%) scale(1.06)}to{transform:translateY(-6%) scale(1.06)}}
@keyframes an-halo{from{opacity:.25;transform:scale(.55)}to{opacity:1;transform:none}}
@keyframes an-ombre{from{opacity:0;transform:scale(.5)}to{opacity:1;transform:none}}
@keyframes an-monte{from{opacity:0;transform:translateY(16%) scale(.9) rotate(-3deg)}25%{opacity:1}to{opacity:1;transform:none}}
@keyframes an-goutte{0%{opacity:0;transform:translateY(var(--g0))}15%{opacity:1}100%{opacity:1;transform:translateY(var(--g1))}}
@keyframes an-chip{from{opacity:0;transform:translateY(12px) scale(.96)}to{opacity:1;transform:none}}
@keyframes an-jour{from{opacity:0;transform:scale(.4)}to{opacity:1;transform:none}}
@media (max-width:600px){.an-chips li{font-size:13px;padding:5px 10px}.an-jours li{width:26px;height:26px;font-size:12px}}
@media (prefers-reduced-motion:reduce){.an .an-anim,.an .an-anim span{animation:none!important}}

/* ---- décor d'ingrédients (champ « decor » du JSON, build.py _an_decor) ----
   Rudy, 26/10/2026 : chaque fiche a son décor selon les ingrédients principaux (pomme et canneberge, pêche et raisin blanc,
   aloe et gel) ou, pour le C9, les photos des 5 produits du programme. Illustrations dessinées (<symbol> dans la page).
   Base = décor fixe, chaque élément à sa place ; animé : parallaxe au défilement (an-dec, an-cascade) + léger flottement (fl-flotte),
   qui ne tourne que lorsque la scène est à l'écran (.is-vu, anim.js). Seules transform et opacity sont animées. */
.an-lib{position:absolute;width:0;height:0;overflow:hidden}
.an-dec{position:absolute;z-index:1;aspect-ratio:1;pointer-events:none;transform:translate3d(0,var(--y1),0) rotate(var(--r1))}
.an-dec.an-p-devant{z-index:3}
.an-dec .an-fl{display:block;width:100%;height:100%;overflow:visible}
.an-p-fond .an-fl{opacity:.88}
.an-dec.an-ph{aspect-ratio:auto}
.an-ph .an-fl{position:relative;height:auto;overflow:hidden}
.an-2d .an-board .an-ph img{position:absolute;max-width:none;height:auto}
.an-ph::after{content:"";position:absolute;left:8%;right:8%;bottom:-5%;height:9%;border-radius:50%;background:radial-gradient(closest-side,rgba(50,30,80,.2),transparent);z-index:-1}
.an.is-live .an-dec{animation-name:an-dec;animation-timing-function:cubic-bezier(.3,.6,.4,1)}
.an.is-live .an-p-cascade{animation-name:an-cascade;animation-timing-function:cubic-bezier(.2,.7,.2,1)}
.an.is-live .an-fl{animation:fl-flotte var(--fl,5s) ease-in-out var(--fd,0s) infinite;animation-play-state:paused}
.an.is-live.is-vu .an-fl{animation-play-state:running}
@keyframes an-dec{0%{opacity:0;transform:translate3d(0,var(--y0),0) rotate(var(--r0))}16%{opacity:1}100%{opacity:1;transform:translate3d(0,var(--y1),0) rotate(var(--r1))}}
@keyframes an-cascade{0%{opacity:0;transform:translate3d(0,var(--y0),0) scale(.72) rotate(var(--r0))}55%{opacity:1}100%{opacity:1;transform:translate3d(0,var(--y1),0) rotate(var(--r1))}}
@keyframes fl-flotte{0%,100%{transform:translateY(0) rotate(0deg)}50%{transform:translateY(-5%) rotate(3deg)}}
@media (prefers-reduced-motion:reduce){.an .an-fl{animation:none!important}}
