/* Les temoignages en plein ecran (Figma 1118:46567 desktop, 1131:49302 mobile).

   Le principe vient des stories Instagram, que Flora a repris explicitement :
   une carte au centre, les voisins en retrait de chaque cote, une barre de
   progression en haut, et deux fleches qui s'eteignent aux extremites. */

.tm-voile {
  position: fixed;
  inset: 0;
  z-index: 60;
  display: none;
  /* Le fond de la page reste lisible dessous, juste efface : c'est un voile
     clair tres flou, pas un noir (I1118:46828 — glassy-light/600 a 0.1 avec
     un flou de 85).

     Le flou de 85 ne vit PAS ici mais sur le calque .tm-fond, premier
     enfant : un backdrop-filter pose sur un ANCETRE fait de lui la racine
     de fond de tous ses descendants, et WebKit ne rend alors plus les
     leurs — les boutons de la barre avaient leur blur(20) calcule mais
     invisible sur iPhone (IMG_7844). C'est la regle deja documentee dans
     progressive-blur.css : rien ne doit filtrer au-dessus d'un element qui
     veut flouter son fond. */
  background: var(--glassy-light-600, rgba(203, 203, 203, 0.1));
  /* LE FOND D'AVANT, remis tel quel (Flora, 22 aout, 22h16 : « remets le
     fond que tu avais mis avant ») : le blur de 85 vit sur le voile
     LUI-MEME, comme en debut de soiree — c'est le rendu qu'elle valide.
     Le calque .tm-fond reste en dessous en redondance : deux mecanismes
     valent mieux qu'un quand l'un peut lacher selon le navigateur.
     Cout assume : un filtre sur le voile refait de lui la racine de fond
     de ses enfants (regle B2), donc le verre des boutons de la barre peut
     ne plus rendre sur iOS — sur un fond deja fondu a 85, leur blanc a
     30% suffit visuellement. Le fond du voile est critique, pas eux. */
  backdrop-filter: blur(85px);
  -webkit-backdrop-filter: blur(85px);
}
/* .tm-fond ne porte plus de flou : enfant d'un voile qui filtre deja, il
   ne peut qu'echantillonner le resultat du voile et flouter une seconde
   fois — le fond passait de « super » a laiteux (85 + 85). Un seul 85,
   celui du voile, comme au debut de soiree. L'element reste pose au cas
   ou une prochaine architecture en ait besoin. */
.tm-fond { position: absolute; inset: 0; }
/* L'arrivee : LA MEME que l'overlay Contact (contact-overlay.css), relue
   image par image sur le GIF d'aparelho le 23 aout — Flora : « fais la meme
   pour les testimonials, les animations doivent etre coherentes entre les
   overlays ». Le voile (flou + teinte) fond seul en 400 ms ; la piste, les
   fleches et la carte isolee n'arrivent qu'ensuite, de 56 px plus bas, avec
   une forte deceleration ; la barre du haut fond avec le voile sans monter.
   La fermeture est la meme chose a l'envers (classe .tm-se-ferme, posee
   par fermer() le temps de l'animation). */
.tm-voile.tm-visible { display: block; animation: tm-voile-in 400ms ease-out both; }
.tm-voile.tm-se-ferme { animation: tm-voile-out 350ms ease-in 120ms both; }
.tm-voile.tm-visible .tm-piste,
.tm-voile.tm-visible .tm-fleche {
  animation: tm-arrive 520ms cubic-bezier(0.16, 1, 0.3, 1) 400ms both;
}
.tm-voile.tm-se-ferme .tm-piste,
.tm-voile.tm-se-ferme .tm-fleche,
.tm-voile.tm-se-ferme .tm-seul { animation: tm-part 320ms cubic-bezier(0.7, 0, 0.84, 0) both; }
@keyframes tm-arrive { from { opacity: 0; translate: 0 56px; } }
@keyframes tm-part   { to   { opacity: 0; translate: 0 40px; } }
@keyframes tm-voile-in  { from { opacity: 0; } }
@keyframes tm-voile-out { to   { opacity: 0; } }

/* Pendant que la fenetre est ouverte, la page dessous ne defile plus.
   `overflow: hidden` seul ne suffit PAS sur iOS : Safari mobile l'ignore
   sur le body et le doigt faisait defiler la home derriere le voile
   (Flora, 22 aout). Le body est donc FIGE en position fixed — sa position
   de defilement est memorisee par testimonials.js (top: -scrollY a
   l'ouverture, restauree a la fermeture), sinon la page sauterait en haut. */
