/* ==========================================================================
   STRYK Property Management — feuille de style unique
   Ordre : polices, tokens, reset, base, utilitaires, boutons, puis les
   composants dans l'ordre de la page, et enfin les préférences de mouvement.
   Mobile-first. Points de rupture à 48rem (768px) et 75rem (1200px).
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Polices auto-hébergées
   Deux familles variables, un fichier chacune : serif de titrage pour les
   titres, sans serif pour tout le reste.
   -------------------------------------------------------------------------- */

@font-face {
  font-family: "Playfair Display";
  src: url("../fonts/playfair-display-variable.woff2") format("woff2");
  font-weight: 400 700;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "Inter";
  src: url("../fonts/inter-variable.woff2") format("woff2");
  font-weight: 300 600;
  font-style: normal;
  font-display: swap;
}

/* --------------------------------------------------------------------------
   2. Tokens
   -------------------------------------------------------------------------- */

:root {
  /* Palette relevée sur la maquette. */
  --c-ink: #121110;             /* noir profond, aplats et texte sur clair */
  --c-cream: #f4efe6;           /* fond de page */
  --c-beige-btn: #e6dccb;       /* boutons pleins */
  --c-beige-footer: #eae2d4;    /* pied de page, un ton plus soutenu */
  --c-brass: #b08d3f;           /* accent laiton, couleur du logo */
  --c-muted: #6b635a;           /* texte secondaire sur clair */

  /* Le laiton de la marque ne fait que 2,7:1 sur le crème : il reste réservé
     aux fonds sombres, aux filets et aux pictogrammes. Sur fond clair, les
     petits textes prennent cette variante foncée, à 5,1:1 sur le crème et
     4,5:1 sur le beige du pied de page. */
  --c-brass-ink: #7a5f20;

  /* Textes posés sur le noir profond. */
  --c-on-ink: #f4efe6;
  --c-on-ink-soft: #b9b2a8;
  --c-on-ink-faint: #8c857c;

  /* Filets */
  --c-line: #ded5c6;                        /* sur clair */
  --c-line-ink: rgba(244, 239, 230, 0.14);  /* sur le noir */
  --c-line-brass: rgba(176, 141, 63, 0.45);
  --c-error: #9a2b1e;

  --f-display: "Playfair Display", Georgia, "Times New Roman", serif;
  --f-body: "Inter", system-ui, -apple-system, "Segoe UI", sans-serif;

  /* Échelle typographique. */
  --t-xs: 0.6875rem;
  --t-sm: 0.8125rem;
  --t-base: 0.9375rem;
  --t-lg: 1.125rem;
  --t-xl: 1.5rem;
  --t-2xl: 2rem;
  --t-3xl: 2.5rem;

  --container: 84rem;
  --gutter: clamp(1.25rem, 5vw, 4rem);
  --section-y: clamp(3.5rem, 8vw, 7rem);
  --header-h: 5rem;

  /* Zones sûres de l'iPhone. Le repli à 0px sert partout ailleurs : sans lui,
     un calc() contenant un env() non résolu invaliderait toute la règle. */
  --safe-top: env(safe-area-inset-top, 0px);
  --safe-bottom: env(safe-area-inset-bottom, 0px);

  /* Interlettrage des capitales espacées, le geste typographique de la
     maquette : libellés, boutons, intitulés de service. */
  --ls-caps: 0.22em;
  --ls-caps-tight: 0.16em;
}

/* --------------------------------------------------------------------------
   3. Reset minimal
   -------------------------------------------------------------------------- */

*,
*::before,
*::after {
  box-sizing: border-box;
}

body,
h1, h2, h3, p, ul, ol, figure, blockquote {
  margin: 0;
}

ul, ol {
  padding: 0;
  list-style: none;
}

img, svg {
  max-width: 100%;
}

button,
input,
select,
textarea {
  font: inherit;
  color: inherit;
}

button {
  cursor: pointer;
}

/* Ce fond ne se voit que là où le corps de page ne peint pas : les zones
   sûres de l'iPhone, derrière la barre d'état et sous la barre d'adresse.
   C'est ce qui les rend noires en mode clair comme en mode sombre. */
html {
  background-color: var(--c-ink);
  scroll-behavior: smooth;
  /* Les ancres ne passent pas sous la barre fixe, encoche comprise. */
  scroll-padding-top: calc(var(--header-h) + var(--safe-top) + 1rem);
  -webkit-text-size-adjust: 100%;
}

/* --------------------------------------------------------------------------
   4. Éléments de base
   -------------------------------------------------------------------------- */

/* Fond sombre, et non crème. Sous iOS, Safari place sa vue web sous la barre
   d'état et peint lui-même cette bande avec la couleur de fond du corps de
   page : un fond crème y produisait une bande claire sous l'heure, que ni le
   fond de l'élément racine ni la marge d'encoche de l'en-tête ne pouvaient
   atteindre. Le crème est porté par les sections, qui le déclarent toutes. */
