/* faq.css — section « Vous demandez, on répond. » : sept questions en accordéon (#faq).

   Toutes les valeurs sont relevées sur la source le 2026-08-11, aux paliers
   1440 / 1024 / 809 / 390, APRÈS parcours de la section par paliers sur toute sa
   hauteur puis dépassement et retour au bord haut (règle A₁.5 : `getAnimations()`
   vide ne prouve rien, la source translate ses blocs en JS). Les deux lectures —
   celle prise juste après le premier défilement et celle prise après l'aller-retour
   — sont identiques au centième de pixel : pas d'artefact de 170 px ici.
   `location.href` ET `innerWidth` ont été renvoyés dans le MÊME `browser_evaluate`
   que chaque mesure (règle A₁.6). Chaque ensemble a été énuméré membre par membre
   (piège n° 8) : sept cartes, sept pastilles d'icône, sept tracés de chevron.

   Contrôle arithmétique de la hauteur de section, panneau 1 ouvert :
     1440 : 60 (pad haut) + 136 (intro)   + 60 (gap) + 1126,95 (liste) + 145 = 1527,95
     1024 : 60            + 156 (intro)   + 60       + 1007,98 (liste) + 145 = 1428,98
      809 : 30            + 205,5 (intro) + 40       +  900,19 (liste) +  70 = 1245,69
      390 : 30            + 205,5 (intro) + 40       + 1307,58 (liste) +  70 = 1653,08
   Les quatre totaux sont exactement les hauteurs mesurées sur la source. La cible
   du brief à 1440 (1528) est donc atteinte à 0,05 px près.

   ---------------------------------------------------------------------------
   LES SIX RÉPONSES 2 À 7 N'EXISTENT PAS DANS LE DOM AU CHARGEMENT. Ce n'est pas
   un masquage : la source substitue le contenu au clic (même mécanisme qu'aux
   onglets de #process). Elles ont été relevées une par une avec de VRAIS clics
   (`browser_click`) — un `dispatchEvent(new MouseEvent(...))` ne déclenche rien
   sur la source. Textes verbatim dans le markup, fautes de la source comprises
   (voir le rapport de tâche).

   BALAYAGE A₀ APRÈS ACTIONNEMENT DES SEPT ÉTATS : liste rigoureusement identique
   à celle d'avant les clics — 0 balise <img>, 1 SVG de sticker (viewBox 0 0 501 291)
   et 7 chevrons (viewBox 0 0 256 256). Aucun asset manquant à `assets/`, rien à
   télécharger. Balayage complémentaire sur `background-image`, `clip-path`,
   `mask-image`, `filter` et `box-shadow` (piège n° 8, corollaire 2) : AUCUN
   élément peint autrement dans toute la section, aux deux états. Les bosses du
   feston de haut sont, comme partout ailleurs sur ce site, des <div> en
   `background-color` + `border-radius: 90px 90px 0 0`.

   ---------------------------------------------------------------------------
   MANQUES DU BRIEF (A₀) — relevés puis reconstruits ici :

   1. LES SEPT CHEVRONS (signalés par le constat n° 3 du contrôleur, absents du
      brief). Un seul tracé pour les sept — Phosphor « CaretDown » plein,
      `viewBox="0 0 256 256"`, rendu à 16 px, `fill` relevé à 24·26·18 soit
      --c-olive-black. À l'ouverture la source ne change PAS de tracé : elle
      applique `matrix(-1,0,0,-1,0,0)` au conteneur du SVG, soit une rotation de
      180°. Énumération des sept transforms à l'état initial : 1 valeur
      `matrix(-1,0,0,-1,0,0)` (la question 1, ouverte) et 6 `none`. Reproduit ici
      par `.faq__item.is-open .faq__toggle svg { transform: rotate(180deg) }` —
      la classe `is-open` est posée par `initAccordions()`, qui n'a donc PAS
      besoin d'être modifié (il est partagé avec #services, tâche 8, close).

   2. LA PASTILLE VERTE DERRIÈRE CHAQUE CHEVRON. Carré de 42 × 42 à coins
      arrondis de 13 px, fond --c-mint (192·236·191), aux SEPT questions et aux
      quatre paliers — donc aussi sur les questions fermées, ce n'est pas un
      marqueur d'état. Le brief n'en dit rien.

   3. L'OPACITÉ DE 0,7 SUR LE TEXTE DE RÉPONSE. La source enveloppe le <p> dans
      un calque à `opacity: 0.7` — la couleur elle-même reste --c-ink pleine
      (59·0·27). Sans ce calque le texte rend nettement plus dense que la source
      (règle A₁.1 : `getComputedStyle` sur le <p> ne montre rien). Posé ici
      directement sur le <p>, ce qui donne le même rendu sans un niveau de
      balisage vide. Le titre de question, lui, est à pleine opacité.

   4. LE DÉCALAGE EN QUINCONCE DES DEUX CARTES. La carte de question et la carte
      de réponse ne sont pas alignées : dans une colonne de 600, la question est
      une carte de 500 collée à GAUCHE et la réponse une carte de 500 collée à
      DROITE (la source pose `padding: 0 100px 0 0` sur la rangée de question et
      `0 0 0 100px` sur celle de réponse). Le brief parlait de cartes « plus
      étroites que le conteneur et décalées vers la gauche » d'après le relevé
      du 07/08 ; le constat n° 4 du contrôleur corrige en « 600 de large, bord
      gauche à 420, centrage exact ». Les deux sont partiellement justes et
      passent à côté du quinconce : la COLONNE fait bien 600 et est bien centrée
      (420 → 1020 sur 1440), mais les CARTES font 500 et alternent de bord.
      Le décalage disparaît à ≤ 809 : les deux cartes y font toute la largeur.

   5. AUCUN FESTON DE BAS DE SECTION — le constat n° 2 du contrôleur est confirmé
      par la mesure et par la capture : les bosses jaunes visibles sous #faq
      appartiennent au `.scallop-top` de la section suivante. `.scallop-bottom`
      (non calibré) n'est donc pas employé.

   ---------------------------------------------------------------------------
   `.sticker` / `.sticker--masked` (layout.css) ne sont PAS réutilisés (règle
   A₁.0) : la source pose le SVG sur 100 % de la LARGEUR de la boîte et le laisse
   déborder en hauteur, alors que `.sticker--masked` contient la forme dans la
   boîte et écraserait l'étoile. Même choix qu'en tâches 10, 12, 13 et 14.
   `.card` n'est pas réutilisée non plus (`overflow: hidden`, rayon 32 ≠ 40).
   `.scallop-top` en revanche convient telle quelle : 15 bosses de 96 × 75,59
   remontées de 61 à 1440, 68,27 × 53,76 / 40 à 1024, 26 × 20,47 / 20 à 390 —
   exactement les tokens --scallop-* en place. La section ne doit donc pas
   passer en `overflow: hidden/clip`.

   Le sticker est le SIXIÈME emploi du tracé `viewBox="0 0 501 291"` sur le site
   (tâches 9, 12, 13 et deux fois en 14). Inliné plutôt que référencé en <img> :
   sa couleur de remplissage vient d'un token, qu'un <img> ne peut pas recevoir.
   La factorisation des tracés partagés reste l'arbitrage de la tâche 18. */

