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

html { -webkit-text-size-adjust: 100%; }

body {
  background: var(--bg);
  color: var(--fg);
  font-family: var(--font-sans);
  font-size: var(--fs-body);
  line-height: 1.65;
  font-weight: 400;
  font-variant-numeric: tabular-nums;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
  scroll-behavior: smooth;
}

h1, h2, h3 {
  font-weight: 600;
  line-height: 1.04;
  letter-spacing: -0.035em;
  text-wrap: balance;
}

h1 { font-size: var(--fs-h1); }
h2 { font-size: var(--fs-h2); }
h3 { font-size: var(--fs-h3); font-weight: 500; letter-spacing: -0.015em; line-height: 1.3; }

h1 em, h2 em, h3 em { font-style: normal; color: var(--fg-muted); }

p { text-wrap: pretty; }

a { color: inherit; text-decoration: none; }
img { display: block; max-width: 100%; height: auto; }

/* Chaque photographie est servie en WebP, avec le JPEG en repli. <picture>
   étant en ligne par défaut, il casserait le `height: 100%` des images qui
   remplissent un conteneur (hero, tuiles, pleine largeur) : il doit donc se
   comporter exactement comme l'image qu'il enveloppe. */
picture { display: contents; }

/* Primitives de mise en page */
.container {
  width: 100%;
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.section { padding-block: var(--sp-6); }
.section + .section { border-top: 1px solid var(--rule); }

/* Étiquette de section. Trois emplois maximum sur tout le site. */
.eyebrow {
  font-size: var(--fs-label);
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--fg-faint);
}

.lede {
  font-size: clamp(1.0625rem, 1.4vw, 1.3125rem);
  line-height: 1.55;
  color: var(--fg-muted);
  max-width: 62ch;
}

/* Engagement commercial discret, pas une étiquette de section : pas de
   majuscules forcées, pas d'accent, juste un ton en retrait. */
.pledge {
  font-size: var(--fs-small);
  color: var(--fg-muted);
  margin-top: var(--sp-2);
}

/* Deux paragraphes d'affilée : sans cette règle ils se collent, la remise à
   zéro des marges en tête de feuille ne laissant aucun blanc entre eux. */
.lede + .lede, .lede + p, p + .lede { margin-top: var(--sp-2); }

/* Bloc court sur colonne étroite. Casse de phrase, plus de majuscules forcées. */
.spec-copy {
  font-size: var(--fs-small);
  line-height: 1.6;
  max-width: 52ch;
  color: var(--fg-muted);
}

/* Grain : rompt la platitude du vectoriel pur. */
body::after {
  content: '';
  position: fixed;
  inset: 0;
  z-index: 9999;
  pointer-events: none;
  opacity: 0.035;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)'/%3E%3C/svg%3E");
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    transition-duration: 0.01ms !important;
    /* Le décalage de groupe ([data-reveal] > ... :nth-child) ne doit pas
       laisser un élément invisible en attente de son tour : motion.js
       marque déjà tout is-visible au chargement quand reduced est vrai,
       ce override neutralise le délai de cascade qui resterait sinon. */
    transition-delay: 0ms !important;
  }
  html { scroll-behavior: auto; }
}