body {
  background-color: var(--c-ink);
  color: var(--c-ink);
  font-family: var(--f-body);
  font-size: var(--t-base);
  font-weight: 400;
  line-height: 1.7;
  -webkit-font-smoothing: antialiased;
  /* Place pour la barre d'action fixe du mobile, encoche basse comprise. */
  padding-bottom: calc(3.5rem + var(--safe-bottom));
  overflow-x: hidden;
}

h1, h2, h3 {
  font-family: var(--f-display);
  font-weight: 400;
  line-height: 1.18;
  letter-spacing: 0.005em;
}

a {
  color: inherit;
}

:focus-visible {
  outline: 2px solid var(--c-brass);
  outline-offset: 3px;
}

/* --------------------------------------------------------------------------
   5. Utilitaires
   -------------------------------------------------------------------------- */

.container {
  width: 100%;
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.sr-only,
.honeypot {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

.skip-link {
  position: absolute;
  top: -100%;
  left: 1rem;
  z-index: 100;
  padding: 0.75rem 1.25rem;
  background-color: var(--c-ink);
  color: var(--c-on-ink);
  text-decoration: none;
}

.skip-link:focus {
  top: 1rem;
}

/* Le petit libellé en capitales espacées qui coiffe chaque section. */
.label {
  font-size: var(--t-xs);
  font-weight: 500;
  letter-spacing: var(--ls-caps);
  line-height: 1.4;
  text-transform: uppercase;
}

.label--brass {
  color: var(--c-brass-ink);
}

.label--light {
  color: var(--c-on-ink-soft);
}

.brass {
  color: var(--c-brass-ink);
}

/* --------------------------------------------------------------------------
   6. Boutons
   Capitales espacées, angles vifs, flèche séparée du texte par une marge :
   jamais collée, elle glisse légèrement au survol.
   -------------------------------------------------------------------------- */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.85rem;
  padding: 0.95rem 1.6rem;
  border: 1px solid transparent;
  border-radius: 0;
  font-size: var(--t-xs);
  font-weight: 500;
  letter-spacing: var(--ls-caps-tight);
  line-height: 1;
  text-transform: uppercase;
  text-decoration: none;
  transition: background-color 0.25s ease, color 0.25s ease, border-color 0.25s ease;
}

.btn .arrow {
  transition: transform 0.25s ease;
}

.btn:hover .arrow {
  transform: translateX(0.25rem);
}

.btn--sm {
  padding: 0.7rem 1.2rem;
}

.btn--block {
  display: flex;
  width: 100%;
}

.btn--solid {
  background-color: var(--c-beige-btn);
  color: var(--c-ink);
}

.btn--solid:hover {
  background-color: #fff;
}

.btn--outline-brass {
  background-color: transparent;
  color: var(--c-on-ink);
  border-color: var(--c-line-brass);
}

.btn--outline-brass:hover {
  background-color: rgba(176, 141, 63, 0.14);
  border-color: var(--c-brass);
}

.btn--outline-ink {
  background-color: transparent;
  color: var(--c-ink);
  border-color: var(--c-ink);
}

.btn--outline-ink:hover {
  background-color: var(--c-ink);
  color: var(--c-on-ink);
}

/* --------------------------------------------------------------------------
   7. En-tête
   Barre fixe posée par-dessus le hero : fond noir translucide et flou
   d'arrière-plan, pour que l'image défile visiblement dessous.
   -------------------------------------------------------------------------- */

.site-header {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 50;
  /* 0,8 plutôt que 0,55 : Safari échantillonne le haut de la page pour
     teinter la barre d'état, il lui faut un noir franc. Le verre dépoli
     reste lisible, la page défile toujours visiblement dessous. */
  background-color: rgba(18, 17, 16, 0.8);
  -webkit-backdrop-filter: blur(14px) saturate(1.2);
  backdrop-filter: blur(14px) saturate(1.2);
  border-bottom: 1px solid var(--c-line-ink);
  color: var(--c-on-ink);
  /* Le fond de la barre remonte sous l'encoche, son contenu reste dessous. */
  padding-top: var(--safe-top);
}

/* La bande de l'encoche est peinte en noir plein, sans translucidité : le
   verre dépoli à 0,8 y laissait encore transparaître le fond de page. */
.site-header::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: var(--safe-top);
  background-color: var(--c-ink);
}

/* Hors accueil, la barre repose sur le crème et non sur une photo sombre : à
   0,55 son lettrage clair et sa navigation tombaient sous le seuil de
   contraste. La teinte est donc renforcée, mais elle reste translucide et le
   flou reste actif : la page défile visiblement dessous. */
