/* =============================================================
   BOUTIQUE — archive produits : en-tête, barre d'outils, filtres,
   grille, états vides.

   Cette feuille est chargée sur TOUTES les pages WooCommerce
   (panier, tunnel, fiche produit incluses) : rien ici ne doit
   toucher un sélecteur générique. Tout est préfixé.
   ============================================================= */

/* =============================================================
   EN-TÊTE DE BOUTIQUE
   Même fond bleuté que le hero de l'accueil : la boutique est la
   suite de la page d'accueil, pas une autre planète.
   ============================================================= */
.shop-head {
  background: var(--bg-tint);
  border-bottom: 1px solid var(--c-blue-100);
  padding-block: clamp(var(--s-6), 4vw, var(--s-8));
}
.shop-head .sechead { margin-bottom: 0; }
.shop-head .sechead__lead { color: var(--c-blue-800); opacity: .8; }

/* ---- Rangée de gammes ---------------------------------------------
   Sur téléphone, elle défile horizontalement dans son propre
   conteneur : dix pastilles qui s'empilent sur quatre lignes
   repousseraient les produits sous la ligne de flottaison. */
.shop-chips {
  display: flex;
  gap: var(--s-2);
  margin-top: var(--s-5);
  margin-inline: calc(var(--gutter) * -1);
  padding: var(--s-1) var(--gutter) var(--s-3);
  overflow-x: auto;
  overscroll-behavior-inline: contain;
  scroll-snap-type: x proximity;
  scrollbar-width: thin;
  scrollbar-color: var(--c-blue-200) transparent;
}
.shop-chips > * {
  flex: none;
  scroll-snap-align: start;
}
/* `.chip` plafonne à 38 px + bordures = 40 : sous le doigt, dans une rangée
   qui défile, c'est trop court. Ici la pastille EST la navigation entre
   gammes — elle passe donc à la zone tactile réglementaire. */
.shop-chips .chip { min-height: var(--tap); }
.shop-chips::-webkit-scrollbar { height: 6px; }
.shop-chips::-webkit-scrollbar-thumb { background: var(--c-blue-200); border-radius: var(--r-pill); }
.shop-chips::-webkit-scrollbar-track { background: transparent; }

@media (min-width: 48rem) {
  .shop-chips {
    flex-wrap: wrap;
    overflow: visible;
    margin-inline: 0;
    padding-inline: 0;
  }
}

/* Dans un état vide, la rangée est centrée et ne défile plus. */
.shop-chips--center {
  flex-wrap: wrap;
  justify-content: center;
  overflow: visible;
  margin-inline: 0;
  padding-inline: 0;
  margin-top: var(--s-2);
}

/* =============================================================
   COLONNES
   ============================================================= */
/* `min-width: 0` : sans cela, une carte large empêcherait la colonne
   de grille de rétrécir et la page défilerait horizontalement. */
.shop-main { min-width: 0; }

/* La colonne de filtres n'existe qu'à partir du moment où il y a la
   place de l'afficher ; en dessous, c'est le tiroir qui prend le relais. */
.shop-aside { display: none; }

@media (min-width: 62rem) {
  .shop-aside {
    display: block;
    max-height: calc(100dvh - var(--header-h) - var(--s-7));
    overflow-y: auto;
    overscroll-behavior: contain;
    scrollbar-width: thin;
    scrollbar-color: var(--border-strong) transparent;
    padding-right: var(--s-2);

    /* Onze gammes + les marques + la disponibilité font toujours plus haut
       que l'écran : la colonne défile sur elle-même. La coupure tombait pile
       entre deux lignes et, sous macOS où la barre de défilement reste
       invisible au repos, la liste avait l'air terminée — le filtre de
       disponibilité était donc introuvable.
       D'où cette ombre de défilement : les deux premiers dégradés sont
       solidaires du CONTENU (`local`) et masquent l'ombre quand on atteint
       le bord ; les deux suivants sont solidaires du CADRE (`scroll`).
       L'ombre n'apparaît donc que s'il reste réellement quelque chose à
       lire — et jamais par-dessus du texte, contrairement à un fondu fixe
       qui aurait délavé la dernière ligne. */
    background-image:
      linear-gradient(to bottom, var(--bg), transparent),
      linear-gradient(to top,    var(--bg), transparent),
      linear-gradient(to bottom, color-mix(in srgb, var(--c-blue-900) 14%, transparent), transparent),
      linear-gradient(to top,    color-mix(in srgb, var(--c-blue-900) 14%, transparent), transparent);
    background-position: top, bottom, top, bottom;
    background-size: 100% var(--s-5), 100% var(--s-5), 100% var(--s-2), 100% var(--s-2);
    background-repeat: no-repeat;
    background-attachment: local, local, scroll, scroll;
  }
}

/* =============================================================
   BARRE D'OUTILS
   ============================================================= */
.toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s-3);
  margin-bottom: var(--s-6);
  padding-bottom: var(--s-4);
  border-bottom: 1px solid var(--border-soft);
  /* Cible du bouton « Fermer » du tiroir : le titre ne doit pas finir
     sous l'en-tête collant. */
  scroll-margin-top: calc(var(--header-h) + var(--s-4));
}
.toolbar__count {
  margin: 0;
  font-size: var(--t-sm);
  font-weight: var(--fw-medium);
  color: var(--text-muted);
}
.toolbar__actions {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  margin-left: auto;
}

