/* ==========================================================================
   DARK-E — Didier Verheyden
   Le logo est coupé par une ligne horizontale : au-dessus noir sur blanc,
   au-dessous blanc sur noir. Tout le site applique ce principe.
   Mécanique : la page est rendue UNE seule fois, en blanc sur noir. Les
   sections « claires » portent un calque `backdrop-filter: invert(1)` qui
   retourne tout ce qui est peint derrière lui. La coupure est donc nette au
   pixel, et les mots qui chevauchent une frontière sont tranchés en deux —
   exactement comme le logo. Aucun JS n'intervient dans cet effet.
   ========================================================================== */

@font-face {
  font-family: 'Archivo';
  font-style: normal;
  font-weight: 400 900;
  font-stretch: 62% 125%;
  font-display: swap;
  src: url('assets/fonts/archivo-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Archivo';
  font-style: normal;
  font-weight: 400 900;
  font-stretch: 62% 125%;
  font-display: swap;
  src: url('assets/fonts/archivo-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
    U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020,
    U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

:root {
  --ink: #fff;
  --ground: #000;

  --gutter: clamp(1.25rem, 5vw, 5.5rem);
  --measure: 34rem;

  /* Emil : les courbes natives manquent de nerf. */
  --ease-out: cubic-bezier(0.23, 1, 0.32, 1);

  --rule: 1px solid color-mix(in srgb, var(--ink) 22%, transparent);

  /* LA COULEUR
     Le site est noir et blanc parce que c'est la marque. La couleur, c'est la
     lumière — donc elle n'apparaît que là où il y a de la lumière : la vidéo
     du bas, et les repères qui comptent. Un seul accent, échantillonné sur le
     show lui-même (les faisceaux y sont d'un rouge quasi pur, #F00000).
     ⚠️ Dans une section claire, tout est retourné par `backdrop-filter`. Un
     accent posé là s'afficherait en négatif. On y déclare donc sa COULEUR
     INVERSE, que l'inversion remet à l'endroit. #FF2D46 ↔ #00D2B9. */
  --beam: #FF2D46;

  /* Géométrie du wordmark — sert à poser la coupure du hero exactement sur la
     bascule du logo. 4.6559 = son rapport largeur/hauteur, 53.3762 % = la
     position de sa bascule. Les deux sont imprimés par tools/build-wordmark.py. */
  --mark-w: min(78vw, 60rem);
  --mark-ratio: 4.6559;
  --mark-split: 53.3762%;
}

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

html {
  scroll-behavior: smooth;
  -webkit-text-size-adjust: 100%;
}
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
}

body {
  margin: 0;
  background: var(--ground);
  color: var(--ink);
  font-family: 'Archivo', 'Helvetica Neue', Arial, sans-serif;
  font-variation-settings: 'wdth' 100, 'wght' 400;
  font-size: clamp(1rem, 0.94rem + 0.3vw, 1.125rem);
  line-height: 1.55;
  overflow-x: hidden;
  /* Le calque d'inversion ne doit jamais révéler de blanc sous le pied de page. */
  overscroll-behavior-y: none;
}

img { max-width: 100%; display: block; }

a { color: inherit; }

:focus-visible {
  outline: 2px solid var(--beam);
  outline-offset: 4px;
}

.skip {
  position: absolute;
  left: -9999px;
  top: 0;
  padding: 0.75rem 1rem;
  background: var(--ground);
  color: var(--ink);
  z-index: 200;
}
.skip:focus { left: 0; }

/* --------------------------------------------------------------------------
   LE COUTEAU
   Un calque par section claire. Il retourne tout ce qui est peint derrière,
   y compris les mots de la section précédente qui débordent chez lui.
   -------------------------------------------------------------------------- */

.cut {
  position: absolute;
  inset: 0;
  /* Indispensable : les sections sont `position: relative`, donc sans z-index
     la section SUIVANTE se peindrait par-dessus ce calque et les mots qui
     débordent chez elle échapperaient à l'inversion. */
  z-index: 10;
  pointer-events: none;
  backdrop-filter: invert(1);
  -webkit-backdrop-filter: invert(1);
}

/* Repli si le navigateur ne sait pas filtrer l'arrière-plan : on repeint la
   section à la main. On perd la découpe des mots, pas la lisibilité. */
@supports not ((backdrop-filter: invert(1)) or (-webkit-backdrop-filter: invert(1))) {
  .cut { display: none; }
  .s--light {
    background: var(--ink);
    color: var(--ground);
  }
  .s--light .rule { border-color: color-mix(in srgb, var(--ground) 22%, transparent); }
  .s--light .mark { filter: invert(1); }
}

/* --------------------------------------------------------------------------
   TRAME
   -------------------------------------------------------------------------- */

.s {
  position: relative;
  padding: clamp(5rem, 14vh, 10rem) var(--gutter);
}

.wrap { max-width: 78rem; margin-inline: auto; width: 100%; }

/* --------------------------------------------------------------------------
   TYPO
   -------------------------------------------------------------------------- */

.display {
  margin: 0;
  font-size: clamp(2.6rem, 10.2vw, 10.5rem);
  font-variation-settings: 'wdth' 112, 'wght' 800;
  line-height: 0.82;
  letter-spacing: -0.035em;
  text-transform: uppercase;
  text-wrap: balance;
}

/* Le mot qui chevauche la frontière : il remonte dans la section précédente,
   donc la ligne d'inversion le traverse. C'est le logo, rejoué à chaque palier.
   0.425em place la coupure à 53,4 % de la hauteur de capitale — la mesure prise
   sur le logo lui-même (bascule à 443px sur 887, soit 53,376 % du wordmark).
   Tous les titres du site sont donc tranchés exactement où le logo l'est. */
.straddle {
  margin-top: calc(-0.425em - clamp(5rem, 14vh, 10rem));
  margin-bottom: 0.32em;
}

.eyebrow {
  margin: 0 0 1.5rem;
  font-size: clamp(0.7rem, 0.66rem + 0.2vw, 0.8rem);
  font-variation-settings: 'wdth' 88, 'wght' 600;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  opacity: 0.62;
}

.lede {
  max-width: var(--measure);
  font-size: clamp(1.15rem, 1rem + 0.7vw, 1.6rem);
  line-height: 1.42;
  font-variation-settings: 'wdth' 100, 'wght' 500;
  text-wrap: pretty;
}

.body { max-width: var(--measure); }
.body p { margin: 0 0 1.35em; text-wrap: pretty; }
.body p:last-child { margin-bottom: 0; }
.body strong {
  font-variation-settings: 'wdth' 100, 'wght' 700;
  box-shadow: inset 0 -0.14em 0 var(--beam);
}

.kicker {
  font-size: clamp(1.4rem, 1.1rem + 1.4vw, 2.6rem);
  line-height: 1.18;
  font-variation-settings: 'wdth' 104, 'wght' 700;
  letter-spacing: -0.015em;
  max-width: 22ch;
  margin: 0;
  text-wrap: balance;
}

/* --------------------------------------------------------------------------
   BARRE HAUTE
   Au-dessus de tous les couteaux : elle garde sa propre polarité.
   -------------------------------------------------------------------------- */

.nav {
  position: fixed;
  top: 0; left: 0; right: 0;
  z-index: 100;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: clamp(1rem, 2.4vh, 1.6rem) var(--gutter);
  mix-blend-mode: difference;
  transition: transform 260ms var(--ease-out);
  font-size: 0.8rem;
  font-variation-settings: 'wdth' 90, 'wght' 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
}

.nav--hidden { transform: translateY(-100%); }

.nav__name { text-decoration: none; }

.nav__langs { display: flex; gap: 0.1rem; align-items: center; }
.nav__langs a {
  text-decoration: none;
  padding: 0.35rem 0.5rem;
  opacity: 0.5;
  transition: opacity 160ms var(--ease-out);
}
.nav__langs a:hover { opacity: 1; }
.nav__langs a[aria-current='true'] { opacity: 1; }
.nav__sep { opacity: 0.35; }

/* --------------------------------------------------------------------------
   HERO
   Haut de 210vh : le wordmark reste collé au centre pendant que la frontière
   de la section suivante remonte et le tranche en deux, en direct.
   -------------------------------------------------------------------------- */

.hero {
  position: relative;
  height: 200vh;
  padding: 0;
}

/* LA COUPURE DU HERO
   Elle se gare exactement sur la bascule du wordmark et n'en bouge plus : le
   logo reste coupé en deux, au milieu de l'écran, pendant que la vidéo et la
   page glissent derrière. main.js pose --cut-top (la bascule du logo, en px
   écran) et --cut-bottom (la distance au bas du hero) — ce second terme est
   ce qui empêche ce calque de déborder sur la section suivante et de la
   ré-inverser une deuxième fois. */
.hero__cut {
  position: fixed;
  inset: 0;
  z-index: 10;
  pointer-events: none;
  clip-path: inset(var(--cut-top, 100%) 0 var(--cut-bottom, 0) 0);
  backdrop-filter: invert(1);
  -webkit-backdrop-filter: invert(1);
}
@supports not ((backdrop-filter: invert(1)) or (-webkit-backdrop-filter: invert(1))) {
  .hero__cut { display: none; }
}

.hero__media {
  position: absolute;
  inset: 0 0 auto 0;
  height: 100vh;
  overflow: hidden;
}

.hero__video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* La vidéo n'est qu'une ambiance : elle ne doit jamais disputer la typo. */
  opacity: 0.72;
}

/* Voile : écrase le centre lumineux de la scène pour que le wordmark tienne. */
.hero__media::after {
  content: '';
  position: absolute;
  inset: 0;
  background:
    radial-gradient(ellipse 74% 50% at 50% 60%, rgba(0,0,0,0.58), transparent 72%),
    linear-gradient(to bottom, rgba(0,0,0,0.55), rgba(0,0,0,0.15) 35%, rgba(0,0,0,0.9));
}

.hero__stick {
  position: sticky;
  top: 50vh;
  transform: translateY(-50%);
  padding-inline: var(--gutter);
  text-align: center;
}

/* Le wordmark EST le titre de premier niveau : il porte le h1, qui ne doit
   introduire ni marge ni taille de texte propre. */
.mark-h1 { margin: 0; font-size: inherit; line-height: 0; }

.mark {
  width: var(--mark-w);
  aspect-ratio: var(--mark-ratio);
  margin-inline: auto;
  height: auto;
}

.hero__tagline {
  margin: clamp(1.5rem, 4vh, 2.75rem) auto 0;
  max-width: 44rem;
  font-size: clamp(0.78rem, 0.72rem + 0.32vw, 1rem);
  font-variation-settings: 'wdth' 88, 'wght' 500;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  line-height: 1.9;
}

.hero__scroll {
  position: absolute;
  bottom: calc(110vh + 2rem);
  left: 50%;
  transform: translateX(-50%);
  font-size: 0.66rem;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  opacity: 0.5;
}

/* --------------------------------------------------------------------------
   SECTIONS CLAIRES
   -------------------------------------------------------------------------- */

.s--light {
  position: relative;
  /* Inverse exact de --beam : l'inversion de la section le remet à l'endroit. */
  --beam: #00D2B9;
}

.s--after-hero { padding-top: clamp(6rem, 18vh, 12rem); }

/* --------------------------------------------------------------------------
   CHIFFRES
   -------------------------------------------------------------------------- */

.facts {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: clamp(2.5rem, 6vw, 4rem);
  grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr));
  border-top: var(--rule);
  padding-top: clamp(2.5rem, 6vh, 4rem);
}