.page-inner .site-header {
  background-color: rgba(18, 17, 16, 0.82);
}

@supports not (backdrop-filter: blur(1px)) {
  .page-inner .site-header {
    background-color: rgba(18, 17, 16, 0.94);
  }
}

/* Repli sans backdrop-filter : l'opacité monte, sinon le texte de la barre
   passe sur l'image du hero. */
@supports not (backdrop-filter: blur(1px)) {
  .site-header {
    background-color: rgba(18, 17, 16, 0.94);
  }
}

.site-header__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  min-height: var(--header-h);
  padding-inline: clamp(1.25rem, 3vw, 2.5rem);
  padding-block: 0.5rem;
}

.brand {
  display: inline-flex;
  flex: none;
  text-decoration: none;
}

.brand img {
  display: block;
  width: auto;
  height: 3.25rem;
  /* Le lettrage « STRYK » du logo est clair. Posé sur la barre translucide,
     au-dessus d'une zone lumineuse du hero, il perdait tout contraste et
     seul le symbole doré restait lisible. L'ombre portée le détache de
     n'importe quel fond sans toucher au dessin, à ses proportions ni à ses
     couleurs. */
  filter:
    drop-shadow(0 1px 2px rgba(0, 0, 0, 0.75))
    drop-shadow(0 0 10px rgba(0, 0, 0, 0.5));
}

/* Navigation et bouton forment un seul groupe, poussé contre le bord droit :
   le logo tient le bord gauche, tout le reste est à droite. */
.site-header__right {
  display: flex;
  align-items: center;
  gap: clamp(1.5rem, 3vw, 2.75rem);
}

.site-nav {
  display: none;
}

.site-nav__list {
  display: flex;
  gap: clamp(1.25rem, 2.6vw, 2.5rem);
}

.site-nav__list a {
  font-size: var(--t-xs);
  font-weight: 500;
  letter-spacing: var(--ls-caps-tight);
  text-transform: uppercase;
  text-decoration: none;
  color: var(--c-on-ink-soft);
  transition: color 0.2s ease;
}

.site-nav__list a:hover,
.site-nav__list a.is-active {
  color: var(--c-brass);
}

.site-header__cta {
  display: none;
}

.burger {
  display: grid;
  place-items: center;
  width: 2.75rem;
  height: 2.75rem;
  padding: 0;
  background: none;
  border: 0;
  color: var(--c-on-ink);
}

.burger__bars {
  display: grid;
  gap: 5px;
  width: 22px;
}

.burger__bars i {
  display: block;
  height: 1.4px;
  background-color: currentColor;
}

.menu-mobile {
  padding: 0.5rem clamp(1.25rem, 3vw, 2.5rem) 1.5rem;
  border-top: 1px solid var(--c-line-ink);
}

.menu-mobile__list {
  display: grid;
  gap: 0.25rem;
  margin-bottom: 1.25rem;
}

.menu-mobile__list a {
  display: block;
  padding-block: 0.7rem;
  font-size: var(--t-xs);
  letter-spacing: var(--ls-caps-tight);
  text-transform: uppercase;
  text-decoration: none;
  color: var(--c-on-ink-soft);
}

.menu-mobile__list a:hover {
  color: var(--c-brass);
}

@media (min-width: 62rem) {
  .burger,
  .menu-mobile {
    display: none;
  }

  .site-nav,
  .site-header__cta {
    display: flex;
  }
}

/* --------------------------------------------------------------------------
   8. Hero
   L'image démarre sous la barre fixe et remonte derrière elle : c'est ce qui
   rend le flou visible. Le bas se fond dans le noir du bandeau suivant, sans
   ligne de coupure.
   -------------------------------------------------------------------------- */

.hero {
  position: relative;
  isolation: isolate;
  display: flex;
  align-items: center;
  min-height: min(100svh, 46rem);
  padding-top: calc(var(--header-h) + var(--safe-top) + clamp(2rem, 6vw, 4rem));
  padding-bottom: clamp(5rem, 12vw, 8rem);
  background-color: var(--c-ink);
}

.hero__media,
.hero__veil,
.hero__fade {
  position: absolute;
  inset: 0;
  z-index: -1;
}

