/* ══════════════════════════════════════════════════
   TECOMDOM — SCROLL EXPERIENCE
   Frames pinned, scroll-driven transitions
════════════════════════════════════════════════════ */

:root {
  --blue:      #6BBED6;
  --blue-mid:  #4BAED0;
  --blue-deep: #2B8BAE;
  --blue-pale: #EAF5FB;
  --ink:       #0A0C10;
  --ink-2:     #15181E;
  --muted:     #6B7380;
  --muted-2:   #A5ACB8;
  --line:      #E8EAED;
  --bg:        #FFFFFF;
  --bg-soft:   #F7F8FA;

  /* Easings unifiés (basés sur les pratiques agency 2026 — out-cubic cinématique) */
  --ease:        cubic-bezier(.22,.61,.36,1);  /* out-cubic doux, plus naturel */
  --ease-out:    cubic-bezier(.16,1,.3,1);     /* out-quint pour reveal punchy */
  --ease-in-out: cubic-bezier(.65,.05,.36,1);  /* in-out pour boucles ambiantes */
  --ease-spring: cubic-bezier(.34,1.56,.64,1); /* léger overshoot, à utiliser avec parcimonie */

  --f-sans:  'Space Grotesk', -apple-system, sans-serif;
  --f-serif: 'Instrument Serif', Georgia, serif;
  --f-mono:  'JetBrains Mono', ui-monospace, monospace;

  /* Hauteur de scroll par frame. Resserrée (220→160vh) pour un rythme plus
     punchy : les animations restent fluides mais le scroll-fatigue diminue. */
  --frame-h: 160vh;
}

* , *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
html, body { background: var(--bg); color: var(--ink); }
html { scroll-behavior: auto; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; }
body {
  font-family: var(--f-sans);
  line-height: 1.5;
  overflow-x: hidden;
}
img, svg { display: block; max-width: 100%; }
a { color: inherit; text-decoration: none; }
::selection { background: var(--ink); color: #fff; }
::-webkit-scrollbar { width: 0; }

/* ───────────── NAV ───────────── */
nav {
  position: fixed; inset: 0 0 auto;
  z-index: 100;
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: 32px;
  padding: 18px 6%;
  pointer-events: none;
}
nav::before {
  content: '';
  position: absolute; inset: 0;
  background: linear-gradient(to bottom, rgba(255,255,255,.85) 0%, rgba(255,255,255,0) 100%);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  -webkit-mask-image: linear-gradient(to bottom, black 30%, transparent 100%);
          mask-image: linear-gradient(to bottom, black 30%, transparent 100%);
  z-index: -1;
  opacity: var(--nav-bg, 0);
  transition: opacity .4s var(--ease);
  pointer-events: none;
}
body.dark-frame nav::before {
  background: linear-gradient(to bottom, rgba(10,12,16,.85) 0%, rgba(10,12,16,0) 100%);
}
nav > * { pointer-events: auto; }
.nav-logo {
  display: inline-flex; align-items: center;
  position: relative;
  transition: opacity .3s var(--ease), transform .5s var(--ease-out);
}
.nav-logo img {
  height: 28px;
  width: auto;
  transition: opacity .4s var(--ease);
}
.nav-logo .nl-dark {
  position: absolute; top: 0; left: 0;
  opacity: 0;
}
body.dark-frame .nav-logo .nl-light { opacity: 0; }
body.dark-frame .nav-logo .nl-dark  { opacity: 1; }
.nav-logo:hover { opacity: .8; }

.nav-menu {
  list-style: none;
  display: flex; align-items: center;
  justify-content: center;
  gap: 4px;
  background: rgba(255,255,255,.6);
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 5px;
  backdrop-filter: blur(20px) saturate(1.4);
  -webkit-backdrop-filter: blur(20px) saturate(1.4);
  width: fit-content;
  margin: 0 auto;
  transition: background .4s var(--ease), border-color .4s var(--ease);
}
body.dark-frame .nav-menu {
  background: rgba(255,255,255,.06);
  border-color: rgba(255,255,255,.1);
}
.nav-link {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 9px 16px;
  font-family: var(--f-mono);
  font-size: 12px;
  letter-spacing: .02em;
  color: var(--muted);
  border-radius: 999px;
  transition: color .3s var(--ease), background .3s var(--ease);
  position: relative;
}
.nav-link .nl-num {
  font-size: 10px;
  color: var(--muted-2);
  font-variant-numeric: tabular-nums;
  transition: color .3s var(--ease);
}
.nav-link:hover { color: var(--ink); }
.nav-link:hover .nl-num { color: var(--blue-deep); }
body.dark-frame .nav-link { color: rgba(255,255,255,.55); }
body.dark-frame .nav-link .nl-num { color: rgba(255,255,255,.3); }
body.dark-frame .nav-link:hover { color: #fff; }
body.dark-frame .nav-link:hover .nl-num { color: var(--blue); }

.nav-link.active {
  background: var(--ink);
  color: #fff;
}
.nav-link.active .nl-num { color: var(--blue); }
body.dark-frame .nav-link.active {
  background: var(--blue);
  color: var(--ink);
}
body.dark-frame .nav-link.active .nl-num { color: var(--ink-2); }

.nav-progress {
  position: absolute;
  left: 0; right: 0; bottom: -1px;
  height: 1.5px;
  background: transparent;
  overflow: hidden;
  pointer-events: none;
}
.np-bar {
  position: absolute; left: 0; top: 0; bottom: 0;
  width: var(--progress, 0%);
  background: linear-gradient(to right, var(--blue), var(--blue-deep));
  transition: width .12s linear;
  box-shadow: 0 0 12px rgba(75,174,208,.6);
}

.nav-cta {
  font-family: var(--f-mono);
  font-size: 12px;
  letter-spacing: .02em;
  padding: 9px 16px;
  border-radius: 999px;
  background: var(--ink);
  color: #fff;
  display: inline-flex; align-items: center; gap: 8px;
  transition: background .3s var(--ease), transform .25s var(--ease);
  white-space: nowrap;
}
.nav-cta .arr { transition: transform .25s var(--ease); }
.nav-cta:hover { background: var(--blue-deep); transform: translateY(-1px); }
.nav-cta:hover .arr { transform: translateX(3px); }
body.dark-frame nav .nav-cta { background: var(--blue); color: var(--ink); }
body.dark-frame nav .nav-cta:hover { background: #fff; }

/* ───────────── EXPERIENCE ───────────── */
#experience {
  position: relative;
  z-index: 1;
}
.frame {
  position: relative;
  height: var(--frame-h);
}
.frame-pin {
  position: sticky;
  top: 0;
  height: 100vh;
  width: 100%;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
}

/* ─────────── FRAME 01 — HERO (galaxy / bokeh · dark immersif) ─────────── */
/* TRANSITION CINÉMATOGRAPHIQUE :
   - Hero plus court (130vh) → la zone de scroll-pin ne dure que 30vh
   - Statement (Approche) reçoit margin-top:-100vh + z-index inférieur
     → il glisse SOUS le hero pendant que celui-ci recule en profondeur
   - Aucun élément du hero ne bouge verticalement : tout se fait par scale + opacity
     → impression de recul dans la profondeur 3D au lieu de slide-up. */
#hero {
  height: 130vh;                /* override --frame-h pour réduire la zone de pin */
  z-index: 2;                   /* hero au-dessus pendant le fade */
  background: transparent;      /* on laisse passer le fond global #experience::before */
  color: #fff;
  /* CRITIQUE — #hero a height:130vh et #statement margin-top:-100vh donc
     #hero chevauche la moitié haute du viewport sur la zone Approche/scroll.
     Le <section> lui-même intercepterait les clics (boutons prev/next,
     tilt Atropos…) même avec une opacité=0. On annule donc le hit-test
     du section et on s'appuie sur .hero-pin (qui a son propre --p1-pe) pour
     gérer la cliquabilité dynamique de son contenu. */
  pointer-events: none;
}
#hero::before {
  /* On reproduit la nappe colorée originelle du hero en couche fade-able */
  content: '';
  position: absolute; inset: 0;
  background:
    radial-gradient(ellipse 70% 45% at 50% 0%, rgba(43,139,174,.35), transparent 60%),
    radial-gradient(ellipse 60% 40% at 50% 50%, rgba(43,139,174,.08), transparent 70%),
    linear-gradient(180deg, #04060A 0%, #060810 45%, #020306 80%, #000 100%);
  pointer-events: none;
  opacity: var(--p1-bg-op, 1);
  transition: opacity .15s linear;
  z-index: 0;
}
#statement {
  /* La section Approche démarre 100vh plus tôt en flow → elle remonte
     SOUS le hero et apparaît au fur et à mesure que le hero recule/fade. */
  margin-top: -100vh;
  z-index: 1;                   /* sous le hero pendant la transition */
  position: relative;           /* nécessaire pour z-index */
}
.hero-pin {
  display: block !important;
  padding: 0;
  opacity: var(--p1-content-op, 1);  /* fade global supplémentaire en fin de scroll */
  pointer-events: var(--p1-pe, auto);
  transition: opacity .15s linear;
}