.facts__n {
  display: block;
  color: var(--beam);
  font-size: clamp(2.5rem, 1.6rem + 3.6vw, 5rem);
  font-variation-settings: 'wdth' 108, 'wght' 800;
  line-height: 0.92;
  letter-spacing: -0.03em;
}

.facts__t {
  display: block;
  margin-top: 0.9rem;
  font-size: 0.82rem;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  opacity: 0.66;
  line-height: 1.6;
}

/* --------------------------------------------------------------------------
   RÉFÉRENCES
   -------------------------------------------------------------------------- */

.refs { list-style: none; margin: 0; padding: 0; }

.refs li {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.5rem 2rem;
  padding: clamp(1.4rem, 3.4vh, 2.4rem) 0;
  border-top: var(--rule);
}
.refs li:last-child { border-bottom: var(--rule); }

.refs__n {
  font-size: clamp(1.6rem, 1.1rem + 2.4vw, 3.75rem);
  font-variation-settings: 'wdth' 106, 'wght' 700;
  line-height: 1.02;
  letter-spacing: -0.022em;
  transition: color 160ms var(--ease-out);
}

/* Une référence s'allume quand on la vise — comme un projecteur qu'on ouvre. */
@media (hover: hover) and (pointer: fine) {
  .refs li:hover .refs__n { color: var(--beam); }
}

