/* ==========================================================================
   WHISP — Reset, typographie de base et primitives de mise en page.
   ========================================================================== */

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

* {
  margin: 0;
}

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  scroll-padding-top: 6rem;

  /* `clip` et non `hidden` : les décors qui débordent sont rognés sans créer
     de conteneur de défilement — le header `sticky` continue de fonctionner. */
  overflow-x: clip;
}

@supports not (overflow-x: clip) {
  html,
  body { overflow-x: hidden; }
}

body {
  min-height: 100dvh;
  background-color: var(--bg);
  color: var(--text);
  font-family: var(--font-sans);
  font-size: var(--text-md);
  line-height: var(--leading-normal);
  letter-spacing: var(--tracking-normal);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

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

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

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

a {
  color: inherit;
  text-decoration: none;
}

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

:focus-visible {
  outline: 3px solid var(--blue-400);
  outline-offset: 2px;
  border-radius: var(--radius-xs);
}

::selection {
  background: var(--blue-100);
  color: var(--blue-900);
}

/* --------------------------------------------------------------- Titres
   Material privilégie la taille à la graisse : les titres restent en 400/500. */
h1, h2, h3, h4, h5 {
  font-family: var(--font-display);
  font-weight: 400;
  line-height: var(--leading-tight);
  letter-spacing: var(--tracking-tighter);
  text-wrap: balance;
  color: var(--text);
}

h1 { font-size: var(--text-4xl); }
h2 { font-size: var(--text-3xl); }
h3 { font-size: var(--text-xl); font-weight: 500; letter-spacing: var(--tracking-tight); }
h4 { font-size: var(--text-lg); font-weight: 500; }

p { text-wrap: pretty; }

strong { font-weight: 500; color: var(--text); }

code {
  font-family: var(--font-mono);
  font-size: 0.9em;
}

/* ==========================================================================
   Primitives de mise en page
   ========================================================================== */

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

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

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

.section--tight { padding-block: clamp(3rem, 6vw, 5rem); }

/* Bandeau gris très clair : c'est ce qui rythme les pages Google, plutôt
   que des séparateurs. */
.section--tinted {
  background-color: var(--bg-subtle);
}

.rule {
  height: 1px;
  border: 0;
  background-color: var(--border);
}

/* ---------------------------------------------------------- En-tête de section */
.section-head {
  max-width: 44rem;
  margin-bottom: var(--space-8);
}

.section-head--center {
  margin-inline: auto;
  text-align: center;
}

.section-head p {
  margin-top: var(--space-4);
  color: var(--text-secondary);
  font-size: var(--text-md);
  line-height: var(--leading-relaxed);
}

/* Sur-titre : petite capitale bleue, sans filet décoratif. */
.eyebrow {
  display: inline-block;
  margin-bottom: var(--space-3);
  color: var(--brand);
  font-size: var(--text-sm);
  font-weight: 500;
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
}

/* ==========================================================================
   Utilitaires
   ========================================================================== */

.text-muted     { color: var(--text-muted); }
.text-secondary { color: var(--text-secondary); }
.text-center    { text-align: center; }
.text-balance   { text-wrap: balance; }
.text-sm        { font-size: var(--text-sm); }

/* Dégradé « quatre couleurs » réservé à un seul segment de titre par page. */
.text-gradient {
  background-image: linear-gradient(
    92deg,
    var(--blue-500) 0%,
    var(--blue-400) 30%,
    var(--green-400) 62%,
    var(--yellow-400) 100%
  );
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

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

.stack   { display: flex; flex-direction: column; }
.cluster { display: flex; flex-wrap: wrap; align-items: center; }
.gap-2 { gap: var(--space-2); }
.gap-3 { gap: var(--space-3); }
.gap-4 { gap: var(--space-4); }
.gap-5 { gap: var(--space-5); }
.gap-6 { gap: var(--space-6); }

/* ==========================================================================
   Décor
   Un unique voile coloré très dilué en haut de page — pas de halo lumineux,
   pas de grain : le fond reste franchement blanc.
   ========================================================================== */

.wash {
  position: absolute;
  inset: 0 0 auto;
  height: 34rem;
  z-index: 0;
  pointer-events: none;
  background-image:
    radial-gradient(ellipse 46% 60% at 14% 0%, var(--wash-a), transparent 66%),
    radial-gradient(ellipse 40% 52% at 84% 6%, var(--wash-b), transparent 68%),
    radial-gradient(ellipse 34% 44% at 52% 0%, var(--wash-c), transparent 70%);
}

/* ==========================================================================
   Apparition au défilement.
   Masquage appliqué uniquement si JS a pris la main : la page reste lisible
   sans JavaScript.
   ========================================================================== */

/* `--lift` permet à un composant (carte survolée) de composer son propre
   décalage avec celui de l'apparition, sans écraser la règle `transform`. */
.js .reveal {
  opacity: 0;
  transform: translateY(14px);
  transition:
    opacity var(--dur-slow) var(--ease),
    transform var(--dur-slow) var(--ease-emphasized);
  transition-delay: var(--reveal-delay, 0ms);
  will-change: opacity, transform;
}

.js .reveal.is-visible {
  opacity: 1;
  transform: translateY(var(--lift, 0px));
}

@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;
    scroll-behavior: auto !important;
  }

  .js .reveal { opacity: 1; transform: none; }
}
