/* ==========================================================================
   BMServices — Base : reset, éléments, layout, utilitaires, révélations
   ========================================================================== */

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

* { margin: 0; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  scroll-padding-top: calc(var(--nav-h) + var(--safe-top) + 18px);
  /* Sur iPhone, tirer la page vers le bas découvre le fond de <html>.
     Sans cette ligne c'est celui de <body> — blanc — qui apparaît au-dessus
     d'un en-tête sombre : la bande blanche. Le haut comme le bas du site
     étant sombres, cette couleur convient aux deux extrémités. */
  background: var(--ink-900);
}

body {
  font-family: var(--font-body);
  font-size: var(--fs-base);
  line-height: var(--lh-normal);
  color: var(--text);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  /* « clip » coupe le débordement horizontal SANS créer de conteneur de
     défilement : position:sticky continue donc de fonctionner (encadré
     latéral des pages services). « hidden » reste le repli des vieux
     navigateurs. */
  overflow-x: hidden;
  overflow-x: clip;
  min-height: 100svh;
  /* Évite le rectangle gris au tapotement sur Android */
  -webkit-tap-highlight-color: transparent;
}


img,
picture,
svg,
video {
  display: block;
  max-width: 100%;
  height: auto;
}

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

button { background: none; border: 0; cursor: pointer; }

a {
  color: var(--accent);
  text-decoration: none;
  transition: color var(--t-fast) var(--ease-out);
}

a:hover { color: var(--brand-500); }
.theme-dark a:hover { color: var(--aqua-300); }

p, li { text-wrap: pretty; }

/* --- Titres --------------------------------------------------------------- */
h1, h2, h3, h4, h5 {
  font-family: var(--font-display);
  font-weight: 700;
  line-height: var(--lh-tight);
  letter-spacing: -0.025em;
  color: var(--text);
  text-wrap: balance;
}

h1 { font-size: var(--fs-4xl); }
h2 { font-size: var(--fs-3xl); }
h3 { font-size: var(--fs-xl); letter-spacing: -0.018em; }
h4 { font-size: var(--fs-lg); letter-spacing: -0.014em; line-height: var(--lh-snug); }

/* --- Accessibilité -------------------------------------------------------- */
:where(a, button, input, textarea, select, summary, [tabindex]):focus-visible {
  outline: 3px solid var(--focus);
  outline-offset: 3px;
  border-radius: var(--r-xs);
}

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

.skip-link {
  position: fixed;
  top: 0; left: 50%;
  transform: translate(-50%, -130%);
  z-index: 999;
  padding: .75rem 1.4rem;
  background: var(--brand-600);
  color: #fff;
  font-weight: 600;
  border-radius: 0 0 var(--r-md) var(--r-md);
  transition: transform var(--t-base) var(--ease-out);
}
.skip-link:focus-visible { transform: translate(-50%, 0); color: #fff; }

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

.container--narrow { max-width: var(--container-narrow); }

.section {
  position: relative;
  padding-block: var(--section-y);
  background: var(--bg);
}

.section--soft { background: var(--bg-soft); }
/* Une section de service, pas de contenu : elle n'a pas besoin des mêmes
   respirations que les autres. */
.section--mince {
  padding-top: clamp(2rem, 1.4rem + 2vw, 3rem);
  padding-bottom: clamp(2rem, 1.4rem + 2vw, 3rem);
}

.section--dark {
  background: var(--grad-ink);
  color: var(--text);
  overflow: hidden;
}

/* Grilles utilitaires : auto-fit, jamais de débordement */
.grid { display: grid; gap: var(--sp-5); }
.grid--2 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 20rem), 1fr)); }
.grid--3 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 17rem), 1fr)); }
.grid--4 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 14rem), 1fr)); }

.stack > * + * { margin-top: var(--sp-4); }

/* --- En-tête de section --------------------------------------------------- */
.section-head {
  max-width: 46rem;
  margin-bottom: clamp(2.25rem, 1.6rem + 2.6vw, 3.75rem);
}
.section-head--center { margin-inline: auto; text-align: center; }

.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: .55rem;
  font-family: var(--font-display);
  font-size: var(--fs-xs);
  font-weight: 600;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--accent);
  margin-bottom: var(--sp-3);
}
.eyebrow::before {
  content: "";
  width: 26px; height: 2px;
  border-radius: 2px;
  background: var(--grad-brand);
}
.section--dark .eyebrow::before,
.page-hero .eyebrow::before { background: linear-gradient(90deg, var(--aqua-400), transparent); }

.section-lead {
  margin-top: var(--sp-4);
  font-size: var(--fs-md);
  color: var(--text-muted);
  max-width: 44rem;
}
.section-head--center .section-lead { margin-inline: auto; }

.text-gradient {
  background: var(--grad-brand);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}
