/* ============================================================================
   Bloc sombre — section « Témoignages ».
   Node Figma 2868:12485. Le fond bascule en marron : c'est la rupture
   visuelle qui sépare l'offre (crème) de la preuve (sombre).
   ========================================================================= */

.section--dark {
  background: var(--c-brown);
  color: var(--c-cream);
}

/* Deux blocs sombres qui se touchent : quand leur arête tombe sur un pixel
   fractionnaire (Safari, écrans à 3x), le fond de page crème filtre en un
   filet clair. Le bloc du dessous déborde d'un pixel vers le haut, dans le
   marron du bloc précédent — aucun effet sur la mise en page. */
.section--dark + .section--dark {
  box-shadow: 0 -1px 0 var(--c-brown);
}


/* ── Bandeau : compteur + navigation ───────────────────────────────────── */
.tm__head {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-24);
  padding: var(--sp-16) var(--sp-24);
  border: 1px solid var(--c-border-inv);
  border-radius: var(--r-lg);
}

.tm__count {
  color: var(--c-cream);
  text-transform: uppercase;
  white-space: nowrap;
}

.tm__nav {
  display: flex;
  gap: var(--sp-4);
}

.tm__arrow {
  display: grid;
  place-items: center;
  inline-size: 28px;
  block-size: 28px;
  border-radius: var(--r-sm);
  background: var(--c-brown-light);
  color: var(--c-cream);
  transition:
    background-color var(--d-micro) var(--e-inout),
    color var(--d-micro) var(--e-inout);
}

.tm__arrow svg {
  inline-size: 10.5px;
  block-size: 16px;
  transition: transform var(--d-micro) var(--e-out);
}

/* Une seule icône dans la bibliothèque : la suivante est la précédente
   pivotée, exactement comme dans la maquette. */
.tm__arrow--next svg {
  transform: rotate(180deg);
}

.tm__arrow:hover:not(:disabled) {
  background: var(--c-orange);
}

.tm__arrow:focus-visible {
  outline: 2px solid var(--c-cream);
  outline-offset: 3px;
}

.tm__arrow:disabled {
  opacity: 0.3;
  cursor: default;
}

/* ── Rail ──────────────────────────────────────────────────────────────
   Pleine largeur, rogné au bord du viewport : le témoignage suivant
   affleure, c'est ce qui annonce qu'il y en a d'autres. */
.tm__viewport {
  container-type: inline-size;
  margin-block-start: var(--sp-16);
  overflow-x: clip;
}

.tm__rail {
  --shell-inset: max(
    var(--gutter),
    calc((100cqi - var(--shell-max)) / 2 + var(--gutter))
  );
  padding-inline-start: var(--shell-inset);
  /* Symétrique du retrait de gauche : en fin de course la dernière slide
     s'arrête sur le bord de la coquille au lieu de coller au bord de
     l'écran. Sans effet visuel propre — le rail déborde — mais c'est la
     valeur que le script lit pour borner la course. */
  padding-inline-end: var(--shell-inset);
}

/* Le rail se déplace en `transform`, pas en `scrollLeft` : c'est ce qui
   permet de maîtriser exactement la courbe et la durée du glissement. */
.tm__track {
  display: flex;
  align-items: stretch;
  gap: var(--sp-64);
  inline-size: max-content;
  /* Main ouverte au repos, main fermée pendant le glissement : c'est la
     seule chose qui annonce que le rail se manipule. */
  cursor: grab;
  transform: translate3d(calc(-1 * var(--tm-x, 0px)), 0, 0);
  transition: transform var(--d-slide) var(--e-out);
}

.tm__track[data-dragging] {
  transition: none;
  cursor: grabbing;
  /* Pendant le glissement seulement : hors de là, la citation doit rester
     sélectionnable et copiable. */
  user-select: none;
}

/* Le glisser natif d'image vole le geste au rail : on le neutralise.
   `-webkit-user-drag` couvre WebKit et Chromium ; l'écouteur `dragstart`
   posé côté JS couvre Firefox, qui ne connaît pas cette propriété. */
.tm__track img {
  -webkit-user-drag: none;
  user-select: none;
}

.tm-slide {
  flex: none;
  display: flex;
  gap: var(--sp-16);
  /* 1116 = 300 (photo) + 16 (gap) + 800 (carte). */
  inline-size: min(1116px, 100cqi - 2 * var(--gutter));
}

