/* ============================================================
   AM Agency — accueil : styles propres à la page d'accueil (chargée seulement sur /, functions.php).
   Porté de la maquette validée g-immersive. Lit seulement les variables de tokens.css.
   Sans JavaScript et en mouvement réduit, tout est visible dans son état final.
   Seuls transform, opacity et filter sont animés ; une règle d'effet de défilement porte « defilement »
   en commentaire sur la ligne qui l'ouvre, la lueur porte « lueur » (règles de .claude/controles-refonte.sh).

   Trois blocs, un propriétaire chacun (écrire seulement dans son bloc, entre ses deux bornes) :
     1. Enchaînement des couches          (chef d'équipe « accueil »)
     2. Haut de la page                   (ouvrier « accueil-haut » : haut de page, réalisations, pour qui, IA)
     3. Bas de la page                    (ouvrier « accueil-bas » : méthode, avis, équipe, questions)
   ============================================================ */


/* ============================================================
   1. ENCHAÎNEMENT DES COUCHES — début (chef d'équipe « accueil »)
   Fonds alternés : haut bg · posséder band · réalisations surface · pour qui band · IA surface ·
   méthode bg · avis band · équipe surface · questions bg · bouton final brand (front-page.php).
   Sur ordinateur, chaque couche du milieu fait au moins un écran et chacun de ses blocs s'efface juste
   avant que la suivante l'atteigne (effacement général : assets/js/motion.js, erase).
   ============================================================ */
@media (prefers-reduced-motion: no-preference) { /* defilement */
  .js #louer-ou-posseder, .js #pour-qui, .js #ia, .js #methode,
  .js #avis, .js #equipe, .js #questions {
    min-height: 100svh;
    display: grid; align-content: center;
  }
  /* Avis sans bande de cartes (moins de 3 avis, extension absente : home-reviews.php pose .avis-court) :
     hauteur au contenu, jamais un écran vide autour d'un titre et d'un bouton. */
  .js #avis.avis-court { min-height: 0; }
  /* Questions : contenu calé en haut, sinon ouvrir une réponse fait remonter la question cliquée. */
  .js #questions { align-content: start; }
  /* Bouton final et pied de page remplissent au moins l'écran : rien ne reste en haut en fin de page. */
  .js #contact.layer { min-height: calc(100svh - var(--foot-h, 0px)); display: grid; align-content: center; }

  .js #louer-ou-posseder .intro[data-reveal], .js #realisations .intro[data-reveal],
  .js #pour-qui .intro[data-reveal], .js #ia .intro[data-reveal], .js #methode .intro[data-reveal],
  .js #avis .intro[data-reveal], .js #equipe .intro[data-reveal],
  .js #questions .intro[data-reveal] { transition-delay: 240ms; }
}

/* Tablette et téléphone : les couches du milieu ne collent plus (layout.css), aucune hauteur imposée. */
@media (prefers-reduced-motion: no-preference) and (max-width: 1023px) { /* defilement */
  .js #louer-ou-posseder, .js #pour-qui, .js #ia, .js #methode,
  .js #avis, .js #equipe, .js #questions, .js #contact.layer { min-height: 0; }
}

/* Débord horizontal : ce qui entre par le côté (bande d'avis, fondateurs, lueur du haut de page) est coupé
   au bord de sa couche. clip, pas hidden : aucune zone de défilement créée, les éléments collants restent collants. */
main > .layer > .layer-body { overflow-x: clip; }
/* 1. ENCHAÎNEMENT DES COUCHES — fin */




/* ============================================================
   2. HAUT DE LA PAGE — début (ouvrier « accueil-haut »)
   Haut de page (#haut, home-hero.php), trois réalisations (#realisations, home-cases.php),
   pour qui (#pour-qui, home-targets.php), avec ou sans IA (#ia, home-ai.php).
   ============================================================ */

/* ---------- Haut de page : texte animé seulement, aucune capture (SPEC.md décision 10 bis) ---------- */
.hero {
  /* « Vos outils s’adaptent » (la ligne la plus longue) mesure 8,41 em : 8,5 la fait tenir dans la largeur.
     100cqi = largeur de .layer-body (conteneur ci-dessous), barre de défilement déduite : 100vw la compte,
     et sur Windows ou un Mac avec souris la ligne passait à la ligne entre 1024 et 1390 px. Sans barre,
     même taille qu'avant. Lu par .hero-title et .hero-glow, tous deux dans le conteneur. */
  --hero-fs: min(9.5rem, calc((100cqi - 2 * var(--gutter)) / 8.5));
  --hero-range: 75vh;     /* course du défilement sur laquelle le titre se resserre */
  --title-rise: -9vh;     /* le titre remonte plus vite que le texte : profondeur */
  --title-shrink: 0.92;
  --text-rise: -4vh;
  background: var(--bg);
}
/* Un écran plein ; l'en-tête est posé en fixed par-dessus, sa hauteur est réservée. */
.hero > .layer-body {
  container-type: inline-size;
  display: flex; flex-direction: column; justify-content: center;
  min-height: 100svh;
  padding-top: calc(var(--header-h) + env(safe-area-inset-top, 0px) + var(--sp-5));
  padding-bottom: var(--sp-7);
}
.hero-grid {
  position: relative;
  isolation: isolate;          /* la lueur reste derrière le texte, jamais derrière la couche */
  display: grid;
  grid-template-columns: minmax(0, 1fr);
}
.hero-title {
  font-size: var(--hero-fs);
  line-height: 1;
  letter-spacing: -0.03em;
  transform-origin: 0 100%;
}
/* Deux lignes de même longueur : pas de nowrap, si la police manque la ligne passe à la ligne. */
.hero-line { display: block; }
.hero-flip { display: inline-block; transform-origin: 50% 55%; }

.hero-text { margin-top: var(--sp-7); }
.hero-lede { font-size: var(--fs-lg); color: var(--ink-soft); max-width: 32rem; }
.hero-actions { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-4) var(--sp-6); margin-top: var(--sp-6); }
.hero-proof { display: flex; flex-wrap: wrap; gap: var(--sp-2) var(--sp-6); margin-top: var(--sp-6); color: var(--ink-soft); }
.hero-proof li { display: inline-flex; align-items: center; gap: var(--sp-2); }
.hero-proof-icon { width: 20px; height: 20px; color: var(--label); }
.hero-proof strong { color: var(--ink); font-weight: 600; }

