/* testimonials.css — section témoignages « Clients talk & we blush » (#reviews).

   Toutes les valeurs sont relevées sur la source le 2026-08-11, aux trois
   paliers, APRÈS parcours de la section par paliers sur toute sa hauteur puis
   retour au bord haut (règle A₁.5 : `document.getAnimations()` vide ne prouve
   rien, la source translate ses blocs en JS). `location.href` a été renvoyé
   dans le MÊME `browser_evaluate` que chaque mesure (règle A₁.6). Chaque
   ensemble a été énuméré membre par membre, jamais échantillonné (piège n° 8) —
   c'est ainsi qu'on a trouvé les CINQ teintes de panneau (voir plus bas), que le
   brief comme les constats du contrôleur donnaient pour une seule.

   ⚠ Cette section est en ANGLAIS sur la source, seule du site. Reproduite telle
   quelle (décision du propriétaire, pas la nôtre).

   Contrôle arithmétique de la hauteur de section, aux trois paliers :
     1440 : 60 (pad haut) + 136   (intro) + 60 (gap) + 454 (carrousel) + 170 = 880
     1024 : 60            + 184,8 (intro) + 60       + 454             + 170 = 928,8
      390 : 30            + 163,5 (intro) + 40       + 454             +  70 = 757,5
   Les trois totaux sont exactement les hauteurs mesurées sur la source
   (880 / 928,8 / 757,5). La cible du brief à 1440 (880) est donc atteinte au
   pixel près.

   La hauteur de 454 du carrousel est CODÉE, et c'est bien ce que fait la source :
   `framer-cljznl-container` porte `height: 454px` aux trois paliers, alors que
   la plus haute des six cartes ne mesure que 423,2 (1440) / 366 (1024 et 390).
   Elle n'est donc pas dictée par le contenu, et une hauteur `auto` rendrait la
   section 31 px (1440) à 88 px (1024) trop courte. Vérifié en remontant toute la
   chaîne des ancêtres du `<ul>` : `height` vaut 454px sur les quatre niveaux
   au-dessus de lui, `min-height` 0/auto partout.
   ⚠ Corollaire heureux du retrait des portraits (2026-08-18) : les cartes ont
   perdu ~36 px de bandeau, mais la hauteur de section n'a pas bougé d'un pixel,
   justement parce que ces 454 sont codés et non dictés par la carte. Les cartes
   restent alignées en haut du hublot ; c'est la bande libre sous elles qui
   s'élargit d'autant.

   ---------------------------------------------------------------------------
   MANQUES DU BRIEF (A₀) — relevés puis reconstruits ici. Ni le brief ni les
   sept constats du contrôleur ne les mentionnent :

   1. LE BORD FESTONNÉ DE HAUT DE SECTION. 15 bosses en --c-olive-black qui
      remontent au-dessus de la section et mordent sur l'orange de #comparison :
      96 × 75,59 remontées de 61 à 1440 ; 68,27 × 53,76 remontées de 40 à 1024 ;
      26 × 20,47 remontées de 20 à 390. Ce sont exactement les tokens --scallop-*
      en place : la primitive partagée `.scallop-top` (layout.css) convient telle
      quelle, portée par la section dans le markup. La section ne doit donc PAS
      passer en overflow hidden/clip.
      ⚠ Invisible au balayage `background-image` du constat n° 6 (« fond
      réellement uni, aucun calque peint ») : la source dessine ses bosses avec
      un `background-color` et un `border-radius: 90px 90px 0 0` sur des <div>
      de 96 de large, pas avec une image de fond. Le constat est juste sur ce
      qu'il mesure, mais il ne mesure pas le feston.

   2. LES CINQ TEINTES DE PANNEAU. Chaque carte a la sienne, et c'est le seul
      élément qui distingue les cartes entre elles. Relevé carte par carte :
        Tobias Green    --c-pink        Callum Yates   --c-lavender
        Silas Leighton  --c-pink-light  Jasper Lowell  --c-pink-light
        Orion Vance     --c-cream       Lowell Vance   --c-mint
      Cinq teintes distinctes pour six cartes : --c-pink-light sert deux fois.
      Tout le reste est CONSTANT sur les six (vérifié membre par membre) :
      bandeau --c-yellow-pale, rond de logo --c-cream, filet du panneau
      « 2px double --c-ink », pointillé du logo « 3px dotted --c-olive-black »,
      triangle --c-yellow-bright.

   3. LE TRIANGLE DE BULLE. Un triangle de 41 × 41 en --c-yellow-bright, posé à
      (20, 71) de la carte, à cheval sur le bas du bandeau jaune et le haut du
      panneau coloré : c'est la queue de la bulle de dialogue. La source le pose
      en <svg><use href="#…"></svg> vers un symbole partagé par les six cartes ;
      le tracé est un triangle pointe en bas, `rotate(180 20.5 20.5)` appliqué à
      un triangle pointe en haut. Le `transform` est ici aplati à la main dans
      les coordonnées du tracé, pour ne pas dépendre d'un attribut de présentation.

   4. LE MASQUE EN ÉTOILE DES PORTRAITS. Les portraits ne sont PAS des ronds :
      `framer-z9r1iu` porte un `mask-image` pointant DjiCc2eOXk5aIpbH0dR0SopaoBQ.png,
      en `mask-size: cover`, `no-repeat`, centre, sur les six cartes. Le fichier est
      un PNG palettisé de 356 × 360 dont le canal alpha dessine une étoile à
      pointes (vérifié en décodant l'IDAT : silhouette blanche sur transparent).
      ⚠ `assets/README.md` le décrit comme « Avatar générique placeholder
      (silhouette blanche quasi invisible sur fond blanc), réutilisé sur les
      témoignages sans photo » — c'est FAUX, il n'est jamais rendu comme image :
      il ne sert que de masque, et les six témoignages ont tous une vraie photo.
      Signalé dans le rapport ; README corrigé depuis.
      ⚠ CADUC POUR NOTRE VERSION depuis le 2026-08-18 : le propriétaire a fait
      retirer les portraits des témoignages. `.testimonials__portrait` et le
      `mask` qui l'accompagnait ont disparu du fichier ; DjiCc2e…png n'est donc
      plus cité par aucune feuille et `build.py`, qui ne recopie que le référencé,
      l'écarte de `dist/`. Le relevé ci-dessus reste ici pour ce qu'il est — la
      description de la SOURCE, pas de ce que nous servons.

   5. LE FILET DU PANNEAU ET LE POINTILLÉ DU LOGO, tous deux portés par un
      `::after` en `position: absolute; inset: 0`, donc invisibles à tout
      balayage de boîtes (corollaire du piège n° 8 : `querySelectorAll('*')` ne
      voit aucun pseudo-élément). Trouvés sur la capture, puis confirmés par
      `getComputedStyle(el, '::after')` sur les six cartes.

   ---------------------------------------------------------------------------
   CONTREDIT LE CONSTAT n° 3 DU CONTRÔLEUR (« huit logos d'entreprise distincts
   pour six témoignages, la correspondance n'est pas évidente »). Énumération
   complète des <img> de la section, avec leur nombre d'occurrences : 14 fichiers
   distincts, dont 6 portraits .jpg (×4 chacun, les 4 copies de la piste), 6
   logos .svg (×4) et les 2 chevrons des flèches (×1). SIX logos, pas huit, et
   la correspondance est bijective, une carte un logo. Le décompte de huit vient
   probablement d'avoir compté aussi les deux chevrons, eux aussi en SVG.
   Appariement relevé carte par carte, dans l'ordre de la piste :
     Tobias Green   3Y1x3Iz9CnzoCeLjfRflZMOiF0   Callum Yates   mGAxAGDBjt0JHg8MI0F9P9FkW0g
     Silas Leighton 6QEz8kJbwqWFzbNDcgcMwaBk7Jk   Jasper Lowell  uTkuLOi3ZjuJHBQNS9i0C4T7A
     Orion Vance    duZwjP73YzY6931zuqasWWfWDZY   Lowell Vance   RsaJCL4Sj4fVM9spQ7bKyrgyngo

   CONTREDIT AUSSI L'ORDRE DU BRIEF. Le tableau du brief donne Orion, Callum,
   Jasper, Lowell, Tobias, Silas — l'ordre de `releve-2026-08-10.json`. Le HTML
   servi aujourd'hui donne, 12 fois de suite (3 variantes de palier × 4 copies
   de piste) : Tobias, Silas, Orion, Callum, Jasper, Lowell, soit l'ordre du
   brief tourné de quatre rangs. C'est cet ordre qui est reproduit ici : la page
   1 du carrousel montre bien Tobias Green en premier sur la source, aux trois
   paliers, sur chargement neuf. Voir le rapport.

   Le tracé du sticker (viewBox 0 0 501 291) est le MÊME que celui déjà inliné
   en tâche 9 (#benefits) et en tâche 12 (#comparison) — comparé caractère par
   caractère : identique, 1318 caractères, TROISIÈME occurrence dans index.html.
   Non factorisé ici (cela rouvrirait deux sections closes) ; l'arbitrage est
   reporté à la tâche 18, comme demandé par le constat n° 5.
   `.sticker` / `.sticker--masked` ne sont PAS réutilisés (règle A₁.0) : la
   source pose le SVG en `contain` sur 100% de la LARGEUR de la boîte en le
   laissant déborder en hauteur (181 × 105,1 pour une boîte de 181 × 86 à 1440) ;
   `.sticker--masked`, qui contient la forme dans la boîte, rendrait une étoile
   écrasée. Même choix qu'en tâches 10 et 12.
   `.card` (layout.css) n'est pas réutilisée non plus : elle pose un fond, un
   rayon 32 et `overflow: hidden`, alors que la carte d'ici n'a ni fond ni rayon
   propres (ce sont le bandeau et le panneau qui les portent, en 50 et 40) et
   doit laisser déborder le triangle de bulle. */

