/* ==========================================================================
   Coasia — Feuille de style principale
   Utilise les tokens définis dans design-tokens.css — ne pas coder de
   valeurs en dur (couleurs, tailles, rayons) qui existent déjà comme token.
   ========================================================================== */

/* --- Polices ------------------------------------------------------------ */
@font-face {
  font-family: 'Gilroy';
  src: url('../assets/fonts/Gilroy-Bold.ttf') format('truetype');
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}

/* --- Reset minimal ------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
/* Pas d'overflow-x:hidden sur html/body : fixer overflow-x sans overflow-y
   force le navigateur à traiter overflow-y comme "auto" (règle CSS), ce qui
   transformait html ET/OU body en conteneurs de scroll indépendants
   imbriqués (le "scroll dans le scroll" observé), en plus d'un comportement
   de "propagation" html/body peu fiable pour le clipping horizontal.
   Le débordement horizontal voulu (masque de la Section 3) est maintenant
   contenu localement par .section3__visual — voir plus bas. */
body {
  /* Blanc par défaut. Le gris (#EEEEEE) est confiné à la zone Hero+Section 2
     via .zone-tinted ci-dessous — sinon il "fuit" dans les marges de tout ce
     qui suit (ex: le panneau de la Section 4 se retrouvait avec un fond gris
     autour au lieu de blanc). */
  background: var(--color-white);
  color: var(--color-navy);
  font-family: var(--font-family-body);
  font-weight: var(--font-weight-paragraph);
  line-height: 1.4;
  -webkit-font-smoothing: antialiased;
}
img { max-width: 100%; display: block; }

/* Zone grise confinée (Hero + Section 2) — voir commentaire sur `body`. */
.zone-tinted { background: var(--color-surface-tint); }
a { color: inherit; }
ul { list-style: none; margin: 0; padding: 0; }
button { font: inherit; color: inherit; background: none; border: none; cursor: pointer; }

/* NB: seuls les titres (h1-h4) utilisent Gilroy. Nav, boutons, sous-menu =
   Poppins (hérité de body) — ne pas leur assigner --font-family-heading. */

/* ==========================================================================
   Boutons (design system — voir design-tokens.css : --radius-pill)
   ========================================================================== */
/* Neutre : label centré, pas d'icône. Hover : le label glisse à gauche et
   le rond-flèche apparaît depuis la droite (voir annotations "Buttons" du
   design system : brief hover = 0.2s, label bouge, apparition rond+flèche). */
.btn {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  height: 60px;
  width: fit-content;
  padding: 0 28px;
  border: 2px solid transparent;
  border-radius: var(--radius-pill);
  font-family: var(--font-family-body);
  font-size: var(--font-size-button);
  font-weight: var(--font-weight-button);
  text-decoration: none;
  white-space: nowrap;
  box-sizing: border-box;
}
.btn__label {
  transition: transform 0.2s ease;
}
.btn__icon {
  position: absolute;
  right: 8px;
  top: 50%;
  width: 46px;
  height: 46px;
  flex-shrink: 0;
  opacity: 0;
  transform: translate(-6px, -50%) scale(0.85);
  transition: opacity 0.2s ease, transform 0.2s ease;
  pointer-events: none;
}
/* Le glissement du label ne doit jouer que sur les boutons qui ont vraiment
   une icône à révéler (:has évite une classe modificatrice en plus) */
.btn:has(.btn__icon):hover .btn__label { transform: translateX(-18px); }
.btn:hover .btn__icon { opacity: 1; transform: translate(0, -50%) scale(1); }

/* Le design system ne change pas le fond au survol (bg identique neutre/hover) —
   seuls le label et l'icône bougent. */
.btn--primary {
  background: var(--color-surface-primary);
  color: var(--color-white);
}

.btn--outline {
  border-color: var(--color-white);
  color: var(--color-white);
}

/* Largeurs relevées sur le nœud Hero (Figma) */
.btn--services { width: 247px; }
.btn--model { width: 259px; }
.btn--contact { width: 248px; }

/* Variante pour fond clair (ex: bouton "About our Model" en Section 2) —
   pas d'icône dans le nœud Figma d'origine, donc pas de reveal au hover ici. */
/* Même système neutre/hover que les boutons du Hero (label glisse, rond+flèche
   apparaît) — juste la couleur du texte/bordure et l'icône qui changent pour
   rester lisibles sur fond clair. */
.btn--outline-navy {
  border-color: var(--color-blue-primary);
  color: var(--color-blue-primary);
}
.btn--about-model { width: 259px; }

/* ==========================================================================
   Hero (Section 1)
   ========================================================================== */
.hero {
  position: relative;
  /* Marge fixe de 40px de chaque côté à toutes les largeurs (pas seulement
     au-delà de 1920px) : on calcule la largeur plutôt que de compter sur
     des marges "auto", qui ne s'appliquent que si max-width contraint. */
  width: calc(100% - (2 * var(--section-padding, 40px)));
  max-width: var(--section-content-width, 1840px);
  margin: var(--section-padding, 40px) auto;
  min-height: clamp(640px, 88vh, 1040px);
  border-radius: var(--radius-lg);
  overflow: hidden;
  background: var(--color-navy-section-bg);
  color: var(--color-white);
  display: flex;
  flex-direction: column;
}

.hero__bg {
  position: absolute;
  inset: 0;
  z-index: 0;
}
.hero__photo {
  position: absolute;
  inset: 0;
  background-image: url('../assets/images/hero-photo.webp');
  background-attachment: fixed;
  background-size: cover;
  background-position: center;
}
.hero__gradient {
  position: absolute;
  inset: 0;
  background: radial-gradient(
    ellipse 90% 90% at 68% 55%,
    rgba(7, 33, 64, 0) 35%,
    var(--color-navy-section-bg) 100%
  );
}
/* Comme .hero__photo : un background-image en background-attachment:fixed,
   pas un <img> pilotée en JS — l'élément lui-même n'est qu'une "fenêtre"
   (inset:0, toute la surface du Hero), la vraie position/taille vient de
   background-position/-size. Ça fait de ce graphique une couche de plus du
   même fond fixe que la photo (même mécanique native, pas de gestion à
   part), et ça règle par la même occasion le bug de scroll tactile mobile
   (rebond élastique) qui cassait la version transform+JS.
   Valeurs desktop approximées en vw/vh depuis le rendu actuel (~1556px de
   large) — cet élément est purement décoratif, une approximation fluide
   suffit ; le mobile (ci-dessous, ≤640px) utilise lui les coordonnées
   exactes de la maquette Figma (node 1851:17, un seul viewport cible). */
.hero__graphic {
  position: absolute;
  inset: 0;
  background-image: url('../assets/images/hero-graphic.svg');
  background-repeat: no-repeat;
  background-attachment: fixed;
  background-size: 123.3vw auto;
  background-position: 26.3vw 19.5vh;
  mix-blend-mode: plus-lighter;
  opacity: 0.9;
  pointer-events: none;
}

