/* about.css — section « À propos » : récit du studio + trois fondateurs (#about).

   Toutes les valeurs sont relevées sur la source le 2026-08-11, aux paliers
   1440 / 1300 / 1024 / 809 / 390, APRÈS parcours de la section par paliers sur
   toute sa hauteur puis retour au bord haut (règle A₁.5 : `document.getAnimations()`
   vide ne prouve rien, la source translate ses blocs en JS). `location.href` ET
   `innerWidth` ont été renvoyés dans le MÊME `browser_evaluate` que chaque mesure
   (règles A₁.6). Chaque ensemble a été énuméré membre par membre, jamais
   échantillonné (piège n° 8) — c'est ainsi qu'on a trouvé les TROIS fonds de carte
   et les QUATRE formes SVG décoratives, que ni le brief ni les constats du
   contrôleur ne mentionnent.

   Contrôle arithmétique de la hauteur de section, aux trois paliers :
     1440 : 90 (pad haut) + 124,81 (récit)  + 60 (gap) +  674,42 (grille) + 145 = 1094,23
     1024 : 90            + 104    (récit)  + 60       +  468,12 (grille) + 145 =  867,12
      390 : 90            + 286    (récit)  + 40       + 1640    (grille) +  70 = 2126
   Les trois totaux sont exactement les hauteurs mesurées sur la source
   (1094,23 / 867,12 / 2126). La cible du brief à 1440 (1094) est donc atteinte
   au pixel près.

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

   1. LE BORD FESTONNÉ DE HAUT DE SECTION. 15 bosses en --c-sand qui remontent
      au-dessus de la section et mordent sur l'olive de #reviews : 96 × 75,59
      remontées de 61 à 1440 ; 68,27 × 53,76 remontées de 40 à 1024 ;
      26 × 20,47 remontées de 20 à 390. Ce sont exactement les tokens --scallop-*
      en place : la primitive partagée `.scallop-top` (layout.css) convient telle
      quelle, portée par la section dans le markup. La section ne doit donc PAS
      passer en overflow hidden/clip.
      ⚠ Le constat n° 5 du contrôleur (« Fond uni, aucun calque peint ») est juste
      sur ce qu'il mesure et FAUX sur ce qu'il conclut : la source dessine ses
      bosses avec un `background-color` + `border-radius: 90px 90px 0 0` sur des
      <div> de 96 de large, jamais avec un `background-image`. Exactement le même
      angle mort qu'en tâche 13 sur #reviews.

   2. LES TROIS FONDS DE CARTE. Chaque fondateur a le sien, et c'est le seul
      élément qui distingue les cartes entre elles :
        Franck Wilhelm   --c-orange       (255·159·0)
        François Haegel  --c-orange-deep  (244·99·30)
        Sylvain Merle    --c-red          (203·4·4)
      Énumérés carte par carte aux trois paliers. Le brief ne parle d'aucun fond.

   3. LES PORTRAITS SONT MASQUÉS, PAS CARRÉS. Le constat n° 3 (« rendus en carré
      presque parfait, border-radius: 0 ») est exact sur la BOÎTE et passe à côté
      du masque : `.framer-cyojnf` porte un `mask-image` en `contain / center /
      no-repeat`, différent pour chacun des trois, qui découpe la photo en trèfle,
      en étoile et en croix. Invisible à un balayage `background-image` comme à un
      relevé de `border-radius` ; trouvé SUR LA CAPTURE puis confirmé par
      `getComputedStyle(el).maskImage`. Les trois fichiers sont déjà dans
      `assets/svg/` (tâche 1).
      ⚠ `assets/README.md` les décrit comme « Sticker blob blanc … décor de
      section » — c'est faux, ils ne sont jamais rendus comme image : ils ne
      servent que de masque. Signalé au rapport ; README non modifié (hors périmètre).

   4. QUATRE formes SVG décoratives, et non trois (constat n° 4). Le tracé
      `viewBox="0 0 501 291"` sert DEUX fois dans cette seule section : sous le
      sticker « À propos » et sous celui de « Pixel Wizard ». Appariement complet,
      relevé sticker par sticker (forme + couleur de remplissage) :
        À propos       501 × 291  --c-orange-deep
        Idea Squeezer  173 ×  89  --c-lavender
        Pixel Wizard   501 × 291  --c-mint
        Detail Ninja   119 × 118  --c-sand
      Les trois tracés sont character-for-character ceux déjà inlinés :
      501×291 en tâches 9, 12 et 13 (4ᵉ et 5ᵉ occurrences ici) ; 173×89 en
      tâche 11 (#process, 2ᵉ occurrence) ; 119×118 en tâche 9 (#benefits, 2ᵉ).
      Non factorisés ici (cela rouvrirait quatre sections closes) ; l'arbitrage
      est reporté à la tâche 18, comme demandé par le constat n° 4.

   5. LE CALQUE D'OMBRE DES ICÔNES SOCIALES. Chaque icône a DEUX tracés — le
      constat n° 1 le dit — mais le premier porte `opacity: 0.2` et n'est pas une
      simple redite du second : c'est le remplissage « duotone » (le corps de
      l'oiseau, le carré du logo LinkedIn). Énuméré sur les douze tracés :
      2 valeurs d'opacité distinctes, 1 seule couleur de remplissage
      (--c-ink-alt, canaux 61·0·27 — le constat est juste, c'est bien
      --c-ink-alt et non --c-ink).

   ---------------------------------------------------------------------------
   `.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 en le
   laissant déborder en hauteur (132 × 130,9 pour une boîte de 132 × 40 sur
   « Detail Ninja »), alors que `.sticker--masked` contient la forme dans la
   boîte et écraserait l'étoile. Même choix qu'en tâches 10, 12 et 13.
   `.card` (layout.css) n'est pas réutilisée non plus : elle pose `overflow:
   hidden`, qui rognerait les stickers, tous en débord de leur carte.

   Les trois sticker-blobs et les six icônes sont inlinés en SVG plutôt que
   référencés en <img> : la source les inline aussi, et leur couleur de
   remplissage vient d'un token — un <img> ne peut pas la recevoir. */