/* La seule lueur du haut de page : un élément de couleur pleine, flouté, derrière le titre (aucun dégradé),
   avec un cœur bleu frais à faible opacité. Même recette que la lueur du bouton final (sections.css). */
.hero-glow {
  position: absolute; z-index: -1;
  top: calc(var(--hero-fs) * -0.3);
  left: 8%;
  width: 62%;
  height: calc(var(--hero-fs) * 2.6);
  border-radius: 50%;
  background: var(--glow-brand); /* lueur */
  filter: blur(96px);
  opacity: 0.7;
  pointer-events: none;
}
.hero-glow::after {
  content: "";
  position: absolute; inset: 30% 25%;
  border-radius: 50%;
  background: var(--glow-fresh); /* lueur */
}

/* Ordinateur : sous le titre, l'introduction à gauche, l'action et la preuve à droite. */
@media (min-width: 1024px) {
  .hero-text {
    display: grid;
    grid-template-columns: repeat(12, minmax(0, 1fr));
    column-gap: var(--sp-6);
    align-items: start;
  }
  .hero-lede { grid-column: 1 / span 5; grid-row: 1 / span 2; }
  .hero-actions { grid-column: 7 / -1; grid-row: 1; margin-top: 0; }
  .hero-proof { grid-column: 7 / -1; grid-row: 2; margin-top: var(--sp-5); }
}
@media (min-width: 640px) and (max-width: 1023px) {
  .hero-text { max-width: 40rem; margin-top: var(--sp-6); }
  .hero-actions, .hero-proof { margin-top: var(--sp-5); }
  .hero-glow { width: 80%; left: 0; filter: blur(72px); }
}
@media (max-width: 639px) {
  .hero { --title-rise: -6vh; --title-shrink: 0.95; --text-rise: -3vh; --hero-range: 60vh; }
  .hero > .layer-body { padding-bottom: var(--sp-6); }
  .hero-glow { left: -10%; width: 110%; filter: blur(56px); }
  .hero-text { margin-top: var(--sp-6); }
  .hero-lede { line-height: 1.5; }
  .hero-actions { gap: var(--sp-2); }
  .hero-actions .btn { width: 100%; }
  .hero-proof { margin-top: var(--sp-4); gap: var(--sp-1) var(--sp-5); }
}
/* Téléphone court (320 × 568, 360 × 600) : au premier passage, le bandeau cookies couvre le bas de l'écran. Le
   haut de page se cale sous l'en-tête et se resserre sur l'échelle de 4 px : le bouton d'audit (48 px, une
   ligne) et les deux preuves finissent entiers au-dessus du bandeau. */
@media (max-width: 639px) and (max-height: 640px) {
  .hero > .layer-body { justify-content: flex-start; padding-top: calc(var(--header-h) + env(safe-area-inset-top, 0px) + var(--sp-2)); }
  .hero-text { margin-top: var(--sp-3); }
  .hero-lede { font-size: 1rem; line-height: 1.4; }
  .hero-actions { margin-top: var(--sp-3); gap: var(--sp-1); }
  .hero-actions .btn-lg { min-height: 48px; }
  .hero-proof { margin-top: var(--sp-2); gap: var(--sp-1) var(--sp-5); font-size: var(--fs-sm); line-height: 1.4; }
}
/* Écran étroit (moins de 360 px) : « Audit gratuit de vos outils » tient sur une ligne. */
@media (max-width: 359px) {
  .hero-actions .btn-lg { padding-inline: var(--sp-4); font-size: 1rem; }
}

/* Entrée puis défilement. Mouvement réduit ou sans JavaScript : tout visible, à l'endroit, immobile. */
@media (prefers-reduced-motion: no-preference) { /* defilement */
  /* Ligne 1 et « à vous. » : chaque mot monte derrière son masque (cascade de 45 ms). */
  .js .hero-title .mask-in { transition-duration: 680ms; transition-delay: calc(var(--w, 0) * 45ms); }
  /* « Pas l’inverse. » : ses mots ne montent pas, la ligne entière se retourne. */
  .js .hero-title .hero-flip .mask-in { transform: none; transition: none; }
  .js .hero-title:not(.is-in) .hero-flip { opacity: 0; }
  .js .hero-title.is-in .hero-flip { animation: ama-hero-flip 1100ms var(--ease-out) 360ms both; }

  /* Introduction, actions, preuve : en cascade de 60 ms juste derrière le titre. */
  .js .hero-text > [data-reveal] { transition-duration: 640ms; transition-delay: calc(600ms + var(--i, 0) * 60ms); }
  .js .hero-text > [data-reveal]:not(.is-in) { transform: translateY(24px); }

  /* Repli sans animation-timeline : --hp (0 → 1) écrit par accueil.js. */
  .js .hero-title {
    transform: translateY(calc(var(--title-rise) * var(--hp, 0))) scale(calc(1 - (1 - var(--title-shrink)) * var(--hp, 0)));
    opacity: calc(1 - 0.45 * var(--hp, 0));
  }
  .js .hero-text { transform: translateY(calc(var(--text-rise) * var(--hp, 0))); }
  .js .hero-glow { opacity: calc(0.7 - 0.2 * var(--hp, 0)); transform: scale(calc(1 + 0.12 * var(--hp, 0))); }

  /* Même effet calculé hors du fil principal ; la timeline vient après le raccourci « animation ». */
  @supports (animation-timeline: scroll()) {
    .js.sda .hero-title.is-split, .js.sda .hero-text, .js.sda .hero-glow {
      animation: linear both;
      animation-timeline: scroll(root);
      animation-range: 0 var(--hero-range);
    }
    .js.sda .hero-title.is-split { animation-name: ama-hero-title-out; }
    .js.sda .hero-text { animation-name: ama-hero-text-out; }
    .js.sda .hero-glow { animation-name: ama-hero-glow-out; }
  }
}
/* À l'envers d'abord (« l'inverse »), 300 ms le temps de la voir retournée, puis remise à l'endroit. */
@keyframes ama-hero-flip { /* defilement */
  0%   { opacity: 0; transform: perspective(900px) rotateX(180deg); }
  27%  { opacity: 1; transform: perspective(900px) rotateX(180deg); }
  100% { opacity: 1; transform: perspective(900px) rotateX(0deg); }
}
@keyframes ama-hero-title-out { /* defilement */
  from { transform: none; opacity: 1; }
  to   { transform: translateY(var(--title-rise)) scale(var(--title-shrink)); opacity: 0.55; }
}
@keyframes ama-hero-text-out { from { transform: none; } to { transform: translateY(var(--text-rise)); } }
@keyframes ama-hero-glow-out { from { opacity: 0.7; transform: scale(1); } to { opacity: 0.5; transform: scale(1.12); } }