.testimonials {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 60px;
  padding: 60px 40px 170px;
  background: var(--c-olive-black);

  /* Bord festonné du haut — manque du brief, voir l'en-tête. La primitive
     `.scallop-top` est portée par la section dans le markup ; la section ne
     doit donc pas passer en overflow: hidden/clip. */
  --scallop-color: var(--c-olive-black);

  /* Nombre de cartes visibles d'un coup. Le carrousel s'en sert pour calculer
     la largeur d'une carte, et le module JS n'a rien à en savoir : il mesure la
     carte rendue. Relevé : (largeur du hublot + gouttière) / largeur du pas
     vaut exactement 3,5 à 1440 (1380 / 394,28) et 2,5 à 1024 (964 / 385,59). */
  --tm-per-view: 3.5;
  --tm-gap: 20px;
}

/* Le focus clavier par défaut (base.css) est un liseré --c-ink, invisible sur
   le fond olive presque noir de cette section. Écart assumé, documenté au
   rapport : la couleur passe au jaune, la forme et l'épaisseur ne changent pas. */
.testimonials :focus-visible { outline-color: var(--c-yellow); }

/* ---------- Intro : sticker + titre ----------
   Même largeur que le conteneur de titre de la source (800 / 600 / pleine
   largeur), pour que la position du sticker, exprimée en pourcentage de cette
   boîte, se transpose telle quelle. */