/* Entrée deux fois plus ample qu'ailleurs : relevé sur la source le 2026-08-13,
   ses 115 éléments de FAQ montent de 340px là où toutes ses autres sections
   montent de 170. Chez elle le doublement vient de deux conteneurs animés l'un
   dans l'autre ; ici les deux blocs animés (`.faq__intro` et `.faq__list`) sont
   frères, la valeur est donc posée directement. */
.faq {
  --reveal-rise: 340px;
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 60px;
  padding: 60px 40px 145px;
  background: var(--c-teal);

  /* Feston de haut de section : bosses en --c-teal qui mordent sur le sable de
     #about. Manque n° 5 ci-dessus pour le BAS : il n'y en a pas. */
  --scallop-color: var(--c-teal);
}

/* ---------- Intro (titre + sticker) ----------
   À 1440 et 1024 le bloc d'intro épouse exactement la boîte du titre (800 × 136,
   puis 600 × 156) et sert de référent au sticker, posé en absolu dans SON repère.
   À ≤ 809 la source change de régime : le sticker repasse DANS LE FLUX, au-dessus
   du titre et centré (voir la media query). */
.faq__intro {
  position: relative;
  width: 800px;
}

.faq__heading {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: var(--fs-68);
  line-height: 68px;
  color: var(--c-ink);
  text-align: center;
  /* Relevé sur la source (`text-wrap: balance` calculé). C'est lui qui coupe en
     « Vous demandez, » / « on répond. » plutôt que de remplir la première ligne. */
  text-wrap: balance;
  /* ⚠ Pas un réglage esthétique : c'est ce qui donne le BON NOMBRE DE LIGNES.
     La source rend ce titre en découpant chaque lettre dans un <span
     display:inline-block> (technique d'animation Framer), ce qui supprime le
     crénage entre lettres voisines et élargit le texte de 0,68 %. Mesuré sur
     notre rendu, en largeur max-content à 52px :
        crénage actif (défaut)  1006,26
        font-kerning: none      1013,12
        découpe lettre à lettre 1013,22   (la technique de la source, reproduite
                                           ici pour vérification)
        cible déduite de la source 1013,16
     Sans cette ligne, « Vous demandez, » mesure 599,2 et TIENT dans les 600 du
     palier tablette, là où la source (604,4) déborde : le titre passait à 2 lignes
     au lieu de 3 et la section était trop courte de 52 px — exactement une hauteur
     de ligne, la signature décrite en A₁.6. Les questions <h3>, elles, sont du
     texte simple sur la source (pas de découpe) et gardent leur crénage. */
  font-kerning: none;
}