/* --- Header / nav -------------------------------------------------------- */
.hero {
  /* --panel-inset est centralisé dans design-tokens.css (réutilisé par tout
     panneau arrondi plein cadre : Hero, Section 4…).
     container query units (cqw) au lieu de % : un % dans une custom property
     se recalcule contre le containing block de l'élément qui l'UTILISE, pas
     de celui qui la déclare — donc à 2 niveaux d'imbrication (ex: dans
     .hero__intro, petit-enfant de .hero), le % donnait une valeur fausse.
     cqw résout toujours contre .hero lui-même, quelle que soit la profondeur. */
  container-type: inline-size;
  --col: calc((100cqw - (2 * var(--panel-inset)) - (11 * var(--grid-gutter))) / 12);
}

.hero__header {
  position: relative;
  z-index: 10; /* doit rester au-dessus de .hero__content pour le sous-menu */
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  column-gap: 24px;
  padding: var(--panel-inset) var(--panel-inset) 0;
}
.hero__logo { justify-self: start; }
.hero__nav { justify-self: center; }
.hero__actions { justify-self: end; }

.hero__logo img { width: 356px; height: auto; }

.hero__nav > ul {
  display: flex;
  align-items: center;
  gap: 40px;
}
.nav-link {
  font-size: var(--font-size-button);
  font-weight: var(--font-weight-button);
  color: var(--color-white);
  text-decoration: none;
}
.has-dropdown { position: relative; }
.nav-link:hover,
.nav-link:focus-visible,
.has-dropdown:focus-within .nav-link,
.has-dropdown.is-open .nav-link { color: var(--color-red-accent); }

/* .dropdown = zone de survol "pont" (pas de gap mort entre le bouton et le
   menu, sinon la souris sort du :hover en descendant). Le rendu visuel
   (fond blanc, ombre, radius) est sur .dropdown__panel, à l'intérieur. */
.dropdown {
  position: absolute;
  top: 100%;
  left: 0; /* aligné sur le bord gauche du bouton de menu, pas centré */
  width: 242px;
  padding-top: 21px;
  transform: translateY(-6px);
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.2s ease, transform 0.2s ease, visibility 0.2s;
}
.has-dropdown:hover .dropdown,
.has-dropdown:focus-within .dropdown,
.has-dropdown.is-open .dropdown {
  opacity: 1;
  visibility: visible;
  transform: translateY(0);
}
.dropdown__panel {
  background: var(--color-white);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-dropdown);
  padding: 12px 0;
}
/* Neutre : label seul, centré-gauche, pas de flèche. Hover : texte + flèche
   passent en rouge et la flèche glisse depuis la gauche (même logique que
   les boutons pleine pilule, appliquée ici à chaque lien du sous-menu). */
.dropdown__link {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 12px 24px;
  font-size: 20px;
  font-weight: var(--font-weight-button);
  color: var(--color-navy);
  text-decoration: none;
}
.dropdown__arrow {
  width: 16px;
  height: 16px;
  opacity: 0;
  transform: translateX(-4px);
  transition: opacity 0.2s ease, transform 0.2s ease;
}
.dropdown__link:hover,
.dropdown__link:focus-visible {
  color: var(--color-red-accent);
}
.dropdown__link:hover .dropdown__arrow,
.dropdown__link:focus-visible .dropdown__arrow {
  opacity: 1;
  transform: translateX(0);
}
.dropdown__separator {
  height: 1px;
  margin: 0 24px;
  background: rgba(7, 33, 64, 0.1);
}

/* Variante étroite pour le sélecteur de langue (EN / FR / TH) */
.dropdown--lang { width: 76px; }
.dropdown--lang .dropdown__link { justify-content: center; padding: 12px 16px; }

.hero__actions {
  display: flex;
  align-items: center;
  gap: 24px;
}
.lang-switch__button {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: var(--font-size-button);
  color: var(--color-white);
}
.lang-switch__chevron { width: 10px; height: 10px; }

/* --- Contenu principal ----------------------------------------------------- */
.hero__content {
  position: relative;
  z-index: 3;
  /* Accoté sur la 2e colonne de la grille (colonne 1 + gutter réservés) */
  padding-top: clamp(40px, 6vh, 100px);
  padding-bottom: clamp(60px, 8vh, 138px);
  padding-left: calc(var(--panel-inset) + var(--col) + var(--grid-gutter));
  padding-right: var(--panel-inset);
  max-width: calc(var(--panel-inset) + (8 * var(--col)) + (7 * var(--grid-gutter)));
}

.hero__title {
  margin: 0 0 32px;
  font-family: var(--font-family-heading);
  font-weight: var(--font-weight-h1);
  font-size: clamp(2.75rem, 5vw, var(--font-size-h1));
  line-height: var(--line-height-h1);
  text-transform: uppercase;
  color: var(--color-white);
}
.hero__title .accent { color: var(--color-red-accent); }

.hero__intro {
  margin: 0 0 40px;
  font-family: var(--font-family-body);
  font-weight: var(--font-weight-intro);
  font-size: clamp(1.125rem, 2vw, var(--font-size-intro));
  line-height: var(--line-height-intro);
  /* 5 colonnes de la grille, pour retomber sur 3 lignes à 1920px */
  max-width: calc((5 * var(--col)) + (4 * var(--grid-gutter)));
}

.hero__cta {
  display: flex;
  flex-wrap: wrap;
  gap: 24px;
}

/* ==========================================================================
   Debug grille (touche "G") — 12 colonnes rouge 15% pour comparer avec Figma
   ========================================================================== */
.grid-debug {
  display: none;
  position: absolute;
  inset: 0;
  z-index: 999;
  pointer-events: none;
  grid-template-columns: repeat(var(--grid-columns, 12), 1fr);
  column-gap: var(--grid-gutter);
  padding: 0 var(--grid-margin); /* sections pleine largeur (Section 2/3) */
}
/* Variante pour les panneaux arrondis imbriqués (Hero, Section 4…) — l'inset
   réel à l'intérieur du panneau est --panel-inset, pas --grid-margin. */
.grid-debug--panel { padding: 0 var(--panel-inset); }
body.show-grid .grid-debug { display: grid; }
.grid-debug span { background: rgba(255, 0, 0, 0.15); height: 100%; }

/* ==========================================================================
   Section 2 — Notre modèle
   ========================================================================== */
.section2 {
  position: relative; /* ancre le debug grille (touche "G") */
  padding: clamp(60px, 10vh, 140px) 0;
}

/* Grille 12 colonnes réutilisable pour les sections pleine largeur (contrairement
   au Hero, pas de panneau imbriqué donc l'inset = --grid-margin directement). */
.grid-2col {
  display: grid;
  grid-template-columns: repeat(var(--grid-columns), 1fr);
  column-gap: var(--grid-gutter);
  padding-inline: var(--grid-margin);
  max-width: var(--section-max-width, 1920px);
  margin-inline: auto;
}

.section2__content { grid-column: 2 / 6; }   /* colonnes 2 à 5 (4 colonnes) */
.section2__models { grid-column: 7 / 12; }   /* colonnes 7 à 11 (5 colonnes) */

/* Composant "intro" réutilisé par toutes les sections de contenu texte
   (Section 2, Section 3, …) : H2 + chapô + paragraphe. */
.intro-title {
  margin: 0 0 32px;
  font-family: var(--font-family-heading);
  font-weight: var(--font-weight-h2);
  font-size: clamp(2.5rem, 4vw, var(--font-size-h2));
  line-height: var(--line-height-h2);
  text-transform: uppercase;
  color: var(--color-navy);
}