.about {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 60px;
  padding: 90px 40px 145px;
  background: var(--c-sand);

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

/* ---------- Récit + sticker « À propos » ----------
   Le bloc de récit fait toute la largeur du contenu de section (1360 à 1440) et
   sert de référent au sticker, posé en absolu dans SON repère. Le padding-left
   de 5px est relevé tel quel : la source le pose à 1440, 1300, 809 et 390 —
   et à 0 au SEUL palier tablette (voir plus bas). */
.about__intro {
  position: relative;
  width: 100%;
  padding-left: 5px;
}

.about__story {
  font-family: var(--font-sans);
  font-weight: 600;
  font-size: var(--fs-24);
  line-height: 31.2px;
  letter-spacing: -0.96px;
  color: var(--c-ink);
  /* Relevé sur la source (`text-wrap-style: balance` calculé). C'est lui qui
     donne les quatre lignes de longueurs voisines à 1440 ; sans lui la coupe
     gloutonne remplit la première ligne jusqu'au bord et déséquilibre le pavé.
     Sans effet à 390 (11 lignes : au-delà de 6, Chrome retombe en coupe
     gloutonne — comme la source, même moteur, même résultat). */
  text-wrap: balance;
}

/* Le sticker déborde à DROITE de son référent et au-dessus de lui : à 1440 son
   bord droit tombe à x = 1453 pour une page de 1440, soit 13px hors écran (et
   28px une fois l'AABB de la rotation prise en compte). La source fait pareil —
   son `document.scrollWidth` vaut 1468 à 1440 de large. Chez nous
   `body { overflow-x: hidden }` (base.css) escamote le débord ; le rendu visible
   est identique, sans la barre de défilement horizontale de la source.
   Ancrage par `right`, pas par `left` : vérifié en mesurant à 1300, où `right`
   reste à -53 alors que `left` passe de 1273 à 1133. */
.about__sticker {
  position: absolute;
  right: -53px;
  top: -98px;
  display: grid;
  place-items: center;
  /* Largeur codée, hauteur libre : c'est ce que fait la source. La boîte mesure
     140 × 112 à 1440 (libellé sur deux lignes) et 140 × 79,5 à 390 (une seule
     ligne, police plus petite) — soit exactement « libellé + 60 » dans les deux
     axes, aux quatre paliers. Le libellé tient donc toujours dans sa forme
     (règle A₁.3), et le nombre de lignes n'est pas codé. */
  width: 140px;
  padding: 30px;
  transform: rotate(-20deg);
}

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

.about__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;
  text-wrap: balance;
}