/* `left`/`top` sont des pixels bruts que la source choisit par palier, pas un
   pourcentage : 40 / 136 sur un référent de 800 × 136 à 1440, 36 / 131,04 sur
   600 × 156 à 1024 — aucun rapport commun (5 % vs 6 % en x, 100 % vs 84 % en y).
   Valeurs lues directement dans le style calculé de l'élément absolu, pas
   déduites de sa boîte englobante.
   `translate(-50%, -50%)` AVANT la rotation, comme la source (matrice relevée :
   rotation -20° composée d'une translation exactement -w/2, -h/2).
   Largeur codée, hauteur libre : la boîte mesure 130 × 86 à 1440, soit
   « libellé + 60 » en hauteur — le libellé tient donc toujours dans sa forme
   (règle A₁.3), sur une seule ligne aux quatre paliers. */
.faq__sticker {
  position: absolute;
  left: 40px;
  top: 136px;
  /* Centrage en FLEX et non en grille, comme la source (`display:flex;
     align-items:center; justify-content:center` relevé). Ce n'est pas
     interchangeable ici : au palier tablette la boîte ne fait que 90 px de large
     pour un libellé de 38,7 (voir la media query), et un élément de grille qui
     déborde sa piste est aligné au DÉBUT par Chrome — mesuré, le libellé partait
     4,35 px trop à droite — alors qu'un élément flex qui déborde reste centré,
     débordant symétriquement. Le centre du libellé retombe alors exactement sur
     le point d'ancrage du sticker, comme sur la source. */
  display: flex;
  align-items: center;
  justify-content: center;
  width: 130px;
  padding: 30px;
  transform: translate(-50%, -50%) rotate(-20deg);
}

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