.refs__m {
  font-size: 0.78rem;
  letter-spacing: 0.17em;
  text-transform: uppercase;
  opacity: 0.6;
  white-space: nowrap;
}

/* --------------------------------------------------------------------------
   PLEIN FEU — la seule section en couleur
   Aucun calque d'inversion ici : la couleur doit rester à l'endroit. Le noir
   sous la vidéo laisse au titre de la section suivante de quoi se faire
   trancher proprement.
   -------------------------------------------------------------------------- */

.s--beam {
  position: relative;
  padding: 0 0 clamp(6rem, 16vh, 12rem);
}

.beam__media {
  position: relative;
  height: 100svh;
  overflow: hidden;
  display: grid;
  place-items: center;
}

.beam__video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Voile léger — et il DOIT rester léger : cette image a une luminance moyenne
   de 23/255, c'est une arène noire avec des faisceaux. Le premier voile posé
   ici (0,78 au centre) l'avait éteinte complètement, on ne voyait plus qu'un
   écran noir. C'est l'ombre portée sur le texte qui fait le travail de
   lisibilité, pas un rideau sur toute l'image. */
.beam__media::after {
  content: '';
  position: absolute;
  inset: 0;
  background:
    radial-gradient(ellipse 58% 34% at 50% 48%, rgba(0,0,0,0.42), transparent 76%),
    linear-gradient(to bottom, rgba(0,0,0,0.42), rgba(0,0,0,0) 38%, rgba(0,0,0,0.72));
}