html.tm-fige, html.tm-fige body { overflow: hidden; overscroll-behavior: none; }
html.tm-fige body { position: fixed; left: 0; right: 0; width: 100%; }

/* Le geste vertical appartient a l'INTERIEUR de la carte. PAS de
   `touch-action: none` sur le voile : sur iOS une interdiction posee sur
   un ancetre neutralise aussi le defilement de ses enfants — c'est ce qui
   empechait de faire defiler le contenu du temoignage au doigt (Flora,
   22 aout). Le body etant deja gele en position:fixed, la page ne peut
   de toute facon plus defiler : le seul defilement possible est celui de
   la carte, exactement ce qu'on veut. */
.tm-voile { overscroll-behavior: contain; }
.tm-plein {
  touch-action: pan-y;
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
}

/* La barre du haut pendant un temoignage (variante Nav 1118:46626) : le nom
   a gauche, la croix a droite, et rien d'autre — les boutons About/Approach/
   Contact de la page cedent la place. */
.tm-nav-rang { position: absolute; top: 0; left: 0; padding: var(--space-24); z-index: 2; }
.tm-nom-pill {
  display: inline-flex;
  align-items: center;
  padding: var(--space-6) var(--space-12);
  border-radius: var(--radius-6);
  background: var(--surface-nav-bg);
  backdrop-filter: blur(var(--blur-8, 4px));
  -webkit-backdrop-filter: blur(var(--blur-8, 4px));
  font-family: var(--font-body);
  font-weight: var(--weight-book);
  font-size: var(--body-14-size, 14px);
  line-height: var(--body-14-line, 20px);
  color: var(--nav-default);
  text-decoration: none;
}

/* La barre de la page dessous s'efface pendant le temoignage : sinon ses
   boutons doublonnent avec ceux du voile. */
html.tm-fige .p27-nav,
html.tm-fige .site-nav,
html.tm-fige .nav,
html.tm-fige .p27-menu,
html.tm-fige .p27-index,
html.tm-fige .p27-body,
html.tm-fige .p27-voile { opacity: 0; pointer-events: none; }
/* Et sur la HOME : le hero-flou (v339) pre-floutait le portrait des qu'on
   est scrolle — le voile du slider echantillonnait de la bouillie deja
   floue au lieu de la video nette, et le fond « super » d'avant
   disparaissait (Flora, 22 aout, 22h15). Voile ouvert, il s'eteint :
   l'unique flou redevient celui du voile, sur la video vive.
   `!important` : son opacite est un style inline pilote au scroll. */
html.tm-fige .hero-flou { opacity: 0 !important; }
/* .p27-body aussi : une page projet est deja une feuille givree (verre
   blanc + blur 65 sur ses blocs) — la re-flouter ne donne qu'un aplat gris
   mort, « on ne voit rien » (Flora, 22 aout, 22h11 : nettete zero dans les
   marges). Or la feuille repose sur .p27-fond : l'image de la HOME. En
   l'escamotant pendant le voile, le fond du temoignage isole redevient
   litteralement celui du slider — la home floutee derriere la carte. */
/* Le sommaire du projet DOIT figurer ici : son `view-transition-name` le
   fait peindre PAR-DESSUS le voile malgre un z-index inferieur (mesure du
   22 aout : elementFromPoint donnait la scene, les pixels montraient les
   pilules blanches — capture de Flora a 21h58). Le cacher est le seul
   remede fiable. */

/* ── Le bouton fermer ─────────────────────────────────────────────────────
   Il se pose a la place du bouton de sommaire dans la barre (1118:46837) :
   meme boite, meme verre, meme retrait de 24. */
.tm-fermer-rang {
  position: absolute;
  top: 0;
  right: 0;
  display: flex;
  gap: 6px;
  padding: var(--space-24);
  z-index: 2;
}
/* Les fleches de la rangee du haut : bureau s'en passe (les siennes sont
   posees de part et d'autre de la carte), telephone les montre
   (1131:49572). */