/* ---------- Grille des fondateurs ----------
   Hauteur de rangée : la source pose `aspect-ratio: 0.662289` (relevé tel quel,
   aux quatre paliers) et laisse le CONTENU l'emporter quand il est plus haut.
   Les deux régimes existent réellement :
     1440 : ratio 674,42 > contenu 600,63  → c'est le ratio qui décide
     1024 : ratio 465,06 < contenu 468,11  → c'est le contenu qui décide
             (la fonction passe alors sur deux lignes, d'où les 3px de plus)
   La source obtient ce max() par ACCIDENT : elle ne pose l'`aspect-ratio` que
   sur les cartes 1 et 3, avec `min-height: 0`, et c'est la carte 2 — la seule
   sans ratio — qui tire la rangée quand le contenu déborde. Énumération des
   trois : `0.662289 / 1`, `auto`, `0.662289 / 1`.

   Reproduit ici sans cette asymétrie fortuite, par un gabarit invisible posé
   dans la même cellule que la première carte : lui seul porte le ratio, les
   cartes ne portent que leur contenu, et la rangée prend le max des deux — ce
   qui est exactement le comportement observé. Les quatre éléments sont placés
   explicitement parce qu'un pseudo-élément à position définie est placé AVANT
   les éléments auto-placés : sans cela les cartes commenceraient en colonne 2.

   ⚠ `aspect-ratio` + `min-height: min-content` sur la carte NE MARCHE PAS et a
   été essayé d'abord : pour une boîte à ratio et largeur définie, la taille
   min-content de l'axe de bloc est la taille TRANSFÉRÉE (largeur / ratio), pas
   la hauteur du contenu. Mesuré : 465,05 au lieu de 468,12 à 1024, et 3px de
   contenu hors carte. */
.about__grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 10px;
  width: 100%;
}

/* ⚠ `width: 100%` + `align-self: start` ne sont pas décoratifs. Sans eux, le
   gabarit n'a de taille définie dans aucun axe : il se fait étirer à la hauteur
   de rangée, puis REDONNE cette hauteur × ratio comme contribution de largeur,
   et élargit sa colonne. Mesuré : colonnes 310,02 / 306,98 / 306,99 au lieu de
   308 partout. Un pourcentage compte pour zéro dans le calcul intrinsèque des
   colonnes : la colonne se dimensionne donc sur les seules cartes, puis le
   gabarit prend sa largeur et en déduit la hauteur de rangée. */
.about__grid::before {
  content: "";
  grid-row: 1;
  grid-column: 1;
  align-self: start;
  width: 100%;
  min-width: 0;
  aspect-ratio: 0.662289;
  pointer-events: none;
}

.about__card:nth-child(1) { grid-row: 1; grid-column: 1; }
.about__card:nth-child(2) { grid-row: 1; grid-column: 2; }
.about__card:nth-child(3) { grid-row: 1; grid-column: 3; }

.about__card {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: space-between;
  padding: 30px;
  border-radius: 40px;
  background: var(--about-tone, var(--c-orange));
}

/* Manque A₀ n° 2 : le fond est le seul élément qui distingue les trois cartes.
   Porté par une custom property plutôt que par un `background` par modificateur,
   pour n'écrire la déclaration qu'une fois. */
.about__card--franck   { --about-tone: var(--c-orange); }
.about__card--francois { --about-tone: var(--c-orange-deep); }
.about__card--sylvain  { --about-tone: var(--c-red); }

/* ---------- Sticker de surnom ----------
   Posé en absolu dans le repère de la carte, à 21 % / 11 % de sa boîte —
   pourcentages vérifiés aux quatre paliers (93,80/74,18 sur 446,66×674,42 à
   1440 ; 73,50/59,40 sur 350×540 à 390). `translate(-50%,-50%)` avant la
   rotation, comme la source (matrice relevée : rotation -20° + translation
   exactement -w/2, -h/2).
   Padding dissymétrique 4/10/10 relevé tel quel : il donne une boîte de
   132 × (libellé + 14), soit 132 × 66 pour deux lignes et 132 × 40 pour une —
   les valeurs mesurées. La largeur utile de 112 est ce qui fait passer
   « Idea Squeezer » et « Pixel Wizard » sur deux lignes et laisse
   « Detail Ninja » sur une seule. */
.about__badge {
  position: absolute;
  left: 21%;
  top: 11%;
  z-index: 1;
  display: grid;
  place-items: center;
  width: 132px;
  padding: 4px 10px 10px;
  transform: translate(-50%, -50%) rotate(-20deg);
}

.about__badge-shape {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 100%;
  height: auto;
  transform: translate(-50%, -50%);
  pointer-events: none;
}