.intro-body { margin-bottom: 40px; }
.intro-lead {
  margin: 0 0 24px;
  font-weight: var(--font-weight-intro);
  font-size: var(--font-size-intro);
  line-height: var(--line-height-intro);
  color: var(--color-text-body);
}
.intro-paragraph {
  margin: 0;
  font-weight: var(--font-weight-paragraph);
  font-size: var(--font-size-paragraph);
  line-height: var(--line-height-paragraph);
  color: var(--color-text-body);
}

.section2__intro { margin-bottom: 40px; }
.section2__eyebrow {
  margin: 0 0 12px;
  font-weight: var(--font-weight-h4);
  font-size: var(--font-size-h4);
  line-height: var(--line-height-h4);
  text-transform: uppercase;
  color: var(--color-text-body);
}
.section2__eyebrow strong { font-weight: 800; } /* Poppins ExtraBold sur "Co-" */
.section2__intro-text {
  margin: 0;
  font-weight: var(--font-weight-small);
  font-size: var(--font-size-small);
  line-height: var(--line-height-small);
  color: var(--color-text-body);
}

.model-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--grid-gutter);
}
.model-card {
  background: var(--color-card-tint);
  border-radius: var(--radius-md);
  padding: 32px;
}
.model-card__number {
  display: block;
  margin-bottom: 16px;
  font-weight: var(--font-weight-surtitle);
  font-size: var(--font-size-surtitle);
  line-height: var(--line-height-surtitle);
  color: var(--color-red-accent);
}
.model-card__title {
  margin: 0 0 8px;
  font-weight: var(--font-weight-h3);
  font-size: var(--font-size-h3);
  line-height: var(--line-height-h3);
  color: var(--color-text-body);
}
.model-card__desc {
  margin: 0;
  font-weight: var(--font-weight-small);
  font-size: var(--font-size-small);
  line-height: var(--line-height-small);
  color: var(--color-text-body);
}
.model-grid__dots { display: none; } /* carrousel + points : mobile seulement */

@media (max-width: 1024px) {
  .grid-2col { grid-template-columns: 1fr; padding-inline: 24px; }
  .section2__content,
  .section2__models { grid-column: 1 / -1; }
  .section2__content { margin-bottom: 60px; }
  .model-grid { grid-template-columns: 1fr; }
}

/* ==========================================================================
   Section 3 — Built for the journey / Services
   ========================================================================== */
.section3 {
  background: var(--color-white);
  padding-bottom: clamp(60px, 10vh, 140px);
  /* position:relative (sans z-index) : sert d'ancre pour le visuel qui
     déborde, mais un z-index ici forcerait cette section entière à passer
     au-dessus de TOUT ce qui suit dans le document (même les siblings
     non-positionnés plus bas comme la Section 4) — c'était le bug qui
     empêchait le débordement du HAUT de la pilule de la Section 4 de
     s'afficher (la Section 3, élevée par son z-index, la recouvrait). */
  position: relative;
  /* overflow-x:clip ICI (pas sur .section3__visual, trop étroit à cause du
     padding/max-width de la grille — ça coupait le masque avant le bord de
     l'écran). .section3 fait toute la largeur du viewport, donc le clip se
     fait au vrai bord de l'écran. "clip" (pas "hidden") ne touche que
     l'horizontal : le débordement vertical voulu vers la Section 2 reste
     intact (overflow-y n'est jamais forcé à auto/hidden, contrairement à
     "hidden" tout court). */
  overflow-x: clip;
}

.section3__hero {
  align-items: start;
  padding-top: clamp(60px, 10vh, 140px);
  padding-bottom: 80px;
}
.section3__content { grid-column: 2 / 6; }  /* colonnes 2 à 5 (4 colonnes) */
.btn--our-services-2 { width: 259px; }

/* Visuel masqué + parallaxe. Débute à la colonne 7 et déborde à droite
   (comme dans Figma, ~880px de haut sur la maquette) — le débordement
   horizontal est géré par overflow-x sur html/body. */
.section3__visual {
  grid-column: 7 / -1;
  position: relative;
  aspect-ratio: 1804 / 880;
  /* Chevauche le gris (#EEEEEE) de la Section 2 juste au-dessus : on annule
     le padding-top du conteneur (identique à celui-ci) puis on va 80px plus
     loin, quelle que soit la hauteur de viewport. */
  margin-top: calc(-1 * clamp(60px, 10vh, 140px) - 30px); /* -50px vs avant (-80px) */
}
/* Le masque scrolle normalement avec la page (un simple "trou" dans le
   site) tandis que la photo, en background-attachment:fixed, reste ancrée
   au viewport — donc c'est le trou qui révèle différentes portions de la
   photo en défilant, plutôt qu'une photo qu'on déplace nous-mêmes en JS.
   Plus simple, plus robuste (la photo ne peut jamais "manquer" de matière
   puisque background-size:cover la couvre toujours entièrement). */
.parallax-mask {
  position: absolute;
  top: 0;
  left: 0;
  /* largeur ET hauteur agrandies par le même facteur pour ne pas déformer
     le masque (le ratio du bloc parent correspond déjà à celui du SVG) */
  width: 180.6%; /* +5% par rapport à 172% */
  height: 180.6%;
  overflow: hidden;
  -webkit-mask-image: url('../assets/images/section3-mask.svg');
  mask-image: url('../assets/images/section3-mask.svg');
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
  -webkit-mask-size: 100% 100%;
  mask-size: 100% 100%;
  background-image: url('../assets/images/section3-photo.webp');
  background-attachment: fixed;
  background-size: cover;
  background-position: center;
}

.section3__heading {
  grid-column: 4 / 10; /* centré entre les colonnes 4 et 9 */
  margin: clamp(40px, 6vw, 120px) 0 60px;
  font-family: var(--font-family-heading);
  font-weight: var(--font-weight-h2);
  font-size: clamp(2.25rem, 3.6vw, var(--font-size-h2));
  line-height: var(--line-height-h2);
  text-align: center;
  text-transform: uppercase;
  color: var(--color-navy);
}

.service-cards {
  grid-column: 1 / -1;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--grid-gutter);
}

/* Neutre : fond transparent, "CO-" en rouge, texte navy. Hover (brief charte
   graphique) : fond bleu qui apparaît rapidement, texte blanc, la carte
   monte de 30px, easing in/out, durée 0.3s. */
.service-card {
  position: relative; /* ancre le lien étiré (::after sur .service-card__link) */
  padding: 40px 32px;
  border-radius: var(--radius-md);
  background: transparent;
  color: var(--color-text-body);
  display: flex;
  flex-direction: column;
  min-height: 400px;
  transition: background-color 0.1s ease-out, transform 0.2s ease-in-out, color 0.2s ease-in-out;
}
.service-card:hover {
  background: var(--color-blue-primary);
  color: var(--color-white);
  transform: translateY(-30px);
}

.service-card__eyebrow {
  margin: 0 0 16px;
  font-weight: var(--font-weight-surtitle);
  font-size: var(--font-size-surtitle);
  line-height: var(--line-height-surtitle);
  text-transform: uppercase;
  color: var(--color-red-accent);
  transition: color 0.2s ease-in-out;
}
.service-card:hover .service-card__eyebrow { color: var(--color-white); }