.hero .text-gradient,
.page-hero .text-gradient,
.centered-page .text-gradient,
.section--dark .text-gradient,
.theme-dark .text-gradient {
  background: var(--grad-text);
  -webkit-background-clip: text;
  background-clip: text;
}

/* --- Décors ambiants ------------------------------------------------------ */
/* Tant que le menu mobile est ouvert, le décor ne bouge plus : le voile n'a
   alors plus rien à recomposer derrière lui. */
.is-menu .glow,
.is-menu .hero__ring,
.is-menu .radar__sweep,
.is-menu .marquee__track { animation-play-state: paused; }

.glow {
  position: absolute;
  border-radius: 50%;
  filter: blur(90px);
  opacity: .5;
  pointer-events: none;
  z-index: 0;
  /* Le halo ne peut rien déborder ni déclencher de recalcul ailleurs */
  contain: strict;
}

/* Un flou de 90 px sur une surface de 700 px doit être recalculé à chaque
   image : c'est ce qui fait ramer et chauffer les téléphones. On l'allège
   nettement sur petit écran — visuellement la différence est imperceptible. */
@media (max-width: 47.99rem) {
  .glow { filter: blur(42px); }
}

.section > .container { position: relative; z-index: 1; }

.grid-lines {
  position: absolute;
  inset: 0;
  pointer-events: none;
  background-image:
    linear-gradient(to right, rgba(255, 255, 255, .045) 1px, transparent 1px),
    linear-gradient(to bottom, rgba(255, 255, 255, .045) 1px, transparent 1px);
  background-size: 62px 62px;
  mask-image: radial-gradient(ellipse 78% 62% at 50% 38%, #000 30%, transparent 100%);
  -webkit-mask-image: radial-gradient(ellipse 78% 62% at 50% 38%, #000 30%, transparent 100%);
}

/* ==========================================================================
   Révélations au scroll (pilotées par IntersectionObserver, cf. ui.js)
   ========================================================================== */
[data-reveal] {
  opacity: 0;
  transform: translate3d(0, 26px, 0);
  transition:
    opacity 700ms var(--ease-out),
    transform 780ms var(--ease-spring);
  transition-delay: var(--reveal-delay, 0ms);
}
[data-reveal="left"]  { transform: translate3d(-32px, 0, 0); }
[data-reveal="right"] { transform: translate3d(32px, 0, 0); }
[data-reveal="scale"] { transform: scale(.94); }
[data-reveal="clip"] {
  opacity: 1;
  transform: none;
  clip-path: inset(0 100% 0 0);
  transition: clip-path 900ms var(--ease-in-out);
}
/* Posé par ui.js sur les titres découpés : l'animation est portée par les lignes */
[data-reveal="lines"] { opacity: 1; transform: none; }

.is-revealed[data-reveal] {
  opacity: 1;
  transform: translate3d(0, 0, 0) scale(1);
}
.is-revealed[data-reveal="clip"] { clip-path: inset(0 0 0 0); }

/* Révélation ligne par ligne d'un texte (spans injectés par ui.js) */
.reveal-lines { display: block; }
.reveal-lines .line-mask {
  display: block;
  overflow: hidden;
  padding-block: .06em;
}
.reveal-lines .line-inner {
  display: block;
  transform: translateY(105%);
  transition: transform 900ms var(--ease-spring);
  transition-delay: var(--line-delay, 0ms);
}
.is-revealed .reveal-lines .line-inner,
.reveal-lines.is-revealed .line-inner { transform: translateY(0); }

/* ==========================================================================
   Respect de prefers-reduced-motion : le contenu reste 100 % accessible
   ========================================================================== */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }

  *,
  *::before,
  *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
    scroll-behavior: auto !important;
  }

  [data-reveal],
  .is-revealed[data-reveal] {
    opacity: 1 !important;
    transform: none !important;
    clip-path: none !important;
  }
  .reveal-lines .line-inner { transform: none !important; }
}

/* --- Impression ----------------------------------------------------------- */
@media print {
  .site-header, .mobile-cta, .to-top, .site-footer nav, .lightbox { display: none !important; }
  body { color: #000; background: #fff; }
  [data-reveal] { opacity: 1 !important; transform: none !important; }
}


/* ==========================================================================
   Rendu différé des sections hors écran
   Le navigateur ne calcule la mise en page d'une section qu'au moment où
   elle approche de l'écran. Sur un téléphone, cela raccourcit nettement le
   premier affichage d'une page longue.
   ========================================================================== */
/* Volontairement limité au pied de page : appliquer ce réglage aux sections
   fausserait l'atterrissage des liens d'ancre (#devis, #faq…), qui sont
   utilisés par la navigation du site. */
.site-footer {
  content-visibility: auto;
  contain-intrinsic-size: auto 620px;
}