.tm-fleche-h {
  display: none;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  padding: 0;
  border: 0;
  border-radius: var(--radius-6);
  background: rgba(232, 232, 232, 0.94);
  backdrop-filter: blur(20px);
  -webkit-backdrop-filter: blur(20px);
  box-shadow: 0 1px 6px rgba(0, 0, 0, 0.06);
  color: var(--nav-default);
  cursor: pointer;
}
.tm-fleche-h:disabled { opacity: 0.35; cursor: default; }
/* Le bouton pause (1166:41689) : meme boite que les autres, fond
   glassy-dark-500 du node. Fige, il montre le triangle "reprendre". */
.tm-pause {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  padding: 0;
  border: 0;
  border-radius: var(--radius-6);
  background: rgba(232, 232, 232, 0.94);
  backdrop-filter: blur(20px);
  -webkit-backdrop-filter: blur(20px);
  box-shadow: 0 1px 6px rgba(0, 0, 0, 0.06);
  color: var(--nav-default);
  cursor: pointer;
}
.tm-pause .tm-play-ico { display: none; }
.tm-pause.tm-pause--fige .tm-pause-ico { display: none; }
.tm-pause.tm-pause--fige .tm-play-ico { display: block; }
/* ── Les boutons doivent rester lisibles quoi qu'il passe dessous ─────────

   Flora, 24 aout, capture d'iPhone a l'appui : « quand on scroll dans les
   testimonials les boutons ne sont plus visibles du tout ». Le texte du
   temoignage defile derriere eux et les traverse.

   La cause est le piege B2, deja paye ici : le voile porte lui-meme un
   `backdrop-filter`, ce qui fait de lui la racine de fond de tous ses
   descendants — et WebKit cesse alors de rendre LEUR filtre. Sur iPhone, le
   verre des boutons n'existe donc pas ; il ne restait qu'un gris a 30-60 %
   d'opacite, largement traverse par du texte noir.

   On ne remet donc pas le probleme dans les mains du filtre : chaque bouton
   pose d'abord un fond DENSE, qui suffit seul, et garde son flou par-dessus
   pour les navigateurs qui le rendent. Le blur est monte a 20 (le « gros
   blur » demande) et double d'une ombre tres douce, pour que le bouton se
   detache aussi d'un fond clair. */
.tm-fermer {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  padding: 0;
  border: 0;
  border-radius: var(--radius-6);
  background: rgba(232, 232, 232, 0.94);
  backdrop-filter: blur(20px);
  -webkit-backdrop-filter: blur(20px);
  box-shadow: 0 1px 6px rgba(0, 0, 0, 0.06);
  color: var(--nav-default);
  cursor: pointer;
}

/* ── La piste ─────────────────────────────────────────────────────────────
   Un vrai carrousel : les sept temoignages sont la en permanence, la piste
   se centre sur celui qu'on lit, et c'est la MEME carte qui grandit ou
   retrecit d'un cran a l'autre — la carte lue retrecit en vignette pendant
   que la voisine cliquee grandit et prend sa place, exactement comme le GIF
   des stories Instagram que Flora a fourni (22 aout), au lieu de remplacer
   un bloc par un autre.

   Duree et courbe relevees sur ce GIF (14,29 img/s, soit 70ms par image) :
   les transitions y durent 6 a 7 images, 420 a 490ms, avec l'essentiel du
   deplacement dans les 200 premieres ms puis une longue traine — un
   ease-out marque, 450ms sur une courbe expo-out. */
:root {
  --tm-duree: 450ms;
  --tm-courbe: cubic-bezier(0.16, 1, 0.3, 1);
  --tm-mini-w: 137.5px;
  --tm-mini-h: 206.68px;
  --tm-carte-w: 475px;
  /* Releve sur la maquette 1118:46567 : la carte finit a x=877, le premier
     voisin commence a x=957 — 80px d'ecart, soit 24 + la fleche de 32 + 24.
     La piste posant deja 24 de gap, la carte porte 56 de marge de chaque
     cote pour retomber sur ces 80. */
  --tm-marge: 56px;
  /* La hauteur de la barre du voile lui-meme (.tm-fermer-rang : 24 de
     padding, le bouton de 32, 24 de padding) — PAS celle de la nav de la
     page dessous, qui s'efface pendant le temoignage et n'a rien a voir.
     C'est ce 80 que Flora releve sur 1159:24746 : le contenu de la carte,
     sur telephone, commence juste en dessous de CETTE barre-la. */
  --tm-barre-h: calc(32px + var(--space-24) * 2);
}