.faq__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);
  text-align: center;
}

/* ---------- Liste ----------
   Colonne de 600 centrée dans la zone de contenu, gouttière de 10 entre items.
   À ≤ 809 la source garde ce plafond de 600 et laisse la colonne se réduire à
   100 % en dessous (600 mesurés à 809, 350 à 390) : d'où `width` + `max-width`
   plutôt qu'une largeur codée par palier. */
.faq__list {
  display: flex;
  flex-direction: column;
  gap: 10px;
  width: 100%;
  max-width: 600px;
}

/* Gouttière de 5 entre la question et sa réponse — plus serrée que les 10 qui
   séparent deux questions. Quand le panneau est fermé, `initAccordions()` lui
   repose l'attribut `hidden` : il sort du flux et cette gouttière disparaît,
   comme sur la source. */
.faq__item {
  display: flex;
  flex-direction: column;
  gap: 5px;
}

/* Manque A₀ n° 4 : le quinconce. La question occupe les 500 de gauche des 600 de
   la colonne, la réponse les 500 de droite. Les deux décalages sont posés en
   padding sur la ligne (et non par un `width` + `align-self`) pour rester
   fidèles à la construction de la source, et parce que `padding-left` sur le
   panneau n'interfère pas avec l'animation de `max-height` de accordion.js —
   qui n'anime que la hauteur. */
.faq__question-wrap {
  padding-right: 100px;
}

.faq__panel {
  padding-left: 100px;
}

/* Le déclencheur EST la carte jaune. Sur la source la zone cliquable couvre les
   600 de la ligne, y compris la bande vide de 100 px à droite de la carte
   (`cursor: pointer` relevé sur les deux niveaux) ; on s'en tient à la carte,
   pour ne pas donner au bouton une cible invisible ni un anneau de focus qui
   déborderait de la forme. Écart de comportement documenté au rapport ; le rendu
   au repos est identique.
   `justify-content: space-between` : les 20,91 px de mou (460 - 397,09 - 42)
   tombent entre le libellé et la pastille, exactement comme sur la source. */
.faq__trigger {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  padding: 20px;
  border-radius: 40px;
  background: var(--c-yellow-pale);
  text-align: left;
}

/* `flex: 0.95 0 0` est relevé tel quel sur la source, et ce n'est pas une
   coquetterie : c'est lui qui donne la largeur de 397,09 à 1440 (0,95 × (460 - 42)),
   492,09 à 809 et 254,59 à 390 — donc le nombre de lignes de chaque question,
   donc la hauteur de chaque carte, donc la hauteur de la section. Un `flex: 1`
   élargirait le libellé de 21 px et ferait remonter deux questions d'une ligne. */
.faq__question {
  flex: 0.95 0 0;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: var(--fs-22);
  line-height: 30.8px;
  color: var(--c-ink);
}

/* Manque A₀ n° 2 : la pastille verte, présente aux sept questions, ouvertes ou
   fermées. Rayon 13 px relevé tel quel (aucun token --r-* ne vaut 13). */
.faq__toggle {
  flex: none;
  display: grid;
  place-items: center;
  width: 42px;
  height: 42px;
  border-radius: 13px;
  background: var(--c-mint);
}

/* Manque A₀ n° 1 : un seul tracé pour les deux états, retourné à l'ouverture. */
.faq__toggle svg {
  width: 16px;
  height: 16px;
  fill: var(--c-olive-black);
  transition: transform var(--dur-base) var(--ease-out);
}

.faq__item.is-open .faq__toggle svg {
  transform: rotate(180deg);
}

@media (prefers-reduced-motion: reduce) {
  .faq__toggle svg { transition: none; }
}