.testimonials__intro {
  position: relative;
  width: 800px;
}

.testimonials__heading {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: var(--fs-68);
  line-height: 1;
  color: var(--c-sand);
  text-align: center;
  /* Relevé sur la source. C'est lui qui donne la coupe « Clients talk / & we
     blush » aux trois paliers ; sans lui la coupe gloutonne remonte « & » sur
     la première ligne à 1440. */
  text-wrap: balance;
}

/* Sticker dimensionné par son CONTENU (libellé + 30px de padding sur les quatre
   côtés), pas par une largeur codée : c'est ce que fait la source (vérifié en
   dépivotant les AABB de 20° aux trois paliers — 181 × 86 à 1440, 156,8 × 80,8
   à 1024, 150,8 × 79,5 à 390, soit exactement le libellé + 60 dans les deux
   axes) et c'est la seule façon de garantir que le libellé tient dans la forme
   (règle A₁.3).

   Position à 1440 : centre du sticker à 5% / 82% de la boîte du titre
   (`left: 40px` sur 800 et `top: 111,516px` sur 136, relevés tels quels). */
.testimonials__sticker {
  position: absolute;
  left: 5%;
  top: 82%;
  display: inline-grid;
  place-items: center;
  padding: 30px;
  transform: translate(-50%, -50%) rotate(-20deg);
}