/* Manque A₀ n° 4 : trois formes et trois couleurs distinctes, une par fondateur. */
.about__badge-shape--cloud { aspect-ratio: 173 /  89; fill: var(--c-lavender); }
.about__badge-shape--star  { aspect-ratio: 501 / 291; fill: var(--c-mint); }
.about__badge-shape--burst { aspect-ratio: 119 / 118; fill: var(--c-sand); }

.about__badge-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;
  text-wrap: balance;
}

/* ---------- Portrait ----------
   Manque A₀ n° 3 : la boîte est bien un carré presque parfait sans rayon
   (`aspect-ratio: 0.993865`, relevé tel quel aux quatre paliers), mais elle
   porte un masque SVG en `contain`, différent pour chacun des trois. Les SVG ne
   sont pas rendus comme image : seul leur tracé compte, la couleur ne joue pas.
   `flex: none` parce que la carte est un flex column : sans lui, le portrait se
   ferait comprimer quand le contenu dépasse (palier mobile large, cf. réserves).
   Les deux dimensions de l'<img> sont redonnées ici, `img { height: auto }` du
   reset écrasant sinon l'attribut `height` du markup. */
.about__portrait {
  flex: none;
  display: block;
  width: 100%;
  aspect-ratio: 0.993865;
  overflow: hidden;
  -webkit-mask: var(--about-mask) no-repeat center / contain;
  mask: var(--about-mask) no-repeat center / contain;
}

.about__card--franck   .about__portrait { --about-mask: url("../../assets/svg/1yTqWT9s2Gwa1tx9b9ngqhTTSJo.svg"); }
.about__card--francois .about__portrait { --about-mask: url("../../assets/svg/Bf3S7lrMf4RLc0FEbNVgXCJTvI.svg"); }
.about__card--sylvain  .about__portrait { --about-mask: url("../../assets/svg/qONRBbHfysnmWnOq6Vnl2OUAl3E.svg"); }

/* Noir et blanc sur les trois portraits — demande du 2026-08-13, ÉCART ASSUMÉ
   avec la source, qui les laisse en couleur (deux des trois y sont d'ailleurs
   déjà monochromes d'origine, ce qui rendait le troisième dissonant).
   Le filtre est porté par l'<img>, pas par `.about__portrait` : sur le parent
   il s'appliquerait aussi au masque et, surtout, la pastille du badge et le
   fond de carte tombent hors de cet élément — seules les photos changent. */
/* Cadrage des trois visages — demande du 2026-08-13, ÉCART ASSUMÉ avec la
   source, qui pose ses photos telles quelles. Les trois clichés n'ont ni le
   même recul ni le même centrage : mesurés dans leur cadre (règle horizontale
   posée à l'écran, graduée tous les 5 % de la hauteur de boîte), la ligne des
   yeux tombait à 27 % chez Franck, 48 % chez François, 39 % chez Sylvain, et
   les visages occupaient 33 / 45 / 43 % de la hauteur.
   Chaque photo est donc recadrée à la volée pour amener les yeux sur une MÊME
   ligne à 40 % et les visages à une taille comparable.

   Modèle, avec l'origine de transformation en haut du cadre :
     yeux_finaux  = zoom × (yeux_mesurés + décalage)
     visage_final = zoom × visage_mesuré
   `--about-shift` est négatif ou nul et jamais inférieur à (1/zoom − 1) : c'est
   la condition pour que l'image couvre encore tout le cadre après déplacement.

   ⚠ Le zoom de Franck (1,5) dépasse la résolution de son fichier (682px de
   large pour ~580 affichés) : léger manque de piqué sur écran très dense. Il
   est inévitable — sa tête est haute et petite dans son cadre, et l'abaisser
   ne peut se faire qu'en zoomant. Un fichier plus grand ou recadré en amont
   supprimerait la réserve. */