/* ---------- Réponse ----------
   Ouverture « pop », demande du 2026-08-13 — ÉCART ASSUMÉ avec la source, qui
   se contente de déplier la hauteur (courbe et durée mesurées, conservées pour
   #services). Trois pièces qui jouent ensemble :

   1. La PLACE s'ouvre vite. `accordion__panel` anime toujours `max-height`,
      mais la FAQ redéfinit sa durée et sa courbe pour elle seule : 300ms en
      sortie franche, au lieu des 600ms en S de la source. La hauteur n'est
      plus le spectacle, elle ne fait que céder le passage.
   2. La BULLE surgit par-dessus : de 0,6 à 1 sur --ease-back, qui dépasse sa
      cible d'environ 9 % avant de se poser (soit un pic à ~1,04 en échelle).
      L'origine est en haut au centre : elle sort de sous la question.
      L'effacement, lui, ne dure qu'un tiers de la course — la bulle est
      pleinement visible pendant qu'elle finit de grossir, sinon le
      dépassement passe inaperçu.
   3. Le DÉZOOM à la fermeture : retour à 0,6 en 200ms sur --ease-in, courbe
      qui accélère (l'inverse du pop). La bulle rentre plus vite qu'elle n'est
      sortie, ce qui évite que la fermeture traîne.

   Le panneau garde le `overflow: hidden` de la primitive, et le dépassement
   sort donc légèrement de sa boîte : l'origine en HAUT À DROITE l'envoie vers
   la gauche, dans les 100px de retrait du quinconce, où il ne sera pas rogné —
   seul le bas dépasse, de 4 % d'une bulle, le temps d'une image ou deux.
   ⚠ Ne PAS remplacer ce `hidden` par `overflow: clip` + `overflow-clip-margin`
   pour gagner cette marge : `clip` ne fait pas du panneau un conteneur de
   défilement, son `scrollHeight` se met alors à compter la bulle TRANSFORMÉE
   (mesuré : 84 au lieu de 141, soit exactement 0,6 × 141) et accordion.js
   n'ouvre plus le panneau qu'à 60 % de sa hauteur. */
.faq__list {
  --dur-accordion: var(--dur-faq-open);
  --ease-accordion: var(--ease-out);
}

/* ⚠ L'ouverture est une ANIMATION, pas une transition — et ce n'est pas un
   choix de style. Le panneau fermé est `hidden` (donc `display: none`) et
   accordion.js pose la classe `is-open` AVANT de le réafficher : la bulle
   apparaît donc déjà dans son état final, sans état de départ à interpoler, et
   une transition ne démarre jamais (mesuré : échelle à 1 dès la première image).
   Une animation, elle, se joue bien au moment où l'élément s'affiche.
   La FERMETURE ne peut pas être une transition non plus : retirer l'animation
   d'ouverture fait sauter la valeur sans rien déclencher (mesuré : échelle à
   0,6 dès la première image, la bulle disparaissait d'un coup). Elle est donc
   animée elle aussi, sur la classe `is-closing` que accordion.js tient entre
   le clic et le retour à `hidden`. */
.faq__answer {
  padding: 20px;
  border-radius: 40px;
  background: var(--c-mint);

  transform: scale(.6);
  transform-origin: 100% 0;
  opacity: 0;
}

/* Le dépassement est porté par la LARGEUR seule : la bulle se déforme — trop
   large, un peu écrasée — puis se pose. C'est le ressort d'un dessin animé, et
   surtout la seule forme de dépassement qui ne se fasse pas rogner : avec
   l'origine en haut à droite, la surlargeur part vers la gauche (100px de
   retrait disponibles) et la hauteur ne franchit jamais 1, donc jamais le bas
   du panneau. Un dépassement uniforme à 1,039 débordait, lui, de 8px sous le
   panneau — mesuré : bulle 199 pour une boîte de 191. */
@keyframes faq-pop {
  0%   { transform: scale(.6, .6); }
  55%  { transform: scale(1.05, .97); }
  78%  { transform: scale(.99, 1); }
  100% { transform: scale(1, 1); }
}

