/* ============================================================
   87seconds — V2 RESPONSIVE · homepage
   Un seul DOM. Toutes les cotes desktop viennent de la maquette Figma
   « homepage-layout » (112:7139, 1440px) et sont exprimées en % pour
   rester fluides. Mobile : nœud 112:7487 (390px).
   ============================================================ */

/* ============================================================
   HERO — frame « hero-banner » 112:7143 (1440 × 1024)
   Le collage est en % de la scène, la colonne de texte occupe les
   720px centraux (frame 1582 : x350 → x1070), ce qui garantit que le
   texte ne recouvre jamais les visuels : ceux-ci s'arrêtent à x422 et
   reprennent à x985.
   ============================================================ */
/* Scène mobile : frame « HERO » 112:7492, 411 × 847. Elle commence SOUS LE HEADER.
   Le frame HERO est bien posé à y0, mais dans son parent « MAIN » (112:7491), lui-même
   à **y72** dans la page mobile 112:7487 — où le header (112:7682) occupe y10 → y62.
   Les 72px de `--header-h` à 390 reproduisent donc exactement ce décalage.
   (J'avais lu le y0 du HERO sans regarder son parent : le collage passait alors
   par-dessus le burger et le logo — corrigé.) */
/* Le texte démarre à 262px du haut de la scène (maquette : le groupe de visuels haut
   s'arrête à 251px, le titre commence à 262). Centrer verticalement le faisait remonter
   dans les visuels dès qu'on s'écartait de 390px de large. */
/* Hauteur de la scène : pilotée par le CONTENU, plus par un ratio figé.
   Elle valait `217vw` (les 847px de la maquette rapportés à 390), or notre typo fluide
   est plus petite que celle de la maquette : le bloc de texte finissait bien plus haut
   et la scène gardait sa hauteur, laissant un vide sous les deux visuels du bas — qui
   restaient collés en bas, au lieu de remonter au niveau du texte comme dans la
   maquette. D'où un hero trop long en mobile (jusqu'à 1098px à 600 de large).
   Le retrait bas est donc calé sur le VISUEL et non sur la fenêtre : `a4` est ancré à
   131px du bas et sa hauteur vaut 1,2455 × sa largeur, d'où
   `retrait = 131 + hauteur de a4 − 35`. Les 35 sont le chevauchement que `a4` a
   aujourd'hui avec le bas du bloc de texte à 390 — la largeur de maquette, validée :
   on le conserve tel quel et on l'applique à toutes les largeurs, au lieu de le
   laisser dériver (55px de vide à 600, 36px de recouvrement à 899).
   Ne pas viser le rapport brut de la maquette (`a4` 104px au-dessus du bas du texte) :
   notre bloc de texte est plus étroit que le sien, et le visuel venait alors recouvrir
   la fin de « ORCHESTRATION ». */
.hero { position: relative; overflow: hidden; display: flex; align-items: flex-start;
  --a4w: clamp(110px, calc(110px + 63 * (100vw - 390px) / 510), 173px);
  padding-block: calc(var(--header-h) + 262px) calc(96px + 1.2455 * var(--a4w)); }
/* Écart titre → bloc logo : 32 sur la maquette mobile, 50 sur la desktop */
/* Écart titre → bloc logo : 32 sur la maquette mobile, 50 sur la desktop.
   Largeur de la colonne de texte : elle grandit de 350 (maquette mobile) à 560 entre
   390 et 900px, pour que le titre tienne toujours sur ses 3 lignes malgré la typo fluide.
   Le `+ 2 × gutter` est indispensable : `max-width` porte sur la boîte de bordure,
   gouttières comprises — sans lui, il ne restait que 297px de texte utile à 888px de
   large et le titre partait sur 6 lignes. */
.hero-inner { position: relative; z-index: 2; width: 100%;
  max-width: calc(clamp(350px, calc(350px + 210 * (100vw - 390px) / 510), 560px) + 2 * var(--gutter));
  display: flex; flex-direction: column; align-items: center; gap: clamp(32px, calc(32px + 18 * (100vw - 390px) / 1050), 50px); }
.hero-title-group { display: flex; flex-direction: column; align-items: center; }

.h-title { font-family: var(--f-alb); font-weight: 300; font-size: var(--fs-h1); line-height: 1; text-transform: uppercase; text-align: center; color: var(--black); }
.h-title .xb { font-family: var(--f-unb); font-weight: 800; font-size: var(--fs-h1-xb); }

/* La pastille NOW mord sur « THE WORLD », comme dans les deux maquettes. La marge est
   négative et proportionnelle au corps du titre : la dernière ligne a un talon de
   descendantes vide sous ses lettres (aucune descendante dans « THE WORLD »), qu'il
   faut rattraper — un écart positif, même petit, décrochait visiblement la pastille. */
