/* ============================================================
   TULIPE PALETTES - HEADER
   Phase 6 : Production Optimization & Code Quality
   Design, layout et animations inchangés depuis les Phases 2-5.
   Cette passe corrige la duplication de sélecteurs, le contraste
   du placeholder de recherche (WCAG AA) et documente les tokens
   du design system ci-dessous. Aucune propriété coûteuse
   (width/height/top/left) n'est animée - uniquement transform
   et opacity.
   ============================================================ */

body.has-locked-scroll {
  overflow: hidden;
}

/* ------------------------------------------------------------
   2. VARIABLES (reset et typo de base : voir css/global/)
   ------------------------------------------------------------ */
.site-header {
  /* Même conteneur et même gouttière que les sections (tokens.css) : le logo
     s'aligne sur le texte du hero et le reste de la page. */
  --header-max-width: var(--container-max-width-wide);
  --header-padding-inline: var(--container-padding-x);

  --topbar-padding-block: clamp(6px, 0.6vw, 8px);
  /* Bandes compactées : le hero gagne ~50px de hauteur visible sans écraser
     la navigation (cibles tactiles ≥ 44px conservées sur mobile). */
  --main-padding-block: clamp(10px, 1.1vw, 15px);
  --categories-padding-block: clamp(7px, 0.7vw, 10px);

  --search-height: 44px;
  --search-max-width: 260px;
  --icon-size-topbar: 20px;
  --topbar-height: 36px; /* hauteur fixe : sert aussi de décalage au header collant */
  --icon-size-header: 20px;
  --logo-icon-size: clamp(36px, 4.2vw, 46px);
  --action-button-size: 44px;

  --nav-gap: clamp(20px, 3vw, 48px);
  --actions-gap: clamp(8px, 1.5vw, 18px);

  --logo-font-size: clamp(22px, 2.8vw, 29px);

  --color-ink-soft: #56534d;
  --color-placeholder: #68625a; /* contraste 4.56:1 sur --color-field (champ de recherche) et 5.2:1 sur --color-cream (WCAG AA) */
  --color-white: #ffffff;

  --mobile-nav-width: min(360px, 86vw);

  /* --- Motion : courbes et durées, centralisées --- */
  --ease-standard: cubic-bezier(0.4, 0, 0.2, 1);   /* transitions d'état (hover, focus) */
  --ease-decel: cubic-bezier(0, 0, 0.2, 1);        /* panneaux qui entrent à l'écran */
  --duration-fast: 150ms;   /* couleur, icône */
  --duration-base: 220ms;   /* boutons, liens */
  --duration-panel: 320ms;  /* nav mobile, recherche */
}

/* ------------------------------------------------------------
   3. CONTENEUR GÉNÉRIQUE
   ------------------------------------------------------------ */
.topbar__container,
.header__container {
  width: 100%;
  max-width: var(--header-max-width);
  margin-inline: auto;
  padding-inline: var(--header-padding-inline);

  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}

.site-header {
  /* Header collant : la barre sombre (topbar) défile et disparaît, tandis que
     l'en-tête principal + la bande des catégories restent en haut de page.
     Le décalage négatif = hauteur exacte de la topbar (fixe, voir plus bas). */
  position: sticky;
  top: calc(-1 * var(--topbar-height));
  z-index: 70;
}

/* --- État « collé » (.is-stuck, posé par header.js quand la topbar est sortie) ---
   Pas d'ombre portée (effet « appli startup ») : un filet « bois & braise » se
   dessine sous la bande des catégories, du centre vers les bords - comme une
   braise qui s'allume. Dégradé bois → braise → bois, pleine opacité jusqu'aux bords.
   Le filet occupe toute la largeur de l'écran, bord à bord, sans extrémités estompées.
   Il est en absolu sous le header : rien ne change de taille (pas de saut de page). */
.site-header::after {
  content: "";
  position: absolute;
  inset-inline: 0;
  top: 100%;
  height: 3px;
  background: linear-gradient(
    90deg,
    var(--color-wood) 0%,
    var(--color-ember) 50%,
    var(--color-wood) 100%
  );
  opacity: 0;
  transform: scaleX(0.35);
  transform-origin: center;
  transition: opacity var(--duration-panel) var(--ease-standard),
              transform 480ms var(--ease-standard);
  pointer-events: none;
}

