/* process.css — section « Notre recette de grand-mère » (#process).

   Toutes les valeurs sont relevées sur la source le 2026-08-11, aux trois
   paliers, APRÈS parcours de la section par paliers puis retour au bord haut
   (règle A1#5 renforcée : `document.getAnimations()` vide ne prouve rien).
   `location.href` a été renvoyé dans le MÊME `browser_evaluate` que chaque
   mesure (règle A1#6). Rien n'est extrapolé sauf mention explicite.

   Contrôle arithmétique de la hauteur de section, aux trois paliers :
     1440 : 60 (pad haut) + 136 (titre) + 60 (gap) + 549 (carte) + 145 = 950
     1024 : 60         + 104         + 60        + 402        + 145 = 771
      390 : 30         + 205,5       + 40        + 831,6      +  70 = 1177,1
   Les trois totaux sont exactement les hauteurs mesurées sur la source
   (950 / 771 / 1177,1). La cible du brief à 1440 (950) est donc atteinte.

   ---------------------------------------------------------------------------
   CONTREDIT LE CONSTAT n° 5 DU CONTRÔLEUR (« fond uni, aucune image ni
   dégradé »). La source pose bien un CALQUE DE POIS sur toute la section :
     radial-gradient(19px 19px, C1, C1 25%, C2 25%) avec C1 = 255 191 0
     (--c-orange-light) et C2 = 255 159 0 (--c-orange) — écrit ici sans la
     notation fonctionnelle, que tools/check.py refuse même en commentaire ;
     background-size 9,5px 9,5px, repeat — identique aux trois paliers,
     opacité 1, aucun ancêtre porteur d'opacity/filter/blend (chaîne remontée
     jusqu'à <body>, règle A1#1).
   C'est exactement le motif déjà relevé sur #statistics (voir statistics.css) ;
   les deux tokens --c-orange-light / --c-orange existent déjà pour lui.
   ---------------------------------------------------------------------------

   Structure de section (flex colonne centrée, identique aux trois paliers) :
     [intro : titre + sticker] — gap — [carte]

   Carte (« Step N - Desktop » / « - Phone » sur la source) :
     1440 : 1360 × 549, padding 40, ligne, gap 50, align-items center,
            rayon 40, fond --c-cream, overflow VISIBLE (le halo déborde de
            10,3px en haut et 10,2px en bas sur l'orange — vérifié à l'écran)
     1024 :  944 × 402, mêmes réglages
      390 :  350 × auto (831,6 mesuré), padding 40px 20px, COLONNE, gap 75,
            centré, overflow HIDDEN (relevé : la source bascule bien
            `overflow` de `visible` à `hidden` entre les deux variantes)
   La hauteur 549 / 402 est FIXE sur la source (elle ne dépend d'aucun
   contenu : le plus haut des enfants vaut 447,9 pour 469 de boîte de contenu
   à 1440). Elle est donc écrite en dur ici, ce qui garantit aussi que la
   section garde sa hauteur quel que soit l'onglet actif. À 390 la hauteur est
   au contraire dictée par le contenu (40 + 326,3 + 75 + 350,3 + 40 = 831,6).

   Typographie relevée :
     titre h2   Climate Crisis 400 — 68/68 (1440) · 52/52 (1024) ·
                42/42 ls -1,6px (390) ; centré ; `text-wrap: balance` relevé
                sur la source (sans lui la coupe gloutonne change à 390)
     sticker    Poppins 600 — 20/26 ls -0,8 · 16/20,8 ls -0,64 · 15/19,5 ls -0,6
     pastilles  Poppins 600 — 37/33,3 ls -1,11 (1440) · 42/37,8 ls -1,26 (1024)
                · 33/29,7 ls -0,99 (390).  ⚠ la TABLETTE est plus grosse que le
                desktop : c'est bien ce que rend la source, vérifié deux fois.
     titre h3   Climate Crisis 400 — 37/37 · 30/30 · 26/30 (centré à 390)
     texte      Poppins 600 — 18/25,2 ls -0,36 · 17/23,8 ls -0,34 (1024 ET 390)

   Manques du brief (A0), tous relevés puis reconstruits ici :
     — le calque de pois ci-dessus ;
     — QUATRE illustrations (une par étape) et non une seule ; trois d'entre
       elles (UPOR…, xpjlkd…, aGXEP…) n'étaient NI dans assets/img/, NI dans
       assets/manifest.json, NI dans assets/README.md — téléchargées et
       enregistrées, voir le rapport de tâche ;
     — le halo « explosion étoilée » derrière chaque illustration : même tracé
       SVG (viewBox 0 0 473 471) que celui déjà inliné en tâche 6
       (.studio__icon-burst) et en tâche 9 (.benefits__card-blob--mint) —
       vérifié caractère par caractère, c'est le MÊME `d`. Il n'est pas
       ré-inliné une troisième fois dans le markup : il est posé ici en
       masque CSS, ce qui évite de le dupliquer quatre fois (une par panneau)
       et ne touche pas au code des sections 6 et 9, closes.
     — le sticker « Process » : tracé SVG unique (viewBox 0 0 173 89, un seul
       `path`, fill relevé à 192 236 191 = --c-mint). `.sticker` rendrait
       une ellipse : faux (règle A1#0). Inliné dans le markup, comme le
       sticker « Portfolio » de la tâche 10. */

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

  /* Bord festonné du haut : primitive `.scallop-top` (layout.css), portée par
     la section dans le markup. Relevé sur la source : 15 bosses de
     96 × 75,6 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. */
  --scallop-color: var(--c-orange);
}