/* ─── Background layers ─── */
.hero-bg {
  position: absolute; inset: 0;
  pointer-events: none;
  z-index: 0;
  overflow: hidden;
}

/* Faisceau central venant du haut — DÉSACTIVÉ
   (glow situé derrière la fresque de navigation, retiré sur demande) */
.hero-beam {
  display: none;
}
@keyframes beamIn { to { opacity: var(--p1-beam-op, 1); } }
@keyframes beamPulse {
  0%,100% { opacity: var(--p1-beam-op, 1); }
  50%     { opacity: calc(var(--p1-beam-op, 1) * .78); }
}

/* Wrapper parallaxe souris — translaté par les vars --mx/--my */
.hero-bg .parallax {
  position: absolute; inset: 0;
  pointer-events: none;
  will-change: transform;
  transition: transform .25s cubic-bezier(.2,.7,.2,1);
  transform: translate(
    calc(var(--mx, 0) * var(--depth, 1) * -32px),
    calc(var(--my, 0) * var(--depth, 1) * -22px)
  );
}

/* SOL EN PERSPECTIVE sous le logo — synth-wave floor (horizon BAS, perspective forte) */
.hero-floor {
  position: absolute;
  /* Étendu horizontalement pour couvrir les écrans plein écran ultra-larges. */
  left: -25%; right: -25%;
  bottom: 0;
  height: 42%;
  perspective: max(380px, 60vh);
  perspective-origin: 50% 0%;
  pointer-events: none;
  mix-blend-mode: screen;
  /* La GRILLE NE RECULE PAS visuellement (pas de scale).
     L'effet d'éloignement est donné par l'inversion + accélération
     de l'animation interne de la grille (cf. .hero-floor-grid). */
  opacity: var(--p1-floor-op, 1);
  will-change: opacity;
}
.hero-floor-grid {
  position: absolute;
  inset: 0;
  background-image:
    linear-gradient(rgba(107,190,214,.6) 1px, transparent 1px),
    linear-gradient(90deg, rgba(107,190,214,.6) 1px, transparent 1px);
  background-size: 70px 70px;
  /* Background-position piloté par JS via --grid-offset :
       - au repos : avance lentement vers le bas (lignes viennent vers le viewer)
       - au scroll : s'inverse et accélère (lignes filent vers l'horizon = éloignement) */
  background-position: 0 var(--grid-offset, 0px);
  transform-origin: 50% 0%;
  transform: rotateX(80deg) translateZ(0);
  -webkit-mask-image: linear-gradient(to bottom, transparent 0%, black 35%, black 92%, transparent 100%);
          mask-image: linear-gradient(to bottom, transparent 0%, black 35%, black 92%, transparent 100%);
  opacity: 0;
  animation: floorIn 1.2s .2s var(--ease) forwards;
}
@keyframes floorIn { to { opacity: 1; } }
.hero-floor-fade {
  position: absolute;
  top: 0; left: 0; right: 0;
  height: 35%;
  background:
    radial-gradient(ellipse 55% 100% at 50% 100%, rgba(107,190,214,.55), transparent 70%),
    linear-gradient(to bottom, rgba(43,139,174,.30), transparent);
  filter: blur(10px);
  opacity: 0;
  animation: floorIn 1.4s .3s var(--ease) forwards;
}

/* Fragments de code en arrière-plan, très subtils */
.hero-code {
  position: absolute; inset: 0;
  pointer-events: none;
  opacity: 0;
  animation: codeIn 1s .55s var(--ease) forwards;
  font-family: var(--f-mono);
  font-size: 10px;
  line-height: 1.55;
  color: rgba(107,190,214,.32);
  letter-spacing: .02em;
}
.hero-code.code-ready {
  opacity: var(--p1-code-op, 1);
  transition: opacity .15s linear;
}
@keyframes codeIn { to { opacity: 1; } }
.hc-block {
  position: absolute;
  white-space: pre;
  text-shadow: 0 0 6px rgba(107,190,214,.25);
}
.hc-1 { top: 6%;  left: 4%;  transform: perspective(800px) rotateY(8deg); }
.hc-2 { top: 12%; right: 4%; transform: perspective(800px) rotateY(-10deg); text-align: right; }
.hc-3 { bottom: 8%; left: 50%; transform: translateX(-50%); opacity: .7; }

/* Nébuleuse bleu/violet derrière le logo */
.hero-nebula {
  position: absolute;
  top: 50%; left: 50%;
  width: 65vw; height: 50vh;
  /* Recul en profondeur : scale dynamique + fade pilotés par scroll */
  transform: translate(-50%,-50%) scale(calc(.6 * var(--p1-nebula-s, 1)));
  opacity: var(--p1-nebula-op, 1);
  background:
    radial-gradient(ellipse 50% 40% at 50% 50%, rgba(107,190,214,.55), transparent 60%),
    radial-gradient(ellipse 30% 25% at 35% 60%, rgba(70,130,180,.35), transparent 55%),
    radial-gradient(ellipse 28% 22% at 70% 45%, rgba(80,140,200,.30), transparent 55%);
  filter: blur(60px);
  opacity: 0;
  animation: nebulaIn 1.3s .7s var(--ease-out) forwards,
             nebulaBreath 9s 2s ease-in-out infinite;
  mix-blend-mode: screen;
}
@keyframes nebulaIn {
  to { opacity: .9; transform: translate(-50%,-50%) scale(1); }
}
@keyframes nebulaBreath {
  0%,100% { opacity: .9; transform: translate(-50%,-50%) scale(1); }
  50%     { opacity: 1;  transform: translate(-50%,-50%) scale(1.06); }
}

/* Canvas particles : bokeh + dots */
#heroParticles {
  position: absolute; inset: 0;
  opacity: 0;
  animation: heroParticlesIn 1s .9s var(--ease) forwards;
}
/* Une fois l'entrée terminée, on applique l'opacité de scroll via la classe ajoutée en JS */
#heroParticles.particles-ready { opacity: var(--p1-particles-op, 1); transition: opacity .15s linear; }
@keyframes heroParticlesIn { to { opacity: 1; } }

/* ─── Centrage absolu du logo ─── */
.hero-center {
  position: absolute;
  top: 50%; left: 50%;
  /* RECUL EN PROFONDEUR : uniquement scale (vers <1 pour s'éloigner) + opacity.
     Aucun translateY → le logo ne bouge pas verticalement, il "s'éloigne". */
  transform: translate(-50%, -50%) scale(var(--p1-mark-s, 1));
  opacity: var(--p1-mark, 1);
  filter: blur(var(--p1-mark-blur, 0px));
  z-index: 2;
  display: grid;
  place-items: center;
  width: min(740px, 84vw);
  height: auto;
  will-change: transform, opacity, filter;
}