.tm-scene {
  position: absolute;
  inset: 0;
  padding: var(--space-24);
  overflow: hidden;
}

.tm-piste {
  display: flex;
  align-items: center;
  gap: var(--space-24);
  height: 100%;
  width: max-content;
  will-change: transform;
  transition: transform var(--tm-duree) var(--tm-courbe);
}
.tm-piste.tm-sans-transition { transition: none; }

/* Une carte au repos : la vignette grise du Figma (1127:47187), qui ne porte
   que le visage, 137.5x206.68. Tout ce qui bouge est transitionne sur la
   meme courbe que la piste, pour que la croissance et le glissement ne se
   desynchronisent jamais. */
.tm-item {
  flex: none;
  position: relative;
  width: var(--tm-mini-w);
  height: var(--tm-mini-h);
  border-radius: var(--blur-8, 8px);
  background: var(--glassy-dark-500, rgba(139, 139, 139, 0.2));
  overflow: hidden;
  cursor: pointer;
  transition: width var(--tm-duree) var(--tm-courbe),
              height var(--tm-duree) var(--tm-courbe),
              margin var(--tm-duree) var(--tm-courbe);
}

/* La carte lue : pleine largeur du Figma (475), et toute la hauteur laissee
   par les 24 du haut et du bas que porte la scene — Flora, 22 aout : « 24 en
   haut ET en bas, alignes sur les boutons de la nav ». `100%` se mesure dans
   la boite de la scene, qui porte deja ce padding, juste a tout niveau de
   zoom sans avoir besoin de le connaitre (`calc(100vh - 48px)` ne le donne
   PAS : le body porte un `zoom`, voir layout.css). */
.tm-item.tm-actif {
  width: var(--tm-carte-w);
  height: 100%;
  margin: 0 var(--tm-marge);
  cursor: default;
}

/* Les deux visages d'une carte se croisent : le contenu complet et la
   vignette. Le fondu est plus court que le glissement et decale, pour que le
   texte n'apparaisse qu'une fois la carte presque a sa taille finale. */
.tm-plein, .tm-mini {
  position: absolute;
  inset: 0;
  transition: opacity 260ms var(--tm-courbe);
}
.tm-plein {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: var(--space-24);
  padding: var(--space-24);
  overflow: hidden auto;
  scrollbar-width: none;
  opacity: 0;
  pointer-events: none;
}
.tm-plein::-webkit-scrollbar { display: none; }
.tm-item.tm-actif .tm-plein { opacity: 1; pointer-events: auto; transition-delay: 120ms; }

.tm-mini { display: flex; align-items: center; justify-content: center; opacity: 1; }
/* `pointer-events: none` est vital : invisible (opacite 0), la vignette
   reste HIT-TESTABLE et, posee au-dessus du contenu, elle avalait chaque
   geste — impossible de faire defiler le temoignage au doigt alors que
   tous les styles etaient justes (Flora, 22 aout, verifie par
   elementFromPoint : c'etait elle sous le doigt). */
.tm-item.tm-actif .tm-mini { opacity: 0; transition-delay: 0ms; pointer-events: none; }
.tm-cote-pastille {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 64px;
  height: 64px;
  padding: var(--space-4);
  box-sizing: border-box;
  border: 1px solid var(--border-action);
  border-radius: var(--radius-full, 999px);
}
.tm-cote-pastille img { width: 54px; height: 54px; border-radius: 100px; object-fit: cover; }

/* Ni le haut ni le bas ne se compriment JAMAIS : des enfants flex libres
   de retrecir se replient l'un sur l'autre quand l'ecran est trop court —
   c'est le chevauchement citation/details que Flora a vu sur certains
   portables (22 aout). Interdit, le contenu qui ne tient pas fait defiler
   la carte (overflow deja en place) au lieu de s'ecraser. */
.tm-haut, .tm-bas { flex-shrink: 0; }

.tm-haut { display: flex; flex-direction: column; gap: var(--space-24); }

/* La barre de progression : un segment par temoignage, celui qu'on lit en
   blanc (1118:46915). Chaque carte porte sa propre rangee complete : seule
   celle de la carte active avance, pilotee par testimonials.js. */