/* ---------- Trois réalisations ----------
   Sans JavaScript (et base de tout) : une rangée par réalisation, capture à côté de son texte.
   Ordinateur avec JavaScript : accueil.js range les captures dans une scène collante (.case-stage) à droite ;
   les textes défilent à gauche, la capture suit. Tablette et téléphone : chaque capture au-dessus de son texte. */
.cases { display: flex; flex-direction: column; gap: var(--sp-9); }
.case {
  display: grid;
  grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
  gap: var(--sp-8);
  align-items: center;
}
.case-flip { grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); }
.case-flip .shot { order: 2; }
.case-text { position: relative; min-width: 0; }
.case-name { font-size: var(--fs-3); line-height: 1.15; overflow-wrap: break-word; hyphens: auto; }
.case .badges { margin-top: var(--sp-3); }
.case-block { margin-top: var(--sp-5); }
.case-label { font-size: var(--fs-sm); font-weight: 600; color: var(--muted); }
.case-label-built { color: var(--label); }
.case-block p + p { margin-top: var(--sp-1); }
.case-before { color: var(--muted); }
.case-built { color: var(--ink); }
/* Le lien et le bouton sont dans une enveloppe révélée : leur propre transition reste celle du toucher. */
.case-more { margin-top: var(--sp-5); }
.cases-all { margin-top: var(--sp-9); }

/* Ordinateur avec JavaScript : la scène collante. */
@media (min-width: 1024px) {
  .cases.has-stage {
    display: grid;
    grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
    column-gap: var(--sp-8);
    row-gap: 0;               /* lignes jointives : le milieu de l'écran est toujours dans un texte */
    container-type: inline-size;
  }
  .has-stage > .case {
    grid-column: 1;
    display: flex; align-items: center;
    min-height: 80vh;         /* chaque réalisation se lit seule */
  }
  .has-stage .case-text {
    width: 100%;
    isolation: isolate;       /* la carte (::before) reste derrière ce texte */
    padding: var(--sp-7) var(--sp-6);
  }
  /* Le texte en cours est posé sur une carte (surface plus claire, ombre douce) ; seule son opacité change. */
  .has-stage .case-text::before {
    content: "";
    position: absolute; inset: 0; z-index: -1;
    border-radius: var(--radius-lg);
    background: var(--surface-2);
    box-shadow: var(--shadow-card);
    opacity: 0;
  }
  .has-stage .case.is-active .case-text::before { opacity: 1; }
  /* Une seule capture visible, centrée sous l'en-tête. Hauteur du cadre = largeur de sa colonne × 10/16
     (cqi = largeur de .cases) ; 4,5rem pour la légende. */
  .case-stage {
    grid-column: 2;
    grid-row: 1 / span 3;
    align-self: start;
    position: sticky;
    top: max(
      calc(var(--header-h) + var(--sp-5)),
      calc((100vh + var(--header-h) - (100cqi - var(--sp-8)) * 7 / 12 * 10 / 16 - 4.5rem) / 2)
    );
    display: grid;
  }
  .case-stage > .shot { grid-area: 1 / 1; opacity: 0; visibility: hidden; }
  .case-stage > .shot.is-current { z-index: 1; opacity: 1; visibility: visible; }
}
/* Changement de capture : fondu, légère échelle et léger flou ; le texte qui n'est pas en cours reste
   lisible à 0,75 d'opacité (≥ 4,5:1 sur la surface). */
@media (min-width: 1024px) and (prefers-reduced-motion: no-preference) { /* defilement */
  .has-stage .case-text { opacity: 0.75; transition: opacity var(--d-swap) var(--ease-out); }
  .has-stage .case.is-active .case-text { opacity: 1; }
  .has-stage .case-text::before { transition: opacity var(--d-swap) var(--ease-out); }
  .case-stage > .shot {
    transform: scale(0.96);
    filter: blur(6px);
    transition: opacity var(--d-swap) var(--ease-out), transform var(--d-swap) var(--ease-out),
      filter var(--d-swap) var(--ease-out), visibility 0s linear var(--d-swap);
  }
  .case-stage > .shot.is-current { transform: none; filter: none; transition-delay: 0s; }
}
/* Mouvement réduit : la scène reste, la capture change par un fondu court, tous les textes en plein. */
@media (min-width: 1024px) and (prefers-reduced-motion: reduce) {
  .case-stage > .shot { transition: opacity var(--d-out) ease, visibility 0s linear var(--d-out); }
  .case-stage > .shot.is-current { transition-delay: 0s; }
  .has-stage .case-text::before { transition: opacity var(--d-out) ease; }
}

@media (max-width: 1023px) {
  .case, .case-flip { grid-template-columns: minmax(0, 1fr); gap: var(--sp-5); }
  .case-flip .shot { order: 0; }
  .case-text { max-width: 40rem; }
}
@media (max-width: 639px) {
  .cases { gap: var(--sp-8); }
  .cases-all .btn { width: 100%; }
}
/* Tablette et téléphone : la capture grandit en entrant (0,92 → 1) et s'éclaircit, sans flou. L'effet porte
   sur le cadre seul, mesuré sur lui seul : la capture est nette et en pleine lumière dès qu'elle est entière à
   l'écran, même quand sa légende (trois lignes au téléphone) est encore sous le bas de l'écran. */
@media (max-width: 1023px) and (prefers-reduced-motion: no-preference) { /* defilement */
  .js .case .shot-frame { transform-origin: 50% 100%; }
  .js:not(.sda) .case .shot-frame {
    opacity: calc(0.25 + 0.75 * var(--p, 1));
    transform: scale(calc(0.92 + 0.08 * var(--p, 1)));
  }
  @supports (animation-timeline: view()) {
    .js.sda .case .shot-frame {
      animation: ama-case-rise linear both;
      animation-timeline: view();
      animation-range: entry 0% entry 100%;
    }
  }
}
@keyframes ama-case-rise { from { opacity: 0.25; transform: scale(0.92); } to { opacity: 1; transform: none; } }

