/* ============================================================
   TULIPE PALETTES - PAGE CATALOGUE
   Géométrie reprise de l'écran validé (fil d'Ariane, en-tête, barre de filtres,
   grille 4/3/2/1 colonnes, pagination). Couleurs = tokens ; rayons = --r-* ;
   le conteneur suit le conteneur commun du site (1440 px, gouttière --container-padding-x)
   pour s'aligner sur le header (l'écran d'origine était en 1200 px).
   ============================================================ */
.catalog-page { max-width: var(--container-max-width-wide); margin-inline: auto; padding: var(--page-top-gap) var(--container-padding-x) var(--section-padding-y); }
#breadcrumb { min-height: 21px; } /* fil d'Ariane injecté par JS : place réservée (1 ligne), pas de décalage */
.catalog-intro { margin-top: 16px; display: flex; flex-direction: column; gap: 8px; }
.catalog-intro__heading { display: flex; align-items: baseline; justify-content: space-between; flex-wrap: wrap; gap: 12px; }
.catalog-intro__title { font-size: var(--fs-page-title); font-weight: 600; line-height: 1.15; color: var(--color-forest); }
.catalog-intro__count { min-width: 80px; min-height: 21px; /* réserve la place avant le rendu JS : évite le décalage de mise en page */ font-size: var(--fs-sm); font-weight: 500; color: var(--color-text-muted); white-space: nowrap; }
.catalog-intro__description { max-width: 640px; font-size: var(--fs-base); line-height: 1.55; color: var(--color-text-muted); }

.catalog-filters { margin-top: 32px; padding: 16px 24px; border-radius: var(--r-card); background: var(--color-surface-dim); border: 1px solid var(--color-border); }
.catalog-filters__form { display: flex; align-items: center; flex-wrap: wrap; gap: 16px; }
.catalog-filters__field { display: flex; align-items: center; min-width: 0; max-width: 100%; }
.catalog-filters__field--checkbox { gap: 8px; }
.catalog-filters__label { font-size: var(--fs-sm); color: var(--color-ink); }
.catalog-filters__field--checkbox .catalog-filters__label { display: inline-flex; align-items: center; min-height: 44px; flex: 1 1 auto; cursor: pointer; } /* zone tactile 44 px : étiquette cliquable pleine hauteur */
.catalog-filters__select { height: 44px; min-width: min(190px, 100%); max-width: 100%; flex: 1 1 auto; text-overflow: ellipsis; padding-inline: 14px 44px; font-size: 16px; /* 16 px : pas de zoom automatique d'iOS au focus */ background-color: var(--color-paper); border: 1.5px solid var(--color-border-field); border-radius: var(--r-control);
  /* Chevron personnalisé : le chevron natif est collé au bord droit, on le décale de 14 px. */
  appearance: none; -webkit-appearance: none; cursor: pointer;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%236B4A34' stroke-width='2'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 14px center; background-size: 18px; }
.catalog-filters__select:hover { border-color: var(--color-wood); }
/* Focus : pas d'anneau décalé, la bordure passe simplement en sapin (épaissie de 1 px, sans espace). */
.catalog-filters__select:focus-visible { outline: none; border-color: var(--color-forest); box-shadow: 0 0 0 1px var(--color-forest); }
.catalog-filters__checkbox { width: 20px; height: 20px; accent-color: var(--color-forest); }

.product-grid { margin-top: 32px; scroll-margin-top: 16px; } /* s'ajoute au scroll-padding-top (130 px) de <html> : le début de la liste se cale sous l'en-tête collant */
.product-grid__list { --product-grid-columns: 4; --product-grid-gap: 24px; display: flex; flex-wrap: wrap; gap: var(--product-grid-gap); }
.product-grid__item { flex: 0 0 calc((100% - (var(--product-grid-columns) - 1) * var(--product-grid-gap)) / var(--product-grid-columns)); min-width: 0; display: flex; }
.product-grid__item .product-card { height: 100%; }
/* Apparition des cartes dès le rendu (filtre, tri, pagination) : plus dépendante du scroll.
   Fondu court et décalé ; aucune carte n'est jamais laissée invisible. */
@media (prefers-reduced-motion: no-preference) {
  .product-grid__item { animation: catalog-card-in 320ms ease both; animation-delay: calc(var(--i, 0) * 40ms); }
}
@keyframes catalog-card-in { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
.product-grid:focus { outline: none; } /* focus programmatique après changement de page */
.product-grid[data-state="loading"] .product-grid__list { min-height: 480px; }

.pagination { margin-top: 40px; display: flex; justify-content: center; }
.pagination__list { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; justify-content: center; }
.pagination__link, .pagination__control { min-width: 44px; min-height: 44px; padding-inline: 8px; white-space: nowrap; display: flex; align-items: center; justify-content: center; border-radius: var(--r-control); font-size: var(--fs-sm); font-weight: 600; color: var(--color-ink); border: 1.5px solid transparent; transition: background-color 160ms ease, border-color 160ms ease; }
a.pagination__link:hover, a.pagination__control:hover { background: var(--color-surface-dim); border-color: var(--color-border-field); }
.pagination__link[aria-current="page"] { background: var(--color-ember); color: var(--color-paper); }
.pagination__control.is-disabled { opacity: 0.4; }
.pagination__item--ellipsis { min-width: 32px; text-align: center; color: var(--color-text-muted); }
.pagination__link:focus-visible, .pagination__control:focus-visible { outline: 2px solid var(--color-focus); outline-offset: 2px; }

@media (max-width: 1279px) { .product-grid__list { --product-grid-columns: 3; } }
@media (max-width: 959px) { .product-grid__list { --product-grid-columns: 2; --product-grid-gap: 16px; }
  .catalog-filters__field, .catalog-filters__select { flex: 1 1 200px; } }
@media (max-width: 599px) { .product-grid__list { --product-grid-columns: 2; --product-grid-gap: 12px; } .catalog-filters { padding: 12px; } .catalog-filters__field { flex: 1 1 100%; } .catalog-filters__field--checkbox { flex-basis: 100%; } }

/* Anti-décalage : tant que le JS n'a pas posé le titre, la description et le fil d'Ariane de l'état demandé
   (catégorie, recherche...), les blocs restent invisibles MAIS gardent leur place (visibility, pas display).
   Sans JS (classe no-js) : tout reste visible. Sécurité : visibles au bout de 3 s même si le script échoue. */
html:not(.no-js) .catalog-page:not([data-heading]) > * { visibility: hidden; animation: catalog-failsafe 0s 3s forwards; }
@keyframes catalog-failsafe { to { visibility: visible; } }
