/* ============================================================================
   scroll-world - habillage du monde scroll-scrubbé
   ----------------------------------------------------------------------------
   Tout est préfixé `sw-` et ne dépend d'aucune règle de style.css : le moteur
   reste transplantable ailleurs. Seules les valeurs de la charte NoBaK sont
   reprises, via les tokens du site quand ils existent.
   ========================================================================== */

.sw-root {
  --sw-total: 6;                    /* écrasé par le moteur : Σ section.scroll */
  --sw-bg: #000000;
  --sw-ink: #ffffff;
  --sw-ink-rgb: 255 255 255;        /* les voiles translucides du HUD */
  --sw-ink-soft: rgb(var(--sw-ink-rgb) / 0.6);
  --sw-btn-fg: #000000;             /* texte posé sur l'aplat d'accent */
  --sw-accent: #c7f33c;
  --sw-haze: 0.55;                  /* profondeur du vignettage, cf. .sw-haze */
  --sw-rail-w: 96px;                /* rail d'icônes du site, à droite duquel on démarre */

  /* Palette du moteur. Triplets RGB bruts : les alphas restent côté JS, où
     chaque prop a le sien. lirePalette() les relit à chaque bascule de thème
     et mute les tableaux sur place, sans reconstruire le décor. */
  --sw-dim: 90 104 70;              /* structure lointaine, presque éteinte */
  --sw-edge: 150 168 128;           /* arêtes proches */
  --sw-steel: 120 128 118;          /* mobilier, foule, caisses */
  --sw-accent-rgb: 199 243 60;      /* néons - la seule source lumineuse */
  --sw-dust: 199 243 60;            /* particules en suspension */
  --sw-blend: lighter;              /* recomposition du bloom */

  --sw-shade: 0 0 0;                /* teinte du vignettage */
  --sw-scan: 255 255 255;           /* teinte des lignes de balayage */

  position: relative;
  height: calc(var(--sw-total) * 100vh);
  /* Même débord que l'ancien .hero : le monde va d'un bord à l'autre de la
     colonne applicative sans jamais provoquer de scroll horizontal. */
  margin: 0 calc(-1 * var(--app-pad-x, 28px)) 32px;
  background: var(--sw-bg);
}

@supports (height: 100svh) {
  .sw-root { height: calc(var(--sw-total) * 100svh); }
}

/* ---- Thème clair -----------------------------------------------------------
   Le monde s'inverse : encre sur papier au lieu de néon sur nuit. Deux choses
   ne se contentent pas d'un échange de couleurs.
   1. Les alphas du moteur ne changent pas. Un trait « faible » l'est parce
      qu'il est proche du fond : sur papier il faut donc de l'encre sombre,
      pas la version claire de la couleur sombre. Les rôles gardent leur
      hiérarchie (dim le plus discret, edge le plus marqué), inversée en
      luminosité.
   2. Le bloom additif ne peut rien sur du blanc. Il passe en `multiply`, qui
      assombrit autour du trait : le halo devient une ombre douce plutôt qu'un
      néon, et le relief tient toujours. */
:root[data-theme="light"] .sw-root {
  --sw-bg: #f1f2ec;
  --sw-ink: #14170f;
  --sw-ink-rgb: 20 23 15;
  --sw-ink-soft: rgb(var(--sw-ink-rgb) / 0.62);
  --sw-btn-fg: #f1f2ec;
  --sw-accent: #4a6100;

  --sw-dim: 154 160 142;
  --sw-edge: 93 101 79;
  --sw-steel: 118 124 110;
  --sw-accent-rgb: 74 97 0;         /* le meme que --sw-accent : les equerres
                                       du HUD et la telemetrie le partagent */
  --sw-dust: 108 132 44;
  --sw-blend: multiply;

  --sw-shade: 22 26 16;
  --sw-scan: 20 24 12;
  --sw-haze: 0.16;
}

/* L'arrondi et l'ombre vont sur le stage, PAS sur .sw-root.
   `overflow: hidden` sur .sw-root en faisait un conteneur de defilement : le
   stage, qui est `position: sticky`, se mettait alors a coller a l'interieur
   de ce conteneur au lieu de la fenetre. Il quittait l'ecran des le premier
   ecran de defilement et laissait les six suivants en aplat sombre - le monde
   disparaissait, et la page ne reprenait qu'apres.
   Le stage porte deja `overflow: hidden` dans la regle de base : sur
   l'element colle lui-meme c'est sans effet, la contrainte ne porte que sur
   ses ancetres. */
:root[data-theme="light"] .sw-stage {
  border-bottom: 0;
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-lg);
}

