/* =====================================================================
   MIVA'KAT — Socle neutre des modèles de catalogue récents

   Ce fichier ne contient que ce qui est ** commun à trois designs
   différents** : la remise à zéro, l'accessibilité, la largeur de page,
   le lien d'évitement, et le cadre des visuels manquants.

   Tout le reste — en-tête, héros, grille, fiche produit, pied — vit dans
   `catalog-<modele>.css`, un fichier par modèle. C'est volontaire : un
   socle trop riche ferait converger les trois designs, et trois
   apparences qui se ressemblent ne valent pas mieux qu'une seule.

   Les couleurs, les polices, la densité et les formats arrivent en
   variables `--t-*`, écrites dans le `<head>` par `DesignSchema`. Aucune
   couleur n'est écrite ici : une valeur écrite dans une feuille de style
   ne serait pas personnalisable, et c'est tout l'objet de la mission.
   ===================================================================== */

*, *::before, *::after { box-sizing: border-box; }

/* Le fond et la couleur du texte viennent des jetons. Ils sont posés sur
   `html` et non sur `body` : la barre de défilement du navigateur suit
   alors la couleur du site sur toute la hauteur, ce qu'un `body` seul ne
   produit pas. */
html {
  background: var(--t-bg, #ffffff);
  color-scheme: light;
  -webkit-text-size-adjust: 100%;
  scrollbar-gutter: stable;
}
@media (prefers-color-scheme: dark) {
  /* Un modèle sombre ne déclare pas `color-scheme: dark` : ses propres
     couleurs font foi, et une inversion automatique du navigateur
     déformerait des couleurs choisies. La règle reste donc claire. */
  html { color-scheme: light; }
}

body {
  min-width: 320px;
  margin: 0;
  overflow-x: hidden;
  background: var(--t-bg);
  color: var(--t-text);
  font-family: var(--t-font-body);
  font-size: 15px;
  line-height: 1.62;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

img, svg { display: block; max-width: 100%; }
img { height: auto; }
h1, h2, h3, h4 { margin: 0; font-family: var(--t-font-heading); font-weight: var(--t-title-weight); line-height: var(--t-title-lh); letter-spacing: var(--t-title-tracking); }
h1, h2, h3, h4 { text-wrap: balance; }
p { margin: 0; }
a { color: inherit; }
ul, ol, dl, dd { margin: 0; padding: 0; }
li { list-style: none; }
button, input, select, textarea { font: inherit; color: inherit; }
button { background: none; border: 0; padding: 0; cursor: pointer; }
table { border-collapse: collapse; }
[hidden] { display: none !important; }

/* Les titres suivent l'échelle choisie par le commerçant. Un seul
   multiplicateur, appliqué une fois : c'est ce qui rend le réglage utile
   sans toucher aux six règles qui lisent la taille. */
.t-titre-1 { font-size: calc(clamp(1.9rem, 5.4vw, 3.4rem) * var(--t-title-scale, 1)); }
.t-titre-2 { font-size: calc(clamp(1.35rem, 3.2vw, 2.1rem) * var(--t-title-scale, 1)); }
.t-titre-3 { font-size: calc(clamp(1.08rem, 2.1vw, 1.35rem) * var(--t-title-scale, 1)); letter-spacing: calc(var(--t-title-tracking, -.03em) * .5); }

/* Sur-titre : la petite ligne qui dit de quoi parle une section. */
.t-sur-titre {
  display: flex;
  align-items: center;
  gap: 10px;
  color: var(--t-muted);
  font-family: var(--t-font-body);
  font-size: .68rem;
  font-weight: 700;
  letter-spacing: .14em;
  text-transform: uppercase;
}
.t-sur-titre::before { content: ""; width: 22px; height: 1px; background: currentColor; flex: none; }

.t-muet { color: var(--t-muted); }

/* ── Mise en page ─────────────────────────────────────────────────────── */

.t-conteneur {
  width: 100%;
  max-width: var(--t-container);
  margin-inline: auto;
  padding-inline: clamp(16px, 4vw, 34px);
}
.t-corps { padding-block: clamp(18px, 3vw, 30px) clamp(64px, 9vw, 96px); }

/* Le lien d'évitement : hors écran jusqu'à ce qu'il reçoive le focus. Il
   est masqué par translation, pas par `display: none`, sinon le navigateur
   ne peut pas l'atteindre au clavier.

   Le nom de la classe est celui du projet entier — `app.css`, `vitrine.css`
   et `catalog.css` l'emploient déjà. Un même mécanisme d'accessibilité ne
   doit pas porter deux noms selon la feuille de style qui le dessine : un
   test, un outil d'audit ou une règle de style globale ne verrait qu'une
   moitié du dispositif. Seule la **peau** diffère ici : l'encre d'accent,
   calculée par `DesignSchema`, et non plus le couple du socle historique. */
.skip-link {
  position: fixed;
  top: 8px;
  left: 10px;
  z-index: 300;
  padding: 11px 16px;
  border-radius: 6px;
  background: var(--t-accent-ink);
  color: #fff;
  font-size: .82rem;
  font-weight: 700;
  text-decoration: none;
  transform: translateY(-180%);
}
.skip-link:focus { transform: none; }

.t-visible-seul {
  position: absolute !important;
  width: 1px !important;
  height: 1px !important;
  padding: 0 !important;
  margin: -1px !important;
  overflow: hidden !important;
  clip: rect(0, 0, 0, 0) !important;
  white-space: nowrap !important;
  border: 0 !important;
}

/* ── Les cibles tactiles ───────────────────────────────────────────────── */

/*
 * Les 44 px ne sont pas une décision de design : c'est la taille minimale
 * qu'un doigt atteint sans viser, et au-delà de laquelle un bouton cesse
 * d'être cliquable sur un téléphone. Elle vit donc dans le socle, **pas**
 * dans les feuilles de modèle.
 *
 * Le raisonnement est le même que pour le lien d'évitement : si la valeur
 * était répétée dans les trois feuilles, une révision du seuil serait
 * appliquée à deux modèles et oubliée au troisième, et le commerce le
 * découvrirait sur un seul de ses sites. Le modèle ne décrit plus que la
 * **peau** — la bordure, l'arrondi, la couleur, la transition.
 */
.t-icone {
  width: 44px;
  height: 44px;
  display: grid;
  place-items: center;
  flex: none;
}
.t-icone svg { width: 18px; height: 18px; }
.t-contact { min-height: 44px; }

/* ── Le focus ─────────────────────────────────────────────────────────── */

:focus-visible {
  outline: 3px solid var(--t-accent-ink);
  outline-offset: 3px;
  border-radius: 3px;
}
::selection { background: var(--t-accent-ink); color: #fff; }

/* ── Le cadre d'un visuel absent ──────────────────────────────────────── */

/*
 * Un produit sans photo est un trou. Le remplir par une image de
 * substitution mentirait sur le produit ; on affiche donc un cadre
 * honnête, posé par la feuille et non par le gabarit, avec le même
 * filettage que le reste de la page.
 */
.t-cadre {
  position: relative;
  display: grid;
  place-items: center;
  width: 100%;
  aspect-ratio: var(--t-ratio, 1/1);
  padding: 22px;
  background: var(--t-bg);
  color: var(--t-muted);
  text-align: center;
}
.t-cadre::after {
  content: "";
  position: absolute;
  inset: 0;
  border: var(--t-border) solid var(--t-line);
  pointer-events: none;
}
.t-cadre > span { display: grid; justify-items: center; gap: 8px; font-size: .74rem; font-weight: 600; }
.t-cadre svg { width: 30px; height: 30px; opacity: .6; }

/* ── Les pastilles de statut ──────────────────────────────────────────── */

.t-pastille {
  display: inline-flex;
  align-items: center;
  padding: 5px 8px;
  border-radius: 4px;
  background: var(--t-primary);
  color: var(--t-surface);
  font-family: var(--t-font-body);
  font-size: .6rem;
  font-weight: 800;
  letter-spacing: .07em;
  text-transform: uppercase;
  line-height: 1;
}
.t-pastille--accent { background: var(--t-accent-ink); color: #fff; }
.t-pastille--vente { background: #b42318; color: #fff; }
.t-pastille--discret { background: var(--t-surface); color: var(--t-muted); box-shadow: inset 0 0 0 var(--t-border) var(--t-line); }

/* ── LF-09 — Le bandeau hors connexion, commun aux modèles récents ───────────
   Il dit que la page vient du cache et **de quand** elle date (D129). Même nom
   que dans `catalog.css` (famille du socle) : le même mot ne s'habille pas de
   deux façons selon le modèle choisi. Discret, jamais rouge — l'absence de
   réseau n'est pas une panne — et masqué par défaut : c'est le script qui le
   révèle, et sans JavaScript il ne s'affiche jamais. */
.catalogue-hors-ligne { display: flex; flex-wrap: wrap; align-items: baseline; gap: 6px; margin: 0; padding: 9px 16px; background: var(--t-surface); color: var(--t-muted); font-size: .8rem; border-bottom: 1px solid var(--t-line); }
.catalogue-hors-ligne[hidden] { display: none; }
.catalogue-hors-ligne time { font-variant-numeric: tabular-nums; font-weight: 700; color: var(--t-text); }

/* ── Le mouvement ─────────────────────────────────────────────────────── */

@media (prefers-reduced-motion: no-preference) {
  html { scroll-behavior: smooth; }
}
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
    scroll-behavior: auto !important;
  }
}

/* =====================================================================
   R28 - La demande : panier, quantite, envoi.

   Ce bloc est ici, et non dans les trois feuilles de modele, pour une
   raison simple : il est identique sur `minimal`, `modern` et `bold`.
   Le mettre dans les trois aurait produit trois fois le meme texte, et
   trois occasions de diverger.

   Aucune couleur n'est ecrite ici non plus : tout passe par les jetons
   `--t-*` de `DesignSchema`, comme le reste de cette feuille. Un commerce
   qui change sa palette voit sa page de demande suivre.

   Les classes sont `cart-*` et non `t-*` : elles ne sont pas la
   propriete d'un modele mais d'une page, qui existe sur les quatre
   apparences. C'est la meme ligne que `catalog/` : une page ne porte
   pas le nom d'un modele.
   ===================================================================== */

.cart-page { padding-block: clamp(20px, 5vw, 48px); }
.cart-page__inner { display: grid; gap: clamp(14px, 3vw, 22px); justify-items: start; }
.cart-page__titre { margin: 0; }
.cart-page__alerte {
  margin: 0;
  padding: 11px 14px;
  border-radius: var(--t-radius);
  border: var(--t-border) solid var(--t-accent);
  background: var(--t-surface);
  color: var(--t-text);
  font-size: .92rem;
}
.cart-zone { width: 100%; display: grid; gap: 14px; }
.cart-lignes { list-style: none; margin: 0; padding: 0; display: grid; gap: 10px; }
.cart-ligne {
  display: grid;
  gap: 6px;
  padding: 14px;
  border-radius: var(--t-radius);
  border: var(--t-border) solid var(--t-line);
  background: var(--t-surface);
}
.cart-ligne__titre { margin: 0; font-family: var(--t-font-heading); font-weight: var(--t-title-weight); }
.cart-ligne__quantite { margin: 0; color: var(--t-muted); font-size: .9rem; }
.cart-ligne__actions { margin: 0; display: flex; gap: 8px; align-items: center; }
/* La hauteur de cible est celle du socle du projet (44 px), pas celle d'un
 * bouton de formulaire : un « - » qu'on rate une fois, on le rate encore. */
.cart-ligne__bouton {
  min-height: 44px;
  min-width: 44px;
  padding: 6px 12px;
  border-radius: var(--t-radius);
  border: var(--t-border) solid var(--t-line);
  background: var(--t-bg);
  color: var(--t-text);
  font: inherit;
  font-size: .9rem;
  cursor: pointer;
}
.cart-ligne__bouton:hover { border-color: var(--t-primary); }
.cart-vide { margin: 0; display: grid; gap: 8px; justify-items: start; color: var(--t-muted); }
.cart-compte { margin: 0; font-family: var(--t-font-heading); font-weight: var(--t-title-weight); }
.cart-note { margin: 0; color: var(--t-muted); font-size: .86rem; }
.cart-sans-js { margin: 0; color: var(--t-muted); font-size: .9rem; }
.cart-retour { margin: 0; display: flex; flex-wrap: wrap; gap: 16px; }
.cart-lien { color: var(--t-primary); text-decoration: underline; }

/* =====================================================================
   R29 - L'entree « ma demande », socle commun aux trois modeles.

   La balise est ecrite une fois et porte sa classe de modele ; ce bloc donne
   la base commune, et chaque feuille de modele ajoute sa peau. Aucune couleur
   n'est ecrite ici non plus : tout passe par les jetons `--t-*` de
   `DesignSchema`, donc une palette changee change aussi le panier.
   ===================================================================== */

.cart-entree {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 44px;
  min-width: 44px;
  padding: 0 9px;
  border-radius: var(--t-radius);
  color: var(--t-text);
  text-decoration: none;
  transition: background-color .18s, color .18s;
}
.cart-entree:hover { background: var(--t-surface); color: var(--t-primary); }
.cart-entree__dessin { width: 21px; height: 21px; display: block; }
.cart-entree__roue { fill: currentColor; stroke: none; }

.cart-entree__compteur {
  position: absolute;
  top: 2px;
  right: 0;
  min-width: 17px;
  height: 17px;
  padding: 0 4px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 9px;
  background: var(--t-accent-ink);
  color: #fff;
  font-size: .64rem;
  font-weight: 800;
  line-height: 1;
  box-shadow: 0 0 0 2px var(--t-bg);
}
.cart-entree[hidden], .cart-entree__compteur[hidden] { display: none; }

/* La pastille du panier dans la barre basse (R29). */
.t-dock__dessin { position: relative; display: inline-flex; }
.t-dock__dessin svg { width: 22px; height: 22px; display: block; }
.t-dock__compteur {
  position: absolute;
  top: -4px;
  right: -8px;
  min-width: 16px;
  height: 16px;
  padding: 0 4px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 8px;
  background: var(--t-accent-ink);
  color: #fff;
  font-size: .62rem;
  font-weight: 800;
  line-height: 1;
}
.t-dock__panier[hidden], .t-dock__compteur[hidden] { display: none; }
/* Le lien actif se deduit du trait de selection de la barre : le panier passe
   au meme endroit que les trois autres, sans regler une couleur de plus. */
.t-dock__panier[aria-current="page"] .t-dock__dessin { color: var(--t-accent); }

/* =====================================================================
   R29 - La page de contact, socle commun.

   Meme bloc pour les trois modeles : la page ne change pas d'un modele a l'autre,
   seule sa presentation change — donc une seule lecture, et trois peaux
   par-dessus. Sur telephone, l'action passe **apres** les coordonnees : on
   scrolle, on ne survole pas, et un bouton seul a trois ecrans de haut n'est pas
   une action.
   ===================================================================== */

.contact-page { padding-block: clamp(28px,7vw,64px); }
.contact-page__inner { display: grid; gap: clamp(20px,4vw,36px); }
.contact-hero { display: flex; flex-wrap: wrap; align-items: center; gap: clamp(14px,3vw,22px); }
.contact-hero__signe {
  width: 76px; height: 76px; flex: none;
  display: grid; place-items: center; overflow: hidden;
  border-radius: var(--t-radius);
  background: var(--t-primary);
  color: var(--t-on-accent);
  font-family: var(--t-font-heading);
  font-size: 1.7rem; font-weight: var(--t-title-weight);
}
.contact-hero__signe img { width: 100%; height: 100%; padding: 6px; object-fit: contain; }
.contact-hero__texte { min-width: 0; }
.contact-hero__texte h1 { margin: 0; font-family: var(--t-font-heading); font-size: clamp(1.6rem,4.5vw,2.3rem); line-height: 1.1; font-weight: var(--t-title-weight); }
.contact-hero__nom { margin: 5px 0 0; color: var(--t-muted); font-weight: 700; }
.contact-hero__note { margin: 8px 0 0; color: var(--t-muted); max-width: 62ch; }

.contact-action {
  display: grid; gap: 11px; justify-items: start;
  padding: clamp(18px,3.5vw,28px);
  border: var(--t-border) solid var(--t-line);
  border-radius: var(--t-radius);
  background: var(--t-surface);
}
.contact-action h2 { margin: 0; font-family: var(--t-font-heading); font-size: 1.18rem; font-weight: var(--t-title-weight); }
.contact-action p { margin: 0; color: var(--t-muted); max-width: 56ch; }
.contact-action__ou { font-size: .88rem; }
.contact-action__email { color: var(--t-accent-ink); }

.contact-block { display: grid; gap: 14px; }
.contact-block h2 { margin: 0; font-family: var(--t-font-heading); font-size: 1.18rem; font-weight: var(--t-title-weight); }
.contact-list { list-style: none; margin: 0; padding: 0; display: grid; }
.contact-list__ligne {
  display: flex; flex-wrap: wrap; gap: 4px 18px; align-items: baseline;
  padding: 13px 0;
  border-bottom: var(--t-border) solid var(--t-line);
}
.contact-list__ligne:last-child { border-bottom: 0; }
.contact-list__nom { min-width: 118px; color: var(--t-muted); font-size: .87rem; }
.contact-list__valeur { color: var(--t-text); font-weight: 700; word-break: break-word; }
.contact-list__ligne--whatsapp .contact-list__valeur { color: var(--t-accent-ink); }

.contact-note { margin: 0; display: flex; flex-wrap: wrap; gap: 4px 18px; align-items: baseline; }
.contact-note span { min-width: 118px; color: var(--t-muted); font-size: .87rem; }

.contact-none {
  display: grid; gap: 12px; justify-items: start;
  padding: clamp(18px,3.5vw,28px);
  border: var(--t-border) solid var(--t-accent);
  border-radius: var(--t-radius);
}
.contact-none p { margin: 0; }

.contact-retour { display: flex; flex-wrap: wrap; gap: 18px; }

@media (max-width: 700px) {
  .contact-page__inner { grid-template-areas: 'hero' 'block' 'action' 'retour'; }
  .contact-hero { grid-area: hero; }
  .contact-action { grid-area: action; }
  .contact-block, .contact-none { grid-area: block; }
  .contact-retour { grid-area: retour; }
}

/* =====================================================================
   R30 � L'�cran de choix d'une fiche produit : un seul bouton, deux routes.

   C'est une feuille de dialogue, pas une page : elle ne se pose que le temps
   d'un choix, et elle ne d�place rien de ce qui est dessous. Le visiteur
   repart exactement l� o� il �tait � aucun geste ici ne recharge.

   Aucune couleur n'est �crite : tout passe par les jetons `--t-*`, pour la
   m�me raison que le reste du socle, une palette chang�e change aussi la
   fiche. Les hauteres de champ et de bouton sont a 44 px minimum, comme partout
   ailleurs : un pouce ne vise pas mieux sur une fiche que sur une liste.
   ===================================================================== */

.cart-fiche { position: fixed; inset: 0; z-index: 90; display: flex; }
.cart-fiche__voile {
  position: absolute; inset: 0;
  background: rgb(15 23 42 / 55%);
  border: 0; padding: 0; margin: 0; cursor: pointer;
}
.cart-fiche__panneau {
  position: relative; z-index: 1;
  width: min(100%, 460px);
  margin: auto;
  max-height: 92vh;
  overflow: auto;
  padding: 22px 20px calc(24px + env(safe-area-inset-bottom));
  background: var(--t-surface);
  color: var(--t-text);
  border: var(--t-border) solid var(--t-line);
  border-radius: var(--t-radius);
  box-shadow: 0 24px 60px rgb(2 6 23 / 35%);
}
@media (max-width: 640px) {
  .cart-fiche { align-items: flex-end; }
  .cart-fiche__panneau {
    width: 100%; max-width: none;
    margin: 0;
    border-radius: var(--t-radius) var(--t-radius) 0 0;
    box-shadow: 0 -18px 44px rgb(2 6 23 / 30%);
  }
}
.cart-fiche__fermer {
  position: absolute; top: 6px; right: 6px;
  min-height: 44px; min-width: 44px;
  display: grid; place-items: center;
  background: transparent; border: 0; cursor: pointer;
  color: var(--t-muted);
}
.cart-fiche__fermer:hover { color: var(--t-text); }
.cart-fiche__fermer svg { width: 20px; height: 20px; }
.cart-fiche__surtitre {
  margin: 0; color: var(--t-muted);
  font-size: .74rem; font-weight: 700;
  letter-spacing: .08em; text-transform: uppercase;
}
.cart-fiche__titre {
  margin: 5px 0 0; padding-right: 44px;
  font-family: var(--t-font-heading);
  font-weight: var(--t-title-weight);
  font-size: 1.12rem; line-height: var(--t-title-lh, 1.25);
}
.cart-fiche__prix {
  margin: 10px 0 0;
  font-family: var(--t-font-heading);
  font-weight: var(--t-title-weight);
  font-size: 1.7rem; line-height: 1.1;
}
.cart-fiche__champ { display: flex; flex-direction: column; gap: 6px; margin-top: 16px; }
.cart-fiche__etiquette { color: var(--t-muted); font-size: .88rem; }
.cart-fiche__select, .cart-fiche__qte {
  min-height: 44px;
  padding: 8px 10px;
  border-radius: var(--t-radius);
  border: var(--t-border) solid var(--t-line);
  background: var(--t-bg);
  color: var(--t-text);
  font: inherit;
}
.cart-fiche__qte { width: 104px; }
.cart-fiche__commande {
  display: flex; flex-direction: column; gap: 12px;
  margin-top: 18px; padding-top: 16px;
  border-top: var(--t-border) solid var(--t-line);
}
.cart-fiche__form { display: flex; flex-direction: column; gap: 10px; margin: 0; }
.cart-fiche__whatsapp,
.cart-fiche__ajouter,
.cart-fiche__repli {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  min-height: 48px; padding: 10px 18px;
  border-radius: var(--t-radius);
  border: var(--t-border) solid var(--t-primary);
  font: inherit; font-weight: 600;
  text-decoration: none; cursor: pointer;
}
.cart-fiche__whatsapp { background: var(--t-primary); color: var(--t-on-accent); }
.cart-fiche__whatsapp svg { width: 20px; height: 20px; flex: none; }
.cart-fiche__ajouter { background: transparent; color: var(--t-primary); }
.cart-fiche__ajouter:hover { background: var(--t-primary); color: var(--t-on-accent); }
.cart-fiche__repli { background: transparent; color: var(--t-primary); }
.cart-fiche__aide { margin: 0; color: var(--t-muted); font-size: .84rem; line-height: 1.45; }
.cart-fiche__retour { margin: 0; color: var(--t-primary); font-size: .88rem; font-weight: 600; }

@media (prefers-reduced-motion: reduce) {
  .cart-fiche__panneau { scroll-behavior: auto; }
}

@media (max-width: 760px) {
  .t-entete__actions [data-panier-entree] { display: none; }
  .shop-header__actions [data-panier-entree] { display: none; }
}
.cart-fiche { align-items: center; justify-content: center; padding: 16px; }
.cart-fiche__panneau { width: min(95%, 460px); margin: auto; max-height: min(90vh, 640px); overflow-y: auto; overscroll-behavior: contain; }
@media (max-width: 640px) {
  .cart-fiche { align-items: center; padding: 12px; }
  .cart-fiche__panneau { width: 95%; max-width: 460px; margin: auto; border-radius: var(--t-radius); box-shadow: 0 24px 60px rgb(2 6 23 / 35%); }
}
.shop-category-list { overflow-x: auto; scrollbar-width: thin; -webkit-overflow-scrolling: touch; scroll-snap-type: x proximity; }
[data-category-list] { overflow-x: auto; scrollbar-width: thin; -webkit-overflow-scrolling: touch; }
[data-category-list].has-overflow::after {
  content: "";
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  width: 48px;
  pointer-events: none;
  background: linear-gradient(to right, transparent, var(--t-bg, #fff));
}
.shop-categories__hint { display: flex; align-items: center; gap: 6px; margin: 6px 0 0; font-size: .8rem; color: var(--t-muted, #64748b); }
.shop-categories__hint svg { width: 16px; height: 16px; }
@keyframes shop-shimmer { 0% { background-position: -400px 0; } 100% { background-position: 400px 0; } }
img[data-skeleton], .shop-media-placeholder, .t-visuel--vide { background: linear-gradient(90deg, #e5e7eb 25%, #f3f4f6 50%, #e5e7eb 75%); background-size: 800px 100%; animation: shop-shimmer 1.4s linear infinite; min-height: 120px; }
img[data-skeleton].is-loaded, img.is-loaded { animation: none; background: none; min-height: 0; }
@media (prefers-reduced-motion: reduce) { img[data-skeleton], .shop-media-placeholder { animation: none; } }