.beam__text {
  position: relative;
  z-index: 1;
  text-shadow: 0 0.06em 0.6em rgba(0, 0, 0, 0.9), 0 0 1.4em rgba(0, 0, 0, 0.7);
  padding-inline: var(--gutter);
  max-width: 72rem;
  text-align: center;
}

.beam__line {
  margin: 0;
  font-size: clamp(1.75rem, 1.1rem + 3.4vw, 4.75rem);
  font-variation-settings: 'wdth' 106, 'wght' 800;
  line-height: 1.04;
  letter-spacing: -0.028em;
  text-wrap: balance;
}

.beam__line em {
  font-style: normal;
  color: var(--beam);
}

/* --------------------------------------------------------------------------
   CONTACT
   -------------------------------------------------------------------------- */

.contact__grid {
  display: grid;
  gap: clamp(2.5rem, 6vw, 4.5rem);
  grid-template-columns: repeat(auto-fit, minmax(13.5rem, 1fr));
  margin-top: clamp(3rem, 8vh, 5rem);
}

.field { border-top: var(--rule); padding-top: 1.25rem; }

.field__k {
  display: block;
  font-size: 0.68rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  opacity: 0.72;
  margin-bottom: 0.7rem;
}

.field__v {
  font-size: clamp(1.05rem, 0.9rem + 0.7vw, 1.45rem);
  font-variation-settings: 'wdth' 100, 'wght' 600;
  text-decoration: none;
  letter-spacing: -0.01em;
  display: inline-block;
  border-bottom: 2px solid transparent;
  transition: border-color 180ms var(--ease-out);
  word-break: break-word;
}
@media (hover: hover) and (pointer: fine) {
  .field__v:hover { border-bottom-color: currentColor; }
}