.testimonials__sticker-shape {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 100%;
  height: auto;
  aspect-ratio: 501 / 291;
  transform: translate(-50%, -50%);
  fill: var(--c-purple);
  pointer-events: none;
}

.testimonials__sticker-label {
  position: relative;
  font-family: var(--font-sans);
  font-weight: 600;
  font-size: var(--fs-20);
  line-height: 26px;
  letter-spacing: -0.8px;
  color: var(--c-ink);
  white-space: nowrap;
}

/* ---------- Carrousel ----------
   `.testimonials__carousel` a exactement la boîte du hublot ; les flèches et
   les pastilles en débordent par le haut et par le bas, en absolu, comme sur la
   source (le <fieldset> de contrôles y recouvre le hublot, et ses deux enfants
   sont posés à `top: -60px` et `top: 473px`). D'où l'absence d'overflow ici. */
.testimonials__carousel {
  position: relative;
  width: 100%;
  height: 454px;
}

.testimonials__viewport {
  width: 100%;
  height: 100%;
  overflow: hidden;
  border-radius: 40px;
}

.testimonials__track {
  display: flex;
  /* Les cartes sont alignées EN HAUT du hublot de 454 (relevé : le bandeau de
     la carte commence exactement au bord haut du hublot), et non centrées —
     alors même que la source déclare `align-items: center` sur son <ul>, sans
     effet puisqu'elle donne aussi à chaque conteneur de carte la hauteur pleine
     du hublot. On obtient le même rendu sans cette hauteur de plus. */
  align-items: flex-start;
  gap: var(--tm-gap);
  height: 100%;
  transition: transform var(--dur-carousel) var(--ease-out);
  will-change: transform;
}

.testimonials__slide {
  flex: 0 0 auto;
  /* Largeur dérivée du nombre de cartes visibles, pas codée en dur :
     (hublot + gouttière) / n − gouttière. Donne 374,29 à 1440 (mesuré 374,28),
     365,6 à 1024 (mesuré 365,59) et 350 à 390 (mesuré 350). */
  width: calc((100% + var(--tm-gap)) / var(--tm-per-view) - var(--tm-gap));
}

