/* ==========================================================================
   SantaMood — feuille de style unique.

   Couleurs, échelle typographique et composition relevées sur la maquette
   d'origine. Millave et Futura PT étant des polices commerciales dont la
   licence Framer ne suit pas en auto-hébergement, elles sont remplacées par
   Marcellus et Jost, toutes deux sous licence SIL Open Font.

   Les deux familles passent par --titre et --texte : rebasculer sur les
   polices d'origine, si leurs licences sont acquises, tient en deux lignes.
   ========================================================================== */

@font-face {
  font-family: "Playfair Display";
  src: url("/assets/fonts/playfair-latin-var.woff2") format("woff2");
  font-weight: 400 900; font-style: normal; font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
                 U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122,
                 U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: Marcellus;
  src: url("/assets/fonts/marcellus-latin.woff2") format("woff2");
  font-weight: 400; font-style: normal; font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
                 U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122,
                 U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: Jost;
  src: url("/assets/fonts/jost-latin-var.woff2") format("woff2");
  font-weight: 100 900; font-style: normal; font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
                 U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122,
                 U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

:root {
  --vert:       #043225;
  --vert-encre: #161C19;
  --creme:      #FFDFA5;
  --creme-pale: #FFF0D2;
  --rose:       #F7B1BC;
  --or:         #BC9456;
  --brun:       #985828;
  --blanc:      #FFFFFF;

  /* Millave est une grasse à fort contraste ; Marcellus, un romain léger, n'en
     rendait ni le poids ni la présence — et n'a qu'une seule graisse, donc
     aucun gras possible sans que le navigateur l'étale lui-même. Playfair
     Display couvre 400 à 900. Revenir en arrière tient en ces deux lignes. */
  --titre: "Playfair Display", "Times New Roman", Georgia, serif;
  --titre-graisse: 800;
  /* La police d'origine est « Futura PT Medium ». Framer la déclare en
     font-weight 400 parce qu'il la charge comme une famille à part, mais la
     fonte servie est bien une Medium. Jost étant variable, il faut le lui
     demander explicitement : sans ça tout le texte courant sort une graisse
     trop léger. */
  --texte: Jost, "Century Gothic", system-ui, sans-serif;
  --texte-graisse: 500;

  --t-xs: .8125rem;
  --t-sm: .875rem;
  --t-md: 1.125rem;
  --t-lg: 1.25rem;
  --t-xl: clamp(1.5rem, 1.2rem + 1.4vw, 1.875rem);
  --t-2xl: clamp(1.9rem, 1.3rem + 2.6vw, 3.125rem);
  --t-3xl: clamp(2.4rem, 1.4rem + 4.4vw, 4.4rem);
  --t-hero: clamp(1.9rem, 1.2rem + 2.4vw, 3.4rem);

  --gouttiere: clamp(1.1rem, 4vw, 3.5rem);
  --rayon: 4px;
}

* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }

body {
  margin: 0;
  background: var(--creme);
  color: var(--vert);
  font-family: var(--texte);
  font-weight: var(--texte-graisse);
  font-size: 1rem;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
}

img, video { max-width: 100%; height: auto; display: block; }
a { color: inherit; text-underline-offset: 3px; }

/* Tous les titres de la marque sont en capitales serif. */
h1, h2, h3, .titre {
  font-family: var(--titre);
  font-weight: var(--titre-graisse);
  text-transform: uppercase;
  line-height: .92;
  letter-spacing: .01em;
  text-wrap: balance;
  margin: 0;
  /* **Un mot trop long se coupe au lieu de sortir de sa boîte** — 22
     septembre 2026. En allemand et en néerlandais, des titres débordaient
     jusqu'à 99 px, parfois hors de l'écran (« DATENSCHUTZERKLÄRUNG »,
     « GLEICHGEWICHT »…). Les catalogues y posent des césures conditionnelles ;
     ceci est le filet pour tout autre mot, y compris un texte réécrit dans
     l'administration. Sans effet sur un titre qui tient. */
  overflow-wrap: break-word;
}

p { margin: 0 0 1em; }
ul, ol { margin: 0; padding: 0; list-style: none; }

/* Enveloppe de page : elle rogne le débordement horizontal des calques qui
   sortent volontairement de la fenêtre. Voir le commentaire du gabarit. */
.page { overflow-x: clip; }

.shell { width: 100%; max-width: 1440px; margin-inline: auto; padding-inline: var(--gouttiere); }
main { display: block; }

.visually-hidden {
  position: absolute !important; width: 1px; height: 1px;
  margin: -1px; padding: 0; overflow: hidden; clip-path: inset(50%); white-space: nowrap;
}
.skip-link {
  position: absolute; left: -9999px; top: 0; z-index: 100;
  background: var(--vert); color: var(--creme); padding: .8rem 1.3rem;
}
.skip-link:focus { left: 0; }
:focus-visible { outline: 3px solid var(--brun); outline-offset: 3px; }

/* ---------- bouton pilule ------------------------------------------------- */

/* Calque « pink » 251 × 56, texte « ACHETEZ MAINTENANT » en Millave 17 px. */
.pill {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: var(--rose);
  color: var(--vert-encre);
  font-family: var(--titre);
  font-weight: var(--titre-graisse);
  font-size: 17px;
  line-height: 100%;
  letter-spacing: .02em;
  text-transform: uppercase;
  text-decoration: none;
  padding: 16px;
  min-height: 56px;
  border-radius: 999px;
  border: 0;
  cursor: pointer;
  white-space: nowrap;
}
.pill:hover { background: var(--or); }

/* Variante avec la pastille ronde accolée, comme sur la maquette. */
.pill--icon { position: relative; margin-right: 2.6rem; }
.pill--icon::after {
  content: "";
  position: absolute; left: calc(100% + .35rem); top: 50%;
  width: 2.2rem; height: 2.2rem; transform: translateY(-50%);
  background: var(--rose);
  border-radius: 50%;
  /* Le tracé du sac vient de l'original : deux courbes, 16,168 × 19,395.
     J'avais dessiné une boîte à couvercle, qui se lisait comme une
     corbeille — mauvais signe sur un bouton d'achat. */
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16.168 19.395' fill='none'%3E%3Cg%3E%3Cpath d='M 4.666 4.5 L 11.495 4.5 C 14.719 4.5 15.042 6.028 15.26 7.892 L 16.114 15.099 C 16.389 17.463 15.668 19.395 12.348 19.395 L 3.822 19.395 C 0.492 19.395 -0.228 17.463 0.056 15.099 L 0.91 7.892 C 1.119 6.028 1.441 4.5 4.666 4.5 Z' fill='transparent' stroke='rgb%2822,28,25%29' stroke-linecap='round' stroke-linejoin='round' stroke-dasharray=''/%3E%3Cpath d='M 4.5 5.766 L 4.5 2.402 C 4.5 0.961 5.449 0 6.871 0 L 9.717 0 C 11.139 0 12.087 0.961 12.087 2.402 L 12.087 5.766' fill='transparent' stroke='rgb%2822,28,25%29' stroke-linecap='round' stroke-linejoin='round' stroke-dasharray=''/%3E%3C/g%3E%3C/svg%3E");
  background-size: 55%; background-position: center; background-repeat: no-repeat;
}
.pill--icon:hover::after { background-color: var(--or); }

/* Sélecteur de langue. L'original n'en a pas, et l'en-tête est calé au pixel
   sur le sien : le poser dans le flux décalerait la pilule de navigation et le
   panier. Il reste donc hors du flux — mais *dans* la barre.

   Deux versions écartées avant celle-ci :

   1. ancré sous la barre, `top: calc(100% - 4px)` : à cheval sur le bord, la
      moitié haute sur le crème et la moitié basse sur la photo du héro, en brun
      sur du sombre. Illisible et détaché — c'est ce qu'a vu l'utilisateur.
   2. les quatre codes côte à côte dans la barre : 104 px de large, alors que
      l'espace entre la pilule et le panier tombe à 115 px à 1280 et à 52 px à
      810. Il chevauchait la pilule.

   D'où le repli : 34 px fermé, la liste s'ouvre par-dessus. `.site-header__droite`
   sert de repère — elle fait la largeur du panier, donc la barre ne bouge pas,
   et l'écart suit tout seul la largeur du libellé, « PANIER » en français,
   « WINKELWAGEN » en néerlandais. */
.site-header__droite { position: relative; display: flex; align-items: center; }

/* 12 px seulement : en néerlandais « WINKELWAGEN » élargit le panier de 57 px,
   et l'espace entre la pilule et lui tombe à 58 px à 1280. */
.langues {
  position: absolute; right: calc(100% + 12px); top: 50%;
  transform: translateY(-50%);
  z-index: 41;
  font-family: var(--texte); font-weight: var(--texte-graisse);
  font-size: 12px; letter-spacing: .06em;
  /* La couleur de la barre, celle que peint réellement l'original. */
  color: #826335;
}
.langues summary {
  display: flex; align-items: center; gap: 4px;
  padding: 3px;
  border-radius: 4px;
  cursor: pointer;
  list-style: none;              /* le triangle par défaut de Firefox */
  opacity: .65; transition: opacity .15s, background-color .15s;
  white-space: nowrap;
}
.langues summary::-webkit-details-marker { display: none; }
.langues summary:hover,
.langues[open] summary { opacity: 1; background: rgb(130 99 53 / .08); }
.langues summary svg { width: 7px; height: 5px; flex: none; transition: transform .15s; }
.langues[open] summary svg { transform: rotate(180deg); }

/* La liste s'ouvre par-dessus le contenu : elle n'a pas à tenir dans la barre.
   Fond crème opaque, sinon elle se lit sur la photo du héro. */
.langues ul {
  position: absolute; right: 0; top: calc(100% + 6px);
  margin: 0; padding: 4px; list-style: none;
  min-width: 128px;
  /* Blanc, comme le panneau de menu : sur une page éditoriale le fond est
     crème lui aussi, et la liste s'y fondait. */
  background: var(--blanc);
  border: 1px solid rgb(130 99 53 / .2);
  border-radius: 8px;
  box-shadow: 0 6px 20px rgb(22 28 25 / .12);
}
.langues ul a {
  display: block; padding: 6px 10px; border-radius: 5px;
  color: inherit; text-decoration: none; letter-spacing: .02em;
  opacity: .75; transition: opacity .15s, background-color .15s;
}
.langues ul a:hover { opacity: 1; background: rgb(130 99 53 / .1); }
.langues ul a[aria-current="true"] { opacity: 1; font-weight: 700; }

/* Au téléphone l'enveloppe s'efface : le panier retrouve exactement le
   positionnement absolu que la plage téléphone lui donne, relatif au bloc de
   l'en-tête et non à une enveloppe qui n'existe plus. Le sélecteur, lui, part
   dans le panneau de menu. */
/* Sous 1026 px la barre passe en composition mobile : plus de place pour le
   sélecteur, qui vit alors dans le panneau de menu. L'enveloppe s'efface, et le
   panier retrouve exactement le positionnement absolu que cette plage lui donne,
   relatif au bloc de l'en-tête et non à une enveloppe qui n'existe plus. */
@media (max-width: 1025.98px) {
  .langues { display: none; }
  .site-header__droite { display: contents; }
}
/* ---------- en-tête -------------------------------------------------------- */

/* En-tête. Largeurs relevées sur l'original, à quatre largeurs de fenêtre puis
   confirmées à une cinquième dans chaque plage : ce ne sont pas des gouttières
   qui varient, c'est le bloc lui-même qui a une largeur fixe par point de
   rupture, centré. Le contenu commence exactement 10 px sous l'en-tête. */
/* L'en-tête de l'original ne suit pas le défilement : il reste en haut de page.
   Le mien était collant — un ajout de ma part, retiré pour rester fidèle. */
.site-header { background: var(--creme); position: relative; z-index: 40; padding-block-end: 10px; }
.site-header__inner {
  display: flex; align-items: center; justify-content: space-between;
  gap: 1.5rem;
  width: 1360px; max-width: 100%; padding-inline: 20px;
  height: 70px; min-height: 0;
  position: relative;                     /* repère de la pastille de menu */
}
@media (min-width: 1026px) and (max-width: 1439.98px) { .site-header__inner { width: 920px; } }
@media (max-width: 1025.98px) { .site-header__inner { width: 717px; height: 103px; } }
/* En dessous de 810 px le bloc fait 370 px : il déborde de 5 px de chaque côté
   d'une fenêtre de 360. C'est bien ce que fait l'original — le fond est crème,
   le débordement ne se voit pas, mais il décale les trois éléments de 5 px si
   on le rabote. `max-width` doit donc être levée ici. */
@media (max-width: 809.98px) {
  /* 370 px dans une fenêtre de 360 : `margin: auto` ne peut pas centrer un bloc
     plus large que son parent, il le colle à gauche. Le décalage de moitié le
     fait déborder également des deux côtés, comme chez l'original. */
  .site-header__inner { width: 370px; max-width: none; margin-left: calc(50% - 185px); }
}
/* #826335 : la couleur réellement peinte par l'original. Framer y arrive par
   un « multiply » sur du crème ; comme le fond de la barre ne change jamais,
   le résultat est constant et se pose directement. Relevé au pixel sur la
   capture, pas déduit. */