.toolbar__filters { flex: none; }
.toolbar__badge {
  display: inline-grid;
  place-items: center;
  min-width: 20px;
  height: 20px;
  padding-inline: var(--s-1);
  border-radius: var(--r-pill);
  background: var(--primary);
  color: var(--on-primary);
  font-size: var(--t-xs);
  font-weight: var(--fw-bold);
  line-height: 1;
}

/* Le tiroir n'a plus de raison d'être quand la colonne est visible. */
@media (min-width: 62rem) {
  .toolbar__filters { display: none; }
}

.toolbar__sort {
  display: flex;
  align-items: center;
  gap: var(--s-2);
  min-width: 0;
}
.toolbar__sort-label {
  flex: none;
  font-size: var(--t-sm);
  color: var(--text-muted);
  white-space: nowrap;
}
/* La taille de police reste à 16 px : en dessous, iOS zoome à l'ouverture
   de la liste et l'utilisateur se retrouve avec une page décadrée. */
.toolbar__sort-select {
  width: auto;
  min-width: 0;
  padding-block: var(--s-2);
}

@media (max-width: 47.99rem) {
  .toolbar__count { flex: 1 1 100%; }
  .toolbar__actions { width: 100%; margin-left: 0; }
  .toolbar__sort { flex: 1 1 auto; justify-content: flex-end; }
  .toolbar__sort-select { flex: 1 1 auto; }
}
@media (max-width: 26rem) {
  /* À 360 px, « Trier par » et la liste ne tiennent plus côte à côte. */
  .toolbar__actions { flex-wrap: wrap; }
  .toolbar__sort { flex: 1 1 100%; }
}

/* =============================================================
   GRILLE DE PRODUITS
   ============================================================= */
.shop-grid {
  list-style: none;
  margin: 0;
  padding: 0;
  /* `auto-fill` et non `auto-fit` : une gamme qui ne contient qu'un
     produit ne doit pas étirer sa carte sur toute la largeur. */
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 9.5rem), 1fr));
}
@media (min-width: 30rem) {
  .shop-grid { grid-template-columns: repeat(auto-fill, minmax(min(100%, 12.5rem), 1fr)); }
}
@media (min-width: 62rem) {
  .shop-grid { grid-template-columns: repeat(auto-fill, minmax(min(100%, 14.5rem), 1fr)); }
}

.shop-cell {
  margin: 0;
  display: flex;
}
.shop-cell > * { width: 100%; }

/* La colonne de filtres rétrécit la grille : ici la cellule descend à
   ~150 px, où « Prix sur demande » et le bouton d'ajout ne tiennent plus
   côte à côte — le bouton débordait de la carte, qui le rognait. Le pied
   passe donc sur deux lignes à TOUTES les largeurs : rythme identique
   d'un bout à l'autre, et une cible tactile pleine largeur. */
.shop-cell .pcard__foot { flex-wrap: wrap; }
.shop-cell .pcard__foot > .btn { width: 100%; }

/* =============================================================
   FILTRES
   Mêmes règles pour la colonne et pour le tiroir : un seul jeu de
   classes, deux contextes.
   ============================================================= */
.filters__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-3);
  padding-bottom: var(--s-4);
  margin-bottom: var(--s-5);
  border-bottom: 1px solid var(--border-soft);
}
.filters__title { font-size: var(--t-lg); margin: 0; }

.filters__reset {
  display: inline-flex;
  align-items: center;
  gap: var(--s-1);
  /* Un lien de 19 px de haut reste une cible : la colonne est visible au
     doigt sur une tablette en 62 rem, pas seulement à la souris. */
  min-height: var(--tap);
  font-family: var(--font-display);
  font-size: var(--t-xs);
  font-weight: var(--fw-bold);
  color: var(--text-muted);
  text-decoration: none;
  white-space: nowrap;
}
.filters__reset:hover { color: var(--error); }
.filters__reset--block {
  width: 100%;
  justify-content: center;
  margin-bottom: var(--s-4);
}

.filters__group + .filters__group {
  margin-top: var(--s-5);
  padding-top: var(--s-5);
  border-top: 1px solid var(--border-soft);
}
.filters__legend {
  margin: 0 0 var(--s-2);
  font-family: var(--font-display);
  font-size: var(--t-xs);
  font-weight: var(--fw-bold);
  letter-spacing: var(--ls-caps);
  text-transform: uppercase;
  /* `--text-faint` ne donne que 3:1 sur le blanc : suffisant pour une
     décoration, pas pour un titre de groupe à 12 px. `--text-muted` en
     donne 5:1 sans changer la discrétion voulue. */
  color: var(--text-muted);
}

.filters__list { list-style: none; margin: 0; padding: 0; }
.filters__list li { margin: 0; }

/* Une ligne de filtre est une cible tactile à part entière : 44 px de
   haut, bord à bord de la colonne. */