/* Motif de pois — voir l'en-tête. Calque dédié plutôt que fond de section,
   pour que `background` de .process reste une couleur simple (même choix
   qu'en statistics.css). Premier enfant du flux, donc peint sous les blocs
   positionnés qui le suivent, sans avoir besoin d'un z-index.

   Le motif n'occupe PAS toute la section : il apparaît en fondu depuis le haut.
   Masque relevé sur la source le 2026-08-13 sur le conteneur de SON calque de
   pois de #process (hauteur de calque 950 à 1440 et 1177 à 390 : ce sont bien
   les hauteurs de cette section-ci, pas celles d'une voisine) :

     mask-image: linear-gradient(181deg, transparent 10%, opaque 48%)

   Soit, au signe près, le masque déjà posé sur #statistics — la source emploie
   le MÊME fondu aux deux sections à pois, et aux trois largeurs. C'est lui qui
   raccorde le bord festonné à la section : les bosses sont peintes en
   --c-orange uni, et sans ce fondu les pois démarraient net juste sous elles,
   d'où l'arête horizontale visible au bas du feston.
   ⚠ Même contrainte qu'en statistics.css : la source écrit sa borne opaque en
   noir brut, interdit ici hors de `tokens.css` (check.py) ; seul le canal alpha
   d'un masque compte, `transparent` + un token rendent donc exactement pareil. */
.process__dots {
  position: absolute;
  inset: 0;
  background-image: radial-gradient(19px 19px, var(--c-orange-light), var(--c-orange-light) 25%, var(--c-orange) 25%);
  background-size: 9.5px 9.5px;
  background-repeat: repeat;
  -webkit-mask-image: linear-gradient(181deg, transparent 10%, var(--c-ink) 48%);
  mask-image: linear-gradient(181deg, transparent 10%, var(--c-ink) 48%);
  pointer-events: none;
}

/* ---------- Intro : titre + sticker ----------
   Même largeur que le conteneur de titre de la source (800 / 600 / pleine
   largeur), pour que la position du sticker, exprimée en pourcentage de cette
   boîte, se transpose telle quelle d'un palier à l'autre. */
.process__intro {
  position: relative;
  width: 800px;
}

.process__heading {
  width: 100%;
  /* Le <h1> de la source fait 750px dans une boîte de 800 à 1440, et occupe
     toute la boîte (600) à 1024 : un max-width reproduit les deux. */
  max-width: 750px;
  margin-inline: auto;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: var(--fs-68);
  line-height: 1;
  color: var(--c-ink);
  text-align: center;
  /* Relevé sur la source (`text-wrap: balance` calculé sur le h1). */
  text-wrap: balance;
}