.site-header.is-stuck::after {
  opacity: 1;
  transform: scaleX(1);
}

.header__main,
.header__categories {
  transition: border-color var(--duration-panel) var(--ease-standard);
}

/* Le filet braise remplace l'ancien filet gris : on garde celui du bas discret */
.site-header.is-stuck .header__categories {
  border-bottom-color: transparent;
}

@media (prefers-reduced-motion: reduce) {
  .site-header::after { transform: none; transition: opacity var(--duration-panel) linear; }
}

/* Desktop : contrôles légèrement plus compacts (la souris n'exige pas 44px) */
@media (min-width: 1181px) {
  .site-header {
    --action-button-size: 40px;
    --search-height: 40px;
  }
}

/* ============================================================
   4. TOPBAR : bandeau d'offres (un message à la fois, défilement vertical)
   Messages : js/data/offers.js. Seuls transform et opacity s'animent.
   ============================================================ */
.topbar {
  height: var(--topbar-height);
  background-color: var(--color-bark);
  color: var(--color-paper);
}

.topbar__container {
  height: 100%;
}

.topbar__offers {
  position: relative;
  flex: 1;
  height: 100%;
  overflow: hidden;
}

.topbar__offer {
  position: absolute;
  inset: 0;
  opacity: 0;
  visibility: hidden;
  transform: translateY(60%);
  transition: opacity 380ms var(--ease-standard), transform 380ms var(--ease-standard), visibility 0s linear 380ms;
}

.topbar__offer.is-active {
  opacity: 1;
  visibility: visible;
  transform: none;
  transition-delay: 0s;
}

.topbar__offer.is-leaving {
  transform: translateY(-60%);
}

.topbar__offer-link {
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 9px;
  color: inherit;
  font-size: 13px;
  font-weight: 500;
  line-height: 16px;
  letter-spacing: 0.01em;
  white-space: nowrap;
}

.topbar__offer-text {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
}

.topbar__offer-link:hover .topbar__offer-text,
.topbar__offer-link:focus-visible .topbar__offer-text {
  text-decoration: underline;
  text-underline-offset: 3px;
}

.topbar__offer-text--short {
  display: none;
}

.topbar__sticker {
  flex: none;
  font-size: 16px;
  line-height: 1;
}

/* Pastille de remise : braise sur fond sombre */
.topbar__badge {
  flex: none;
  padding: 1px 7px;
  border-radius: var(--r-badge);
  background-color: var(--color-ember);
  color: var(--color-white);
  font-size: 12px;
  font-weight: 700;
  line-height: 18px;
}

/* Le sticker « sursaute » à l'arrivée de chaque message pour attirer l'œil */
@media (prefers-reduced-motion: no-preference) {
  .topbar__offer.is-active .topbar__sticker {
    animation: topbar-sticker-pop 700ms var(--ease-decel) 150ms both;
  }
}

@keyframes topbar-sticker-pop {
  0%   { transform: scale(0.4) rotate(-25deg); }
  60%  { transform: scale(1.35) rotate(12deg); }
  100% { transform: scale(1) rotate(0); }
}

@media (prefers-reduced-motion: reduce) {
  .topbar__offer { transition: none; }
}

/* ============================================================
   5. EN-TÊTE PRINCIPAL
   ============================================================ */
.header__main {
  background-color: var(--color-paper);
  border-bottom: 1px solid rgba(38, 38, 38, 0.07);
}

.header__container {
  padding-block: var(--main-padding-block);
  position: relative;
}

.header__menu-toggle {
  display: none;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-width: var(--action-button-size);
  height: var(--action-button-size);
  padding-inline: 12px;
  flex-shrink: 0;
  color: var(--color-forest);
  order: -1;
  border: 1px solid color-mix(in srgb, var(--color-forest) 22%, transparent);
  border-radius: var(--r-control);
  transition: background-color var(--duration-fast) var(--ease-standard),
              border-color var(--duration-fast) var(--ease-standard),
              transform var(--duration-fast) var(--ease-standard);
}

.header__menu-toggle:hover {
  background-color: color-mix(in srgb, var(--color-forest) 7%, transparent);
  border-color: color-mix(in srgb, var(--color-forest) 40%, transparent);
}

.header__menu-toggle:active {
  transform: scale(0.96);
}

/* Icône : trois planches décalées (clin d'œil à la palette), la planche du milieu en rouge braise.
   À l'ouverture, elles se rejoignent en croix. */