/* ---------- Pour qui : trois portes, en cascade (data-stagger) ; le survol soulève la carte ---------- */
.doors { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--sp-5); }
.doors > li { display: flex; min-width: 0; }
.door {
  position: relative;
  isolation: isolate;
  flex: 1;
  min-width: 0;
  display: flex; flex-direction: column;
  padding: var(--sp-6);
  border-radius: var(--radius-lg);
  background: var(--surface-sunk);
  box-shadow: var(--shadow-shot);
  color: inherit;
  transition: transform var(--d-base) var(--ease-out);
}
/* Ombre qui s'approfondit : l'opacité d'une ombre posée d'avance change, pas box-shadow. */
.door::before {
  content: "";
  position: absolute; inset: 0; z-index: -1;
  border-radius: inherit;
  box-shadow: var(--shadow-lift);
  opacity: 0;
  transition: opacity var(--d-base) ease;
  pointer-events: none;
}
.door-name { font-size: var(--fs-4); line-height: 1.2; overflow-wrap: break-word; hyphens: auto; }
.door-text { margin-top: var(--sp-3); color: var(--muted); overflow-wrap: break-word; }
.door-link {
  display: inline-flex; align-items: center; gap: var(--sp-2);
  min-height: 44px; margin-top: auto; padding-top: var(--sp-5);
  font-weight: 600; color: var(--ink);
  transition: transform var(--d-base) var(--ease-out);
}
.door-arrow { width: 20px; height: 20px; transition: transform var(--d-base) var(--ease-out); }
.door:focus-visible { outline: 2px solid var(--label); outline-offset: 3px; }
.door:active { transform: scale(0.97); transition-duration: var(--d-press); }
@media (hover: hover) and (pointer: fine) {
  .door:hover, .door:focus-visible { transform: translateY(-6px); }
  .door:hover:active { transform: translateY(-6px) scale(0.97); }
  .door:hover::before, .door:focus-visible::before { opacity: 1; }
  .door:hover .door-link { color: var(--label); transform: translateX(4px); }
  .door:hover .door-arrow { transform: translateX(4px); }
}
@media (max-width: 1023px) {
  .doors { grid-template-columns: minmax(0, 1fr); }
}
@media (max-width: 639px) {
  .door { padding: var(--sp-5); }
}

/* ---------- Avec ou sans IA : deux surfaces côte à côte ---------- */
#ia .section-head h2 { overflow-wrap: anywhere; }  /* un mot long n'élargit jamais la page à 320 px */
.ai-pair {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--sp-5);
  align-items: stretch;
}
.ai-block { min-width: 0; padding: var(--sp-7) var(--sp-6); border-radius: var(--radius-lg); }
/* « Avec IA » en relief (surface claire, ombre), « Sans IA » posé dans une surface creusée. */
.ai-with    { background: var(--surface-2); box-shadow: var(--shadow-shot); }
.ai-without { background: var(--surface-sunk); }
.ai-label { font-size: var(--fs-3); line-height: 1.15; }
.ai-text  { margin-top: var(--sp-4); color: var(--ink-soft); max-width: 34rem; overflow-wrap: break-word; }
@media (max-width: 639px) {
  .ai-pair { grid-template-columns: minmax(0, 1fr); gap: var(--sp-4); }
  .ai-block { padding: var(--sp-6) var(--sp-5); }
}
/* Paragraphe qui s'écrit : accueil.js découpe les mots (.ai-word, --d = départ en ms, --dn = temps jusqu'au
   mot suivant) et pose .is-typing quand le bloc est bien à l'écran. Sans JavaScript et en mouvement réduit,
   le texte n'est jamais découpé, donc affiché d'emblée. Les mots gardent leur place (opacité seulement). */
.ai-word { position: relative; }
@media (prefers-reduced-motion: no-preference) { /* defilement */
  .js .ai-type.is-split .ai-word { opacity: 0; }
  .js .ai-type.is-typing .ai-word { animation: ama-ai-word 140ms var(--ease-out) calc(var(--d) * 1ms + 120ms) both; }
  /* Curseur discret en bleu frais : il suit le dernier mot écrit, clignote deux fois à la fin et s'efface. */
  .js .ai-type.is-typing .ai-word::after {
    content: "";
    position: absolute;
    left: calc(100% + 0.12em); top: 0.1em;
    width: 2px; height: 1.2em;
    border-radius: 1px;
    background: var(--label);
    opacity: 0;
    animation: ama-ai-caret calc(var(--dn) * 1ms) linear calc(var(--d) * 1ms + 120ms) none;
  }
  .js .ai-type.is-typing .ai-word:last-child::after {
    animation: ama-ai-caret-end 1200ms linear calc(var(--d) * 1ms + 120ms) none;
  }
}
@keyframes ama-ai-word { from { opacity: 0; } to { opacity: 1; } }
@keyframes ama-ai-caret { from, to { opacity: 1; } }
@keyframes ama-ai-caret-end {
  0%, 30%   { opacity: 1; }
  31%, 55%  { opacity: 0; }
  56%, 80%  { opacity: 1; }
  81%, 100% { opacity: 0; }
}

/* ---------- Louer ou posséder (#louer-ou-posseder, own-tools.php) ----------
   Comparatif et état final (le sur mesure allumé, le loué en retrait) : assets/css/sections.css.
   Ici, la bascule liée au défilement : la surface bleu marque glisse de la case « loué » vers la case « sur
   mesure », le loué recule, le sur mesure s'allume, puis sa coche apparaît ; tout avance et recule avec la
   position du comparatif dans l'écran. Les images-clés ne posent que l'état de départ (« from ») : l'arrivée
   est l'état final de sections.css. Seuls transform et opacity bougent.
   - À partir de 640 px, une timeline sur le tableau : la ligne i (--pv-i, et --pv-j = lignes après elle,
     écrits par own-tools.php) part quand le haut du tableau passe à 80 % de l'écran (+ i × 6vh) et arrive
     quand le tableau est centré (− j × 6vh) : les lignes basculent dans l'ordre, la dernière au plus tard
     quand le tableau est centré, avant que la couche ne colle en haut de l'écran.
   - Téléphone (le tableau dépasse l'écran) : chaque paire porte sa timeline, de « à moitié entrée par le
     bas » à « centrée » ; la légende suit le haut du tableau (de 80 % à 45 % de l'écran).
   Repli sans animation-timeline : --own-p (0 → 1), écrit par assets/js/accueil.js sur les mêmes plages.
   Sans JavaScript, en mouvement réduit : rien ici, l'état final s'affiche. */