.tm-barres { display: flex; gap: var(--space-4); width: 100%; }
.tm-barre {
  position: relative;
  flex: 1 1 0;
  height: 4px;
  border-radius: var(--radius-full, 999px);
  background: var(--glassy-dark-300, rgba(139, 139, 139, 0.6));
  overflow: hidden;
}
.tm-barre--pleine { background: var(--primary-white, #fff); }
.tm-barre-fill {
  position: absolute;
  inset: 0 auto 0 0;
  width: 0;
  border-radius: inherit;
  background: var(--primary-white, #fff);
}

/* Qui parle : la pastille de 64 avec le disque de 54, puis nom et fonction. */
.tm-qui { display: flex; align-items: center; gap: var(--space-16); }
.tm-qui-pastille {
  flex: none;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 64px;
  height: 64px;
  padding: var(--space-4);
  box-sizing: border-box;
  border: 1px solid var(--glassy-black-500);
  border-radius: var(--radius-full, 999px);
}
.tm-qui-pastille img { width: 54px; height: 54px; border-radius: 100px; object-fit: cover; }
.tm-qui-texte { display: flex; flex-direction: column; min-width: 0; }
.tm-nom {
  font-family: var(--font-body);
  font-weight: var(--weight-book);
  font-size: var(--body-16-size, 16px);
  line-height: var(--space-24);
  color: var(--primary-800);
}
.tm-titre {
  font-family: var(--font-body);
  font-weight: var(--weight-regular);
  font-size: var(--body-16-size, 16px);
  line-height: var(--space-24);
  color: var(--greyscale-600, #4d4d4d);
}

/* Le temoignage lui-meme : c'est le H2 du systeme, en noir franc. */
.tm-citation {
  margin: 0;
  font-family: var(--font-headings, var(--font-body));
  font-weight: var(--weight-book);
  font-size: 24px;
  line-height: 30px;
  letter-spacing: -0.24px;
  color: #000;
}
.tm-citation + .tm-citation { margin-top: 0; }

.tm-bas { display: flex; flex-direction: column; gap: var(--space-24); }
.tm-details { display: flex; flex-direction: column; gap: var(--space-8); }
.tm-details-tete {
  margin: 0;
  font-family: var(--font-headings, var(--font-body));
  font-weight: var(--weight-book);
  font-size: 14px;
  line-height: 20px;
  color: var(--glassy-white-200, rgba(255, 255, 255, 0.8));
}
.tm-details-texte {
  margin: 0;
  font-family: var(--font-body);
  font-weight: var(--weight-book);
  font-size: var(--body-16-size, 16px);
  line-height: var(--space-24);
  color: var(--greyscale-600, #4d4d4d);
}

/* L'encart Linkedin (1118:46970) : present sur tous sauf Steve Rodgers. */
.tm-linkedin {
  margin: 0;
  padding: var(--space-12);
  border-radius: var(--radius-6);
  background: var(--glassy-white-500, rgba(255, 255, 255, 0.2));
  font-family: var(--font-body);
  font-style: italic;
  font-size: var(--body-16-size, 16px);
  line-height: var(--space-24);
  color: var(--glassy-black-400);
}

/* ── Les fleches ──────────────────────────────────────────────────────────
   Meme boite que le bouton fermer, en plus sombre (1118:47100), posees a 24
   de la carte centrale. Eteintes, elles restent visibles mais ne repondent
   plus — Flora : « quand c'est le premier temoignage affiche, la fleche
   gauche est disabled, et quand c'est le dernier, pareil pour la droite ». */
.tm-fleche {
  position: absolute;
  top: 50%;
  margin-top: -16px;
  z-index: 2;
  flex: none;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  padding: 0;
  border: 0;
  border-radius: var(--radius-6);
  background: rgba(232, 232, 232, 0.94);
  backdrop-filter: blur(20px);
  -webkit-backdrop-filter: blur(20px);
  box-shadow: 0 1px 6px rgba(0, 0, 0, 0.06);
  color: var(--nav-default);
  cursor: pointer;
}
.tm-fleche:disabled { opacity: 0.35; cursor: default; }
.tm-fleche--prec { right: calc(50% + var(--tm-carte-w) / 2 + var(--space-24)); }
.tm-fleche--suiv { left:  calc(50% + var(--tm-carte-w) / 2 + var(--space-24)); }

/* ── La vue ISOLEE (1167:42523) ───────────────────────────────────────────
   Depuis une page projet, un temoignage s'ouvre SEUL : la meme carte, au
   meme endroit, mais pas de ronde — pas de voisins, pas de fleches (bureau
   comme telephone), pas de barres, pas de pause : « on ne peut slider que a
   partir du composant de la home ou de la page About » (Flora, 22 aout).
   La carte porte les classes tm-item/tm-actif pour heriter de TOUTE la
   geometrie existante, bureau (475, hauteur pleine) comme telephone (plein
   ecran, scene qui defile). */
.tm-seul { display: none; }
/* Le voile isole est LE MEME que partout ailleurs : teinte a 10% + le flou
   de 85 du calque .tm-fond — on voit la page floutee derriere, comme sur la
   home. Le gris opaque a 55% essaye ici le 22 aout effacait tout ("on ne
   voit rien, pas de fond blur") : une sur-correction d'un non-probleme,
   retiree le soir meme. Une cover sombre floutee derriere la carte est un
   fond flou normal, pas un defaut. */
.tm-voile--isole .tm-piste,
.tm-voile--isole .tm-fleche,
.tm-voile--isole .tm-fleche-h,
.tm-voile--isole .tm-pause { display: none; }
/* Le bouton pause disparait avec les barres (Flora, 22 aout, 1170:43224 et
   43266 mobile) : un seul temoignage, rien ne defile, rien a mettre en
   pause. Il ne reste que la croix dans la barre du haut. */
.tm-voile--isole .tm-seul {
  display: block;
  margin: 0 auto;
}
/* AUCUNE regle propre au .tm-plein isole : la carte isolee EST la carte du
   slider (classes tm-item/tm-actif), memes regles partout — Flora, 22 aout :
   « ces deux elements sont les memes et doivent etre lies ». L'ancien
   `position: static` force ici decollait les details du bas de la carte
   sur bureau (le space-between du slider ne jouait plus). Bureau : plein
   absolu qui remplit la carte, details cales en bas ; telephone : la regle
   mobile commune le passe en flux et la scene defile. */
.tm-voile.tm-visible .tm-seul { animation: tm-arrive 520ms cubic-bezier(0.16, 1, 0.3, 1) 400ms both; }

/* Un avatar qui ouvre un temoignage se comporte comme un bouton. */
.tm-declencheur { cursor: pointer; }

/* ── Sur telephone (variante mobile du container, 1159:24746 — a l'echelle
   pleine page, 1131:49302) ────────────────────────────────────────────────
   La carte prend l'ecran ENTIER, sans le retrait de 24 que porte la scene
   sur bureau (Testimonial-Container y va de 0,0 a 393x852, pas d'inset).
   Une seule carte a l'ecran, les fleches disparaissent : on passe d'un
   temoignage a l'autre au doigt (deja cable, `touchstart`/`touchend` sur
   `.tm-scene`).

   Sur bureau, `.tm-plein` distribue l'espace entre le haut et le bas avec
   `justify-content: space-between` : la carte est assez haute pour que ce
   soit invisible. Sur telephone l'ecran est plus petit et Flora a dessine
   un ecart FIXE de 64 a la place — mesure : Top se termine a 466 (80 + 386),
   Bottom commence a 530, l'ecart est 530-466=64. Tout s'aligne donc en haut,
   et le bloc entier defile si le contenu (temoignages a deux paragraphes)
   depasse l'ecran — deja permis par `overflow: hidden auto` sur
   `.tm-plein`, inchange. */
@media (max-width: 900px) {
  /* LE defilement mobile (1131:49599) : c'est la SCENE qui defile — enfant
     direct du voile fixe, sans transform ni overflow intermediaire
     au-dessus d'elle, le seul schema de scroll interne qu'iOS honore sans
     caprice (celui de toutes les modales du web). La carte active sort du
     jeu des couches absolues : son contenu passe en flux normal, la carte
     grandit avec lui, et quand elle depasse l'ecran c'est la scene qui
     porte le geste. Les tentatives precedentes faisaient defiler une
     couche absolue enfouie sous un carrousel transforme — Chrome voulait
     bien, pas les iPhone. */
  .tm-scene {
    padding: 0;
    overflow-y: auto;
    overflow-x: hidden;
    -webkit-overflow-scrolling: touch;
    touch-action: pan-y;
    overscroll-behavior: contain;
  }
  .tm-piste { height: auto; min-height: 100%; align-items: flex-start; }
  .tm-item.tm-actif {
    height: auto;
    min-height: 100vh;
    min-height: 100dvh;
  }
  .tm-item.tm-actif .tm-plein {
    position: static;
    overflow: visible;
    touch-action: auto;
  }
  .tm-fleche { display: none; }
  .tm-fleche-h { display: flex; }
  /* Les pilules de la barre sont plus blanches que le gris 203 des autres
     pages (glassy-white/450, 1131:49572) — mais PAS a 30 % : le blur de 20
     pose ci-dessous ne rend pas sur iPhone (le voile porte deja un filtre,
     piege B2), et a 30 % le texte de la citation traversait les boutons.
     Flora, 24 aout, capture a l'appui. Le blanc reste, son opacite tient
     toute seule. */
  .tm-nom-pill, .tm-fermer, .tm-pause { background: rgba(255, 255, 255, 0.92); }
  /* Flora, 22 aout (1131:49574) : « mets un gros blur dans le background
     car on doit toujours voir la nav ». Le flou est la, et il rend partout
     ou le navigateur l'accepte ; il ne porte simplement plus seul la
     lisibilite, puisque iOS ne le rend pas ici. */
  .tm-nom-pill, .tm-fleche-h, .tm-pause, .tm-fermer {
    backdrop-filter: blur(20px);
    -webkit-backdrop-filter: blur(20px);
    box-shadow: 0 1px 6px rgba(0, 0, 0, 0.06);
  }
  .tm-fleche-h { background: rgba(255, 255, 255, 0.92); }
  /* La regle etablie sur tout le site (Flora, 22 aout, deja appliquee aux
     nav des pages et au Project index) : sur telephone, TOUS les boutons
     de nav font 36 de haut avec un corps de 16 — ceux du voile testimonial
     ne font pas exception. */
  .tm-nom-pill { padding: 8px var(--space-12); font-size: 16px; line-height: 20px; }
  .tm-fleche-h, .tm-fermer, .tm-pause { width: 36px; height: 36px; }
  :root {
    --tm-carte-w: 100vw;
    --tm-marge: 0px;
  }
  .tm-item.tm-actif { width: 100vw; margin: 0; }
  /* 24 a gauche et a droite, comme partout ailleurs sur la carte (Top et
     Bottom sont tous deux inset de 24 dans la maquette) ; 80 en haut, la
     hauteur exacte de la barre "Nav" du mobile (1131:49590) qui recouvre le
     sommet de l'ecran — le texte ne doit jamais passer derriere elle. */
  .tm-plein {
    padding: var(--tm-barre-h) var(--space-24) var(--space-24);
    gap: 64px;
    justify-content: flex-start;
  }
  .tm-citation { font-size: 24px; line-height: 30px; }
}

/* ── Ecrans courts (bureau) ───────────────────────────────────────────────
   La hauteur des portables varie (900, 800, 720...) : plutot que de faire
   defiler les longs temoignages, la citation descend d'un cran de corps —
   le reglage d'Instagram sur les petites hauteurs. Les seuils sont des
   hauteurs REELLES de machines courantes ; le zoom de layout.css croit
   avec la LARGEUR, donc a largeur egale ces seuils restent justes. */
@media (min-width: 901px) and (max-height: 900px) {
  .tm-citation { font-size: 20px; line-height: 26px; letter-spacing: -0.2px; }
}
@media (min-width: 901px) and (max-height: 760px) {
  .tm-citation { font-size: 18px; line-height: 24px; letter-spacing: -0.18px; }
  .tm-details-texte, .tm-linkedin { font-size: 14px; line-height: 20px; }
}

/* Flora, 22 aout : « le nom n'apparait QUE au hover, il n'est jamais visible
   si on n'a pas notre souris dessus ». Il restait affiche apres la fermeture
   parce qu'on rend le focus a l'avatar en sortant, et la regle de nav.css
   montre l'infobulle sur `:focus-within`. `:focus-visible` ne repond qu'au
   clavier, donc un focus rendu a la souris ne l'allume plus. */
.testimonial:focus-within .testimonial-name { opacity: 0; }
.testimonial:hover .testimonial-name,
.testimonial:has(:focus-visible) .testimonial-name { opacity: 1; }