/* ── Portrait ──────────────────────────────────────────────────────────── */
.tm-slide__photo {
  /* Plafond de la contre-translation. Le JS applique la même borne : c'est
     cette valeur qui dimensionne la marge de couverture ci-dessous. */
  --par-max: 10px;

  position: relative;
  flex: none;
  inline-size: 300px;
  block-size: 400px;
  margin: 0;
  border-radius: var(--r-lg);
  overflow: clip;
  background: var(--c-brown-light);
}

.tm-slide__photo img {
  /* L'image déborde volontairement du cadre de part et d'autre, plutôt que
     d'être agrandie : le sujet garde exactement le cadrage de la maquette,
     et la contre-translation ne peut jamais découvrir un bord.
     4 px de sécurité au-delà de la course, contre les arrondis sous-pixel. */
  inline-size: calc(100% + 2 * (var(--par-max) + 4px));
  /* Le reset global plafonne les images à 100 % : il faut lever ce plafond,
     sinon la largeur ci-dessus est ignorée et le débord disparaît. */
  max-inline-size: none;
  margin-inline-start: calc(-1 * (var(--par-max) + 4px));
  block-size: 100%;
  object-fit: cover;
  /* Contre-translation : la photo traîne derrière le rail. */
  transform: translate3d(var(--tm-par, 0px), 0, 0);
  transition: transform var(--d-slide) var(--e-out);
}

.tm__track[data-dragging] .tm-slide__photo img {
  transition: none;
}

.tm-slide__photo::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(
    180deg,
    rgb(0 0 0 / 0) 40%,
    rgb(0 0 0 / 0.45) 72%,
    rgb(0 0 0 / 0.88) 100%
  );
  pointer-events: none;
}

.tm-slide__caption {
  position: absolute;
  inset-block-end: var(--sp-16);
  inset-inline-start: var(--sp-16);
  z-index: var(--z-scrim);
  display: flex;
  flex-direction: column;
  gap: var(--sp-4);
  color: var(--c-cream);
  text-transform: uppercase;
  white-space: nowrap;
}

.tm-slide__role {
  opacity: 0.4;
}

/* ── Carte citation ────────────────────────────────────────────────────── */
.tm-slide__card {
  position: relative;
  flex: 1 1 auto;
  min-inline-size: 0;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  margin: 0;
  padding: var(--sp-48) var(--sp-64);
  background: var(--c-brown-light);
  border-radius: var(--r-lg);
  overflow: clip;
}

/* Guillemet géant : un tracé au trait à 5 % — le même filet que
   `--c-border-inv`, d'où la couleur prise sur le token. */
.tm-slide__quote {
  position: absolute;
  inset-block-start: 50%;
  inset-inline-start: -41.5px;
  inline-size: 856px;
  block-size: 712px;
  translate: 0 -50%;
  pointer-events: none;
  stroke: var(--c-border-inv);
  fill: none;
}

.tm-slide__text,
.tm-slide__meta {
  position: relative; /* au-dessus du guillemet */
}

.tm-slide__meta {
  display: flex;
  flex-direction: column;
  font-size: var(--fs-body-lg);
  line-height: var(--lh-body);
}

/* Même traitement que les autres liens en ligne (voir .blocage__lien) : crème,
   gras, trait animé et flèche ↗ au survol (voir base.css). */
.tm-slide__link {
  color: var(--c-cream);
  font-variation-settings: "wght" var(--fw-bold), "opsz" var(--opsz-display);
  letter-spacing: var(--ls-tight);
  text-decoration: none;
  align-self: flex-start;
}

.tm-slide__client {
  color: var(--c-ink-inv-2);
  font-style: normal;
}

@container (max-width: 1023px) {
  .tm-slide__card {
    padding: var(--sp-32);
  }

  .tm-slide__quote {
    inline-size: 620px;
    block-size: 516px;
  }
}

@container (max-width: 767px) {
  .tm-slide {
    flex-direction: column;
  }

  .tm-slide__photo {
    inline-size: 100%;
    block-size: 260px;
  }
}

@media (prefers-reduced-motion: reduce) {
  .tm__track,
  .tm-slide__photo img {
    transition-duration: 200ms;
  }

  .tm-slide__photo img {
    transform: none;
  }
}