.header__menu-icon {
  display: inline-block;
  width: 22px;
  height: 22px;
  flex-shrink: 0;
}

.header__menu-icon svg {
  display: block;
  width: 100%;
  height: 100%;
  overflow: visible;
}

.header__menu-bar {
  transform-box: fill-box;
  transform-origin: center;
  transition: transform 260ms var(--ease-standard), opacity 160ms var(--ease-standard);
}

.header__menu-bar--mid { fill: var(--color-ember); }

.header__menu-toggle[aria-expanded="true"] .header__menu-bar--top {
  transform: translateY(5.7px) rotate(45deg);
}

.header__menu-toggle[aria-expanded="true"] .header__menu-bar--bot {
  transform: translate(3.5px, -5.7px) rotate(-45deg) scaleX(1.58);
}

.header__menu-toggle[aria-expanded="true"] .header__menu-bar--mid {
  opacity: 0;
  transform: scaleX(0);
}

/* Libellé visible : l'icône seule ne suffit pas à tout le monde, le mot « Menu » lève le doute. */
.header__menu-label {
  font-family: var(--font-sans);
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  line-height: 1;
}

.header__menu-label-close { display: none; }

.header__menu-toggle[aria-expanded="true"] .header__menu-label-open { display: none; }
.header__menu-toggle[aria-expanded="true"] .header__menu-label-close { display: inline; }

/* Très petits écrans : l'icône seule garde la place du logo et des actions. */
@media (max-width: 359px) {
  .header__menu-label { display: none; }
  .header__menu-toggle { padding-inline: 0; width: var(--action-button-size); }
}

/* --- Logo --- */
.header__logo {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-shrink: 0;
  min-height: 44px; /* zone tactile ; la rangée fait déjà 40 px de haut au minimum */
  color: var(--color-forest);
}

.header__logo-icon {
  display: inline-flex;
  /* Monogramme TP : 397 x 264 (≈ 3:2). On fixe la hauteur, la largeur suit. */
  height: calc(var(--logo-icon-size) * 0.8);
  aspect-ratio: 397 / 264;
  flex-shrink: 0;
  transition: transform var(--duration-base) var(--ease-standard);
}

.header__logo-icon svg {
  width: 100%;
  height: 100%;
}

/* Le monogramme grossit très légèrement au survol. */
.header__logo:hover .header__logo-icon,
.header__logo:focus-visible .header__logo-icon {
  transform: scale(1.06);
}

/* Mot-symbole dessiné (SVG, pas de police) : « Tulipe » en grosses barres, « PALETTES » en lettres claires dans une pastille braise.
   Sa hauteur suit le font-size de .header__logo-text (les points de rupture plus bas ne changent que ce font-size). */
.header__logo-text {
  display: block;
  font-size: var(--logo-font-size);
  white-space: nowrap;
  color: var(--color-forest);
  --logo-dot: #B0600A;          /* ocre du pied du P (logo) */
  --logo-pill: var(--color-ember);       /* pastille « PALETTES » = braise */
  --logo-pill-text: var(--color-paper);
  transition: opacity var(--duration-fast) var(--ease-standard);
}

.header__logo-text .logo-wordmark {
  display: block;
  height: 1.55em;               /* viewBox 346 x 182 : « Tulipe » garde la taille d'avant (1,45 em pour 170 u) */
  width: auto;
}

.header__logo:hover .header__logo-text,
.header__logo:focus-visible .header__logo-text {
  opacity: 0.85;
}

/* --- Navigation principale --- */
.header__nav-list {
  display: flex;
  align-items: center;
  gap: var(--nav-gap);
}

.header__nav-link {
  position: relative;
  display: inline-flex;
  align-items: center;
  font-size: 15px;
  font-weight: 500;
  line-height: 20px;
  white-space: nowrap;
  padding-block: 4px;
  color: var(--color-ink);
  border-bottom: 2px solid transparent;
  transition: color var(--duration-base) var(--ease-standard);
}

/* Soulignement animé : une ligne indépendante du border-bottom
   (déjà utilisé pour l'état actif), qui se déploie depuis le
   centre au survol des liens inactifs. */
.header__nav-link::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: -2px;
  height: 2px;
  background-color: var(--color-forest);
  transform: scaleX(0);
  transition: transform var(--duration-base) var(--ease-standard);
}