.hero__media {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Voile dégradé depuis la gauche : le texte reste lisible, l'image reste
   lisible elle aussi à droite. */
.hero__veil {
  background:
    linear-gradient(to right, rgba(18, 17, 16, 0.82) 0%, rgba(18, 17, 16, 0.55) 45%, rgba(18, 17, 16, 0.15) 80%, rgba(18, 17, 16, 0.05) 100%),
    linear-gradient(to bottom, rgba(18, 17, 16, 0.5) 0%, rgba(18, 17, 16, 0) 35%);
}

/* Le raccord avec le bandeau noir. Il descend jusqu'au noir plein, donc aucun
   bord net n'apparaît entre les deux sections. */
.hero__fade {
  top: auto;
  height: 45%;
  background: linear-gradient(to bottom, rgba(18, 17, 16, 0) 0%, rgba(18, 17, 16, 0.75) 60%, var(--c-ink) 100%);
}

.hero__inner {
  width: 100%;
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: var(--gutter);
  color: var(--c-on-ink);
}

.hero__title {
  max-width: 14ch;
  margin-top: 1.1rem;
  font-size: clamp(1.9rem, 3.6vw, 3rem);
  line-height: 1.16;
  letter-spacing: 0.02em;
  text-transform: uppercase;
}

/* Sous 48rem, la borne basse du clamp ci-dessus était atteinte d'emblée et le
   titre occupait toute la largeur. Échelle propre au mobile, qui rejoint la
   précédente au point de rupture. */
@media (max-width: 47.999rem) {
  .hero__title {
    font-size: clamp(1.5rem, 6.2vw, 1.9rem);
  }

  .hero__lede {
    font-size: var(--t-sm);
  }
}

.hero__lede {
  max-width: 34rem;
  margin-top: 1.35rem;
  color: var(--c-on-ink-soft);
}

.hero .btn {
  margin-top: 2.25rem;
}

/* --------------------------------------------------------------------------
   9. Bandeau des trois étapes
   Fond noir, trois colonnes séparées par de fins traits verticaux. C'est la
   seule numérotation du site, et elle est justifiée : c'est une séquence.
   -------------------------------------------------------------------------- */

.steps-band {
  /* Moins de marge haute que basse : le bandeau prolonge le fondu du hero,
     les étapes viennent donc au contact de celui-ci. */
  padding-block: clamp(1.25rem, 2.5vw, 2rem) clamp(2.75rem, 6vw, 4rem);
  background-color: var(--c-ink);
  color: var(--c-on-ink-soft);
}

.steps {
  display: grid;
  gap: 0;
}

.step {
  padding: clamp(1.5rem, 4vw, 2rem) clamp(1rem, 3vw, 2rem);
  text-align: center;
  border-top: 1px solid var(--c-line-ink);
}

.step:first-child {
  border-top: 0;
}

.step__number {
  display: block;
  font-family: var(--f-display);
  font-size: var(--t-xl);
  line-height: 1;
  letter-spacing: 0.12em;
  /* L'interlettrage ajoute un blanc après le dernier caractère : on le reprend
     pour que le chiffre reste optiquement centré dans sa colonne. */
  text-indent: 0.12em;
  color: var(--c-brass);
}

.step__title {
  margin-top: 0.9rem;
  font-family: var(--f-body);
  font-size: var(--t-xs);
  font-weight: 500;
  letter-spacing: var(--ls-caps);
  text-transform: uppercase;
  color: var(--c-on-ink);
}

.step p {
  max-width: 26rem;
  margin: 0.55rem auto 0;
  font-size: var(--t-sm);
  line-height: 1.6;
}

@media (min-width: 48rem) {
  .steps {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }

  .step {
    border-top: 0;
    border-left: 1px solid var(--c-line-ink);
  }

  .step:first-child {
    border-left: 0;
  }
}

/* --------------------------------------------------------------------------
   10. Qui sommes-nous
   Deux colonnes : le texte respire dans le conteneur, l'image va jusqu'au
   bord droit de l'écran, comme sur la maquette.
   -------------------------------------------------------------------------- */

.about {
  display: grid;
  align-items: center;
  gap: clamp(2.5rem, 6vw, 4rem);
  padding-block: var(--section-y);
  background-color: var(--c-cream);
}

.about__text {
  padding-inline: var(--gutter);
  /* Aligné sur la colonne de texte du conteneur, pas sur le bord de l'écran. */
  margin-left: auto;
  max-width: calc(var(--container) / 2);
  width: 100%;
}

.about__title {
  margin-top: 1.1rem;
  font-size: clamp(1.75rem, 3.4vw, var(--t-3xl));
}

.about__lede {
  max-width: 34rem;
  margin-top: 1.5rem;
  color: var(--c-muted);
}

.about .btn {
  margin-top: 2rem;
}

.about__media {
  display: block;
  width: 100%;
  height: clamp(20rem, 60vw, 34rem);
  object-fit: cover;
}

@media (min-width: 62rem) {
  .about {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    padding-block: 0;
  }

  .about__text {
    padding-block: var(--section-y);
    padding-right: clamp(2rem, 5vw, 5rem);
  }

  .about__media {
    height: clamp(30rem, 46vw, 44rem);
  }
}

/* --------------------------------------------------------------------------
   11. Services
   Six cartes de même facture : photo en haut, bloc blanc dessous avec un
   pictogramme au trait et l'intitulé en capitales serif espacées. La
   description n'apparaît qu'au survol, en surimpression sur la photo.
   -------------------------------------------------------------------------- */

.services {
  /* Marge haute réduite : au-dessus, la photo de la section précédente vient
     déjà jusqu'au bord, l'écart paraissait plus grand que celui du bas. */
  padding-block: calc(var(--section-y) * 0.78) var(--section-y);
  background-color: var(--c-cream);
}

.services__eyebrow,
.services__title {
  text-align: center;
}

.services__title {
  margin-top: 0.9rem;
  font-size: clamp(1.75rem, 3.4vw, var(--t-3xl));
}

.service-list {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(0.75rem, 1.6vw, 1.25rem);
  margin-top: clamp(2.5rem, 5vw, 3.5rem);
}

.service {
  display: flex;
  flex-direction: column;
  background-color: #fff;
  border: 1px solid var(--c-line);
}

/* C'est ce cadre qui rogne le zoom, et non la carte : sinon la photo
   agrandie déborderait sur le bloc blanc, sous le bord du voile. */
.service__visual {
  position: relative;
  overflow: hidden;
  aspect-ratio: 4 / 3;
}

.service__visual img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 0.5s ease;
}