/* ---------- Survol : la FORME tourne, la photo non (2026-08-14) ----------
   Demandé sur le modèle de la carte d'invitation des Projets, mais sans le zoom.

   La difficulté : la forme n'est pas un décor posé à côté de la photo, c'est le
   `mask` de `.about__portrait`. Faire tourner cet élément ferait donc tourner la
   photo avec — visage penché, exactement ce qu'on ne veut pas.

   La parade est une enveloppe qui tourne EN SENS INVERSE. Le conteneur masqué
   pivote de +θ (son masque suit), l'enveloppe intérieure de −θ : les deux
   rotations ont la même origine (le centre par défaut) et s'annulent exactement
   sur le contenu. Seul le découpage bouge, le visage reste droit.
   ⚠ C'est pour cela que la contre-rotation ne peut PAS être posée sur l'`<img>` :
   celle-ci porte déjà `transform-origin: 50% 0` pour son recadrage (règle
   ci-dessous), et tourner autour de ce point-là ne compenserait pas la première.
   ⚠ Le cadre est quasi carré (rapport 0,9939) et les trois formes tiennent dans
   le disque inscrit : elles peuvent donc pivoter sans sortir de la photo, qui
   remplit tout le cadre. Le recadrage relevé (--about-zoom / --about-shift, ligne
   des yeux à 42 %) n'est pas touché.

   ⚠ Un QUART DE TOUR, aligné sur le halo du Process (demande du 2026-08-14).
   Ces formes sont très symétriques : mesuré au pixel entre 0° et 90°, l'astérisque
   de Sylvain est identique à 0,0 % près, le trèfle de Franck à 4,5 %, le médaillon
   de François à 12,1 %. Un premier jet posait 12°, au motif qu'un quart de tour
   serait « invisible » — le raisonnement portait sur la position d'ARRIVÉE et
   passait à côté de l'essentiel : ce qui se voit, c'est le MOUVEMENT pendant la
   demi-seconde. Le halo du Process a la même symétrie et se lit très bien.

   Durée et courbe : celles du halo du Process (--dur-halo / --ease-halo), comme
   pour l'étoile de la carte d'invitation. Pas de zoom, à la demande. */
.about__portrait,
.about__portrait-inner {
  transition: transform var(--dur-halo) var(--ease-out);
  /* Déclaration séparée : un navigateur sans `linear()` garde --ease-out, donc
     la rotation sans le petit recul. */
  transition-timing-function: var(--ease-halo);
}

.about__portrait-inner {
  display: block;
  width: 100%;
  height: 100%;
}

/* `hover: hover` écarte le tactile, où l'état resterait collé au premier
   toucher. `focus-within` fait profiter le clavier de l'effet : chaque carte
   contient un lien LinkedIn focalisable. */
@media (hover: hover) {
  .about__card:hover .about__portrait,
  .about__card:focus-within .about__portrait { transform: rotate(90deg); }

  .about__card:hover .about__portrait-inner,
  .about__card:focus-within .about__portrait-inner { transform: rotate(-90deg); }
}

@media (prefers-reduced-motion: reduce) {
  .about__portrait,
  .about__portrait-inner { transition: none; }

  .about__card:hover .about__portrait,
  .about__card:focus-within .about__portrait,
  .about__card:hover .about__portrait-inner,
  .about__card:focus-within .about__portrait-inner { transform: none; }
}

.about__portrait img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  filter: grayscale(1);
  transform-origin: 50% 0;
  transform: scale(var(--about-zoom, 1)) translateY(var(--about-shift, 0));
}

.about__card--franck   .about__portrait img { --about-zoom: 1.5;  --about-shift: 0; }
.about__card--francois .about__portrait img { --about-zoom: 1.18; --about-shift: -14.1%; }
.about__card--sylvain  .about__portrait img { --about-zoom: 1.18; --about-shift: -2.1%; }

/* ---------- Identité ----------
   Trois gouttières emboîtées, relevées : 10 entre le bloc nom et les réseaux,
   7 entre les noms et la fonction, 0 entre prénom et nom. */
.about__ident {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  width: 100%;
}

.about__names {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 7px;
  width: 100%;
}

/* La source pose DEUX <h3> par carte, un par ligne. Un seul titre portant deux
   <span> en bloc donne le même rendu au pixel (même pile, même gouttière nulle)
   et un arbre d'en-têtes correct : « Franck Wilhelm » et non deux titres
   « Franck » puis « Wilhelm ». Écart de balisage assumé, documenté au rapport.
   Les deux lignes n'ont ni la même taille ni le même interligne — c'est relevé,
   pas une approximation. */
.about__name {
  width: 100%;
  font-family: var(--font-display);
  font-weight: 400;
  color: var(--c-ink);
  text-align: center;
}

.about__first { display: block; font-size: var(--fs-37); line-height: 37px; }
.about__last  { display: block; font-size: var(--fs-22); line-height: 30.8px; }

/* Fonction : le texte est écrit en casse MIXTE dans le markup et mis en
   capitales par ce `text-transform`, comme la source — d'où l'irrégularité
   « Co-fondateur » / « co-fondateur » conservée telle quelle, invisible à
   l'écran mais lue correctement par les lecteurs d'écran.
   Seul texte de la section à porter un interlettrage POSITIF (+0,6px). */