/* Le sticker est dimensionné par son contenu (libellé + 30px de padding sur
   les quatre côtés), pas par une largeur codée : c'est ce que fait la source
   (vérifié en dépivotant les AABB de 20° aux trois paliers — 133,53 × 86,02
   à 1440, 118,87 × 80,80 à 1024, 115,19 × 79,50 à 390, soit exactement le
   libellé + 60 dans les deux axes) et c'est la seule façon de garantir que le
   libellé tient dans la forme (règle A1#3).

   Position : centre du sticker à -4,95% / 63% de la boîte du titre — vérifié
   identique aux deux paliers (1440 : -39,55/800 et 85,65/136 ;
   1024 : -30,05/600 et 65,5/104). */
.process__sticker {
  position: absolute;
  left: -4.95%;
  top: 63%;
  display: inline-grid;
  place-items: center;
  padding: 30px;
  transform: translate(-50%, -50%) rotate(-20deg);
}

.process__sticker-shape {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 100%;
  height: auto;
  aspect-ratio: 173 / 89;
  transform: translate(-50%, -50%);
  fill: var(--c-mint);
  pointer-events: none;
}

.process__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);
  white-space: nowrap;
}

/* ---------- Carte ----------
   `.card` (layout.css) n'est PAS réutilisée (règle A1#0) : elle ne porte
   qu'un fond, un rayon de --r-xl (32) et `overflow: hidden`, alors que la
   source pose un rayon de 40 et un overflow VISIBLE à ce palier. Trois
   déclarations sur trois auraient dû être annulées.

   La carte est aussi le bloc positionné de référence de l'illustration, qui
   est en absolu dans la colonne de droite (voir .process__visual). */
.process__card {
  position: relative;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: flex-start;
  gap: 10px;
  width: 100%;
  /* Le conteneur de la source est en max-width 1440px. */
  max-width: 1440px;
  height: 549px;
  padding: 40px;
  background: var(--c-cream);
  border-radius: 40px;
}

/* ---------- Sélecteur d'étapes ----------
   Sur la source ce sont quatre <div> en cursor: pointer, SANS tabindex, sans
   role et sans libellé : inatteignables au clavier, muets pour un lecteur
   d'écran. Écart délibéré et documenté (voir le rapport de tâche) : ce sont
   ici de vrais <button> dans un motif d'onglets ARIA. Le rendu visuel des
   deux états est conservé à l'identique.

   Géométrie relevée : hauteur = interligne + 40, largeur = chiffre + 40,
   rayon 20, filet de 2px en --c-olive-black. La source dessine ce filet avec
   un ::after en inset 0 (donc HORS de la boîte) ; ici c'est une vraie
   `border`, d'où un padding de 18 et non 20 — 18 + 2 = 20 de chaque côté,
   la boîte extérieure est identique au pixel près (52,3 × 73,3 pour « 1 »).

   État actif : fond --c-olive-black, chiffre en --c-yellow-pale (relevé
   24 26 18 et 250 250 191). Sur la source la bascule se fait par un
   calque de fond qui DESCEND depuis le haut de la pastille (relevé :
   `Background` en absolu, z-index -1, inset haut -140px à l'état inactif,
   rogné par l'overflow: hidden de la pastille). Simplifié ici en une
   transition de couleur : le glissement demanderait un calque dédié pour un
   effet de 320ms invisible au repos. */
.process__tabs {
  display: flex;
  align-items: center;
  gap: 10px;
}

.process__tab {
  display: grid;
  place-items: center;
  padding: 18px;
  border: 2px solid var(--c-olive-black);
  border-radius: 20px;
  background: transparent;
  color: var(--c-ink);
  font-family: var(--font-sans);
  font-weight: 600;
  font-size: var(--fs-37);
  line-height: 33.3px;
  letter-spacing: -1.11px;
  transition:
    background-color var(--dur-base) var(--ease-out),
    color var(--dur-base) var(--ease-out);
}