.service-card__title {
  margin: 0 0 16px;
  font-weight: var(--font-weight-h3);
  font-size: var(--font-size-h3);
  line-height: var(--line-height-h3);
  text-transform: uppercase;
  color: inherit;
}
.service-card__desc {
  margin: 0 0 24px;
  padding-bottom: 24px;
  font-weight: var(--font-weight-small);
  font-size: var(--font-size-small);
  line-height: var(--line-height-small);
  color: inherit;
}
.service-card__link {
  margin-top: auto;
  display: inline-flex;
  align-items: center;
  gap: 12px;
  font-family: var(--font-family-body);
  font-weight: var(--font-weight-button);
  font-size: var(--font-size-button);
  color: inherit;
  text-decoration: none;
}
/* Lien étiré : rend toute la carte cliquable via ce seul lien (au lieu
   d'imbriquer un <a> dans un autre élément cliquable). */
.service-card__link::after {
  content: '';
  position: absolute;
  inset: 0;
}
.service-card__arrow { width: 16px; height: 16px; transition: transform 0.2s ease; }
.service-card:hover .service-card__arrow { transform: translateX(6px); }

@media (max-width: 1024px) {
  .section3__content,
  .section3__visual,
  .section3__heading { grid-column: 1 / -1; }
  /* overflow:hidden ICI : sur desktop, le masque (180.6% de son propre bloc)
     déborde volontairement au-dessus/à droite (effet composé avec la Section
     2). En 1 colonne, ce même débordement remontait/descendait par-dessus le
     titre "From intent..." juste après — on le contient donc localement. */
  .section3__visual { margin-top: 40px; aspect-ratio: 4 / 3; overflow: hidden; }
  .parallax-mask { width: 100%; height: 100%; }
  .service-cards { grid-template-columns: 1fr; }
  /* Sans min-height fixe, les cartes s'ajustent à leur contenu au lieu de
     laisser un grand vide avant "Explore" (le 400px du desktop n'a plus de
     raison d'être en 1 colonne). */
  .service-card { min-height: auto; }
}

/* ==========================================================================
   Section 4 — Local presence. Senior experience. (panneau sombre, comme le Hero)
   ========================================================================== */
.section4 {
  position: relative;
  /* La pilule déborde de 80px SOUS le panneau (voir .section4__photo-shape) —
     sans z-index, la Section 5 (sibling suivant, fond blanc) peint PAR-DESSUS
     ce débordement en ordre normal du DOM. z-index la fait passer devant. */
  z-index: 2;
  width: calc(100% - (2 * var(--section-padding)));
  max-width: var(--section-content-width);
  margin: var(--section-padding) auto;
  min-height: clamp(480px, 40vw, 760px);
  background: var(--color-navy-section-bg);
  border-radius: var(--radius-lg);
  color: var(--color-white);
  container-type: inline-size;
  --col: calc((100cqw - (2 * var(--panel-inset)) - (11 * var(--grid-gutter))) / 12);
  /* Padding haut/bas généreux (120px), séparé du padding gauche/droite
     (--panel-inset, qui doit rester lié à la grille pour l'alignement des
     colonnes) — sa propre variable pour que .section4__photo-shape puisse
     calculer son débordement bas par rapport à la vraie valeur utilisée. */
  --panel-block-padding: 120px;
  display: grid;
  grid-template-columns: repeat(var(--grid-columns), 1fr);
  column-gap: var(--grid-gutter);
  padding: var(--panel-block-padding) var(--panel-inset);
  align-items: start; /* la photo et le bloc de texte démarrent à la même hauteur */
}

/* Photo "pilule" — même principe que le masque de la Section 3 (fond en
   background-attachment:fixed = la photo reste ancrée au viewport, la forme
   qui scrolle avec la page révèle une portion différente : vitesse de
   déplacement "différente" entre la photo et le bloc, sans JS).
   .section4__photo = juste un repère de largeur/placement dans la grille.
   .section4__photo-shape = la vraie forme visible, plus haute que la zone de
   contenu et qui déborde en haut/bas du panneau (comme le visuel demandé). */
.section4__photo {
  grid-column: 2 / 6; /* largeur des colonnes 2 à 5 */
  align-self: stretch;
  position: relative;
}
.section4__photo-shape {
  position: absolute;
  left: 0;
  right: 0;
  /* Haut : aligné avec le bloc de texte (même point de départ), ne sort
     donc plus du panneau. Bas : déborde toujours sous le panneau — comme
     .section4__photo est déjà inset de --panel-inset (padding du panneau),
     il faut dépasser CE padding pour vraiment déborder du panneau lui-même. */
  top: 0;
  bottom: calc(-1 * var(--panel-block-padding) - 80px); /* déborde de 80px sous le panneau */
  border-radius: 9999px; /* forme pilule : un rectangle très arrondi */
  overflow: hidden;
}
.section4__photo-bg {
  position: absolute;
  inset: 0;
  background-image: url('../assets/images/section4-photo.webp');
  background-attachment: fixed;
  /* Hauteur = 100vh, largeur en "auto" pour PRÉSERVER le ratio de la photo
     (deux valeurs explicites en vw/vh, comme avant, étirent l'image sans
     respecter son ratio — d'où la distorsion). Le résultat reste plus large
     que la pilule (donc moins "zoomé"), sans jamais déformer l'image. */
  background-size: auto 100vh;
  background-position: left center;
}

.section4__content { grid-column: 7 / 13; }

.section4__route {
  display: flex;
  align-items: center;
  gap: 16px;
  margin-bottom: 32px;
  font-weight: var(--font-weight-surtitle);
  font-size: var(--font-size-surtitle);
  line-height: var(--line-height-surtitle);
  text-transform: uppercase;
  color: var(--color-red-accent);
}
.section4__route svg { color: var(--color-red-accent); flex-shrink: 0; }

.section4__title {
  margin: 0 0 32px;
  font-family: var(--font-family-heading);
  font-weight: var(--font-weight-h2);
  font-size: clamp(2.5rem, 4vw, var(--font-size-h2));
  line-height: var(--line-height-h2);
  text-transform: uppercase;
  color: var(--color-white);
}

.section4__lead { color: var(--color-white); }
.section4__paragraph {
  margin: 0;
  font-weight: var(--font-weight-paragraph);
  font-size: var(--font-size-paragraph);
  line-height: var(--line-height-paragraph);
  color: var(--color-muted-blue);
}

.btn--about-us { width: 248px; }

@media (max-width: 1024px) {
  /* display:block plutôt qu'une grille à 1 colonne : avec
     container-type:inline-size + cqw, le track "1fr" se calculait mal sous
     émulation mobile (largeur de piste incohérente avec la largeur réelle du
     conteneur, provoquant un débordement horizontal). Pas besoin de grille
     pour un empilement à une seule colonne de toute façon. */
  .section4 { display: block; padding: 40px 24px; text-align: left; }
  .section4__photo { min-height: 320px; margin-bottom: 40px; }
  .section4__photo-shape { top: -24px; bottom: -24px; }
  .section4__photo-bg { background-size: cover; background-position: center; }
  /* La flèche à largeur fixe (163px) faisait déborder "CANADA ↔ THAILAND" */
  .section4__route { flex-wrap: wrap; row-gap: 8px; }
  .section4__route svg { width: 60px; height: auto; }
}