/* ---------- Carte ---------- */
.testimonials__card {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

/* Bandeau : hauteur toujours non codée, mais dictée depuis le 2026-08-18 par
   son seul contenu restant, le nom — 10 + 25,2 + 10 = 45,2 à 1440, et
   10 + 23,8 + 10 = 43,8 aux deux autres paliers. La source la portait à 81
   (10 + 61 + 10) parce qu'un portrait de 61 y siégeait ; les portraits ont été
   retirés (décision du propriétaire) et le bandeau se referme sur le nom.
   ⚠ Le padding horizontal passe de 10 à 20, et ce n'est pas cosmétique : à 45,2
   de haut, `border-radius: 50px` est ramené par le navigateur à une pastille de
   rayon 22,6, et un texte posé à 10 du bord entrerait dans la courbe. 20 l'en
   dégage et l'aligne sur le `left: 20px` de la queue de bulle.
   Le `gap: 16px` a disparu avec le portrait : il ne reste qu'un seul enfant en
   flux (la queue est en `position: absolute`, une gouttière ne l'atteint pas). */
.testimonials__head {
  position: relative;
  z-index: 1;
  display: flex;
  align-items: center;
  padding: 10px 20px;
  border-radius: 50px;
  background: var(--c-yellow-pale);
}

.testimonials__name {
  flex: 1 1 auto;
  min-width: 0;
  font-family: var(--font-sans);
  font-weight: 600;
  font-size: var(--fs-18);
  line-height: 25.2px;
  letter-spacing: -0.36px;
  color: var(--c-ink);
}

/* Queue de la bulle — manque A₀ n° 3. Posée dans le bandeau mais débordant vers
   le bas sur le panneau coloré ; le `z-index: 1` du bandeau la fait peindre
   par-dessus le panneau, qui le suit dans l'ordre du DOM.
   ⚠ Ancrée par le BAS depuis le retrait des portraits, alors que la source la
   posait en `top: 71px`. Les deux valeurs sont la même : dans un bandeau de 81,
   un `top: 71` sur une boîte de 41 laisse 31 de débord sous le bandeau, ce que
   `bottom: -31px` écrit directement. Mais le bandeau ne mesure plus 81, et sa
   hauteur varie désormais selon l'interlettrage du nom (45,2 à 1440 ; 43,8 aux
   deux autres paliers) : un `top` codé décrocherait la queue à un palier sur
   deux, l'ancrage par le bas tient aux trois. */
.testimonials__tail {
  position: absolute;
  left: 20px;
  bottom: -31px;
  width: 41px;
  height: 41px;
  /* ⚠ Piège A₁.1, payé d'un tour de correction ici. L'attribut `fill` du tracé
     source vaut `var(--token-9f0badbf-…, <canaux 255·245·112>)`, soit
     --c-yellow-bright si l'on s'arrête à la déclaration. Le token EST défini
     (sur un ancêtre du <svg>, pas sur :root) et le `fill` CALCULÉ vaut
     les canaux 250·250·191 = --c-yellow-pale, la couleur même du bandeau — ce qui
     est cohérent, la queue appartient à la bulle. Lire la déclaration ne prouve
     rien ; c'est le style calculé qui tranche. */
  fill: var(--c-yellow-pale);
  pointer-events: none;
}

/* ---------- Panneau coloré ----------
   Sa teinte est le seul élément qui distingue les six cartes (manque A₀ n° 2).
   Elle est portée par une custom property plutôt que par un `background` par
   modificateur, pour n'écrire la déclaration qu'une fois. */
.testimonials__panel {
  display: flex;
  flex-direction: column;
  border-radius: 40px;
  background: var(--tm-tone, var(--c-pink));
}

.testimonials__card--pink       { --tm-tone: var(--c-pink); }
.testimonials__card--pink-light { --tm-tone: var(--c-pink-light); }
.testimonials__card--cream      { --tm-tone: var(--c-cream); }
.testimonials__card--lavender   { --tm-tone: var(--c-lavender); }
.testimonials__card--mint       { --tm-tone: var(--c-mint); }

.testimonials__quote {
  position: relative;
  padding: 20px;
}

/* Filet du panneau — manque A₀ n° 5. Reproduit tel quel : un pseudo-élément en
   inset 0, et non une `border` sur le bloc lui-même, qui décalerait le texte de
   2px vers l'intérieur (la source pose son texte à exactement 20px du bord). */
.testimonials__quote::after {
  content: "";
  position: absolute;
  inset: 0;
  border: 2px double var(--c-ink);
  border-radius: 40px;
  pointer-events: none;
}

.testimonials__quote p {
  font-family: var(--font-sans);
  font-weight: 600;
  font-size: var(--fs-24);
  line-height: 31.2px;
  letter-spacing: -0.96px;
  color: var(--c-ink);
  /* Relevé sur les SIX citations (`text-wrap-style: balance` calculé). Sans lui
     la coupe gloutonne remonte un mot sur la première ligne de quatre citations
     sur six — même nombre de lignes, donc même hauteur de carte, mais un pavé
     visiblement différent. Le libellé du nom et la fonction, eux, sont en
     `wrap` normal (vérifié aussi). */
  text-wrap: balance;
}

/* Pied : hauteur 105 = 20 + 61 + 24, imposée par le rond de logo. Aux trois
   paliers. Le padding bas (24) diffère bien du haut (20) — relevé. */
.testimonials__foot {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 20px 20px 24px;
}

.testimonials__logo {
  position: relative;
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  width: 61px;
  height: 61px;
  padding: 10px;
  border-radius: 30px;
  background: var(--c-cream);
}

/* Pointillé du rond de logo — manque A₀ n° 5, même technique que le filet. */
.testimonials__logo::after {
  content: "";
  position: absolute;
  inset: 0;
  border: 3px dotted var(--c-olive-black);
  border-radius: 30px;
  pointer-events: none;
}

.testimonials__logo img {
  width: 41px;
  height: 41px;
  object-fit: contain;
  /* Logos clients en noir et blanc (demande du 2026-08-14). Les trois arrivent
     avec des couleurs très différentes — bleu-violet, brun, vert foncé — et
     chacun sur une carte d'une autre teinte : en couleur, la rangée de bas de
     carte devenait un patchwork. Le gris les met à égalité et laisse la couleur
     aux cartes.
     Même méthode que les portraits de l'équipe dans `about.css` : un filtre sur
     l'IMAGE seule. La pastille crème et son liseré pointillé gardent donc leurs
     couleurs, comme là-bas.
     ⚠ Ne concerne QUE les logos : les portraits des témoignages restent en
     couleur. */
  filter: grayscale(1);
}

/* ⚠ Médaillon ÉLARGI, pour le seul logo « Les Moulins Bleus » (2026-08-14).
   Les autres logos sont trapus et tiennent dans le rond de 61px. Celui-ci est un
   wordmark manuscrit de 456 × 62, soit 7,35 fois plus large que haut : dans le
   rond, il ne mesurait que 41 × 5,6px — un trait. Le médaillon passe donc à
   124px de large ; le rayon de 30px en fait une pastille allongée au lieu d'un
   rond, ce qui reste dans le vocabulaire du site. Le logo y rend 104 × 14px,
   comparable à ce qu'il donne dans le bandeau de clients (123 × 17).

   ⚠ Ce que ça coûte, mesuré : le rôle de Cyrielle est le plus long des trois
   (« Chargée Marketing et Communication, Les Moulins Bleus ») et passe de deux à
   TROIS lignes, ce qui grandit sa carte de 392 à 399px. Le seuil est à 76px de
   médaillon — en dessous le rôle tient sur deux lignes, mais le logo y est
   illisible (8px de haut). Arbitrage assumé en faveur de la lisibilité du logo. */
.testimonials__logo--wide { width: 124px; }

.testimonials__logo--wide img {
  width: 104px;
  height: auto;
}

.testimonials__role {
  flex: 1 1 auto;
  min-width: 0;
  font-family: var(--font-sans);
  font-style: normal; /* <cite> est italique par défaut ; la source ne l'est pas. */
  font-weight: 500;
  font-size: var(--fs-15);
  line-height: 22.5px;
  letter-spacing: -0.45px;
  color: var(--c-ink);
}

/* ---------- Flèches ----------
   Relevé : conteneur de 90 × 40 (deux boutons de 40, gouttière 10) collé au
   bord DROIT du hublot et remonté de 60, soit exactement dans la gouttière de
   60 qui sépare le titre du carrousel. */
.testimonials__nav {
  position: absolute;
  right: 0;
  top: -60px;
  display: flex;
  gap: 10px;
}

.testimonials__arrow {
  display: grid;
  place-items: center;
  width: 40px;
  height: 40px;
  border-radius: var(--r-pill);
  background: var(--c-ink-alt);
}

/* Les deux chevrons sont les fichiers de la source, déjà employés par #services :
   des tracés blancs de 2px déjà centrés dans un canevas de 40 × 40. Ils occupent
   donc tout le bouton, contrairement à #services qui les réduit à 20. */
.testimonials__arrow img { width: 40px; height: 40px; }

/* ---------- Pastilles de pagination ----------
   Pilule de 130 × 30 centrée sous le hublot (`top: 473px` = 454 + 19, relevé),
   130 = 6 pastilles de 20 + 5 de rab sur la première et la dernière.
   La source pose `overflow: hidden` sur la pilule ; il n'y sert à rien (aucun
   enfant ne dépasse) et rognerait le liseré de focus : écart assumé. */
.testimonials__dots {
  position: absolute;
  left: 50%;
  top: 473px;
  display: flex;
  height: 30px;
  border-radius: 50px;
  background: var(--c-pink);
  transform: translateX(-50%);
}

.testimonials__dot {
  display: grid;
  place-items: center;
  padding: 10px 5px;
}

.testimonials__dot:first-child { padding-left: 10px; }
.testimonials__dot:last-child  { padding-right: 10px; }

.testimonials__dot-mark {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--c-olive-black);
  opacity: 0.5;
  transition: opacity var(--dur-fast) var(--ease-out);
}