.filters__opt {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  min-height: var(--tap);
  padding: var(--s-2) var(--s-3);
  border-radius: var(--r-sm);
  color: var(--text);
  font-size: var(--t-sm);
  line-height: 1.3;
  text-decoration: none;
  transition: background var(--dur-2) var(--ease), color var(--dur-2) var(--ease);
}
a.filters__opt:hover { background: var(--primary-soft); color: var(--primary); }

.filters__name { flex: 1; min-width: 0; }
.filters__n {
  flex: none;
  font-size: var(--t-xs);
  /* Ce nombre est une information, pas un ornement : il doit se lire. */
  color: var(--text-muted);
}
/* Une gamme sans produit en ligne n'affiche pas « 0 » : le client la
   vend réellement, elle n'est simplement pas encore saisie. */
.filters__ask {
  flex: none;
  font-size: var(--t-xs);
  font-weight: var(--fw-semi);
  color: var(--secondary);
  white-space: nowrap;
}

/* ---- Case de sélection (marques, disponibilité) --------------------
   L'état actif n'est jamais porté par la seule couleur : la coche est
   dessinée, et le libellé passe en gras. */
.filters__box {
  flex: none;
  display: grid;
  place-items: center;
  width: 20px;
  height: 20px;
  border: 1.5px solid var(--border-strong);
  border-radius: var(--r-xs);
  background: var(--surface);
  color: transparent;
  transition: background var(--dur-2) var(--ease), border-color var(--dur-2) var(--ease);
}
a.filters__opt:hover .filters__box { border-color: var(--primary); }

.filters__opt.is-on {
  color: var(--text-strong);
  font-weight: var(--fw-semi);
}
.filters__opt.is-on .filters__box {
  background: var(--primary);
  border-color: var(--primary);
  color: var(--on-primary);
}
/* `--primary` plafonne à 4,1:1 sur le blanc — sous la barre pour du 12 px.
   Le teal foncé garde le rappel de couleur et passe à 5,8:1. */
.filters__opt.is-on .filters__n { color: var(--primary-hover); }

/* Option sans aucun produit : montrée, mais pas cliquable — un lien
   vers zéro résultat est une impasse. */
/* Indisponible ≠ illisible : le praticien doit pouvoir LIRE quelle option
   lui manque. L'état est déjà porté par la case vide et par le « 0 » ;
   la couleur se contente de reculer d'un cran, à 5:1. */
.filters__opt.is-off { color: var(--text-muted); cursor: default; }
.filters__opt.is-off .filters__box { background: var(--bg-alt); border-color: var(--border); }

/* ---- Gammes : navigation, pas cases à cocher ----------------------- */
.filters__list--nav .filters__opt { position: relative; padding-left: var(--s-4); }
.filters__list--nav .filters__opt.is-on {
  background: var(--primary-soft);
  font-weight: var(--fw-bold);
}
/* Filet teal — l'élément signature du site marque la gamme courante. */
.filters__list--nav .filters__opt.is-on::before {
  content: "";
  position: absolute;
  left: 0;
  top: 50%;
  transform: translateY(-50%);
  width: 3px;
  height: 62%;
  border-radius: var(--r-pill);
  background: var(--edge-solid);
}

.filters__note { margin-top: var(--s-5); }

/* =============================================================
   TIROIR DE FILTRES (mobile)

   Sans JavaScript, l'ancre `:target` ouvre le tiroir et le lien
   « Fermer » (#shop-top) le referme. Avec JavaScript, app.js prend
   la main via aria-hidden et ajoute le piège à focus.
   ============================================================= */
/* `:not([aria-hidden="true"])` : dès qu'app.js a touché au tiroir une fois,
   il pose cet attribut et devient la seule source de vérité. Sans ce garde-
   fou, un retour arrière du navigateur ramenant #shop-filters rouvrait le
   panneau à l'écran alors qu'il restait aria-hidden pour les lecteurs
   d'écran — et le corps restait bloqué au défilement. */
.shop-drawer:target:not([aria-hidden="true"]) { visibility: visible; pointer-events: auto; }
.shop-drawer:target:not([aria-hidden="true"]) .drawer__veil { opacity: 1; }
.shop-drawer:target:not([aria-hidden="true"]) .drawer__panel { transform: translateX(0); }

/* Le fond ne défile pas derrière le tiroir, même sans script. */
body:has(.shop-drawer:target:not([aria-hidden="true"])) { overflow: hidden; }

@media (min-width: 62rem) {
  .shop-drawer { display: none; }
}

/* =============================================================
   ÉTATS VIDES
   ============================================================= */
.shop-main .empty {
  max-width: 40rem;
  padding: var(--s-8) var(--s-6);
  border: 1px solid var(--border-soft);
  border-radius: var(--r-md);
  background: var(--surface-alt);
}
.empty__actions { justify-content: center; }
.empty__aside {
  display: inline-flex;
  align-items: flex-start;
  gap: var(--s-2);
  margin: 0;
  font-size: var(--t-xs);
  line-height: 1.6;
  color: var(--text-muted);
}
.empty__aside .ico { color: var(--primary); margin-top: var(--s-1); }