.header__nav-link:hover,
.header__nav-link:focus-visible {
  color: var(--color-forest);
}

.header__nav-link:hover::after,
.header__nav-link:focus-visible::after {
  transform: scaleX(1);
}

.header__nav-link[aria-current="page"] {
  color: var(--color-forest);
  border-bottom-color: var(--color-forest);
}

/* Le lien actif a déjà son trait via border-bottom : pas besoin
   du second soulignement animé par-dessus. */
.header__nav-link[aria-current="page"]::after {
  display: none;
}

/* Icônes du menu : brun bois (token --color-wood), qui passe au vert forêt au survol et sur la page courante. */
.header__nav-icon {
  flex: none;
  width: 20px;
  height: 20px;
  margin-right: 8px;
  color: var(--color-wood);
  transition: color var(--duration-base) var(--ease-standard), transform var(--duration-base) var(--ease-standard);
}

.header__nav-link:hover .header__nav-icon,
.header__nav-link:focus-visible .header__nav-icon,
.header__nav-link[aria-current="page"] .header__nav-icon {
  color: var(--color-forest);
}

@media (hover: hover) and (prefers-reduced-motion: no-preference) {
  .header__nav-link:hover .header__nav-icon {
    transform: translateY(-1px);
  }
}

.header__nav-utility {
  display: none;
}

/* ============================================================
   PANNEAU MOBILE + VOILE
   Toujours présents dans le flux (visibility, pas display),
   pour que l'ouverture/fermeture puisse être animée.
   ============================================================ */
.header__nav-scrim {
  position: fixed;
  inset: 0;
  z-index: 50;
  background-color: rgba(20, 18, 15, 0.4);
  opacity: 0;
  visibility: hidden;
  transition: opacity var(--duration-panel) var(--ease-standard),
              visibility 0s linear var(--duration-panel);
}

.header__nav-scrim.is-open {
  opacity: 1;
  visibility: visible;
  transition: opacity var(--duration-panel) var(--ease-standard);
}

/* --- Actions --- */
.header__actions {
  display: flex;
  align-items: center;
  gap: var(--actions-gap);
  flex-shrink: 0;
}

.header__search-toggle {
  display: none;
  align-items: center;
  justify-content: center;
  width: var(--action-button-size);
  height: var(--action-button-size);
  flex-shrink: 0;
  color: var(--color-ink);
  border-radius: var(--r-control);
  transition: background-color var(--duration-fast) var(--ease-standard),
              transform var(--duration-fast) var(--ease-standard),
              color var(--duration-fast) var(--ease-standard);
}

.header__search-toggle:hover {
  background-color: rgba(38, 38, 38, 0.06);
  color: var(--color-forest);
}

.header__search-toggle:active {
  transform: scale(0.94);
}

.header__search {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  max-width: var(--search-max-width);
  height: var(--search-height);
  border-radius: var(--r-control);
  padding-inline: 16px;
  background-color: var(--color-field); /* en creux : visible sur le header clair */
  box-shadow: 0 0 0 1px var(--color-field-edge);
  transition: box-shadow var(--duration-base) var(--ease-standard), background-color var(--duration-base) var(--ease-standard);
}

/* Halo de focus sur tout le champ, pas seulement sur l'input :
   confirme que la zone entière appartient au même composant.
   Trait de 1px (même épaisseur que l'état repos) : à 2px il paraissait trop épais. */
.header__search:focus-within {
  background-color: var(--color-paper); /* le champ s'éclaircit quand on y écrit */
  box-shadow: 0 0 0 1px var(--color-forest);
}

.header__search-input {
  flex: 1 1 auto;
  min-width: 0;
  height: 100%;
  border: none;
  background: transparent;
  font-family: var(--font-sans);
  font-size: 14px;
  color: var(--color-ink);
}

/* Le focus est déjà signalé par l'anneau arrondi de .header__search
   (:focus-within ci-dessus) : on retire le contour générique de
   base.css sur l'input lui-même, qui est rectangulaire et déborde
   des coins arrondis du champ (double contour disgracieux). */
.header__search-input:focus-visible {
  outline: none;
  box-shadow: none; /* l'anneau est celui du conteneur .header__search */
}

/* Remplissage automatique : le navigateur impose un fond bleu / jaune sur le champ transparent.
   On le recouvre avec la couleur du conteneur (voir form-field.css pour le détail de la technique). */