/* ─── Réticule (converge avant l'arrivée) ─── */
.hero-cross {
  position: absolute;
  inset: -80px;
  pointer-events: none;
  opacity: 0;
  animation: crossIn .3s .1s var(--ease) forwards,
             crossOut .4s .9s var(--ease) forwards;
}
@keyframes crossIn  { to { opacity: 1; } }
@keyframes crossOut { to { opacity: 0; transform: scale(1.08); } }
.cx {
  position: absolute;
  background: linear-gradient(to var(--dir, right), transparent, rgba(107,190,214,.7) 50%, transparent);
}
.cx-h {
  --dir: right;
  left: 0; right: 0; top: 50%;
  height: 1px;
  transform: scaleX(0);
  transform-origin: center;
  animation: cxExpand .6s .15s cubic-bezier(.77,0,.18,1) forwards;
}
.cx-v {
  --dir: bottom;
  top: 0; bottom: 0; left: 50%;
  width: 1px;
  transform: scaleY(0);
  transform-origin: center;
  animation: cxExpand .6s .25s cubic-bezier(.77,0,.18,1) forwards;
}
@keyframes cxExpand { to { transform: scaleX(1) scaleY(1); } }
.cx-ring {
  position: absolute;
  top: 50%; left: 50%;
  width: 18px; height: 18px;
  border: 1px solid rgba(107,190,214,.85);
  border-radius: 50%;
  box-shadow: 0 0 14px rgba(107,190,214,.5);
  transform: translate(-50%, -50%) scale(0);
  animation: cxRing .45s .5s var(--ease-spring) forwards,
             cxRingPulse 1s .85s ease-out forwards;
}
@keyframes cxRing { to { transform: translate(-50%,-50%) scale(1); } }
@keyframes cxRingPulse {
  to {
    transform: translate(-50%,-50%) scale(8);
    opacity: 0;
    border-width: 2px;
  }
}

/* ─── Brackets ─── */
.hero-brackets {
  position: absolute;
  inset: -28px -42px;
  pointer-events: none;
  opacity: 0;
  animation: bkIn .4s .7s var(--ease-out) forwards,
             bkOut .45s 1.6s var(--ease) forwards;
}
@keyframes bkIn  { to { opacity: 1; } }
@keyframes bkOut { to { opacity: 0; transform: scale(1.04); } }
.bk {
  position: absolute;
  width: 22px; height: 22px;
  border: 1.5px solid var(--blue);
  filter: drop-shadow(0 0 4px rgba(107,190,214,.5));
}
.bk-tl { top: 0; left: 0; border-right: 0; border-bottom: 0; }
.bk-tr { top: 0; right: 0; border-left: 0;  border-bottom: 0; }
.bk-bl { bottom: 0; left: 0; border-right: 0; border-top: 0; }
.bk-br { bottom: 0; right: 0; border-left: 0; border-top: 0; }

/* ─── Glow burst au moment du reveal ─── */
.hero-burst {
  position: absolute;
  top: 50%; left: 50%;
  width: 65%; height: 65%;
  transform: translate(-50%,-50%) scale(.2);
  background: radial-gradient(circle, rgba(107,190,214,.85), rgba(107,190,214,0) 65%);
  filter: blur(24px);
  opacity: 0;
  pointer-events: none;
  animation: burst .8s .85s var(--ease-out) forwards;
  mix-blend-mode: screen;
}
@keyframes burst {
  0%   { opacity: 0; transform: translate(-50%,-50%) scale(.2); }
  40%  { opacity: 1; }
  100% { opacity: 0; transform: translate(-50%,-50%) scale(2.6); }
}

/* ─── Logo : wipe + scale + breathing ─── */
.hero-mark {
  position: relative;
  display: block;
  width: 100%;
  will-change: transform, opacity, filter;
}
.hero-logo {
  width: 100%;
  height: auto;
  display: block;
  position: relative;
  z-index: 1;
  filter: drop-shadow(0 24px 60px rgba(0,0,0,.5)) drop-shadow(0 0 20px rgba(107,190,214,.18));
  opacity: 0;
  transform: scale(.94);
  animation: logoIn 1s .85s var(--ease-out) forwards,
             logoBreath 6s 2.2s ease-in-out infinite;
}
@keyframes logoIn {
  0%   { opacity: 0; transform: scale(.94); filter: drop-shadow(0 24px 60px rgba(0,0,0,.5)) drop-shadow(0 0 20px rgba(107,190,214,.18)) blur(8px); }
  60%  { opacity: 1; filter: drop-shadow(0 24px 60px rgba(0,0,0,.5)) drop-shadow(0 0 32px rgba(107,190,214,.7)) blur(0); }
  100% { opacity: 1; transform: scale(1); filter: drop-shadow(0 24px 60px rgba(0,0,0,.5)) drop-shadow(0 0 20px rgba(107,190,214,.22)) blur(0); }
}
@keyframes logoBreath {
  0%, 100% { transform: scale(1) translateY(0); }
  50%      { transform: scale(1.012) translateY(-2px); }
}
/* Voile sombre qui se rétracte de gauche à droite */
.mark-wipe {
  position: absolute; inset: 0;
  background: linear-gradient(90deg, #07090C 0%, #0A0C10 100%);
  z-index: 3;
  transform-origin: right center;
  animation: wipe .7s .9s cubic-bezier(.77,0,.18,1) forwards;
  pointer-events: none;
}
@keyframes wipe {
  0%   { transform: scaleX(1); }
  100% { transform: scaleX(0); }
}
/* Scan line bleue qui passe une fois sur le logo après le reveal */
.mark-scan {
  position: absolute;
  top: 0; bottom: 0;
  left: -10%;
  width: 28%;
  background: linear-gradient(90deg, transparent, rgba(107,190,214,.55) 50%, transparent);
  z-index: 2;
  opacity: 0;
  transform: skewX(-12deg);
  animation: scan 1.2s 1.4s var(--ease) forwards;
  mix-blend-mode: screen;
  pointer-events: none;
}
@keyframes scan {
  0%   { left: -20%; opacity: 0; }
  20%  { opacity: 1; }
  80%  { opacity: 1; }
  100% { left: 110%; opacity: 0; }
}

/* ─── Bas : caption + scroll cue (épurés, dark) ─── */
.hero-bottom {
  position: absolute;
  left: 0; right: 0;
  bottom: clamp(28px, 4vh, 56px);
  z-index: 3;
  display: flex; flex-direction: column; align-items: center;
  gap: 22px;
  /* Fade SANS translateY (recule au lieu de glisser vers le bas) */
  opacity: var(--p1-bottom, 1);
  transform: scale(var(--p1-bottom-s, 1));
  transform-origin: 50% 100%;
  pointer-events: none;
}
.hero-caption {
  display: inline-flex; align-items: center; gap: 16px;
  font-family: var(--f-mono);
  font-size: 11px;
  letter-spacing: .22em;
  text-transform: uppercase;
  color: rgba(255,255,255,.85);
  opacity: 0;
  animation: capIn .7s 1.5s var(--ease-out) forwards;
}
@keyframes capIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } }
.cap-line {
  width: 32px; height: 1px;
  background: linear-gradient(to right, transparent, rgba(255,255,255,.45), transparent);
}
.cap-text { font-weight: 500; }

/* CTA primaire du hero — pill blue + chevron, animation d'entrée propre */
.hero-cta {
  pointer-events: auto;
  display: inline-flex; align-items: center;
  gap: 10px;
  font-family: var(--f-mono);
  font-size: 13px;
  font-weight: 500;
  letter-spacing: .06em;
  padding: 14px 24px;
  border-radius: 999px;
  background: var(--blue);
  color: var(--ink);
  box-shadow:
    0 12px 36px -8px rgba(75,174,208,.55),
    0 0 0 1px rgba(255,255,255,.06) inset;
  opacity: 0;
  transform: translateY(10px);
  animation: capIn .7s 1.6s var(--ease-out) forwards;
  white-space: nowrap;
}
.hero-cta:hover {
  background: #fff;
  color: var(--ink);
  transform: translateY(-2px);
  box-shadow:
    0 18px 48px -8px rgba(75,174,208,.7),
    0 0 0 1px rgba(255,255,255,.1) inset;
}
.hero-cta .arr { transition: transform .25s var(--ease); display: inline-block; }
.hero-cta:hover .arr { transform: translateX(4px); }