@media (prefers-reduced-motion: no-preference) { /* defilement */
  .js .pv-head th { color: var(--ink); }            /* le recul des en-têtes passe par l'opacité */
  .js .pv-head .pv-rent { opacity: 0.68; }          /* = --muted, l'état final */
  @supports (animation-timeline: view()) {
    .js.sda .pv-table { view-timeline: --pv-table block; }
    .js.sda .pv-row::before,
    .js.sda .pv-row .pv-in,
    .js.sda .pv-row .pv-own svg,
    .js.sda .pv-head th {
      animation: ama-pv-slide linear both;
    }
    .js.sda .pv-row .pv-rent .pv-in { animation-name: ama-pv-rent; }
    .js.sda .pv-row .pv-own .pv-in  { animation-name: ama-pv-own; }
    .js.sda .pv-row .pv-own svg     { animation-name: ama-pv-tick; }
    .js.sda .pv-head .pv-rent       { animation-name: ama-pv-dim; }
    .js.sda .pv-head .pv-own        { animation-name: ama-pv-lit; }
    /* Timelines et plages après le raccourci « animation », qui les remet à zéro. */
    .js.sda .pv-row::before,
    .js.sda .pv-row .pv-in,
    .js.sda .pv-row .pv-own svg {
      animation-timeline: --pv-table;
      animation-range: entry calc(20vh + var(--pv-i, 0) * 6vh) entry calc(50vh + 50% - var(--pv-j, 0) * 6vh);
    }
    .js.sda .pv-head th {
      animation-timeline: --pv-table;
      animation-range: entry 20vh entry calc(50vh + 50%);
    }
  }
}
@media (prefers-reduced-motion: no-preference) and (max-width: 639px) { /* defilement */
  @supports (animation-timeline: view()) {
    .js.sda .pv-row { view-timeline: --pv-row block; }
    .js.sda .pv-row::before,
    .js.sda .pv-row .pv-in,
    .js.sda .pv-row .pv-own svg {
      animation-timeline: --pv-row;
      animation-range: entry 50% contain 50%;
    }
    .js.sda .pv-head th { animation-range: entry 20vh entry 55vh; }
  }
}
@keyframes ama-pv-slide { from { transform: none; } }
@keyframes ama-pv-rent  { from { opacity: 1; transform: none; } }
@keyframes ama-pv-own   { from { opacity: 0.68; transform: scale(0.96); } }
@keyframes ama-pv-tick  { from, 50% { opacity: 0; transform: scale(0.5); } }
@keyframes ama-pv-dim   { from { opacity: 1; } }
@keyframes ama-pv-lit   { from { opacity: 0.68; } }
/* Repli : mêmes états, lus sur --own-p (absent = 1 = état final). */
@media (prefers-reduced-motion: no-preference) { /* defilement */
  .js:not(.sda) .pv-row::before {
    transform: translate(calc((100% + var(--pv-gap)) * var(--pv-dx) * var(--own-p, 1)),
                         calc((100% + var(--pv-gap)) * var(--pv-dy) * var(--own-p, 1)));
  }
  .js:not(.sda) .pv-head .pv-rent { opacity: calc(1 - 0.32 * var(--own-p, 1)); }
  .js:not(.sda) .pv-head .pv-own  { opacity: calc(0.68 + 0.32 * var(--own-p, 1)); }
  .js:not(.sda) .pv-row .pv-rent .pv-in {
    opacity: calc(1 - 0.32 * var(--own-p, 1));
    transform: scale(calc(1 - 0.04 * var(--own-p, 1)));
  }
  .js:not(.sda) .pv-row .pv-own .pv-in {
    opacity: calc(0.68 + 0.32 * var(--own-p, 1));
    transform: scale(calc(0.96 + 0.04 * var(--own-p, 1)));
  }
  .js:not(.sda) .pv-row .pv-own svg {
    opacity: clamp(0, var(--own-p, 1) * 2 - 1, 1);
    transform: scale(calc(0.5 + 0.5 * clamp(0, var(--own-p, 1) * 2 - 1, 1)));
  }
}

/* 2. HAUT DE LA PAGE — fin */




/* ============================================================
   3. BAS DE LA PAGE — début (ouvrier « accueil-bas »)
   Méthode (#methode, home-method.php), avis Google (#avis, home-reviews.php),
   qui sommes-nous (#equipe, home-team.php), questions fréquentes (#questions, home-faq.php).
   Rien n'est posé sur .layer, .layer-body ni sur le .wrap lui-même (bloc 1) : seulement sur ses enfants.
   ============================================================ */

/* ---------- Méthode : quatre étapes, une ligne qui se remplit à gauche ---------- */
#methode {
  --step-dot: 20px;    /* pastille */
  --step-track: 4px;   /* ligne : 3 px au moins, pas un trait fin */
}
.step-grid {
  display: grid;
  grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
  gap: var(--sp-6) var(--sp-8);
  align-items: start;
}
.step-grid .section-head { margin-bottom: 0; }
.step-item {
  position: relative;
  min-width: 0;
  padding-left: calc(var(--step-dot) + var(--sp-5));
  padding-bottom: var(--sp-7);
}
.step-item:last-child { padding-bottom: 0; }
.step-title { font-size: var(--fs-4); overflow-wrap: break-word; }
.step-text { margin-top: var(--sp-3); color: var(--muted); }

/* Pastille : fond de bande, couche « atteinte » (bleu frais) et couche « en cours » (jaune) posées dessus ;
   seule leur opacité change. Sans JavaScript ou en mouvement réduit : toutes atteintes. */
.step-dot {
  position: absolute; left: 0; top: 0.25rem; z-index: 1;
  width: var(--step-dot); height: var(--step-dot);
  border-radius: 50%;
  background: var(--surface-2);
}
.step-dot::before, .step-dot::after {
  content: "";
  position: absolute; inset: 0;
  border-radius: inherit;
}
.step-dot::before { background: var(--label); }
.step-dot::after { background: var(--accent); opacity: 0; }