/* ---- La scène épinglée ---------------------------------------------------- */

.sw-stage {
  position: sticky;
  top: 0;
  height: 100vh;
  overflow: hidden;
  isolation: isolate;
  background: var(--sw-bg);
  border-bottom: 1px solid var(--border, rgb(var(--sw-ink-rgb) / 0.1));
}

@supports (height: 100svh) {
  .sw-stage { height: 100svh; }
}

.sw-canvas {
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
}

/* Brume : un puits de lumière au centre, des bords qui s'éteignent. C'est ce
   qui donne la profondeur au fil de fer, qui autrement reste plat. */
.sw-haze {
  position: absolute;
  inset: 0;
  pointer-events: none;
  background:
    radial-gradient(ellipse 70% 55% at 50% 46%, transparent 0%, rgb(var(--sw-shade) / var(--sw-haze)) 78%, rgb(var(--sw-shade) / calc(var(--sw-haze) * 1.6)) 100%),
    radial-gradient(ellipse 40% 30% at 50% 44%, rgb(var(--sw-dust) / 0.05), transparent 70%);
}

/* Lignes de balayage - le grain d'un flux vidéo. Un dégradé répété plutôt
   qu'une turbulence SVG : celle-ci laisse des coutures visibles sur iOS. */
.sw-grain {
  position: absolute;
  inset: 0;
  pointer-events: none;
  opacity: 0.5;
  background: repeating-linear-gradient(
    180deg,
    rgb(var(--sw-scan) / 0.022) 0px,
    rgb(var(--sw-scan) / 0.022) 1px,
    transparent 1px,
    transparent 3px
  );
}

/* ---- Cadre HUD ------------------------------------------------------------
   Quatre équerres et une ligne de télémétrie. Rien n'est cliquable : c'est du
   cadre, pas de l'interface - d'où `aria-hidden` côté moteur. */

.sw-hud {
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 1;
}

.sw-hud__corner {
  position: absolute;
  width: 18px;
  height: 18px;
  border: 0 solid rgb(var(--sw-accent-rgb) / 0.34);
}

.sw-hud__corner--tl { top: 18px; left: 18px; border-top-width: 1px; border-left-width: 1px; }
.sw-hud__corner--tr { top: 18px; right: 18px; border-top-width: 1px; border-right-width: 1px; }
.sw-hud__corner--bl { bottom: 18px; left: 18px; border-bottom-width: 1px; border-left-width: 1px; }
.sw-hud__corner--br { bottom: 18px; right: 18px; border-bottom-width: 1px; border-right-width: 1px; }

.sw-hud__telemetry {
  position: absolute;
  left: 44px;
  bottom: 20px;
  /* 0.55 et non 0.42 : à 0.42 la ligne tombait à 3.29:1, sous le seuil AA.
     Elle est décorative et `aria-hidden`, mais elle reste du texte qu'on lit
     à l'écran - et la remonter ne coûte rien à la discrétion recherchée. */
  color: rgb(var(--sw-accent-rgb) / 0.55);
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 0.625rem;
  letter-spacing: 0.1em;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}

/* ---- Copy ----------------------------------------------------------------- */

.sw-copy {
  position: absolute;
  inset: 0;
  display: grid;
  align-items: center;
  padding: 72px clamp(24px, 6vw, 88px) 96px;
  pointer-events: none;
}

/* Les panneaux se superposent dans la même cellule de grille ; c'est le
   moteur qui règle leur opacité. La valeur de départ est ici pour que rien ne
   s'empile si le script tarde - seul le premier est visible à froid. */
.sw-panel {
  grid-area: 1 / 1;
  max-width: 34rem;
  opacity: 0;
  will-change: opacity, transform;
}

.sw-panel:first-child { opacity: 1; }

.sw-panel__logo {
  display: block;
  width: 56px;
  height: auto;
  margin-bottom: 22px;
  filter: drop-shadow(0 0 18px rgb(var(--sw-accent-rgb) / 0.35));
}

.sw-panel__eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  margin-bottom: 14px;
  color: var(--sw-accent);
  font-family: var(--font-display, 'Chakra Petch', sans-serif);
  font-size: 0.6875rem;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
}

.sw-panel__eyebrow::before {
  content: '';
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: currentColor;
  box-shadow: 0 0 12px currentColor;
}

/* Le filet se tire vers la droite au rythme du scroll : `--v` est la
   visibilité du panneau, écrite par le moteur à chaque frame. Aucune
   transition CSS - c'est le scroll qui fait le mouvement, image par image. */