.process__tab[aria-selected="true"] {
  background: var(--c-olive-black);
  color: var(--c-yellow-pale);
}

/* ---------- Panneau d'étape ----------
   La source empile [pastilles] — gap 10 — [titre + texte], le tout centré
   verticalement dans la carte : la hauteur du bloc change d'une étape à
   l'autre (278,1 pour l'étape 1, 215,9 pour l'étape 4) et les pastilles se
   recentrent avec lui. C'est pour cela que les pastilles et le panneau sont
   deux enfants du MÊME conteneur centré, et non deux colonnes séparées.

   `padding-top: 10px` + `gap: 10px` reproduisent les 20px relevés entre le
   bas des pastilles et le haut du titre (10 de gap de la colonne + 10 de
   padding du bloc « Title and Text » sur la source), et les 10px entre titre
   et texte.

   Largeur : la colonne de texte de la source vaut (largeur de carte - 130)/2,
   soit 615 à 1440 et 407 à 1024, mais le bloc titre+texte y est plafonné à
   570 — d'où le max-width.
   ⚠ Le panneau est un enfant EN FLUX de la carte : ses pourcentages se
   résolvent sur la boîte de CONTENU (largeur de carte - 80 de padding), pas
   sur sa boîte de bordure. D'où `- 50px` ici et `- 130px` sur
   .process__visual, qui est en absolu et se résout, lui, sur la boîte de
   remplissage. Écrire 130 des deux côtés donnait 367 au lieu de 407 à 1024
   (l'erreur ne se voyait pas à 1440, où le max-width de 570 la masquait). */
/* La hauteur est animée au changement d'étape : les quatre panneaux n'ont pas
   la même, et la carte centrant son contenu, la rangée de chiffres se recale de
   quelques pixels. La source anime ce recalage sur ~250ms (relevé le
   2026-08-13) ; il se faisait ici en une image. C'est `tabs.js` qui pose les
   deux hauteurs, la transition ci-dessous qui les relie. Sans JS, aucune
   hauteur n'est posée et la propriété ne sert pas. */
.process__panel {
  display: flex;
  flex-direction: column;
  gap: 10px;
  width: calc((100% - 50px) / 2);
  max-width: 570px;
  padding-top: 10px;
  transition: height var(--dur-base) var(--ease-out);
}

/* `hidden` doit l'emporter sur le `display: flex` ci-dessus. */
.process__panel[hidden] { display: none; }

.process__title {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: var(--fs-37);
  line-height: 37px;
  color: var(--c-ink);
}

.process__text {
  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);
  /* Relevé sur la source (`text-wrap: balance` calculé sur le <p>, contrairement
     au <h3> qui reste en `wrap`). Sans lui, la coupe gloutonne donne à 1440
     « … votre marque, vos objectifs, / votre ambiance … » là où la source
     équilibre en « … votre marque, vos / objectifs, votre ambiance … » : même
     nombre de lignes, mais quatre coupes différentes sur quatre. */
  text-wrap: balance;
}

/* ---------- Illustration + halo ----------
   L'illustration est dans le panneau (elle change avec l'étape) mais rendue
   en absolu dans la colonne de droite : elle sort ainsi du flux vertical du
   panneau, ce qui préserve le centrage du bloc [pastilles + titre + texte]
   mesuré sur la source. Boîte : (largeur de carte - 130)/2 de large, calée à
   40 du bord droit, centrée verticalement sur la carte, rapport 1,37317
   relevé sur la source (615 × 447,9 à 1440, 407 × 296,4 à 1024). */
.process__visual {
  position: absolute;
  top: 50%;
  right: 40px;
  width: calc((100% - 130px) / 2);
  aspect-ratio: 1.37317;
  transform: translateY(-50%);
}

/* Halo : 93,0% de la largeur de la boîte, centré (mesuré 571,9/615 à 1440 et
   378,5/407 à 1024 — même rapport aux deux paliers), rapport 473/471.
   Posé en masque CSS et non en SVG inline : le tracé est le MÊME que celui
   déjà inliné en tâche 6 et en tâche 9 (comparé caractère par caractère), et
   il faudrait sinon le répéter dans les quatre panneaux. */