.header__search-input:is(:-webkit-autofill, :autofill) {
  -webkit-text-fill-color: var(--color-ink);
  caret-color: var(--color-ink);
  box-shadow: 0 0 0 1000px var(--color-field) inset;
}

@media (pointer: coarse) {
  .header__search-input { font-size: 16px; } /* évite le zoom automatique d'iOS au-delà de 1180 px aussi */
}
.header__search-input::placeholder {
  color: var(--color-placeholder);
  transition: color var(--duration-fast) var(--ease-standard);
}

.header__search:focus-within .header__search-input::placeholder {
  color: var(--color-ink-soft);
}

.header__search-button {
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--search-height); /* zone tactile = hauteur du champ ; l'icône garde sa place (marge négative) */
  height: var(--search-height);
  margin-inline-end: calc((var(--search-height) - var(--icon-size-header)) / -2);
  color: var(--color-ink);
  transition: color var(--duration-fast) var(--ease-standard),
              transform var(--duration-fast) var(--ease-standard);
}

.header__search-button:hover {
  color: var(--color-forest);
}

.header__search-button:active {
  transform: scale(0.9);
}

.header__icon {
  display: inline-flex;
  width: var(--icon-size-header);
  height: var(--icon-size-header);
  color: var(--color-ink);
  transition: transform var(--duration-base) var(--ease-standard);
}

.header__icon svg {
  width: 100%;
  height: 100%;
}

.header__action-link {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--action-button-size);
  height: var(--action-button-size);
  flex-shrink: 0;
  color: var(--color-ink);
  border-radius: var(--r-control);
  transition: background-color var(--duration-fast) var(--ease-standard),
              color var(--duration-fast) var(--ease-standard),
              transform var(--duration-fast) var(--ease-standard);
}

.header__action-link:hover {
  background-color: rgba(38, 38, 38, 0.06);
  color: var(--color-forest);
}

.header__action-link:active {
  transform: scale(0.94);
}

/* Le panier reçoit un mouvement un peu plus marqué : c'est
   l'action la plus commerciale de l'en-tête. */
.header__action-link--cart:hover .header__icon {
  transform: translateY(-1px) rotate(-4deg);
}

.header__cart-count {
  position: absolute;
  top: 2px;
  right: 2px;
  min-width: 20px;
  min-height: 20px; /* pas de hauteur fixe : la pastille suit son texte */
  padding-inline: 5px;
  border-radius: 999px; /* pastille de comptage : reste ronde (exception assumée) */
  background-color: var(--color-ember);
  color: var(--color-white);
  font-size: 12px;
  font-weight: 600;
  line-height: 20px;
  text-align: center;
}

/* ============================================================
   6. NAVIGATION SECONDAIRE - catégories
   ============================================================ */
.header__categories {
  background-color: var(--color-cream);
  border-bottom: 1px solid rgba(38, 38, 38, 0.07);
}

.header__categories > .header__container {
  justify-content: flex-start;
  padding-block: var(--categories-padding-block);
}

.header__categories-list {
  display: flex;
  align-items: center;
  gap: 32px;
}

.header__categories-link {
  position: relative;
  display: inline-flex;
  align-items: center;
  font-size: 14px;
  font-weight: 500;
  line-height: 20px;
  white-space: nowrap;
  padding-block: 4px;
  color: var(--color-ink);
  border-bottom: 2px solid transparent;
  transition: color var(--duration-base) var(--ease-standard);
}

.header__categories-link::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: -2px;
  height: 2px;
  background-color: var(--color-forest); /* même trait que la navigation principale */
  transform: scaleX(0);
  transition: transform var(--duration-base) var(--ease-standard);
}

.header__categories-link:hover,
.header__categories-link:focus-visible {
  color: var(--color-forest); /* texte + trait en vert, comme .header__nav-link */
}

.header__categories-link:hover::after,
.header__categories-link:focus-visible::after {
  transform: scaleX(1);
}

/* Catégorie courante : texte vert + trait plein, comme .header__nav-link[aria-current].
   Indispensable sur mobile : la bande défile, et c'est ce repère qui dit où l'on est
   (le JS la recentre sur ce lien à chaque page, voir revealCurrentCategory()). */
.header__categories-link[aria-current="page"] {
  color: var(--color-forest);
  font-weight: 600;
}