/* ==========================================================================
   Section 5 — Insight where it matters. (texte + mosaïque bento)
   ========================================================================== */
.section5 {
  position: relative; /* ancre le debug grille (touche "G") */
  background: var(--color-white);
  padding: clamp(60px, 10vh, 140px) 0;
}
.section5__content { grid-column: 2 / 6; align-self: center; } /* colonnes 2 à 5 */
.section5__title .accent { color: var(--color-red-accent); }
.btn--experience { width: 259px; }

/* Bento : sous-grille de 12 colonnes propre à la mosaïque, proportions
   relevées sur les images sources (705×480, 270×480, 490×365, 485×365). */
.mosaic {
  grid-column: 7 / 13; /* colonnes 7 à 12 */
  align-self: center;
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  gap: var(--grid-gutter);
}
.mosaic__tile {
  border-radius: var(--radius-lg);
  overflow: hidden;
}
.mosaic__tile img { width: 100%; height: 100%; object-fit: cover; }
/* Une seule tuile par rangée fixe la hauteur (aspect-ratio) ; l'autre tuile
   de la même rangée n'a PAS de aspect-ratio propre, elle s'étire donc pour
   remplir exactement cette même hauteur (comportement stretch par défaut de
   la grille) — sinon chaque tuile calcule sa propre hauteur indépendamment
   et elles ne s'alignent plus (la 2e image de chaque rangée finissait "un
   peu courte"). */
.mosaic__tile--1 { grid-column: 1 / 10; grid-row: 1; aspect-ratio: 705 / 480; }
.mosaic__tile--2 { grid-column: 10 / 13; grid-row: 1; }
.mosaic__tile--3 { grid-column: 1 / 7; grid-row: 2; aspect-ratio: 490 / 365; }
.mosaic__tile--4 { grid-column: 7 / 13; grid-row: 2; }

@media (max-width: 1024px) {
  .section5__content,
  .mosaic { grid-column: 1 / -1; }
  .section5__content { margin-bottom: 40px; }
  .mosaic { grid-template-columns: 1fr 1fr; }
  .mosaic__tile--1 { grid-column: 1 / 3; grid-row: 1; }
  .mosaic__tile--2 { grid-column: 1 / 3; grid-row: 2; aspect-ratio: 16 / 9; }
  .mosaic__tile--3 { grid-column: 1 / 2; grid-row: 3; }
  .mosaic__tile--4 { grid-column: 2 / 3; grid-row: 3; }
}

/* ==========================================================================
   Footer — Let's build what's next.
   ========================================================================== */
.site-footer {
  position: relative;
  z-index: 2;
  width: calc(100% - (2 * var(--section-padding)));
  max-width: var(--section-content-width);
  margin: var(--section-padding) auto;
  min-height: clamp(560px, 45vw, 913px); /* 913px = hauteur du panneau sur la maquette */
  background: var(--color-navy-section-bg);
  border-radius: var(--radius-lg);
  color: var(--color-white);
  overflow: hidden; /* contient l'élément graphique — dernier bloc de page, pas de débordement voulu au-delà */
  /* Grille 12 colonnes, comme le reste du site, pour accoter le contenu sur
     la colonne 2 au lieu d'un padding uniforme. */
  container-type: inline-size;
  --col: calc((100cqw - (2 * var(--panel-inset)) - (11 * var(--grid-gutter))) / 12);
  display: grid;
  grid-template-columns: repeat(var(--grid-columns), 1fr);
  column-gap: var(--grid-gutter);
  padding: 0 var(--panel-inset);
}

/* Élément graphique — SVG multicolore autonome (dégradés inclus dans le
   fichier), pas un simple masque comme le Hero : on l'utilise donc tel quel,
   sans recréer les dégradés en CSS. */
.site-footer__graphic {
  position: absolute;
  top: -68%;
  right: -55%;
  width: 115%; /* encore un peu plus gros qu'avant (100%) */
  pointer-events: none;
  z-index: 0;
}
.site-footer__graphic img { width: 100%; height: auto; display: block; }

.site-footer__content {
  grid-column: 2 / 9; /* colonne 2, comme le reste du site */
  position: relative;
  z-index: 2;
  padding: 160px 0 140px; /* padding-top augmenté */
}

.site-footer__logo img { width: 286px; height: auto; margin-bottom: 64px; }

.site-footer__title {
  margin: 0 0 32px;
  font-family: var(--font-family-heading);
  font-weight: var(--font-weight-display);
  font-size: clamp(3rem, 8vw, var(--font-size-display));
  line-height: var(--line-height-display);
  text-transform: uppercase;
  color: var(--color-white);
}

.site-footer__lead {
  margin: 0 0 48px;
  font-weight: var(--font-weight-intro);
  font-size: var(--font-size-intro);
  line-height: var(--line-height-intro);
  color: var(--color-white);
}

.site-footer__cta {
  display: flex;
  align-items: center;
  gap: 24px;
}
.btn--contact-footer { width: 248px; }
.site-footer__divider {
  width: 1px;
  height: 40px;
  background: rgba(255, 255, 255, 0.3);
}
.site-footer__social {
  display: inline-flex;
  color: var(--color-white);
  transition: opacity 0.2s ease;
}
.site-footer__social-icon { width: 26px; height: auto; } /* un peu plus grand qu'avant (20px) */
.site-footer__social:hover { opacity: 0.7; }

.site-footer__meta {
  position: absolute;
  z-index: 2;
  right: var(--panel-inset);
  bottom: 48px;
  display: flex;
  align-items: center;
  gap: 24px;
  font-family: var(--font-family-body);
  font-weight: var(--font-weight-button);
  font-size: 16px;
  color: rgba(255, 255, 255, 0.4);
}
.site-footer__meta a { color: inherit; text-decoration: none; transition: color 0.2s ease; }
.site-footer__meta a:hover { color: var(--color-white); }

@media (max-width: 1024px) {
  /* display:block, même raison que la Section 4 (voir plus haut) : la
     grille à 1 colonne se calculait mal sous émulation mobile avec
     container-type:inline-size + cqw. */
  .site-footer { width: calc(100% - 32px); margin: 16px auto; display: block; padding: 0 24px; }
  .site-footer__content { padding: 60px 0 100px; }
  .site-footer__meta { position: static; margin: 0 0 24px; }
  .site-footer__graphic { width: 130%; top: -10%; right: -30%; }
}

/* ==========================================================================
   Responsive — deux points de rupture partagés par tout le site :
   - 1024px : bascule tablette portrait + mobile → nav en menu burger
   - 640px  : ajustements fins mobile (tailles, empilement, espacements)
   ========================================================================== */

/* --------------------------------------------------------------------------
   Menu burger (bouton + panneau plein écran) — tablette portrait et mobile
   -------------------------------------------------------------------------- */