.hero-scroll {
  display: inline-flex; flex-direction: column; align-items: center;
  gap: 10px;
  font-family: var(--f-mono);
  font-size: 9.5px;
  letter-spacing: .3em;
  text-transform: uppercase;
  color: rgba(255,255,255,.5);
  opacity: 0;
  animation: capIn .7s 1.75s var(--ease-out) forwards;
}
.hs-rail {
  position: relative;
  width: 1px; height: 38px;
  background: linear-gradient(to bottom, transparent, rgba(255,255,255,.35), transparent);
  overflow: hidden;
}
.hs-bead {
  position: absolute;
  top: -8px; left: 50%;
  width: 4px; height: 12px;
  margin-left: -2px;
  background: var(--blue);
  border-radius: 2px;
  box-shadow: 0 0 10px rgba(107,190,214,.8);
  animation: bead 2s 2s var(--ease) infinite;
}
@keyframes bead {
  0%   { top: -12px; opacity: 0; }
  20%  { opacity: 1; }
  80%  { opacity: 1; }
  100% { top: 38px; opacity: 0; }
}

/* Sécurité : si jamais des HUD restent dans le DOM, on les masque */
.hero-hud { display: none !important; }

.hero-bottom { transition: opacity .3s linear; }
#dust, #neuralnet, #matrixRain, #orbField {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  pointer-events: none;
}
#neuralnet { z-index: 1; opacity: var(--p1-net, .55); mix-blend-mode: multiply; }

/* Data stream overlay (frame 1) */
.data-stream {
  position: absolute;
  top: 0; left: 0; right: 0; bottom: 0;
  font-family: var(--f-mono);
  font-size: 11px;
  color: rgba(75,174,208,.55);
  letter-spacing: .04em;
  pointer-events: none;
  z-index: 2;
}
.ds-line {
  position: absolute;
  white-space: nowrap;
  opacity: 0;
  transform: translateX(-20px);
  animation: dsAppear 6s ease-in-out infinite;
}
.ds-l1 { top: 18%; left: 6%; animation-delay: 0s; }
.ds-l2 { top: 28%; right: 8%; animation-delay: 1.5s; }
.ds-l3 { bottom: 26%; left: 8%; animation-delay: 3s; }
.ds-l4 { bottom: 18%; right: 6%; animation-delay: 4.5s; }
@keyframes dsAppear {
  0%, 5% { opacity: 0; transform: translateX(-20px); }
  10%, 70% { opacity: 1; transform: translateX(0); }
  85%, 100% { opacity: 0; transform: translateX(20px); }
}

/* Scan line sweep */
.scan-line {
  position: absolute;
  left: 0; right: 0;
  height: 2px;
  background: linear-gradient(to right, transparent, rgba(75,174,208,.5), transparent);
  top: var(--scan-y, -10%);
  z-index: 1;
  pointer-events: none;
  box-shadow: 0 0 24px rgba(75,174,208,.6);
  opacity: var(--scan-op, 0);
}

/* Matrix rain (frame 2) */
#matrixRain {
  z-index: 0;
  opacity: var(--p2-rain, .35);
}

/* Circuit lines (frame 2) */
.circuit-lines {
  position: absolute; inset: 0;
  z-index: 0;
  color: rgba(75,174,208,.45);
  opacity: var(--p2-circuit, 0);
  pointer-events: none;
}
.circuit-lines svg { width: 100%; height: 100%; }
.circuit-lines path {
  stroke-dasharray: 2000;
  stroke-dashoffset: var(--circuit-draw, 2000);
  filter: drop-shadow(0 0 4px rgba(75,174,208,.6));
}
.circuit-lines circle {
  opacity: var(--circuit-nodes, 0);
  filter: drop-shadow(0 0 6px rgba(75,174,208,.8));
}

/* Hex pattern bg (frame 3) */
.hex-bg {
  position: absolute; inset: 0;
  color: rgba(43,139,174,.18);
  z-index: 0;
  opacity: var(--p3-hex, 0);
  pointer-events: none;
  transform: scale(var(--p3-hex-s, 1.2)) rotate(var(--p3-hex-rot, 0deg));
  transform-origin: center;
  will-change: transform, opacity;
}
.hex-bg svg { width: 100%; height: 100%; }

/* Process circuit bg (frame 4) */
.proc-bg-circuit {
  position: absolute; inset: 0;
  z-index: 0;
  pointer-events: none;
  color: rgba(43,139,174,.25);
}
.proc-bg-circuit svg { width: 100%; height: 100%; }
.proc-bg-circuit path {
  stroke-dasharray: 4000;
  stroke-dashoffset: var(--p4-trace, 4000);
  filter: drop-shadow(0 0 4px rgba(75,174,208,.4));
}
.trace-pulse {
  position: absolute;
  width: 8px; height: 8px; border-radius: 50%;
  background: var(--blue);
  top: 100px; left: 100px;
  box-shadow: 0 0 20px var(--blue), 0 0 40px var(--blue);
  opacity: var(--p4-pulse, 0);
  animation: tracePulse 6s linear infinite;
}
@keyframes tracePulse {
  0%   { top: 100px; left: 100px; }
  25%  { top: 100px; left: calc(100% - 100px); }
  50%  { top: calc(100% - 100px); left: calc(100% - 100px); }
  75%  { top: calc(100% - 100px); left: 100px; }
  100% { top: 100px; left: 100px; }
}

/* AI core (frame 5) */
#orbField { z-index: 1; opacity: var(--p5-orbs, 0); }
.ai-core {
  position: absolute;
  top: 50%; left: 50%;
  width: 1px; height: 1px;
  transform: translate(-50%, -50%) scale(var(--p5-core, 0));
  pointer-events: none;
  z-index: 1;
  opacity: var(--p5-core-op, 0);
}
.core-ring {
  position: absolute;
  top: 50%; left: 50%;
  border: 1px solid rgba(107,190,214,.4);
  border-radius: 50%;
  transform: translate(-50%, -50%);
}
.core-ring.r1 { width: 200px; height: 200px; animation: coreSpin 8s linear infinite; border-style: dashed; }
.core-ring.r2 { width: 360px; height: 360px; animation: coreSpin 14s linear infinite reverse; border-color: rgba(107,190,214,.25); }
.core-ring.r3 { width: 540px; height: 540px; animation: coreSpin 22s linear infinite; border-color: rgba(107,190,214,.15); border-style: dotted; }
.core-dot {
  position: absolute;
  top: 50%; left: 50%;
  width: 14px; height: 14px;
  border-radius: 50%;
  background: var(--blue);
  transform: translate(-50%, -50%);
  box-shadow: 0 0 24px var(--blue), 0 0 48px var(--blue);
  animation: corePulse 2.4s ease-in-out infinite;
}
@keyframes coreSpin {
  to { transform: translate(-50%, -50%) rotate(360deg); }
}
@keyframes corePulse {
  0%, 100% { transform: translate(-50%, -50%) scale(1); }
  50% { transform: translate(-50%, -50%) scale(1.5); }
}

.hero-stage {
  /* legacy — superseded by .hero-center */
  display: none;
}

/* ═══════════════════════════════════════════════════
   FRAME 02 — APPROCHE / Portfolio rotatif 3D
   - Carte glassmorphism en perspective avec mockup SaaS
   - Texte/description sur la droite
   - Navigation prev/next + dots
═════════════════════════════════════════════════════ */
.frame-approach { background: var(--ink); color: #fff; }
.frame-approach .frame-pin {
  background: transparent;
  padding: 72px 6%;
  align-items: center;
  justify-content: center;
}

/* Conteneur principal — grille éditoriale asymétrique
   (texte à gauche, écran 3D à droite ; le nuage de points reste visible
   tout autour et participe à la profondeur de la composition). */
.approach-wrap {
  width: 100%;
  max-width: 1180px;
  margin: 0 auto;
  display: grid;
  grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.18fr);
  align-items: center;
  gap: clamp(32px, 5vw, 76px);
  text-align: left;
  opacity: var(--p2-cam-op, 1);
  /* Entrée (--p2-cam-y) + parallax de sortie (--approach-lift) appliqués au
     BLOC ENTIER → tout monte de façon solidaire, aucun chevauchement. */
  transform: translateY(calc(var(--p2-cam-y, 30px) + var(--approach-lift, 0px)));
  will-change: transform, opacity;
}