.header__categories-link[aria-current="page"]::after {
  transform: scaleX(1);
}

/* ============================================================
   11. NAVIGATION MOBILE (≤ 1180px)
   Seuil relevé de 991 à 1180px : entre les deux, la nav complète
   + la recherche + compte/panier avaient besoin de plus de place
   que la ligne desktop n'en laissait, et rien ne pouvait rétrécir
   en dessous - le surplus était poussé hors écran à droite au lieu
   de passer en menu mobile. 1180px laisse une marge de sécurité
   confortable au-dessus du seuil réel de débordement (~1075px).
   Le panneau et la recherche restent dans le flux (visibility)
   pour glisser/s'estomper au lieu d'apparaître d'un bloc.
   ============================================================ */
@media (max-width: 1180px) {
  /* Rangée d'en-tête en 3 zones : menu à gauche, logo CENTRÉ, actions à droite.
     Les colonnes latérales sont égales (1fr), donc le logo est équidistant du menu et des
     actions au lieu d'être collé au bouton Menu. Le panneau (.header__nav), le voile et le
     champ de recherche sont en position fixed / absolute : ils ne comptent pas comme zones. */
  .header__main > .header__container {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
    column-gap: 8px;
  }

  .header__menu-toggle {
    display: inline-flex;
    position: relative;
    z-index: 65; /* au-dessus du panneau (60) : la croix de fermeture reste visible et cliquable */
    justify-self: start;
  }

  .header__logo {
    justify-self: center;
  }

  /* Les icônes (20 px) vivent dans des zones tactiles de 40 px : on laisse la dernière déborder
     dans la gouttière pour que le DESSIN du panier s'aligne sur le bord droit du contenu,
     comme le bouton Menu s'aligne sur le bord gauche (même marge visuelle de 16 px). */
  .header__actions {
    justify-self: end;
    margin-inline-end: calc((var(--action-button-size) - var(--icon-size-header)) / -2);
  }

  .header__nav {
    position: fixed;
    inset: 0;
    z-index: 60;
    width: var(--mobile-nav-width);
    max-width: 100%;
    background-color: var(--color-paper);
    /* le haut du panneau laisse la place à la rangée d'en-tête (topbar + bouton) où reste la croix */
    padding: calc(var(--topbar-height) + 2 * var(--main-padding-block) + var(--action-button-size) + 12px) var(--header-padding-inline) 32px; /* mêmes marges que la rangée d'en-tête : liens alignés sur le bouton « Fermer » */
    display: flex;
    flex-direction: column;
    gap: 32px;
    overflow-y: auto;
    box-shadow: 2px 0 12px rgba(0, 0, 0, 0.08);

    visibility: hidden;
    transform: translateX(-100%);
    transition: transform var(--duration-panel) var(--ease-decel),
                visibility 0s linear var(--duration-panel);
  }

  .header__nav.is-open {
    visibility: visible;
    transform: translateX(0);
    transition: transform var(--duration-panel) var(--ease-decel);
  }

  .header__nav-list {
    flex-direction: column;
    align-items: flex-start;
    gap: 8px;
    width: 100%;
  }

  .header__nav-link {
    width: 100%;
    padding-block: 14px;
    font-size: 18px;
    border-bottom: 1px solid rgba(38, 38, 38, 0.08);

    /* Apparition en cascade : chaque lien part légèrement décalé
       et rejoint sa place pendant que le panneau glisse. */
    opacity: 0;
    transform: translateX(-8px);
    transition: opacity var(--duration-base) var(--ease-standard),
                transform var(--duration-base) var(--ease-standard),
                color var(--duration-base) var(--ease-standard);
  }

  .header__nav-link::after {
    display: none; /* le soulignement animé n'a pas de sens en pile verticale */
  }

  .header__nav-icon {
    width: 22px;
    height: 22px;
    margin-right: 14px;
  }

  .header__nav.is-open .header__nav-link {
    opacity: 1;
    transform: translateX(0);
  }

  .header__nav-item:nth-child(1) .header__nav-link { transition-delay: 60ms; }
  .header__nav-item:nth-child(2) .header__nav-link { transition-delay: 110ms; }
  .header__nav-item:nth-child(3) .header__nav-link { transition-delay: 160ms; }
  .header__nav-item:nth-child(4) .header__nav-link { transition-delay: 210ms; }

  .header__nav-link[aria-current="page"] {
    border-bottom-color: var(--color-forest);
  }

  .header__nav-utility {
    display: block;
    margin-top: auto;
    padding-top: 20px;
    border-top: 1px solid rgba(38, 38, 38, 0.08);
  }

  .header__nav-utility-link {
    font-size: 14px;
    color: var(--color-ink-soft);
  }

  .header__search-toggle {
    display: inline-flex;
  }

  .header__search {
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    max-width: none;
    height: 64px;
    border-radius: 0;
    padding-inline: var(--header-padding-inline);
    box-shadow: 0 3px 8px rgba(0, 0, 0, 0.05);
    z-index: 40;

    visibility: hidden;
    opacity: 0;
    transform: translateY(-6px);
    transition: opacity var(--duration-base) var(--ease-standard),
                transform var(--duration-base) var(--ease-standard),
                visibility 0s linear var(--duration-base);
  }

  .header__search.is-open {
    visibility: visible;
    opacity: 1;
    transform: translateY(0);
    transition: opacity var(--duration-base) var(--ease-standard),
                transform var(--duration-base) var(--ease-standard);
  }

  .header__search:focus-within {
    box-shadow: 0 3px 8px rgba(0, 0, 0, 0.05);
  }

  .header__search-input {
    font-size: 16px;
  }
}