.hero__burger {
  display: none; /* visible seulement <=1024px, voir media query plus bas */
  position: relative;
  width: 28px;
  height: 20px;
  flex-shrink: 0;
}
.hero__burger-line {
  position: absolute;
  left: 0;
  width: 100%;
  height: 2px;
  border-radius: 2px;
  background: var(--color-white);
  transition: transform 0.25s ease, opacity 0.2s ease, top 0.25s ease;
}
.hero__burger-line:nth-child(1) { top: 0; }
.hero__burger-line:nth-child(2) { top: 9px; }
.hero__burger-line:nth-child(3) { top: 18px; }
.hero__burger.is-open .hero__burger-line:nth-child(1) { top: 9px; transform: rotate(45deg); }
.hero__burger.is-open .hero__burger-line:nth-child(2) { opacity: 0; }
.hero__burger.is-open .hero__burger-line:nth-child(3) { top: 9px; transform: rotate(-45deg); }

/* Empêche le fond de scroller quand le menu plein écran est ouvert. Ce n'est
   pas le même piège que le overflow-x:hidden html/body (voir plus haut) :
   ici c'est un verrou TEMPORAIRE (activé/désactivé par JS), pas un état
   permanent qui entrerait en conflit avec le débordement volontaire de
   certaines sections. */
body.nav-open { overflow: hidden; }

.mobile-nav {
  position: fixed;
  inset: 0;
  z-index: 100;
  display: flex;
  flex-direction: column;
  /* Flux naturel (pas de justify-content:space-between) : le contenu est
     largement plus court que la hauteur d'écran typique, pousser le footer
     tout en bas rendait sa position imprévisible sur les petits écrans. */
  background: var(--color-navy-section-bg);
  /* 40px de chaque côté (standard du site), pas 24px : les liens et le
     séparateur ont donc 375-80=295px de large, comme partout ailleurs. */
  padding: 110px 40px 40px;
  overflow-y: auto;
  transform: translateX(100%);
  transition: transform 0.3s ease;
}
.mobile-nav.is-open { transform: translateX(0); }

.mobile-nav__list { display: flex; flex-direction: column; }
.mobile-nav__item { border-bottom: 1px solid rgba(255, 255, 255, 0.12); }
.mobile-nav__item:first-child { border-top: 1px solid rgba(255, 255, 255, 0.12); }

.mobile-nav__link {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  padding: 22px 0;
  font-family: var(--font-family-body);
  font-weight: var(--font-weight-button); /* medium, comme le nav-link desktop */
  font-size: 28px;
  color: var(--color-white);
  text-decoration: none;
}
button.mobile-nav__link { justify-content: space-between; }
.mobile-nav__link:hover,
.mobile-nav__link:focus-visible,
.has-dropdown.is-open .mobile-nav__link { color: var(--color-red-accent); }
/* L'icône pointe naturellement vers la DROITE (pas vers le bas malgré son
   nom de fichier) — rotate(-90deg) la fait pointer vers le HAUT au repos ;
   +180deg (donc rotate(90deg)) la fait pointer vers le BAS à l'ouverture. */
.mobile-nav__chevron { width: 12px; height: auto; transition: transform 0.2s ease; transform: rotate(-90deg); }
.has-dropdown.is-open .mobile-nav__chevron { transform: rotate(90deg); }

.mobile-nav__submenu {
  max-height: 0;
  overflow: hidden;
  transition: max-height 0.3s ease;
}
.has-dropdown.is-open .mobile-nav__submenu { max-height: 320px; }
.mobile-nav__sublink {
  display: block;
  padding: 12px 0 12px 4px;
  font-family: var(--font-family-body);
  font-weight: var(--font-weight-button);
  font-size: 18px;
  color: rgba(255, 255, 255, 0.7);
  text-decoration: none;
}
.mobile-nav__sublink:hover,
.mobile-nav__sublink:focus-visible { color: var(--color-red-accent); }

.mobile-nav__footer {
  display: flex;
  flex-direction: column;
  gap: 24px;
  padding-top: 32px;
  /* Pousse le footer (langues + CTA) jusqu'en bas de l'espace DISPONIBLE
     dans .mobile-nav (flex column) — reste donc dans le flux normal :
     au repos ça atterrit à 40px du bas (le padding-bottom du menu), mais
     si le sous-menu "Services" s'ouvre et allonge la liste au-dessus,
     le footer est repoussé en conséquence (et le menu devient scrollable
     via overflow-y:auto s'il n'y a plus assez de place), au lieu de rester
     figé par-dessus au même endroit. */
  margin-top: auto;
}
.mobile-nav__lang { display: flex; gap: 12px; }
.mobile-nav__lang-btn {
  padding: 12px 22px;
  border: 1px solid rgba(255, 255, 255, 0.3);
  border-radius: var(--radius-pill);
  font-family: var(--font-family-body);
  font-weight: var(--font-weight-button);
  font-size: 14px;
  color: rgba(255, 255, 255, 0.6);
}
.mobile-nav__lang-btn.is-active { border-color: var(--color-white); color: var(--color-white); }
/* Remis dans le flux normal (plus de position:absolute) : le bouton reste
   à 295px de large et centré, mais suit maintenant .mobile-nav__footer —
   donc il bouge avec le reste si le sous-menu "Services" s'ouvre, au lieu
   de rester figé par-dessus. Sa position au repos (40px du bas) vient du
   margin-top:auto sur .mobile-nav__footer, pas d'un ancrage direct ici. */
.btn--contact-mobile {
  width: 295px;
  margin-inline: auto;
}

/* --------------------------------------------------------------------------
   Hero — tablette portrait + mobile (<=1024px)
   -------------------------------------------------------------------------- */
/* 1280px (pas 1024) pour la nav/burger spécifiquement : en dessous de
   ~1300px, le menu desktop complet (logo 356px + 4 liens + FR + bouton) n'a
   plus la place dans la grille 3 colonnes et écrasait le logo à ~7px de
   large (grid squeeze). Les autres sections, elles, peuvent tout de même
   repasser en 1 colonne dès 1024px (voir les autres media queries). */
@media (max-width: 1280px) {
  .hero { width: calc(100% - 32px); margin: 16px auto; min-height: auto; }

  .hero__header {
    position: sticky;
    top: 16px;
    z-index: 101; /* au-dessus de .mobile-nav (100) */
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 24px;
  }
  .hero__logo img { width: 160px; }
  .hero__nav,
  .hero__actions .lang-switch { display: none; } /* remplacés par le menu burger */
  .hero__actions { gap: 0; }
  .hero__burger { display: block; }

  .hero__content {
    padding: 40px 24px 56px !important;
    max-width: none;
  }
  .hero__title { font-size: clamp(2.5rem, 8vw, 4rem); }
  .hero__intro { max-width: none; }
}

@media (max-width: 640px) {
  .hero__header { padding: 16px; top: 8px; }
  /* Le bouton "Talk to Coasia" sort de la top bar mobile (il reste
     disponible dans le menu burger) — la top bar devient logo + burger. */
  .hero__header .btn--contact { display: none; }
  .hero__logo img { width: 170px; } /* plus de place sans le bouton contact */
  .hero__title { font-size: clamp(2.25rem, 11vw, 3rem); margin-bottom: 24px; }
  /* Le retour à la ligne forcé entre "Presence" et "that creates" est pensé
     pour la largeur desktop — en dessous, on laisse le texte s'enrouler
     naturellement (sinon "that creates" se casse lui-même en 2 mots). */
  .hero__break { display: none; }
  .hero__intro { font-size: 1.125rem; margin-bottom: 32px; }
  .hero__cta { flex-direction: column; align-items: stretch; gap: 16px; }
  .hero__cta .btn { width: 100%; }
  /* opacity:0.7 : la photo est trop intense pour le texte qui passe par-dessus en mobile. */
  .hero__photo { background-position: 70% center; opacity: 0.7; }
}