@keyframes faq-pop-fade {
  from { opacity: 0; }
  to   { opacity: 1; }
}

.faq__item.is-open .faq__answer {
  animation: faq-pop var(--dur-faq-pop) var(--ease-out) both,
             faq-pop-fade calc(var(--dur-faq-pop) / 3) var(--ease-out) both;
}

/* Dézoom de sortie : la bulle repart d'où elle est venue, en accélérant
   (--ease-in), et plus vite qu'elle n'est arrivée — une fermeture qui traîne
   donne l'impression d'un site lourd. */
@keyframes faq-unpop {
  from { transform: scale(1);     opacity: 1; }
  to   { transform: scale(.6, .6); opacity: 0; }
}

.faq__item.is-closing .faq__answer {
  animation: faq-unpop var(--dur-faq-close) var(--ease-in) both;
}

/* La place se referme sur le MÊME temps et la MÊME courbe que la bulle. Sans
   cela le panneau garde --ease-out, qui expédie plus de la moitié de la course
   en 45ms (mesuré : 191px -> 106) : le dézoom se jouait derrière un couvercle
   déjà retombé, on ne le voyait pas. */
.faq__item.is-closing .faq__panel {
  transition-duration: var(--dur-faq-close);
  transition-timing-function: var(--ease-in);
}

@media (prefers-reduced-motion: reduce) {
  .faq__item.is-closing .faq__answer { animation: none; }
  .faq__item.is-open .faq__answer { animation: none; transform: scale(1); opacity: 1; }
}

/* Manque A₀ n° 3 : le calque à 0,7 de la source, reporté sur le <p> lui-même. */
.faq__answer-text {
  opacity: 0.7;
  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);
}

@media (max-width: 1199px) {
  .faq__intro { width: 600px; }

  .faq__heading {
    font-size: var(--fs-52);
    line-height: 52px;
  }

  /* Relevé : left 36, top 131,039, largeur 90. La largeur de 90 est plus étroite
     que le libellé + ses 60 de padding (98,7) : « FAQs » déborde donc de 4,35 px
     de chaque côté de la boîte, sur la source comme ici. C'est bien ce que fait
     la source, ce n'est pas un défaut d'ajustement — le mot reste entier et
     lisible, largement à l'intérieur de l'étoile. */
  .faq__sticker {
    left: 36px;
    top: 131.04px;
    width: 90px;
  }

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

  .faq__question {
    font-size: var(--fs-20);
    line-height: 28px;
  }

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

@media (max-width: 809px) {
  .faq {
    gap: 40px;
    padding: 30px 20px 70px;
  }

  /* Changement de régime : le sticker quitte le positionnement absolu et devient
     le premier élément d'une colonne centrée, au-dessus du titre, gouttière nulle
     (relevé à 809 comme à 390 : boîte d'intro 350 × 205,5 = 79,5 de sticker +
     126 de titre). Le titre garde une largeur codée de 350 — pas 100 % : à 809 la
     zone de contenu fait 769 et le titre y reste à 350, centré. */
  .faq__intro {
    display: flex;
    flex-direction: column;
    align-items: center;
    width: 350px;
    max-width: 100%;
  }

  .faq__heading {
    font-size: var(--fs-42);
    line-height: 42px;
  }

  /* `position: relative` et non `static` : la forme du sticker reste positionnée
     en absolu dans SON repère. `width: fit-content` reproduit le comportement
     mesuré (96,2734 relevé = 36,29 de libellé + 60 de padding, au centième), là
     où les deux paliers supérieurs codent une largeur. */
  .faq__sticker {
    position: relative;
    left: auto;
    top: auto;
    width: fit-content;
    transform: rotate(-20deg);
  }

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

  /* Le quinconce disparaît : les deux cartes prennent toute la largeur. */
  .faq__question-wrap { padding-right: 0; }
  .faq__panel { padding-left: 0; }
}