/* ============================================================
   12. TABLETTE (≤ 768px)
   ============================================================ */
@media (max-width: 768px) {
  .header__categories-list {
    flex-wrap: nowrap;
    overflow-x: auto;
    gap: 24px;
    padding-bottom: 2px;
    scrollbar-width: none;
    -ms-overflow-style: none;
  }

  .header__categories-list::-webkit-scrollbar {
    display: none;
  }

  .header__categories-item {
    flex-shrink: 0;
  }

  /* Indice de défilement : un fondu + un chevron sur le(s) bord(s) où il reste des catégories.
     Les classes .has-more-start / .has-more-end sont posées par bindCategoriesScroll() (header.js),
     uniquement quand la liste déborde réellement ; sans JS, rien ne s'affiche (la liste reste défilable).
     Purement décoratif : pointer-events: none, les liens dessous restent cliquables.
     Fondu = pseudo-éléments de la bande ; chevron = pseudo-éléments de son conteneur (un masque
     colorierait aussi le dégradé s'ils étaient sur le même élément). */
  .header__categories {
    position: relative;
  }

  .header__categories::before,
  .header__categories::after,
  .header__categories > .header__container::before,
  .header__categories > .header__container::after {
    content: "";
    position: absolute;
    pointer-events: none;
    opacity: 0;
    transition: opacity var(--duration-base) var(--ease-standard);
  }

  .header__categories::before,
  .header__categories::after {
    top: 0;
    bottom: 1px;
    width: 52px;
    z-index: 1;
  }

  .header__categories::after {
    right: 0;
    background: linear-gradient(to right, transparent, var(--color-cream) 62%);
  }

  .header__categories::before {
    left: 0;
    background: linear-gradient(to left, transparent, var(--color-cream) 62%);
  }

  .header__categories > .header__container::before,
  .header__categories > .header__container::after {
    top: 50%;
    width: 7px;
    height: 12px;
    margin-top: -6px;
    z-index: 2;
    background: var(--color-forest);
    -webkit-mask: var(--chevron) center / contain no-repeat;
            mask: var(--chevron) center / contain no-repeat;
  }

  .header__categories > .header__container {
    --chevron: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 7 12' fill='none' stroke='%23000' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M1 1l5 5-5 5'/%3E%3C/svg%3E");
  }

  .header__categories > .header__container::after {
    right: var(--header-padding-inline);
  }

  .header__categories > .header__container::before {
    left: var(--header-padding-inline);
    transform: scaleX(-1);
  }

  .header__categories.has-more-end::after,
  .header__categories.has-more-end > .header__container::after,
  .header__categories.has-more-start::before,
  .header__categories.has-more-start > .header__container::before {
    opacity: 1;
  }

  /* Petit appel du regard : le chevron de droite pousse 3 fois vers la droite, puis reste fixe */
  @media (prefers-reduced-motion: no-preference) {
    .header__categories.has-more-end > .header__container::after {
      animation: header-categories-nudge 900ms var(--ease-standard) 600ms 3;
    }
  }
}

/* ============================================================
   13. GRAND SMARTPHONE (≤ 576px)
   ============================================================ */