/* ═══════════════════════════════════════════════════
   COLONNE GAUCHE — intro, métadonnées scan, index des écrans
═════════════════════════════════════════════════════ */
.approach-intro {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 26px;
}
.approach-header {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 14px;
}
.approach-intro .approach-lead { max-width: 460px; }
.approach-intro .approach-tags { justify-content: flex-start; }

/* ───── Index des écrans — petits traits qui sortent DERRIÈRE la fenêtre ─────
   La nav est positionnée en absolu, calée sur le bord droit de la fenêtre 3D
   et placée SOUS elle (z-index inférieur). Seuls de courts traits + le titre
   en petit dépassent du bord droit. Clic = changement d'image. */
.approach-nav {
  position: relative;
  z-index: 1;                 /* DERRIÈRE la fenêtre (.approach-show = z-index 2) */
  flex: 0 0 auto;
  width: 122px;
  /* Glisse de 20px derrière le bord droit de la fenêtre : c'est de là que
     « sortent » les traits. Les titres, eux, restent dans le clair à droite. */
  margin-left: -20px;
  display: flex;
  flex-direction: column;
  gap: 17px;
}
.an-item {
  position: relative;
  display: flex;
  align-items: center;
  gap: 9px;
  width: 100%;
  padding: 2px 0;
  border: none;
  background: none;
  cursor: pointer;
  text-align: left;
  color: rgba(255,255,255,.5);
  transition: color .35s var(--ease),
              opacity .6s var(--ease-out), transform .6s var(--ease-out);
}
/* Le petit trait : largeur FIXE (titres alignés) ; ses ~20px de gauche sont
   masqués derrière la vitre → il ne dépasse que de quelques px sur le bord. */
.an-item::before {
  content: '';
  flex: 0 0 auto;
  width: 34px;
  height: 1.5px;
  border-radius: 2px;
  background: rgba(255,255,255,.4);
  transition: background .35s var(--ease), height .25s var(--ease),
              box-shadow .35s var(--ease);
}
.an-num { display: none; }    /* numéro retiré : on garde trait + titre */
.an-label {
  font-family: var(--f-sans);
  font-size: 11.5px;
  font-weight: 500;
  letter-spacing: -.01em;
  white-space: nowrap;
}
.an-bar { display: none; }    /* barre de progression retirée (rendu épuré) */