/* L'adresse n'existe nulle part en clair dans le HTML : elle est recomposée
   ici par CSS, et transformée en vrai lien mailto par main.js. Les moissonneurs
   qui lisent la source brute ne trouvent aucune chaîne à ramasser. */
.mail::after { content: attr(data-u) '@' attr(data-d); }
.tel::after { content: attr(data-a) ' ' attr(data-b); }

.cta {
  display: inline-flex;
  align-items: center;
  gap: 0.85rem;
  margin-top: clamp(3rem, 7vh, 4.5rem);
  padding: 1.15rem 1.9rem;
  border: 2px solid currentColor;
  text-decoration: none;
  font-size: clamp(0.85rem, 0.8rem + 0.3vw, 1.05rem);
  font-variation-settings: 'wdth' 96, 'wght' 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  transition: transform 160ms var(--ease-out), border-color 180ms var(--ease-out),
    color 180ms var(--ease-out);
}
@media (hover: hover) and (pointer: fine) {
  .cta:hover { border-color: var(--beam); color: var(--beam); }
}
.cta:active { transform: scale(0.97); }
.cta svg { width: 1.3em; height: 1.3em; flex: none; }

/* --------------------------------------------------------------------------
   BOUTON WHATSAPP FLOTTANT
   -------------------------------------------------------------------------- */

.wa {
  position: fixed;
  right: clamp(1rem, 3vw, 2.25rem);
  bottom: clamp(1rem, 3vw, 2.25rem);
  z-index: 100;
  display: grid;
  place-items: center;
  width: 3.5rem;
  height: 3.5rem;
  border-radius: 50%;
  background: #fff;
  color: #000;
  /* `difference` fait basculer la pastille avec le fond : rondelle noire à
     icône blanche sur page claire, l'inverse sur page sombre. Un seul élément,
     jamais invisible. */
  mix-blend-mode: difference;
  transition: transform 180ms var(--ease-out);
}
.wa svg { width: 1.85rem; height: 1.85rem; }
@media (hover: hover) and (pointer: fine) {
  .wa:hover { transform: scale(1.06); }
}
.wa:active { transform: scale(0.95); }

/* --------------------------------------------------------------------------
   PIED
   -------------------------------------------------------------------------- */

.foot {
  /* La pastille WhatsApp flotte en bas à droite : on lui laisse sa place
     plutôt que de la laisser mordre sur la mention légale. */
  padding: clamp(3rem, 8vh, 5rem) calc(var(--gutter) + 4rem) clamp(5rem, 9vh, 6rem) var(--gutter);
  font-size: 0.72rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  opacity: 0.45;
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 2rem;
  justify-content: space-between;
}
.foot a { text-decoration: none; border-bottom: 1px solid transparent; }
@media (hover: hover) and (pointer: fine) {
  .foot a:hover { border-bottom-color: currentColor; }
}

/* --------------------------------------------------------------------------
   APPARITIONS
   Discrètes : on les voit une fois. Emil — décoratif, donc léger, et coupé net
   dès que la machine ou l'utilisateur demande moins de mouvement.
   -------------------------------------------------------------------------- */

@media (prefers-reduced-motion: no-preference) {
  .rise {
    opacity: 0;
    transform: translateY(10px);
    transition: opacity 520ms var(--ease-out), transform 520ms var(--ease-out);
  }
  .rise.is-in { opacity: 1; transform: none; }
}

@media (prefers-reduced-motion: reduce) {
  .hero__scroll { display: none; }
}