@media (max-width: 576px) {
  /* Pastille du panier : plus petite, elle ne recouvre plus l'icône et reste dans l'écran. */
  .header__cart-count {
    top: 4px;
    right: 4px; /* reste à ~10 px du bord d'écran (le panier déborde déjà dans la gouttière) */
    min-width: 18px;
    min-height: 18px;
    padding-inline: 4px;
    font-size: 11px;
    line-height: 18px;
  }
}

/* ============================================================
   14. SMARTPHONE STANDARD (≤ 430px)
   ============================================================ */
@media (max-width: 430px) {
  /* Logo + menu + 3 actions demandaient ~425 px pour 390 px : la dernière icône (panier)
     sortait de l'écran. Boutons 40 px (≥ 24 px WCAG 2.2 AA), écarts resserrés, logo 19 px. */
  .site-header {
    --action-button-size: 40px;
    --actions-gap: 4px; /* zones tactiles de 40 px : les dessins restent espacés de 24 px */
  }

  .header__container {
    gap: 8px;
  }

  .header__logo-text {
    font-size: 19px;
  }

  /* Smartphone : texte court, sans pastille (le pourcentage est déjà dans le message) */
  .topbar__offer-text--full,
  .topbar__badge {
    display: none;
  }

  .topbar__offer-text--short {
    display: inline;
  }

  .topbar__offer-link {
    font-size: 12.5px;
  }

  .header__nav {
    width: 100%;
  }
}

/* ============================================================
   15. PETIT SMARTPHONE (≤ 375px)
   ============================================================ */
@media (max-width: 375px) {
  .site-header {
    --actions-gap: 4px;
    --logo-icon-size: 26px;
  }

  .header__logo {
    gap: 8px;
  }

  .header__logo-text {
    font-size: 17px;
  }

  .topbar__offer-link {
    gap: 6px;
  }
}

/* 360 px (Android courant) : à 16 px la rangée dépassait encore de ~9 px ; logo à 15 px. */
@media (max-width: 360px) {
  .header__logo-text {
    font-size: 15px;
  }
}

/* 320 px (très petits écrans) : même en 16 px, la rangée demandait ~378 px pour 280 px utiles.
   On resserre les espacements et les boutons (36 px, au-dessus du minimum de 24 px de WCAG 2.2 AA). */
@media (max-width: 340px) {
  .site-header {
    --action-button-size: 36px;
    --actions-gap: 0px;
  }

  /* Colonnes latérales à la taille de leur contenu : le logo occupe le milieu restant,
     les deux écarts (menu → logo, logo → actions) restent identiques. */
  .header__container {
    column-gap: 6px;
    padding-inline: 16px;
  }

  .header__main > .header__container {
    grid-template-columns: auto minmax(0, 1fr) auto;
  }

  .header__logo {
    gap: 6px;
  }

  .header__logo-text {
    font-size: 15px;
  }
}

/* ============================================================
   16. ACCESSIBILITÉ - PRÉFÉRENCE DE MOUVEMENT RÉDUIT
   Le neutralisation générale des transitions vit dans
   css/global/base.css ; ce bloc ne garde que les overrides de
   position propres au panneau mobile du header.
   ============================================================ */
@media (prefers-reduced-motion: reduce) {
  .header__logo:hover .header__logo-icon,
  .header__action-link--cart:hover .header__icon,
  .header__menu-toggle:active,
  .header__search-toggle:active,
  .header__search-button:active,
  .header__action-link:active {
    transform: none;
  }

  .header__nav {
    transform: none;
    left: -100%;
  }

  .header__nav.is-open {
    left: 0;
  }
}

/* --- Intégration : badge panier dynamique --- */
/* (le header est pré-rendu dans le HTML : plus besoin de réserver sa hauteur ; le point de montage de repli, lui, la garde) */
div[data-component="site-header"] { display: block; min-height: 156px; }
.header__cart-count[hidden] { display: none; }
@media (prefers-reduced-motion: no-preference) {
  .header__cart-count.is-bump { animation: cart-bump 320ms ease-out; }
}
@keyframes cart-bump { 0% { transform: scale(1); } 40% { transform: scale(1.35); } 100% { transform: scale(1); } }
@keyframes header-categories-nudge {
  0%, 100% { transform: translateX(0); }
  50%      { transform: translateX(5px); }
}