/* Ligne : un segment par étape, de sa pastille à la suivante (piste + remplissage bleu frais). */
.step-item:not(:last-child)::before, .step-item:not(:last-child)::after {
  content: "";
  position: absolute;
  left: calc((var(--step-dot) - var(--step-track)) / 2);
  top: calc(0.25rem + var(--step-dot) / 2);
  bottom: calc(-0.25rem - var(--step-dot) / 2);
  width: var(--step-track);
  border-radius: var(--radius-pill);
}
.step-item:not(:last-child)::before { background: var(--surface-2); }
.step-item:not(:last-child)::after { background: var(--label); transform-origin: 50% 0; }

@media (max-width: 1023px) {
  .step-grid { grid-template-columns: minmax(0, 1fr); }
  .step-grid .section-head { margin-bottom: var(--sp-5); }
}
@media (max-width: 639px) {
  .step-item { padding-bottom: var(--sp-6); }
}

/* Chaque étape porte sa timeline : du passage de son haut à 85 % de l'écran à celui de son bas (le haut de
   l'étape suivante). La pastille s'allume au début, la ligne descend jusqu'à la suivante, l'étape en cours
   est jaune ; la dernière reste jaune une fois atteinte. Repli : --q (même plage), assets/js/accueil.js. */
@media (prefers-reduced-motion: no-preference) { /* defilement */
  @supports (animation-timeline: view()) {
    .js.sda .step-item { view-timeline-name: --step; }
    .js.sda .step-item:not(:last-child)::after,
    .js.sda .step-dot::before,
    .js.sda .step-dot::after {
      animation: ama-step-fill linear both;
      animation-timeline: --step;
      animation-range: entry 15vh contain 15vh;
    }
    .js.sda .step-dot::before { animation-name: ama-step-lit; }
    .js.sda .step-dot::after { animation-name: ama-step-now; }
    .js.sda .step-item:last-child .step-dot::after { animation-name: ama-step-lit; }
  }
  .js:not(.sda) .step-item:not(:last-child)::after { transform: scaleY(var(--q, 1)); }
  .js:not(.sda) .step-dot::before { opacity: clamp(0, var(--q, 1) * 50, 1); }
  .js:not(.sda) .step-dot::after { opacity: min(clamp(0, var(--q, 1) * 50, 1), clamp(0, (1 - var(--q, 1)) * 50, 1)); }
  .js:not(.sda) .step-item:last-child .step-dot::after { opacity: clamp(0, var(--q, 1) * 50, 1); }
}
@keyframes ama-step-fill { 0% { transform: scaleY(0); } 100% { transform: scaleY(1); } }
@keyframes ama-step-lit  { 0% { opacity: 0; } 2%, 100% { opacity: 1; } }
@keyframes ama-step-now  { 0% { opacity: 0; } 2%, 98% { opacity: 1; } 100% { opacity: 0; } }

/* ---------- Avis Google : note, cartes, lien vers Google ---------- */
/* Sans JavaScript et en mouvement réduit : grille fixe de toutes les cartes, textes entiers. */
#avis {
  --avis-card-w: 26rem;   /* largeur d'une carte dans la bande */
  --avis-gap: var(--sp-5);
  --avis-lines: 10;       /* lignes visibles d'un avis dans la bande ; au-delà, il défile dans sa carte */
  --avis-duree: 72s; /* defilement */
}
/* Bande + actions tiennent dans un écran de 900 px de haut (sinon la couche colle par son bas). */
#avis .section-head { margin-bottom: var(--sp-7); }
.avis-score { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2) var(--sp-3); }
.avis-stars { display: inline-flex; color: var(--label); flex-shrink: 0; }
.avis-stars svg { fill: currentColor; stroke: none; }
.avis-stars .avis-star-off { fill: var(--line-strong); }

.avis-list {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--avis-gap);
}
.avis-card { display: flex; min-width: 0; }
.avis-figure {
  flex: 1;
  min-width: 0;
  display: flex; flex-direction: column; gap: var(--sp-3);
  padding: var(--sp-5) var(--sp-6);
  border-radius: var(--radius-lg);
  background: var(--surface-sunk);
  box-shadow: var(--shadow-shot);
}
.avis-text { color: var(--ink-soft); overflow-wrap: break-word; }
/* Le nom passe sous l'initiale quand il lui reste moins de 7 rem (nom long, texte agrandi au téléphone). */
.avis-who { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-3); min-width: 0; margin-top: auto; padding-top: var(--sp-2); }
.avis-avatar {
  display: inline-flex; align-items: center; justify-content: center;
  width: 44px; height: 44px; flex-shrink: 0;
  border-radius: 50%;
  background: var(--c-brand);
  color: var(--label);
  font-family: var(--ff-display);
  font-weight: 600;
  font-size: 1rem;
  line-height: 1;
}
.avis-id { flex: 1 1 7rem; display: flex; flex-direction: column; min-width: 0; }
.avis-name { color: var(--ink); font-weight: 600; line-height: 1.3; overflow-wrap: anywhere; }
.avis-date { font-size: var(--fs-sm); color: var(--muted); line-height: 1.4; }

.avis-actions { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-3); }
.avis-zone-list .avis-actions { margin-top: var(--sp-5); }
.avis-zone-list .avis-link { margin-left: auto; }
/* Le bouton gris de la charte (--surface-2) se confondrait avec la bande : surface creusée ici. */
#avis .avis-link { background: var(--surface-sunk); }

/* Bouton pause / lecture : seulement quand la bande défile (JavaScript et mouvement permis). */
.avis-toggle {
  display: none;
  align-items: center; justify-content: center;
  position: relative;
  width: 48px; height: 48px; flex-shrink: 0;
  border-radius: 50%;
  background: var(--surface-sunk);
  color: var(--ink);
  transition: transform var(--d-press) var(--ease-out);
}
.avis-toggle:active { transform: scale(0.97); }
.avis-toggle svg { transition: opacity var(--d-press) ease; }
.avis-toggle .avis-ico-play { position: absolute; opacity: 0; }
.avis-toggle .avis-ico-play path { fill: currentColor; }
.avis-zone.is-paused .avis-ico-pause { opacity: 0; }
.avis-zone.is-paused .avis-ico-play { opacity: 1; }
@media (hover: hover) and (pointer: fine) {
  .avis-toggle:hover { color: var(--label); }
}