.testimonials__dot[aria-current="true"] .testimonials__dot-mark { opacity: 1; }

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

@media (max-width: 1199px) {
  .testimonials { --tm-per-view: 2.5; }

  /* À ce palier la source sort le sticker du flux absolu et le remet EN FLUX,
     centré, collé au-dessus du titre (relevé : `position: relative`, aucun
     décalage, l'intro mesure 184,8 = 80,8 de sticker + 104 de titre). Même
     bascule qu'en comparison.css, à ceci près qu'elle se produit ici dès le
     palier tablette et non seulement en mobile. Dans le markup le sticker
     PRÉCÈDE déjà le titre : aucun `order` n'est nécessaire. Le centrage passe
     par des marges automatiques et non par un `transform`, qui porte déjà la
     rotation. */
  .testimonials__intro {
    width: 600px;
    display: flex;
    flex-direction: column;
    align-items: center;
  }

  .testimonials__sticker {
    position: static;
    display: grid;
    width: max-content;
    margin-inline: auto;
    transform: rotate(-20deg);
  }

  .testimonials__sticker-label {
    font-size: var(--fs-16);
    line-height: 20.8px;
    letter-spacing: -0.64px;
  }

  .testimonials__heading { font-size: var(--fs-52); }

  .testimonials__name {
    font-size: var(--fs-17);
    line-height: 23.8px;
    letter-spacing: -0.34px;
  }

  .testimonials__quote p {
    font-size: var(--fs-20);
    line-height: 26px;
    letter-spacing: -0.8px;
  }
}

@media (max-width: 809px) {
  .testimonials {
    gap: 40px;
    padding: 30px 20px 70px;
    --tm-per-view: 1;
  }

  .testimonials__intro { width: 100%; }

  .testimonials__sticker-label {
    font-size: var(--fs-15);
    line-height: 19.5px;
    letter-spacing: -0.6px;
  }

  /* Seul palier où le titre porte un interlettrage (−1,6px, relevé). */
  .testimonials__heading {
    font-size: var(--fs-42);
    letter-spacing: -1.6px;
  }

  /* Les flèches quittent le coin haut droit et passent au BAS du hublot,
     centrées, dans la bande laissée libre sous la carte (relevé : conteneur
     `left: 0; right: 0; top: 414px`, soit 454 − 40, et boutons centrés). */
  .testimonials__nav {
    left: 0;
    right: 0;
    top: 414px;
    justify-content: center;
  }

  /* La source supprime purement et simplement les pastilles à ce palier :
     la section n'y contient plus que deux boutons, Previous et Next
     (énumération complète des <button> à 390 : 2, contre 8 aux deux autres
     paliers). Retirées de l'accessibilité aussi, pas seulement de l'affichage. */
  .testimonials__dots { display: none; }
}