.an-item:hover { color: #fff; }
.an-item:hover::before { background: rgba(255,255,255,.7); }
.an-item.active { color: #fff; }
.an-item.active::before {
  height: 2px;
  background: var(--blue);
  box-shadow: 0 0 9px rgba(107,190,214,.7);
}
/* État masqué initial (cascade au scroll) */
.approach-nav.is-hidden .an-item { opacity: 0; transform: translateX(14px); }

/* ═══════════════════════════════════════════════════
   COLONNE DROITE — écran du projet flottant en 3D
   « Scan Room » : l'écran est incliné en perspective au-dessus
   du nuage de points, avec parallaxe souris, cadre lumineux,
   reflet et repères d'angle type viseur.
═════════════════════════════════════════════════════ */
/* Bloc droit : fenêtre 3D + index accolé à son bord droit (en flux).
   L'index glisse de quelques px DERRIÈRE la fenêtre (marge négative + z-index
   inférieur) : les traits naissent sous la vitre, les titres dépassent à droite. */
.approach-showcase {
  position: relative;
  display: flex;
  align-items: center;
  width: 100%;
}
.approach-show {
  position: relative;
  z-index: 2;               /* AU-DESSUS de l'index → masque le départ des traits */
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  justify-content: center;
}
.av-stage3d {
  position: relative;
  width: 100%;
  max-width: 660px;
  perspective: 1500px;
  perspective-origin: 50% 42%;
  transition: opacity 1s var(--ease-out), transform 1s var(--ease-out);
}

/* Le cadre : porte l'inclinaison 3D (base + parallaxe souris via --mx/--my) */
.av-frame {
  --base-rx: 7deg;
  --base-ry: -15deg;
  --mx: 0deg; --my: 0deg;
  position: relative;
  border-radius: 16px;
  overflow: hidden;
  background: var(--ink-2);
  border: 1px solid rgba(255,255,255,.1);
  transform-style: preserve-3d;
  transform:
    rotateX(calc(var(--base-rx) + var(--mx)))
    rotateY(calc(var(--base-ry) + var(--my)));
  box-shadow:
    0 50px 90px -28px rgba(0,0,0,.85),
    0 0 0 1px rgba(255,255,255,.03) inset,
    -34px 28px 70px -44px rgba(107,190,214,.4);
  will-change: transform;
}
/* Liseré lumineux bleu sur le pourtour du cadre */
.av-frame::before {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: 16px;
  padding: 1px;
  background: linear-gradient(135deg,
    rgba(107,190,214,.7), rgba(107,190,214,0) 38%,
    rgba(107,190,214,0) 62%, rgba(107,190,214,.3));
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
          mask-composite: exclude;
  pointer-events: none;
  z-index: 5;
}

/* Barre « navigateur » */
.av-bar {
  display: flex;
  align-items: center;
  gap: 14px;
  height: 40px;
  padding: 0 14px;
  background: linear-gradient(180deg, rgba(255,255,255,.06), rgba(255,255,255,.02));
  border-bottom: 1px solid rgba(255,255,255,.07);
}
.av-dots { display: flex; gap: 7px; flex: 0 0 auto; }
.av-dots i { width: 11px; height: 11px; border-radius: 50%; background: rgba(255,255,255,.18); }
.av-dots i:first-child  { background: rgba(255,95,86,.85); }
.av-dots i:nth-child(2) { background: rgba(255,189,46,.85); }
.av-dots i:last-child   { background: rgba(39,201,63,.85); }
.av-url {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  margin: 0 auto;
  padding: 4px 14px;
  border-radius: 999px;
  background: rgba(0,0,0,.35);
  border: 1px solid rgba(255,255,255,.06);
  font-family: var(--f-mono);
  font-size: 11px;
  letter-spacing: .02em;
  color: rgba(255,255,255,.5);
  max-width: 70%;
}
.av-url svg { color: var(--blue); flex: 0 0 auto; }
.av-url-text { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.av-url-text b { color: rgba(255,255,255,.82); font-weight: 500; }

/* Scène : ratio fixe, couches superposées en crossfade */
.av-screen {
  position: relative;
  width: 100%;
  aspect-ratio: 16 / 9.6;
  background: #07080b;
  overflow: hidden;
}
.av-layer {
  position: absolute;
  inset: 0;
  opacity: 0;
  transform: scale(1.05);
  transition: opacity .8s var(--ease), transform 1.3s var(--ease);
  will-change: opacity, transform;
}
.av-layer.is-active { opacity: 1; transform: scale(1); z-index: 1; }
.av-layer img {
  display: block;
  width: 100%; height: 100%;
  object-fit: cover;
  object-position: top center;
  pointer-events: none;
}

/* Reflet diagonal sur la vitre */
.av-sheen {
  position: absolute;
  inset: 0;
  z-index: 3;
  pointer-events: none;
  background: linear-gradient(118deg,
    rgba(255,255,255,.16) 0%, rgba(255,255,255,0) 24%,
    rgba(255,255,255,0) 100%);
  mix-blend-mode: screen;
}

/* Repères d'angle (HUD viseur) */
.av-ticks i {
  position: absolute;
  width: 14px; height: 14px;
  z-index: 6;
  pointer-events: none;
}
.av-ticks i:nth-child(1) { top: 9px;  left: 9px;
  border-top: 1.5px solid rgba(107,190,214,.6); border-left: 1.5px solid rgba(107,190,214,.6); }
.av-ticks i:nth-child(2) { top: 9px;  right: 9px;
  border-top: 1.5px solid rgba(107,190,214,.6); border-right: 1.5px solid rgba(107,190,214,.6); }
.av-ticks i:nth-child(3) { bottom: 9px; left: 9px;
  border-bottom: 1.5px solid rgba(107,190,214,.6); border-left: 1.5px solid rgba(107,190,214,.6); }
.av-ticks i:nth-child(4) { bottom: 9px; right: 9px;
  border-bottom: 1.5px solid rgba(107,190,214,.6); border-right: 1.5px solid rgba(107,190,214,.6); }

/* ── ENTRÉE EN CASCADE (stagger) ── */
.approach-show.is-hidden .av-stage3d {
  opacity: 0;
  transform: translateY(46px);
}

/* ═══════════════════════════════════════════════════
   TEXTE DE LA SECTION
═════════════════════════════════════════════════════ */
/* ───── TEXTE EN-TÊTE ───── */
.approach-title {
  font-family: var(--f-sans);
  font-size: clamp(30px, 4vw, 52px);
  font-weight: 700;
  line-height: 1.05;
  letter-spacing: -.03em;
  color: #fff;
  text-wrap: balance;
}

.approach-lead {
  font-size: clamp(14px, 1.1vw, 17px);
  color: rgba(255,255,255,.72);
  line-height: 1.55;
  max-width: 600px;
  font-weight: 400;
  text-wrap: pretty;
}

/* ───── TAGS ───── */
.approach-tags {
  display: flex; flex-wrap: wrap;
  justify-content: center;
  gap: 7px;
}
.approach-tags .tag {
  display: inline-flex; align-items: center;
  padding: 5px 11px;
  border-radius: 999px;
  font-family: var(--f-mono);
  font-size: 10.5px;
  letter-spacing: .06em;
  color: rgba(255,255,255,.65);
  background: rgba(255,255,255,.04);
  border: 1px solid rgba(255,255,255,.1);
}

/* ───── RESPONSIVE — empilement sous 980px ───── */
@media (max-width: 980px) {
  /* Une seule colonne : intro au-dessus, écran 3D en dessous, centrés */
  .approach-wrap {
    grid-template-columns: 1fr;
    justify-items: center;
    text-align: center;
    gap: 28px;
    max-width: 640px;
  }
  .approach-intro { align-items: center; text-align: center; gap: 18px; }
  .approach-header { align-items: center; gap: 10px; }
  .approach-intro .approach-lead { max-width: 540px; }
  .approach-intro .approach-tags { justify-content: center; }

  /* En 1 colonne : nav au-dessus de la fenêtre 3D. */
  .approach-showcase { flex-direction: column; gap: 14px; }
  .approach-nav {
    order: -1;
    width: auto;
    margin-left: 0;
    flex-direction: row;
    flex-wrap: wrap;
    justify-content: center;
    gap: 6px 16px;
  }
  /* Items : largeur auto pour tenir en ligne plutôt qu'occuper 100% */
  .an-item { width: auto; }
  /* Le trait reste, plus court, devant chaque titre en ligne */
  .an-item::before { width: 16px; }
  .an-item.active::before { width: 22px; }

  /* Inclinaison 3D adoucie de face quand l'écran passe pleine largeur */
  .av-frame { --base-rx: 4deg; --base-ry: -7deg; }
}

@media (max-width: 600px) {
  .frame-approach .frame-pin { padding: 44px 5%; }

  /* Pile compactée pour tenir dans 100svh sans rognage haut/bas */
  .approach-wrap { gap: 18px; }
  .approach-intro { gap: 14px; }
  .approach-header { gap: 8px; }
  .approach-showcase { gap: 12px; }
  /* Fenêtre 3D plafonnée → réduit la hauteur via le ratio 16/9.6 */
  .av-stage3d { max-width: 320px; }
  .av-frame { --base-rx: 3deg; --base-ry: -4deg; }
  .av-bar { height: 32px; padding: 0 10px; }
  .av-dots i { width: 8px; height: 8px; }
  .av-url { font-size: 10px; padding: 3px 10px; max-width: 80%; }

  .an-item { padding: 4px 8px; }
  .an-label { font-size: 11px; }
  .approach-lead { font-size: 13px; line-height: 1.5; }
  .approach-tags { gap: 5px; }
  .approach-tags .tag { font-size: 9.5px; padding: 3px 8px; }
}

/* ═══════════════════════════════════════════════════
   TRANSITION RÉALISATIONS → SERVICES — Parallax doux vertical
   ─────────────────────────────────────────────────────
   Pas de section tampon, pas d'overlay : la continuité visuelle vient
   d'un léger lift vertical de .approach-stage en fin de Réalisations
   (var --approach-lift pilotée par scroll-exp.js, frame 2).
   Le lift fait remonter la carte LÉGÈREMENT plus vite que le scroll
   naturel → effet parallax, puis Services prend le relais avec ses
   propres animations natives (--p3-head, --p3-c{1,2,3}).
   ─────────────────────────────────────────────────────
   Le lift (--approach-lift) est désormais appliqué à .approach-wrap
   (bloc entier) et non plus aux seules vignettes → cf. règle .approach-wrap.
═════════════════════════════════════════════════════ */
@media (prefers-reduced-motion: reduce) {
  .approach-wrap { transform: translateY(var(--p2-cam-y, 0px)) !important; }
}

/* === Legacy .statement (anciennes règles encore référencées plus bas) === */
.statement {
  max-width: 1200px;
  width: 100%;
  transform: scale(var(--p2-cam-s, 1));
  opacity: var(--p2-cam-op, 1);
  will-change: transform, opacity;
}
.st-eyebrow {
  font-family: var(--f-mono);
  font-size: 12px;
  letter-spacing: .08em;
  color: rgba(255,255,255,.4);
  text-transform: uppercase;
  margin-bottom: 32px;
  display: flex; align-items: center; gap: 12px;
  opacity: var(--p2-eyebrow, 0);
  transform: translateY(var(--p2-eyebrow-y, 30px));
}
.st-eyebrow::before {
  content: ''; width: 24px; height: 1px; background: var(--blue);
}
.st-text {
  font-family: var(--f-sans);
  font-weight: 600;
  font-size: clamp(36px, 6.4vw, 96px);
  line-height: 1.05;
  letter-spacing: -.04em;
  color: #fff;
  text-wrap: balance;
}
.st-text .w {
  display: inline-block;
  opacity: var(--p2-words, 0);
  transform: translateY(var(--p2-words-y, 50px));
  margin-right: .25em;
  transition: opacity .8s var(--ease-out), transform .8s var(--ease-out);
}
.st-text .accent { color: var(--blue); }
.st-text .muted { color: rgba(255,255,255,.35); }
.st-text .italic {
  font-family: var(--f-serif);
  font-style: italic;
  font-weight: 400;
  color: var(--blue);
}
/* Stagger via custom prop set per word index */
.st-text .w:nth-child(1)  { transition-delay: 0ms; }
.st-text .w:nth-child(2)  { transition-delay: 50ms; }
.st-text .w:nth-child(3)  { transition-delay: 100ms; }
.st-text .w:nth-child(4)  { transition-delay: 150ms; }
.st-text .w:nth-child(5)  { transition-delay: 220ms; }
.st-text .w:nth-child(6)  { transition-delay: 270ms; }
.st-text .w:nth-child(7)  { transition-delay: 320ms; }
.st-text .w:nth-child(8)  { transition-delay: 370ms; }
.st-text .w:nth-child(9)  { transition-delay: 440ms; }
.st-text .w:nth-child(10) { transition-delay: 490ms; }
.st-text .w:nth-child(11) { transition-delay: 540ms; }
.st-text .w:nth-child(12) { transition-delay: 590ms; }

/* ─────────── FRAME 03 — SERVICES ─────────── */
.frame-services { background: var(--bg-soft); }
.frame-services .frame-pin {
  background: var(--bg-soft);
  padding: 80px 6%;
  align-items: flex-start;
}
.svc-stack {
  width: 100%;
  max-width: 1200px;
  margin: 0 auto;
  display: flex; flex-direction: column;
  gap: 24px;
  height: 100%;
  justify-content: center;
}
.svc-head {
  margin-bottom: 8px;
  opacity: var(--p3-head, 0);
  /* Le head arrive "trop près" (inverse de l'animation logo du hero) :
     scale 1.14 → 1 + blur 14px → 0, en plus du slide vertical existant.
     Effet de rack-focus / zoom-out qui se cale. */
  transform: translateY(var(--p3-head-y, 30px)) scale(var(--p3-head-s, 1.14));
  filter: blur(var(--p3-head-blur, 14px));
  will-change: transform, opacity, filter;
}
.kicker {
  display: inline-block;
  font-family: var(--f-mono);
  font-size: 11px;
  letter-spacing: .08em;
  color: var(--blue-deep);
  text-transform: uppercase;
  margin-bottom: 14px;
}
.svc-head h2 {
  font-family: var(--f-sans);
  font-size: clamp(32px, 4vw, 56px);
  font-weight: 700;
  line-height: 1.05;
  letter-spacing: -.03em;
  color: var(--ink);
  text-wrap: balance;
}
.svc-row {
  display: grid;
  grid-template-columns: 64px 1fr 110px;
  gap: 32px;
  align-items: center;
  padding: 22px 28px;
  background: #fff;
  border: 1px solid var(--line);
  border-radius: 18px;
  opacity: var(--svc-op, 0);
  /* Effet "trop près → normal" (inverse de l'animation logo hero) :
     scale > 1 qui se réduit à 1 + filter blur qui se dissout.
     Composé avec le slide latéral/vertical et la rotation existants. */
  transform: translate(var(--svc-x, 0), var(--svc-y, 40px)) scale(var(--svc-s, 1.18)) rotate(var(--svc-rot, 0deg));
  filter: blur(var(--svc-blur, 16px));
  box-shadow: 0 8px 30px -16px rgba(10,12,16,.05);
  transition: box-shadow .3s var(--ease);
  transform-origin: center center;
  will-change: transform, opacity, filter;
}
.svc-row:hover {
  box-shadow: 0 16px 48px -12px rgba(10,12,16,.12);
}
.svc-1 { --svc-op: var(--p3-c1, 0); --svc-x: var(--p3-c1-x, 0); --svc-y: var(--p3-c1-y, 40px); --svc-s: var(--p3-c1-s, 1.18); --svc-rot: var(--p3-c1-rot, 0deg); --svc-blur: var(--p3-c1-blur, 16px); }
.svc-2 { --svc-op: var(--p3-c2, 0); --svc-x: var(--p3-c2-x, 0); --svc-y: var(--p3-c2-y, 40px); --svc-s: var(--p3-c2-s, 1.18); --svc-rot: var(--p3-c2-rot, 0deg); --svc-blur: var(--p3-c2-blur, 16px); }
.svc-3 { --svc-op: var(--p3-c3, 0); --svc-x: var(--p3-c3-x, 0); --svc-y: var(--p3-c3-y, 40px); --svc-s: var(--p3-c3-s, 1.18); --svc-rot: var(--p3-c3-rot, 0deg); --svc-blur: var(--p3-c3-blur, 16px); }
.svc-num {
  font-family: var(--f-mono);
  font-size: 13px;
  color: var(--muted-2);
  border-right: 1px solid var(--line);
  padding-right: 24px;
  height: 60px;
  display: flex; align-items: center;
}
.svc-info h3 {
  font-family: var(--f-sans);
  font-size: clamp(20px, 1.8vw, 26px);
  font-weight: 600;
  letter-spacing: -.02em;
  color: var(--ink);
  margin-bottom: 6px;
}
.svc-info p {
  font-size: 14px;
  color: var(--muted);
  line-height: 1.55;
  max-width: 540px;
}
.svc-glyph {
  color: var(--blue-deep);
  width: 100%;
}
.svc-glyph svg { width: 100%; height: auto; }

/* ─────────── FRAME 04 — PROCESS ─────────── */
.frame-process { background: var(--bg); }
.proc-wrap {
  display: grid;
  grid-template-columns: .9fr 1.2fr;
  gap: 80px;
  align-items: start;
  width: 100%;
  max-width: 1200px;
  margin: 0 auto;
  padding: 0 6%;
}
.proc-head {
  position: sticky; top: 0;
  opacity: var(--p4-head, 0);
  transform: translateY(var(--p4-head-y, 30px));
}
.proc-head h2 {
  font-family: var(--f-sans);
  font-size: clamp(32px, 4vw, 56px);
  font-weight: 700;
  line-height: 1.05;
  letter-spacing: -.03em;
  color: var(--ink);
  text-wrap: balance;
}
.proc-list {
  list-style: none;
  display: flex; flex-direction: column;
  gap: 0;
  border-top: 1px solid var(--line);
}
.proc-list li {
  display: grid;
  grid-template-columns: 64px 1fr;
  gap: 24px;
  padding: 28px 0;
  border-bottom: 1px solid var(--line);
  opacity: var(--proc-op, 0);
  transform: translateX(var(--proc-x, 30px)) rotate(var(--proc-rot, 0deg));
  transform-origin: left center;
  will-change: transform, opacity;
}
.proc-list li:nth-child(1) { --proc-op: var(--p4-1, 0); --proc-x: var(--p4-1-x, 30px); --proc-rot: var(--p4-1-rot, 0deg); }
.proc-list li:nth-child(2) { --proc-op: var(--p4-2, 0); --proc-x: var(--p4-2-x, 30px); --proc-rot: var(--p4-2-rot, 0deg); }
.proc-list li:nth-child(3) { --proc-op: var(--p4-3, 0); --proc-x: var(--p4-3-x, 30px); --proc-rot: var(--p4-3-rot, 0deg); }
.proc-list li:nth-child(4) { --proc-op: var(--p4-4, 0); --proc-x: var(--p4-4-x, 30px); --proc-rot: var(--p4-4-rot, 0deg); }
.pn {
  font-family: var(--f-mono);
  font-size: 12px;
  color: var(--blue-deep);
  letter-spacing: .04em;
  padding-top: 4px;
}
.proc-list h4 {
  font-family: var(--f-sans);
  font-size: 22px;
  font-weight: 600;
  letter-spacing: -.02em;
  color: var(--ink);
  margin-bottom: 6px;
}
.proc-list p {
  font-size: 15px;
  color: var(--muted);
  line-height: 1.6;
  max-width: 460px;
}

/* ─────────── FRAME 05 — CONTACT ─────────── */
.frame-contact { background: var(--ink); color: #fff; }
.frame-contact .frame-pin {
  background: var(--ink);
  padding: 0 6%;
}
.frame-contact .frame-pin::before {
  content: '';
  position: absolute;
  width: 80vmin; height: 80vmin;
  top: 50%; left: 50%;
  transform: translate(-50%, -50%);
  background: radial-gradient(circle, rgba(75,174,208,.18) 0%, rgba(75,174,208,0) 60%);
  filter: blur(12px);
  pointer-events: none;
}
.contact-wrap {
  position: relative;
  z-index: 2;
  text-align: center;
  max-width: 900px;
  width: 100%;
  opacity: var(--p5-op, 0);
  transform: translateY(var(--p5-y, 40px)) scale(var(--p5-s, .9));
  will-change: transform, opacity;
}
.frame-contact .frame-pin::before {
  transform: translate(-50%, -50%) scale(var(--p5-glow, 1));
}
.frame-contact .kicker { color: var(--blue); }
.contact-title {
  font-family: var(--f-sans);
  font-size: clamp(48px, 8vw, 128px);
  font-weight: 700;
  line-height: .98;
  letter-spacing: -.04em;
  margin: 4px 0 28px;
  text-wrap: balance;
}
.contact-title em {
  font-family: var(--f-serif);
  font-style: italic;
  font-weight: 400;
  color: var(--blue);
}
.contact-sub {
  font-size: clamp(15px, 1.3vw, 18px);
  color: rgba(255,255,255,.55);
  max-width: 540px;
  margin: 0 auto 44px;
  line-height: 1.6;
  text-wrap: pretty;
}
.contact-actions {
  display: flex; gap: 14px;
  justify-content: center;
  flex-wrap: wrap;
  margin-bottom: 52px;
}
.ca-btn {
  display: inline-flex; align-items: center; gap: 12px;
  font-family: var(--f-mono);
  font-size: 14px;
  letter-spacing: .01em;
  padding: 18px 28px;
  border-radius: 999px;
  transition: all .3s var(--ease);
}
.ca-primary {
  background: var(--blue);
  color: var(--ink);
  box-shadow: 0 12px 36px -8px rgba(75,174,208,.5);
}
.ca-primary:hover {
  background: #fff;
  transform: translateY(-2px);
  box-shadow: 0 18px 48px -8px rgba(75,174,208,.7);
}
.ca-primary .arr { transition: transform .25s var(--ease); }
.ca-primary:hover .arr { transform: translateX(4px); }
.ca-ghost {
  border: 1px solid rgba(255,255,255,.18);
  color: rgba(255,255,255,.85);
}
.ca-ghost:hover {
  background: rgba(255,255,255,.08);
  border-color: rgba(255,255,255,.4);
}
.contact-foot {
  display: flex; justify-content: space-between;
  font-family: var(--f-mono);
  font-size: 11px;
  color: rgba(255,255,255,.3);
  letter-spacing: .04em;
  text-transform: uppercase;
  padding-top: 28px;
  border-top: 1px solid rgba(255,255,255,.08);
  flex-wrap: wrap;
  gap: 8px;
}

/* ───────────── FRAME INDICATOR ───────────── */
.frame-indicator {
  position: fixed;
  right: 32px;
  top: 50%;
  transform: translateY(-50%);
  z-index: 90;
  display: flex; flex-direction: column; align-items: center;
  gap: 12px;
  font-family: var(--f-mono);
  font-size: 12px;
  letter-spacing: .04em;
  color: var(--muted);
  pointer-events: none;
  mix-blend-mode: difference;
  filter: invert(1) brightness(2);
}
.fi-num {
  font-size: 32px;
  font-weight: 500;
  color: var(--ink);
  font-family: var(--f-sans);
  letter-spacing: -.02em;
  font-variant-numeric: tabular-nums;
  transition: opacity .3s;
}
.fi-line {
  width: 1px;
  height: 80px;
  background: var(--muted-2);
  position: relative;
  overflow: hidden;
}
.fi-line::after {
  content: '';
  position: absolute;
  inset: 0 0 calc(100% - var(--frame-progress, 0%)) 0;
  background: var(--ink);
}
.fi-tot {
  font-size: 12px;
  color: var(--muted-2);
}

/* ───────────── RESPONSIVE ───────────── */
@media (max-width: 900px) {
  /* iOS Safari : svh (small viewport height) reste STABLE quand la barre
     d'adresse apparaît/disparaît → plus de saut de contenu, plus rien masqué
     derrière la barre système. Le pin, le hero et le chevauchement
     hero→statement utilisent tous svh pour rester alignés au pixel.
     Fallback automatique sur 100vh si le navigateur ne connaît pas svh. */
  :root { --frame-h: 145svh; }
  .frame-pin { height: 100svh; }
  #hero { height: 130svh; }
  #statement { margin-top: -100svh; }

  .frame-indicator { display: none; }
  .nav-menu .nl-text { display: none; }
  .nav-link { padding: 8px 10px; }
  .proc-wrap { grid-template-columns: 1fr; gap: 32px; }
  .proc-head { position: static; }
  .svc-row { grid-template-columns: 40px 1fr; padding: 18px 20px; }
  .svc-row .svc-glyph { display: none; }
  .svc-num { padding-right: 12px; height: auto; }
  .hero-stage { padding: 80px 5% 48px; }
  .mark-rings span:nth-child(1) { width: 380px; height: 240px; }
  .mark-rings span:nth-child(2) { width: 540px; height: 340px; }
  .mark-rings span:nth-child(3) { width: 720px; height: 460px; }

  /* ── Safe area : barre de navigation Android/iOS ──
     padding-bottom pousse le contenu centré vers le haut
     et empêche que les éléments en bas du viewport
     soient masqués par la barre système. */
  .frame-pin {
    padding-bottom: env(safe-area-inset-bottom, 0px);
  }

  /* Hero CTA + scroll-cue : décollé du bas de l'écran */
  .hero-bottom {
    bottom: calc(clamp(28px, 4vh, 56px) + env(safe-area-inset-bottom, 0px));
  }
}
@media (max-width: 700px) {
  nav { grid-template-columns: auto auto; gap: 12px; }
  .nav-menu { display: none; }
}
@media (max-width: 600px) {
  nav { padding: 14px 5%; gap: 10px; }
  .frame-services .frame-pin,
  .frame-process .frame-pin,
  .frame-approach .frame-pin,
  .frame-contact .frame-pin { padding: 40px 5%; }
  .ca-btn { padding: 14px 20px; font-size: 12px; }
  .contact-foot { font-size: 9px; flex-direction: column; align-items: center; }
  
  /* Services empilés */
  .svc-row { grid-template-columns: 1fr; padding: 16px; gap: 8px; }
  .svc-num { padding-right: 0; border-right: none; border-bottom: 1px solid var(--line); padding-bottom: 8px; margin-bottom: 4px; height: auto; }
  .svc-info h3 { font-size: 18px; }
  .svc-info p { font-size: 13px; }
  
  /* Processus empilé */
  .proc-list li { grid-template-columns: 1fr; gap: 8px; padding: 20px 0; }
  .pn { padding-top: 0; font-size: 11px; }
  .proc-list h4 { font-size: 18px; }
  .proc-list p { font-size: 13px; }
  
  /* Titres réduits */
  .svc-head h2, .proc-head h2 { font-size: 26px; }
  .contact-title { font-size: 38px; }

  /* Réalisations 600px : approach-title plus compact */
  .approach-title { font-size: 26px; }
  .approach-lead  { font-size: 14px; line-height: 1.5; }
  .approach-tags .tag { font-size: 10px; padding: 4px 9px; }
}

/* ─── Très petits écrans ≤400px ─── */
@media (max-width: 400px) {
  .approach-title { font-size: 22px; }
}

/* ═══════════════════════════════════════════════════
   GARDE-FOU HAUTEUR — écrans courts (mobile paysage,
   petits Android portrait, petites fenêtres desktop).
   Les frames sont pinned à 100svh avec overflow:hidden et
   AUCUN scroll interne : si le contenu dépasse la hauteur du
   viewport il est rogné en haut/bas. On compacte donc
   verticalement dès que la hauteur devient critique.
═════════════════════════════════════════════════════ */
@media (max-height: 720px) {
  /* Paddings verticaux réduits sur toutes les sections pinned */
  .frame-approach .frame-pin,
  .frame-services .frame-pin,
  .frame-contact .frame-pin { padding-top: 40px; padding-bottom: 40px; }

  /* Réalisations : pile resserrée + fenêtre 3D plafonnée */
  .approach-wrap { gap: 18px; }
  .approach-intro { gap: 14px; }
  .approach-showcase { gap: 12px; }
  .av-stage3d { max-width: min(100%, 330px); }
  .approach-lead { font-size: 13px; line-height: 1.45; }

  /* Services : cartes resserrées */
  .svc-stack { gap: 14px; }
  .svc-row { padding-top: 14px; padding-bottom: 14px; }

  /* Process : items resserrés */
  .proc-list li { padding: 16px 0; }
}

/* Écrans très courts (mobile paysage typique ~360-420px de haut) :
   on retire les éléments secondaires pour garantir l'essentiel visible. */
@media (max-height: 520px) {
  /* L'index des écrans est secondaire (la fenêtre tourne déjà seule) */
  .approach-nav { display: none; }
  .av-stage3d { max-width: min(100%, 300px); }
  .approach-tags { display: none; }
  .svc-row .svc-info p { display: none; }
  .proc-list p { display: none; }
}

/* Reduce motion */
@media (prefers-reduced-motion: reduce) {
  * { animation-duration: .01ms !important; transition-duration: .01ms !important; }
  .frame-pin { position: static; height: auto; min-height: 100vh; }
  .frame { height: auto; }
}