.sw-panel__eyebrow::after {
  content: '';
  width: clamp(28px, 8vw, 72px);
  height: 1px;
  margin-left: 4px;
  background: currentColor;
  transform: scaleX(var(--v, 1));
  transform-origin: left center;
  opacity: 0.5;
}

.sw-panel__title {
  margin: 0 0 16px;
  color: var(--sw-ink);
  font-family: var(--font-display, 'Chakra Petch', sans-serif);
  font-size: clamp(1.75rem, 4vw, 3.1rem);
  font-weight: 700;
  line-height: 1.02;
  letter-spacing: -0.03em;
  text-wrap: balance;
  /* Volet d'ouverture, tiré par le scroll comme le filet ci-dessus. Le titre
     ne fait pas que s'allumer : il se découvre de gauche à droite, dans le
     sens de la marche de la caméra. 102 % plutôt que 100 % pour que les
     jambages débordants soient couverts au départ. */
  clip-path: inset(0 calc((1 - var(--v, 1)) * 102%) 0 0);
}

/* Le titre du hero porte le nom du club : c'est un wordmark, pas un titre de
   section - il joue deux crans au-dessus et resserre son interlettrage. */
.sw-panel--hero .sw-panel__title {
  font-size: clamp(3rem, 9vw, 7rem);
  line-height: 0.92;
  letter-spacing: -0.045em;
}

/* `em` sert de surligneur de marque dans les titres et les textes : il n'est
   jamais rendu en italique, il passe en lime. */
.sw-panel__title em,
.sw-panel__body em {
  font-style: normal;
  color: var(--sw-accent);
}

.sw-panel__body {
  margin: 0;
  max-width: 30rem;
  color: var(--sw-ink-soft);
  font-family: var(--font-body, 'DM Sans', sans-serif);
  font-size: clamp(0.9375rem, 1.6vw, 1.0625rem);
  line-height: 1.6;
}

/* Sous le wordmark, la baseline du club porte le même poids qu'un sous-titre :
   elle n'est pas du corps de texte, elle est la deuxième ligne du logo. */
.sw-panel--hero .sw-panel__body {
  color: var(--sw-ink);
  font-family: var(--font-display, 'Chakra Petch', sans-serif);
  font-size: clamp(1rem, 2.1vw, 1.4rem);
  font-weight: 500;
  line-height: 1.35;
  letter-spacing: -0.01em;
}

.sw-panel__tags {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: 22px 0 0;
  padding: 0;
  list-style: none;
}

.sw-panel__tags li {
  padding: 6px 12px;
  border: 1px solid rgb(var(--sw-ink-rgb) / 0.16);
  border-radius: 999px;
  background: rgb(var(--sw-ink-rgb) / 0.04);
  color: var(--sw-ink-soft);
  font-family: var(--font-display, 'Chakra Petch', sans-serif);
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}

.sw-panel__ctas {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  margin-top: 30px;
}

.sw-btn {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 13px 24px;
  border: 1px solid var(--sw-accent);
  border-radius: var(--radius, 4px);
  background: var(--sw-accent);
  color: var(--sw-btn-fg);
  font-family: var(--font-display, 'Chakra Petch', sans-serif);
  font-size: 0.8125rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  text-decoration: none;
  transition: transform 0.18s var(--ease, cubic-bezier(0.22, 1, 0.36, 1)),
              box-shadow 0.18s var(--ease, cubic-bezier(0.22, 1, 0.36, 1));
}

.sw-btn:hover {
  transform: translateY(-2px);
  box-shadow: 0 10px 30px rgb(var(--sw-accent-rgb) / 0.28);
}

.sw-btn:active { transform: translateY(0); }

.sw-btn--ghost {
  border-color: rgb(var(--sw-ink-rgb) / 0.24);
  background: rgb(var(--sw-ink-rgb) / 0.04);
  color: var(--sw-ink);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}

.sw-btn--ghost:hover {
  border-color: rgb(var(--sw-ink-rgb) / 0.5);
  box-shadow: none;
}

/* ---- Rail de progression -------------------------------------------------- */

.sw-rail {
  position: absolute;
  top: 50%;
  right: clamp(16px, 3vw, 34px);
  transform: translateY(-50%);
  display: flex;
  flex-direction: column;
  gap: 14px;
  z-index: 2;
}

.sw-tick {
  position: relative;
  display: block;
  width: 26px;
  height: 2px;
  padding: 0;
  border: 0;
  border-radius: 2px;
  background: rgb(var(--sw-ink-rgb) / 0.22);
  cursor: pointer;
  transition: background 0.25s var(--ease, ease), width 0.25s var(--ease, ease);
}