/* Le halo tourne d'un quart de tour à chaque changement d'étape : angle =
   90° × numéro d'étape, avec le petit recul relevé sur la source (voir
   --dur-halo / --ease-halo dans tokens.css). `--halo-turn` est posé par
   tabs.js sur la carte, donc partagé par les quatre panneaux : le halo du
   panneau qui arrive part de l'angle de celui qui part, et la rotation est
   continue d'une étape à l'autre comme sur la source.
   ⚠ La rotation est écrite DANS le `transform`, à la suite du translate de
   centrage, et non dans la propriété individuelle `rotate` : CSS applique
   `rotate` APRÈS `transform`, donc autour du centre d'origine de la boîte, et
   le halo décentré de -50 % partirait en orbite au lieu de tourner sur place.
   Sans JavaScript, `--halo-turn` vaut 0 : c'est l'état de l'étape 1. */
.process__visual::before {
  content: "";
  position: absolute;
  left: 50%;
  top: 50%;
  width: 93%;
  aspect-ratio: 473 / 471;
  transform: translate(-50%, -50%) rotate(calc(var(--halo-turn, 0) * 90deg));
  transition: transform var(--dur-halo) var(--ease-out);
  /* Déclaration séparée : un navigateur sans `linear()` l'ignore et garde
     --ease-out ci-dessus, ce qui donne la rotation sans le recul. */
  transition-timing-function: var(--ease-halo);
  /* La couleur CHANGE d'une étape à l'autre — voir les quatre déclarations sous
     cette règle. Le repli sert de garde-fou : un panneau qui oublierait de la
     déclarer retomberait sur la couleur de l'étape 1 plutôt que de disparaître. */
  background-color: var(--process-halo, var(--c-yellow-pale));
  -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 473 471'%3E%3Cpath d='M228.604 4.16201C232.607 -0.990265 240.393 -0.990264 244.396 4.16201L261.274 25.8824C264.545 30.0913 270.541 30.9952 274.907 27.9372L297.437 12.1566C302.782 8.41334 310.221 10.7082 312.528 16.8116L322.254 42.5418C324.139 47.5277 329.603 50.1591 334.676 48.5239L360.856 40.0852C367.067 38.0835 373.499 42.4692 373.905 48.9815L375.614 76.4352C375.946 81.7551 380.391 85.8802 385.721 85.813L413.226 85.466C419.75 85.3837 424.604 91.4707 423.072 97.8132L416.614 124.551C415.362 129.732 418.395 134.985 423.507 136.491L449.892 144.267C456.151 146.111 458.996 153.359 455.662 158.968L441.609 182.614C438.886 187.196 440.236 193.109 444.677 196.056L467.598 211.263C473.035 214.87 473.617 222.634 468.778 227.012L448.38 245.465C444.427 249.041 443.974 255.089 447.35 259.214L464.77 280.502C468.902 285.551 467.17 293.142 461.256 295.898L436.324 307.52C431.493 309.772 429.277 315.417 431.287 320.354L441.659 345.831C444.119 351.874 440.226 358.616 433.762 359.507L406.513 363.264C401.233 363.992 397.452 368.733 397.917 374.043L400.318 401.445C400.888 407.945 395.181 413.24 388.742 412.187L361.596 407.744C356.335 406.883 351.325 410.3 350.204 415.511L344.422 442.403C343.05 448.782 336.036 452.16 330.193 449.255L305.563 437.009C300.79 434.636 294.995 436.423 292.388 441.073L278.936 465.066C275.745 470.758 268.047 471.918 263.32 467.42L243.394 448.458C239.532 444.783 233.468 444.783 229.606 448.458L209.68 467.42C204.953 471.918 197.255 470.758 194.064 465.066L180.612 441.073C178.005 436.423 172.21 434.636 167.437 437.009L142.807 449.255C136.964 452.16 129.95 448.782 128.578 442.403L122.796 415.511C121.675 410.3 116.665 406.883 111.404 407.744L84.2584 412.187C77.8192 413.24 72.112 407.945 72.6816 401.445L75.083 374.043C75.5483 368.733 71.7671 363.992 66.4868 363.264L39.2376 359.507C32.7738 358.616 28.881 351.874 31.3412 345.831L41.7128 320.354C43.7225 315.417 41.5069 309.772 36.6757 307.52L11.7443 295.898C5.83034 293.142 4.09789 285.551 8.23011 280.502L25.6503 259.214C29.0259 255.089 28.5727 249.041 24.6199 245.465L4.22158 227.012C-0.617099 222.634 -0.0352793 214.87 5.40177 211.263L28.3227 196.056C32.7642 193.109 34.1137 187.196 31.3906 182.614L17.3378 158.968C14.0044 153.359 16.8487 146.111 23.1075 144.267L49.4925 136.491C54.6054 134.985 57.6377 129.732 56.3862 124.551L49.9276 97.8132C48.3955 91.4707 53.2497 85.3837 59.7741 85.466L87.2788 85.813C92.6086 85.8802 97.0544 81.7551 97.3856 76.4352L99.0951 48.9815C99.5006 42.4692 105.933 38.0835 112.144 40.0852L138.324 48.5239C143.397 50.1591 148.861 47.5277 150.746 42.5418L160.472 16.8116C162.779 10.7082 170.218 8.41334 175.563 12.1567L198.093 27.9372C202.459 30.9952 208.455 30.0913 211.726 25.8824L228.604 4.16201Z'/%3E%3C/svg%3E");
  mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 473 471'%3E%3Cpath d='M228.604 4.16201C232.607 -0.990265 240.393 -0.990264 244.396 4.16201L261.274 25.8824C264.545 30.0913 270.541 30.9952 274.907 27.9372L297.437 12.1566C302.782 8.41334 310.221 10.7082 312.528 16.8116L322.254 42.5418C324.139 47.5277 329.603 50.1591 334.676 48.5239L360.856 40.0852C367.067 38.0835 373.499 42.4692 373.905 48.9815L375.614 76.4352C375.946 81.7551 380.391 85.8802 385.721 85.813L413.226 85.466C419.75 85.3837 424.604 91.4707 423.072 97.8132L416.614 124.551C415.362 129.732 418.395 134.985 423.507 136.491L449.892 144.267C456.151 146.111 458.996 153.359 455.662 158.968L441.609 182.614C438.886 187.196 440.236 193.109 444.677 196.056L467.598 211.263C473.035 214.87 473.617 222.634 468.778 227.012L448.38 245.465C444.427 249.041 443.974 255.089 447.35 259.214L464.77 280.502C468.902 285.551 467.17 293.142 461.256 295.898L436.324 307.52C431.493 309.772 429.277 315.417 431.287 320.354L441.659 345.831C444.119 351.874 440.226 358.616 433.762 359.507L406.513 363.264C401.233 363.992 397.452 368.733 397.917 374.043L400.318 401.445C400.888 407.945 395.181 413.24 388.742 412.187L361.596 407.744C356.335 406.883 351.325 410.3 350.204 415.511L344.422 442.403C343.05 448.782 336.036 452.16 330.193 449.255L305.563 437.009C300.79 434.636 294.995 436.423 292.388 441.073L278.936 465.066C275.745 470.758 268.047 471.918 263.32 467.42L243.394 448.458C239.532 444.783 233.468 444.783 229.606 448.458L209.68 467.42C204.953 471.918 197.255 470.758 194.064 465.066L180.612 441.073C178.005 436.423 172.21 434.636 167.437 437.009L142.807 449.255C136.964 452.16 129.95 448.782 128.578 442.403L122.796 415.511C121.675 410.3 116.665 406.883 111.404 407.744L84.2584 412.187C77.8192 413.24 72.112 407.945 72.6816 401.445L75.083 374.043C75.5483 368.733 71.7671 363.992 66.4868 363.264L39.2376 359.507C32.7738 358.616 28.881 351.874 31.3412 345.831L41.7128 320.354C43.7225 315.417 41.5069 309.772 36.6757 307.52L11.7443 295.898C5.83034 293.142 4.09789 285.551 8.23011 280.502L25.6503 259.214C29.0259 255.089 28.5727 249.041 24.6199 245.465L4.22158 227.012C-0.617099 222.634 -0.0352793 214.87 5.40177 211.263L28.3227 196.056C32.7642 193.109 34.1137 187.196 31.3906 182.614L17.3378 158.968C14.0044 153.359 16.8487 146.111 23.1075 144.267L49.4925 136.491C54.6054 134.985 57.6377 129.732 56.3862 124.551L49.9276 97.8132C48.3955 91.4707 53.2497 85.3837 59.7741 85.466L87.2788 85.813C92.6086 85.8802 97.0544 81.7551 97.3856 76.4352L99.0951 48.9815C99.5006 42.4692 105.933 38.0835 112.144 40.0852L138.324 48.5239C143.397 50.1591 148.861 47.5277 150.746 42.5418L160.472 16.8116C162.779 10.7082 170.218 8.41334 175.563 12.1567L198.093 27.9372C202.459 30.9952 208.455 30.0913 211.726 25.8824L228.604 4.16201Z'/%3E%3C/svg%3E");
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
  -webkit-mask-size: 100% 100%;
  mask-size: 100% 100%;
  pointer-events: none;
}