.about__role {
  width: 100%;
  font-family: var(--font-sans);
  font-weight: 600;
  font-size: var(--fs-12);
  line-height: 16.8px;
  letter-spacing: 0.6px;
  text-transform: uppercase;
  color: var(--c-ink);
  text-align: center;
}

/* ---------- Réseaux sociaux ----------
   Manque A₀ du brief, signalé par le constat n° 1 : deux liens par fondateur,
   six au total. Cible de 50 × 50 pour une icône de 30 — la marge n'est pas
   décorative, c'est la zone cliquable. Aucun fond : les icônes se posent
   directement sur la carte. */
.about__social {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
}

.about__social-link {
  display: grid;
  place-items: center;
  width: 50px;
  height: 50px;
}

/* Les deux icônes ne sont pas inclinées du même angle, ni dans le même sens :
   +12° pour X, -16° pour LinkedIn. Relevé sur les SIX liens (6 valeurs,
   2 distinctes) et non sur un échantillon. */
.about__icon {
  width: 30px;
  height: 30px;
  fill: var(--c-ink-alt);
}

.about__icon--x        { transform: rotate(12deg); }
.about__icon--linkedin { transform: rotate(-16deg); }

/* Manque A₀ n° 5 : le calque « duotone » de chaque icône. */
.about__icon-shade { opacity: 0.2; }

/* ---------- Survol des liens sociaux ----------
   Manque relevé le 2026-08-13 : ces six liens sont les SEULS éléments du site
   dont la source anime le survol au-delà des boutons (cartes, lignes de
   services, questions de FAQ et cartes de témoignage : rien, vérifié en
   comparant l'intégralité des styles calculés de chaque sous-arbre).
   Deux effets, mesurés :
   - l'icône passe de 30 à 40px — 86 % du chemin en 125ms, le dernier centième
     à ~810ms (ressort). --ease-out sur --dur-social redonne les mêmes 86 % à
     125ms ; la traîne sub-pixel de la source n'est pas reproduite ;
   - le calque duotone passe de 0,2 à 1, et celui-là bascule D'UN COUP (déjà à 1
     à la première image relevée après le survol) : pas de transition dessus.
   `:focus-visible` reçoit le même état — même convention qu'au pied de page,
   ce n'est pas un ajout mais l'équivalent clavier d'un état de la source. */
.about__icon {
  transition:
    width var(--dur-social) var(--ease-out),
    height var(--dur-social) var(--ease-out);
}

.about__social-link:hover .about__icon,
.about__social-link:focus-visible .about__icon {
  width: 40px;
  height: 40px;
}

.about__social-link:hover .about__icon-shade,
.about__social-link:focus-visible .about__icon-shade {
  opacity: 1;
}

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

@media (max-width: 1199px) {
  /* Seul palier où la source retire le décalage de 5px du bloc de récit
     (relevé : padding 0 à 1024, 0 0 0 5px à 1300 comme à 809 et 390). */
  .about__intro { padding-left: 0; }

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

  /* Le sticker se rapproche du bord (relevé : right -25, top -87 ; les mêmes
     -53 / -98 qu'à 1440 le feraient sortir de l'écran de 15px de plus). */
  .about__sticker { right: -25px; top: -87px; }

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

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

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

  /* Le décalage de 5px revient, et le sticker retrouve exactement l'ancrage du
     palier desktop (right -53, top -98) — relevé à 809 comme à 390. */
  .about__intro { padding-left: 5px; }
  .about__sticker { right: -53px; top: -98px; }

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

  /* Colonne unique, même gouttière de 10 qu'en grille. Le gabarit de ratio
     disparaît : à ce palier la hauteur de carte est codée, pas dérivée. */
  .about__grid { grid-template-columns: 1fr; }
  .about__grid::before { display: none; }

  .about__card:nth-child(1) { grid-row: 1; grid-column: 1; }
  .about__card:nth-child(2) { grid-row: 2; grid-column: 1; }
  .about__card:nth-child(3) { grid-row: 3; grid-column: 1; }

  /* ⚠ Hauteur CODÉE, et c'est bien ce que fait la source : le conteneur de
     chaque carte porte `height: 540px` à ce palier, quelle que soit la largeur.
     À 390 le contenu mesure 493,59 et tient donc largement ; au-delà d'environ
     600px de large il déborde de la carte, sur la source comme ici (voir
     réserves du rapport). */
  .about__card { height: 540px; }

  .about__first { font-size: var(--fs-26); line-height: 30px; }
}