.sw-tick.is-active {
  width: 42px;
  background: var(--sw-accent);
  box-shadow: 0 0 14px var(--sw-accent);
}

/* Le libellé ne s'affiche que pour l'étape courante (ou au survol) : le rail
   reste une barre de progression, pas un menu. */
.sw-tick__label {
  position: absolute;
  right: calc(100% + 12px);
  top: 50%;
  transform: translateY(-50%);
  white-space: nowrap;
  color: var(--sw-ink-soft);
  font-family: var(--font-display, 'Chakra Petch', sans-serif);
  font-size: 0.625rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  opacity: 0;
  transition: opacity 0.25s var(--ease, ease);
}

.sw-tick.is-active .sw-tick__label,
.sw-tick:hover .sw-tick__label,
.sw-tick:focus-visible .sw-tick__label {
  opacity: 1;
}

.sw-tick.is-active .sw-tick__label { color: var(--sw-accent); }

.sw-tick:focus-visible {
  outline: 2px solid var(--sw-accent);
  outline-offset: 4px;
}

/* ---- Invite au scroll ----------------------------------------------------- */

.sw-hint {
  position: absolute;
  left: 50%;
  bottom: 26px;
  transform: translateX(-50%);
  display: flex;
  align-items: center;
  gap: 10px;
  color: var(--sw-ink-soft);
  font-family: var(--font-display, 'Chakra Petch', sans-serif);
  font-size: 0.625rem;
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  pointer-events: none;
}

.sw-hint::after {
  content: '';
  width: 1px;
  height: 22px;
  background: linear-gradient(180deg, var(--sw-accent), transparent);
  animation: sw-hint-drop 1.9s var(--ease, ease-in-out) infinite;
}

@keyframes sw-hint-drop {
  0%   { transform: translateY(-6px); opacity: 0; }
  35%  { opacity: 1; }
  100% { transform: translateY(8px); opacity: 0; }
}

/* ---- Mobile --------------------------------------------------------------- */

@media (max-width: 900px) {
  .sw-copy {
    align-items: end;
    padding: 96px 22px calc(104px + env(safe-area-inset-bottom, 0px));
  }

  .sw-panel { max-width: none; }

  .sw-panel__logo { width: 44px; margin-bottom: 16px; }

  /* Le rail passe à l'horizontale au-dessus de l'invite : sur un écran étroit
     une colonne de tirets à droite mange la largeur de la copy. */
  .sw-rail {
    top: auto;
    bottom: calc(64px + env(safe-area-inset-bottom, 0px));
    right: 50%;
    transform: translateX(50%);
    flex-direction: row;
    align-items: center;
  }

  .sw-tick { width: 18px; }
  .sw-tick.is-active { width: 30px; }

  /* En ligne, le libellé passerait sous les autres tirets : il repasse
     au-dessus du rail. */
  .sw-tick__label {
    right: auto;
    left: 50%;
    top: auto;
    bottom: calc(100% + 10px);
    transform: translateX(-50%);
  }

  .sw-hint { bottom: calc(22px + env(safe-area-inset-bottom, 0px)); }

  /* Les équerres se resserrent et la télémétrie remonte au-dessus du rail,
     qui occupe désormais le bas du cadre. */
  .sw-hud__corner { width: 12px; height: 12px; }
  .sw-hud__corner--tl, .sw-hud__corner--tr { top: 12px; }
  .sw-hud__corner--bl, .sw-hud__corner--br { bottom: 12px; }
  .sw-hud__corner--tl, .sw-hud__corner--bl { left: 12px; }
  .sw-hud__corner--tr, .sw-hud__corner--br { right: 12px; }

  /* La télémétrie disparaît sur téléphone : le bas du cadre y porte déjà le
     rail et l'invite, et la copy remonte jusqu'à eux. Trois lignes de chrome
     empilées sur 60 px, ce n'est plus du cadre, c'est du bruit. */
  .sw-hud__telemetry { display: none; }
}

/* ---- Mouvement réduit ------------------------------------------------------
   La caméra reste pilotée par le scroll - c'est de la manipulation directe,
   l'utilisateur en garde le contrôle image par image. Ce qu'on coupe, c'est
   tout ce qui bouge de soi-même : l'invite qui pulse et les transitions. */

@media (prefers-reduced-motion: reduce) {
  .sw-hint::after { animation: none; opacity: 0.6; }
  .sw-tick,
  .sw-tick__label,
  .sw-btn { transition: none; }
  .sw-btn:hover { transform: none; }
}