.service__desc {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1rem;
  background-color: rgba(18, 17, 16, 0.78);
  color: var(--c-on-ink);
  font-size: var(--t-sm);
  line-height: 1.55;
  text-align: center;
  text-wrap: balance;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.3s ease;
}

.service:hover .service__visual img,
.service:focus-within .service__visual img {
  transform: scale(1.06);
}

.service:hover .service__desc,
.service:focus-within .service__desc {
  opacity: 1;
}

.service__label {
  display: flex;
  flex: 1;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.6rem;
  padding: clamp(0.9rem, 2vw, 1.25rem) 0.75rem;
  text-align: center;
}

.service__icon {
  width: 1.5rem;
  height: 1.5rem;
  color: var(--c-brass);
}

.service__label h3 {
  font-size: var(--t-xs);
  letter-spacing: var(--ls-caps-tight);
  line-height: 1.4;
  text-transform: uppercase;
}

@media (min-width: 48rem) {
  .service-list {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

@media (min-width: 75rem) {
  .service-list {
    grid-template-columns: repeat(6, minmax(0, 1fr));
  }

  .service__label {
    padding-inline: 0.5rem;
  }
}

/* --------------------------------------------------------------------------
   12. Zone d'intervention
   Le trait de côte et les quatre villes sont projetés depuis leurs
   coordonnées réelles. Seul l'océan est en aplat : la terre reste
   transparente, c'est le fond de la section qui la porte.
   -------------------------------------------------------------------------- */

.zone {
  /* La section suit désormais l'aplat noir du CTA : il lui faut une marge
     haute, là où elle venait auparavant juste après les cartes de services. */
  padding-block: var(--section-y);
  background-color: var(--c-cream);
}

.zone__inner {
  display: grid;
  gap: clamp(2rem, 4vw, 3.5rem);
  align-items: center;
}

.zone__title {
  margin-top: 1.1rem;
  font-size: clamp(1.5rem, 2.8vw, var(--t-2xl));
}

.zone__lede {
  max-width: 30rem;
  margin-top: 1.25rem;
  color: var(--c-muted);
}

.zone-map-figure {
  margin: 0;
  border: 1px solid var(--c-line);
}

.zone-map {
  display: block;
  width: 100%;
  height: auto;
}

.zone-map__sea {
  fill: var(--c-ink);
  fill-opacity: 0.05;
}

.zone-map__coast {
  fill: none;
  stroke: var(--c-brass);
  stroke-width: 1.5;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.zone-map__halo {
  fill: var(--c-brass);
  fill-opacity: 0.2;
}

.zone-map__pin {
  fill: var(--c-brass-ink);
}

/* Le corps est exprimé en unités du viewBox : il est donc multiplié par le
   rapport entre la largeur rendue de la carte et ses 820 unités. Ce rapport
   varie beaucoup selon la largeur d'écran, d'où ces paliers, qui gardent un
   texte rendu autour de 12px partout. */
.zone-map__label {
  fill: var(--c-ink);
  font-family: var(--f-body);
  font-size: 30px;
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

@media (min-width: 28rem) {
  .zone-map__label {
    font-size: 24px;
  }
}

@media (min-width: 44rem) {
  .zone-map__label {
    font-size: 17px;
  }
}

@media (min-width: 62rem) {
  .zone__inner {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.25fr);
  }

  .zone-map__label {
    font-size: 21px;
  }
}

/* --------------------------------------------------------------------------
   13. Parlons de votre bien
   Photo à fond perdu à gauche, aplat noir à droite.
   -------------------------------------------------------------------------- */

.cta {
  display: grid;
}

/* Le cadre porte la hauteur, jamais l'image. Laissée seule, la photo, très
   verticale, imposait sa hauteur naturelle à la rangée : 1260px sur desktop,
   et toute réduction restait sans effet. */
.cta__visual {
  height: clamp(20rem, 64vw, 26rem);
}

.cta__media {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* Photo au format paysage : le cadre en rogne surtout les côtés, le sujet
     reste entier. Cadrage neutre. */
  object-position: center;
}

.cta__panel {
  display: flex;
  align-items: center;
  padding-block: var(--section-y);
  background-color: var(--c-ink);
  color: var(--c-on-ink-soft);
}

.cta__inner {
  width: 100%;
  padding-inline: var(--gutter);
  max-width: calc(var(--container) / 2);
}

.cta__title {
  margin-top: 1.1rem;
  font-size: clamp(1.75rem, 3.4vw, var(--t-3xl));
  color: var(--c-on-ink);
}

.cta__lede {
  max-width: 30rem;
  margin-top: 1.35rem;
}

.cta .btn {
  margin-top: 2rem;
}

@media (min-width: 62rem) {
  .cta {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  }

  /* La photo est sortie du flux : c'est le panneau noir d'en face qui fixe la
     hauteur de la rangée, et le cadre s'y étire. */
  .cta__visual {
    position: relative;
    height: auto;
    min-height: clamp(26rem, 40vw, 36rem);
  }

  .cta__media {
    position: absolute;
    inset: 0;
  }

  .cta__inner {
    /* Le bloc de texte est centré dans l'aplat, non plaqué contre son bord. */
    margin-inline: auto;
    padding-inline: clamp(2.5rem, 5vw, 5rem);
  }
}

/* --------------------------------------------------------------------------
   14. Pied de page
   Beige, un ton plus soutenu que le crème de la page, avec un filet haut.
   -------------------------------------------------------------------------- */

.site-footer {
  padding-block: clamp(1.75rem, 3.5vw, 2.5rem) 1.25rem;
  background-color: var(--c-ink);
  color: var(--c-on-ink-soft);
}

.site-footer__inner,
.site-footer__details,
.site-footer__bottom {
  width: 100%;
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.site-footer__inner {
  display: grid;
  gap: 1.75rem;
  align-items: center;
}

.site-footer__brand img {
  display: block;
  width: auto;
  height: clamp(3.75rem, 8vw, 4.5rem);
}

.site-footer__nav {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem 1.5rem;
}

.site-footer__nav a {
  font-size: var(--t-sm);
  text-decoration: none;
  transition: color 0.2s ease;
}

.site-footer__nav a:hover {
  color: var(--c-brass);
}

.site-footer__values {
  font-size: var(--t-xs);
  font-weight: 500;
  letter-spacing: var(--ls-caps);
  text-transform: uppercase;
  color: var(--c-brass-ink);
}

.site-footer__values span {
  margin-inline: 0.35rem;
  opacity: 0.55;
}

.site-footer__details {
  display: grid;
  gap: 1.5rem;
  margin-top: clamp(1.5rem, 3vw, 2rem);
  padding-top: clamp(1.5rem, 3vw, 2rem);
  border-top: 1px solid var(--c-line-ink);
}

.site-footer__col .label {
  color: var(--c-brass);
}

.site-footer__col p {
  margin-top: 0.45rem;
  font-size: var(--t-sm);
  /* Une adresse email est un mot insécable : sans cette règle elle impose sa
     largeur à la grille et fait déborder la page sous 360px. */
  overflow-wrap: anywhere;
}

.site-footer__col a {
  color: var(--c-on-ink);
  text-decoration: none;
}

.site-footer__col a:hover {
  color: var(--c-brass);
  text-decoration: underline;
  text-underline-offset: 0.2em;
}

.site-footer__bottom {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem 1.5rem;
  justify-content: space-between;
  margin-top: clamp(1.5rem, 3vw, 2rem);
  padding-top: 1.25rem;
  border-top: 1px solid var(--c-line-ink);
  font-size: var(--t-xs);
  color: var(--c-on-ink-faint);
}

.site-footer__bottom nav {
  display: flex;
  flex-wrap: wrap;
  gap: 1.25rem;
}

.site-footer__bottom a {
  text-decoration: none;
}

.site-footer__bottom a:hover {
  color: var(--c-on-ink);
  text-decoration: underline;
  text-underline-offset: 0.2em;
}

@media (min-width: 48rem) {
  .site-footer__inner {
    grid-template-columns: auto 1fr;
    gap: clamp(1.5rem, 4vw, 3rem);
  }

  /* Quatre colonnes depuis l'ajout d'Instagram. En « auto-fit », elles se
     replient d'elles-mêmes quand la place manque, plutôt que d'écraser les
     adresses. */
  .site-footer__details {
    grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
  }
}

/* --------------------------------------------------------------------------
   15. Barre d'action mobile
   -------------------------------------------------------------------------- */

/* Toute la zone basse est noire, encoche comprise : le fond est porté par la
   barre elle-même, et sa marge basse descend jusqu'au bord de l'écran. */
.action-bar {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 40;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  padding-bottom: var(--safe-bottom);
  background-color: var(--c-ink);
  border-top: 1px solid var(--c-line-ink);
  font-size: var(--t-xs);
  font-weight: 500;
  letter-spacing: var(--ls-caps-tight);
  text-transform: uppercase;
}

.action-bar a {
  padding-block: 1.05rem;
  text-align: center;
  text-decoration: none;
}

.action-bar__call {
  background-color: var(--c-ink);
  color: var(--c-brass);
  /* Le filet sépare les deux moitiés, maintenant qu'elles partagent le même
     fond noir. */
  border-right: 1px solid var(--c-line-brass);
}

.action-bar__whatsapp {
  background-color: var(--c-ink);
  color: var(--c-on-ink);
}

@media (min-width: 48rem) {
  body {
    padding-bottom: 0;
  }

  .action-bar {
    display: none;
  }
}

/* --------------------------------------------------------------------------
   16. Modale de contact
   Élément <dialog> natif : la fermeture par Échap, le piège à focus et
   l'inertie de l'arrière-plan sont pris en charge par le navigateur.
   -------------------------------------------------------------------------- */

.modal {
  width: min(38rem, calc(100vw - 2rem));
  max-height: min(90svh, 52rem);
  padding: 0;
  background-color: var(--c-cream);
  border: 1px solid var(--c-line);
  color: var(--c-ink);
}

.modal::backdrop {
  background-color: rgba(18, 17, 16, 0.65);
  -webkit-backdrop-filter: blur(3px);
  backdrop-filter: blur(3px);
}

.modal__box {
  position: relative;
  display: grid;
  gap: 1.1rem;
  padding: clamp(1.75rem, 4vw, 2.75rem);
}

.modal__close {
  position: absolute;
  top: 0.75rem;
  right: 0.75rem;
  display: grid;
  place-items: center;
  width: 2.25rem;
  height: 2.25rem;
  padding: 0;
  background: none;
  border: 0;
  color: var(--c-muted);
}

.modal__close:hover {
  color: var(--c-ink);
}

.modal__title {
  font-size: clamp(1.5rem, 3vw, var(--t-2xl));
  margin-top: -0.6rem;
}

.modal__aside {
  margin-top: 0.25rem;
  font-size: var(--t-sm);
  color: var(--c-muted);
  text-align: center;
}

.modal__aside a {
  color: var(--c-brass-ink);
  text-underline-offset: 0.2em;
}

.modal__aside span {
  margin-inline: 0.35rem;
}

/* Champs soulignés, sans caisson. */

.field {
  display: grid;
  gap: 0.35rem;
  min-width: 0;
}

.field label {
  font-size: var(--t-xs);
  font-weight: 500;
  letter-spacing: var(--ls-caps-tight);
  text-transform: uppercase;
  color: var(--c-muted);
}

.field .req {
  color: var(--c-brass-ink);
}

.field input,
.field select,
.field textarea {
  width: 100%;
  padding: 0.55rem 0;
  background-color: transparent;
  border: 0;
  /* 3,4:1 sur le crème : au-dessus du seuil exigé pour un contour de champ. */
  border-bottom: 1px solid #9c9387;
  border-radius: 0;
  /* 16px au minimum, et pas la taille du texte courant : en dessous de ce
     seuil, Safari sur iOS zoome la page dès qu'un champ prend le focus, et
     n'en ressort pas seul. C'est la seule façon de l'éviter sans interdire au
     visiteur de zoomer lui-même. */
  font-size: 1rem;
  transition: border-color 0.2s ease;
}

.field textarea {
  resize: vertical;
}

.field input:focus,
.field select:focus,
.field textarea:focus {
  border-bottom-color: var(--c-brass-ink);
}

.field input[aria-invalid="true"],
.field select[aria-invalid="true"],
.field textarea[aria-invalid="true"] {
  border-bottom-color: var(--c-error);
}

.field-row {
  display: grid;
  gap: 1.1rem;
}

.form__status {
  padding: 0.85rem 1.1rem;
  border-left: 3px solid var(--c-muted);
  background-color: rgba(18, 17, 16, 0.05);
  font-size: var(--t-sm);
  line-height: 1.55;
}

.form__status[data-tone="success"] {
  border-left-color: var(--c-brass-ink);
}

.form__status[data-tone="error"] {
  border-left-color: var(--c-error);
  color: var(--c-error);
}

.form__status a {
  color: inherit;
}

@media (min-width: 30rem) {
  .field-row {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

/* --------------------------------------------------------------------------
   17. Pages légales
   -------------------------------------------------------------------------- */

/* Le corps de page étant sombre, c'est cette section qui porte le crème sur
   les pages sans bande pleine largeur. Elle s'étend donc d'un bord à l'autre,
   et ce sont ses enfants qui gardent la mesure de lecture. */
.legal {
  max-width: none;
  padding-top: calc(var(--header-h) + var(--safe-top) + var(--section-y));
  padding-bottom: var(--section-y);
  background-color: var(--c-cream);
}

.legal > * {
  max-width: 48rem;
  margin-inline: auto;
}

.legal h1 {
  font-size: clamp(1.9rem, 4vw, var(--t-3xl));
}

.legal h2 {
  margin-top: 2.5rem;
  font-size: var(--t-xl);
}

.legal p,
.legal li {
  margin-top: 0.9rem;
  color: var(--c-muted);
}

.legal ul {
  list-style: disc;
  padding-left: 1.25rem;
}

.legal a {
  color: var(--c-brass-ink);
  text-underline-offset: 0.2em;
}

/* Page équipe : deux portraits en vis-à-vis. */

.team__lede {
  margin-top: 1.25rem;
  font-size: var(--t-lg);
  color: var(--c-muted);
}

.team {
  display: grid;
  gap: clamp(2rem, 5vw, 3.5rem);
  margin-top: clamp(2.5rem, 5vw, 3.5rem);
}

.team__member h2 {
  margin-top: 1.25rem;
  font-size: var(--t-xl);
}

.team__member .label {
  margin-top: 0.35rem;
}

/* Emplacement des portraits, à remplacer par une balise <img> en WebP de
   800px de large, avec width, height et un alt décrivant la personne. */
.team__photo {
  display: grid;
  place-items: center;
  aspect-ratio: 4 / 5;
  background-color: var(--c-beige-footer);
  border: 1px solid var(--c-line);
  color: var(--c-muted);
  font-size: var(--t-xs);
  letter-spacing: var(--ls-caps-tight);
  text-transform: uppercase;
}

.team__heading {
  margin-top: clamp(2.5rem, 5vw, 3.5rem);
}

@media (min-width: 48rem) {
  .team {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

/* --------------------------------------------------------------------------
   18. Apparition au scroll

   Trois sections seulement : le bandeau des étapes, les services et les
   secteurs d'intervention. Les autres entrent dans leur état normal.

   L'état d'arrivée est exactement l'état par défaut du composant : opacité
   pleine et aucune transformation. L'animation n'est qu'une façon d'y venir,
   elle ne laisse aucune trace sur la forme finale.

   Seules l'opacité et la translation sont animées, les deux propriétés que le
   compositeur traite sans recalculer la mise en page : le défilement reste
   fluide. Aucun « will-change » n'est posé, il créerait un bloc conteneur et
   une couche permanente pour un gain nul à cette échelle.
   -------------------------------------------------------------------------- */

.js [data-reveal] {
  opacity: 0;
  transform: translateY(1.125rem);
}

.js [data-reveal-root].is-revealed [data-reveal] {
  opacity: 1;
  transform: none;
  /* Courbe sortante : départ franc, arrivée amortie. C'est elle qui donne le
     caractère posé plutôt que mécanique. */
  transition:
    opacity 0.72s cubic-bezier(0.22, 1, 0.36, 1) var(--reveal-delay, 0ms),
    transform 0.72s cubic-bezier(0.22, 1, 0.36, 1) var(--reveal-delay, 0ms);
}

/* La carte des secteurs vient d'un peu plus bas et sur une course un peu plus
   longue que le texte qui lui fait face : c'est ce décalage qui donne la
   profondeur, sans rien changer à sa position finale. */
.js .zone-map-figure[data-reveal] {
  transform: translateY(2.25rem);
}

/* La carte prend une course plus longue que les autres blocs : elle est le
   sujet de la section, elle mérite d'être vue arriver. */
.js [data-reveal-root].is-revealed .zone-map-figure[data-reveal] {
  transition-duration: 0.95s;
}

/* --------------------------------------------------------------------------
   19. Mouvement
   Le mouvement répond à une action de l'utilisateur et rien d'autre. Sous
   prefers-reduced-motion, il est neutralisé.
   -------------------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }

  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }

  .service:hover .service__visual img,
  .service:focus-within .service__visual img {
    transform: none;
  }

  .btn:hover .arrow {
    transform: none;
  }

  /* Les blocs animés sont livrés dans leur état final, sans transition. */
  .js [data-reveal],
  .js .zone-map-figure[data-reveal] {
    opacity: 1;
    transform: none;
    transition: none;
  }
}