.site-header__brand img { width: 192px; height: 44px; }
.site-nav a, .site-nav__menu, .site-header__cart { color: #826335; }
.site-nav ul { border-color: #826335; }

.site-nav ul {
  display: flex; align-items: center; gap: clamp(1rem, 2.4vw, 2.2rem);
  border: 1px solid var(--vert); border-radius: 999px;
  padding: .55rem 1.6rem;
}

@media (min-width: 1026px) {
  .site-nav { position: absolute; top: 9px; left: 480px; }
  .site-nav ul {
    width: 422px; height: 53px;
    justify-content: flex-start; gap: 43.5px;
    padding: 0 58px;
  }
}
@media (min-width: 1026px) and (max-width: 1439.98px) { .site-nav { left: 256px; } }

/* ---------- la pastille de menu de la pilule — 11 septembre 2026 -----------

   Relevée en direct sur le site publié, à 1440 et à 1026 : deux barres de 24 et
   15 px hautes de 1 px, écartées de 5 — 24 × 7 au total — posées à **339,6 px
   du bord gauche de la pilule**. Le décalage est constant : x=859,6 à 1440,
   x=649,1 à 1026, et la pilule fait 422 px partout.

   **Hors du flux, volontairement.** En quatrième élément flex, elle pousserait
   les trois liens vers la gauche — et ils sont calés au pixel depuis le 24 août.
   Nos libellés sont d'ailleurs plus larges que les siens (Jost contre Futura
   PT : « FAQ » finit à 844 chez nous, 816,6 chez lui), donc aucune disposition
   en flux ne peut satisfaire les deux. Posée en absolu, les liens ne bougent pas
   et la pastille tombe exactement où l'original la met. Il reste 16 px entre la
   fin de « FAQ » et elle — mesuré, pas estimé.

   Elle n'existe qu'au-dessus de 1026 px : en dessous, c'est la barre mobile qui
   sert, avec sa pastille ronde de 46 × 46 à gauche. */
.site-nav__menu { display: none; }

@media (min-width: 1026px) {
  .site-nav { /* le conteneur de la pilule sert de repère à la pastille */ }
  .site-nav__menu {
    display: block;
    position: absolute;
    left: 339.6px;
    top: 50%;
    transform: translateY(-50%);
    width: 24px;
    height: 7px;
    padding: 0;
    border: 0;
    background: none;
    cursor: pointer;
  }
  .site-nav__menu-barres { display: block; position: relative; width: 24px; height: 7px; }
  /* Les deux barres : 24 px en haut, 15 px en dessous et **alignée à droite** —
     chez l'original, le conteneur est en « align-items: flex-end ». */
  .site-nav__menu-barres::before,
  .site-nav__menu-barres::after {
    content: ''; position: absolute; height: 1px; background: currentColor;
  }
  .site-nav__menu-barres::before { left: 0; top: 0; width: 24px; }
  .site-nav__menu-barres::after  { left: 9px; top: 6px; width: 15px; }
}

/* La cible tactile fait 24 × 7 : c'est la taille de l'original, et c'est trop
   peu pour un pointeur. On l'élargit sans déplacer le dessin. */
@media (min-width: 1026px) {
  .site-nav__menu::before {
    content: ''; position: absolute; inset: -14px -10px;
  }
  .site-nav__menu:focus-visible { outline: 2px solid currentColor; outline-offset: 8px; }
}

.site-nav a {
  font-family: var(--titre);
  font-weight: var(--titre-graisse); text-transform: uppercase;
  font-size: var(--t-xs); letter-spacing: .06em; text-decoration: none;
}
.site-nav a:hover { color: var(--vert); }

.site-header__cart {
  display: inline-flex; align-items: center; gap: .5rem;
  font-family: var(--titre);
  font-weight: var(--titre-graisse); text-transform: uppercase;
  font-size: var(--t-xs); letter-spacing: .08em; text-decoration: none;
}

/* L'original passe à la barre mobile — pastille de menu, logo centré, panier
   rond — dès 1025 px, pas 810 : à 900 son en-tête est le calque « Mobile tan »,
   717 × 103, avec le burger à 20 px du bord et le logo au centre. La pilule de
   navigation n'existe plus dans cette plage. */
@media (max-width: 1025.98px) { .site-nav { display: none; } }

/* ---------- en-tête, plage téléphone --------------------------------------
   Trois positions relevées dans le rendu de l'original à 360 px de fenêtre,
   donc dans un bloc de 370 centré : pastille de menu à 20 px du bord gauche,
   logo centré, panier à 20 px du bord droit, tous à 42 px du haut. Le calage
   vertical n'est ni un centrage ni un alignement bas — les trois sont posés,
   c'est donc en absolu qu'ils tiennent au pixel. */

/* Bouton panier : le cercle et le sac sont un seul tracé de 46 × 46, celui de
   l'original. Le compteur se pose au centre du cercle, comme chez lui — il n'y
   apparaît qu'à partir d'un article. */
.site-header__cart { position: relative; }
.site-header__cart-icone {
  display: block; width: 46px; height: 46px; flex: none;
  color: #826335;
}
.site-header__cart-icone svg { width: 100%; height: 100%; display: block; }
.site-header__cart-label {
  font-family: var(--titre); font-weight: var(--titre-graisse);
  text-transform: uppercase; font-size: 14px; line-height: 14px;
  letter-spacing: .02em;
}
/* Sur ordinateur, « Group 365 » fait 92 × 46 : le mot « cart », 7 px d'écart,
   puis le cercle. */
.site-header__cart { gap: 7px; }

/* La pastille de menu n'existe qu'au téléphone. Au-dessus de 810 px l'original
   la loge dans la barre de navigation ; ce point n'est pas encore traité. */
.site-header__burger { display: none; }

/* La composition mobile vaut pour toute la plage sous 1026 px. Les trois
   positions sont les mêmes en tablette qu'au téléphone — relevées à 900 chez
   l'original : burger x112 (bloc + 20), logo centré sur la fenêtre, panier à
   20 px du bord droit du bloc, tous à 42-43 px du haut. Seule la largeur du
   bloc change : 717 en tablette, 370 au téléphone. */
@media (max-width: 1025.98px) {
  .site-header__inner {
    display: block; padding-inline: 0;
    margin-inline: auto;
  }

  .site-header__burger {
    display: block;
    position: absolute; left: 20px; top: 42px;
    width: 46px; height: 46px;
    padding: 0; margin: 0;
    background: none; border: 1px solid currentColor; border-radius: 9999px;
    color: #826335;
    cursor: pointer;
  }
  /* Deux barres de 1 px : 24 px de large, puis 15 px décalée de 9 px à droite
     et 6 px plus bas. Boîte de 24 × 7 centrée horizontalement, à 20 px du haut
     de la pastille. */
  .site-header__burger-barres {
    position: absolute; left: 10px; top: 19px;
    width: 24px; height: 7px;
    display: block;
  }
  .site-header__burger-barres::before,
  .site-header__burger-barres::after {
    content: ""; position: absolute; height: 1px; background: currentColor;
  }
  .site-header__burger-barres::before { left: 0; top: 0; width: 24px; }
  .site-header__burger-barres::after  { left: 9px; top: 6px; width: 15px; }

  .site-header__brand {
    position: absolute; left: 50%; top: 43px;
    width: 192px; height: 44px;
    transform: translateX(-50%);
  }

  .site-header__cart {
    position: absolute; right: 20px; top: 42px;
    width: 46px; height: 46px;
    gap: 0;
  }
  .site-header__cart-label { display: none; }
}

/* 370 px dans une fenêtre de 360 : `margin: auto` ne peut pas centrer un bloc
   plus large que son parent, il le colle à gauche. Le décalage de moitié le fait
   déborder également des deux côtés, comme chez l'original. Après le bloc
   ci-dessus, qui pose `margin-inline: auto` pour la tablette. */
@media (max-width: 809.98px) {
  .site-header__inner { margin-left: calc(50% - 185px); margin-right: 0; }
}


/* ---------- panneaux superposés : menu et panier ---------------------------
   Les deux sont des composants de l'original, relevés dans son rendu à 360,
   500 et 809 px de large et à trois hauteurs de fenêtre.

   Menu   : cadre blanc, 24 px de marge sur les trois bords, hauteur fixe de
            520 px, contenu calé en bas, liens dans une colonne de 160 px.
   Panier : cadre gris, 8 px de marge, hauteur de 80 % de la fenêtre moins
            13 px — trois relevés strictement alignés sur cette droite.

   Ils ne s'ouvrent qu'avec le script. Sans lui, la pastille de menu ne s'affiche
   pas et le panier reste un lien vers /panier : la page complète prend le relais.
   -------------------------------------------------------------------------- */

.modale { position: fixed; inset: 0; z-index: 60; }
.modale[hidden] { display: none; }
.no-js .site-header__burger { display: none; }

/* Le fond ne peint rien : l'original ne pose aucun voile derrière ses panneaux,
   la page reste visible telle quelle. Il ne sert qu'à fermer au clic. */
.modale__fond {
  position: absolute; inset: 0;
  padding: 0; margin: 0; border: 0; background: none; cursor: default;
}

.modale__cadre { position: relative; z-index: 2; }

.modale__croix {
  position: absolute; right: 24px; top: 24px;
  width: 17px; height: 17px;
  padding: 0; border: 0; background: none; cursor: pointer;
  color: var(--vert);
}
.modale__croix svg { width: 100%; height: 100%; display: block; }

/* ----- menu ----- */
.modale__cadre--menu {
  margin: 24px;
  height: 520px;
  padding: 24px;
  background: var(--blanc);
  border-radius: 32px;
  display: flex; flex-flow: column;
  align-items: center; justify-content: flex-end;
  gap: 53px;
}
.modale__liens {
  width: 160px; margin: 0; padding: 0; list-style: none;
  display: flex; flex-flow: column; align-items: center;
  gap: 67px;
}
.modale__liens a {
  display: block; width: 160px; height: 29px;
  font-family: var(--titre); font-weight: var(--titre-graisse);
  font-size: 24px; line-height: 28.8px;
  text-transform: uppercase; text-align: center; text-decoration: none;
  color: var(--vert);
}
/* Le sélecteur du téléphone : hors du flux, en haut à gauche du cadre, face à
   la croix de fermeture. Le cadre n'a que 34 px de mou — dans le flux, il
   remonterait les quatre liens, qui sont calés au pixel. */
.modale__langues {
  position: absolute; left: 24px; top: 24px;
  display: flex; gap: 12px; align-items: center;
  font-family: var(--texte); font-weight: var(--texte-graisse);
  font-size: 12px; letter-spacing: .06em;
  color: var(--vert);
}
.modale__langues a {
  color: inherit; text-decoration: none; opacity: .5; padding: 1px 0;
}
.modale__langues a[aria-current="true"] {
  opacity: 1; border-bottom: 1px solid currentColor;
}

.modale__cta {
  width: 100%; height: 68px;
  display: grid; place-items: center;
  background: var(--rose); border-radius: 9999px;
  font-family: var(--titre); font-weight: var(--titre-graisse);
  font-size: 17px; line-height: 25px;
  text-transform: uppercase; text-decoration: none;
  color: var(--vert-encre);
}

/* « Mon compte » dans le panneau de menu — 11 septembre 2026.

   Hors du flux, au milieu de l'écart de 53 px qui sépare les quatre liens du
   bouton d'achat. Le calcul, depuis le bas du cadre : 24 px de retrait, 68 px
   de bouton, la moitié de l'écart (26,5) moins la moitié de sa propre hauteur
   (12) — soit 106,5 px. Rien d'autre ne bouge, et c'est vérifiable : le cadre
   reste à 520 px et les liens à leur pas de 67. */
.modale__compte {
  position: absolute;
  left: 24px; right: 24px; bottom: 106.5px;
  height: 24px; line-height: 24px;
  font-family: var(--texte); font-weight: 600;
  font-size: 14px; letter-spacing: .04em;
  text-transform: uppercase; text-align: center; text-decoration: underline;
  text-underline-offset: 4px;
  color: var(--vert);
}
.modale__compte:hover { color: var(--brun); }

/* ----- panier ----- */
.modale__cadre--panier {
  margin: 8px;
  height: calc(80vh - 13px);
  background: #F2F2F3;
  border-radius: 32px;
  overflow: hidden;
  display: flex; flex-flow: column;
}

.panier__entete {
  position: relative; flex: none;
  height: 65px; padding: 24px 16px;
  display: grid; place-items: center;
  border-bottom: 1px solid var(--rose);
}
.panier__titre {
  margin: 0;
  font-family: var(--titre); font-weight: var(--titre-graisse);
  font-size: 27px; line-height: 32.4px;
  text-transform: uppercase; color: #252930;
}
.modale__croix--panier { right: 16px; top: 50%; transform: translateY(-50%); }

/* Ordinateur : le panneau du panier n'occupe plus toute la largeur mais un
   cadre de 400 × 520 ancré en haut à droite — x=1008 sur 1 440, soit 32 px du
   bord. Relevé le 25 août 2026 sur la variante « Desktop » de l'original. */
@media (min-width: 810px) {
  .modale__cadre--panier {
    width: 400px; height: 520px;
    margin: 8px 32px 0 auto;
  }
}

.panier__vide { flex: 1; display: grid; place-items: center; padding: 16px; }
.panier__vide-titre {
  margin: 0; text-align: center;
  font-family: var(--titre); font-weight: var(--titre-graisse);
  font-size: 27px; line-height: 32.4px;
  text-transform: uppercase; color: var(--vert);
}

.panier__lignes {
  flex: 1; min-height: 0; overflow-y: auto;
  margin: 0; padding: 16px; list-style: none;
  display: flex; flex-flow: column; gap: 0;
}
.panier__ligne { display: flex; gap: 16px; height: 72px; }
/* Le filet rose n'est pas une bordure de la ligne : l'original le pose sur la
   vignette seule, en haut et en bas. */
.panier__vignette {
  flex: none; width: 65px; height: 65px;
  background: #EDEFF0; overflow: hidden;
  border-block: 1px solid var(--rose);
}
.panier__vignette img { width: 100%; height: 100%; object-fit: cover; }

.panier__corps { flex: 1; min-width: 0; display: flex; flex-flow: column; gap: 8px; }
.panier__haut { display: flex; justify-content: space-between; align-items: flex-start; gap: 16px; }
.panier__identite { display: flex; flex-flow: column; gap: 8px; min-width: 0; }
.panier__nom {
  margin: 0;
  font-family: var(--titre); font-weight: var(--titre-graisse);
  font-size: 16px; line-height: 16px;
  text-transform: uppercase; color: var(--vert);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.panier__quantite {
  margin: 0;
  font-family: var(--texte); font-weight: var(--texte-graisse);
  font-size: 12px; line-height: 12px; letter-spacing: -.24px;
  color: var(--vert);
}
.panier__prix {
  margin: 0; flex: none;
  font-family: var(--titre); font-weight: var(--titre-graisse);
  font-size: 16px; line-height: 16px; color: #000;
}

.panier__bas { display: flex; justify-content: space-between; align-items: center; height: 26px; }
.panier__compteur {
  display: flex; align-items: center; gap: 8px;
  height: 26px; padding: 4px; border-radius: 14px;
}
.panier__compteur form { display: contents; }
.panier__pas {
  width: 18px; height: 18px; padding: 2px;
  display: grid; place-items: center;
  border: 0; background: none; cursor: pointer; color: var(--vert);
}
.panier__pas svg { width: 14px; height: 14px; display: block; }
.panier__nombre {
  font-family: var(--titre); font-weight: var(--titre-graisse);
  font-size: 18px; line-height: 18px; color: var(--vert);
}
.panier__retirer {
  width: 24px; height: 24px; padding: 4px;
  display: grid; place-items: center;
  border: 1px solid var(--vert); border-radius: 9999px;
  background: none; cursor: pointer; color: var(--vert);
}
.panier__retirer svg { width: 10px; height: 10px; display: block; }

.panier__pied {
  flex: none;
  padding: 16px 16px 24px;
  display: flex; flex-flow: column; gap: 24px;
  border-radius: 0 0 32px 32px;
}
.panier__soustotal {
  margin: 0; height: 29px;
  display: flex; justify-content: space-between; align-items: center;
  font-family: var(--titre); font-weight: var(--titre-graisse);
  font-size: 24px; line-height: 28.8px; color: var(--vert);
}
.panier__soustotal-valeur { line-height: 24px; }
/* Une promotion appliquée : le sous-total barré, puis une ligne par offre —
   nuit du 12 au 13 septembre 2026. */
.panier__barre {
  margin-right: 6px;
  font-family: var(--texte); font-weight: var(--texte-graisse);
  font-size: 16px; color: rgb(4 50 37 / .55);
}
.panier__remise {
  margin: -18px 0 0;
  display: flex; justify-content: space-between; gap: 12px;
  font-family: var(--texte); font-weight: var(--texte-graisse);
  font-size: 14px; line-height: 18px; color: var(--brun);
}
.panier__commander {
  height: 68px;
  display: grid; place-items: center;
  background: var(--rose); border-radius: 9999px;
  font-family: var(--titre); font-weight: var(--titre-graisse);
  font-size: 16px; line-height: 16px; letter-spacing: -.16px;
  text-transform: uppercase; text-decoration: none; color: var(--vert);
}

/* Le fond ne défile plus tant qu'un panneau est ouvert. */
html.modale-ouverte, html.modale-ouverte body { overflow: hidden; }

/* ---------- héro ----------------------------------------------------------
   Valeurs transcrites du CSS compilé de Framer, calque par calque. La trame de
   conception fait 1440 px et les hauteurs y sont fixes, pas relatives à la
   fenêtre : c'est ce que j'avais mal deviné jusqu'ici.
   -------------------------------------------------------------------------- */

.hero {                                   /* calque « hero section » */
  position: relative;
  width: 100%;
  height: 750px;
  padding: 96px 40px 0;
  display: flex;
  flex-flow: column;
  place-content: center flex-start;
  align-items: center;
  gap: 10px;
  overflow: visible;
  background: transparent;
}
@media (min-width: 1026px) and (max-width: 1439.98px) { .hero { padding: 96px 20px 0; } }
/* Plage tablette, relevée chez l'original à 810, 900 et 1025 : le calque
   « hero section - Tablet » fait 952 px de haut à ces trois largeurs, son bloc
   intérieur commence 96 px sous le haut et le retrait latéral vaut 32 px —
   « inner content » fait la largeur de la fenêtre moins 64. */
@media (min-width: 810px) and (max-width: 1025.98px) {
  .hero { height: 952px; padding: 96px 32px 0; }
}
/* Plage téléphone : retraits 140 / 20 / 0, hauteur libre. Elle n'est pas fixe
   chez l'original — 743 px à 360, 719 à 500, 783 à 809 — elle vaut toujours
   140 px plus la hauteur de « inner content ». */
/* Marge haute réduite 140 → 44 px sur téléphone — 16 septembre 2026 : à la
   demande du marchand, pour resserrer le vide sous l'en-tête (écart assumé au
   calque Framer, qui posait 140). */
@media (max-width: 809.98px) { .hero { height: auto; padding: 44px 20px 0; } }

/* La photo déborde le bloc de 750 px : le calque « black overlay » qui la
   recouvre fait 950 px, ce qui donne la hauteur réelle du fond. C'est ce
   débordement qui laisse voir la vague de l'arche, sinon masquée. */
/* Le fond déborde à droite : 122 % de la largeur de fenêtre sur ordinateur,
   relevé à trois largeurs — 2342 pour 1920, 1757 pour 1440, 1562 pour 1280.
   En tablette et en mobile il tient dans la fenêtre. La hauteur, elle, vaut
   950 px partout : le fond descend 200 px sous le héro. */
.hero__photo {
  position: absolute; top: 0; left: 0;
  /* La remise à zéro globale plafonne images et vidéos à 100 % : il faut la
     lever ici, sinon le débordement de 22 % est rogné sans bruit. */
  width: 122vw; max-width: none; height: 950px;
  object-fit: cover; object-position: center 38%;
  z-index: 0;
}
@media (max-width: 1025.98px) { .hero__photo { width: 100%; } }

/* calque « black overlay » : présent mais transparent au repos, il s'assombrit
   au défilement. Sa hauteur dépasse le héro (950 px contre 750). */
/* Calque « black overlay » : un noir à 25 % posé en permanence sur le fond,
   sans mode de fusion. Le mien était à « opacity: 0 » et piloté par un script
   qui n'existe pas — donc invisible, et le héro trop clair de 25 %. */
.hero__overlay {
  position: absolute; top: 0; left: 0; right: 0;
  height: 950px;
  z-index: 2;
  background: rgba(0, 0, 0, .25);
  pointer-events: none;
}

/* Calque « line fix (visual) » : bande crème de 3 px posée sur la couture entre
   le bas du héro et le haut de la scène collante, `bottom: -1px` — donc deux
   pixels au-dessus du bord, un en dessous. L'original ne la met que sous
   1026 px ; au-dessus il n'y a pas de couture, l'arche y descend bien plus bas.
   Le `z-index: 7` la fait passer devant la scène collante, qui est à 3. */
.hero__couture { display: none; }
@media (max-width: 1025.98px) {
  .hero__couture {
    display: block;
    position: absolute; left: 0; right: 0; bottom: -1px;
    height: 3px; z-index: 7;
    background: var(--creme);
    pointer-events: none;
  }
}

/* Calque « pattern » : conteneur de l'arche. Position absolue, sans dimension
   propre en dessous de 1920 px — c'est l'arche qui donne la taille. */
/* Colonne du milieu du héro : 368 × 501. Ce n'est pas un décor flottant, c'est
   le deuxième des trois enfants de « inner content ». C'est lui qui écarte le
   texte de la fiche produit — sans lui la fiche remonte de 90 px vers la
   gauche et rien ne tombe juste. */
.hero__pattern {
  flex: 0 0 auto;
  width: 368px; height: 501px;
  position: relative;
  z-index: 1;
  pointer-events: none;
}
.hero__pattern picture { display: contents; }
/* 368 × 501, centrée sous le texte — mêmes valeurs à 810, 900 et 1025. Les
   313 × 434 que j'avais posés ici sont ceux du dôme, pas de la colonne. */
@media (min-width: 810px) and (max-width: 1025.98px) {
  .hero__pattern { width: 368px; height: 501px; align-self: center; }
}
/* Au téléphone la colonne n'est plus une colonne : c'est un bloc de pleine
   largeur posé sous le texte, dont la hauteur vient de l'arche. */
@media (max-width: 809.98px)  { .hero__pattern { width: 100%; height: auto; } }

/* Boîte de l'arche. Elle ne compte pas au-dessus de 810 px : les deux médias y
   sont posés en absolu sur la colonne, comme chez l'original. */
.hero__arche-boite { display: contents; }
@media (max-width: 809.98px) {
  /* L'arche vaut 110 % de la colonne, sans jamais descendre sous 570 px :
     relevé à 360, 500, 700 et 809 — 570, 570, 726 et 846. Le seuil tombe donc
     vers 558 px de fenêtre. Elle est posée 23 px sous le haut de la colonne et
     c'est elle qui lui donne sa hauteur. */
  .hero__arche-boite {
    display: block; position: relative;
    width: max(570px, 110%);
    aspect-ratio: 570 / 232;
    margin-top: 23px;
    left: 50%; transform: translateX(-50%);
  }
}

/* L'arche déborde très largement de sa colonne, centrée sur la fenêtre. Les
   tailles sont fixes par plage, relevées dans le rendu de l'original à cinq
   largeurs : ce n'est ni une proportion de la fenêtre — 218 % à 1920 contre
   149 % à 1440 — ni le même dessin redimensionné. Trois fichiers distincts. */
.hero__arch {
  position: absolute; top: 0; left: 50%;
  transform: translateX(-50%);
  width: 2146px; height: 983px;
  max-width: none; display: block;
}
@media (min-width: 1920px)    { .hero__arch { width: 4194px; height: 983px; } }
/* 1110 × 561 centrée sur la fenêtre, posée 60 px au-dessus du haut de la
   colonne : arche à y551 pour une colonne à y611 à 1025, y575 pour y635 à 900
   et à 810. */
@media (max-width: 1025.98px) { .hero__arch { width: 1110px; height: 561px; } }
@media (min-width: 810px) and (max-width: 1025.98px) { .hero__arch { top: -60px; } }


/* Le dôme est une vidéo en boucle — 368 × 528, rayon 190 px, 10 px sous le haut
   de la colonne. J'y affichais quatre images permutées en JavaScript : ni la
   bonne nature, ni la bonne taille.
   Le fond de la vidéo est blanc et opaque. C'est le conteneur qui le fait
   disparaître, par « darken » : le blanc cède devant le crème de l'arche, le
   champignon reste. */
.hero__dome-fusion {
  position: absolute; top: 10px; left: 50%;
  transform: translateX(-50%);
  width: 368px; height: 528px;
  mix-blend-mode: darken;
}
.hero__dome {
  width: 100%; height: 100%;
  border-radius: 190px;
  object-fit: cover;
  display: block;
}
/* Dôme : 313 × 434, rayon 180, posé 7 px sous le haut de la colonne. */
@media (max-width: 1025.98px) {
  .hero__dome-fusion { width: 313px; height: 434px; }
  .hero__dome { border-radius: 180px; }
}
@media (min-width: 810px) and (max-width: 1025.98px) { .hero__dome-fusion { top: 7px; } }
@media (max-width: 809.98px) {
  /* L'arche remplit sa boîte ; le dôme fait 30 % de sa largeur — 171 sur 570,
     254 sur 846 — centré sur elle, à 2,3 % de sa hauteur du haut. Ces deux
     règles doivent venir après celles de la plage tablette, qui posent des
     tailles fermes et les recouvriraient sinon. */
  .hero__arch { position: static; transform: none; width: 100%; height: 100%; }
  .hero__dome-fusion {
    top: 2.3%; left: 50%; transform: translateX(-50%);
    width: 30%; height: auto;
    aspect-ratio: 171 / 221;
  }
  .hero__dome { border-radius: 180px; }
}

.hero__inner {                            /* calque « inner content » */
  position: relative;
  z-index: 3;
  width: 100%;
  max-width: 1440px;
  height: min-content;
  display: flex;
  flex-flow: row;
  place-content: flex-start space-between;
  align-items: flex-start;
  gap: 2rem;
}
/* La variante tablette de l'original n'a que **deux** enfants — la colonne de
   texte, en pleine largeur, et la colonne du champignon sous elle. La fiche
   produit disparaît. C'est vrai dès 1025 px, pas seulement au téléphone :
   c'était la cause du héro écrasé que l'utilisateur a signalé, la colonne de
   texte tombant à 93 px de large à 900. */
@media (max-width: 1025.98px) { .hero__inner { flex-flow: column; gap: 0; align-items: stretch; } }
/* « inner content » a une hauteur ferme de 856 px : la colonne du champignon la
   dépasse de 71 px et déborde sur la section suivante, comme chez l'original. */
@media (min-width: 810px) and (max-width: 1025.98px) { .hero__inner { height: 856px; } }

.hero__text {                             /* calque « Text left » */
  flex: 1 0 0;
  width: 1px;
  max-width: 390px;
  height: auto;
  /* Framer pose « align-self: stretch » ici, ce qui annule le
     « align-items: flex-start » du parent. Sans lui la colonne prend la
     hauteur de son contenu, le « flex-end » vertical n'a plus d'espace à
     repousser, et le titre remonte de 103 px. */
  align-self: stretch;
  display: flex;
  flex-flow: column;
  place-content: flex-start flex-end;
  align-items: flex-start;
  gap: 32px;
  color: var(--creme);
}
@media (max-width: 1025.98px) { .hero__text { width: auto; max-width: none; } }
@media (max-width: 809.98px)  { .hero__text { gap: 12px; } }

/* Calque « content » : paragraphe, filet et avantages. Écart de 30 px sur
   ordinateur et en tablette, 16 px au téléphone. */
.hero__content { display: flex; flex-flow: column; gap: 30px; align-items: flex-start; align-self: stretch; }
@media (max-width: 809.98px) { .hero__content { gap: 16px; } }

/* Calque « Section Title » : Millave 64,7 px, crème. L'interligne vaut
   77,64 px — lue dans le rendu de l'original, pas estimée : le 0,95 qui
   figurait ici raccourcissait le bloc de 32 px et remontait tout le texte. */
.hero__kicker {
  /* Le titre occupe toute la largeur de sa colonne. Sans cette ligne il se
     réduit au texte — 205 px au lieu de 320 — parce que « Text left » aligne
     ses enfants au début. */
  align-self: stretch;
  font-family: var(--titre);
  font-weight: var(--titre-graisse);
  font-size: 64.7px;
  line-height: 77.64px;
  color: var(--creme);
  margin: 0;
}
@media (min-width: 810px) and (max-width: 1025.98px) { .hero__kicker { font-size: 64.7px; line-height: 77.64px; } }
@media (max-width: 809.98px)  { .hero__kicker { font-size: 32px; line-height: 38.4px; } }
/* Calque « Description » : Millave — une serif, pas la sans que j'avais mise. */
.hero__lead {
  font-family: var(--titre);
  font-weight: var(--titre-graisse);
  font-size: 20px;
  line-height: 24px;
  text-transform: none;
  color: var(--creme);
  margin: 0;
}
@media (max-width: 809.98px) { .hero__lead { font-size: 16px; line-height: 24px; } }

.hero__rule {                             /* calque « Line 3 » : 382 × 3 */
  flex: none;
  width: 100%; max-width: 382px; height: 3px;
  border: 0; background: rgba(255, 223, 165, .45); margin: 0;
}
/* Le bloc ne fait plus que 320 px au téléphone : le filet en garde 382 et
   déborde à droite, comme sur l'original. */
@media (max-width: 809.98px) { .hero__rule { width: 382px; max-width: none; } }

/* Calque « Feature » : Futura PT 20 px, interligne 16 px, gris très clair. */
.hero__benefits {
  display: flex; flex-flow: column; gap: 16px; margin: 0; padding: 0;
  list-style: none;
  align-self: stretch;
  font-family: var(--texte);
  font-weight: var(--texte-graisse);
  font-size: 20px;
  line-height: 16px;
  color: #F2F2F3;
}
/* Chaque rangée est un calque « Container » : icône de 16, écart de 12, texte.
   L'icône était posée en absolu avec un retrait de 28 px, ce qui donnait le même
   rendu sur ordinateur mais ne pouvait pas suivre une rangée haute de 24 px.

   « min-height » et non « height » : les traductions sont plus longues que le
   français, et une rangée figée à 16 px laisse la seconde ligne déborder sur
   la rangée suivante. En français la rangée mesure 16 px de toute façon —
   le rendu de l'original est inchangé. */
.hero__benefits li { display: flex; flex-flow: row; align-items: center; gap: 12px; min-height: 16px; }
.hero__benefit-texte { flex: 1; }
/* En tablette la rangée garde ses 16 px de haut et son écart de 16, seul le
   corps descend de 20 à 16 — relevé à 900 : trois rangées de 16 à y555, 587
   et 619. */
@media (min-width: 810px) and (max-width: 1025.98px) { .hero__benefits { font-size: 16px; } }
@media (max-width: 809.98px) {
  .hero__benefits { gap: 4px; font-size: 16px; line-height: 24px; }
  .hero__benefits li { min-height: 24px; }
}
/* Calque « icons » : boîte de 16 × 16, texte à 28 px du bord. Les tracés sont
   ceux de l'original — un éclair, une cible, une feuille — au trait crème.
   J'avais mis un rond vide à la place des trois. */
.hero__benefit-icon {
  flex: none;
  width: 16px; height: 16px;
  display: grid; place-items: center;
  color: var(--creme);
}
.hero__benefit-icon svg { width: 100%; height: 100%; display: block; overflow: visible; }

/* Colonne de droite du héro. Les trois éléments sont poussés vers le bas ; le
   cadre, lui, est hors flux et couvre toute la colonne. Retraits relevés dans
   le rendu de l'original : 37 px à gauche, 30,19 px à droite, 9,66 px en bas. */
.hero__card {
  flex: none;
  width: 390px; max-width: 100%;
  height: 601px;
  position: relative;
  display: flex; flex-flow: column;
  align-items: center; justify-content: flex-end;
  gap: 14.3px;
  padding: 0 30.19px 9.66px 37px;
}
.hero__card-frame {
  position: absolute; top: 0; left: 37px;
  width: 353px; height: 601px;
  pointer-events: none;
}
.hero__card-media { width: 234px; height: 370px; display: grid; place-items: center; }
.hero__card-media img { max-width: 100%; max-height: 100%; width: auto; height: auto; }
/* Calque « Product Name » : Millave 20 px, centré. */
.hero__card-title {
  font-family: var(--titre);
  font-weight: var(--titre-graisse); text-transform: uppercase; color: var(--creme);
  font-size: 20px; text-align: center; line-height: 24px; margin: 0;
}
.hero__card .pill { width: 303px; height: 68px; display: grid; place-items: center; padding: 0; }
/* « hero section - Tablet » n'a que deux enfants, la colonne de texte et celle
   du champignon : la fiche produit n'existe pas sous 1026 px. */
@media (max-width: 1025.98px) { .hero__card { display: none; } }

/* Plage 1026-1439 : une variante à part entière chez Framer, pas une réduction
   de l'ordinateur. La colonne de texte et la fiche se partagent également ce qui
   reste après la colonne du champignon — 390 chacune tant que la place suffit,
   310 à 1026 — et l'écart entre les trois tombe à zéro.

   Sans cela la colonne de texte, seule extensible, encaissait tout le rétrécissement
   et tombait à 338 px à 1200, 164 à 1026 : le titre passait sous l'arche. C'est le
   défaut signalé par l'utilisateur. */
@media (min-width: 1026px) and (max-width: 1439.98px) {
  .hero__inner { gap: 0; }
  /* Largeur calculée plutôt que laissée au flex : les deux colonnes doivent
     valoir exactement la moitié de ce qui reste après les 368 px du champignon,
     plafonnée à 390. Le flex, lui, donnait 374 à la fiche et 318 au texte —
     la fiche a un contenu plus large et le partage penchait de son côté. */
  .hero__text,
  .hero__card { flex: none; width: min(390px, (100% - 368px) / 2); min-width: 0; }
  .hero__card { max-width: none; height: 497px; }

  /* Titre 49/58,8, paragraphe 16/19,2, avantages 18/16 : valeurs fermes de la
     variante, identiques de 1026 à 1439. */
  .hero__kicker   { font-size: 49px; line-height: 58.8px; }
  .hero__lead     { font-size: 16px; line-height: 19.2px; }
  .hero__benefits { font-size: 18px; }

  /* Le paragraphe et la liste sont en retrait de 16 px à droite dans cette
     variante — 374 pour une colonne de 390, 294 pour 310 — alors que le titre,
     lui, occupe toute la colonne. C'est ce retrait qui fixe le renvoi à la
     ligne du paragraphe. */
  .hero__lead,
  .hero__benefits { width: calc(100% - 16px); }

  /* La fiche est le dessin de l'ordinateur réduit de 17,3 % — 292/353 — mais
     ses textes, eux, gardent leur corps. Le cadre est calé sur le bord droit. */
  .hero__card-frame { left: auto; right: 0; width: 292px; height: 497px; }
  .hero__card-media { width: 194px; height: 306px; }
  .hero__card .pill { width: 251px; height: 56px; }
  /* Le contenu de la fiche se cale sur son cadre, pas sur sa colonne : le cadre
     fait 292 px et colle au bord droit, la colonne en fait 309 à 1026 et 390 à
     partir de 1188. Le retrait gauche vaut donc la différence — même expression
     que la largeur, et les pourcentages s'y résolvent sur le même bloc. */
  .hero__card {
    padding: 0 25px 8px calc(min(390px, (100% - 368px) / 2) - 292px);
    gap: 11.8px;
  }
}

/* ---------- scène collante -------------------------------------------------
   Calque « le cafe en - scroll » : 125vh. « viewport sticky » y reste accroché
   en haut pendant toute la course, ce qui laisse le temps à l'animation de se
   dérouler. Les deux repères invisibles la découpent en deux temps.
   -------------------------------------------------------------------------- */

.scroll-scene {
  position: relative;
  z-index: 3;
  width: 100%;
  height: 125vh;
  display: flex;
  flex-flow: column;
  place-content: center flex-start;
  align-items: center;
  gap: 10px;
  /* Pas de fond : c'est le bas de l'arche, en crème plein, qui fait office de
     fond ici. Un fond opaque recouvrirait la vague. */
  background: transparent;
}
@media (max-width: 1025.98px) { .scroll-scene { height: auto; padding-block: 3rem; background: var(--creme); } }
/* Plage téléphone : la section n'a ni retrait ni fond — c'est « cup animation »,
   désormais pleine largeur, qui porte le crème, et le corps de page qui le
   prolonge sous le texte. Sa hauteur est celle de son contenu : 697 px à 360,
   898 à 500, 1126 à 700, 1283 à 809 — jamais 125vh. */
@media (max-width: 809.98px) { .scroll-scene { padding-block: 0; background: transparent; } }

.viewport-sticky {
  position: sticky;
  top: 0;
  z-index: 1;
  width: 100%;
  height: min-content;
  display: flex;
  flex-flow: column;
  place-content: center;
  align-items: center;
  gap: 40px;
  padding: 0;
  overflow: clip;
}
@media (max-width: 1025.98px) { .viewport-sticky { position: static; gap: 24px; } }
@media (max-width: 809.98px) { .viewport-sticky { gap: 40px; } }

.cup-animation {                          /* calque « cup animation » : 360 × 517 */
  position: relative;
  z-index: 0;
  flex: none;
  width: 360px;
  height: 517px;
  /* Le fond crème n'est pas décoratif : « z-index: 0 » isole la fusion, donc
     le « multiply » de la danseuse se calcule contre ce fond-là et non contre
     la page. Sans lui, son fond blanc reste un carré blanc. Framer le déclare
     exactement ainsi. */
  background-color: var(--creme);
}
@media (max-width: 1025.98px) {
  .cup-animation { width: 100%; max-width: 360px; height: auto; aspect-ratio: .696325; }
}
/* En dessous de 810 px le bloc prend toute la largeur et sa hauteur vaut
   143,6 % de celle-ci : relevé à 360, 500, 700 et 809 — 517, 718, 1005, 1162. */
@media (max-width: 809.98px) {
  .cup-animation { max-width: none; aspect-ratio: 360 / 517; }
}
/* Calque « Cup » : 481 × 546, centre à 63 % de la hauteur du conteneur. */
.cup-animation__cup {
  position: absolute; left: 50%; top: 63%;
  width: 481px; height: 546px; max-width: none;
  transform: translate(-50%, -50%);
}
/* Calque de la danseuse : vidéo de 350 × 350 posée en haut du conteneur, son
   fond blanc effacé par « multiply » — le même procédé que le dôme du héro. */
.cup-animation__danseuse {
  position: absolute; top: 0; left: 50%;
  transform: translateX(-50%);
  width: 350px; height: 350px;
  mix-blend-mode: multiply;
}
.cup-animation__danseuse video { width: 100%; height: 100%; display: block; }
@media (max-width: 1025.98px) {
  .cup-animation__cup { width: 134%; height: auto; }
  .cup-animation__danseuse { width: 56%; height: auto; aspect-ratio: 1; }
}

/* Plage téléphone. Les quatre relevés — 360, 500, 700 et 809 — donnent des
   règles franches pour les largeurs et les côtés, et deux droites pour les
   hauteurs de pose. Elles tombent à un pixel près sur les quatre points.

     tasse    : 11 px à gauche, largeur du bloc moins 22, rapport 995/1129
     danseuse : 71 px à gauche, 50 à droite, 117 px du haut, rapport 449/407
     bouton   : 12 px à gauche, largeur moins 24, hauteur 68

   Les deux `top` sont exprimés en pourcentage de la hauteur du bloc plus une
   constante : c'est la forme qui rend la droite relevée. */
@media (max-width: 809.98px) {
  .cup-animation__cup {
    left: 11px; top: calc(23.418% + 12.93px);
    width: calc(100% - 22px); height: auto;
    transform: none;
  }
  .cup-animation__danseuse {
    left: 71px; right: 50px; top: 117px;
    width: auto; height: auto;
    aspect-ratio: 449 / 407;
    transform: none;
  }
}

/* Calque « pink » : le bouton d'achat posé dans « cup animation », au-dessus de
   la tasse. L'original ne le met qu'en dessous de 1026 px ; sur ordinateur il
   n'y a rien à cet endroit. */
.cup-animation__cta {
  display: none;
  position: absolute; z-index: 1;
  left: 12px; top: calc(10.856% - 35.1px);
  width: calc(100% - 24px); height: 68px;
  padding: 16px; gap: 10px;
  border-radius: 9999px;
  color: var(--vert);
  font-size: 17px; line-height: 17px; letter-spacing: normal;
}
/* L'original le pose dans les deux plages sous 1026 px, pas seulement au
   téléphone. La règle vient après la déclaration de base : à spécificité égale
   c'est la dernière qui l'emporte, et l'inverse la laissait invisible. */
@media (max-width: 1025.98px) { .cup-animation__cta { display: flex; } }

/* Titre et sous-titre de la scène collante. Valeurs relevées dans le rendu de
   l'original : 84,11/100,932 et 28,27/33,924, sans écart entre les deux blocs.
   J'avais une taille élastique qui plafonnait à 70,4 px et un interligne plus
   court que le corps — le bloc faisait 130 px au lieu de 202. */
.scene-text { display: grid; justify-items: center; gap: 0; text-align: center; }
.scene-title {
  width: 544px; max-width: 100%;
  font-size: 84.11px; line-height: 100.932px;
  margin: 0;
}
.scene-sub {
  font-family: var(--titre);
  font-weight: var(--titre-graisse); text-transform: uppercase;
  font-size: 28.27px; line-height: 33.924px; letter-spacing: normal; margin: 0;
}
/* Plage téléphone : 54 / 59,4 et 18 / 21,6, bloc de pleine largeur avec un
   retrait de 16 px. Le titre y tenait 544 px de large et débordait de 92 px
   de chaque côté. */
@media (max-width: 809.98px) {
  .scene-text { width: 100%; padding-inline: 16px; }
  .scene-title { width: 100%; font-size: 54px; line-height: 59.4px; }
  .scene-sub { font-size: 18px; line-height: 21.6px; }
}

/* Repères de progression : invisibles, ils servent de jalons au script. */
.scroll-wrapper {
  position: absolute; top: 0; left: 0;
  width: 19px; height: 125vh;
  display: flex; flex-flow: column; gap: 0;
  place-content: center; align-items: center;
  overflow: clip; pointer-events: none;
}
.scroll-mark { flex: 1 0 0; width: 10px; height: 1px; }

/* ---------- ingrédients ---------------------------------------------------
   Valeurs relevées sur le calque « ingredients » et ses enfants.
   -------------------------------------------------------------------------- */

.ingredients {
  position: relative;
  width: 100%;
  padding: 75px 40px 197px;
  display: flex;
  flex-flow: column;
  place-content: center;
  align-items: center;
  gap: 10px;
  background: var(--creme);
}
@media (min-width: 810px) and (max-width: 1025.98px) { .ingredients { padding: 75px 0 197px; } }
@media (max-width: 809.98px) { .ingredients { padding: 75px 0 30px; } }

/* Le bloc de contenu ne fait pas toute la largeur du gabarit : 1110 px,
   centrés, partagés en une colonne de 544 et une fiche de 477 séparées de 89.
   Je l'avais laissé à 1440, ce qui allongeait chaque ligne de texte de 290 px
   et écrasait la fiche. C'était la cause principale de la différence de
   taille des éléments. */
.ingredients__inner {
  display: grid;
  gap: clamp(2rem, 5vw, 4rem);
  width: 100%;
  max-width: 1110px;
  /* La gouttière de « .shell » vaut 56 px à cette largeur : elle décalait les
     deux colonnes vers la droite et faisait déborder la fiche de 56 px. Le
     retrait est déjà porté par la section elle-même. */
  padding-inline: 0;
}


/* Structure commune aux deux compositions. Chaque article porte son texte, sa
   fiche et son compteur ; c'est la mise en page qui les redistribue. */
.ingredients__carrousel { position: relative; width: 100%; }
/* Au-dessus de 1026 px la voie n'existe pas : la fiche est posée en absolu sur
   le bloc entier, et les flèches avec elle. */
.ingredients__voie { display: contents; }
.ingredients__piste { display: flex; flex-flow: column; gap: 24px; width: 100%; }
.ingredient { display: flex; flex-flow: column; }
.ingredient__compteur { display: none; }
.mushroom-card__logo { display: none; }

/* Flèches et compteur. Ils existent dans le balisage de l'original — deux
   boutons de 40 × 40 posés aux deux bords de la piste — mais il les laisse en
   `display: none`, si bien qu'on ne peut atteindre les deux autres fiches
   qu'en faisant glisser la piste au doigt. Ils sont rendus visibles ici. */
.ingredients__nav {
  display: flex; align-items: center; justify-content: flex-end;
  gap: 12px; margin-top: 16px;
}
.carousel-nav__btn {
  width: 34px; height: 34px;
  display: grid; place-items: center;
  border: 1px solid var(--vert); border-radius: 50%;
  background: none; color: var(--vert);
  font-size: 18px; line-height: 1; cursor: pointer;
  padding: 0;
}
.carousel-nav__btn:hover { background: var(--vert); color: var(--creme); }
.carousel-nav__btn:focus-visible { outline: 2px solid var(--vert); outline-offset: 2px; }
.carousel-nav__btn svg { width: 100%; height: 100%; display: block; }
.carousel-nav__count {
  font-family: var(--texte);
  font-weight: var(--texte-graisse); font-size: 14px; color: var(--vert-encre);
  min-width: 42px; text-align: center;
}

.ingredient__texte[role="tab"] { cursor: pointer; }
.ingredient__texte[aria-selected="false"] .ingredient__name,
.ingredient__texte[aria-selected="false"] .ingredient__text { opacity: .55; }

.ingredient { width: 100%; padding: 0; border: 0; margin: 0; }
.ingredient + .ingredient { border-top: 1px solid rgba(4, 50, 37, .25); padding-top: 24px; }

/* Calque « FOCUS & CLARTÉ MENTALE » : Millave 24 px, vert profond. */
.ingredient__label {
  font-family: var(--titre);
  font-weight: var(--titre-graisse);
  font-size: 24px;
  line-height: 28.8px;
  text-transform: uppercase;
  color: var(--vert);
  margin: 0 0 18px;
}

/* **Un mot trop long reste dans sa fenêtre** — 22 septembre 2026. En
   néerlandais, « UITHOUDINGSVERMOGEN » (19 lettres, corps 30 en capitales)
   dépassait de 124 px sa boîte de 277 et débordait sur la diapositive voisine.
   Le catalogue y pose des césures conditionnelles ; ceci est le filet pour
   tout autre mot, y compris un texte réécrit dans l'administration : le mot
   qui ne tient pas sur une ligne se coupe au lieu de déborder. Sans effet sur
   un texte qui tient — le français ne bouge pas. */
.ingredient__label, .ingredient__name, .ingredient__text,
.mushroom-card__title, .mushroom-card figcaption { overflow-wrap: break-word; }

.ingredient__body { display: grid; grid-template-columns: 80px minmax(0, 1fr); gap: 16px; align-items: start; }
.ingredient__icon { width: 80px; height: 81px; object-fit: contain; }

.ingredient__name { font-family: var(--texte); font-weight: 600; font-size: 16px; line-height: 20px; margin: 0 0 4px; color: var(--vert-encre); }
.ingredient__text { font-family: var(--texte);
  font-weight: var(--texte-graisse); font-size: 16px; line-height: 20px; margin: 0; color: var(--vert-encre); }

.cta-wrap { margin: 32px 0 0; display: flex; justify-content: flex-start; }
/* Les 300 px relevés couvrent le bouton ET sa pastille : 246 + 68 − 14 de
   chevauchement. Deux formes arrondies bord à bord ne se touchent qu'en un
   point ; ailleurs il reste un vide en croissant. L'original les fait
   déborder l'une sur l'autre pour qu'elles forment une seule silhouette. */
.cta-wrap .pill { width: 240px; height: 68px; }
.cta-wrap .pill--icon { margin-right: 60px; }
.cta-wrap .pill--icon::after {
  left: calc(100% - 8px); width: 68px; height: 68px;
  background-size: 16px 19.4px;              /* taille relevée sur l'original */
}

/* Fiche champignon — calque « 1 » : 350 px de large, colonne, gap 15 px. */
/* Fiche champignon : 477 × 621, la photo en fond, le titre en haut à gauche
   et la légende calée en bas. Retraits relevés : 34 px sur les côtés, 27 en bas. */
.mushroom-card {
  position: relative;
  width: 477px;
  height: 621px;
  max-width: 100%;
  display: flex;
  flex-flow: column;
  justify-content: flex-end;
  gap: 10px;
  margin: 0;
  padding: 0 34px 27px;
  overflow: hidden;
  background: var(--creme-pale);
}
@media (min-width: 1026px) { .mushroom-card--hidden { display: none; } }

/* Calque « Product Title » : Millave 38,88 px, sans remplissage, trait 1 px. */
.mushroom-card__title {
  position: absolute; top: 34px; left: 34px; z-index: 1;
  margin: 0;
  font-family: var(--titre);
  font-weight: var(--titre-graisse);
  font-size: 38.88px;
  line-height: 46.656px;
  text-transform: uppercase;
  color: transparent;
  -webkit-text-stroke: 1px var(--vert);
  text-stroke: 1px var(--vert);
}

.mushroom-card__photo {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
}
.mushroom-card figcaption {
  position: relative;
  font-family: var(--texte);
  font-weight: var(--texte-graisse);
  font-size: 16px;
  line-height: 20px;
  color: var(--vert-encre);
  /* Filet blanc de 1 px puis 19 px de respiration : c'est un calque à part
     dans l'original, une bordure haute suffit ici. */
  border-top: 1px solid #fff;
  padding: 19px 0 0;
}

/* Carrousel, en dessous de 1026 px. Valeurs relevées sur l'original à 360 px :
   piste de 320 posée 4 px plus bas, diapositives de 350 séparées de 4, accrochage
   au centre. Chaque diapositive empile son texte, sa fiche et son compteur avec
   un écart de 15. */
@media (max-width: 1025.98px) {
  .ingredients__inner {
    display: flex; flex-flow: column; align-items: center; gap: 16px;
    max-width: none; padding-inline: 20px;
  }

  .ingredients__carrousel { display: flex; flex-flow: column; gap: 16px; }
  .ingredients__voie { display: block; position: relative; width: 100%; }

  /* Les 24 px du bas sont ceux de l'original : sa liste fait 666 pour des
     diapositives de 642. C'est la réserve que son composant garde pour la
     barre de défilement — visible ou non, elle occupe la place. */
  .ingredients__piste {
    flex-flow: row; gap: 4px; align-items: flex-start;
    padding: 4px 0 24px;
    overflow-x: auto; overscroll-behavior-x: contain;
    scroll-snap-type: x mandatory;
  }

  .ingredient, .ingredient + .ingredient {
    flex: none; width: 350px;
    align-items: center; gap: 15px;
    scroll-snap-align: center;
    padding-top: 0; border-top: 0;
  }

  /* Calque « Text content » : 350 de large, écart 22, centré. */
  .ingredient__texte { display: flex; flex-flow: column; align-items: center; gap: 22px; width: 100%; }
  .ingredient__label {
    width: 277px; margin: 0;
    font-size: 30px; line-height: 25.5px; text-align: center;
  }
  /* La diapositive de l'original ne porte pas d'icône. */
  .ingredient__icon { display: none; }
  .ingredient__body { display: block; width: 100%; }
  .ingredient__name, .ingredient__text { text-align: center; margin: 0; }

  /* Calque « Bottom » : la fiche de 325 × 425 puis le compteur, écart 16. */
  .mushroom-card {
    width: 325px; height: 425px;
    padding: 0 24px 18px;
    gap: 10px;
  }
  .mushroom-card__title { display: none; }
  .mushroom-card__logo {
    display: block;
    position: absolute; top: 34px; left: 34px; z-index: 1;
  }
  .mushroom-card figcaption {
    width: 277px;
    font-size: 14px; line-height: 15px;
    padding-top: 19px;
  }

  /* L'original imbrique deux écarts : 15 px entre le texte et le bas de la
     diapositive, 16 entre la fiche et le compteur. La diapositive est plate
     ici — le pixel manquant se rattrape en marge. */
  .ingredient__compteur {
    display: block; margin: 1px 0 0;
    font-family: var(--titre); font-weight: var(--titre-graisse);
    font-size: 13px; line-height: 13px;
    text-transform: uppercase; text-align: center; color: var(--vert);
  }

  /* Les flèches reprennent la place que l'original leur réserve : aux deux
     bords de la piste, 20 px de retrait, centrées en hauteur. */
  .ingredients__nav {
    position: absolute; inset: 0;
    margin: 0; padding: 20px;
    justify-content: space-between;
    pointer-events: none;
  }
  .carousel-nav__btn {
    width: 40px; height: 40px;
    border: 0; border-radius: 40px;
    background: rgba(0, 0, 0, .2); color: #fff;
    pointer-events: auto;
  }
  .carousel-nav__btn:hover { background: rgba(0, 0, 0, .35); color: #fff; }
  .carousel-nav__count { display: none; }

  .cta-wrap { margin: 0; justify-content: center; }
}

/* Ordinateur : les rubriques en colonne de 544 à gauche, la fiche hors flux à
   droite. Elle est posée en absolu — et non dans une grille partagée — pour que
   la colonne de gauche garde exactement son enchaînement : trois rubriques,
   puis le bouton 32 px plus bas. Une grille à cases communes aurait aligné le
   bouton sur le bas de la fiche et l'aurait descendu de 99 px.
   La hauteur minimale du bloc est celle de la colonne de droite — fiche 621,
   écart 16, flèches 34 — sinon la fiche déborderait sur la section suivante. */
@media (min-width: 1026px) {
  .ingredients__inner { display: block; }
  .ingredients__carrousel { min-height: 671px; }
  .ingredients__piste { width: 544px; }
  .mushroom-card { position: absolute; top: 0; left: 633px; }
  .ingredients__nav { position: absolute; top: 637px; left: 633px; width: 477px; }
}

/* Le bouton reste dans la colonne de gauche, 72 px sous la dernière rubrique :
   écart relevé sur l'original — 2 583 pour un bloc de rubriques finissant à
   2 511. Il valait 56 px avant, hérité d'un `gap` de 24 plus une marge de 32,
   aucun des deux relevé. */
@media (min-width: 1026px) { .cta-wrap { width: 544px; margin-top: 72px; } }

/* ---------- rituel --------------------------------------------------------
   Calque « Le café comme un rituel » : fond vert, colonne centrée.
   La vague « curve line » mesure 3213 × 299 et démarre à left:-200px — elle
   n'est pas centrée, contrairement à ce que j'avais supposé.
   -------------------------------------------------------------------------- */

.wave { display: block; max-width: none; }
/* La vague est un rectangle crème opaque avec la courbe verte par-dessus :
   elle masque donc tout ce qui passe derrière. Chez Framer la personne est
   au-dessus d'elle — son chapeau se détache sur le crème. */
.wave--top { position: absolute; top: 0; left: -200px; width: 3213px; height: 299px; z-index: 1; }

/* Le fond commun aux deux sections. Le panneau reste collé en haut de la
   fenêtre et couvre toute sa hauteur ; c'est sa couleur que le script fait
   passer du vert au rose. Les deux sections deviennent donc transparentes. */
.scroll-bg { position: relative; }
.scroll-bg__panneau {
  position: sticky; top: 0;
  height: 100vh;
  background: var(--vert);
  z-index: 0;
  pointer-events: none;
}
/* Sans script, chaque section garde son fond : le raccord est franc, mais
   rien ne manque. Le script prend le relais en rendant les deux transparentes
   pour laisser voir le panneau. */
.no-js .scroll-bg__panneau { display: none; }
.scroll-bg.est-actif .ritual,
.scroll-bg.est-actif .prep { background: transparent; }

.ritual {
  position: relative;
  z-index: 1;
  margin-top: -100vh;                     /* le panneau ne prend pas de place */
  width: 100%;
  background: var(--vert);
  color: var(--creme);
  display: flex;
  flex-flow: column;
  place-content: center;
  align-items: center;
  overflow: clip;
  /* 280 px : c'est là que commence le titre dans l'original, mesuré depuis le
     haut de la section. La vague, elle, se superpose sans occuper de place. */
  padding: 280px 40px 125px;
}
@media (max-width: 809.98px) { .ritual { padding: 0 12px 46px; } }

/* 920 px, et sans la gouttière de « .shell » : elle vaut 56 px de chaque côté
   et ramenait la grille à 808. Le retrait est déjà porté par la section. */
.ritual__inner { width: 100%; max-width: 920px; padding-inline: 0; position: relative; z-index: 3; }
.ritual__head { position: relative; text-align: center; margin-bottom: 60px; }

/* Calques « Person » et son tracé : 372 × 910 et 481 × 448, tous deux centrés
   sur la fenêtre et calés en haut de la section. Ils passent au-dessus de la
   vague et sous les blocs de contenu — d'où la personne tronquée par le bas.
   Le tracé vient avant la personne dans le document : chez Framer il porte
   « z-index: 0 » contre « 1 » pour elle, dans le même conteneur. Il passe donc
   derrière, et les courbes s'arrêtent à sa silhouette. */
.ritual__person,
.ritual__lines {
  position: absolute; top: 0; left: 50%;
  transform: translateX(-50%);
  max-width: none; z-index: 2;
  pointer-events: none;
}
.ritual__person {
  width: 372px; height: 910px; object-fit: contain;
  /* La personne ne s'arrête pas net : l'original la fait disparaître en fondu.
     Un masque dégradé, opaque jusqu'à 31 % de sa hauteur puis transparent à
     62 %. Valeur identique aux quatre points de rupture. Sans lui, on voit ses
     jambes là où l'original ne montre plus rien. `getComputedStyle` ne la donne
     que si on demande `mask-image` : rien dans la géométrie ne la trahit. */
  -webkit-mask-image: linear-gradient(#000 31%, transparent 62%);
  mask-image: linear-gradient(#000 31%, transparent 62%);
}

.ritual__lines  { width: 481px; height: 448px; }

/* Calque « Section Title » : 71,44 px, interligne 85,728, rose. */
.ritual__title {
  color: var(--rose);
  font-size: 71.44px; line-height: 85.728px;
  margin: 0; position: relative;
}

.ritual__grid { display: flex; gap: 30px; }
.ritual__col { flex: 1 1 445px; min-width: 0; display: flex; flex-flow: column; gap: 30px; }
@media (max-width: 809.98px) { .ritual__grid { flex-flow: column; } }

/* Les quatre blocs. Retraits et hauteurs relevés dans le rendu de l'original :
   ni bordure, ni angle arrondi, ni dégradé sur la photo — le texte est posé
   directement dessus. */
.rblock { overflow: hidden; }
/* Futura PT Medium 28/28 dans l'original — j'avais 18/1,35, soit un texte
   d'un tiers trop petit. Brun sur le bloc crème, blanc cassé ailleurs. */
.rblock p { font-family: var(--texte);
  font-weight: var(--texte-graisse); font-size: 28px; line-height: 28px; }

/* Crème, 445 × 445 : texte en haut à 50 px, grain de café centré et plaqué en bas. */
.rblock--creme {
  height: 445px; padding: 50px 50px 0;
  background: var(--creme); color: var(--brun);
  display: flex; flex-flow: column; align-items: flex-start;
}
.rblock--creme p { width: 345px; max-width: 100%; margin: 0; }
.rblock--creme img { width: 214px; height: 216px; margin: auto auto 0; }

/* Or, 445 × 605 : le visuel occupe le carré du haut, le texte et le bouton
   sont posés par-dessus, à 334 et 503 px du haut. */
.rblock--or {
  height: 605px; position: relative;
  background: var(--or); color: #F2F2F3;
}
.rblock--or img { position: absolute; top: 0; left: 0; width: 445px; height: 445px; object-fit: cover; max-width: none; }
.rblock--or p { position: absolute; top: 334px; left: 50px; width: 345px; margin: 0; }
.rblock--or .pill { position: absolute; top: 503px; left: 50px; }

/* Photo, 445 × 605 : le fond est une vidéo. Texte à 60 px du haut,
   bouton à 50 px du bas. */
.rblock--photo { height: 605px; position: relative; }
.rblock--photo video {
  position: absolute; inset: 0;
  width: 100%; height: 100%; object-fit: cover; max-width: none;
}
.rblock__overlay {
  position: absolute; inset: 0;
  display: flex; flex-flow: column; justify-content: space-between;
  padding: 60px 50px 50px;
  color: #F2F2F3;
}
.rblock__overlay p { width: 345px; max-width: 100%; margin: 0; }

/* Les deux boutons de la section : 240 × 68. */
.rblock .pill { width: 240px; height: 68px; }

/* Citation, 445 × 445, sans fond ni bordure. Calques « Quote » (97 px) et
   « Review » (345 px, Millave 30 px capitales), retrait de 40 px. */
.rblock--quote {
  height: 445px; padding: 40px; margin: 0;
  /* Fond vert encre, relevé chez l'original : rgb(4, 50, 37). Il manquait, et
     le texte — #F2F2F3 — se lisait crème sur crème, illisible à toutes les
     largeurs. */
  background: var(--vert);
  /* Framer ne le déclare pas en bordure — mais il peint bien un filet de 1 px
     en #F2F2F3 sur tout le pourtour. Relevé au pixel. */
  border: 1px solid #F2F2F3;
  display: flex; flex-flow: column; justify-content: space-between;
}
.rblock--quote::before {
  content: "\201C";
  font-family: var(--titre);
  font-weight: var(--titre-graisse); font-size: 97px; line-height: 97px;
  color: #F2F2F3; display: block;
}
.rblock--quote blockquote { margin: 0; }
.rblock--quote p {
  font-family: var(--titre);
  font-weight: var(--titre-graisse); text-transform: uppercase;
  font-size: 30px; line-height: 30px; color: #F2F2F3;
  width: 345px; max-width: 100%; margin: 0;
}

/* ----- rituel, plage téléphone -------------------------------------------
   Relevé sur l'original à 360 px. La section ne fait plus deux colonnes mais
   une seule, et l'ordre des blocs y change : crème, doré, vidéo, citation —
   alors que l'empilement des deux colonnes donnerait crème, vidéo, doré,
   citation. Chez Framer c'est un `order` sur les enfants ; ici les colonnes
   s'effacent et les quatre blocs reprennent la main.
   -------------------------------------------------------------------------- */
@media (max-width: 809.98px) {
  /* Le tracé descend de 65 px ; la personne et la vague restent en haut. */
  .ritual__person { width: 262px; height: 642px; }
  .ritual__lines  { width: 341px; height: 318px; top: 65px; }
  .wave--top { left: -90px; }

  /* Bloc du titre : 511 px de haut, contenu calé en bas, 60 px de retrait. */
  .ritual__head {
    height: 511px; margin: 0; padding-bottom: 60px;
    display: flex; flex-flow: column; justify-content: flex-end; align-items: center;
  }
  .ritual__title { width: 100%; font-size: 54px; line-height: 48.6px; }

  .ritual__col { display: contents; }
  .rblock--creme { order: 1; }
  .rblock--or    { order: 2; }
  .rblock--photo { order: 3; }
  .rblock--quote { order: 4; }

  /* Crème : 445 de haut, retraits 25 / 27 / 0, texte en haut et grain en bas,
     tous deux centrés. Le texte fait 296 px — plus large que la boîte de 282 —
     et déborde donc de 7 px de chaque côté. C'est ce que fait l'original. */
  .rblock--creme {
    padding: 25px 27px 0;
    justify-content: space-between; align-items: center;
  }
  .rblock--creme p { width: 296px; max-width: none; font-size: 22px; line-height: 22px; }
  .rblock--creme img { margin: 0; }

  /* Doré : 560 de haut, le sachet déborde de 20 px par le haut et de 15 px de
     chaque côté ; texte et bouton sont calés en bas, écartés de 24. */
  .rblock--or {
    height: 560px; padding: 0 20px 20px; gap: 24px;
    display: flex; flex-flow: column; justify-content: flex-end; align-items: flex-start;
  }
  .rblock--or img {
    top: -20px; left: 50%; transform: translateX(-50%);
    width: 366px; height: 366px; z-index: 0;
  }
  .rblock--or p {
    position: relative; top: auto; left: auto; z-index: 1;
    width: 296px; font-size: 22px; line-height: 28px;
  }
  .rblock--or .pill { position: relative; top: auto; left: auto; z-index: 1; }

  /* Vidéo : 477 de haut, retraits 34 / 20 / 20. Le texte y fait 313 px, une
     valeur à lui — les deux autres blocs sont à 296. */
  .rblock--photo { height: 477px; }
  .rblock__overlay { padding: 34px 20px 20px; }
  .rblock__overlay p { width: 313px; max-width: none; font-size: 22px; line-height: 28px; }

  /* Les deux boutons passent de 240 à 296 px. */
  .rblock .pill { width: 296px; }

  /* Citation : 350 de haut, retraits 40 / 39 / 40 / 40. Le guillemet garde ses
     97 px ; l'avis passe à 22 / 24 sur 271 px de large. */
  .rblock--quote { height: 350px; padding: 40px 39px 40px 40px; }
  .rblock--quote p { width: 271px; max-width: none; font-size: 22px; line-height: 24px; }
}

/* ---------- préparation ----------------------------------------------------
   Calque « Comment préparer le café » : fond rose, disposition en ligne.
   -------------------------------------------------------------------------- */

.prep {
  position: relative;
  z-index: 1;
  width: 100%;
  /* « clip » et non « hidden » : il coupe le débordement de l'illustration sans
     créer de conteneur de défilement, donc sans casser les colonnes figées. */
  overflow: clip;
  background: var(--rose);
  color: var(--vert);
  display: flex;
  justify-content: center;
  padding: 60px 40px;
}
@media (max-width: 1025.98px) { .prep { padding: 48px 20px; } }

/* Trois colonnes centrées dans 1360 px, écart de 10. Le tout fait 1102 px de
   large : les 258 px restants se répartissent de part et d'autre. */
.prep__inner {
  display: flex; justify-content: center; align-items: flex-start;
  gap: 10px;
  width: 100%; max-width: 1360px;
}
@media (max-width: 1025.98px) { .prep__inner { flex-flow: column; align-items: center; } }

/* Les deux colonnes extérieures se figent à 110 px du haut pendant que la
   colonne des étapes continue de défiler. Elles se décrochent quand le bas de
   la section les rattrape. Relevé sur l'original : « sticky, top: 110px ». */
.prep__left {
  width: 362px; flex: none;
  display: flex; flex-flow: column; gap: 20px;
  position: sticky; top: 110px;
}

/* Calque « Section Title » : 55,97 px, interligne 67,164. */
.prep__title { font-size: 55.97px; line-height: 67.164px; margin: 0; }

/* Bloc aux grains : vidéo de 295 × 423, légende posée à 279 px de son haut. */
.dose { position: relative; width: 295px; height: 423px; margin: 0; }
.dose video {
  position: absolute; inset: 0;
  width: 100%; height: 100%; object-fit: cover;
}
/* Le filet est un élément à part dans l'original : 239 × 1 en crème, 30 px
   au-dessus du texte. Une bordure haute avec ce retrait donne le même rendu. */
.dose figcaption {
  position: absolute; left: 28px; top: 248px;
  width: 239px;
  font-family: var(--titre);
  font-weight: var(--titre-graisse); text-transform: uppercase; color: var(--creme);
  font-size: 27px; line-height: 28px;
  border-top: 1px solid var(--creme);
  padding-top: 30px;
}

/* Cinq étapes de 556 × 240, écartées de 20 : illustration de 240 puis le bloc
   texte de 269, séparés de 47. */
.steps {
  width: 556px; flex: none;
  counter-reset: etape;
  display: flex; flex-flow: column; gap: 20px;
  margin: 0;
}
.steps li {
  counter-increment: etape;
  display: flex; align-items: center; gap: 47px;
  height: 240px; padding: 0; min-height: 0;
}
.steps__icone { width: 240px; height: 240px; flex: none; display: block; }
.steps__icone img,
.steps__icone svg { width: 100%; height: 100%; display: block; }
.steps__bloc { width: 269px; }

/* Calque du numéro : Millave 64 px, sans remplissage, trait de 1 px. */
.steps__bloc::before {
  content: counter(etape, decimal-leading-zero);
  display: block;
  font-family: var(--titre);
  font-weight: var(--titre-graisse);
  font-size: 64px; line-height: 76.8px;
  color: transparent; -webkit-text-stroke: 1px #F2F2F3;
  font-variant-numeric: tabular-nums;
  margin-bottom: 23px;
}
.steps__text {
  display: block;
  font-family: var(--texte);
  font-weight: var(--texte-graisse);
  font-size: 24px; line-height: 24px; color: var(--vert);
}

/* Colonne de droite : 164 px de large, mais l'illustration en fait 437 et
   déborde volontairement. */
/* 164 × 522 : l'illustration de 437 × 786 déborde des deux côtés, à dessein.
   C'est cette hauteur de 522 qui décide du moment où la colonne se décroche. */
.prep__right { width: 164px; height: 522px; flex: none; position: sticky; top: 110px; }
.prep__illustration { width: 437px; height: 786px; max-width: none; display: block; }
@media (max-width: 1025.98px) {
  .prep__right { display: none; }
  /* En colonne, il n'y a plus rien à figer : les blocs se suivent. */
  .prep__left { position: static; }
}

/* ----- préparation, plage téléphone ---------------------------------------
   Relevé sur l'original à 360 px. Une seule colonne de 336 : le titre et le
   bloc aux grains d'abord, écartés de 28, puis les cinq étapes 59 px plus bas,
   écartées de 40. La colonne de droite n'existe pas ici.
   -------------------------------------------------------------------------- */
@media (max-width: 809.98px) {
  .prep { padding: 40px 12px 60px; }
  .prep__inner {
    flex-flow: column; align-items: flex-start; justify-content: center;
    gap: 59px; width: 100%; max-width: none;
  }

  .prep__left { width: 100%; gap: 28px; align-items: center; }
  .prep__title { width: 100%; font-size: 54px; line-height: 54px; text-align: center; }

  /* Le bloc aux grains prend toute la largeur ; sa légende est calée en bas,
     retraits 32 / 60 / 40 / 33, ce qui lui laisse 243 px. Le filet est un
     élément à part chez l'original, 35 px au-dessus du texte : une bordure
     haute avec ce retrait donne le même rendu. */
  /* Le bloc suit la largeur : sa hauteur vaut 143,45 % de celle-ci — relevé à
     360, 500 et 809, soit 482, 683 et 1126. */
  .dose {
    width: 100%; height: auto; aspect-ratio: 336 / 482;
    display: flex; flex-flow: column; justify-content: flex-end; align-items: center;
    padding: 32px 60px 40px 33px;
  }
  /* `relative` et non `static` : la vidéo est posée en absolu au-dessus du
     contenu de flux, et une légende statique passait dessous — invisible. */
  .dose figcaption {
    position: relative; left: auto; top: auto; z-index: 1;
    width: 100%; padding-top: 35px;
  }

  /* Cinq étapes : illustration et colonne de texte se partagent la largeur à
     parts égales, écartées de 31, sans jamais dépasser 240 et 269 — les valeurs
     de l'ordinateur. À 360 cela donne 153 et 153 ; à 809, 240 et 269. Les deux
     relevés tombent juste. */
  .steps { width: 100%; gap: 40px; }
  .steps li { height: auto; gap: 31px; justify-content: center; }
  .steps__icone { flex: 1 1 0; width: auto; max-width: 240px; height: auto; aspect-ratio: 1; }
  .steps__bloc {
    flex: 1 1 0; width: auto; max-width: 269px;
    display: flex; flex-flow: column; align-items: flex-start; gap: 24px;
  }
  .steps__bloc::before { font-size: 50px; line-height: 50px; margin-bottom: 0; }
  .steps__text { font-size: 20px; line-height: 24px; }
}

/* ---------- bandeau énergie ------------------------------------------------- */

/* 1440 × 655, fond vidéo, vague de 79 px posée au bord haut. Le contenu tient
   dans un bloc de 920 px centré, à 415 px du haut : un filet blanc de 1 px,
   puis le titre et le bouton alignés par le bas. */
.energy {
  position: relative;
  height: 655px;
  padding: 0 0 76px;
  overflow: clip;
  color: #F2F2F3;
}
.energy__fond {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  max-width: none; object-fit: cover;
  z-index: 0;
}
.energy__vague {
  position: absolute; top: 0; left: 0;
  width: 100%; height: 79px;
  max-width: none;
  z-index: 1;
}
/* Centré par les marges, pas par « transform » : le script d'apparition pose
   son propre transform sur les blocs marqués « data-reveal » et écraserait
   celui-ci sans bruit. */
.energy__inner {
  position: absolute; top: 415px; left: 0; right: 0;
  margin-inline: auto;
  width: 920px; max-width: calc(100% - 80px);
  z-index: 2;
}
.energy__rule { border: 0; border-top: 1px solid #F2F2F3; margin: 0; }
.energy__row {
  display: flex; align-items: flex-end; justify-content: space-between;
  padding-top: 56px;
}
/* Calque « Description » : Millave 45 px, interligne 54, capitales. */
.energy__title {
  width: 570px; max-width: 100%;
  font-size: 45px; line-height: 54px;
  text-transform: uppercase;
  color: #F2F2F3;
  margin: 0;
}
.energy .pill { width: 232px; height: 68px; }
.energy .pill--icon { margin-right: 68px; }
.energy .pill--icon::after { left: calc(100% - 8px); width: 68px; height: 68px; background-size: 16px 19.4px; }

@media (max-width: 1025.98px) {
  .energy { height: auto; padding: 96px 20px 76px; }
  .energy__inner { position: static; width: 100%; max-width: none; }
  .energy__row { flex-flow: column; align-items: flex-start; gap: 24px; }
  .energy__title { width: auto; font-size: 32px; line-height: 38px; }
}

/* Téléphone : la section garde les 655 px qu'elle a sur ordinateur — seuls ses
   retraits changent, 0 / 12 / 24. Le bloc reste calé en bas, la vague suit la
   largeur par son rapport 18,2278, le titre passe à 44 / 48,4 sur 570 px au
   plus, et l'écart entre le titre et le bouton passe de 55 à 32.
   Relevé identique à 360, 500 et 809. */
@media (max-width: 809.98px) {
  .energy { height: 655px; padding: 0 12px 24px; }
  .energy__vague { height: auto; aspect-ratio: 18.2278; }
  .energy__inner {
    position: absolute; top: auto; bottom: 24px; left: 12px; right: 12px;
    width: auto; max-width: none;
    display: flex; flex-flow: column; gap: 24px;
  }
  .energy__row { gap: 32px; padding-top: 0; }
  .energy__title { width: 570px; max-width: 100%; font-size: 44px; line-height: 48.4px; }
}

/* ---------- bande photo — calque « ticker » : ligne, padding 10px 0 0 ------- */

/* Calque « ticker » : 1440 × 247, retrait de 10 px en haut, débordement coupé.
   Les vignettes font 380 × 237, écartées de 10 — le rapport 1,60338 est celui
   que déclare l'original, et c'est lui qui donne 152,17 aux vignettes de 244.

   En dessous de 1026 px le calque passe en colonne et une seconde rangée
   apparaît : elle est dans le balisage de l'original à tous les points de
   rupture, masquée au-dessus par ses classes « hidden ». Les deux pistes
   défilent en sens contraire.

   Hauteur du calque : 10 + 237 sur ordinateur, 10 + 152,17 + 10 + 152,17
   = 324,34 en dessous de 1026 — relevé identique à 360, 500, 700 et 809. */
.strip-wrap { display: flex; flex-flow: column; gap: 10px; overflow: clip; padding: 10px 0 0; }
.strip-row { overflow: clip; }
.strip { display: flex; gap: 10px; margin: 0; }
.strip li { flex: none; }
.strip img { width: 380px; aspect-ratio: 1.60338; object-fit: cover; display: block; }
/* Quatre vignettes : la piste parcourt sa propre largeur plus un écart. */
.strip-row { --cycle: 1560; }
@media (max-width: 809.98px) {
  .strip img { width: 244px; }
  .strip-row { --cycle: 1016; }
}

/* ---------- avis — calque « testimonials » : padding 75px 0 0 --------------- */

.reviews { background: var(--creme); padding: 75px 0 0; }
/* Calque « Section Title » : 84 px, interligne 100,8, puis 48 px avant la
   piste — c'est ce qui donne à la section ses 623 px. Ma taille élastique
   plafonnait 14 px trop bas avec un interligne plus court que le corps. */
.reviews__title {
  font-size: 84px; line-height: 100.8px;
  text-align: center; margin: 0 0 48px;
}
@media (max-width: 809.98px) { .reviews__title { font-size: 44px; line-height: 52px; margin-bottom: 32px; } }
/* Calque « testimonials » : vignettes de 225 × 399, écart 10, sur une piste qui
   défile vers la droite à 30,5 px/s. Sans script, le rail reste simplement
   parcourable au doigt. */
.reviews__piste { overflow: clip; }
.reviews__rail {
  display: flex; gap: 10px; margin: 0;
  overflow-x: auto;
  padding-inline: var(--gouttiere);
}
.reviews__rail li { flex: 0 0 225px; }
.reviews__rail img { width: 225px; height: 399px; object-fit: cover; display: block; border-radius: 20px; }

/* Six vignettes de 225 écartées de 10 : la piste parcourt 1 410 px, ce qui fait
   47 s à la vitesse de 30 px/s relevée sur l'original. */
.reviews__piste { --cycle: 1410; }
.reviews__piste.is-running { display: flex; gap: 10px; }
.reviews__piste.is-running .reviews__rail {
  flex: none; overflow: visible; padding-inline: 0;
  animation: defilement-droite calc(var(--cycle) / 30 * 1s) linear infinite;
}
.reviews__piste.is-running:hover .reviews__rail { animation-play-state: paused; }
@keyframes defilement-droite {
  from { transform: translateX(calc(-100% - 10px)); }
  to { transform: translateX(0); }
}
/* Téléphone : les vignettes gardent leurs 225 × 399 — l'original ne les réduit
   pas. Le titre passe à 54 / 59,4 sur 76 % de la fenêtre, écarté de 48 de la
   piste, et cette largeur de 76 % le fait tenir sur deux lignes à 360 et une
   seule dès 500 : c'est ce qui fait varier la hauteur de la section, 640,81
   puis 581,41. La piste, elle, part du bord. */
@media (max-width: 809.98px) {
  .reviews { padding-top: 75px; }
  .reviews .shell { padding-inline: 0; }
  .reviews__title {
    width: 76%; margin-inline: auto; margin-bottom: 48px;
    font-size: 54px; line-height: 59.4px;
  }
  .reviews__rail { padding-inline: 0; }
}

/* ---------- FAQ — calque « FAQ Component » : gap 18px ---------------------- */

/* Calque « faq » : 1440 × 423, bloc de 1110 centré, deux colonnes de 339 et
   723 séparées de 48. */
.faq { background: var(--creme); padding-block: 37px; }
.faq__inner {
  display: grid; gap: 48px; align-items: start;
  width: 1110px; max-width: 100%;
  margin-inline: auto; padding-inline: 0;
}
@media (min-width: 810px) { .faq__inner { grid-template-columns: 339px 723px; } }
.faq__title { font-size: 36px; line-height: 43.2px; margin: 0; }
.faq__list { display: flex; flex-flow: column; gap: 18px; }

/* Une entrée fermée : filet doré de 1 px, fond transparent, question en noir.
   Ouverte, elle bascule sur un panneau vert plein et tout passe en crème.
   J'avais un simple filet sous chaque ligne, sans panneau. */
.faq-item {
  border: 1px solid var(--or);
  background: transparent;
  transition: background-color .25s ease, border-color .25s ease;
}
.faq-item[open] { background: rgb(4, 51, 38); border-color: transparent; }

.faq-item > summary {
  cursor: pointer; list-style: none;
  display: flex; justify-content: space-between; align-items: flex-start; gap: 16px;
  /* 25 et 37 plutôt que 26 et 38 : le filet de 1 px s'ajoute au calcul, et
     l'entrée doit faire 74 px de haut avec le texte à 38 px du bord. */
  padding: 25px 37px;
  font-family: var(--texte);
  font-weight: var(--texte-graisse); font-size: 18px; line-height: 21.6px;
  color: #000;
}
.faq-item[open] > summary { color: var(--creme); }
.faq-item > summary::-webkit-details-marker { display: none; }

/* Chevron quand c'est fermé, croix quand c'est ouvert. */
.faq-item > summary::after {
  content: ""; flex: none; width: .6rem; height: .6rem; margin-top: .25rem;
  border-right: 1.5px solid currentColor; border-bottom: 1.5px solid currentColor;
  transform: rotate(45deg);
}
.faq-item[open] > summary::after {
  content: "\00D7";
  width: auto; height: auto; margin-top: -.25rem;
  border: 0; transform: none;
  font-size: 22px; line-height: 1;
}

/* Ouverte, l'entrée garde ses retraits de 26 / 38 mais l'écart entre la question
   et la réponse tombe de 40 à 20, et la réponse est en 18 / 24 — un interligne
   plus long que celui de la question. Relevé en ouvrant une entrée par un vrai
   clic ; le composant a deux jeux de valeurs, un par état. */
.faq-item[open] > summary { padding-bottom: 20px; }
.faq-item__answer {
  padding: 0 37px 25px;
  font-family: var(--texte);
  font-weight: var(--texte-graisse); font-size: 18px; line-height: 24px;
  color: var(--creme);
}
.faq-item__answer p { margin: 0; }

/* Téléphone : une seule colonne, retraits 75 / 12, titre centré en 36 / 43,2
   puis 48 px avant la liste. Les entrées gardent les retraits 26 / 38 de
   l'original — 25 / 37 chez nous, le filet de 1 px s'ajoutant au calcul, comme
   sur ordinateur — et la question laisse 40 px au chevron, centré sur elle.

   Écart assumé nº 5, 26 août 2026 : chez l'original le titre déborde de son
   bloc et vient se coller à 7,8 px de la section précédente au lieu des 75 px
   qu'il déclare. Ce n'est pas une mise en page : son runtime pose en ligne un
   « height: 434.75px » sur le bloc — la hauteur mesurée pour la disposition en
   deux colonnes de l'ordinateur, appliquée telle quelle une fois le bloc passé
   en colonne. Le titre s'y retrouve centré hors de sa boîte et la section perd
   134 px. Ici il est dans le flux et le retrait est respecté. Ne pas
   « corriger » vers l'original en croyant rétablir la fidélité. */
@media (max-width: 809.98px) {
  .faq { padding: 75px 12px; }
  .faq__inner { width: 100%; padding-inline: 0; gap: 48px; }
  .faq__title { text-align: center; }
  .faq-item > summary { padding: 25px 37px; gap: 40px; align-items: center; }
  .faq-item__answer { padding: 0 37px 25px; }
}

/* ---------- bannière -------------------------------------------------------- */

/* Bannière : 1440 × 665, image de 1110 × 590 centrée sous 75 px de retrait.
   Le bloc de texte fait 544 de large, centré, et commence 113 px sous le haut
   de l'image. J'avais une image pleine largeur et un voile sombre inexistant. */
.banner { background: var(--creme); padding: 75px 40px 0; }
.banner__frame {
  position: relative;
  width: 1110px; height: 590px; max-width: 100%;
  margin-inline: auto;
  overflow: hidden;
}
/* Le cadrage 68,1 % / 50,3 % vient de l'original. Sans effet sur ordinateur,
   où le cadre et l'image ont le même rapport ; déterminant au téléphone, où
   le cadre passe en portrait et recadre fortement. */
.banner__frame > img {
  width: 100%; height: 100%; display: block;
  object-fit: cover; object-position: 68.1% 50.3%;
}
.banner__overlay {
  position: absolute; top: 113px; left: 0; right: 0;
  margin-inline: auto;
  width: 544px; max-width: calc(100% - 48px);
  display: flex; flex-flow: column; align-items: center;
  text-align: center;
  background: none;
}
/* Calque du sur-titre : Millave 28,27, interligne 33,924, rose. */
.banner__kicker {
  font-family: var(--titre);
  font-weight: var(--titre-graisse); text-transform: uppercase;
  font-size: 28.27px; line-height: 33.924px; letter-spacing: normal;
  color: var(--rose);
  margin: 0 0 16px;
}
/* Calque du titre : Millave 60, interligne 72, blanc cassé. Le calque déclare
   « word-break: break-word » : à 360 px « CONCENTRATION » ne tient pas sur la
   ligne et l'original le coupe en deux plutôt que de le laisser déborder du
   cadre. Reproduit tel quel — sans cette règle, le mot sort de l'image de 19 px
   de chaque côté chez nous. */
.banner__title {
  font-size: 60px; line-height: 72px;
  color: #F2F2F3;
  margin: 0 0 30px;
  word-break: break-word; overflow-wrap: break-word;
}
.banner .pill { width: 232px; height: 68px; }
.banner .pill--icon { margin-right: 68px; }
.banner .pill--icon::after { left: calc(100% - 8px); width: 68px; height: 68px; background-size: 16px 19.4px; }

@media (max-width: 1025.98px) {
  .banner { padding: 48px 20px 0; }
  .banner__frame { width: 100%; height: auto; aspect-ratio: 1110 / 590; }
  .banner__overlay { top: 12%; width: auto; }
  .banner__title { font-size: 34px; line-height: 40px; }
  .banner__kicker { font-size: 20px; line-height: 24px; }
}

/* Téléphone : la section perd ses retraits, le cadre prend toute la largeur et
   garde ses 590 px. Le bloc de texte n'est plus posé à 113 px du haut mais calé
   en bas, à 48 px du bord, sur toute la largeur. Le sur-titre garde ses
   28,27 / 33,924 ; le titre passe de 60 / 72 à 44 / 52,8 et se coupe seul —
   trois lignes à 360 et 500, deux dès 700, ce qui fait varier le bloc de 306,31
   à 253,52 sans toucher aux 590 px de la section. */
@media (max-width: 809.98px) {
  .banner { padding: 0; }
  .banner__frame { width: 100%; height: 590px; }
  .banner__overlay {
    top: auto; bottom: 48px;
    width: 100%; max-width: none;
  }
  .banner__title { font-size: 44px; line-height: 52.8px; }
  .banner__kicker { font-size: 28.27px; line-height: 33.924px; }
}


/* ---------- pied de page — calque « Top » : 600 px, ligne, gap 40px --------- */

/* Pied de page : 1440 × 656, filigrane en fond sur toute la surface, et trois
   colonnes posées à leurs coordonnées relevées. Les deux colonnes extérieures
   ont leur contenu calé bas (titre à 249), la centrale part du haut (titre à
   66) — ce n'est pas une grille régulière, et la traiter comme telle donnait
   trois colonnes alignées qui ne ressemblaient à rien. */
.site-footer {
  position: relative;
  height: 656px;
  background: var(--creme);
  overflow: clip;
}
/* L'opacité est portée par le CSS et non par le fichier : l'original peint le
   filigrane à 9 % sur ordinateur et en pleine teinte au téléphone, où il change
   d'ailleurs de fichier — un PNG de 1444 × 324 au lieu du SVG. */
.site-footer__mark {
  position: absolute; inset: 0;
  width: 100%; height: 656px;
  max-width: none; object-fit: cover;
  pointer-events: none;
  opacity: .09;
}
/* Tout est centré dans la colonne : le titre, les liens, la rangée d'icônes.
   Je les avais alignés à gauche. */
/* Trois colonnes de largeur égale sur 1094 px, centrées : « Service client »
   tombe sur l'axe de la page à 720, les deux autres à distance égale.
   L'original ne fait pas ça — ses colonnes font 256, 221 et 330, ce qui décale
   l'axe central à 683. Écart demandé et assumé. */
.site-footer__inner {
  position: absolute; top: 66px; left: 0; right: 0;
  margin-inline: auto;
  width: 1094px; max-width: 100%;
  display: grid; grid-template-columns: repeat(3, 1fr);
  align-items: start;
}
.site-footer__col { text-align: center; }
/* Le décalage vertical de l'original est conservé : contenu calé bas à gauche
   et à droite, en haut au centre. */
.site-footer__col--reseaux,
.site-footer__col--paiement { margin-top: 183px; }

/* Calque de titre de colonne : Futura PT 14 px, interligne 10, brun. */
.site-footer__title {
  font-family: var(--texte);
  font-weight: var(--texte-graisse);
  font-size: 14px; line-height: 10px;
  text-transform: uppercase; letter-spacing: normal;
  color: var(--brun);
  margin: 0;
}

/* Les liens : 14/14, pas de 46 px d'une ligne à l'autre. */
.site-footer__col--service ul {
  display: flex; flex-flow: column; align-items: center; gap: 32px;
  margin: 32px 0 0;
}
.site-footer__col--service a {
  display: block;                       /* sinon la boîte de ligne ajoute 6 px */
  font-family: var(--texte);
  font-weight: var(--texte-graisse); font-size: 14px; line-height: 14px;
  color: var(--vert); text-decoration: none;
}
.site-footer__col--service a:hover { text-decoration: underline; }

/* Rangées d'icônes, 42 px sous leur titre. */
.site-footer__icones {
  display: flex; align-items: center; justify-content: center; gap: 24px;
  margin: 32px 0 0;
}
.site-footer__icones--reseaux { gap: 44px; }
/* Chaque enveloppe a sa largeur — carrée pour les réseaux, relevée pour les
   moyens de paiement (36, 36, 21, 50, 42, 25). Sans elle la rangée se resserre
   sur la largeur propre de chaque tracé et n'atteint plus ses 256 et 330 px. */
.site-footer__icones > li { flex: none; display: flex; align-items: center; justify-content: center; }
/* Les enveloppes font toutes 16 px de haut : le tracé iDEAL, qui en fait 19,
   déborde de la sienne chez l'original plutôt que de grandir la rangée. */
.site-footer__icones > li { width: var(--boite, 16px); height: 16px; overflow: visible; }
.site-footer__icones > li > img { flex: none; }
/* Le tracé remplit la largeur de son enveloppe et garde son rapport ; les deux
   PNG carrés reçoivent leur hauteur relevée et sont recadrés, comme chez
   l'original. */
.site-footer__icones img { display: block; width: 100%; height: var(--haut, auto); object-fit: cover; }
.site-footer__icones--reseaux img { width: auto; height: 16px; object-fit: contain; }
.site-footer__icones a { display: block; }
.site-footer__icones a:hover img { opacity: .7; }

@media (max-width: 1279.98px) {
  .site-footer { height: auto; padding: 56px 20px 64px; }
  .site-footer__mark { display: none; }
  .site-footer__inner { position: static; width: 100%; gap: 48px; }
  .site-footer__col--reseaux,
  .site-footer__col--paiement { margin-top: 0; }
}
/* Téléphone : le pied redevient une colonne — filigrane, bloc des trois
   rubriques, puis une seconde rangée de moyens de paiement, écartés de 34 sous
   des retraits 34 / 32 / 101. Le filigrane rentre dans le flux et fait 116 % de
   la largeur intérieure : il déborde des deux côtés, et le pied le rogne.

   Le bloc des rubriques garde les 555 px qu'il a sur ordinateur alors que son
   contenu en fait 650 : l'original ne recalcule pas cette hauteur en passant en
   colonne. Le contenu y est centré et rogné de 47 px en haut comme en bas —
   « SERVICE CLIENT » disparaît, ainsi que la rangée de paiement, que l'original
   rend une seconde fois plus bas pour la rattraper. Reproduit tel quel : le
   rognage est déclaré dans son projet, pas produit par son runtime, et le
   contournement de la rangée montre qu'il a composé avec.

   Retirer « height » et « overflow » de .site-footer__inner rétablit le titre
   manquant et rallonge le pied de 95 px. */
@media (max-width: 809.98px) {
  /* Le pied est posé dans un cadre de 926 px que l'original ne recalcule pas
     davantage : le bloc y est centré, avec 37 px de doré de part et d'autre à
     360 et 19 à 500 — et à 809, où le bloc atteint 968,6, ce sont ses deux
     bords qui sont rognés de 21 px. Les 10 px qui le séparent de la bannière
     sont dorés eux aussi. */
  .site-footer-cadre {
    display: flex; flex-flow: column; justify-content: center; align-items: center;
    box-sizing: border-box; height: 936px; padding-top: 10px;
    background: var(--creme); overflow: clip;
  }
  .site-footer {
    height: auto; overflow: clip; width: 100%;
    display: flex; flex-flow: column; align-items: center; justify-content: center;
    gap: 34px; padding: 34px 32px 101px;
  }
  .site-footer__mark {
    order: 0; position: static; display: block;
    width: 116%; height: auto; max-width: none;
    aspect-ratio: 4.44048; object-fit: contain;
    opacity: 1;
  }
  /* ÉCART ASSUMÉ Nº 6 — 10 septembre 2026 : le pied n'est plus rogné au
     téléphone.

     L'original fige ce bloc à 555 px pour un contenu de 650 et rogne 47 px en
     haut comme en bas : « SERVICE CLIENT » y disparaît, et l'original rend la
     rangée de paiement une seconde fois plus bas pour rattraper ce qu'il perd.
     Nous le reproduisions fidèlement depuis le 26 août.

     L'ajout du lien « Mon compte » a rendu le rognage nuisible : mesuré, il
     chassait « Livraison » du bloc — un lien de navigation réel devenait
     inatteignable au téléphone. Un défaut de mise en page qu'on reproduit est
     un choix ; un lien qu'on rend inaccessible n'en est pas un.

     Coût : le pied s'allonge d'environ 95 px sous 810 px, et « SERVICE
     CLIENT » réapparaît. Revenir en arrière tient en deux lignes — rétablir
     « height: 555px » et « overflow: clip » ci-dessous. */
  .site-footer__inner {
    order: 1;
    display: flex; flex-flow: column; align-items: center; justify-content: center;
    gap: 40px; padding: 2px 0;
  }
  .site-footer__mark, .site-footer__inner, .site-footer__icones--bas { flex: none; }
  /* Le bloc est plus court que son contenu : sans « flex: none » les trois
     rubriques se compriment au lieu de déborder, et le rognage ne tombe plus au
     même endroit que chez l'original. */
  .site-footer__col { flex: none; }
  .site-footer__col--service  { order: 0; min-height: 450px; display: flex; flex-flow: column;
                                align-items: center; justify-content: center; }
  .site-footer__col--reseaux  { order: 1; }
  .site-footer__col--paiement { order: 2; }
  /* La rangée dupliquée n'a plus de raison d'être : elle n'existait que pour
     rattraper celle que le bloc de 555 px rognait, et ce bloc ne rogne plus
     (écart nº 6 ci-dessus). La laisser afficherait les moyens de paiement deux
     fois — mesuré à 360 px, deux rangées à 52 px l'une de l'autre.
     Elle reste dans le balisage : rétablir le rognage la fait revenir. */
  .site-footer__icones--bas   { order: 3; margin: 0; display: none; }
  .site-footer__col--service ul { margin-top: 0; }
  .site-footer__col--service,
  .site-footer__col--reseaux,
  .site-footer__col--paiement { gap: 32px; }
  .site-footer__col--reseaux,
  .site-footer__col--paiement { display: flex; flex-flow: column; align-items: center; }
  .site-footer__col--reseaux .site-footer__icones,
  .site-footer__col--paiement .site-footer__icones { margin-top: 0; }
}

/* ---------- fiche produit — /boutique --------------------------------------- */

/* Calque « hero section » : retraits 112 / 64 / 0, fond doré. La fiche tient
   dans un bloc de 1 111 px centré, deux colonnes de 636 et 445 écartées de 30.
   Relevé au pixel sur la fiche d'origine. */
.fiche { background: var(--creme); padding: 112px 64px 0; }
.fiche__inner { width: 1111px; max-width: 100%; margin-inline: auto; overflow: clip; }
.fiche__cols { display: flex; gap: 30px; align-items: flex-start; }

/* -- galerie -- */
.fiche__gauche { display: flex; flex-flow: column; gap: 10px; align-items: center; width: 636px; }
.galerie { display: flex; gap: 10px; align-items: flex-start; width: 100%; }
.galerie__vignettes { display: flex; flex-flow: column; gap: 10px; margin: 0; flex: none; width: 139.9px; }
.galerie__vignette {
  display: block; padding: 0; border: 0; background: none; cursor: pointer;
  width: 139.9px; height: 155.4px; overflow: clip;
}
.galerie__vignette img { width: 100%; height: 100%; object-fit: cover; display: block; }
.galerie__vignette.est-active { outline: 1px solid var(--or); outline-offset: -1px; }
/* Une seule vue à la fois sur ordinateur : les autres attendent leur tour. */
.galerie__grande { flex: 1 1 auto; margin: 0; min-width: 0; }
.galerie__grande > li { display: none; aspect-ratio: 1 / 1; overflow: clip; }
.galerie__grande > li.est-active { display: block; }
.galerie__grande img { width: 100%; height: 100%; object-fit: cover; display: block; }
/* Les flèches de la galerie n'existent qu'au téléphone — 22 septembre 2026 ;
   à partir de 810 px, ce sont les vignettes qui changent l'image. */
.galerie__nav { display: none; }

/* Calque « icons » : trois mentions écartées de 30, sur 28 px de haut. */
.fiche__labels {
  display: flex; gap: 30px; justify-content: center; align-items: center;
  margin: 0; width: 100%; height: 28px;
}
.fiche__labels li { display: flex; gap: 6px; align-items: center; }
.fiche__labels img { display: block; width: auto; height: 28px; }
.fiche__labels span {
  font-family: var(--texte); font-weight: var(--texte-graisse);
  font-size: 14px; line-height: 16px; color: var(--vert);
}

/* -- colonne d'information et d'achat -- */
.fiche__droite {
  display: flex; flex-flow: column; gap: 21px; align-items: flex-start;
  width: 445px; flex: none;
}
.fiche__haut { display: flex; flex-flow: column; gap: 24px; width: 100%; }
.fiche__details { width: 100%; }

/* Les trois rubriques : pastilles de 36 px, retraits 8 / 12, rayon 74. */
.fiche__tags { display: flex; gap: 10px; margin: 0 0 16px; height: 36px; }
/* Retraits 7 / 11 et non 8 / 12 : le filet de 1 px s'ajoute au calcul. Framer
   le peint sans le déclarer — « border » y vaut 0, comme sur le bloc citation
   du rituel. */
.fiche__tags li {
  display: flex; align-items: center; padding: 7px 11px;
  border: 1px solid var(--or); border-radius: 74px;
  font-family: var(--texte); font-weight: var(--texte-graisse);
  font-size: 12px; line-height: 20px; color: var(--vert);
  white-space: nowrap;
}

.fiche__entete { display: flex; flex-flow: column; gap: 16px; }
.fiche__note {
  display: flex; justify-content: space-between; align-items: center;
  height: 20px; margin: 0 0 -4px;
}
.fiche__etoiles { display: flex; gap: 4px; align-items: center; margin: 0; }
.fiche__etoiles img { display: block; }
.fiche__etoiles span,
.fiche__partager span {
  font-family: var(--texte); font-weight: var(--texte-graisse);
  font-size: 12px; line-height: 20px; color: var(--vert);
}
.fiche__partager { display: flex; gap: 8px; align-items: center; text-decoration: none; }
.fiche__partager img { display: block; }

/* Calque « Product Info Title » : Millave 32, interligne 38,4. */
.fiche__titre {
  font-size: 32px; line-height: 38.4px; color: var(--vert);
  margin: 0; text-transform: uppercase;
}

/* Le prix et sa pastille de conditionnement, écartés de 16 sur 40 px de haut.
   Le bloc s'arrête à son contenu — 281,8 px chez l'original, pas la colonne. */
.fiche__prix {
  display: flex; gap: 16px; align-items: center;
  height: 40px; margin: 0; width: max-content; max-width: 100%;
}
.fiche__prix strong {
  font-family: var(--titre); font-weight: var(--titre-graisse);
  font-size: 24px; line-height: 24px; color: var(--vert);
}
.fiche__format {
  display: flex; gap: 6px; align-items: center; padding: 9px 15px;
  border: 1px solid var(--or); border-radius: 74px;
  font-family: var(--texte); font-weight: var(--texte-graisse);
  font-size: 12px; line-height: 20px; color: var(--vert);
  white-space: nowrap;
}
.fiche__format img { display: block; }
/* Les promotions annoncées — nuit du 12 au 13 septembre 2026. Le prix de
   référence barré, en texte courant et atténué, devant le prix payé ; la
   mention de l'offre sous le prix, dans le brun des lignes offertes. Rien de
   cela n'est rendu sans promotion. */
.fiche__barre {
  font-family: var(--texte); font-weight: var(--texte-graisse);
  font-size: 16px; line-height: 24px; color: rgb(4 50 37 / .6);
  white-space: nowrap;
}
.fiche__prix .fiche__barre + strong { margin-left: -8px; }
.fiche__promo {
  margin: -6px 0 0;
  font-family: var(--texte); font-weight: var(--texte-graisse);
  font-size: 13px; line-height: 18px; color: var(--brun);
}
.fiche__filet { border: 0; border-top: 1px solid var(--or); margin: 0; }

.fiche__desc { display: flex; flex-flow: column; gap: 16px; width: 100%; }
.fiche__desc > p {
  font-family: var(--texte); font-weight: var(--texte-graisse);
  font-size: 14px; line-height: 16px; color: var(--vert); margin: 0;
}
/* Les trois avantages : lignes de 24 px, retraits 4 / 0, écart 12 avec l'icône. */
.fiche__avantages { display: flex; flex-flow: column; margin: 0; }
.fiche__avantages li { display: flex; gap: 12px; align-items: center; padding: 4px 0; height: 24px; }
.fiche__avantages img { display: block; flex: none; }
.fiche__avantages span {
  font-family: var(--texte); font-weight: var(--texte-graisse);
  font-size: 14px; line-height: 16px; color: var(--vert);
}

/* -- achat -- */
.fiche__achat { display: flex; flex-flow: column; gap: 24px; width: 100%; }

/* Les trois conditionnements : boutons de 142,3 × 66, écartés de 9. La remise
   déborde par le haut, ce qui demande une réserve au-dessus de la rangée. */
.fiche__offres { display: flex; gap: 9px; height: 66px; }
.pack {
  position: relative; flex: 1 1 0; min-width: 0;
  display: flex; flex-flow: column; justify-content: center; align-items: center; gap: 0;
  height: 66px; padding: 0; cursor: pointer;
  background: none; border: 1px solid var(--or); border-radius: 9999px;
  transition: background-color .2s ease, border-color .2s ease;
}
.pack.est-actif { background: var(--rose); border-color: var(--rose); }
.pack[disabled] { opacity: .45; cursor: not-allowed; }
.pack__label {
  font-family: var(--texte); font-weight: var(--texte-graisse);
  font-size: 12px; line-height: 12px; color: var(--vert);
}
.pack__prix {
  font-family: var(--titre); font-weight: var(--titre-graisse);
  font-size: 18px; line-height: 18px; color: var(--vert);
}
.pack__remise {
  position: absolute; top: -9px; left: 50%; transform: translateX(-50%);
  display: flex; justify-content: center; align-items: center;
  width: 40px; height: 20px; border-radius: 100px;
  background: rgb(4, 51, 38); color: #F2F2F3;
  font-family: var(--texte); font-weight: var(--texte-graisse);
  font-size: 12px; line-height: 12px;
}
/* Le prix de référence d'un conditionnement réduit par une promotion
   automatique, sous son prix — nuit du 12 au 13 septembre 2026. */
/* Posé en bas du bouton, hors du flux : le libellé et le prix restent centrés
   comme sur les deux autres, et ne remontent pas sous la pastille de remise. */
.pack__barre {
  position: absolute; left: 0; right: 0; bottom: 5px;
  text-align: center;
  font-family: var(--texte); font-weight: var(--texte-graisse);
  font-size: 11px; line-height: 12px; color: rgb(4 50 37 / .6);
}

/* La ligne d'achat : 68 px, le compteur de 187 puis le bouton qui prend le reste. */
.fiche__ligne { display: flex; align-items: center; height: 68px; width: 100%; }
.quantite {
  display: flex; gap: 13px; justify-content: center; align-items: center;
  flex: none; width: 187px; height: 68px; padding: 0 8px;
  border: 1px solid var(--or); border-radius: 8px; background: var(--creme);
}
.quantite__pas {
  display: flex; justify-content: center; align-items: center;
  width: 32px; height: 32px; padding: 0; cursor: pointer;
  border: 0; border-radius: 8px; background: var(--creme);
  font-size: 20px; line-height: 1; color: var(--vert);
}
.quantite__pas:hover { background: var(--or); }
.quantite__valeur {
  width: 40px; padding: 0; border: 0; background: none; text-align: center;
  font-family: var(--titre); font-weight: var(--titre-graisse);
  font-size: 18px; line-height: 25px; color: #000;
  -moz-appearance: textfield; appearance: textfield;
}
.quantite__valeur::-webkit-outer-spin-button,
.quantite__valeur::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
/* Le bouton d'achat porte son sac à l'intérieur, retraits 0 / 24 — et non
   accolé au dehors comme les boutons des autres sections. */
.fiche__ajouter {
  flex: 1 1 auto; height: 68px; width: auto; margin-right: 0;
  gap: 13px; padding: 0 24px; justify-content: center;
}
.fiche__ajouter::after {
  position: static; transform: none; flex: none;
  width: 16px; height: 19.4px; border-radius: 0;
  background-color: transparent; background-size: contain;
}
.fiche__ajouter:hover::after { background-color: transparent; }

/* Téléphone : les deux colonnes s'empilent, écartées de 30. La galerie devient
   un carrousel que l'on fait glisser au doigt, les vignettes lui servant de
   puces sous la piste. Relevé : section de 1 100,4 px à 360, retraits 112 / 12,
   colonne de gauche 388, colonne de droite 570,4. */
@media (max-width: 809.98px) {
  /* Marge haute divisée par deux 112 → 56 px sur téléphone — 16 septembre
     2026, à la demande du marchand (comme le hero), pour resserrer le vide
     sous l'en-tête. */
  .fiche { padding: 56px 12px 0; }
  .fiche__inner { width: 100%; }
  .fiche__cols { flex-flow: column; gap: 30px; }
  .fiche__gauche, .fiche__droite { width: 100%; }
  .fiche__gauche { gap: 0; }

  .galerie { flex-flow: column-reverse; gap: 0; }
  .galerie__grande {
    display: flex; width: 100%;
    overflow-x: auto; scroll-snap-type: x mandatory;
    scrollbar-width: none;
  }
  .galerie__grande::-webkit-scrollbar { display: none; }
  .galerie__grande > li { display: block; flex: 0 0 100%; scroll-snap-align: center; }
  /* Les vignettes deviennent les puces de la piste. */
  .galerie__vignettes {
    flex-flow: row; justify-content: center; gap: 8px;
    width: 100%; height: 32px; align-items: center;
  }
  .galerie__vignette { width: 8px; height: 8px; border-radius: 50%; background: var(--or); opacity: .35; }
  .galerie__vignette.est-active { opacity: 1; outline: 0; }
  .galerie__vignette img { display: none; }
  /* Les flèches, posées par le script sur l'image carrée — 22 septembre 2026,
     demande du marchand : un carrousel qui se clique, pas seulement au doigt.
     Celles des champignons de l'accueil : boîte de 40, voile noir à 20 %,
     20 px des bords, centrées en hauteur (`.carousel-nav__btn`). */
  .galerie { position: relative; }
  .galerie__nav {
    display: flex; align-items: center; justify-content: space-between;
    position: absolute; top: 0; left: 0; right: 0; aspect-ratio: 1 / 1;
    padding: 0 20px; pointer-events: none;
  }
  .galerie__nav .carousel-nav__btn { pointer-events: auto; }

  .fiche__labels { gap: 16px; height: 20px; }
  .fiche__labels img { height: 20px; }
  .fiche__labels span { font-size: 12px; }

  /* Les rubriques passent à la ligne — deux rangées de 26 px écartées de 10 —
     et leur texte tombe de 12 / 20 à 10 / 10. */
  .fiche__tags { flex-wrap: wrap; height: auto; gap: 10px; }
  .fiche__tags li { height: 26px; padding: 7px 11px; font-size: 10px; line-height: 10px; }
  /* Le prix reprend toute la largeur, sur 46 px. */
  .fiche__prix { width: 100%; height: 46px; }
}

/* ---------- fiche produit — « qu'y a-t-il à l'intérieur » ------------------- */

/* Calque « Nutritional Information » : 1440 × 1138,3, retraits 144 / 0 / 39.
   Un bloc de 1 111 centré, une colonne de 344,4 à gauche et une grille de deux
   cartes de 367,3 × 453,7 à droite, écartées de 48 en hauteur et 32 en largeur. */
.dedans { background: var(--creme); }
.dedans__inner {
  width: 1111px; max-width: 100%; margin-inline: auto;
  padding: 144px 0 39px;
}
/* Gouttière entre le tableau nutritionnel (colonne de gauche) et les cartes
   d'ingrédients — 16 septembre 2026. À `gap: 0`, le panneau blanc collait aux
   cartes une fois déployé ; l'ancienne petite image ne le montrait pas. */
.dedans__cols { display: flex; gap: 48px; align-items: flex-start; }
.dedans__gauche { display: flex; flex-flow: column; gap: 39px; width: 344.4px; flex: none; }
.dedans__titre {
  font-size: 36px; line-height: 43.2px; text-transform: uppercase;
  color: var(--vert); margin: 0;
}
/* Le tableau et sa légende, écartés de 18 sur une colonne de 209. */
/* Tableau nutritionnel en HTML — 16 septembre 2026. Il remplace l'image plate
   `fiche-nutrition.webp` (police système, traits noirs) par un panneau aux
   couleurs du site : blanc sur le crème de la section, encre verte, Jost. Net à
   tout zoom, lisible au téléphone (où l'image était masquée), accessible. */
/* Le tableau nutritionnel replié derrière un bouton — 16 septembre 2026,
   demande du marchand : il ne s'ouvre que sur clic et se détache du reste.
   `<details>` natif, sans JavaScript, accessible au clavier. */
.valeurs-repli { margin-top: 4px; }
.valeurs-repli__bouton {
  display: inline-flex; align-items: center; gap: 9px;
  cursor: pointer; list-style: none; user-select: none;
  font-family: var(--texte); font-weight: 600; font-size: 14px;
  color: var(--vert); background: var(--blanc);
  border: 1px solid rgb(4 50 37 / .2); border-radius: 999px;
  padding: 11px 20px;
  transition: background .15s ease, border-color .15s ease;
}
.valeurs-repli__bouton::-webkit-details-marker { display: none; }
.valeurs-repli__bouton::after {
  content: ""; width: 8px; height: 8px; margin-top: -3px;
  border-right: 2px solid currentColor; border-bottom: 2px solid currentColor;
  transform: rotate(45deg); transition: transform .2s ease;
}
.valeurs-repli[open] > .valeurs-repli__bouton::after { transform: rotate(-135deg); margin-top: 3px; }
.valeurs-repli[open] > .valeurs-repli__bouton { margin-bottom: 16px; }
.valeurs-repli__bouton:hover { background: var(--creme); border-color: rgb(4 50 37 / .38); }
.valeurs-repli__bouton:focus-visible { outline: 2px solid var(--vert); outline-offset: 2px; }

.valeurs {
  width: 100%; max-width: 360px; box-sizing: border-box;
  background: var(--blanc);
  border: 1px solid rgb(4 50 37 / .14);
  border-radius: 18px;
  padding: 20px 22px 18px;
  color: var(--vert);
  font-family: var(--texte);
}
.valeurs__titre {
  margin: 0 0 10px;
  font-family: var(--titre); font-weight: var(--titre-graisse);
  font-size: 22px; line-height: 1.1;
}
.valeurs__intro { margin: 0 0 8px; font-size: 13px; line-height: 1.45; }
.valeurs__intro strong { font-weight: 600; }
.valeurs__note { color: rgb(4 50 37 / .6); }
.valeurs__diet { margin: 0 0 14px; font-size: 12.5px; line-height: 1.5; color: rgb(4 50 37 / .78); font-style: italic; }
.valeurs__table { width: 100%; border-collapse: collapse; font-size: 13px; }
.valeurs__table + .valeurs__table { margin-top: 6px; }
.valeurs__table th, .valeurs__table td {
  padding: 7px 0; vertical-align: top;
  border-bottom: 1px solid rgb(4 50 37 / .1);
}
.valeurs__table thead th {
  text-align: right; font-weight: 600; font-size: 11px;
  text-transform: uppercase; letter-spacing: .04em;
  border-bottom: 1.5px solid rgb(4 50 37 / .28); padding-bottom: 5px;
}
.valeurs__table thead th:first-child { text-align: left; }
.valeurs__table tbody th { text-align: left; font-weight: 500; padding-right: 10px; }
.valeurs__table td {
  text-align: right; font-variant-numeric: tabular-nums;
  white-space: nowrap; padding-left: 8px; width: 1%;
}
.valeurs__sous th { padding-left: 12px; font-weight: 400; font-style: italic; color: rgb(4 50 37 / .7); }
.valeurs__prec { display: block; font-weight: 400; font-style: italic; font-size: 11px; color: rgb(4 50 37 / .6); }
.valeurs__pied { margin: 12px 0 0; font-size: 11.5px; line-height: 1.5; color: rgb(4 50 37 / .66); }

/* Version compacte au téléphone — 16 septembre 2026 : à pleine taille le
   panneau dépassait 1100 px (plus d'un écran). Ici typo et interlignes
   resserrés pour tenir en une hauteur d'écran, sans rien retirer de
   l'étiquette. Un plafond de hauteur + défilement interne sert de garde-fou
   sur les très petits écrans. */
@media (max-width: 809.98px) {
  .valeurs { padding: 15px 16px 13px; max-height: 94vh; overflow-y: auto; }
  .valeurs__titre { font-size: 18px; margin-bottom: 6px; }
  .valeurs__intro { font-size: 11.5px; line-height: 1.35; margin-bottom: 6px; }
  .valeurs__diet  { font-size: 10.5px; line-height: 1.4; margin-bottom: 9px; }
  .valeurs__table { font-size: 11.5px; }
  .valeurs__table th, .valeurs__table td { padding: 2.5px 0; }
  /* Écart franc entre les deux colonnes de valeurs : trop serrées, « 13kcal »
     et « 163kcal » se touchaient. En-têtes non coupés. */
  .valeurs__table td { padding-left: 16px; }
  .valeurs__table thead th { font-size: 9.5px; padding-bottom: 3px; white-space: nowrap; }
  .valeurs__prec  { font-size: 9.5px; }
  .valeurs__pied  { margin-top: 8px; font-size: 10px; line-height: 1.45; }
}

.dedans__grille {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 48px 32px; margin: 0; flex: 1 1 auto; min-width: 0;
}
/* Chaque carte : image en fond, nom puis texte calé en bas, retraits 20 / 26. */
/* « min-width: 0 » : un élément de grille prend par défaut la largeur de son
   mot le plus long, ce qui faisait déborder la carte de 14 px au téléphone. */
.dedans__carte {
  position: relative; display: flex; flex-flow: column;
  height: 453.7px; padding: 20px 26px; overflow: clip;
  min-width: 0; width: 100%;
}
.dedans__carte-fond {
  position: absolute; inset: 0; z-index: 0;
  width: 100%; height: 100%; max-width: none; object-fit: cover;
}
.dedans__carte-nom, .dedans__carte-texte { position: relative; z-index: 1; }
.dedans__carte-nom {
  font-size: 28px; line-height: 28px; text-transform: uppercase;
  color: var(--vert); margin: 0;
}
.dedans__carte-texte { margin-top: auto; padding-top: 14px; }
.dedans__carte-texte p {
  font-family: var(--texte); font-weight: var(--texte-graisse);
  font-size: 16px; line-height: 17.6px; color: var(--vert); margin: 0;
}

/* Téléphone : une seule colonne, le titre seul en tête et les quatre cartes
   empilées, écartées de 12. Le tableau nutritionnel disparaît — l'original ne
   le montre pas à cette largeur, où il serait illisible. */
@media (max-width: 809.98px) {
  .dedans__inner { width: 100%; padding: 33px 12px 12px; }
  .dedans__cols { flex-flow: column; gap: 40px; }
  .dedans__gauche { width: 100%; gap: 18px; }
  .dedans__titre { font-size: 33px; line-height: 39.6px; }
  /* Une pile plutôt qu'une grille d'une colonne : en grille, les cartes autres
     que la première prenaient la largeur de leur mot le plus long et débordaient
     de 14 px. En flex, « min-width: 0 » suffit à les contenir. */
  .dedans__grille { display: flex; flex-flow: column; gap: 12px; width: 100%; }
  .dedans__carte { height: 415px; }
}

/* ---------- fiche produit — la frise des effets ----------------------------- */

/* Calque « 3 » : 1440 × 597,6, retraits 144 / 0 / 39. Un cadre de 1 111 avec un
   filet doré, retraits 64 / 0, et trois blocs écartés de 40 : les jalons, la
   ligne qui les relie, puis les parts. */
.frise { background: var(--creme); }
.frise__inner { padding: 144px 0 39px; }
.frise__cadre {
  width: 1111px; max-width: 100%; margin-inline: auto;
  display: flex; flex-flow: column; align-items: center; gap: 40px;
  padding: 64px 0; border: 1px solid var(--or);
}
.frise__jalons, .frise__parts { display: flex; justify-content: space-between; margin: 0; }
.frise__jalons { width: 622px; max-width: 100%; }
.frise__jalons li { display: flex; flex-flow: column; gap: 7px; align-items: center; }
.frise__jalons strong, .frise__parts strong {
  font-family: var(--titre); font-weight: var(--titre-graisse);
  font-size: 32px; line-height: 32px; color: var(--vert);
}
.frise__jalons span {
  font-family: var(--titre); font-weight: var(--titre-graisse);
  font-size: 16px; line-height: 16px; color: var(--vert); text-transform: uppercase;
}

/* Le trait et ses trois points, aux mêmes abscisses que les jalons. */
.frise__ligne {
  position: relative; width: 587px; max-width: 100%; height: 16px;
  display: flex; justify-content: space-between; align-items: center;
}
.frise__ligne::before {
  content: ""; position: absolute; left: 0; right: 0; top: 50%;
  height: 1px; background: var(--or);
}
.frise__ligne span {
  position: relative; width: 10px; height: 10px; border-radius: 50%;
  background: var(--or);
}

.frise__parts { width: 722px; max-width: 100%; align-items: flex-start; }
.frise__parts li {
  display: flex; flex-flow: column; gap: 7px; align-items: center;
  width: 152px; text-align: center;
}
.frise__parts p {
  font-family: var(--texte); font-weight: var(--texte-graisse);
  font-size: 14px; line-height: 16.1px; color: var(--vert); margin: 0;
}

/* Téléphone : la frise bascule à la verticale — les jalons en colonne à gauche,
   la ligne au milieu, les parts à droite. Retraits 20 / 12 / 32, cadre à
   64 px du haut, les trois blocs écartés de 28. */
@media (max-width: 809.98px) {
  .frise__inner { padding: 20px 12px 32px; }
  .frise__cadre { width: 100%; flex-flow: row; align-items: stretch; gap: 28px; padding: 64px 0 0; }
  .frise__jalons {
    flex-flow: column; justify-content: flex-start; gap: 97px;
    width: 51px; flex: none;
  }
  .frise__ligne {
    flex-flow: column; width: 16px; height: auto; flex: none;
    padding-top: 8px; justify-content: flex-start; gap: 165px;
  }
  .frise__ligne::before {
    left: 50%; right: auto; top: 0; bottom: 0;
    width: 1px; height: auto; transform: translateX(-50%);
  }
  .frise__parts { flex-flow: column; gap: 23px; width: 190px; flex: 1 1 auto; }
  .frise__parts li { width: 100%; gap: 18px; }
}

/* ---------- pages éditoriales ------------------------------------------------------ */

.prose { padding-block: clamp(2rem, 5vw, 3.5rem); }
/* Marge haute resserrée au téléphone : 32 → 16 px — 16 septembre 2026, à
   la demande du marchand (comme le hero), pour remonter le contenu sous
   l'en-tête. Le bas garde son clamp. */
@media (max-width: 809.98px) { .prose { padding-top: 16px; } }
/* Colonne unique et centrée, à la largeur relevée sur l'original : 900 px, plus
   les gouttières du « shell » qui la bordent — l'original la centre lui aussi,
   à x=500 sur une fenêtre de 1900. Elle passe à 300 px en dessous de 1026 chez
   lui ; ici la colonne reste fluide tant que les pages annexes n'ont pas été
   reprises au téléphone.

   Un « max-width: 68ch » par bloc, comme avant, les faisait diverger : chacun
   l'exprimait en « ch » de son propre corps, si bien qu'un titre faisait 1 328
   px là où un paragraphe en faisait 595. Aligné à gauche cela ne se voyait pas ;
   centré, cela aurait formé un escalier. */
.shell.prose { max-width: calc(900px + 2 * var(--gouttiere)); }
.prose h1 { font-size: var(--t-2xl); margin-bottom: .6em; }
.prose h2 { font-size: var(--t-xl); margin: 2em 0 .5em; }
.prose h3 { font-size: var(--t-md); margin: 1.6em 0 .4em; }
.prose p, .prose li { font-size: var(--t-sm); line-height: 1.6; }
.prose ul { list-style: disc; padding-left: 1.2rem; margin-bottom: 1.1em; }
.prose li { margin-bottom: .4em; }
.lead { font-size: var(--t-md); }

/* ---------- formulaire de contact ------------------------------------------

   La structure est celle de l'original — même ordre, mêmes champs, mêmes
   proportions entre les pièces — mais **l'échelle est la nôtre**, à la demande.

   Chez lui le bloc est figé à 280 × 500 avec des champs de 240, identiques aux
   quatre points de rupture : Framer ne l'adapte jamais. Posé au milieu d'une
   colonne de texte de 900 px, cela fait timbre-poste, et une boîte de 40 px de
   haut passe sous le minimum de 44 px recommandé pour une cible tactile.

   Tout part donc de six variables, redéfinies par plage. Le bloc grandit tant
   qu'il y a de la place et retombe sur la largeur disponible quand il n'y en a
   plus : « min(100%, …) » fait que rien ne déborde jamais, y compris à 360.

   Deux écarts assumés, signalés :
   - la typographie est la nôtre (Jost) et non l'Inter de l'original, comme sur
     toutes les pages annexes ;
   - le bouton garde le gris #333 de l'original. C'est le gris par défaut de
     Framer, pas une couleur de la marque : le passer au rose se ferait en
     changeant cette seule ligne. */
.formulaire {
  /* Les valeurs du téléphone. Les plages plus larges ne font que les relever. */
  --form-largeur: 420px;
  --form-retrait: 22px;
  /* Aucun retrait latéral au téléphone : le bloc y occupe toute la colonne, et
     un retrait décalerait les champs de 22 px par rapport aux paragraphes qui
     les précèdent. Au-dessus de 810 le bloc est plus étroit que la colonne et
     l'alignement ne se pose plus. */
  --form-retrait-h: 0px;
  --form-ecart: 22px;
  --form-tete: 12px;      /* l'air au-dessus du premier libellé */
  --form-libelle: 13px;
  --form-boite: 50px;
  --form-zone: 150px;
  --form-texte: 15px;
  --form-rayon: 12px;

  width: min(100%, var(--form-largeur));
  margin-inline: auto;
  padding: var(--form-retrait) var(--form-retrait-h);
  display: flex;
  flex-direction: column;
  gap: var(--form-ecart);
}

/* Tablette : le bloc a de la place, la colonne de texte n'est pas encore large. */
@media (min-width: 810px) {
  .formulaire {
    --form-largeur: 520px;
    --form-retrait: 28px;
    --form-retrait-h: 28px;
    --form-ecart: 26px;
    --form-tete: 16px;
    --form-libelle: 14px;
    --form-boite: 54px;
    --form-zone: 170px;
    --form-texte: 16px;
  }
}

/* Ordinateur : la colonne fait 900 px, le formulaire peut en prendre 600 sans
   se détacher du texte qui le précède — il reste plus étroit que lui. */
@media (min-width: 1026px) {
  .formulaire {
    --form-largeur: 600px;
    --form-retrait: 32px;
    --form-retrait-h: 32px;
    --form-ecart: 28px;
    --form-tete: 18px;
    --form-boite: 56px;
    --form-zone: 190px;
    --form-rayon: 14px;
  }
}

.formulaire__champ {
  display: flex;
  flex-direction: column;
  gap: 10px;
  width: 100%;
}
/* L'air que l'original pose au-dessus du seul premier champ. */
.formulaire__champ:first-of-type { padding-top: var(--form-tete); }

.formulaire__libelle {
  font-family: var(--texte);
  font-weight: 600;
  font-size: var(--form-libelle);
  line-height: 1.2;
  letter-spacing: .02em;
  color: var(--vert);
}
.formulaire__boite {
  display: block;
  height: var(--form-boite);
  border-radius: var(--form-rayon);
  background: rgb(4 50 37 / .07);
  transition: background-color .15s;
}
.formulaire__boite--haute { height: var(--form-zone); }
.formulaire__boite:hover { background: rgb(4 50 37 / .1); }

.formulaire__boite input,
.formulaire__boite textarea {
  width: 100%;
  height: 100%;
  padding: 0 16px;
  border: 0;
  border-radius: inherit;
  background: none;
  font-family: var(--texte);
  font-weight: var(--texte-graisse);
  font-size: var(--form-texte);
  line-height: 1.5;
  color: var(--vert);
}
/* Une zone de texte n'a pas de centrage vertical : son retrait est complet. */
.formulaire__boite textarea {
  padding: 14px 16px;
  resize: vertical;
  display: block;
}
.formulaire__boite input::placeholder,
.formulaire__boite textarea::placeholder { color: rgb(4 50 37 / .45); }
/* Le contour du navigateur ne se voit pas sur un fond aussi pâle : il faut le
   reposer, sinon la navigation au clavier devient aveugle. */
.formulaire__boite:focus-within {
  outline: 2px solid var(--vert);
  outline-offset: 2px;
  background: rgb(4 50 37 / .1);
}
.formulaire__boite input:focus,
.formulaire__boite textarea:focus { outline: none; }

.formulaire__envoi {
  width: 100%;
  height: var(--form-boite);
  margin-top: 4px;
  border: 0;
  border-radius: var(--form-rayon);
  background: #333;
  color: #fff;
  font-family: var(--texte);
  font-weight: 600;
  font-size: var(--form-texte);
  letter-spacing: .02em;
  cursor: pointer;
  transition: background-color .15s;
}
.formulaire__envoi:hover { background: #1f1f1f; }

.formulaire__erreur {
  font-family: var(--texte);
  font-size: calc(var(--form-libelle) - 1px);
  line-height: 1.35;
  color: #A3231C;
}
.formulaire__boite:has(input[aria-invalid], textarea[aria-invalid]) {
  box-shadow: inset 0 0 0 1px #A3231C;
}

/* L'issue de l'envoi, au-dessus du formulaire et à sa largeur : elle suit donc
   la même échelle sans qu'il faille la redire par plage. */
.formulaire__mot {
  width: min(100%, var(--form-largeur, 420px));
  margin: 2rem auto 0;
  padding: 14px 18px;
  border-radius: 12px;
  font-family: var(--texte);
  font-size: var(--t-xs);
  line-height: 1.5;
}
.formulaire__mot--merci { background: rgb(4 50 37 / .1); color: var(--vert); }
.formulaire__mot--echec { background: rgb(163 35 28 / .1); color: #A3231C; }

/* Les champs-leurres. « display: none » suffirait à les cacher, mais certains
   automates ignorent ce qui n'est pas rendu : le décalage hors champ les laisse
   dans la page tout en les gardant invisibles et inatteignables. */
.formulaire__leurres {
  position: absolute;
  left: -9999px;
  width: 1px; height: 1px;
  overflow: hidden;
}

.breadcrumb { font-size: var(--t-xs); margin-bottom: 1.5rem; }
.breadcrumb ol { display: flex; flex-wrap: wrap; gap: .5rem; }
.breadcrumb li + li::before { content: "›"; margin-right: .5rem; }
.breadcrumb a { text-decoration: none; }

.product-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 17rem), 1fr)); gap: 1.5rem; padding-block: 2rem; }
.product-card { display: flex; flex-direction: column; gap: .7rem; padding: 1rem; background: var(--creme-pale); border-radius: var(--rayon); }
.product-card__image { aspect-ratio: 4 / 5; object-fit: cover; border-radius: var(--rayon); }
.product-card__title { font-size: var(--t-md); }
.product-card__form { display: flex; gap: .6rem; align-items: center; flex-wrap: wrap; margin-top: auto; }
.qty { width: 4.4rem; padding: .5rem; border: 1px solid var(--vert); border-radius: var(--rayon); font: inherit; }

.cart-table { width: 100%; border-collapse: collapse; margin: 2rem 0; font-size: var(--t-sm); }
.cart-table th, .cart-table td { text-align: left; padding: .8rem .6rem .8rem 0; border-bottom: 1px solid rgba(4,50,37,.25); vertical-align: top; }
.cart-table__qty { display: flex; gap: .4rem; align-items: center; flex-wrap: wrap; }
.notice { padding: 1rem 1.2rem; border-radius: var(--rayon); background: var(--creme-pale); }
.figure { margin: 2rem 0; }

/* ---------- préférences ------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation-duration: .01ms !important; transition-duration: .01ms !important; }
}
@media print { .site-header, .site-footer, .pill, .skip-link { display: none; } body { color: #000; background: #fff; } }

/* ==========================================================================
   Animations — amélioration progressive.

   Chaque effet part d'un état final visible : sans JavaScript, ou si
   l'utilisateur a demandé moins d'animations, la page reste complète. Rien
   n'est masqué en attendant un script.
   ========================================================================== */

/* Apparition au défilement. L'état masqué n'est appliqué que si le script a
   pris la main (classe .js) : sinon le contenu reste visible d'emblée. */
.js [data-reveal] {
  opacity: 0;
  transform: translateY(1.6rem);
  transition: opacity .7s cubic-bezier(.22, .61, .36, 1),
              transform .7s cubic-bezier(.22, .61, .36, 1);
}
.js [data-reveal].is-visible { opacity: 1; transform: none; }

/* Décalage en cascade pour les listes. */
.js [data-reveal] > * { transition-delay: 0ms; }
.js [data-reveal].is-visible > :nth-child(2) { transition-delay: 80ms; }
.js [data-reveal].is-visible > :nth-child(3) { transition-delay: 160ms; }

/* Bande photo défilante. La piste est dupliquée par le script ; l'animation
   translate la paire de moitié, ce qui boucle sans saut visible. */
/* En défilement, la rangée reste à la largeur de la fenêtre et coupe : ce
   sont les deux pistes qui glissent à l'intérieur. Lui donner « max-content »
   la faisait déborder de 1 094 px et élargissait toute la page.

   La vitesse de l'original est de 30 px/s, relevée identique sur les trois
   pistes de la page et à toutes les largeurs — c'est une constante de son
   composant, pas une durée fixe. La durée se déduit donc du parcours. */
.strip-row.is-running { display: flex; gap: 10px; }
.strip-row.is-running .strip {
  flex: none;
  animation: defilement calc(var(--cycle) / 30 * 1s) linear infinite;
}
.strip-row.is-running[data-sens="droite"] .strip { animation-name: defilement-droite; }
.strip-row.is-running:hover .strip { animation-play-state: paused; }
/* La seconde rangée n'existe qu'en dessous de 1026 px, comme chez l'original.
   Le masquage vient après « .strip-row.is-running » : à spécificité égale c'est
   l'ordre qui tranche, et le script repose un display en ajoutant cette classe. */
.strip-wrap .strip-row--retour { display: none; }
@media (max-width: 1025.98px) { .strip-wrap .strip-row--retour { display: flex; } }
@keyframes defilement {
  from { transform: translateX(0); }
  to { transform: translateX(calc(-100% - 10px)); }
}

/* Carrousel des fiches champignons. Sans script les trois restent empilées. */
.pill, .carousel-nav__btn, .site-nav a { transition: background-color .2s ease, color .2s ease, transform .2s ease; }
.pill:active { transform: translateY(1px); }
.product-card { transition: transform .3s ease; }
.product-card:hover { transform: translateY(-3px); }

@media (prefers-reduced-motion: reduce) {
  .js [data-reveal] { opacity: 1; transform: none; transition: none; }
  .strip-row.is-running .strip { animation: none; }
  .hero__dome-media img { transition: none; }
}


/* ---------- page « à propos » -----------------------------------------------
   Quatre sections, relevées calque par calque dans le rendu de l'original à
   1440, 900 et 360 px. Ce n'est pas une page éditoriale : elle a sa propre
   composition, sa vidéo, ses deux vagues et son dégradé.

   Les hauteurs de section sont fermes sur ordinateur — 1928, 973, 956, 790 à
   1440 comme à 1200 — et libres en dessous de 1026, où l'original les laisse
   suivre le contenu.                                                          */

.propos { display: block; }

/* ----- héro : 1440 × 1928, fond vert d'encre ----- */
.propos__hero {
  position: relative;
  height: 1928px;
  background: var(--vert);
  overflow: hidden;
}
/* La photo déborde de 47 px vers le haut et s'arrête 129 px avant le bas : le
   vert n'apparaît que sous elle, derrière la citation. */
.propos__hero-fond {
  position: absolute; top: -47px; left: 0;
  width: 100%; height: 1799px; max-width: none;
  object-fit: cover; object-position: center;
  z-index: 0;
}
/* Calque « Overlay gradient » : 1440 × 400 posé à 1376. Il détache la citation
   du fond photographique sans assombrir la moitié haute. */
.propos__hero-degrade {
  position: absolute; left: 0; right: 0; top: 1376px; height: 400px;
  z-index: 1; pointer-events: none;
  background: linear-gradient(to bottom, rgb(4 50 37 / 0) 0%, var(--vert) 100%);
}
.propos__hero-inner {
  position: relative; z-index: 2;
  padding: 197px 20px;
  display: flex; flex-flow: column; align-items: center;
}

/* Titre : Millave 47/47, vert d'encre, centré. L'original lui donne 516 px et
   coupe après « Reconnectez-vous. ». Playfair Display demande 528 px pour cette
   première ligne : à 516 elle passait à la ligne au trait d'union et le titre se
   lisait « RECONNECTEZ- / VOUS. VRAIMENT. ». La boîte est portée à 560 — assez
   pour la première ligne, trop peu pour que « Vraiment. » (815 au total) la
   rejoigne. Le texte étant centré, seul le point de coupure change. */
.propos__titre {
  width: 560px; max-width: 100%; margin: 0;
  /* Les titres du site sont en `text-wrap: balance`, qui égalise la longueur
     des lignes : il coupait « RECONNECTEZ- / VOUS. VRAIMENT. » parce que c'est
     plus équilibré que 530 / 271. L'original coupe après la phrase. */
  text-wrap: wrap;
  font-family: var(--titre); font-weight: var(--titre-graisse);
  font-size: 47px; line-height: 47px;
  text-transform: uppercase; text-align: center;
  color: var(--vert);
}
.propos__lead {
  width: 538px; max-width: 100%; margin: 13px 0 0;
  font-family: var(--texte); font-weight: var(--texte-graisse);
  font-size: 18px; line-height: 18px; text-align: center;
  color: var(--vert);
}

/* Vidéo à gauche, rubriques à droite, centrées l'une sur l'autre : le milieu
   de la vidéo et celui du bloc de texte tombent tous deux à 715 px. */
.propos__duo {
  margin-top: 138px;
  width: 920px; max-width: 100%;
  display: flex; flex-flow: row; align-items: center; gap: 133px;
}
.propos__video {
  flex: none; width: 350px; height: 475px;
  object-fit: cover; display: block;
}
.propos__rubriques { flex: 1 1 auto; min-width: 0; display: flex; flex-flow: column; gap: 44px; }
.propos__rubrique  { display: flex; flex-flow: column; gap: 16px; }
.propos__rubrique-titre {
  margin: 0;
  font-family: var(--titre); font-weight: var(--titre-graisse);
  font-size: 36px; line-height: 36px; text-transform: uppercase;
  color: var(--creme);
}
.propos__rubrique-texte {
  margin: 0;
  font-family: var(--texte); font-weight: var(--texte-graisse);
  font-size: 18px; line-height: 21.6px;
  color: #F2F2F3;
}
/* Le premier paragraphe est serré à 18 px d'interligne, le second à 21,6 :
   ce sont deux réglages distincts chez Framer, pas une régularité. */
.propos__rubrique:first-child .propos__rubrique-texte { line-height: 18px; }

.propos__citation {
  margin: 449px 0 0;
  width: 608px; max-width: 100%;
  font-family: var(--titre); font-weight: var(--titre-graisse);
  font-size: 47px; line-height: 47px;
  text-transform: uppercase; text-align: center;
  color: #F2F2F3;
}

/* ----- les deux blocs à vague ----- */
/* Chaque section forme son propre plan d'empilement. Sans cela, la photo de la
   section rose — posée à `z-index: 2` dans son bloc — passait **devant** la vague
   crème de la section suivante, qui n'est qu'à 1. Chez l'original la vague
   recouvre le bas de la photo et l'entame en biais ; c'est ce que l'utilisateur
   a relevé. Avec `isolation`, les sections se peignent dans l'ordre du document
   et chaque vague passe devant tout ce qui la précède. */
.propos__bloc,
.propos__hero,
.propos__appel { isolation: isolate; }

.propos__bloc { position: relative; }
.propos__bloc--rose  { background: #F7B1BC; height: 973px; }
.propos__bloc--creme { background: var(--creme); height: 956px; }

/* La vague n'est ni centrée ni de taille fixe.

   Sa largeur vaut **139 % de la page** dès que celle-ci dépasse 1440 px, et
   reste à 2004 en dessous — relevé à neuf largeurs : 2004 à 1440, 2085 à 1500,
   2224 à 1600, 2502 à 1800, 2766 à 1990, 3336 à 2400. Je l'avais figée à 2004 :
   au-delà de 1720 px de fenêtre elle ne couvrait plus le bord gauche, et la
   forme se lisait de travers. C'est ce qu'a vu l'utilisateur.

   Son milieu tombe à 62 % de la page, et à 54 % au-dessus de 1920 px — Framer y
   a une variante. Le pourcentage porte sur la section, pas sur `vw` : `vw`
   compte la barre de défilement, la section non. */
.propos__vague {
  position: absolute; top: -130px; left: 62%;
  transform: translateX(-50%);
  width: max(2004px, 139%); height: auto; aspect-ratio: 2004 / 157;
  max-width: none;
  display: block; pointer-events: none; z-index: 1;
}
@media (min-width: 1920px) { .propos__vague { top: -141px; left: 54%; } }

.propos__bloc-inner {
  position: relative; z-index: 2;
  width: 920px; max-width: 100%;
  /* Aucun retrait latéral : le bloc de 920 px porte lui-même ses marges,
     comme chez l'original où le contenu commence exactement à 260. */
  margin-inline: auto; padding: 49px 0 5px;
}
.propos__bloc-titre {
  margin: 0;
  width: 385px; max-width: 100%;
  /* 385 px est la largeur du français. « Qualitätsanspruch » et
     « kwaliteitsnorm » sont des mots que rien ne coupe : sans plancher à
     `min-content`, ils sortaient de la boîte de 318 et 212 px. */
  min-width: min-content;
  font-family: var(--titre); font-weight: var(--titre-graisse);
  font-size: 62px; line-height: 62px; text-transform: uppercase;
  color: var(--vert);
}
.propos__bloc-corps {
  margin-top: 59px;
  display: flex; flex-flow: row; align-items: flex-start; gap: 119px;
}
.propos__bloc-image {
  flex: none; width: 451px; height: 676px;
  object-fit: cover; display: block;
}
.propos__bloc-texte {
  margin: 0;
  font-family: var(--texte); font-weight: var(--texte-graisse);
  font-size: 18px; line-height: 23.94px;
  color: var(--vert-encre);
}

/* « Regardons vers l'avenir » : une seule colonne de 540 px centrée, l'image
   dessous et non à côté. */
.propos__bloc-inner--colonne {
  width: 540px;
  padding: 144px 0 57px;
  display: flex; flex-flow: column;
}
.propos__bloc-inner--colonne .propos__bloc-titre  { width: 100%; }
.propos__bloc-inner--colonne .propos__bloc-texte  { margin-top: 32px; }
.propos__bloc-image--large {
  width: 540px; height: 398px; margin-top: 57px; max-width: 100%;
}

/* ----- appel à l'achat ----- */
.propos__appel { position: relative; background: var(--creme); height: 790px; }
.propos__appel-inner { position: relative; height: 100%; }
.propos__appel-image {
  position: absolute; top: 144px; left: 50%; transform: translateX(-50%);
  width: 1110px; height: 590px; max-width: none;
  object-fit: cover; display: block;
}
/* La pastille chevauche la photo : 126 px au-dessus de son bord bas.

   Même construction que celle de la bannière de l'accueil : le corps fait 232 px
   et le cercle 68, posé à −8 px du bord — l'ensemble tient dans les 300 px que
   mesure la pastille de l'original. Le décalage de moitié porte donc sur 300, pas
   sur 232. */
.propos__appel-pastille {
  position: absolute; top: 608px; left: 50%; margin-left: -150px; transform: none;
  width: 232px; height: 68px; margin-right: 68px;
  display: grid; place-items: center; padding: 0;
  z-index: 2;
}
.propos__appel-pastille::after {
  left: calc(100% - 8px); width: 68px; height: 68px;
  background-size: 16px 19.4px;
}

/* ----- plage 1026-1439 : mêmes hauteurs, largeurs resserrées ----- */
/* Sous 1440 px les blocs de 920 et 540 pourraient toucher le bord : on leur
   redonne une marge, sans toucher à leur largeur. */
@media (min-width: 1026px) and (max-width: 1439.98px) {
  .propos__bloc-inner { max-width: calc(100% - 40px); }
}

/* ----- tablette : une seule colonne, comme le héro de l'accueil -----
   L'original y passe en pleine largeur — 836 px de texte dans une fenêtre de
   900 — et empile la vidéo au-dessus des rubriques. Les hauteurs deviennent
   libres. */
@media (max-width: 1025.98px) {
  .propos__hero { height: auto; }
  /* La photo ne remplit pas le héro : elle s'arrête avant, et le vert d'encre
     apparaît derrière la citation. Hauteurs relevées chez l'original — 2938 à
     900 px de fenêtre, 2126 à 360 — ce ne sont ni un rapport conservé ni une
     proportion de la fenêtre : c'est une hauteur posée, la photo étant
     recadrée. */
  .propos__hero-fond { height: 2938px; }
  /* Le dégradé finit au bas de la photo, pas à une distance fixe du haut. */
  .propos__hero-degrade { top: 2496px; }
  .propos__hero-inner { padding: 163px 32px 113px; }
  .propos__duo { width: 100%; flex-flow: column; align-items: stretch; gap: 60px; }
  /* La boîte de la vidéo ne garde pas ses proportions d'une plage à l'autre :
     350 × 475 sur ordinateur, 836 × 1258 en tablette, 328 × 473 au téléphone.
     C'est une hauteur posée, pas un rapport conservé — la vidéo est recadrée. */
  .propos__video { width: 100%; height: auto; aspect-ratio: 836 / 1258; object-fit: cover; }
  .propos__rubriques { width: 100%; }

  .propos__bloc--rose, .propos__bloc--creme { height: auto; }
  .propos__vague { top: -100px; }
  .propos__bloc-inner,
  .propos__bloc-inner--colonne { width: 100%; padding: 40px 32px 48px; }
  .propos__bloc-titre { width: 100%; text-align: center; }
  .propos__bloc-corps { flex-flow: column; align-items: stretch; gap: 34px; margin-top: 24px; }
  .propos__bloc-image,
  .propos__bloc-image--large { width: 100%; height: auto; }
  .propos__bloc-inner--colonne .propos__bloc-titre { text-align: left; }

  .propos__appel { height: auto; }
  .propos__appel-inner { padding: 13px 20px 56px; display: grid; place-items: center; }
  /* L'original ne montre pas l'enseigne sous 1026 px : la section n'y contient
     plus que la pastille. */
  .propos__appel-image { display: none; }
  /* Hors du flux sur ordinateur, dans le flux ici : la marge droite de 68 px
     porte le cercle, et le centrage de la grille tombe alors juste sur les
     300 px de l'ensemble. */
  .propos__appel-pastille { position: static; margin-left: 0; }
}

/* ----- téléphone : valeurs relevées à 360 ----- */
@media (max-width: 809.98px) {
  .propos__hero-inner { padding: 163px 16px 113px; }
  .propos__hero-fond { top: -260px; height: 2126px; }
  .propos__hero-degrade { top: 1656px; height: 310px; }
  /* 40 et non 47 : « RECONNECTEZ- » demande 385 px en Playfair Display là où
     Millave en prend 328. À 47 le mot sortait de la fenêtre et la page défilait
     à l'horizontale. Même raison pour les titres de bloc, 52 au lieu de 54.
     C'est la conséquence des polices substituées, pas un choix de mise en page. */
  .propos__titre    { width: 100%; font-size: 40px; line-height: 40px; }
  .propos__lead     { width: 100%; }
  .propos__duo      { margin-top: 27px; gap: 591px; }
  .propos__video    { aspect-ratio: 328 / 473; }
  .propos__citation { margin-top: 64px; width: 100%; font-size: 30px; line-height: 30px; }

  /* Sous 810 px les deux vagues ne sont plus le même dessin mis à l'échelle :
     la rose fait 1108 × 87 et son milieu tombe à 47 % de la page, la crème
     912 × 71 à 55 % — relevé à 360, 500, 700 et 809. */
  .propos__vague { width: 1108px; aspect-ratio: 1108 / 87; top: -67px; left: 47%; }
  .propos__bloc--creme .propos__vague { width: 912px; aspect-ratio: 912 / 71; top: -53px; left: 55%; }

  .propos__bloc-inner { padding: 40px 12px 0; }
  .propos__bloc-titre { font-size: 52px; line-height: 52px; }
  .propos__bloc-corps { margin-top: 24px; gap: 34px; }
  .propos__bloc-inner--colonne { padding: 20px 12px 11px; }
  .propos__bloc-inner--colonne .propos__bloc-texte { margin-top: 32px; }
  .propos__bloc-image--large { margin-top: 29px; }
}

/* ----- barre transparente, verte : la variante « Desktop green » de l'original
   sur la page « à propos ». Elle ne pose pas de bande crème, elle flotte
   au-dessus de la photo du héro, 21 px sous le haut de page. Elle sort donc du
   flux : le contenu commence à zéro, comme chez lui. ----- */
.site-header--vert {
  position: absolute; top: 21px; left: 0; right: 0;
  background: transparent;
  padding-block-end: 0;
}
.site-header--vert .site-nav a,
.site-header--vert .site-nav__menu,
.site-header--vert .site-header__cart,
.site-header--vert .site-header__burger,
.site-header--vert .langues { color: var(--vert); }
.site-header--vert .site-nav ul { border-color: var(--vert); }
.site-header--vert .langues summary:hover,
.site-header--vert .langues[open] summary { background: rgb(4 50 37 / .1); }
/* Au téléphone l'original la pose tout en haut, sans décalage. */
@media (max-width: 1025.98px) { .site-header--vert { top: 0; } }
/* Sous 810 px le bloc de l'en-tête fait 370 px dans une fenêtre de 360 : il
   déborde de 5 px de chaque côté, ce qui est voulu et invisible sur la bande
   crème des autres pages. Hors du flux et sur une photo, ce débordement fait
   défiler la page à l'horizontale — on le rogne ici, et seulement ici : au-dessus
   de 810 px la même règle couperait la liste déroulante des langues. */
@media (max-width: 809.98px) { .site-header--vert { overflow: clip; } }

/* ---------------------------------------------------------------------------
   Avis clients
   ---------------------------------------------------------------------------
   Ce bloc n'existe pas sur l'original : « Avis Clients » y coiffe un ruban de
   photos, et rien d'autre. Il se pose donc SOUS la piste, à l'intérieur de la
   même section, sans rien déplacer de ce qui a été relevé au pixel.

   Fond crème comme la section qui l'accueille, cartes blanches, or pour les
   étoiles : la palette est celle du site, aucune couleur nouvelle. */

.avis { padding-block: 56px 80px; }

.avis__resume {
  display: flex; align-items: baseline; flex-wrap: wrap; gap: 10px;
  margin: 0 0 28px; font-size: var(--t-md);
}
.avis__resume strong { font-family: var(--titre); font-size: 2rem; font-weight: 700; }
.avis__total { color: color-mix(in srgb, var(--vert) 62%, transparent); }
.avis__resume--vide { color: color-mix(in srgb, var(--vert) 72%, transparent); }

.avis-etoiles { letter-spacing: 2px; white-space: nowrap; }
.avis-etoiles__pleines { color: var(--or); }
.avis-etoiles__vides { color: color-mix(in srgb, var(--or) 32%, transparent); }

.avis__mot {
  margin: 0 0 24px; padding: 14px 18px; border-radius: 12px;
  font-size: var(--t-sm);
}
.avis__mot--merci { background: var(--vert); color: var(--creme-pale); }
.avis__mot--echec { background: #FBE6E6; color: #8A1F1F; }

/* La liste, en vignettes — 15 septembre 2026. Une grille de tuiles : la photo
   du client quand elle existe, un extrait sinon. Un clic agrandit (:target). */
.avis__liste {
  list-style: none; margin: 0 0 40px; padding: 0;
  display: grid; gap: 16px;
  grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
  align-items: start;
}
.avis-carte { margin: 0; }
/* Toute la tuile est un lien qui ouvre la fenêtre agrandie. */
.avis-carte__ouvrir {
  display: flex; flex-direction: column; height: 100%;
  background: var(--blanc); border-radius: 18px; overflow: hidden;
  color: inherit; text-decoration: none; cursor: pointer;
  transition: transform .18s ease, box-shadow .18s ease;
}
.avis-carte__ouvrir:hover, .avis-carte__ouvrir:focus-visible {
  transform: translateY(-3px);
  box-shadow: 0 10px 26px color-mix(in srgb, var(--vert) 16%, transparent);
}
.avis-carte__ouvrir:focus-visible { outline: 2px solid var(--or); outline-offset: 3px; }
.avis-carte__photo { display: block; background: var(--creme-pale); }
.avis-carte__photo img {
  display: block; width: 100%; aspect-ratio: 4 / 5; object-fit: cover;
}
.avis-carte__corps {
  display: flex; flex-direction: column; gap: 8px; padding: 20px 22px; flex: 1 1 auto;
}
.avis-carte__tete {
  display: flex; align-items: center; flex-wrap: wrap; gap: 8px 12px; margin: 0;
}
.avis-carte__nom { font-weight: 600; }
.avis-carte__badge {
  font-size: var(--t-xs); padding: 3px 9px; border-radius: 999px;
  background: color-mix(in srgb, var(--vert) 12%, transparent); color: var(--vert);
}
.avis-carte__titre {
  margin: 0; font-family: var(--titre); font-size: 1.25rem; font-weight: 700;
  line-height: 1.2;
}
/* L'extrait : coupé à quelques lignes, le reste se lit agrandi. */
.avis-carte__texte {
  margin: 0;
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 5;
  line-clamp: 5; overflow: hidden;
}
.avis-carte--photo .avis-carte__texte { -webkit-line-clamp: 3; line-clamp: 3; }
.avis-carte__pied {
  display: flex; align-items: baseline; justify-content: space-between; gap: 10px;
  margin-top: auto; padding-top: 4px;
}
.avis-carte__date {
  margin: 0; font-size: var(--t-xs);
  color: color-mix(in srgb, var(--vert) 55%, transparent);
}
.avis-carte__loupe {
  font-size: var(--t-xs); font-weight: 600; color: var(--or); white-space: nowrap;
}
.avis-carte__loupe::before { content: '⤢ '; }

/* La fenêtre agrandie, ouverte par l'ancre :target, fermée par le fond ou la
   croix. Aucun script — la politique de sécurité interdit le script en ligne. */
.avis-modale {
  display: none; position: fixed; inset: 0; z-index: 1000;
  padding: 24px; overflow: auto;
}
.avis-modale:target { display: flex; align-items: center; justify-content: center; }
.avis-modale__fond {
  position: fixed; inset: 0; cursor: pointer;
  background: color-mix(in srgb, var(--vert-encre) 66%, transparent);
}
.avis-modale__panneau {
  position: relative; z-index: 1; margin: auto;
  width: min(560px, 100%); max-height: 90vh; overflow: auto;
  background: var(--blanc); border-radius: 20px;
  box-shadow: 0 24px 60px rgba(0, 0, 0, .3);
}
.avis-modale__fermer {
  position: absolute; top: 12px; right: 12px; z-index: 2;
  width: 38px; height: 38px; display: grid; place-items: center;
  border-radius: 999px; font-size: 24px; line-height: 1; text-decoration: none;
  color: var(--vert); background: color-mix(in srgb, var(--blanc) 82%, transparent);
  backdrop-filter: blur(2px);
}
.avis-modale__fermer:hover, .avis-modale__fermer:focus-visible { background: var(--creme-pale); }
.avis-modale__fermer:focus-visible { outline: 2px solid var(--or); outline-offset: 2px; }
.avis-modale__photo { background: var(--creme-pale); border-radius: 20px 20px 0 0; overflow: hidden; }
.avis-modale__photo img {
  display: block; width: 100%; max-height: 62vh; object-fit: contain;
}
.avis-modale__contenu { display: flex; flex-direction: column; gap: 10px; padding: 24px 26px 26px; }
.avis-modale__texte { margin: 0; }
@media (prefers-reduced-motion: reduce) {
  .avis-carte__ouvrir { transition: none; }
}

/* La réponse de la marque, décalée : c'est une voix différente, elle ne doit
   pas se confondre avec l'avis qu'elle commente. */
.avis-carte__reponse {
  margin-top: 6px; padding: 12px 16px; border-radius: 12px;
  background: var(--creme-pale); font-size: var(--t-sm);
}
.avis-carte__reponse p { margin: 0; }
.avis-carte__repondant { font-weight: 600; margin-bottom: 4px !important; }

/* ---- déposer ---- */
.avis__depot {
  background: var(--blanc); border-radius: 18px; padding: 4px 24px;
  max-width: 720px;
}
.avis__depot[open] { padding-bottom: 26px; }
.avis__depot-titre {
  cursor: pointer; padding: 18px 0; font-weight: 600; font-size: var(--t-md);
  list-style: none;
}
.avis__depot-titre::-webkit-details-marker { display: none; }
.avis__depot-titre::after { content: ' +'; color: var(--or); }
.avis__depot[open] .avis__depot-titre::after { content: ' –'; }
.avis__depot-titre:focus-visible { outline: 2px solid var(--or); outline-offset: 3px; }
.avis__depot-aide, .avis__invite {
  margin: 0 0 18px; font-size: var(--t-sm);
  color: color-mix(in srgb, var(--vert) 70%, transparent);
}
.avis__invite {
  padding: 10px 14px; border-radius: 10px;
  background: var(--creme-pale); color: var(--vert);
}

.avis-form { display: flex; flex-direction: column; gap: 16px; }
.avis-form__paire { display: grid; gap: 16px; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); }
.avis-form__champ { display: flex; flex-direction: column; gap: 6px; }
.avis-form__libelle { font-size: var(--t-sm); font-weight: 600; }
.avis-form__note {
  font-size: var(--t-xs);
  color: color-mix(in srgb, var(--vert) 60%, transparent);
}
.avis-form__erreur { font-size: var(--t-xs); color: #8A1F1F; }
.avis-form input[type="text"], .avis-form input[type="email"], .avis-form textarea {
  width: 100%; font: inherit; font-size: var(--t-sm);
  padding: 11px 14px; border-radius: 10px;
  border: 1px solid color-mix(in srgb, var(--vert) 22%, transparent);
  background: var(--blanc); color: var(--vert-encre);
}
.avis-form textarea { resize: vertical; min-height: 110px; }
.avis-form :is(input, textarea):focus-visible {
  outline: 2px solid var(--or); outline-offset: 1px; border-color: transparent;
}
.avis-form [aria-invalid="true"] { border-color: #C46A6A; }

/* La note. Cinq boutons radio rendus dans l'ordre décroissant : le sélecteur
   `~` ne regarde que les frères SUIVANTS, donc écrire 5 puis 4 puis 3 permet
   d'allumer l'étoile survolée et toutes celles qui la précèdent à l'écran,
   sans une ligne de script. `row-reverse` remet 1 à gauche pour l'œil. */
.avis-form__notes { border: 0; padding: 0; margin: 0; }
.avis-form__notes legend { padding: 0; font-size: var(--t-sm); font-weight: 600; margin-bottom: 6px; }
.avis-form__etoiles { display: flex; flex-direction: row-reverse; justify-content: flex-end; gap: 2px; }
.avis-form__etoiles input { position: absolute; opacity: 0; width: 1px; height: 1px; }
.avis-form__etoiles label {
  cursor: pointer; font-size: 30px; line-height: 1; padding: 2px;
  color: color-mix(in srgb, var(--or) 42%, var(--blanc));
  transition: color .12s;
}
.avis-form__etoiles label:hover,
.avis-form__etoiles label:hover ~ label,
.avis-form__etoiles input:checked ~ label { color: var(--or); }
/* Le focus clavier doit se voir : la case est masquée, c'est son étiquette qui
   le porte. */
.avis-form__etoiles input:focus-visible + label { outline: 2px solid var(--or); outline-offset: 2px; }

.avis-form__envoi {
  align-self: flex-start; cursor: pointer;
  font: inherit; font-size: var(--t-sm); font-weight: 600;
  padding: 13px 28px; border: 0; border-radius: 999px;
  background: var(--vert); color: var(--creme-pale);
}
.avis-form__envoi:hover { background: color-mix(in srgb, var(--vert) 88%, var(--blanc)); }
.avis-form__envoi:focus-visible { outline: 2px solid var(--or); outline-offset: 2px; }

@media (max-width: 809.98px) {
  .avis { padding-block: 40px 56px; }
  .avis__depot { padding-inline: 18px; }
  .avis__liste { grid-template-columns: 1fr; }
}

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

/* ---------------------------------------------------------------------------
   Les lignes offertes — 7 septembre 2026

   Une ligne qui apparaît toute seule dans un panier doit se distinguer de
   celles que le client y a mises, et dire pourquoi elle est là. Le rose de la
   marque suffit : rien de clignotant, rien qui crie.
   --------------------------------------------------------------------------- */

.panier__prix--offert { color: var(--vert); font-variant-caps: all-small-caps; letter-spacing: .04em; }

.panier__offert-par {
  margin: .25rem 0 0;
  font-size: 11px; line-height: 1.35;
  color: var(--vert); opacity: .75;
}

.cart-table__row--offert { background: rgba(247,177,188,.18); }

.cart-table__offert {
  display: block; margin-top: .25rem;
  font-size: var(--t-xs, 12px); color: var(--vert); opacity: .8;
}

/* La quantité d'un cadeau reste lisible sans champ de saisie : un champ grisé
   sans explication passe pour une panne. */
.cart-table__qty-figee { display: inline-block; padding: .35rem .1rem; font-variant-numeric: tabular-nums; }
/* Les promotions au panier — nuit du 12 au 13 septembre 2026. */
.cart-table__remise th, .cart-table__remise td { color: var(--brun); font-weight: 500; }
.cart-table__barre { margin-right: .4rem; color: rgb(4 50 37 / .55); }

/* Le panier au téléphone — 14 septembre 2026. Les cinq colonnes ne tenaient
   pas : à 360 px le tableau allait jusqu'à 441 px en allemand et la page
   défilait en largeur. Chaque ligne s'empile — le produit sur toute la largeur,
   puis prix, quantité, total et retrait, chacun précédé de son intitulé
   (`data-libelle`, traduit par le gabarit). Les en-têtes restent lus par les
   lecteurs d'écran. Au-dessus de 810 px, rien ne change. */
@media (max-width: 809px) {
  .cart-table, .cart-table tbody, .cart-table tfoot, .cart-table tr, .cart-table th, .cart-table td { display: block; }
  .cart-table thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
  .cart-table tbody tr {
    display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: .5rem 1rem; align-items: center;
    padding: .9rem 0; border-bottom: 1px solid rgba(4,50,37,.25);
  }
  .cart-table tbody th { grid-column: 1 / -1; }
  .cart-table th, .cart-table td { border-bottom: 0; padding: 0; min-width: 0; overflow-wrap: anywhere; }
  .cart-table td[data-libelle]::before { content: attr(data-libelle) "\00a0"; color: rgb(4 50 37 / .7); }
  .cart-table tfoot tr { display: flex; justify-content: space-between; gap: 1rem; padding: .8rem 0; border-bottom: 1px solid rgba(4,50,37,.25); }
}

/* ---------- l'espace client — 10 septembre 2026 ----------------------------

   L'original n'avait rien de tel : le compte vivait chez Shopify, et le
   visiteur ne le rencontrait qu'une fois sorti de la vitrine Framer. Aucune de
   ces valeurs ne vient donc d'un relevé — il n'y avait rien à relever.

   Elles viennent en revanche du **thème du site** : palette (--vert, --creme,
   --rose, --or), typographies (--titre, --texte), échelles de corps (--t-*), et
   surtout le système de formulaire écrit pour le contact, réutilisé tel quel.
   L'espace doit avoir l'air d'appartenir à la boutique, pas d'un panneau
   d'administration greffé dessus.

   Deux dispositions : une carte centrée pour les pages de la porte (connexion,
   inscription, liens reçus par courriel), et deux colonnes — navigation à
   gauche, contenu à droite — pour l'espace connecté, qui s'empilent sous
   810 px. */

/* -- la porte : une carte centrée ------------------------------------------ */

.compte-porte {
  padding-block: clamp(48px, 8vw, 104px);
  display: flex;
  justify-content: center;
}

.carte-compte {
  width: min(100%, 460px);
  box-sizing: border-box;
  padding: clamp(28px, 5vw, 44px);
  border-radius: 24px;
  background: var(--blanc);
  /* Une ombre très douce plutôt qu'un trait : le fond du site est crème, un
     trait franc y ferait sévère. */
  box-shadow: 0 1px 2px rgb(4 50 37 / .05), 0 12px 32px -12px rgb(4 50 37 / .16);
  text-align: center;
}
.carte-compte--large { width: min(100%, 560px); }
.carte-compte--message { text-align: center; }

.carte-compte__titre {
  margin: 0;
  font-family: var(--titre);
  font-weight: var(--titre-graisse);
  font-size: clamp(1.6rem, 1.2rem + 1.4vw, 2.1rem);
  line-height: 1.15;
  color: var(--vert);
}
.carte-compte__intro {
  margin: .7em 0 0;
  font-family: var(--texte);
  font-size: var(--t-sm);
  line-height: 1.55;
  color: rgb(4 50 37 / .72);
}
.carte-compte__note {
  margin: 1em 0 0;
  font-family: var(--texte);
  font-size: var(--t-xs);
  line-height: 1.5;
  color: rgb(4 50 37 / .6);
}

/* Le signe d'une page de résultat — une pastille, pas une icône chargée. */
.carte-compte__signe {
  width: 52px; height: 52px;
  margin: 0 auto 20px;
  display: grid; place-items: center;
  border-radius: 50%;
  font-size: 24px; line-height: 1;
  font-family: var(--texte); font-weight: 600;
}
.carte-compte__signe--ok    { background: rgb(4 50 37 / .1);  color: var(--vert); }
.carte-compte__signe--error { background: rgb(163 35 28 / .1); color: #A3231C; }

.carte-compte__oubli {
  margin: -6px 0 0;
  text-align: right;
  font-family: var(--texte);
  font-size: var(--t-xs);
}
.carte-compte__oubli a { color: rgb(4 50 37 / .7); text-decoration: underline; }
.carte-compte__oubli a:hover { color: var(--vert); }

.carte-compte__pied {
  margin: 26px 0 0;
  padding-top: 22px;
  border-top: 1px solid rgb(4 50 37 / .1);
  font-family: var(--texte);
  font-size: var(--t-sm);
  color: rgb(4 50 37 / .7);
}
.carte-compte__pied a { color: var(--vert); font-weight: 600; text-decoration: underline; }

/* Dans une carte, le formulaire n'a plus à se centrer ni à se limiter : la
   carte s'en charge. On neutralise donc la largeur du système de contact sans
   toucher au reste de son échelle. */
.formulaire--compte {
  --form-largeur: 100%;
  --form-retrait: 0px;
  --form-retrait-h: 0px;
  --form-tete: 18px;
  text-align: left;
}
/* Le bouton d'envoi du formulaire de contact garde le gris #333 de Framer —
   c'est un écart assumé, consigné : le gris par défaut de son éditeur, pas une
   couleur de la marque. Cet héritage n'a aucune raison d'être ici : l'original
   n'avait pas d'espace client, il n'impose donc rien. Le vert de la marque. */
.formulaire--compte .formulaire__envoi { background: var(--vert); color: var(--creme-pale); }
.formulaire--compte .formulaire__envoi:hover { background: #06452f; }
.formulaire--large { --form-largeur: 100%; }

/* Deux champs côte à côte quand la place le permet — prénom et nom, code postal
   et ville. En dessous, ils s'empilent : deux champs de 150 px ne se remplissent
   pas au pouce. */
.formulaire__paire {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--form-ecart);
}
@media (min-width: 560px) {
  .formulaire__paire { grid-template-columns: 1fr 1fr; }
  /* La rue puis son numéro, colonne étroite — 21 septembre 2026. */
  .formulaire__paire--rue { grid-template-columns: minmax(0, 1fr) 140px; }
}
.formulaire__paire .formulaire__champ:first-of-type { padding-top: 0; }

.formulaire__aide {
  font-family: var(--texte);
  font-size: var(--t-xs);
  line-height: 1.45;
  color: rgb(4 50 37 / .6);
}
.formulaire__libelle small {
  margin-left: .4em;
  font-weight: 400;
  text-transform: none;
  letter-spacing: 0;
  color: rgb(4 50 37 / .5);
}

/* Une case à cocher : la cible tactile est la ligne entière, pas le carré de
   16 px — c'est la différence entre un formulaire qu'on remplit au pouce et un
   formulaire qu'on abandonne. */
.formulaire__case {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  padding: 10px 0;
  font-family: var(--texte);
  font-size: var(--t-xs);
  line-height: 1.5;
  color: rgb(4 50 37 / .8);
  cursor: pointer;
}
.formulaire__case input {
  flex: none;
  width: 20px; height: 20px;
  margin: 1px 0 0;
  accent-color: var(--vert);
  cursor: pointer;
}
.formulaire__case span { display: block; }
.formulaire__case a { color: var(--vert); text-decoration: underline; }
.formulaire__case--erreur { color: #A3231C; }
.formulaire__champ--erreur .formulaire__boite { box-shadow: inset 0 0 0 1px #A3231C; }

.formulaire__boite--zone { height: auto; }
.formulaire__boite--zone textarea { min-height: 96px; }
.formulaire__boite select {
  width: 100%; height: 100%;
  padding: 0 14px;
  border: 0; border-radius: inherit;
  background: none;
  font-family: var(--texte); font-size: var(--form-texte);
  color: var(--vert);
  cursor: pointer;
}
.formulaire__boite input:disabled { color: rgb(4 50 37 / .5); cursor: not-allowed; }

/* -- l'espace connecté : deux colonnes ------------------------------------- */

.compte { padding-block: clamp(40px, 6vw, 76px); }

.compte__tete { margin-bottom: clamp(24px, 4vw, 38px); }
.compte__titre {
  margin: 0;
  font-family: var(--titre);
  font-weight: var(--titre-graisse);
  font-size: clamp(1.8rem, 1.3rem + 2vw, 2.6rem);
  line-height: 1.1;
  color: var(--vert);
}
.compte__bonjour {
  margin: .5em 0 0;
  font-family: var(--texte);
  font-size: var(--t-md);
  color: rgb(4 50 37 / .68);
}
.compte__intro {
  margin: 0 0 22px;
  font-family: var(--texte);
  font-size: var(--t-sm);
  line-height: 1.55;
  color: rgb(4 50 37 / .7);
}

.compte__corps {
  display: grid;
  grid-template-columns: 1fr;
  gap: clamp(24px, 4vw, 44px);
  align-items: start;
}
@media (min-width: 810px) {
  .compte__corps { grid-template-columns: 232px minmax(0, 1fr); }
  /* La navigation suit le défilement sur les pages longues : la liste des
     commandes peut faire plusieurs écrans, et remonter pour changer de rubrique
     est le genre de détail qui fait paraître un espace client bricolé. */
  .compte-nav { position: sticky; top: 24px; }
}

.compte-nav__liste { list-style: none; margin: 0; padding: 0; }
.compte-nav__lien {
  display: block;
  padding: 12px 16px;
  border-radius: 10px;
  font-family: var(--texte);
  font-weight: 500;
  font-size: var(--t-sm);
  color: rgb(4 50 37 / .78);
  text-decoration: none;
  transition: background-color .15s, color .15s;
}
.compte-nav__lien:hover { background: rgb(4 50 37 / .06); color: var(--vert); }
.compte-nav__lien.est-actif {
  background: var(--vert);
  color: var(--creme-pale);
  font-weight: 600;
}
.compte-nav__sortie { margin-top: 18px; padding-top: 18px; border-top: 1px solid rgb(4 50 37 / .12); }
.compte-nav__deconnexion {
  padding: 0; border: 0; background: none;
  font-family: var(--texte); font-size: var(--t-xs);
  color: rgb(4 50 37 / .6);
  text-decoration: underline;
  cursor: pointer;
}
.compte-nav__deconnexion:hover { color: #A3231C; }

.compte__contenu { min-width: 0; }

/* -- les chiffres ---------------------------------------------------------- */

.compte-stats {
  list-style: none; margin: 0 0 clamp(24px, 4vw, 36px); padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 14px;
}
.compte-stat {
  padding: 20px;
  border-radius: 16px;
  background: var(--blanc);
  box-shadow: 0 1px 2px rgb(4 50 37 / .05);
}
.compte-stat__nombre {
  display: block;
  font-family: var(--titre);
  font-weight: var(--titre-graisse);
  font-size: 1.55rem;
  line-height: 1.1;
  color: var(--vert);
}
.compte-stat__nom {
  display: block; margin-top: 6px;
  font-family: var(--texte); font-size: var(--t-xs);
  color: rgb(4 50 37 / .62);
}
.compte-stat__note {
  display: block; margin-top: 4px;
  font-family: var(--texte); font-size: 11px; line-height: 1.35;
  color: rgb(4 50 37 / .45);
}

/* -- les blocs ------------------------------------------------------------- */

.compte-bloc {
  padding: clamp(20px, 3vw, 28px);
  margin-bottom: 20px;
  border-radius: 18px;
  background: var(--blanc);
  box-shadow: 0 1px 2px rgb(4 50 37 / .05);
}
.compte-bloc--grave { box-shadow: inset 0 0 0 1px rgb(163 35 28 / .28); background: rgb(163 35 28 / .03); }
.compte-bloc__tete {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 16px; flex-wrap: wrap; margin-bottom: 16px;
}
.compte-bloc__titre {
  margin: 0;
  font-family: var(--titre);
  font-weight: var(--titre-graisse);
  font-size: 1.15rem;
  color: var(--vert);
}
.compte-bloc__date, .compte-bloc__lien {
  font-family: var(--texte); font-size: var(--t-xs);
}
.compte-bloc__date { color: rgb(4 50 37 / .55); }
.compte-bloc__lien { color: var(--vert); text-decoration: underline; }
.compte-bloc p { font-family: var(--texte); font-size: var(--t-sm); line-height: 1.6; color: rgb(4 50 37 / .8); }
.compte-bloc form { margin-top: 14px; }

.compte-fil { margin: 0 0 16px; font-family: var(--texte); font-size: var(--t-xs); }
.compte-fil a { color: rgb(4 50 37 / .7); text-decoration: none; }
.compte-fil a:hover { color: var(--vert); text-decoration: underline; }

.compte-vide {
  padding: clamp(32px, 6vw, 56px) 24px;
  border-radius: 18px;
  background: var(--blanc);
  box-shadow: 0 1px 2px rgb(4 50 37 / .05);
  text-align: center;
}
.compte-vide__titre {
  margin: 0;
  font-family: var(--titre); font-weight: var(--titre-graisse);
  font-size: 1.2rem; color: var(--vert);
}
.compte-vide__texte {
  margin: .6em 0 0;
  font-family: var(--texte); font-size: var(--t-sm); color: rgb(4 50 37 / .65);
}

/* -- les commandes --------------------------------------------------------- */

.cmd-liste { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 12px; }
.cmd-ligne {
  padding: 18px 20px;
  border-radius: 14px;
  background: var(--blanc);
  box-shadow: 0 1px 2px rgb(4 50 37 / .05);
}
.cmd-ligne__haut, .cmd-ligne__bas {
  display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
  font-family: var(--texte);
}
.cmd-ligne__haut { justify-content: space-between; margin-bottom: 10px; }
.cmd-ligne__numero { font-weight: 600; font-size: var(--t-sm); color: var(--vert); }
.cmd-ligne__bas { font-size: var(--t-xs); color: rgb(4 50 37 / .62); }
.cmd-ligne__total { font-weight: 600; color: var(--vert); }
.cmd-ligne__voir { margin-left: auto; color: var(--vert); text-decoration: underline; }

.cmd-etat {
  display: inline-block;
  padding: 4px 11px;
  border-radius: 999px;
  font-family: var(--texte); font-size: 11px; font-weight: 600;
  letter-spacing: .03em; text-transform: uppercase;
  white-space: nowrap;
}
.cmd-etat--expedie  { background: rgb(4 50 37 / .1);    color: var(--vert); }
.cmd-etat--prepare  { background: rgb(188 148 86 / .18); color: #7a5c2e; }
.cmd-etat--a-regler { background: rgb(188 148 86 / .18); color: #7a5c2e; }
.cmd-etat--rembourse,
.cmd-etat--annulee,
.cmd-etat--refuse   { background: rgb(4 50 37 / .07);   color: rgb(4 50 37 / .55); }
.cmd-etat--ok       { background: rgb(4 50 37 / .1);    color: var(--vert); }
.cmd-etat--attente  { background: rgb(247 177 188 / .35); color: #8a3c48; }

/* Le tableau du détail défile dans sa propre boîte : sur un téléphone, une
   ligne de produit longue ne doit pas faire défiler la page entière à
   l'horizontale. */
.cmd-detail { width: 100%; border-collapse: collapse; font-family: var(--texte); font-size: var(--t-sm); }
.cmd-detail th, .cmd-detail td { padding: 12px 8px; text-align: left; vertical-align: top; }
.cmd-detail thead th {
  font-size: 11px; text-transform: uppercase; letter-spacing: .04em;
  color: rgb(4 50 37 / .5); font-weight: 600;
  border-bottom: 1px solid rgb(4 50 37 / .12);
}
.cmd-detail tbody td { border-bottom: 1px solid rgb(4 50 37 / .07); color: var(--vert); }
.cmd-detail td small { display: block; margin-top: 2px; font-size: var(--t-xs); color: rgb(4 50 37 / .55); }
.cmd-detail tfoot th, .cmd-detail tfoot td { font-size: var(--t-xs); color: rgb(4 50 37 / .7); padding-top: 8px; padding-bottom: 8px; }
.cmd-detail tfoot th { font-weight: 400; text-align: right; }
.cmd-detail__total th, .cmd-detail__total td {
  padding-top: 14px;
  border-top: 1px solid rgb(4 50 37 / .16);
  font-size: var(--t-sm); font-weight: 700; color: var(--vert);
}
.cmd-detail th:last-child, .cmd-detail td:last-child { text-align: right; white-space: nowrap; }
/* La TVA comprise, sous le total, et la mention de franchise qui peut passer à
   la ligne — 14 septembre 2026 (lot TVA). */
.cmd-detail .cmd-detail__tva th, .cmd-detail .cmd-detail__tva td { padding-top: 4px; color: rgb(4 50 37 / .55); }
.cmd-detail .cmd-detail__tva th[colspan="3"] { white-space: normal; }
.cmd-documents { margin: 0; padding: 0; list-style: none; font-family: var(--texte); font-size: var(--t-sm); }
.cmd-documents li { padding: 8px 0; border-bottom: 1px solid rgb(4 50 37 / .07); }
.cmd-documents li:last-child { border-bottom: 0; }
.cmd-documents a { color: var(--vert); text-decoration: underline; }
.cmd-documents small { display: block; margin-top: 2px; font-size: var(--t-xs); color: rgb(4 50 37 / .55); }

.cmd-adresses { display: grid; grid-template-columns: 1fr; gap: 0; }
@media (min-width: 640px) {
  .cmd-adresses { grid-template-columns: 1fr 1fr; gap: 20px; }
  .cmd-adresses .compte-bloc { margin-bottom: 20px; }
}
.cmd-adresse {
  font-family: var(--texte); font-size: var(--t-sm); line-height: 1.65;
  font-style: normal; color: rgb(4 50 37 / .8);
}

/* -- les avis du compte ----------------------------------------------------

   **Préfixées « compte- », et il a fallu s'y reprendre.** Mes premières classes
   s'appelaient `.avis-carte*` — un nom déjà pris par `templates/partials/avis.php`,
   qui rend les vrais avis sur l'accueil, sur la fiche produit et sur `/avis`.
   Six sélecteurs se recouvraient, et comme les miens venaient après, ils
   gagnaient : les cartes d'avis du site changeaient d'apparence, et la hauteur
   de l'accueil avec elles.

   Trouvé en mesurant la page — 9 835 px la veille, 9 842 le lendemain — et en
   cherchant d'où venaient les sept pixels, pas en relisant le code.

   *C'est la deuxième fois que ce projet paie une collision de nom de classe,
   après `.vignette` le 1er septembre. La feuille n'est pas compartimentée :
   vérifier qu'un nom est libre avant de l'employer.* */

.compte-avis-liste { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 14px; }
.compte-avis {
  padding: 20px;
  border-radius: 16px;
  background: var(--blanc);
  box-shadow: 0 1px 2px rgb(4 50 37 / .05);
}
.compte-avis__tete { display: flex; align-items: center; justify-content: space-between; gap: 14px; margin-bottom: 10px; }
.compte-avis__note { color: var(--or); font-size: 15px; letter-spacing: .08em; }
.compte-avis__note-vide { color: rgb(4 50 37 / .16); }
.compte-avis__titre { margin: 0 0 6px; font-family: var(--texte); font-weight: 600; color: var(--vert); }
.compte-avis__texte { margin: 0; font-family: var(--texte); font-size: var(--t-sm); line-height: 1.6; color: rgb(4 50 37 / .82); }
.compte-avis__pied { margin: 12px 0 0; font-family: var(--texte); font-size: var(--t-xs); color: rgb(4 50 37 / .55); }
.compte-avis__reponse {
  margin-top: 14px; padding: 14px 16px;
  border-radius: 12px;
  background: rgb(4 50 37 / .05);
}
.compte-avis__reponse-qui { margin: 0 0 4px; font-family: var(--texte); font-size: 11px; font-weight: 600;
                           text-transform: uppercase; letter-spacing: .04em; color: rgb(4 50 37 / .6); }
.compte-avis__reponse p { margin: 0; font-size: var(--t-sm); }

/* -- les avis rendus, les boutons ------------------------------------------ */

/* ---------- les boutons « .btn » -------------------------------------------

   **Ils n'étaient définis nulle part.** `templates/pages/cart.php`,
   `checkout.php`, `error.php` et le bloc bouton de `blocks.php` écrivent
   `class="btn"`, `btn--primary` et `btn--quiet` depuis le 7 septembre, et la
   feuille n'en portait aucune règle. Vérifié au rendu, pas au `grep` : sur
   `/panier`, le lien « Voir la boutique » sortait en texte nu — fond
   transparent, aucun retrait, 22,4 px de haut. « Passer commande » et
   « Valider ma commande » étaient dans le même état.

   Ils sont posés ici parce que l'espace client les emploie à son tour, et
   qu'écrire une seconde famille de boutons à côté d'une famille cassée aurait
   été le mauvais choix. Aucune page calée au pixel n'en contient — vérifié sur
   l'accueil, la boutique, « à propos », la FAQ, la livraison et le contact :
   zéro occurrence. Le bouton de l'original, lui, reste `.pill`, intouché.

   *Correction de ma part, signalée : ce n'était pas demandé.* */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 52px;
  padding: 0 26px;
  border: 0;
  border-radius: 12px;
  background: var(--vert);
  color: var(--creme-pale);
  font-family: var(--texte);
  font-weight: 600;
  font-size: var(--t-sm);
  letter-spacing: .02em;
  text-align: center;
  text-decoration: none;
  cursor: pointer;
  transition: background-color .15s, color .15s;
}
.btn:hover { background: #06452f; color: var(--creme-pale); }
.btn:focus-visible { outline: 2px solid var(--vert); outline-offset: 3px; }

/* Le bouton de l'action principale : le rose de la marque, comme la pilule. */
.btn--primary { background: var(--rose); color: var(--vert); }
.btn--primary:hover { background: #f59fac; color: var(--vert); }

/* Une action de service — « mettre à jour », « retirer » — qui ne doit pas
   peser autant que « passer commande » dans la même rangée. */
.btn--quiet {
  min-height: 40px;
  padding: 0 14px;
  background: transparent;
  color: rgb(4 50 37 / .72);
  font-weight: 500;
  font-size: var(--t-xs);
  text-decoration: underline;
}
.btn--quiet:hover { background: rgb(4 50 37 / .06); color: var(--vert); }

.btn--discret {
  background: transparent;
  color: var(--vert);
  box-shadow: inset 0 0 0 1px rgb(4 50 37 / .3);
}
.btn--discret:hover { background: rgb(4 50 37 / .06); }
.btn--grave { background: #A3231C; color: #fff; border: 0; cursor: pointer; }
.btn--grave:hover { background: #841a15; }

/* ---------- le bandeau de consentement — 13 septembre 2026 ------------------

   Posé en position fixe au bas de la fenêtre : il ne prend aucune place dans
   la page, et les pages calées au pixel gardent leur hauteur — mesuré avant et
   après sur l'accueil et la boutique, à 1440 et à 360.

   Les trois boutons ont exactement la même forme et la même couleur : la
   « Check-list cookies » de l'Autorité de protection des données proscrit la
   couleur qui pousse vers « accepter ». Ils ne reprennent pas `.btn` pour
   cette raison — la famille y distingue justement l'action principale.

   Le conteneur laisse passer les clics (`pointer-events: none`) : seule la
   boîte en capte. Ce n'est pas un mur, la page reste utilisable derrière. */
.consentement {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 90;
  padding: 0 var(--gouttiere) 16px;
  pointer-events: none;
}
.consentement[hidden],
.consentement__details[hidden],
.consentement__bouton[hidden] { display: none; }
.consentement__boite {
  pointer-events: auto;
  max-width: 760px; max-height: calc(100vh - 32px); overflow: auto;
  margin-inline: auto; padding: 20px 24px;
  background: var(--creme-pale); color: var(--vert);
  border: 1px solid rgb(4 50 37 / .2); border-radius: 12px;
  box-shadow: 0 12px 32px rgb(22 28 25 / .18);
  font-family: var(--texte); font-weight: var(--texte-graisse);
  font-size: var(--t-sm); line-height: 1.5;
}
.consentement__titre {
  margin: 0 0 8px;
  font-family: var(--titre); font-weight: var(--titre-graisse);
  font-size: var(--t-lg); line-height: 1.25;
}
.consentement__texte { margin: 0 0 8px; }
.consentement__texte a { color: var(--vert); text-decoration: underline; }
.consentement__finalites { margin: 0 0 8px; padding-left: 1.1em; list-style: disc; }
.consentement__details { display: grid; gap: 10px; margin: 12px 0 4px; }
.consentement__choix { display: flex; gap: 10px; align-items: flex-start; cursor: pointer; }
.consentement__choix input { flex: none; width: 18px; height: 18px; margin: 2px 0 0; accent-color: var(--vert); }
.consentement__choix strong { display: block; }
.consentement__actions { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 14px; }
.consentement__bouton {
  flex: 1 1 0; min-width: 9.5rem; min-height: 44px; padding: 0 16px;
  border: 1px solid var(--vert); border-radius: 12px;
  background: var(--vert); color: var(--creme-pale);
  font: inherit; font-weight: 600; letter-spacing: .02em;
  cursor: pointer;
}
.consentement__bouton:hover { background: #06452f; }
.consentement__bouton:focus-visible,
.consentement__choix input:focus-visible { outline: 2px solid var(--vert); outline-offset: 3px; }
@media print { .consentement { display: none; } }

/* Le bandeau ne masque aucune action d'achat — 14 septembre 2026.

   Constaté au banc par vrais clics : tant que le choix n'était pas fait, la
   boîte couvrait le lien « Commander » du panneau du panier (un cadre fixe, qu'on
   ne fait pas défiler) au téléphone et à 1024 px, « Passer commande » sur
   /panier dès l'arrivée, et « Ajouter au panier » à 1024 × 768.

   - Un panneau ouvert (panier ou menu) passe devant tout : le bandeau s'efface
     le temps qu'il reste ouvert, et revient à sa fermeture. Rien n'est décidé
     pour autant — aucun traceur ne se charge sans un clic sur ses boutons.
   - Sur le panier, le bandeau ne s'ouvre plus de lui-même (voir `$render`).
   - À partir de 810 px, la boîte n'est plus centrée sur 760 px mais posée en
     bas à gauche sur 440 px : les boutons d'achat de la boutique vivent dans la
     colonne de droite (« Ajouter au panier » commence à 488 px à 810, à 702 px
     à 1024), et le panneau du panier s'ouvre à droite.
   - Partout ailleurs, et à toutes les largeurs, le script efface la boîte
     (`consentement--efface`) tant qu'un lien ou un bouton d'achat passe
     dessous — voir `consentement.js`. `visibility` et non `display` : la boîte
     garde sa place, ce qui permet de savoir quand elle peut revenir.

   Toujours en position fixe : aucune hauteur de page ne bouge. */
html.modale-ouverte .consentement { display: none; }
.consentement--efface .consentement__boite { visibility: hidden; }
@media (min-width: 810px) {
  .consentement__boite { max-width: 440px; margin-inline: 0 auto; }
}

/* Au téléphone, la boîte se resserre : refuser et accepter partagent une
   rangée, le réglage fin prend la suivante. */
@media (max-width: 809.98px) {
  .consentement { padding: 0 10px 10px; }
  .consentement__boite { padding: 16px; font-size: var(--t-xs); max-height: calc(100vh - 20px); }
  .consentement__titre { font-size: var(--t-md); }
  .consentement__actions { gap: 8px; margin-top: 10px; }
  .consentement__bouton { min-width: calc(50% - 4px); padding: 0 8px; }
}

/* Le lien « Cookies » du pied, sur la ligne de la politique de confidentialité.
   Hauteur de ligne tenue à 14 px, comme les liens voisins : la colonne garde
   son pas de 46 px. */
.site-footer__col--service li.site-footer__double {
  display: flex; flex-wrap: wrap; justify-content: center; align-items: center; column-gap: 6px;
}
.site-footer__separateur {
  font-family: var(--texte); font-weight: var(--texte-graisse);
  font-size: 14px; line-height: 14px; color: var(--vert);
}

/* Les variantes de « .notice » n'existaient pas davantage : `--info` et
   `--error` sont écrites par la caisse, le panier et la fiche produit depuis le
   7 septembre et rendaient toutes le même crème pâle — un avertissement et une
   erreur se lisaient à l'identique. */
.notice { font-family: var(--texte); font-size: var(--t-sm); line-height: 1.55; color: var(--vert); }
.notice--info  { background: rgb(188 148 86 / .16); }
.notice--error { background: rgb(163 35 28 / .09);  color: #8d1f19; }
.notice--ok    { background: rgb(4 50 37 / .08);    color: var(--vert); }

/* ---------- l'étape de paiement — 11 septembre 2026 ------------------------

   Le formulaire de Stripe vit dans une iframe : notre feuille ne l'atteint pas,
   et son apparence se règle en JavaScript (voir `templates/pages/paiement.php`).
   Ce qui suit habille ce qui l'entoure — et surtout le contient : laissé libre,
   l'élément prend toute la largeur de la coquille, soit 1 280 px sur un
   ordinateur, ce qui n'est pas un formulaire de paiement, c'est un mur. */

.caisse--paiement { max-width: 560px; margin-inline: auto; }

.caisse__commande {
  margin: -.4em 0 1.6em;
  font-family: var(--texte); font-size: var(--t-sm);
  color: rgb(4 50 37 / .6);
}

.paiement {
  padding: clamp(20px, 4vw, 30px);
  border-radius: 18px;
  background: var(--blanc);
  box-shadow: 0 1px 2px rgb(4 50 37 / .05), 0 12px 32px -16px rgb(4 50 37 / .18);
}

.paiement__somme {
  display: flex; align-items: baseline; justify-content: space-between;
  margin-bottom: 22px; padding-bottom: 16px;
  border-bottom: 1px solid rgb(4 50 37 / .1);
  font-family: var(--texte); font-size: var(--t-sm);
  color: rgb(4 50 37 / .7);
}
.paiement__somme strong {
  font-family: var(--titre); font-weight: var(--titre-graisse);
  font-size: 1.4rem; color: var(--vert);
}

.paiement__payer { width: 100%; margin-top: 22px; }
.paiement__payer[disabled] { opacity: .6; cursor: progress; }

.paiement__erreur {
  margin: 16px 0 0; padding: 12px 14px;
  border-radius: 10px;
  background: rgb(163 35 28 / .09);
  font-family: var(--texte); font-size: var(--t-xs); line-height: 1.5;
  color: #8d1f19;
}

.paiement__sur {
  margin: 18px 0 0;
  font-family: var(--texte); font-size: var(--t-xs); line-height: 1.5;
  text-align: center;
  color: rgb(4 50 37 / .55);
}

/* ---------- la caisse — refaite le 11 septembre 2026 -----------------------

   La version du 7 septembre n'avait aucune feuille : des `<p class="champ">`
   avec le libellé collé au champ et la largeur du navigateur. Elle marchait et
   ne se regardait pas.

   Ce qui suit reprend la disposition vers laquelle toutes les grandes caisses
   ont convergé — formulaire à gauche, récapitulatif collant à droite, étapes
   nommées — parce qu'elle répond à trois questions qu'un acheteur se pose dans
   cet ordre : combien, où j'en suis, et est-ce sûr. */

.caisse { padding-block: clamp(28px, 5vw, 56px); }

/* -- les étapes ------------------------------------------------------------ */

.etapes {
  list-style: none; margin: 0 0 clamp(24px, 4vw, 40px); padding: 0;
  display: flex; align-items: center; gap: clamp(8px, 2vw, 20px);
  flex-wrap: wrap;
}
.etape {
  display: flex; align-items: center; gap: 9px;
  font-family: var(--texte); font-size: var(--t-xs);
  color: rgb(4 50 37 / .45);
}
/* Le trait qui relie deux étapes : il dit que c'est un chemin, pas une liste. */
.etape + .etape::before {
  content: ''; width: clamp(14px, 4vw, 44px); height: 1px;
  margin-right: 9px; background: rgb(4 50 37 / .18);
}
/* En dessous de 480 px les trois étapes ne tiennent pas sur une ligne, et le
   trait de liaison se retrouve orphelin en début de seconde ligne. On le
   retire et on resserre : trois pastilles numérotées suffisent à dire le
   chemin. */
@media (max-width: 479.98px) {
  .etapes { gap: 6px 12px; }
  .etape + .etape::before { display: none; }
  .etape { font-size: 12px; }
}
.etape__rond {
  width: 24px; height: 24px; flex: none;
  display: grid; place-items: center;
  border-radius: 50%;
  background: rgb(4 50 37 / .08);
  font-weight: 600; font-size: 12px;
  color: rgb(4 50 37 / .5);
}
.etape--ici { color: var(--vert); font-weight: 600; }
.etape--ici .etape__rond { background: var(--vert); color: var(--creme-pale); }
.etape--faite { color: rgb(4 50 37 / .7); }
.etape--faite .etape__rond { background: rgb(4 50 37 / .16); color: var(--vert); }

/* -- les deux colonnes ------------------------------------------------------

   Le seuil est à 900 px et non à un point de rupture du site : c'est la largeur
   à partir de laquelle deux colonnes de 420 et 340 tiennent sans se serrer. La
   caisse n'existe pas chez l'original, elle n'a donc pas de relevé à respecter. */

.caisse__grille {
  display: grid;
  grid-template-columns: 1fr;
  gap: clamp(24px, 4vw, 44px);
  align-items: start;
}
@media (min-width: 900px) {
  .caisse__grille { grid-template-columns: minmax(0, 1fr) 360px; }
  /* Le récapitulatif suit le défilement : le client voit ce qu'il paie pendant
     qu'il saisit, sans remonter. C'est le détail qui distingue une caisse d'un
     formulaire. */
  .caisse__resume { position: sticky; top: 24px; }
}

/* Au téléphone, le récapitulatif passe **en tête** : on veut savoir combien
   avant de remplir dix champs. L'ordre du balisage sert l'ordinateur ; `order`
   le renverse en dessous. */
@media (max-width: 899.98px) {
  .caisse__grille { display: flex; flex-direction: column; }
  .caisse__resume { order: -1; }
}

.caisse__principal { min-width: 0; }

/* -- les blocs du formulaire ------------------------------------------------ */

.caisse__bloc {
  padding: clamp(20px, 3.4vw, 28px);
  margin-bottom: 18px;
  border-radius: 18px;
  background: var(--blanc);
  box-shadow: 0 1px 2px rgb(4 50 37 / .05);
}
/* Le mode d'envoi, masqué tant que l'adresse n'est pas complète — 21
   septembre 2026. Explicite, comme pour la modale et le bandeau : une règle
   `display` posée un jour sur le bloc ne doit pas le faire réapparaître. */
.caisse__bloc[hidden] { display: none; }
.caisse__titre {
  margin: 0 0 18px;
  font-family: var(--titre); font-weight: var(--titre-graisse);
  font-size: 1.15rem; line-height: 1.2;
  color: var(--vert);
}
.caisse__aide {
  margin: -6px 0 0;
  font-family: var(--texte); font-size: var(--t-xs); line-height: 1.5;
  color: rgb(4 50 37 / .55);
}

/* L'achat professionnel : la case révèle société + numéro de TVA — 16 septembre
   2026. Révélation par CSS `:has(:checked)`, sans JavaScript. Repli : là où
   `:has` n'est pas connu, les deux règles sont ignorées et `.caisse__b2b` garde
   sa valeur par défaut (visible), comme avant l'ajout de la case. */
.caisse__b2b-case {
  display: flex; align-items: center; gap: 12px;
  cursor: pointer; margin-bottom: 4px;
  font-family: var(--texte); font-size: var(--t-sm);
}
.caisse__b2b-case input {
  flex: none; width: 20px; height: 20px; margin: 0;
  accent-color: var(--vert); cursor: pointer;
}
.caisse__b2b { display: block; }
.caisse__bloc:has(#c-b2b) .caisse__b2b { display: none; }
.caisse__bloc:has(#c-b2b:checked) .caisse__b2b { display: block; }
.caisse__vide {
  margin: 0; padding: 18px;
  border: 1px dashed rgb(4 50 37 / .2); border-radius: 12px;
  font-family: var(--texte); font-size: var(--t-sm);
  color: rgb(4 50 37 / .6);
}

/* -- un champ ---------------------------------------------------------------

   Le libellé **au-dessus**, jamais à côté : c'est ce qui permet à tous les
   champs d'avoir la même largeur et de s'empiler proprement au téléphone. */

.champ { display: block; margin: 0 0 16px; }
.champ:last-child { margin-bottom: 0; }

.champ__libelle {
  display: block; margin-bottom: 7px;
  font-family: var(--texte); font-weight: 600;
  font-size: 13px; letter-spacing: .01em;
  color: var(--vert);
}
.champ__saisie {
  display: block; width: 100%; height: 50px;
  box-sizing: border-box;
  padding: 0 14px;
  border: 1px solid rgb(4 50 37 / .18);
  border-radius: 10px;
  background: var(--blanc);
  font-family: var(--texte); font-weight: var(--texte-graisse);
  font-size: 15px; color: var(--vert);
  transition: border-color .15s, box-shadow .15s;
}
.champ__saisie:hover { border-color: rgb(4 50 37 / .32); }
.champ__saisie:focus {
  outline: none;
  border-color: var(--vert);
  /* Un anneau plutôt qu'un contour : il ne déplace rien et se voit sur crème. */
  box-shadow: 0 0 0 3px rgb(4 50 37 / .12);
}
select.champ__saisie { appearance: none; cursor: pointer; padding-right: 38px; }

/* Le chevron du menu déroulant, dessiné en fond : `appearance: none` retire
   celui du navigateur, et sans lui rien ne dit que le champ s'ouvre. */
.champ__enveloppe { display: block; position: relative; }
.champ__enveloppe::after {
  content: ''; position: absolute; right: 16px; top: 50%;
  width: 8px; height: 8px; margin-top: -6px;
  border-right: 1.5px solid rgb(4 50 37 / .5);
  border-bottom: 1.5px solid rgb(4 50 37 / .5);
  transform: rotate(45deg);
  pointer-events: none;
}

.champ--erreur .champ__saisie { border-color: #A3231C; }
.champ--erreur .champ__saisie:focus { box-shadow: 0 0 0 3px rgb(163 35 28 / .14); }
.champ__erreur {
  display: block; margin-top: 6px;
  font-family: var(--texte); font-size: 12px; line-height: 1.4;
  color: #A3231C;
}

/* Deux champs sur une ligne — code postal et ville vont ensemble dans la tête
   de qui les écrit. En dessous de 520 px ils s'empilent : deux champs de
   150 px ne se remplissent pas au pouce. */
.champ__paire { display: grid; grid-template-columns: 1fr; gap: 0 14px; }
@media (min-width: 520px) {
  .champ__paire { grid-template-columns: 140px minmax(0, 1fr); }
  /* La rue puis son numéro — 21 septembre 2026 : l'ordre inverse de la paire
     code postal / ville, la rue prenant la place et le numéro une colonne
     étroite. En dessous de 520 px, empilés comme l'autre paire. */
  .champ__paire--rue { grid-template-columns: minmax(0, 1fr) 120px; }
}

/* -- les modes d'envoi ------------------------------------------------------

   Des cartes, pas des ronds. **La ligne entière est la cible** : un rond de
   16 px ne se vise pas au pouce, et c'est la première chose que corrigent les
   caisses qui mesurent leurs abandons. */

.envois { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 10px; }
.envoi {
  display: flex; align-items: center; gap: 12px;
  padding: 15px 16px;
  border: 1px solid rgb(4 50 37 / .18);
  border-radius: 12px;
  font-family: var(--texte); font-size: var(--t-sm);
  color: var(--vert);
  cursor: pointer;
  transition: border-color .15s, background-color .15s;
}
.envoi:hover { border-color: rgb(4 50 37 / .38); background: rgb(4 50 37 / .03); }
/* Le vrai bouton radio reste dans le flux, invisible mais focalisable : le
   retirer casserait la navigation au clavier. */
.envoi__radio { position: absolute; opacity: 0; width: 0; height: 0; }
.envoi__marque {
  width: 18px; height: 18px; flex: none;
  border: 1.5px solid rgb(4 50 37 / .35);
  border-radius: 50%;
  position: relative;
}
.envoi__radio:checked + .envoi__marque { border-color: var(--vert); }
.envoi__radio:checked + .envoi__marque::after {
  content: ''; position: absolute; inset: 3px;
  border-radius: 50%; background: var(--vert);
}
.envoi__radio:focus-visible + .envoi__marque {
  box-shadow: 0 0 0 3px rgb(4 50 37 / .18);
}
.envoi:has(.envoi__radio:checked) {
  border-color: var(--vert);
  background: rgb(4 50 37 / .04);
  box-shadow: inset 0 0 0 1px var(--vert);
}
.envoi__nom { flex: 1; font-weight: 500; }
.envoi__prix { font-weight: 600; white-space: nowrap; }

/* -- le pied du formulaire -------------------------------------------------- */

.caisse__actions {
  margin-top: 22px;
  display: flex; flex-direction: column; align-items: center; gap: 14px;
}
.caisse__valider { width: 100%; min-height: 56px; font-size: var(--t-sm); }
.caisse__retour {
  font-family: var(--texte); font-size: var(--t-xs);
  color: rgb(4 50 37 / .6); text-decoration: none;
}
.caisse__retour:hover { color: var(--vert); text-decoration: underline; }

/* Les mentions légales au-dessus du bouton : droit de rétractation, CGV. Même
   corps et même gris que l'aide des champs, pleine largeur, alignées à gauche
   comme le formulaire — un paragraphe centré se lit mal sur trois lignes. */
.caisse__mentions {
  align-self: stretch;
  margin: 0;
  font-family: var(--texte); font-size: var(--t-xs); line-height: 1.5;
  color: rgb(4 50 37 / .7);
}
.caisse__mentions a { color: var(--vert); text-decoration: underline; }
.caisse__mentions + .caisse__mentions { margin-top: -8px; }

/* -- le récapitulatif -------------------------------------------------------

   C'est un `<details>` : au téléphone il se replie sur le total, au-dessus de
   900 px le CSS le force ouvert et masque l'affordance. Un seul balisage pour
   les deux comportements, et il fonctionne sans JavaScript. */

.resume {
  padding: clamp(18px, 3vw, 24px);
  border-radius: 18px;
  background: var(--blanc);
  box-shadow: 0 1px 2px rgb(4 50 37 / .05);
}
.resume__tete {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 14px; cursor: pointer;
  list-style: none;
  font-family: var(--texte);
}
.resume__tete::-webkit-details-marker { display: none; }
.resume__titre {
  font-family: var(--titre); font-weight: var(--titre-graisse);
  font-size: 1.05rem; color: var(--vert);
}
.resume__total-court {
  font-family: var(--titre); font-weight: var(--titre-graisse);
  font-size: 1.15rem; color: var(--vert);
}
/* Le chevron n'apparaît que là où le bloc se replie vraiment. */
@media (max-width: 899.98px) {
  .resume__titre::after {
    content: ''; display: inline-block; vertical-align: middle;
    width: 7px; height: 7px; margin-left: 9px; margin-top: -3px;
    border-right: 1.5px solid rgb(4 50 37 / .5);
    border-bottom: 1.5px solid rgb(4 50 37 / .5);
    transform: rotate(45deg);
    transition: transform .15s;
  }
  .resume[open] .resume__titre::after { transform: rotate(-135deg); margin-top: 2px; }
}
@media (min-width: 900px) {
  .resume__tete { cursor: default; }
  .resume__total-court { display: none; }
}

.resume__lignes {
  list-style: none; margin: 18px 0 0; padding: 18px 0 0;
  border-top: 1px solid rgb(4 50 37 / .1);
  display: flex; flex-direction: column; gap: 15px;
}
.resume__ligne { display: flex; align-items: flex-start; gap: 13px; }

/* La pastille de quantité posée sur la vignette : c'est la convention des
   récapitulatifs de caisse, et elle économise une colonne. */
.resume__vignette { position: relative; flex: none; }
.resume__vignette img {
  display: block; width: 54px; height: 54px;
  object-fit: cover;
  border-radius: 10px;
  background: rgb(4 50 37 / .05);
}
.resume__quantite {
  position: absolute; top: -7px; right: -7px;
  min-width: 20px; height: 20px; padding: 0 5px;
  box-sizing: border-box;
  display: grid; place-items: center;
  border-radius: 999px;
  background: var(--vert); color: var(--creme-pale);
  font-family: var(--texte); font-size: 11px; font-weight: 600;
}

.resume__identite { flex: 1; min-width: 0; font-family: var(--texte); }
.resume__nom {
  display: block; font-size: var(--t-sm); font-weight: 600; line-height: 1.3;
  color: var(--vert);
}
.resume__variante,
.resume__offert {
  display: block; margin-top: 3px;
  font-size: var(--t-xs); color: rgb(4 50 37 / .55);
}
.resume__offert { color: var(--brun); }
.resume__prix {
  font-family: var(--texte); font-size: var(--t-sm); font-weight: 600;
  white-space: nowrap; color: var(--vert);
}
.resume__ligne--offert .resume__prix { color: var(--brun); }

.resume__comptes {
  margin: 18px 0 0; padding: 16px 0 0;
  border-top: 1px solid rgb(4 50 37 / .1);
  font-family: var(--texte); font-size: var(--t-sm);
}
.resume__comptes > div {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 14px; margin-bottom: 9px;
}
.resume__comptes dt { color: rgb(4 50 37 / .65); }
.resume__comptes dd { margin: 0; font-weight: 500; color: var(--vert); }
.resume__attente { font-size: var(--t-xs); color: rgb(4 50 37 / .45); }
.resume__total {
  margin: 14px 0 0 !important; padding-top: 14px;
  border-top: 1px solid rgb(4 50 37 / .1);
}
.resume__total dt { font-weight: 600; color: var(--vert) !important; }
.resume__total dd {
  font-family: var(--titre); font-weight: var(--titre-graisse);
  font-size: 1.3rem;
}
.resume__tva {
  margin: 12px 0 0;
  font-family: var(--texte); font-size: 11.5px; line-height: 1.45;
  color: rgb(4 50 37 / .45);
}
/* La TVA comprise dans le total, sous lui et en retrait — 14 septembre 2026
   (lot TVA) : une précision du total, pas une ligne qui s'y ajoute. */
.resume__dont { margin: 8px 0 0 !important; font-size: var(--t-xs); }
.resume__dont dt, .resume__dont dd { color: rgb(4 50 37 / .55); font-weight: 400; }

/* -- le code de réduction et les remises — nuit du 12 au 13 septembre 2026 --

   Dans le récapitulatif, sous les articles : c'est là qu'on regarde le total.
   Le champ reprend celui du formulaire, le bouton celui des gestes discrets. */
.resume__code {
  margin: 18px 0 0; padding: 16px 0 0;
  border-top: 1px solid rgb(4 50 37 / .1);
  font-family: var(--texte);
}
.resume__code-libelle {
  display: block; margin-bottom: 6px;
  font-size: var(--t-xs); color: rgb(4 50 37 / .65);
}
.resume__code-ligne { display: flex; gap: 8px; align-items: stretch; }
.resume__code-saisie { flex: 1 1 auto; min-width: 0; text-transform: uppercase; }
.resume__code-bouton { flex: none; min-height: 50px; }
.resume__code-message { margin: 6px 0 0; font-size: 12px; line-height: 1.4; }
.resume__code-message--ok { color: var(--vert); }
.resume__code-retirer {
  margin: 6px 0 0; padding: 0; border: 0; background: none; cursor: pointer;
  font-family: var(--texte); font-size: 12px; color: rgb(4 50 37 / .65);
  text-decoration: underline;
}
.resume__remise dt, .resume__remise dd { color: var(--brun); }

/* -- la confiance -----------------------------------------------------------

   Les moyens de paiement montrés **avant** le paiement, pas au moment de
   payer : savoir qu'on pourra régler par Bancontact change la décision de
   remplir le formulaire. */

.resume__sur { margin-top: 16px; padding: 0 4px; }
.resume__sur-mot {
  display: flex; align-items: center; gap: 7px;
  margin: 0 0 10px;
  font-family: var(--texte); font-size: var(--t-xs); font-weight: 600;
  color: rgb(4 50 37 / .7);
}
.resume__moyens {
  list-style: none; margin: 0; padding: 0;
  display: flex; align-items: center; flex-wrap: wrap; gap: 10px 14px;
}
/* La technique du pied de page, reprise telle quelle : une boîte de largeur
   donnée par `--boite`, et `object-fit: cover` qui recadre. Les PNG d'iDEAL et
   de Bancontact sont des carrés de 100 × 100 avec le logo au milieu ; sans ce
   recadrage ils se rendaient en carrés de 16 px. */
.resume__moyens > li { width: var(--boite, 16px); height: 16px; overflow: visible; flex: none; }
.resume__moyens img { display: block; width: 100%; height: var(--haut, auto); object-fit: cover; opacity: .85; }

/* -- l'issue ---------------------------------------------------------------- */

.caisse-fin { padding-block: clamp(48px, 8vw, 96px); display: flex; justify-content: center; }
.caisse-fin__carte {
  width: min(100%, 520px);
  box-sizing: border-box;
  padding: clamp(28px, 5vw, 44px);
  border-radius: 22px;
  background: var(--blanc);
  box-shadow: 0 1px 2px rgb(4 50 37 / .05), 0 14px 36px -16px rgb(4 50 37 / .2);
  text-align: center;
}
.caisse-fin__signe {
  width: 58px; height: 58px; margin: 0 auto 20px;
  display: grid; place-items: center;
  border-radius: 50%;
  font-size: 26px; line-height: 1;
}
.caisse-fin__signe--ok { background: rgb(4 50 37 / .1); color: var(--vert); }
.caisse-fin__signe--attente { background: rgb(188 148 86 / .18); }
.caisse-fin__titre {
  margin: 0;
  font-family: var(--titre); font-weight: var(--titre-graisse);
  font-size: clamp(1.5rem, 1.1rem + 1.4vw, 2rem); line-height: 1.15;
  color: var(--vert);
}
.caisse-fin__numero {
  margin: .6em 0 1.4em;
  font-family: var(--texte); font-size: var(--t-md);
  color: rgb(4 50 37 / .7);
}
.cta-wrap--centre { justify-content: center; flex-wrap: wrap; gap: 12px; }

/* Le titre de l'étape de paiement : la page est étroite, le grand titre du site
   y serait disproportionné. */
.caisse__h1 {
  margin: 0 0 .3em;
  font-family: var(--titre); font-weight: var(--titre-graisse);
  font-size: clamp(1.5rem, 1.1rem + 1.4vw, 1.9rem); line-height: 1.15;
  color: var(--vert);
}
.caisse--paiement .etapes { justify-content: center; }

/* ---------------------------------------------------------------- le point
   relais — 11 septembre 2026.

   Mondial Relay livre en point relais et la caisse ne le demandait nulle part :
   27 des 56 commandes de la base sont parties par lui à l'aveugle. Le bloc
   reprend les codes des cartes de livraison juste au-dessus, pour que le choix
   se lise comme la suite du même geste et non comme un formulaire de plus. */
.relais {
  margin-top: 20px;
  padding-top: 20px;
  border-top: 1px solid var(--trait, #dfe5e2);
}

.relais__titre {
  margin: 0 0 4px;
  font-size: 15px;
  font-weight: 600;
  color: var(--vert, #043225);
}

.relais__aide {
  margin: 0 0 14px;
  font-size: 13px;
  line-height: 1.5;
  color: var(--gris, #6b7770);
}

.relais__simule {
  margin-bottom: 14px;
}

.relais__liste {
  display: grid;
  gap: 8px;
}

/* Une liste de points peut être longue : on la borne et on la fait défiler
   plutôt que de repousser le bouton de paiement hors de l'écran. */
@media (min-width: 600px) {
  .relais__liste {
    max-height: 340px;
    overflow-y: auto;
    padding-right: 4px;
  }
}

.relais__point {
  display: flex;
  gap: 12px;
  align-items: flex-start;
  padding: 12px 14px;
  border: 1px solid var(--trait, #dfe5e2);
  border-radius: 12px;
  cursor: pointer;
  background: #fff;
  transition: border-color .15s ease, background-color .15s ease;
}

.relais__point:hover {
  border-color: var(--vert, #043225);
}

.relais__point--actif {
  border-color: var(--vert, #043225);
  background: var(--vert-pale, #f1f4f3);
}

.relais__radio {
  margin-top: 3px;
  width: auto;
  flex: 0 0 auto;
  accent-color: var(--vert, #043225);
}

.relais__corps {
  display: grid;
  gap: 2px;
  min-width: 0;
}

.relais__nom {
  font-size: 14px;
  font-weight: 600;
  color: var(--vert, #043225);
}

.relais__adresse,
.relais__distance {
  font-size: 13px;
  color: var(--gris, #6b7770);
  /* Un nom de rue long ne doit pas élargir la carte au point de faire défiler
     la page de côté. */
  overflow-wrap: anywhere;
}

.relais__distance {
  font-variant-numeric: tabular-nums;
}

.relais__etat:empty {
  display: none;
}

.relais__etat {
  margin: 12px 0 0;
  font-size: 13px;
  color: var(--gris, #6b7770);
}

/* Le renvoi du courriel de confirmation — 12 septembre 2026. Il suit le message
   d'erreur auquel il répond, et s'en écarte juste assez pour ne pas passer pour
   le bouton du formulaire de connexion qui vient après. */
.carte-compte__renvoi {
  margin: -6px 0 18px;
}

/* ----------------------------------------------- la rangée d'achat au mobile
   Mesuré le 12 septembre 2026 : à 360 px, la fiche produit dispose de 336 px,
   et cette rangée en réclame 441 — 187 pour le sélecteur de quantité, 254 pour
   « Ajouter au panier », dont le libellé est insécable. Le bouton sortait donc
   de l'écran de plus de cent pixels.

   La quantité ne peut pas rétrécir sans que ses boutons + et − deviennent trop
   petits pour le pouce, et le libellé ne peut pas se couper. On empile : c'est
   ce que fait toute fiche produit au téléphone, et cela rend au bouton toute la
   largeur — ce qui en fait une meilleure cible, pas seulement une cible qui
   tient. */
@media (max-width: 809.98px) {
  .fiche__ligne {
    flex-flow: column;
    align-items: stretch;
    gap: 12px;
    height: auto;
  }

  .fiche__ligne .quantite {
    width: 100%;
  }

  .fiche__ligne .fiche__ajouter {
    width: 100%;
    flex: none;
  }
}

/* ═══════════════════════════════════════════════════════════════════════════
   Cibles tactiles — 12 septembre 2026.

   La norme WCAG 2.2 (critère 2.5.8, niveau AA) demande 24 × 24 px pour tout
   ce qui se touche. Un relevé au doigt d'écran, à 390 px, en a trouvé une
   dizaine en dessous : les liens du pied font 14 px de haut, les icônes des
   réseaux 16 × 16, les puces de la galerie 8 × 8.

   **Rien ci-dessous ne déplace un pixel.** La zone sensible est portée par un
   `::after` en position absolue, qui déborde dans le vide déjà présent entre
   les éléments — les liens du pied sont écartés de 32 px, il y a largement la
   place. Agrandir les éléments eux-mêmes aurait écarté la colonne et rompu la
   fidélité à la maquette d'origine.

   `pointer-events` n'a pas à être touché : un pseudo-élément d'un `<a>` fait
   partie de la surface cliquable du lien.
   ═══════════════════════════════════════════════════════════════════════════ */

.site-footer__col--service a,
.site-footer__icones a,
.fiche__partager {
  position: relative;
}

.site-footer__col--service a::after,
.site-footer__icones a::after,
.fiche__partager::after {
  content: '';
  position: absolute;
  /* Centré sur l'élément, étendu jusqu'à 24 px dans les deux sens. La moitié
     de l'écart suffit : 5 px de part et d'autre d'un texte de 14 px. */
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 100%;
  min-width: 24px;
  height: 100%;
  min-height: 24px;
}

/* Les puces de la galerie, sur téléphone.
   Celles-ci ne viennent pas de la maquette : ce sont les vignettes du bureau
   transformées en puces pour la piste défilante. L'écart passe donc de 8 à
   14 px — sans quoi deux zones de 24 px se chevaucheraient, ce que la norme
   refuse explicitement. Le point lui-même garde ses 8 px. */
/* Le point de rupture est celui de la piste défilante — 809.98 px, pas 768 :
   entre les deux, les puces existent déjà et seraient restées minuscules. */
@media (max-width: 809.98px) {
  .galerie__vignettes { gap: 14px; }

  /* `overflow: clip` rognait la vignette du bureau sur son image. Sur
     téléphone l'image est masquée, la coupe ne sert plus à rien — mais elle
     rognait aussi le pseudo-élément, et avec lui la zone sensible. */
  .galerie__vignette { position: relative; overflow: visible; }

  .galerie__vignette::after {
    content: '';
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    width: 22px;
    height: 32px;
  }
}

/* ═══════════════════════════════════════════════════════════════════════════
   La mention qui remplace le tableau nutritionnel — 12 septembre 2026.

   Celui qui figurait ici décrivait un autre produit : une formule cacao pour
   le sommeil, là où l'on vend un café aux champignons. Il a été retiré, et
   cette mention prend sa place en attendant le vrai.

   Elle reprend la largeur du tableau (209 px) pour que la colonne ne se
   réorganise pas, et reste masquée sous 810 px comme lui — l'original y
   retirait déjà le tableau.
   ═══════════════════════════════════════════════════════════════════════════ */