.badge-now { display: inline-flex; align-items: center; justify-content: center; background: #fff; border: 2px solid var(--black); border-radius: 6px; padding: 4px 14px; transform: rotate(-8.4deg); margin-top: calc(-.15 * var(--fs-h1)); }
.badge-now .clip { font-family: var(--f-unb); font-weight: 700; font-size: clamp(26px, calc(26px + 10 * (100vw - 390px) / 1050), 36px); line-height: 1.3; text-transform: uppercase; background-size: 400.25% 988.35%; background-position: 48.82% 21.39%; }

.hero-sign { display: flex; flex-direction: column; gap: 10px; align-items: center; }
.hero-sign img { width: clamp(101px, calc(101px + 50 * (100vw - 390px) / 1050), 151px); height: auto; }
/* `.h-baseline` est dans le socle (r-base.css) : la signature sert aussi au footer. */

/* Hors desktop, le collage démarre SOUS le header : la maquette mobile place tout le
   contenu dans un « MAIN » décalé de 72px, sous le menu. En desktop il occupe toute
   la scène (voir le bloc ≥900), la maquette y posant les visuels à y220 sous un
   header de 200. */
.hero-art { position: absolute; inset: var(--header-h) 0 0; z-index: 1; pointer-events: none; }
.hero-art figure { position: absolute; overflow: hidden; }
.hero-art img { width: 100%; height: 100%; object-fit: cover; }
/* Mobile — cotes exactes de la maquette 112:7492, en PIXELS et ancrées aux coins :
   groupe haut en haut à gauche, groupe bas en bas à droite.
   Surtout pas de pourcentages ici : la largeur du bloc de texte, elle, est fixe, donc
   des visuels en % s'en rapprochent ou s'en éloignent selon la largeur d'écran et
   finissent par le recouvrir. En px ils restent collés aux bords et la bande centrale
   ne fait que s'élargir — le texte est dégagé à toutes les largeurs.
   Les largeurs, elles, partent des cotes maquette à 390 et rejoignent progressivement
   celles de la composition desktop à 900 : la transition au point de rupture ne saute
   plus, et l'espace disponible aux largeurs intermédiaires est réellement occupé. */
.hero-art .a1 { left: -10px; top: 111px; width: clamp(112px, calc(112px + 33 * (100vw - 390px) / 510), 145px); aspect-ratio: 112/140; }
.hero-art .a2 { left: 51px;  top: 0;     width: clamp(119px, calc(119px + 35 * (100vw - 390px) / 510), 154px); aspect-ratio: 119/148; }
.hero-art .a3 { left: 129px; top: 93px;  width: clamp(85px,  calc(85px  + 26 * (100vw - 390px) / 510), 111px); aspect-ratio: 85/106; }
.hero-art .a4 { left: auto; right: -10px; top: auto; bottom: 131px; width: var(--a4w); aspect-ratio: 110/137; }
.hero-art .a5 { left: auto; right: 78px;  top: auto; bottom: 80px;  width: clamp(134px, calc(134px + 49 * (100vw - 390px) / 510), 183px); aspect-ratio: 134/120; }
@media (min-width: 900px) {
  /* En desktop le header se superpose au hero (maquette : visuels à partir de y220,
     sous le header) — la zone du collage reprend donc toute la scène. */
  /* ------------------------------------------------------------------
     La scène tient dans la FENÊTRE, quelle que soit sa hauteur.
     Hauteur = fenêtre moins un bandeau qui laisse voir le haut de la section
     suivante — le lecteur comprend qu'il y a du contenu dessous. Plancher :
     en dessous de 720px de fenêtre la scène garde la taille qu'elle a à 720,
     et la page défile normalement (limite fixée par le client).
     `svh` et non `vh` : sur mobile et sur les navigateurs à barre d'outils
     rétractable, `vh` vaut la hauteur BARRE RÉTRACTÉE — la scène dépasserait
     au chargement. Ligne `vh` conservée avant, comme repli.
     `container-type: size` ouvre les unités `cqh` aux enfants : tout ce qui
     occupe de la hauteur (titre, pastille, signature, visuels) se mesure
     désormais en pourcentage de la scène, et non plus en pixels fixes. */
  /* Mêmes jetons que les autres bandeaux (r-base.css), mais employés pour REMPLIR :
     la scène d'accueil occupe toute la fenêtre moins la bande laissée visible, là où
     les autres bandeaux se contentent de s'y plafonner. */
  .hero { --hero-peek: var(--banner-peek);
    --hero-h: var(--hero-fill);
    min-height: 0; height: var(--hero-h);
    align-items: center;
    padding-block: calc(var(--header-h) + 20px) min(var(--sec-pad), calc(.0977 * var(--hero-h))); }
  .hero-art { inset: 0; }
  .hero-art figure { right: auto; bottom: auto; }
  /* Colonne de texte = les 720px centraux de la maquette, soit 50 % de la scène.
     `+ 2 × gutter` obligatoire : `max-width` porte sur la boîte de bordure, gouttières
     comprises — sans lui il ne restait que 484px de texte utile à 1440 et le titre
     passait sur 4 lignes au lieu de 3.
     Le corps est en plus plafonné en vw (64/1440 = 4.44vw) : sans cela, entre 900 et
     1200px le titre grandissait plus vite que l'espace libre et mordait sur les photos. */
  /* Toutes les cotes verticales du bloc de texte sont plafonnées en `cqh`,
     c'est-à-dire en pourcentage de la hauteur de la scène — les valeurs sont
     celles de la maquette rapportées à ses 1024px de haut (64/1024 = 6,25 %,
     151/1024 = 14,75 %, etc.). Sur une fenêtre haute elles retrouvent donc
     exactement la maquette ; sur une fenêtre basse elles se resserrent
     ensemble, et le texte reste entier. */
  .hero-inner { max-width: calc(50% + 2 * var(--gutter));
    --h1-used: min(var(--fs-h1), 4.44vw, calc(.0625 * var(--hero-h)));
    gap: min(clamp(32px, calc(32px + 18 * (100vw - 390px) / 1050), 50px), calc(.0488 * var(--hero-h))); }
  .h-title { font-size: var(--h1-used); }
  .h-title .xb { font-size: min(var(--fs-h1-xb), 4.31vw, calc(.0605 * var(--hero-h))); }
  /* Le décalage de la pastille suit le corps RÉELLEMENT utilisé, pas le jeton :
     sinon elle se décroche du titre dès que la fenêtre raccourcit. */
  .badge-now { margin-top: calc(-.15 * var(--h1-used)); }
  .badge-now .clip { font-size: min(clamp(26px, calc(26px + 10 * (100vw - 390px) / 1050), 36px), calc(.0352 * var(--hero-h))); }
  .hero-sign { gap: min(10px, calc(.0098 * var(--hero-h))); }
  .hero-sign img { width: min(clamp(101px, calc(101px + 50 * (100vw - 390px) / 1050), 151px), calc(.1475 * var(--hero-h))); }
  .hero .h-baseline { font-size: min(var(--fs-baseline), calc(.0234 * var(--hero-h))); }
  /* Coordonnées desktop — frame « Asset » 112:7144, converties en % de 1440 × 1024.
     L'ordre des visuels suit celui de la maquette (STACK 1/2/6/5/4). */
  /* Largeur de maquette (en % de la scène), PLAFONNÉE par la place qui reste
     réellement sous le visuel : posé à `top` = t %, de rapport r = largeur/hauteur,
     il ne peut pas dépasser (1 − t) × hauteur × r sans sortir du cadre. Les plafonds
     ci-dessous gardent 4 % de marge sur cette limite.
     Conséquence : tant que la composition de la maquette tient dans la fenêtre, elle
     est INTACTE — y compris sur écran large, où les visuels grandissent comme avant.
     Le plafond ne mord que lorsque la fenêtre est trop basse pour eux. Sans lui, un
     1920 × 900 faisait sortir STACK 1 de 13px sous le cadre. */
  .hero-art .a1 { left: 2.64%;  top: 55.27%; width: min(16.11%, calc(.3435 * var(--hero-h))); aspect-ratio: 232/290; }  /* STACK 1 */
  .hero-art .a2 { left: 8.47%;  top: 21.78%; width: min(17.15%, calc(.6003 * var(--hero-h))); aspect-ratio: 247/309; }  /* STACK 2 */
  .hero-art .a3 { left: 17.01%; top: 44.53%; width: min(12.29%, calc(.4265 * var(--hero-h))); aspect-ratio: 177/221; }  /* STACK 6 */
  .hero-art .a4 { left: 68.40%; top: 21.48%; width: min(19.17%, calc(.6013 * var(--hero-h))); aspect-ratio: 276/346; }  /* STACK 5 */
  .hero-art .a5 { left: 76.94%; top: 51.95%; width: min(20.35%, calc(.5120 * var(--hero-h))); aspect-ratio: 293/264; }  /* STACK 4 */
}

/* ============================================================
   WHAT WE DO — 3 étapes
   Desktop : la flèche traverse la section (x75 → x1368 dans la maquette),
   les 3 puces sont sur son axe à 16,08 / 50,73 / 84,62 % et chaque colonne
   (pastille + sous-texte) est centrée sur cet axe.
   ============================================================ */
/* `.blue` est dans le socle (r-base.css) : plusieurs gabarits ont des sections bleues. */

.wwd-catch { font-family: var(--f-alb); font-size: var(--fs-catch); line-height: 1.2; letter-spacing: -0.01em; text-transform: uppercase; text-align: center; color: #fff; }
.wwd-catch .b { font-family: var(--f-unb); font-weight: 700; font-size: var(--fs-catch-b); }

/* Rythme de section, interpolé entre les deux ancres de maquette (390 / 1440) :
   pastille WHAT WE DO → accroche 32 / 80, bas des blocs → bas de section 100 / 180. */
.s-wwd { padding-bottom: clamp(100px, calc(100px + 80 * (100vw - 390px) / 1050), 180px); }
.s-wwd .cap-astride { margin-bottom: clamp(32px, calc(32px + 48 * (100vw - 390px) / 1050), 80px); }

/* Hors desktop la maquette change de fond : la traînée lumineuse disparaît au profit
   d'un dégradé seul. C'est `fond-bleu2.webp` retourné horizontalement — vérifié pixel
   à pixel contre l'export Figma (écart moyen 0,55/255, soit du bruit JPEG). */
.s-wwd .bg-mob { display: none; }

.wwd-steps {
  /* Pastille : texte (corps × 1,5) + padding 11 × 2 + bordure 2 × 2. Recalculée et
     non figée, le corps étant fluide (26 → 32px). */
  --wwd-title-h: calc(var(--fs-step) * 1.5 + 26px);
  --wwd-dot: 19px;
  --wwd-rail-h: 22px;        /* épaisseur de arrow2.svg, sa ligne à mi-hauteur */
  --wwd-gap-dot: 32px;       /* pastille → puce (maquette, desktop et mobile) */
  --wwd-gap-sub: 40px;       /* puce → sous-texte (maquette) */
  /* Longueur de arrow2.svg à 22px d'épaisseur : 1294,53 × 22 / 22,0919. */
  --wwd-arrow-len: 1289px;
  position: relative;
  display: flex; flex-direction: column; gap: 50px;
  margin-top: clamp(70px, calc(70px + 80 * (100vw - 390px) / 1050), 150px);
}
/* La flèche est rendue à sa LONGUEUR NATURELLE et sa queue est rognée, jamais
   étirée : `arrow2.svg` est en `preserveAspectRatio: none`, l'ajuster à la longueur
   du rail écrasait la pointe (mesuré : 63,6 % de sa largeur à 900px, 83,8 % à 1200).
   La queue étant une ligne uniforme, la rogner ne se voit pas. */
.wwd-rail { position: absolute; overflow: hidden; }
/* `max-width: none` est indispensable : le reset (`img { max-width: 100% }`) rabotait
   la flèche à la largeur du rail — c'est ce qui écrasait la pointe. */
.wwd-arrow { display: block; position: absolute; max-width: none; width: max(var(--wwd-arrow-len), 100%); height: var(--wwd-rail-h); }

/* Mobile : flèche verticale le long de la colonne des puces, pointe vers le bas.
   Elle court sur toute la hauteur du bloc (maquette : y0 → y645). */
.wwd-rail { left: calc(var(--wwd-dot) / 2 - var(--wwd-rail-h) / 2); top: 0; bottom: 0; width: var(--wwd-rail-h); }
.wwd-arrow { left: 0; top: calc(100% - var(--wwd-arrow-len)); transform-origin: 0 0; transform: translateX(var(--wwd-rail-h)) rotate(90deg); }

.wwd-row { position: relative; display: flex; gap: 20px; align-items: flex-start; }
/* Cercle plat, sans halo : la maquette ne pose aucun effet sur les puces. */
.wwd-row .dot { width: var(--wwd-dot); height: var(--wwd-dot); flex: none; border-radius: 50%; background: #fff; margin-top: calc((var(--wwd-title-h) - var(--wwd-dot)) / 2); }
/* Hors desktop la maquette cale la pastille et son sous-texte à gauche, sur l'axe
   de la colonne de texte ; le centrage n'apparaît qu'en desktop. */
.wwd-col { display: flex; flex-direction: column; gap: 24px; align-items: flex-start; }

.wwd-step { display: inline-flex; background: #fff; border: 2px solid var(--black); border-radius: 13px; padding: 11px 45px; width: max-content; max-width: 100%; }
.wwd-step .clip { font-family: var(--f-unb); font-weight: 800; font-size: var(--fs-step); line-height: 1.5; letter-spacing: -0.01em; text-transform: uppercase; white-space: nowrap; }
/* Aligné à gauche hors desktop, centré sous sa pastille en desktop (maquettes). */
.wwd-sub { font-family: var(--f-alb); font-size: var(--fs-body); line-height: 1.2; letter-spacing: -0.01em; text-transform: uppercase; color: #fff; text-align: left; }

/* Hors desktop, le fond de la maquette est le dégradé seul, retourné. */
@media (max-width: 899px) {
  .s-wwd .bg-desk { display: none; }
  .s-wwd .bg-mob { display: block; transform: scaleX(-1); }
  /* La maquette mobile serre l'accroche à un interligne de 1 (1,2 en desktop) :
     à 1,2 elle occupait 156px au lieu de 117. */
  .wwd-catch { line-height: 1; }
}

@media (min-width: 900px) {
  /* Maquette desktop (nœud 123:20341, colonne haute de 248) : pastille en tête,
     puce 32px sous elle, sous-texte 40px sous la puce. La pastille est AU-DESSUS
     de la flèche, le sous-texte en dessous. */
  .wwd-steps {
    display: block;
    /* Tous les enfants sont en absolu : la hauteur ne peut venir que d'ici.
       Sous-texte = 3 lignes de corps courant à 1,2 d'interligne. */
    height: calc(var(--wwd-title-h) + var(--wwd-gap-dot) + var(--wwd-dot)
                 + var(--wwd-gap-sub) + var(--fs-body) * 3.6);
  }
  /* La flèche déborde la colonne de texte : x75 → x1368 sur 1440.
     Sa ligne est à mi-épaisseur, donc centrée sur la puce. */
  .wwd-rail {
    left: -3.57%; right: -3.57%; width: auto;
    top: calc(var(--wwd-title-h) + var(--wwd-gap-dot) + (var(--wwd-dot) - var(--wwd-rail-h)) / 2);
    bottom: auto; height: var(--wwd-rail-h);
  }
  .wwd-arrow { left: auto; right: 0; top: 0; transform: none; }
  /* Colonnes centrées sur l'axe des puces */
  /* Axes des puces : x231,5 / 730,5 / 1218,5 dans la maquette, ramenés en % de la
     colonne de contenu (118 → 1322, soit 1204 de large). */
  .wwd-row { position: absolute; top: 0; display: block; width: max-content; max-width: 32%; transform: translateX(-50%); }
  /* nth-child et non nth-of-type : .wwd-rail est aussi un <div> et fausserait le compte */
  .wwd-row:nth-child(2) { left: 9.43%; }
  .wwd-row:nth-child(3) { left: 50.87%; }
  .wwd-row:nth-child(4) { left: 91.40%; }
  .wwd-row .dot { position: absolute; left: 50%; top: calc(var(--wwd-title-h) + var(--wwd-gap-dot)); margin: 0; transform: translateX(-50%); }
  /* L'écart pastille ↔ sous-texte enjambe la puce : 32 + 19 + 40 = 91 dans la maquette */
  .wwd-col { gap: calc(var(--wwd-gap-dot) + var(--wwd-dot) + var(--wwd-gap-sub)); align-items: center; }
  .wwd-sub { text-align: center; }
}

/* ============================================================
   « What we do » ramené à 75 % (demande client : voir la section
   dans son ensemble au premier coup d'œil).

   Les corps de texte sont redéclarés EN LOCAL sur la section plutôt
   qu'à la source : `--fs-seclabel`, `--fs-catch`, `--fs-catch-b` et
   `--fs-body` servent à d'autres blocs du site, que personne n'a
   demandé de réduire. Les propriétés personnalisées héritant, il
   suffit de les réécrire sur `.s-wwd` pour que tout son sous-arbre
   suive — y compris `--wwd-title-h`, qui se calcule sur `--fs-step`.
   ============================================================ */
.s-wwd {
  --sec-pad:     clamp(60px, calc(60px + 15 * (100vw - 390px) / 1050), 75px);
  --fs-seclabel: clamp(18px, calc(18px +  9 * (100vw - 390px) / 1050), 27px);
  --fs-catch:    clamp(20px, calc(20px +  6 * (100vw - 390px) / 1050), 26px);
  --fs-catch-b:  clamp(17px, calc(17px +  7 * (100vw - 390px) / 1050), 24px);
  --fs-step:     clamp(20px, calc(20px +  4 * (100vw - 390px) / 1050), 24px);
  --fs-body:     clamp(15px, calc(15px +  3 * (100vw - 390px) / 1050), 18px);
  padding-bottom: clamp(75px, calc(75px + 60 * (100vw - 390px) / 1050), 135px);
}
/* Le retrait de la pastille est réduit lui aussi, sans quoi elle resterait à
   84 % quand tout le reste est à 75 % : c'est du remplissage en pixels, que la
   baisse du corps de texte ne touche pas. `.cap` sert à toutes les sections du
   site — d'où la portée `.s-wwd`. */
.s-wwd .cap { padding: 8px clamp(15px, 3vw, 25px); }
/* Le débord de la pastille au-dessus du bord de section suit sa hauteur : la
   pastille passant de 70 à 53px, son débord passe de 32 à 24 — sinon elle
   chevaucherait proportionnellement moins la bordure qu'avant. */
.s-wwd .cap-astride { margin-top: calc(-1 * var(--sec-pad) - 24px);
                      margin-bottom: clamp(24px, calc(24px + 36 * (100vw - 390px) / 1050), 60px); }
.s-wwd .wwd-steps {
  /* Les deux dernières cotes verticales du bloc, restées en dur ailleurs. */
  margin-top: clamp(53px, calc(53px + 60 * (100vw - 390px) / 1050), 113px);
  gap: 38px;
  /* `+ 20px` au lieu de `+ 26px` : cette constante est la hauteur que le
     bouton ajoute à son texte (2 × retrait + 2 × trait). Le retrait passant
     de 11 à 8px, elle maigrit d'autant — sans quoi la puce, centrée sur
     `--wwd-title-h`, se décalerait de 3px par rapport au bouton. */
  --wwd-title-h: calc(var(--fs-step) * 1.5 + 20px);
  --wwd-dot:     14px;
  --wwd-rail-h:  16px;
  --wwd-gap-dot: 24px;
  --wwd-gap-sub: 30px;
}
.s-wwd .wwd-step { padding: 8px 34px; border-radius: 10px; }
/* Sous 900px seulement : au-delà, l'écart de la colonne est CALCULÉ sur les
   jetons ci-dessus (puce comprise) et une valeur fixe le casserait. */
@media (max-width: 899px) {
  .s-wwd .wwd-col { gap: 18px; }
  .s-wwd .wwd-row { gap: 15px; }
}

/* ============================================================
   HOW WE DO IT — frame « how » 112:7183
   Texte à gauche (576px), cercle à droite (596 × 555), note en bas de
   section sur toute la largeur (x118, y780 dans la maquette).
   ============================================================ */
.how { display: flex; flex-direction: column; align-items: center; gap: clamp(32px, 5vw, 48px); }
.how-text { font-family: var(--f-alb); font-size: var(--fs-catch); line-height: 1.2; letter-spacing: -0.01em; text-transform: uppercase; text-align: center; color: var(--black); }
.how-text .b { font-family: var(--f-unb); font-weight: 700; font-size: var(--fs-catch-b); }
.how-col { display: flex; flex-direction: column; gap: clamp(20px, 3vw, 28px); align-items: center; width: 100%; }

/* Le badge est incliné ; l'inclinaison est portée par .awarded et l'animation
   d'apparition par .awarded-rv — sinon `.rv.in { transform:none }` écrasait la rotation
   et le badge retombait à plat. */
.awarded-rv { display: flex; justify-content: center; }
.awarded { display: inline-flex; align-items: center; justify-content: center; gap: 6px 11px; background: #fff; border: 2px solid var(--black); border-radius: 6px; padding: 8px clamp(16px, 3vw, 24px); transform: rotate(-3.61deg); max-width: 100%; }
/* V134 — « RÉCOMPENSÉ PAR [Meta] EN 2026 » fait ~35 % de plus que « AWARDED BY
   [Meta] 2026 ». Les libellés sont en `white-space: nowrap`, donc irréductibles :
   en `flex-wrap: nowrap` les items se COMPRESSENT et le texte sort du cadre blanc
   (25 px à 1440, 26 px à 390, 32 px à 900) au lieu de passer à la ligne.
   Le retour à la ligne est réservé à la version FR : en anglais la compression
   reste de 9 à 15 px et le badge tient sur une ligne — la règle ne doit pas
   changer un rendu que le client a validé. */
html[lang="fr"] .awarded { flex-wrap: wrap; }
.awarded .clip { font-family: var(--f-unb); font-weight: 700; font-size: clamp(18px, calc(18px + 6 * (100vw - 390px) / 1050), 24px); line-height: 1.3; text-transform: uppercase; white-space: nowrap; background-size: 268.93% 2233.5%; background-position: 32.33% 66.24%; }
.awarded img { height: clamp(17px, 2.5vw, 23px); width: auto; object-fit: contain; }
.how-note { font-family: var(--f-alb); font-size: var(--fs-ui); letter-spacing: -0.01em; color: var(--black); width: 100%; margin-top: clamp(24px, 4vw, 60px); }

/* Cercle — cadre Figma 596 × 555. Le recadrage vient du nœud `circle 1` (112:7193) :
   l'image y est rendue à 233,11 % × 140,57 % du cadre, calée à (−66,55 % ; −18,94 %).
   C'est un zoom nettement plus fort qu'un `object-fit:cover` (qui donnerait 165 % × 100 %) :
   avec `cover` le motif était trop petit et les libellés paraissaient très éloignés.
   Le ratio du cadre étant fixe, ces pourcentages ne déforment pas l'image.
   Le recadrage est porté par .disc-crop et NON par .how-circle : sinon les libellés
   débordant du cadre sont rognés — c'est ce qui coupait « E-COM » à droite. */
.how-circle { position: relative; width: min(100%, 596px); aspect-ratio: 596/555; }
.disc-crop { position: absolute; inset: 0; overflow: hidden; }
.disc-crop img.disc { position: absolute; width: 233.11%; height: 140.57%; left: -66.55%; top: -18.94%; max-width: none; }

/* --- Visuel animé (V99) ---------------------------------------------------
   Le fichier animé n'est PAS cadré comme `circle 1` : en plus du motif, il porte
   déjà les libellés de canaux et les deux points. Le zoom ci-dessus ne s'applique
   donc pas — le cadrage est recalculé pour que la COMPOSITION ENTIÈRE tienne dans
   le cadre 596 × 555 (contenu utile du fichier : 85,46 % × 75,28 %, calé à
   6,76 % ; 13,24 % ; on ajuste sur la largeur, il reste 30px de mou en hauteur).
   Les .chan / .pip restent dans le DOM — lecture d'écran et indexation — mais
   sortent de la vue, sinon les libellés s'affichent DEUX fois. */
/* Le motif animé est calé sur la POSE de `circle 1` — image 292 du fichier, dont le
   motif mesure 589 × 615 là où le PNG fixe en mesure 593 × 619 : c'est la même image
   de synthèse. Le motif retombe donc à ±0,22px de sa position d'origine, à 0,45px
   près en taille. À cette échelle les libellés du fichier SORTENT du cadre 596 × 555
   (43px à gauche, 34 à droite, 9 en haut, 29 en bas). On n'ouvre PAS le rognage pour
   autant : le carré du fichier est bien plus large que son contenu, et laisser sortir
   la boîte de l'image faisait scroller la page de 35px à 390. .disc-crop est donc
   agrandie jusqu'à l'emprise EXACTE du contenu, mesurée sur les 480 images, et garde
   son `overflow:hidden` — ce qui dépasse est du vide, jamais du dessin. */
/* Filet : à 390 le contenu du fichier fait 395px pour une fenêtre de 390 — la marge
   à droite tombe à 0,1px. `clip` (et non `hidden`, qui créerait un conteneur de
   défilement) garantit qu'aucun arrondi ne pourra faire scroller la page en largeur.
   La section occupe toute la largeur : ce qui est rogné est déjà hors écran. */
.s-how { overflow-x: clip; }
.how-circle.has-anim .disc-crop { inset: -1.63% -5.70% -5.24% -7.26%; }
.how-circle.has-anim .disc-crop img.disc { width: 116.76%; height: 132.52%; left: -7.78%; top: -17.55%; }
.how-circle.has-anim .pip { display: none; }
.how-circle.has-anim .chan { width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }
.chan { position: absolute; font-family: var(--f-alb); font-size: clamp(13px, calc(13px + 11 * (100vw - 390px) / 1050), 24px); line-height: 1.2; letter-spacing: -0.01em; text-transform: uppercase; color: var(--black); white-space: nowrap; }
/* % du frame 596 × 555 */
.how-circle .c-eretail { left: 40.0%; top: 2.3%;  }
.how-circle .c-tvc     { left: 7.9%;  top: 16.0%; }
.how-circle .c-pos     { left: 0;     top: 55.7%; }
.how-circle .c-social  { left: 13.6%; top: 86.5%; }
.how-circle .c-ooh     { left: 51.8%; top: 94.8%; }
.how-circle .c-ecom    { left: 85.7%; top: 64.0%; }
.how-circle .c-website { left: 77.8%; top: 18.4%; }
/* `aspect-ratio` obligatoire : ces SVG n'ont pas de dimensions intrinsèques,
   sans quoi le navigateur leur applique la hauteur par défaut de 150px. */
.how-circle .pip { position: absolute; width: 2.35%; aspect-ratio: 1; height: auto; }
.how-circle .pip1 { left: 74.2%; top: 23.6%; }
.how-circle .pip2 { left: 19.3%; top: 21.3%; }

@media (min-width: 900px) {
  /* Maquette : colonne texte 576px, cercle 596px, gouttière 32px sur 1204 */
  .how { display: grid; grid-template-columns: 576fr 596fr; column-gap: 32px; align-items: center; }
  .how-col { align-items: center; }
  .how-note { grid-column: 1 / -1; }
}

/* ============================================================
   GLOBAL PRESENCE — auto-layout Figma 112:7209
   ============================================================ */
.gp-catch { font-family: var(--f-alb); font-size: var(--fs-catch); line-height: 1.2; letter-spacing: -0.01em; text-transform: uppercase; text-align: center; color: #fff; }
.gp-catch .b { display: block; font-family: var(--f-unb); font-weight: 700; font-size: var(--fs-catch-b); }

/* En colonne, l'écart doit tenir compte des DÉCORS, qui débordent largement des blocs
   (anneau orbital, sphère pointillée, jauge…) : à 70-80px ils se chevauchaient. */
.gp-stats { display: flex; flex-direction: column; align-items: center; gap: clamp(140px, 26vw, 175px); margin-top: var(--gap-lg); }
.gp-stat { position: relative; display: flex; flex-direction: column; align-items: center; gap: 12px; }
/* Pastille et libellé AU-DESSUS des illustrations : sans cela le décor (la pile de
   cartes blanches du bloc « +1 000 », notamment) recouvre le texte et le libellé
   semble avoir disparu. */
.gp-stat-box, .stat-lab { position: relative; z-index: 1; }
/* Hauteur de la boîte = boîte ENGLOBANTE de la pastille tournée à -5°. Une transform
   n'affectant pas la mise en page, sans hauteur explicite la pastille déborde et
   l'écart pastille/libellé de la maquette n'est pas respecté.
   englobante = hauteur pastille + largeur pastille × sin(5°), le second terme exprimé
   en multiple de --fs-statnum pour rester fluide (Figma à 48px : 21,6 / 13,9 / 21,3 / 16,5). */
.gp-stat-box { position: relative; width: 100%; display: flex; align-items: center; justify-content: center;
  height: calc(1.2 * var(--fs-statnum) + 16px + var(--extra, .44) * var(--fs-statnum)); }
.gp-stat--1 { --extra: .45; }
.gp-stat--2 { --extra: .29; }
.gp-stat--3 { --extra: .44; }
.gp-stat--4 { --extra: .34; }
.stat-pill { position: relative; display: inline-flex; align-items: center; justify-content: center; background: #fff; border: 1px solid var(--black); border-radius: 8px; padding: 8px clamp(18px, 3vw, 24px); transform: rotate(-5deg); }
.stat-num { font-family: var(--f-unb); font-weight: 800; font-size: var(--fs-statnum); line-height: 1.2; letter-spacing: -0.01em; text-transform: uppercase; text-align: center; white-space: nowrap; }
.stat-lab { font-family: var(--f-unb); font-weight: 800; font-size: var(--fs-statlab); line-height: 1.2; letter-spacing: -0.01em; text-transform: uppercase; text-align: center; white-space: nowrap; }
.stat-lab .r { font-weight: 400; display: block; }
/* Décors des stats. L'image est positionnée en ABSOLU dans son cadre, jamais par des
   marges : une marge en % se calcule sur la LARGEUR du parent, y compris `margin-top`.
   `margin-top:-69.17%` décalait donc de −201px au lieu de −114px et tronquait l'anneau
   orbital du bloc « 160 ». `top:-69.17%`, lui, se calcule bien sur la hauteur. */
/* Le cadre ne rogne QUE là où la V1 posait un `.crop`, c'est-à-dire là où l'image est
   volontairement agrandie et décalée (blocs « +1 000 » et « 160 »). Ailleurs l'image
   remplit exactement son cadre et le rognage n'a rien à couper — sauf le halo du
   `drop-shadow`, qu'il équarrissait : l'anneau de points de « +1 300 », tangent aux
   bords de son fichier, s'en trouvait tranché sur les côtés. */
.gp-deco { position: absolute; pointer-events: none; }
.gp-deco--crop { overflow: hidden; }
.gp-deco img { position: absolute; left: 0; top: 0; width: 100%; height: 100%; object-fit: cover; max-width: none; }

/* La rangée ne passe qu'à partir de 1270 (et non 900, la bascule desktop générale).
   Les 4 blocs de la maquette totalisent 865px de largeur incompressible (min-width) et
   la rangée est CENTRÉE : il lui faut donc 865 + 3 × --gap-md pour tenir. En dessous
   elle débordait des DEUX côtés — 59px à 900, 17px à 1000, encore 7px à 1024 (un iPad
   en paysage) — et l'`overflow-x:hidden` du body rognait « +1 000 EXPERTS » à gauche et
   « 24/7 » à droite.
   Le seuil a d'abord été fixé à 1100 (V23), calculé sur les seuls BLOCS. Or leurs
   DÉCORS débordent largement : la jauge du bloc « 24/7 » s'étend 92px à droite de son
   bloc et sortait donc de l'écran entre 1100 et 1260 (60px à 1120, 19px à 1216).
   Le seuil est porté à 1270, largeur mesurée à partir de laquelle décors compris tout
   tient. Même raisonnement que le nuage de logos, qui n'apparaît qu'à 1200 : sous le
   seuil, on garde la disposition en colonne, qui est juste. (V34.) */
@media (min-width: 1270px) {
  /* Rangée, gap 80, items-start ; largeurs des blocs reprises de la maquette
     (en min-width pour qu'un libellé FR plus long puisse élargir son bloc). */
  .gp-stats { flex-direction: row; align-items: flex-start; justify-content: center; gap: var(--gap-md); margin-top: var(--gap-lg); }
  .gp-stat--1 { min-width: 253.5px; gap: 6px; }
  .gp-stat--2 { min-width: 165.8px; }
  .gp-stat--3 { min-width: 249.5px; }
  .gp-stat--4 { min-width: 195px; }
}

/* ============================================================
   OUR WORK — frame « work » 112:7232
   Colonnes 590,5 / 282,75 / 282,75 · gouttières 24 · rangées 283,25
   ============================================================ */
.cases { display: flex; flex-direction: column; gap: 50px; margin-top: var(--gap-md); }
.case { display: grid; gap: 24px; grid-template-columns: minmax(0, 1fr); }
/* Cadrage des visuels : `object-fit:cover` + `object-position` par image.
   NE PAS revenir à un recadrage en pourcentages (image surdimensionnée et décalée) :
   ces pourcentages sont calculés pour UN ratio de cadre donné. Le cadre passant de
   carré (590×590 en desktop) à large (602×250 en intermédiaire) puis à 350×250 en
   mobile, les mêmes valeurs donnaient une image de ratio 4,3 au lieu de 1,78 —
   d'où les visuels étirés en responsive. `cover` conserve le ratio à toute largeur ;
   `object-position` reproduit le cadrage de la maquette. */
.case-media, .case-shot { position: relative; border-radius: 16px; overflow: hidden; }
/* V138 — l'ombre était la valeur PAR DÉFAUT de Figma (`0 4 4 · noir 25 %`), recopiée
   telle quelle. À 4 px de flou pour 4 px de décalage, elle ne se lit pas comme une
   élévation mais comme un SECOND RECTANGLE décalé : une bande grise à arête franche
   sous le visuel et un filet vertical le long du bord droit. Le flou est le seul
   chiffre faux — porté à 24 px (décalage 6, opacité 22 %, soit la même charge
   d'encre), l'ombre redevient un dégradé. Comparatif : `_outils-qa/banc-ombre-case.html`. */
.case-media { box-shadow: 0 4px 4px rgba(0,0,0,.25); aspect-ratio: 350/250; }
.case-shot { aspect-ratio: 283/284; }
.case-media img, .case-shot img { width: 100%; height: 100%; object-fit: cover; }
.case-logo { background: var(--black); border-radius: 16px; display: flex; align-items: center; justify-content: center; padding: 23px 25px; aspect-ratio: 350/190; }
.case-logo img { width: min(232px, 82%); height: auto; object-fit: contain; }
/* Mobile : la maquette n'affiche PAS le 3e visuel (grande photo + logo + texte) */
.case-shot { display: none; }
.case-txt { border: 2px solid var(--black); border-radius: 16px; padding: 24px; display: flex; flex-direction: column; justify-content: center; gap: clamp(16px, 2vw, 24px); }
.case-kpi { font-family: var(--f-unb); font-weight: 700; font-size: var(--fs-kpi); line-height: 1.09; letter-spacing: -0.01em; text-transform: uppercase; color: var(--black); }
.case-desc { font-family: var(--f-alb); font-size: var(--fs-desc); line-height: 1.2; letter-spacing: -0.01em; color: var(--black); }

/* Palier intermédiaire (600 → 899) : la grande photo en pleine largeur, puis les
   3 blocs de la colonne en dessous — logo et 2e visuel côte à côte, carte texte dessous. */
@media (min-width: 600px) {
  .case { grid-template-columns: minmax(0,1fr) minmax(0,1fr); }
  .case-media { grid-column: 1 / -1; aspect-ratio: 1204/500; }
  .case-shot  { display: block; aspect-ratio: 1/1; }
  .case-logo  { aspect-ratio: 1/1; }
  .case-txt   { grid-column: 1 / -1; }
}

@media (min-width: 900px) {
  /* Composition maquette. Deux pièges de grille évités ici :
     — `minmax(0, …)` sur les pistes : sans lui leur minimum automatique (min-content des
       items) gonflait les colonnes du cas miroir à 384/384/522 au lieu de 283/283/590,5 ;
     — `align-self:start` + tuiles carrées : la hauteur découle de la LARGEUR de colonne,
       jamais de la rangée. Sans cela on crée une boucle (hauteur ← rangée ← ratio ←
       hauteur) qui envoyait la grande image à 824px. */
  .case { grid-template-columns: minmax(0,590.5fr) minmax(0,282.75fr) minmax(0,282.75fr); grid-template-rows: auto auto; }
  .case-logo, .case-shot { aspect-ratio: 1/1; align-self: start; }
  /* La grande image enjambe les DEUX rangées et doit les remplir, sinon le bento est
     décalé : son bas s'arrêtait à la hauteur de sa colonne (ratio 1/1) pendant que la
     colonne de droite descendait plus bas (tuile carrée + carte texte).
     Elle n'a donc plus d'`aspect-ratio` — c'est la rangée qui commande — et son image
     passe en ABSOLU : une image en flux ne peut pas remplir un item étiré (la rangée
     dépendrait du contenu et le contenu de la rangée), le navigateur retombant alors
     sur la hauteur intrinsèque. En absolu, elle ne participe plus au calcul. */
  .case-media { grid-column: 1 / 2; grid-row: 1 / 3; aspect-ratio: auto; align-self: stretch; }
  .case-media img { position: absolute; inset: 0; }
  .case-logo  { grid-column: 2 / 3; grid-row: 1 / 2; }
  .case-shot  { grid-column: 3 / 4; grid-row: 1 / 2; }
  .case-txt   { grid-column: 2 / 4; grid-row: 2 / 3; align-self: stretch; overflow: hidden; }
  /* Cas 2 : composition en miroir — il faut AUSSI inverser le gabarit de colonnes,
     sinon la grande image atterrit dans une colonne étroite de 283. */
  .case--mirror { grid-template-columns: minmax(0,282.75fr) minmax(0,282.75fr) minmax(0,590.5fr); }
  .case--mirror .case-media { grid-column: 3 / 4; }
  .case--mirror .case-logo  { grid-column: 1 / 2; }
  .case--mirror .case-shot  { grid-column: 2 / 3; }
  .case--mirror .case-txt   { grid-column: 1 / 3; }
}

/* ============================================================
   BRANDS WHO TRUST US — champ de logos en dérive radiale
   ------------------------------------------------------------
   L'animation est pilotée par `assets/js/brands-field.js`, pas par une `@keyframes`.
   Raison : **une animation CSS rejoue toujours au MÊME endroit.** Le client demande
   qu'un logo réapparaisse à un emplacement différent à chaque cycle, et qu'aucun
   logo n'approche un autre à moins de 20px — deux contraintes qui se décident à
   l'exécution, en fonction de la position courante des 25 autres.

   Ce que porte cette feuille : la TAILLE de chaque logo, sa proportion, et un
   emplacement de repli. Le reste — position, trajectoire, durée, opacité — est
   dans le bloc `CFG` du module, à un seul endroit.
   ============================================================ */
.brands { background: var(--black); }
.brands-cloud { position: relative; width: 100%; aspect-ratio: 353/760; margin-inline: auto;
  max-width: 400px; padding-inline: var(--gutter); overflow: hidden; }

/* Sans JavaScript : chaque logo reste à son emplacement de repli, à opacité de
   croisière. La section est alors figée mais parfaitement lisible. */
.brands-cloud img { position: absolute; height: auto; object-fit: contain;
  left: var(--x); top: var(--y); width: var(--w); aspect-ratio: var(--ar);
  opacity: var(--op, .4); }
/* Avec JavaScript : le module pose position ET opacité par `transform`, depuis le
   coin haut-gauche de la bande. `left`/`top` doivent donc repartir de zéro, sinon
   les deux systèmes de coordonnées s'additionnent. */
.brands-cloud.js-champ img { left: 0; top: 0; opacity: 0; will-change: transform, opacity; }

/* 60 % et non 94 % en mobile : à pleine largeur, le bloc barrait la bande de bord à
   bord et aucun logo ne pouvait passer sur les côtés — ils se rangeaient tous au-dessus
   et en dessous. Le libellé passe sur trois lignes, ce qui monte un peu la hauteur du
   bloc, mais dégage deux couloirs latéraux et rend l'anneau possible. */
.brands-center { position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); display: flex; flex-direction: column; align-items: center; width: 60%; z-index: 2; }
.big-97 { font-family: var(--f-unb); font-weight: 800; font-size: var(--fs-97); line-height: 1.2; letter-spacing: -0.01em; text-transform: uppercase; text-align: center; background-size: cover; background-position: 30% 25%; white-space: nowrap; }
.big-97-cap { font-family: var(--f-alb); font-weight: 300; font-size: var(--fs-97-cap); line-height: 1.2; text-transform: uppercase; text-align: center; color: #fff; }

/* Proportion de chaque fichier — indispensable, les SVG n'ont pas toujours de
   dimensions intrinsèques et se rendraient à la hauteur par défaut de 150px.
   Le module lit aussi la taille rendue ici pour calculer les gardes de 20px. */
.brands-cloud .audi { --ar: 1.6142; }
.brands-cloud .boss { --ar: 3.8344; }
.brands-cloud .carrefour { --ar: 1.1524; }
.brands-cloud .cartier { --ar: 3.6076; }
.brands-cloud .celine { --ar: 4.7985; }
.brands-cloud .chanel { --ar: 6.351; }
.brands-cloud .chloe { --ar: 3.2159; }
.brands-cloud .clarins { --ar: 8.7746; }
.brands-cloud .coty { --ar: 2.7333; }
.brands-cloud .dior { --ar: 3.5542; }
.brands-cloud .estee-lauder { --ar: 7.9365; }
.brands-cloud .givenchy { --ar: 11.5741; }
.brands-cloud .gucci { --ar: 6.3804; }
.brands-cloud .guerlain { --ar: 7.2157; }
.brands-cloud .henkel { --ar: 1.7953; }
.brands-cloud .loreal { --ar: 5.5182; }
.brands-cloud .miele { --ar: 5.4471; }
.brands-cloud .omega { --ar: 2.0; }
.brands-cloud .saint-laurent { --ar: 9.9306; }
.brands-cloud .seb { --ar: 0.4327; }
.brands-cloud .shangri { --ar: 2.0; }
.brands-cloud .shiseido { --ar: 6.2256; }
.brands-cloud .van-cleef { --ar: 8.4897; }
.brands-cloud .colgate { --ar: 4.6429; }
.brands-cloud .michelin { --ar: 9.4509; }
.brands-cloud .lvmh { --ar: 4.1195; }

/* --- TAILLES ET REPLI, MOBILE --- */
.brands-cloud .audi { --x: 32.19%; --y: 18.74%; --w: 15.18%; --op: 0.39; }
.brands-cloud .boss { --x: 82.15%; --y: 78.58%; --w: 19.18%; --op: 0.33; }
.brands-cloud .carrefour { --x: 67.33%; --y: 13.56%; --w: 12.84%; --op: 0.41; }
.brands-cloud .cartier { --x: 53.4%; --y: 70.61%; --w: 18.60%; --op: 0.47; }
.brands-cloud .celine { --x: 81.15%; --y: 27.95%; --w: 21.46%; --op: 0.29; }
.brands-cloud .chanel { --x: 44.71%; --y: 69.2%; --w: 24.68%; --op: 0.42; }
.brands-cloud .chloe { --x: 83.68%; --y: 26.74%; --w: 17.58%; --op: 0.36; }
.brands-cloud .clarins { --x: 61.01%; --y: 77.52%; --w: 26.12%; --op: 0.34; }
.brands-cloud .coty { --x: 52.02%; --y: 29.71%; --w: 16.20%; --op: 0.35; }
.brands-cloud .dior { --x: 34.39%; --y: 86.23%; --w: 18.48%; --op: 0.45; }
.brands-cloud .estee-lauder { --x: 79.52%; --y: 30.7%; --w: 24.84%; --op: 0.37; }
.brands-cloud .givenchy { --x: 69.46%; --y: 74.01%; --w: 29.98%; --op: 0.43; }
.brands-cloud .gucci { --x: 12.27%; --y: 10.54%; --w: 24.76%; --op: 0.4; }
.brands-cloud .guerlain { --x: 80.42%; --y: 62.63%; --w: 23.68%; --op: 0.46; }
.brands-cloud .henkel { --x: 85.02%; --y: 35.0%; --w: 16.02%; --op: 0.41; }
.brands-cloud .loreal { --x: 75.22%; --y: 88.23%; --w: 23.00%; --op: 0.37; }
.brands-cloud .miele { --x: 28.69%; --y: 29.82%; --w: 22.86%; --op: 0.43; }
.brands-cloud .omega { --x: 59.68%; --y: 66.58%; --w: 16.92%; --op: 0.46; }
.brands-cloud .saint-laurent { --x: 6.27%; --y: 13.71%; --w: 27.78%; --op: 0.44; }
.brands-cloud .seb { --x: 75.31%; --y: 71.13%; --w: 7.86%; --op: 0.26; }
.brands-cloud .shangri { --x: 40.08%; --y: 16.8%; --w: 16.92%; --op: 0.36; }
.brands-cloud .shiseido { --x: 20.19%; --y: 89.9%; --w: 24.44%; --op: 0.33; }
.brands-cloud .van-cleef { --x: 73.43%; --y: 29.34%; --w: 25.68%; --op: 0.33; }
.brands-cloud .colgate { --x: 81.91%; --y: 85.1%; --w: 21.12%; --op: 0.47; }
.brands-cloud .michelin { --x: 72.9%; --y: 11.96%; --w: 27.10%; --op: 0.31; }
.brands-cloud .lvmh { --x: 66.63%; --y: 68.8%; --w: 19.88%; --op: 0.41; }

@media (min-width: 1200px) {
  .brands-cloud { max-width: none; aspect-ratio: 1440/532; padding-inline: 0; }
  .brands-center { width: 26%; }
  /* --- TAILLES ET REPLI, DESKTOP --- */
  .brands-cloud .audi { --x: 66.17%; --y: 44.41%; --w: 7.35%; --op: 0.33; }
  .brands-cloud .boss { --x: 65.06%; --y: 56.03%; --w: 9.28%; --op: 0.44; }
  .brands-cloud .carrefour { --x: 66.84%; --y: 57.52%; --w: 6.21%; --op: 0.28; }
  .brands-cloud .cartier { --x: 62.37%; --y: 68.81%; --w: 9.00%; --op: 0.47; }
  .brands-cloud .celine { --x: 57.55%; --y: 70.39%; --w: 10.39%; --op: 0.32; }
  .brands-cloud .chanel { --x: 51.86%; --y: 76.8%; --w: 11.94%; --op: 0.36; }
  .brands-cloud .chloe { --x: 51.12%; --y: 74.25%; --w: 8.50%; --op: 0.47; }
  .brands-cloud .clarins { --x: 45.48%; --y: 74.58%; --w: 12.64%; --op: 0.32; }
  .brands-cloud .coty { --x: 42.0%; --y: 72.56%; --w: 7.84%; --op: 0.27; }
  .brands-cloud .dior { --x: 37.01%; --y: 72.37%; --w: 8.94%; --op: 0.31; }
  .brands-cloud .estee-lauder { --x: 31.42%; --y: 72.53%; --w: 12.02%; --op: 0.39; }
  .brands-cloud .givenchy { --x: 27.6%; --y: 61.86%; --w: 14.51%; --op: 0.46; }
  .brands-cloud .gucci { --x: 27.29%; --y: 56.97%; --w: 11.97%; --op: 0.3; }
  .brands-cloud .guerlain { --x: 23.99%; --y: 49.63%; --w: 11.46%; --op: 0.45; }
  .brands-cloud .henkel { --x: 27.01%; --y: 38.74%; --w: 7.75%; --op: 0.27; }
  .brands-cloud .loreal { --x: 28.44%; --y: 35.81%; --w: 11.12%; --op: 0.33; }
  .brands-cloud .miele { --x: 29.18%; --y: 26.85%; --w: 11.06%; --op: 0.46; }
  .brands-cloud .omega { --x: 35.12%; --y: 22.92%; --w: 8.18%; --op: 0.34; }
  .brands-cloud .saint-laurent { --x: 39.83%; --y: 22.93%; --w: 13.44%; --op: 0.48; }
  .brands-cloud .seb { --x: 45.71%; --y: 16.23%; --w: 3.80%; --op: 0.3; }
  .brands-cloud .shangri { --x: 50.54%; --y: 21.14%; --w: 8.18%; --op: 0.38; }
  .brands-cloud .shiseido { --x: 51.45%; --y: 22.33%; --w: 11.83%; --op: 0.42; }
  .brands-cloud .van-cleef { --x: 59.23%; --y: 21.78%; --w: 12.44%; --op: 0.29; }
  .brands-cloud .colgate { --x: 61.24%; --y: 27.9%; --w: 10.20%; --op: 0.43; }
  .brands-cloud .michelin { --x: 67.18%; --y: 32.4%; --w: 13.11%; --op: 0.33; }
  .brands-cloud .lvmh { --x: 65.89%; --y: 38.82%; --w: 9.62%; --op: 0.32; }
}




/* ============================================================
   FOOTER — entièrement dans le socle (r-base.css)
   ------------------------------------------------------------
   Le bloc CTA du footer est commun à tous les gabarits. Sa géométrie desktop
   passe par des variables (`--ft-ratio`, `--ft-cta-*`, `--man-*`) dont les
   valeurs par défaut du socle SONT celles de la homepage : cette page n'a donc
   rien à redéfinir. Les autres gabarits, eux, surchargent ces variables.
   ============================================================ */