@media (max-width: 1023px) {
  .avis-list { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 639px) {
  #avis { --avis-card-w: 18.5rem; --avis-gap: var(--sp-4); --avis-lines: 12; --avis-duree: 54s; } /* defilement */
  .avis-list { grid-template-columns: minmax(0, 1fr); }
  .avis-figure { padding: var(--sp-5); }
  .avis-zone-list .avis-link { margin-left: 0; flex: 1; }
}

/* Avis sans bande de cartes (.avis-court), ordinateur : la bande tient toute sa largeur, sans texte en plus.
   Titre à gauche (5 parts), note en grand au milieu (4), lien vers Google à droite, calé sur la ligne
   de la note. L'en-tête s'efface de la grille (display: contents) pour que la note y prenne sa place. */
@media (min-width: 1024px) {
  #avis.avis-court .wrap {
    display: grid;
    grid-template-columns: minmax(0, 5fr) minmax(0, 4fr) auto; /* le lien garde sa ligne (1024 px) */
    column-gap: var(--sp-8);
    align-items: center;
  }
  #avis.avis-court .section-head { display: contents; }
  #avis.avis-court h2 { grid-column: 1; grid-row: 1; }
  #avis.avis-court .avis-score {
    grid-column: 2; grid-row: 1;
    display: grid; justify-items: start; gap: var(--sp-3);
    margin: 0;
  }
  #avis.avis-court .avis-score .avis-stars svg { width: auto; height: 1.75rem; }
  #avis.avis-court .avis-score .num {
    display: block;
    margin-bottom: var(--sp-1);
    font-family: var(--ff-display);
    font-size: clamp(3.5rem, 3vw + 2rem, 5.5rem);
    line-height: 1;
    letter-spacing: -0.03em;
    color: var(--ink);
  }
  #avis.avis-court .avis-zone { grid-column: 3; grid-row: 1; align-self: end; justify-self: end; }
}

/* La bande qui défile : une rangée dès le premier rendu (aucun saut quand le script arrive). Tant que le
   script n'a pas doublé la piste, la rangée se fait défiler à la main : rien n'est jamais inaccessible.
   La bande va d'un bord de l'écran à l'autre (coupée au bord de sa couche, bloc 1 : overflow-x clip) ; au
   repos, la première carte est alignée sur le titre. */
@media (prefers-reduced-motion: no-preference) { /* defilement */
  .js .avis-toggle { display: inline-flex; }
  .js .avis-band {
    contain: inline-size; /* la piste très large ne pousse pas la largeur de la section */
    margin-inline: calc(50% - 50vw);
    padding-inline: calc(50vw - 50%);
    scroll-padding-inline: calc(50vw - 50%);
    overflow-x: auto;
    scrollbar-width: none;
    scroll-snap-type: x mandatory;
  }
  .js .avis-band::-webkit-scrollbar { display: none; }
  .js .avis-track { display: flex; width: max-content; }
  .js .avis-list {
    display: flex;
    gap: var(--avis-gap);
    padding-right: var(--avis-gap); /* même pas entre la fin d'une liste et le début de son double */
  }
  .js .avis-card { width: min(var(--avis-card-w), 78vw); scroll-snap-align: start; }
  /* Avis long : jamais tronqué, il défile dans sa carte (le script le rend atteignable au clavier). */
  .js .avis-text {
    max-height: calc(var(--avis-lines) * var(--lh-base) * 1em);
    overflow-y: auto;
    scrollbar-width: thin;
    scrollbar-color: var(--line-strong) transparent;
  }

  /* Piste doublée : elle avance d'une liste entière, puis reprend au début sans saut visible. */
  .js .avis-zone.is-ready .avis-band { overflow-x: hidden; scroll-snap-type: none; }
  .js .avis-zone.is-ready .avis-track {
    animation: ama-avis-scroll var(--avis-duree) linear infinite;
    animation-play-state: paused;
  }
  .js .avis-zone.is-ready.is-visible:not(.is-paused) .avis-track { animation-play-state: running; }
  /* Pause au focus dans la bande (une carte, un avis long) ; le bouton seul ne met pas en pause, sinon
     « lecture » resterait sans effet. */
  .js .avis-zone.is-ready .avis-band:focus-within .avis-track { animation-play-state: paused; }
  /* Couche recouverte par la suivante (motion.js : .is-covered) : la bande ne tourne plus pour rien. */
  .js .layer.is-covered .avis-zone.is-ready .avis-track { animation-play-state: paused; }

}
@media (prefers-reduced-motion: no-preference) and (hover: hover) and (pointer: fine) { /* defilement */
  .js .avis-zone.is-ready .avis-band:hover .avis-track { animation-play-state: paused; }
}
@keyframes ama-avis-scroll { to { transform: translateX(-50%); } }

/* ---------- Équipe : deux fondateurs ---------- */
#equipe { --team-slide: 64px; } /* course horizontale d'arrivée d'un fondateur */
.team-list {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--sp-5);
}
.team-card {
  min-width: 0;
  display: grid;
  grid-template-columns: minmax(0, 11rem) minmax(0, 1fr);
  gap: var(--sp-5) var(--sp-6);
  align-items: start;
  align-content: start; /* la carte la plus courte ne répartit pas son vide entre photo et texte */
  padding: var(--sp-6);
  border-radius: var(--radius-lg);
  background: var(--surface-2);
}
.team-photo {
  position: relative;
  display: grid; place-items: center;
  aspect-ratio: 1;
  border-radius: var(--radius);
  overflow: hidden;
  background: var(--surface-sunk);
}
.team-photo img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
/* Repli si la photo manque (main.js retire l'<img> cassée) : les initiales, au centre du cadre. */
.team-initials { font-family: var(--ff-display); font-size: var(--fs-3); font-weight: 600; color: var(--label); }
.team-photo:has(img) .team-initials { visibility: hidden; }
.team-text { min-width: 0; }
.team-name { font-size: var(--fs-4); overflow-wrap: break-word; }
.team-role { margin-top: var(--sp-1); color: var(--label); font-weight: 500; line-height: 1.45; }
.team-bio { margin-top: var(--sp-3); color: var(--muted); }
.team-link { margin-top: var(--sp-3); }
.team-link a { overflow-wrap: anywhere; }

@media (max-width: 1023px) {
  .team-card { grid-template-columns: minmax(0, 1fr); }
  .team-photo { width: min(100%, 11rem); }
}
@media (max-width: 639px) {
  #equipe { --team-slide: 32px; } /* l'arrivée latérale ne pousse rien hors de l'écran */
  .team-list { grid-template-columns: minmax(0, 1fr); }
  .team-card { padding: var(--sp-5); }
  .team-photo { width: min(100%, 9rem); }
}