/* ==========================================================================
   Mobile (≤640px) — valeurs alignées sur la maquette Figma mobile (375px) :
   https://www.figma.com/design/FyCZgqDt8kg2rWpnSONabR/Explorations?node-id=1851-8
   Toutes les tailles ci-dessous viennent directement de get_design_context
   sur cette maquette — plus de valeurs devinées à l'œil.
   ========================================================================== */
@media (max-width: 640px) {
  /* --- Rayon des grands panneaux (Hero, Section 4, Footer, tuiles mosaïque) */
  :root { --radius-lg: 20px; }

  /* --- Espacement : 40px de la fenêtre au contenu, PARTOUT (sections pleine
     largeur et panneaux confondus). Les panneaux arrondis (Hero/Section4/
     Footer) ont une marge extérieure de 10px, donc leur padding intérieur
     propre = 40 - 10 = 30px pour arriver au même total de 40px. */
  .grid-2col { padding-inline: 40px; }

  /* --- Typo : échelle mobile de la maquette --- */
  .hero__title { font-size: 42px; }
  .intro-title,
  .section3__heading,
  .section4__title { font-size: 36px; }
  .intro-lead,
  .hero__intro,
  .site-footer__lead { font-size: 22px; }
  /* Paragraphe standard ET "petits" textes (descriptions de cartes, texte
     d'intro Section 2) convergent vers la même taille sur mobile — c'est ça
     qui manquait de constance avant. */
  .intro-paragraph,
  .section4__paragraph,
  .section2__intro-text,
  .model-card__desc,
  .service-card__desc { font-size: 16px; }
  .model-card__title,
  .service-card__title { font-size: 22px; }
  .model-card__number,
  .service-card__eyebrow,
  .section4__route { font-size: 16px; }

  /* --- Boutons : la maquette les garde à 60px de haut (pas de réduction) —
     seule la taille de police baisse légèrement, standardisée à 18px. */
  .btn { height: 60px; font-size: 18px; padding: 0 24px; }
  .btn__icon { width: 46px; height: 46px; right: 8px; }
  .btn:has(.btn__icon):hover .btn__label { transform: translateX(-18px); }

  /* --- Boutons "pleine largeur de contenu" : chaque bouton en pilule seul
     sur sa ligne fait 295px (largeur du contenu, comme le texte), pas la
     largeur desktop héritée (247/248/259px). Le CTA du footer (accompagné
     du séparateur + de l'icône LinkedIn sur la même ligne) et le bouton du
     menu burger (déjà 100% de son propre menu) sont volontairement exclus
     — les forcer à 295px les ferait déborder de leur ligne. */
  .btn--services,
  .btn--model,
  .btn--about-model,
  .btn--our-services-2,
  .btn--about-us,
  .btn--experience {
    width: 295px;
  }

  /* --- Menu burger : mon essai précédent (90deg fermé / -90deg ouvert,
     pour imiter un chevron "vers le bas") tournait dans le mauvais sens.
     Simplifié comme demandé : juste 180° à l'ouverture, 180° au retour à la
     fermeture — la règle de base (ligne ~1007) fait déjà exactement ça, il
     suffit de ne plus la surcharger ici. */

  /* --- Hero : marge extérieure + padding intérieur alignés sur le standard
     40px total (10 + 30). La largeur héritait encore de calc(100% - 32px)
     (palier 1280px, marge 16px) : jamais recalculée pour la vraie marge
     10px mobile, ce qui donnait 16px de chaque côté au lieu de 10px (donc
     aussi un contenu qui ne démarrait pas exactement à 40px). */
  .hero { width: calc(100% - 20px); margin: 10px auto; min-height: 720px; } /* maquette : ~720px de hauteur totale */
  .hero__header { padding: 30px 30px 0; top: 10px; }
  /* padding-top 89px = 140px (position du H1 dans la maquette, depuis le
     haut du panneau) - hauteur du header (~51px, logo + padding). */
  /* flex:1 pour que .hero__content occupe tout l'espace restant sous le
     header (dans .hero, hauteur fixe 720px) — mais ça agrandit juste la
     BOÎTE, sans pousser son DERNIER enfant vers le bas (.hero__content
     n'est pas lui-même un flex container) : le vide apparaissait donc
     avant le padding-bottom plutôt qu'entre les boutons et le bas du
     panneau. En passant .hero__content en flex column + margin-top:auto
     sur .hero__cta, les boutons sont poussés jusqu'au padding-bottom (donc
     pile à 40px du bas du panneau), sans changer la position du H1/intro. */
  .hero__content { padding: 89px 30px 40px !important; flex: 1; display: flex; flex-direction: column; }
  .hero__cta { margin-top: auto; }

  /* Élément graphique : coordonnées exactes du node Figma 1851:17 (mockup
     mobile 375px), converties en position à l'écran pour background-
     position/-size (fixed attachment résout les deux en px bruts contre le
     viewport, pas contre l'élément — donc px direct, pas de % ici). Panneau
     Hero à 10px du haut/de la gauche à cette largeur : élément à
     left:-132px/top:393px/804×392 dans le panneau → 10-132=-122px,
     10+393=403px à l'écran. */
  .hero__graphic {
    background-size: 804px 392px;
    background-position: -122px 403px;
  }

  /* Le fond gris de .zone-tinted "collabait" (margin-collapse CSS) avec la
     marge du haut de .hero (premier enfant) : le gris ne devenait visible
     qu'à partir d'où commençait déjà le panneau navy, donc les 10px du haut
     de la fenêtre restaient blancs. flow-root isole .zone-tinted de ce
     collapse pour que son fond gris démarre bien à 0. */
  .zone-tinted { display: flow-root; }

  /* --- Section 2 : cartes modèle en carrousel horizontal (swipe + points de
     pagination), comme la maquette — plus un empilement vertical simple. */
  /* Sans min-width:0 ici, l'élément à overflow:auto (.model-grid) plus bas
     forçait TOUTE la grille (donc la page) à s'élargir pour "faire de la
     place" au contenu scrollable au lieu de le contenir localement — piège
     classique grid/flex + overflow. */
  .section2__models { min-width: 0; }
  .model-grid {
    display: flex;
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    gap: 16px;
    margin: 0 -40px; /* déborde jusqu'au bord de l'écran pour le "peek" */
    padding: 0 40px 4px;
    scrollbar-width: none;
    /* Sans scroll-padding, le snap ignore le padding-left du conteneur : au
       chargement le navire "saute" directement au repos sur scrollLeft:40
       (bord de la 1ère card), sautant par-dessus le padding — la card se
       retrouvait donc collée au bord de l'écran au lieu d'être à 40px. En
       fixant scroll-padding = au padding visuel, chaque point d'arrêt (1ère
       card comme les suivantes) s'aligne bien à 40px du bord du contenu. */
    scroll-padding-left: 40px;
  }
  .model-grid::-webkit-scrollbar { display: none; }
  .model-card {
    flex: 0 0 220px;
    min-height: auto;
    scroll-snap-align: start;
  }
  .model-grid__dots {
    display: flex; /* override du display:none desktop */
    justify-content: center;
    gap: 10px;
    margin-top: 24px;
  }
  .model-grid__dot {
    width: 16px;
    height: 16px;
    border-radius: 50%;
    /* pas --color-gray-light : identique au fond de la Section 2, les points
       inactifs devenaient invisibles dessus */
    background: rgba(1, 44, 66, 0.2);
    transition: background-color 0.2s ease;
  }
  .model-grid__dot.is-active { background: var(--color-navy); }

  /* --- Section 3 : le visuel masqué doit être plein cadre (bord à bord,
     comme le reste de la maquette mobile — pas inséré à 40px comme le
     bouton au-dessus) et faire 312px de haut (mesuré sur le node
     "Visual_scroll" de la maquette, node-id 1851:81). Auparavant le
     conteneur héritait du aspect-ratio:4/3 + largeur insérée (295px) du
     palier tablette (≤1024px), ce qui donnait un visuel trop petit et
     "coupé de partout" au lieu de déborder jusqu'au bord de l'écran. */
  .section3__visual {
    margin-inline: -40px; /* annule le padding-inline de .grid-2col : 295px → 375px, plein cadre */
    aspect-ratio: auto;
    height: 312px;
  }
  /* Masque proportionnel (pas étiré, ratio 1804:880 comme la source, pas
     4:3) : hauteur = 100% du conteneur (312px, comme la maquette — donc pas
     besoin de centrage vertical, top:0 suffit), largeur déduite du ratio
     (≈640px). PAS centré horizontalement : la maquette place le bord gauche
     à -40px (donc surtout coupé à droite, très peu à gauche) — valeur
     donnée par le design, pas un crop symétrique.
     PAS de `transform` ici : un transform sur CET élément (même juste pour
     du centrage) crée un nouveau containing block, et Chrome calcule alors
     son background-attachment:fixed par rapport à CET élément au lieu du
     vrai viewport — la photo se remettait donc à bouger avec le masque
     (l'effet "trou" ne marchait plus). C'était le `translateY(-50%)` d'une
     précédente itération, devenu inutile maintenant que height:100% tombe
     déjà pile sur la hauteur du conteneur. */
  .parallax-mask {
    top: 0;
    left: -40px;
    width: auto;
    height: 100%;
    aspect-ratio: 1804 / 880;
  }
  /* Note : background-attachment:fixed (hérité de la règle de base) est
     laissé tel quel ici, pour rester cohérent avec la Section 4 qui utilise
     exactement la même technique (.section4__photo-bg) et fonctionne. Vrai
     bémol connu : iOS Safari désactive fixed (traité comme "scroll") — mais
     c'est alors un problème pour LES DEUX sections identiquement, pas
     spécifique à celle-ci ; pas la peine de la "réparer" seule avec un
     substitut JS plus faible que l'original. À revisiter ensemble si un
     test sur iOS réel confirme le problème. */
  /* Sujet (le personnage) un peu trop sur le bord droit du cadre — décalé de
     100px vers la gauche pour mieux le montrer. */
  .parallax-mask { background-position: calc(50% - 100px) center; }

  /* --- Section 3 : pas d'effet hover tactile sur les cartes services — un
     fond gris fixe les délimite à la place. */
  .service-card { background: var(--color-gray-light); }
  .service-card:hover {
    background: var(--color-gray-light);
    color: var(--color-text-body);
    transform: none;
  }
  .service-card:hover .service-card__arrow { transform: none; }

  /* --- Section 4 : photo repositionnée SOUS le texte (flex + order, pas de
     changement de markup), padding standard 10 (marge) + 30 (intérieur).
     La largeur héritait encore de calc(100% - 80px) (formule desktop,
     --section-padding:40px), jamais recalculée pour mobile — d'où un
     panneau à 40px de chaque côté au lieu de 10px comme le Hero/Footer, et
     une zone de contenu (donc la photo) plus étroite que prévu. */
  /* padding-top 47px (mesuré sur le node Figma 1851:130 : le texte "CANADA"
     commence 47px sous le haut du panneau navy) au lieu des 30px uniformes
     — le haut manquait clairement d'air par rapport au reste du panneau. */
  .section4 { display: flex; flex-direction: column; width: calc(100% - 20px); margin: 10px auto; padding: 47px 30px 30px; }
  .section4__photo { order: 2; margin-top: 32px; margin-bottom: 0; }
  .section4__content { order: 1; }
  /* La maquette fait déborder la photo sous le panneau (pas juste sous son
     propre conteneur .section4__photo) — le -20px d'origine restait
     entièrement contenu dans le padding bas de .section4 (30px), la photo
     ne débordait donc pas du tout de la section. -140px = 30px de padding +
     110px de vrai débordement visible sous le panneau (réduit depuis 150px,
     un peu trop prononcé). Ce débordement rentrait carrément dans le titre
     de la Section 5 (qui commençait ~59px avant la fin de la photo) — voir
     le padding-top explicite ajouté plus bas sur .section5. */
  .section4__photo-shape { top: 0; bottom: -140px; }

  /* --- Section 5 : padding-top explicite (au lieu du clamp(60px,10vh,140px)
     hérité, qui pouvait descendre bien en dessous du débordement de la
     photo de la Section 4 juste au-dessus) pour garder une marge nette
     sous la photo, quelle que soit la hauteur de l'écran. Espace entre les
     photos de la mosaïque un peu réduit. */
  .section5 { padding-top: 140px; }
  /* La mosaïque doit faire 355px de large (marge 10px, comme le Hero/
     Section4/Footer) et non 295px (marge 40px, comme le texte) — mesuré sur
     le node Figma 1851:152. margin-inline:-30px annule les 40px de
     .grid-2col pour ne garder que 10px de chaque côté (40-30=10). */
  .mosaic { gap: 10px; margin-inline: -30px; }

  /* --- Footer : padding standard, ruban plus gros et tassé à droite, logo/
     icône LinkedIn/texte légal à la bonne taille (maquette). La largeur
     héritait encore de calc(100% - 32px) (palier 1024px, marge 16px) :
     jamais recalculée pour la vraie marge 10px mobile. --- */
  .site-footer { width: calc(100% - 20px); margin: 10px auto; padding: 0 30px; }
  .site-footer__content { padding: 32px 0 48px; }
  /* Valeurs exactes converties depuis le node Figma 1851:165 (comparées au
     panneau 355×780) : largeur 1268.5/355=357%, right -1038.5/355=-292.5%,
     top -210/780=-26.9%. Mes essais précédents (220%/240%, -15%, 135px)
     étaient devinés à l'œil — ceci vient des vraies coordonnées. */
  .site-footer__graphic { width: 357%; top: -26.9%; right: -292.5%; }
  .site-footer__logo img { width: 200px; padding-top: 20px; }
  .site-footer__title { font-size: 60px; }
  .site-footer__social-icon { width: 34px; }
  .site-footer__meta { font-size: 14px; }
}