/* Une couleur de halo par étape — constat Critique de la revue de la tâche 11,
   re-vérifié par le contrôleur sur la source par CLIC RÉEL sur chaque pastille
   (un `dispatchEvent(new MouseEvent('click'))` ne déclenche RIEN sur la source :
   le premier contrôle, fait ainsi, concluait à tort à une couleur unique).
   `fill` du tracé 473×471 relevé étape par étape (canaux notés R·V·B pour ne pas
   déclencher le contrôle de couleurs brutes de check.py, qui inspecte aussi les
   commentaires — mineur connu, différé depuis la tâche 2) :
       1 « Réunion de lancement »      250·250·191  --c-yellow-pale
       2 « La magie en marche »        192·236·191  --c-mint
       3 « Feedback & Mise au point »  199·202·255  --c-lavender
       4 « Lancement et suivi »        246·194·244  --c-pink-light
   Ciblage par identifiant plutôt que par `nth-of-type` : les id existent déjà
   pour l'ARIA, et le rattachement ne dépend alors pas de l'ordre du DOM. */
#process-panel-1 { --process-halo: var(--c-yellow-pale); }
#process-panel-2 { --process-halo: var(--c-mint); }
#process-panel-3 { --process-halo: var(--c-lavender); }
#process-panel-4 { --process-halo: var(--c-pink-light); }