/* Arrivée, une seule fois : chaque fondateur glisse depuis son côté et ils se rejoignent ; le portrait remonte
   dans son cadre en se resserrant ; puis nom, rôle, bio et lien entrent en cascade (60 ms). Le fondu de la
   carte vient de [data-reveal="fade"] (base.css). */
@media (prefers-reduced-motion: no-preference) { /* defilement */
  .js .team-card[data-side="left"]:not(.is-in) { transform: translateX(calc(-1 * var(--team-slide))); }
  .js .team-card[data-side="right"]:not(.is-in) { transform: translateX(var(--team-slide)); }

  .js .team-photo img,
  .js .team-text > * {
    transition: transform var(--d-reveal) var(--ease-out), opacity var(--d-reveal) var(--ease-out);
  }
  .js .team-photo img { transition-duration: 1100ms; transition-delay: 120ms; }
  .js .team-card:not(.is-in) .team-photo img { transform: translateY(28%) scale(1.12); opacity: 0; }

  .js .team-text > * { transition-duration: 700ms; }
  .js .team-text > :nth-child(1) { transition-delay: 300ms; }
  .js .team-text > :nth-child(2) { transition-delay: 360ms; }
  .js .team-text > :nth-child(3) { transition-delay: 420ms; }
  .js .team-text > :nth-child(4) { transition-delay: 480ms; }
  .js .team-card:not(.is-in) .team-text > * { transform: translateY(16px); opacity: 0; }
}

/* ---------- Questions fréquentes : accordéon (contrat de assets/js/main.js) ---------- */
.faq-grid { display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); gap: var(--sp-6) var(--sp-8); align-items: start; }
.faq-head { margin-bottom: 0; }
.faq-list { display: grid; gap: var(--sp-3); min-width: 0; }
.faq-item {
  position: relative;
  isolation: isolate;
  min-width: 0;
  border-radius: var(--radius-lg);
  background: var(--surface);
}
/* Surface de l'état ouvert, posée d'avance : seule son opacité change, pas la couleur du fond. */
.faq-item::before {
  content: "";
  position: absolute; inset: 0; z-index: -1;
  border-radius: inherit;
  background: var(--surface-2);
  opacity: 0;
  transition: opacity var(--d-base) ease;
  pointer-events: none;
}
.faq-item.is-open::before { opacity: 1; }

.faq-h { font-size: var(--fs-4); line-height: 1.3; text-wrap: pretty; }
.faq-btn {
  display: flex; align-items: center; justify-content: space-between; gap: var(--sp-4);
  width: 100%; min-height: 64px;
  padding: var(--sp-4) var(--sp-5);
  text-align: left;
  color: var(--ink);
  border-radius: var(--radius-lg);
  transition: transform var(--d-press) var(--ease-out);
}
.faq-btn:active { transform: scale(0.97); }
.faq-q { display: block; min-width: 0; overflow-wrap: break-word; hyphens: auto; }
/* « + » ouvert = « − » : le trait vertical se replie. Lu sur aria-expanded, juste aussi sans JavaScript. */
.faq-ico { width: 24px; height: 24px; color: var(--muted); stroke-width: 2; transition: color var(--d-base) ease; }
.faq-ico .faq-v { transform-box: fill-box; transform-origin: center; transition: transform var(--d-base) var(--ease-out); }
.faq-btn[aria-expanded="true"] .faq-ico { color: var(--label); }
.faq-btn[aria-expanded="true"] .faq-v { transform: scaleY(0); }
@media (hover: hover) and (pointer: fine) {
  .faq-btn:hover, .faq-btn:hover .faq-ico { color: var(--label); }
}

.faq-a { padding: 0 var(--sp-5) var(--sp-5); }
.faq-a p { max-width: 38rem; color: var(--ink-soft); }

/* Ouverture par un clic (.is-anim, main.js) : la réponse entre en 260 ms ; la fermeture est immédiate,
   seules les questions suivantes glissent (main.js). Aucune hauteur animée. */
@keyframes ama-faq-in   { from { opacity: 0; transform: translateY(-8px); } }
@keyframes ama-faq-fade { from { opacity: 0; } }
@media (prefers-reduced-motion: no-preference) {
  .faq-a.is-anim { animation: ama-faq-in var(--d-base) var(--ease-out); }
}
@media (prefers-reduced-motion: reduce) {
  .faq-a.is-anim { animation: ama-faq-fade var(--d-out) ease; }
}

@media (max-width: 1023px) {
  .faq-grid { grid-template-columns: minmax(0, 1fr); }
  .faq-head { margin-bottom: var(--sp-2); }
}
@media (max-width: 639px) {
  .faq-btn { padding-inline: var(--sp-4); }
  .faq-a { padding-inline: var(--sp-4); }
}

/* Entrée au défilement : la question glisse de la largeur de la marge (jamais hors de l'écran) et se range
   contre son bord, son « + » finit un quart de tour. Propriétés translate et rotate : indépendantes du
   transform que main.js pose sur les questions qui glissent à l'ouverture d'une réponse. */
/* Opacité de départ 0,4, pas 0 : une question encore sous le bas de l'écran reste lisible (aucun trou). */
@keyframes ama-faq-settle { from { translate: var(--gutter) 0; opacity: 0.4; } }
@keyframes ama-faq-turn   { from { rotate: 90deg; } }
@media (prefers-reduced-motion: no-preference) { /* defilement */
  @supports (animation-timeline: view()) {
    .js.sda .faq-item {
      view-timeline-name: --faq-item;
      animation: ama-faq-settle linear both;
      animation-timeline: view();
      animation-range: entry 0% entry 100%;
    }
    .js.sda .faq-ico {
      animation: ama-faq-turn linear both;
      animation-timeline: --faq-item;
      animation-range: entry 0% entry 100%;
    }
  }
  /* Repli : --p (0 → 1) écrit par motion.js sur [data-progress="entry"]. */
  .js:not(.sda) .faq-item {
    translate: calc((1 - var(--p, 1)) * var(--gutter)) 0;
    opacity: calc(0.4 + 0.6 * var(--p, 1));
  }
  .js:not(.sda) .faq-ico { rotate: calc((1 - var(--p, 1)) * 90deg); }
}

/* 3. BAS DE LA PAGE — fin */