/* `object-fit: contain` relevé sur la source (règle A1#4) : les quatre PNG
   n'ont pas le même rapport (1024×1024 pour l'étape 1, 1080×1112 pour les
   trois autres) et sont tous posés dans la même boîte.
   `filter: brightness(1.35)` est relevé en style en ligne sur le conteneur
   d'image de la source (règle A1#1 : il n'apparaît sur aucun style calculé de
   l'<img>). Il est porté ici par l'image seule, et non par .process__visual,
   pour ne pas éclaircir aussi le halo — c'est bien ce que fait la source, où
   le halo est hors du conteneur filtré. */
.process__img {
  position: relative;
  width: 100%;
  height: 100%;
  object-fit: contain;
  filter: brightness(1.35);
}

@media (prefers-reduced-motion: reduce) {
  .process__tab { transition: none; }
  /* Le panneau prend sa hauteur d'un coup ; tabs.js retire la hauteur en ligne
     par son filet de sécurité, aucun `transitionend` ne pouvant survenir. */
  .process__panel { transition: none; }
  /* Le halo se pose directement sur son quart de tour, sans le parcourir. */
  .process__visual::before { transition: none; }
}

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

  .process__heading { font-size: var(--fs-52); }

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

  .process__card { height: 402px; }

  /* Relevé sur la source : les pastilles sont PLUS GROSSES en tablette qu'en
     desktop (42px contre 37px). Vérifié deux fois, ce n'est pas une erreur de
     lecture : hauteur de pastille 77,8 contre 73,3. */
  .process__tab {
    font-size: var(--fs-42);
    line-height: 37.8px;
    letter-spacing: -1.26px;
  }

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

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

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

  /* Le sticker repasse EN FLUX, centré, collé au-dessus du titre (mesuré :
     l'intro y fait 205,5 = 79,5 de sticker + 126 de titre, sans espace).
     Même bascule qu'en projects.css et benefits.css. Le centrage passe par
     des marges automatiques et non par un `transform`, qui porte déjà la
     rotation. */
  .process__intro {
    width: 100%;
    display: flex;
    flex-direction: column;
    align-items: center;
  }

  .process__sticker {
    position: static;
    /* Le sticker passe AVANT le titre : dans le markup il le suit, parce qu'à
       1440 et 1024 il est en absolu et que l'ordre du DOM y met le titre en
       premier (ordre de lecture). `order` remet l'ordre visuel de la source
       sans toucher à l'ordre de lecture. */
    order: -1;
    display: grid;
    width: max-content;
    margin-inline: auto;
    transform: rotate(-20deg);
  }

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

  .process__heading {
    max-width: none;
    font-size: var(--fs-42);
    letter-spacing: -1.6px;
  }

  /* La carte passe en colonne centrée et reprend une hauteur libre ; elle
     rogne l'illustration, volontairement plus large qu'elle (voir plus bas). */
  .process__card {
    align-items: center;
    justify-content: flex-start;
    height: auto;
    padding: 40px 20px;
    overflow: hidden;
  }

  .process__tabs { justify-content: center; }

  .process__tab {
    font-size: var(--fs-33);
    line-height: 29.7px;
    letter-spacing: -0.99px;
  }

  .process__panel {
    width: 100%;
    max-width: none;
    align-items: center;
    text-align: center;
  }

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

  /* L'illustration repasse dans le flux, sous le texte. Sa boîte est FIXE et
     plus large que la colonne (481 × 350,28 relevés à 390 ET à 360 : la
     source ne la fait pas varier avec la largeur de fenêtre) ; elle déborde
     donc symétriquement de la carte, qui la rogne. Ce débord est voulu : avec
     `object-fit: contain`, il donne à l'illustration carrée de l'étape 1 une
     largeur rendue de 350,3px, soit exactement la largeur de la carte.
     La marge de 65 s'ajoute au gap de 10 de .process__panel pour faire les
     75px relevés entre le bas du texte et le haut de l'illustration.

     ⚠ La hauteur est écrite en dur et non déduite d'`aspect-ratio` : en flux,
     .process__visual est un élément de flex dont le `min-height: auto` se
     calcule sur son contenu (l'image), ce qui l'emportait sur le rapport et
     donnait une boîte de 481 × 481 au lieu de 481 × 350,3 — soit 130,7px de
     trop sur la hauteur de section. En absolu (1440 / 1024) le problème ne se
     pose pas, `aspect-ratio` y suffit. */
  .process__visual {
    /* `relative` et non `static` : le halo est un ::before en absolu calé sur
       50%/50% de CETTE boîte. En `static`, il se recalait sur .process__card
       (seul ancêtre positionné) et venait se peindre par-dessus le texte. */
    position: relative;
    /* ⚠ `top` et `right` du palier desktop DOIVENT être neutralisés : sur un
       élément `relative` ils ne sont plus des ancrages mais des décalages.
       `right: 40px` poussait l'illustration de 40px vers la GAUCHE (centre à
       155 au lieu de 195). `top: 50%` restait sans effet, la hauteur du bloc
       conteneur étant en `auto`, mais on le remet à zéro par sûreté. */
    top: auto;
    right: auto;
    flex: 0 0 auto;
    align-self: center;
    width: 481px;
    height: 350.281px;
    aspect-ratio: auto;
    margin-top: 65px;
    transform: none;
  }

  /* Halo : 223,2px relevés à 390 (72% de la colonne de 310 de la source).
     Valeur en dur parce que la boîte qui la porte l'est aussi à ce palier. */
  .process__visual::before { width: 223.2px; }
}
