/* ============================================================
   ASLAN — Site vitrine V3 · charte graphique
   Fonts: DM Sans (UI/display) + DM Mono (données)

   DEUX THÈMES (2026-08-31). Le site reste conçu SOMBRE D'ABORD : le thème
   sombre est la valeur de base de `:root`, le clair ne redéfinit que ce qui
   change. Un visiteur sans préférence exprimée reçoit le thème de son système ;
   le bouton de l'en-tête force l'un ou l'autre et le choix est retenu.

   Trois familles de jetons, et il FAUT les distinguer — c'est ce qui casse
   quand on se contente d'inverser une palette :

     · SURFACE / TEXTE  (--bg, --bg-2, --bg-3, --line, --fg, --fg-2, --fg-3,
       --fg-strong) : elles s'inversent. Le fond devient clair, le texte foncé.

     · ACCENT  (--blue*, --ok, --warn, --crit, --s-*) : elles GARDENT leur
       teinte et n'ajustent que leur luminosité, pour rester lisibles sur le
       fond du moment. Un accent qui s'inverse cesse d'être un accent.

     · POSÉ SUR UN ACCENT  (--on-accent) : la couleur d'un texte ou d'une icône
       posé sur un APLAT d'accent — un bouton bleu plein, `::selection`, une
       étape active. Elle reste CLAIRE dans les deux thèmes, parce que l'aplat,
       lui, reste foncé. C'est le piège n°1 d'un mode clair : `var(--paper)`
       employé là devenait noir sur bleu foncé, illisible.

   Les noms historiques (--navy, --paper, --txt…) sont conservés en ALIAS :
   ils comptent 991 usages dans ce fichier, les renommer serait un risque sans
   contrepartie. Ils pointent sur les rôles ci-dessous. Un `--navy` qui vaut du
   blanc en thème clair se lit mal ; c'est le prix de ne pas toucher 991 lignes.

   --mist et --slate étaient déclarés et JAMAIS utilisés (0 occurrence dans le
   CSS, le JS et les pages). Retirés.
   ============================================================ */

:root {
  color-scheme: dark;

  /* --- surfaces et texte : le thème sombre --- */
  --bg:         #0D1726;   /* fond de page */
  --bg-2:       #131F33;   /* surface d'une carte */
  --bg-3:       #1A2A44;   /* surface soulevée (survol, pastille) */
  --deep:       #05090F;   /* creux : verre d'écran, letterbox vidéo */
  --line:       #27344A;   /* trait */
  --fg:         #E9EFF7;   /* texte courant */
  --fg-2:       #8FA1B8;   /* texte secondaire */
  /* #5C6E86 ne donnait que 3,17:1 sur --bg-2 : « Démonstrateur ASLAN » et la
     ligne de consentement du formulaire échouaient AA dans le thème EN LIGNE.
     #7A8CA4 donne 4,77:1 sur --bg-2 et 5,27:1 sur --bg. Le texte tertiaire du
     thème sombre est donc un peu plus clair qu'avant — c'est visible, et c'est
     le prix du seuil. */
  --fg-3:       #7A8CA4;   /* texte tertiaire, légendes */
  --fg-strong:  #FFFFFF;   /* le texte le plus appuyé */

  /* --- accents : même teinte dans les deux thèmes --- */
  --blue:       #318CE7;
  --blue-deep:  #1F6FC4;
  --blue-soft:  #7FC0FF;   /* bleu clair, lisible SUR fond sombre */
  --ok:         #28C77D;
  --warn:       #F5A623;
  --crit:       #E84040;
  --s-mf:       #318CE7;
  --s-vig:      #1F9E6E;
  --s-drow:     #9E63CE;
  --teal-soft:  #8FE3C0;   /* texte teal sur fond sombre */
  --alarm:      #FF6B6B;   /* lampe du gyrophare (figure du studio) */
  --ice:        #DCEEFF;   /* reflet froid, balayage */

  /* --- aplat d'accent PORTANT DU TEXTE ---
     Distinct de --blue, et il le faut : #318CE7 sous du blanc ne donne que
     3,48:1, sous le seuil AA de 4,5. Le bouton « Réserver une démo » y échouait
     depuis toujours, dans le thème sombre déjà en ligne. --accent-fill est le
     bleu qu'on peut remplir SOUS du texte : 5,18:1 en sombre, 7,49:1 en clair.
     --blue reste le bleu vif, pour les traits, les points et le texte d'accent. */
  --accent-fill:   #1F6FC4;
  --accent-fill-h: #17579B;

  /* --- posé SUR un aplat d'accent : reste clair dans les deux thèmes --- */
  --on-accent:  #FFFFFF;

  /* --- posé SUR une PHOTO ---
     Une vignette-photo est assombrie pour qu'un libellé clair s'y lise. Ce
     voile-là ne suit PAS le thème : en clair, un voile clair délave la photo
     au lieu de l'assombrir, et le libellé devenu noir se retrouve sur une image
     pâle. Les deux jetons vont donc par paire et restent constants.
     À ne pas confondre avec --veil, qui est un voile posé sur une SURFACE et
     qui, lui, suit le thème. */
  --media-veil: 9, 14, 22;
  --on-media:   #FFFFFF;

  /* --- voiles et ombres ---
     Une ombre noire à 82 % est juste sur un fond sombre et brutale sur du
     blanc : ces jetons s'allègent franchement en thème clair. */
  /* Voile posé sur une SURFACE — il SUIT le thème. À ne pas confondre avec
     --media-veil, posé sur une photo, qui lui reste sombre dans les deux.
     Le seul usage est `.aud-card::after`, qui estompe une image de fond vers le
     bas pour que le texte de la carte se lise. Laissé sombre en thème clair, il
     noircissait le bas de quatre cartes claires dont le texte, lui, est resté
     foncé — illisible. La sonde de contraste ne pouvait pas le voir : cette
     carte contient une image, elle fait partie des « écartés ». */
  --veil:       9, 14, 22;
  --shadow:     0, 0, 0;        /* composantes d'une ombre portée */
  --shadow-a1:  .70;
  --shadow-a2:  .78;
  --shadow-a3:  .82;
  --logo-plate: #FFFFFF;        /* plaque sous un logo client */
  --logo-plate-line: transparent;

  /* --- alias historiques (991 usages) --- */
  --navy:    var(--bg);
  --navy-2:  var(--bg-2);
  --navy-3:  var(--bg-3);
  --line-d:  var(--line);
  --txt:     var(--fg);
  --txt-2:   var(--fg-2);
  --txt-3:   var(--fg-3);
  --paper:   var(--fg-strong);

  --sans: "DM Sans", system-ui, sans-serif;
  --mono: "DM Mono", ui-monospace, monospace;

  --r: 10px;
  --r-sm: 6px;

  --wrap: 1160px;
  --pad-x: clamp(20px, 5vw, 48px);
}

/* ------------------------------------------------------------------ CLAIR
   Un thème clair n'est pas la palette sombre retournée. Trois écarts assumés :

     · les BLEUS s'assombrissent. #318CE7 sur blanc donne 3,1:1 — sous le seuil
       AA de 4,5:1 pour du texte. Les aplats, eux, gardent le bleu vif : c'est
       du texte blanc qui se pose dessus, et le contraste s'y mesure à l'envers.
     · les VOILES et les OMBRES s'allègent de moitié et plus. Une ombre calculée
       pour du bleu nuit noircit une page blanche.
     · les HALOS (les `box-shadow` diffus, les `radial-gradient` bleus) perdent
       leur raison d'être : une lueur ne se voit pas sur du blanc. Ils sont
       conservés à faible opacité, où ils jouent le rôle d'une teinte de fond.

   Et une inversion de la RAMPE, qui n'en est pas une erreur. En sombre, une
   surface s'ÉCLAIRCIT quand elle s'élève : --bg #0D1726 → --bg-2 → --bg-3. Le
   miroir exact donnait une page d'un blanc pur avec des cartes légèrement
   grises — dur à l'œil, et des cartes qui ne se détachaient de rien. Ici la
   page est un gris doux et les cartes sont BLANCHES : elles s'élèvent en
   s'éclaircissant, comme en sombre. C'est la même logique, pas son miroir.
   `--veil` (le voile posé sur une SURFACE) vaut donc du blanc : il estompe
   vers la carte, pas vers la page.

   Le bloc est écrit DEUX FOIS : une fois pour le choix explicite du visiteur
   (`[data-theme="light"]`), une fois pour la préférence système, gardée par
   `:not([data-theme="dark"])` — sans quoi un visiteur en système clair qui
   force le sombre au bouton verrait le média l'emporter.
   ------------------------------------------------------------------------ */
@media (prefers-color-scheme: light) {
  :root:not([data-theme="dark"]) {
    color-scheme: light;

    --bg:        #EDF0F5;
    --bg-2:      #FFFFFF;
    --bg-3:      #F4F7FB;
    --deep:      #DDE3EC;
    --line:      #D3DBE6;
    --fg:        #0F1B2D;
    --fg-2:      #4A5A70;
    --fg-3:      #5F6E85;   /* #6B7B92 ne donnait que 4,05:1 sur --bg-2 */
    --fg-strong: #06101F;

    --blue:      #1A6FC9;
    --blue-deep: #12559C;
    --accent-fill:   #12559C;
    --accent-fill-h: #0D4278;
    --blue-soft: #1F6FC4;
    --ok:        #0E7146;
    --warn:      #8A5A00;
    --crit:      #C22B2B;
    --s-mf:      #1A6FC9;
    --s-vig:     #0E7146;
    --s-drow:    #6B3FA0;
    --teal-soft: #0E7146;
    --alarm:     #D93B3B;
    --ice:       #1A6FC9;

    --veil:      255, 255, 255;
    --shadow:    18, 32, 54;
    --shadow-a1: .16;
    --shadow-a2: .20;
    --shadow-a3: .24;
    --logo-plate: #FFFFFF;
    --logo-plate-line: #D8E0EB;
  }
}

:root[data-theme="light"] {
  color-scheme: light;

  --bg:        #EDF0F5;
  --bg-2:      #FFFFFF;
  --bg-3:      #F4F7FB;
  --deep:      #DDE3EC;
  --line:      #D3DBE6;
  --fg:        #0F1B2D;
  --fg-2:      #4A5A70;
  --fg-3:      #5F6E85;   /* #6B7B92 ne donnait que 4,05:1 sur --bg-2 */
  --fg-strong: #06101F;

  --blue:      #1A6FC9;
  --blue-deep: #12559C;
  --accent-fill:   #12559C;
  --accent-fill-h: #0D4278;
  --blue-soft: #1F6FC4;
  --ok:        #0E7146;
  --warn:      #8A5A00;
  --crit:      #C22B2B;
  --s-mf:      #1A6FC9;
  --s-vig:     #0E7146;
  --s-drow:    #6B3FA0;
  --teal-soft: #0E7146;
  --alarm:     #D93B3B;
  --ice:       #1A6FC9;

  --veil:      255, 255, 255;
  --shadow:    18, 32, 54;
  --shadow-a1: .16;
  --shadow-a2: .20;
  --shadow-a3: .24;
  --logo-plate: #FFFFFF;
  --logo-plate-line: #D8E0EB;
}

/* ------------------------------------------------------------------ #earWave
   Le trace EAR est du SVG construit par js/site.js. Ses couleurs etaient posees
   en `setAttribute("stroke", "#318CE7")` a la construction — donc figees, et le
   changement de theme ne pouvait pas les atteindre. Elles vivent ici : le CSS
   colore le DOM, et les deux themes suivent sans une ligne de JS. */
.ew-thr    { stroke: var(--line); }
.ew-mf     { stroke: var(--s-mf); }
.ew-vig    { stroke: var(--s-vig); }
.ew-drow   { stroke: var(--s-drow); }
.ew-ear    { stroke: var(--blue-soft); }
.ew-cursor { stroke: var(--fg-3); stroke-width: 1; }
.ew-blink  { stroke: var(--warn); stroke-width: 1.4; opacity: .8; }

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

html { scroll-behavior: smooth; }

body {
  background: var(--navy);
  color: var(--txt);
  font-family: var(--sans);
  font-size: 16px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  overflow-x: clip;
}

/* ---------- i18n ---------- */
html[data-lang="fr"] [lang="en"] { display: none !important; }
html[data-lang="en"] [lang="fr"] { display: none !important; }

::selection { background: var(--accent-fill); color: var(--on-accent); }
a { color: var(--blue-soft); }
:focus-visible {
  outline: 2px solid var(--blue-soft);
  outline-offset: 3px;
  border-radius: 2px;
}

.wrap {
  max-width: var(--wrap);
  margin: 0 auto;
  padding: 0 var(--pad-x);
}

/* ============================================================
   Barre de progression de lecture
   ============================================================ */
#scrollbar {
  position: fixed;
  top: 0; left: 0;
  height: 2px;
  width: 100%;
  z-index: 60;
  background: linear-gradient(90deg, var(--blue-deep), var(--blue), var(--blue-soft));
  transform-origin: 0 50%;
  transform: scaleX(0);
  pointer-events: none;
}

/* ============================================================
   Header
   ============================================================ */
.site-header {
  position: sticky;
  top: 0;
  z-index: 50;
  height: 76px;
  border-bottom: 1px solid var(--line-d);
  background: color-mix(in srgb, var(--navy) 82%, transparent);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
}
.site-header .wrap {
  height: 100%;
  display: flex;
  align-items: center;
  gap: 24px;
}
.brand { display: flex; align-items: center; gap: 12px; text-decoration: none; }
.brand-logo { height: 50px; width: auto; display: block; }
.site-footer .brand-logo { height: 40px; }
.brand .logo {
  font-weight: 700;
  font-size: 20px;
  letter-spacing: 0.14em;
  color: var(--paper);
}
.brand .logo b { color: var(--blue); font-weight: 700; }
.brand .tag {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--txt-3);
  white-space: nowrap;
}
@media (max-width: 1180px) { .site-header .brand .tag { display: none; } }

.site-nav { display: flex; gap: 2px; margin-left: auto; }
.site-nav a {
  padding: 7px 13px;
  border-radius: var(--r-sm);
  color: var(--txt-2);
  text-decoration: none;
  font-weight: 500;
  font-size: 14px;
  border: 1px solid transparent;
  white-space: nowrap;
}
.site-nav a:hover { color: var(--txt); }
.site-nav a.active {
  color: var(--paper);
  background: var(--navy-3);
  border-color: var(--line-d);
}

.lang-toggle {
  display: flex;
  border: 1px solid var(--line-d);
  border-radius: 20px;
  overflow: hidden;
  font-family: var(--mono);
  font-size: 11px;
  flex: none;
}
/* D-013 — le selecteur n'est plus une paire de boutons qui basculent la page
   en place, mais deux LIENS vers l'URL jumelle (/solutions.html <->
   /en/solutions.html). Une langue = une URL, donc un vrai changement de page. */
.lang-toggle a, .lang-toggle button {
  appearance: none;
  border: 0;
  background: transparent;
  color: var(--txt-3);
  font: inherit;
  padding: 5px 12px;
  cursor: pointer;
  letter-spacing: 0.08em;
  text-decoration: none;
  line-height: 1.5;
}
/* ------------------------------------------------------- bascule de theme
   Un seul bouton rond, de la meme famille que la pastille FR/EN (meme trait,
   meme rayon), mais compact : l'en-tete est deja plein sous 960 px.
   L'icone montre le theme qu'on VA obtenir — soleil quand on est en sombre. */
.theme-toggle {
  appearance: none;
  flex: none;
  width: 34px; height: 34px;
  display: grid; place-items: center;
  border: 1px solid var(--line-d);
  border-radius: 50%;
  background: transparent;
  color: var(--txt-3);
  cursor: pointer;
  transition: color .2s ease, border-color .2s ease, background .2s ease;
}
.theme-toggle:hover {
  color: var(--blue-soft);
  border-color: color-mix(in srgb, var(--blue) 50%, var(--line-d));
  background: var(--navy-3);
}
.theme-toggle:focus-visible { outline: 2px solid var(--blue-soft); outline-offset: 3px; }
.theme-toggle .ti { width: 16px; height: 16px; display: none; }
/* En sombre on propose le clair : soleil. En clair, l'inverse.
   Le selecteur suit la meme logique de garde que les jetons — un choix
   explicite au bouton doit l'emporter sur la preference systeme. */
.theme-toggle .ti-sun { display: block; }
@media (prefers-color-scheme: light) {
  :root:not([data-theme="dark"]) .theme-toggle .ti-sun { display: none; }
  :root:not([data-theme="dark"]) .theme-toggle .ti-moon { display: block; }
}
:root[data-theme="light"] .theme-toggle .ti-sun { display: none; }
:root[data-theme="light"] .theme-toggle .ti-moon { display: block; }
:root[data-theme="dark"] .theme-toggle .ti-sun { display: block; }
:root[data-theme="dark"] .theme-toggle .ti-moon { display: none; }

.lang-toggle a:hover { color: var(--txt); }
.lang-toggle a[aria-current="true"],
.lang-toggle button[aria-pressed="true"] { background: var(--navy-3); color: var(--paper); }

.header-cta {
  flex: none;
  font-size: 13px;
  font-weight: 600;
  text-decoration: none;
  color: var(--on-accent);
  background: var(--accent-fill);
  padding: 8px 16px;
  border-radius: var(--r-sm);
}
.header-cta:hover { background: var(--accent-fill-h); }

/* ============================================================
   Boutons
   ============================================================ */
.btn {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  font-family: var(--sans);
  font-weight: 600;
  font-size: 15px;
  text-decoration: none;
  padding: 13px 26px;
  border-radius: var(--r-sm);
  border: 1px solid transparent;
  cursor: pointer;
  position: relative;
}
.btn-primary {
  background: var(--accent-fill);
  color: var(--on-accent);
  box-shadow: 0 0 0 0 color-mix(in srgb, var(--blue) 45%, transparent);
  transition: box-shadow 0.35s ease, background 0.2s ease, transform 0.2s ease;
}
.btn-primary:hover {
  background: var(--accent-fill-h);
  box-shadow: 0 6px 28px -6px color-mix(in srgb, var(--blue) 65%, transparent);
  transform: translateY(-1px);
}
.btn-ghost {
  background: transparent;
  color: var(--txt);
  border-color: var(--line-d);
  transition: border-color 0.2s ease, transform 0.2s ease;
}
.btn-ghost:hover { border-color: var(--txt-3); transform: translateY(-1px); }

/* ============================================================
   Sections communes
   ============================================================ */
section { padding: clamp(46px, 6vw, 84px) 0; position: relative; overflow-x: clip; }
/* plus de trait de séparation : on alterne des bandes de transparence pour délimiter les sections */
main > section:nth-of-type(even) { background: color-mix(in srgb, var(--navy) 34%, transparent); }
main > section:nth-of-type(odd) { background: color-mix(in srgb, var(--navy) 6%, transparent); }
.hero { background: transparent !important; }

.eyebrow {
  display: flex;
  align-items: center;
  gap: 10px;
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--txt-2);
  margin-bottom: 22px;
}
.eyebrow::before {
  content: "";
  width: 22px;
  height: 2px;
  background: var(--blue);
  flex: none;
  transform-origin: 0 50%;
}

h2 {
  font-size: clamp(30px, 4.4vw, 50px);
  font-weight: 700;
  line-height: 1.1;
  letter-spacing: -0.018em;
  color: var(--paper);
  max-width: 21ch;
  margin-bottom: 18px;
}
.lede {
  color: var(--txt-2);
  font-size: clamp(16px, 1.6vw, 18px);
  max-width: 62ch;
}

/* halo ambiant réutilisable */
.glow {
  position: absolute;
  width: 620px;
  height: 620px;
  border-radius: 50%;
  background: radial-gradient(circle, color-mix(in srgb, var(--blue) 9%, transparent), transparent 65%);
  pointer-events: none;
  z-index: 0;
}
section > .wrap { position: relative; z-index: 1; }

/* ============================================================
   Hero
   ============================================================ */
.hero {
  position: relative;
  display: flex;
  flex-direction: column;
  padding: clamp(44px, 5vw, 72px) 0 clamp(48px, 6vw, 88px);
  overflow: hidden;
  background-color: transparent;
}
/* fond « mesh » global, fixe, derrière tout le site */
.mesh-bg {
  position: fixed;
  inset: 0;
  width: 100vw;
  height: 100vh;
  z-index: 0;
  pointer-events: none;
}
/* le contenu passe au-dessus du mesh */
.site-header { z-index: 50; }
main, .site-footer, #scrollbar { position: relative; z-index: 1; }
.hero::after {
  /* fondu doux pour asseoir le contenu du hero */
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  background: radial-gradient(120% 80% at 70% 0%, transparent 45%, color-mix(in srgb, var(--navy) 40%, transparent) 100%);
  pointer-events: none;
}
.hero > .wrap {
  position: relative;
  z-index: 2;
  width: 100%;
}
.hero-grid { width: 100%; }

.hero-grid {
  display: grid;
  grid-template-columns: minmax(0, 1.02fr) minmax(0, 0.98fr);
  gap: clamp(28px, 4vw, 60px);
  align-items: center;
  min-height: min(72vh, 640px);
}

.hero-kicker {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--txt-2);
  border: 1px solid var(--line-d);
  border-radius: 20px;
  padding: 5px 14px;
  margin-bottom: 28px;
  background: color-mix(in srgb, var(--navy-2) 65%, transparent);
}
.hero-kicker .dot {
  width: 7px; height: 7px;
  border-radius: 50%;
  background: var(--ok);
  box-shadow: 0 0 6px var(--ok);
  animation: beat 2.4s ease-in-out infinite;
}
@keyframes beat {
  0%, 100% { transform: scale(1); opacity: 1; }
  50% { transform: scale(0.72); opacity: 0.65; }
}

h1 {
  font-size: clamp(40px, 5.8vw, 82px);
  font-weight: 700;
  line-height: 1.02;
  letter-spacing: -0.028em;
  color: var(--paper);
  max-width: 14ch;
}
h1 .accent { color: var(--blue); }
/* mots animés à l'ouverture */
h1 .w { display: inline-block; }

.hero-sub {
  margin-top: 26px;
  font-size: clamp(16px, 1.7vw, 18.5px);
  color: var(--txt-2);
  max-width: 50ch;
}
.hero-actions { display: flex; flex-wrap: wrap; gap: 14px; margin-top: clamp(28px, 3vw, 38px); }
.hero .hero-actions { margin-bottom: clamp(12px, 4vh, 40px); }
.hero-actions .btn { padding: 15px 30px; font-size: 15.5px; }

/* les blocs orchestrés démarrent invisibles (JS anime les révèle,
   fallback no-JS / reduced-motion les raffiche) */
.js .hero .stage { opacity: 0; }
@media (prefers-reduced-motion: reduce) { .js .hero .stage { opacity: 1 !important; } }

/* --- Colonne visuelle : face + signal empilés --- */
.hero-visual {
  display: flex;
  flex-direction: column;
  gap: 16px;
  align-self: center;
  justify-content: center;
}

/* --- Constellation de repères faciaux --- */
/* Fixed aspect box so the mesh face renders identically regardless of the
   copy-column height (i.e. identical in FR and EN). */
.hero-face {
  position: relative;
  width: 100%;
  aspect-ratio: 1 / 1;
  min-height: 340px;
  flex: 0 0 auto;
}
#faceCloud {
  display: block;
  width: 100%;
  height: 100%;
  position: absolute;
  inset: 0;
}
.face-readout {
  position: absolute;
  font-family: var(--mono);
  font-size: 10.5px;
  letter-spacing: 0.08em;
  color: var(--txt-2);
  background: color-mix(in srgb, var(--navy-2) 78%, transparent);
  border: 1px solid var(--line-d);
  border-radius: var(--r-sm);
  padding: 5px 10px;
  white-space: nowrap;
  backdrop-filter: blur(4px);
}
.face-readout b { color: var(--blue-soft); font-weight: 500; font-variant-numeric: tabular-nums; }
.face-readout.state b { color: var(--ok); }
.face-readout.state.warn b { color: var(--warn); }
.fr-1 { top: 8%; right: 4%; }
.fr-2 { bottom: 14%; left: 6%; }
.fr-3 { bottom: 6%; right: 8%; }

/* --- Signal EAR (compacté sous la face) --- */
.hero-signal {
  position: relative;
  z-index: 2;
  padding: 16px 18px 12px;
}
.signal-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 10px 26px;
  font-family: var(--mono);
  font-size: 11px;
  color: var(--txt-3);
  letter-spacing: 0.08em;
  margin-bottom: 10px;
}
.signal-head .label { text-transform: uppercase; color: var(--txt-2); }
.signal-head .readout { color: var(--txt-2); }
.signal-head .readout b {
  color: var(--blue-soft);
  font-weight: 500;
  font-variant-numeric: tabular-nums;
}
.signal-head .readout.blink b { color: var(--warn); }
.signal-legend { margin-left: auto; display: flex; gap: 18px; }
.signal-legend span { display: inline-flex; align-items: center; gap: 7px; }
.signal-legend i { width: 14px; height: 2px; border-radius: 1px; flex: none; }
.signal-legend .k-mf i { background: var(--s-mf); }
.signal-legend .k-vig i { background: var(--s-vig); }
.signal-legend .k-drow i { background: var(--s-drow); }

#earWave { display: block; width: 100%; height: 104px; }

/* ============================================================
   Ticker télémétrie
   ============================================================ */
.ticker {
  border-top: 1px solid var(--line-d);
  border-bottom: 1px solid var(--line-d);
  background: var(--navy-2);
  overflow: hidden;
  padding: 11px 0;
  position: relative;
}
.ticker::before, .ticker::after {
  content: "";
  position: absolute;
  top: 0; bottom: 0;
  width: 90px;
  z-index: 2;
  pointer-events: none;
}
.ticker::before { left: 0; background: linear-gradient(90deg, var(--navy-2), transparent); }
.ticker::after { right: 0; background: linear-gradient(-90deg, var(--navy-2), transparent); }
.ticker-track {
  display: flex;
  gap: 44px;
  width: max-content;
  animation: ticker-scroll 36s linear infinite;
}
.ticker:hover .ticker-track { animation-play-state: paused; }
@keyframes ticker-scroll {
  from { transform: translateX(0); }
  to { transform: translateX(-50%); }
}
.ticker-track span {
  font-family: var(--mono);
  font-size: 11.5px;
  letter-spacing: 0.1em;
  color: var(--txt-3);
  text-transform: uppercase;
  white-space: nowrap;
}
.ticker-track b {
  color: var(--blue-soft);
  font-weight: 500;
  font-variant-numeric: tabular-nums;
}
.ticker-track .sep { color: var(--line-d); }

/* ============================================================
   Statement — respiration typographique (façon film produit)
   ============================================================ */
.statement { text-align: center; }
.statement .big {
  font-size: clamp(28px, 4.8vw, 58px);
  font-weight: 700;
  line-height: 1.14;
  letter-spacing: -0.022em;
  color: var(--paper);
  max-width: 24ch;
  margin: 0 auto;
}
.statement .big .dim { color: var(--txt-3); }
.statement .who {
  margin-top: 26px;
  font-family: var(--mono);
  font-size: 11.5px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--txt-3);
}

/* ============================================================
   Problème
   ============================================================ */
.facts {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 16px;
  margin-top: 48px;
}
.fact {
  background: var(--navy-2);
  border: 1px solid var(--line-d);
  border-radius: var(--r);
  padding: 26px 24px;
  transition: transform 0.3s cubic-bezier(0.2, 0.7, 0.3, 1), border-color 0.3s ease;
}
.fact:hover { transform: translateY(-4px); border-color: color-mix(in srgb, var(--blue) 40%, var(--line-d)); }
.fact .k {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--txt-3);
  margin-bottom: 14px;
}
.fact p { color: var(--txt-2); font-size: 15px; }
.fact p b { color: var(--txt); font-weight: 600; }
.fact .drift {
  display: block;
  width: 100%;
  height: 36px;
  margin-top: 18px;
}
.fact .drift path { stroke-dasharray: 400; stroke-dashoffset: 400; }
.fact.in .drift path { animation: draw 1.6s cubic-bezier(0.3, 0, 0.2, 1) 0.25s forwards; }
@keyframes draw { to { stroke-dashoffset: 0; } }

/* ============================================================
   Solution — bento
   ============================================================ */
.bento {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 16px;
  margin-top: 48px;
}
.axis {
  position: relative;
  background: var(--navy-2);
  border: 1px solid var(--line-d);
  border-radius: var(--r);
  padding: 26px 24px 20px;
  overflow: hidden;
  transition: transform 0.3s cubic-bezier(0.2, 0.7, 0.3, 1), border-color 0.3s ease;
}
.axis:hover { transform: translateY(-4px); border-color: color-mix(in srgb, var(--ax) 45%, var(--line-d)); }
.axis::before {
  content: "";
  position: absolute;
  inset: 0 auto 0 0;
  width: 3px;
  background: var(--ax);
}
.axis .code {
  display: flex;
  align-items: baseline;
  gap: 10px;
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.14em;
  color: var(--ax);
  margin-bottom: 12px;
}
.axis .code .val {
  margin-left: auto;
  font-size: 12px;
  color: var(--txt-2);
  font-variant-numeric: tabular-nums;
}
.axis .code .val b { color: var(--ax); font-weight: 500; }
.axis h3 { font-size: 19px; font-weight: 700; color: var(--paper); margin-bottom: 10px; line-height: 1.25; }
.axis p { color: var(--txt-2); font-size: 14.5px; }
.axis canvas { display: block; width: 100%; height: 44px; margin-top: 18px; }
.axis-mf { --ax: var(--s-mf); }
.axis-vig { --ax: var(--s-vig); }
.axis-drow { --ax: var(--s-drow); }

/* carte prévision, pleine largeur */
.forecast {
  grid-column: 1 / -1;
  display: grid;
  grid-template-columns: minmax(240px, 340px) 1fr;
  gap: clamp(20px, 3vw, 40px);
  background: var(--navy-2);
  border: 1px solid var(--line-d);
  border-radius: var(--r);
  padding: 26px 24px;
  align-items: center;
}
.forecast .code {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.14em;
  color: var(--blue-soft);
  margin-bottom: 12px;
}
.forecast h3 { font-size: 19px; font-weight: 700; color: var(--paper); margin-bottom: 10px; }
.forecast p { color: var(--txt-2); font-size: 14.5px; }
.forecast .chips { display: flex; gap: 10px; margin-top: 18px; flex-wrap: wrap; }
.forecast .chips .h {
  font-family: var(--mono);
  font-size: 12px;
  color: var(--txt-2);
  border: 1px solid var(--line-d);
  border-radius: 20px;
  padding: 5px 13px;
}
.forecast .chips .h b { color: var(--blue-soft); font-weight: 500; }
#forecastChart { display: block; width: 100%; height: 150px; }

/* ============================================================
   Approche — Capter · Comprendre · Agir
   ============================================================ */
.steps {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 16px;
  margin-top: 48px;
}
.step {
  position: relative;
  background: var(--navy-2);
  border: 1px solid var(--line-d);
  border-radius: var(--r);
  padding: 28px 24px;
  transition: transform 0.3s cubic-bezier(0.2, 0.7, 0.3, 1), border-color 0.3s ease;
}
.step:hover { transform: translateY(-4px); border-color: color-mix(in srgb, var(--blue) 40%, var(--line-d)); }
.step .n {
  font-family: var(--mono);
  font-size: 13px;
  letter-spacing: 0.14em;
  color: var(--blue-soft);
  margin-bottom: 16px;
}
.step h3 { font-size: 20px; font-weight: 700; color: var(--paper); margin-bottom: 10px; line-height: 1.25; }
.step p { color: var(--txt-2); font-size: 14.5px; }

/* Statement — sous-titre centré */
.statement .lede { margin: 22px auto 0; }

/* ============================================================
   Partenaires
   ============================================================ */
.partners { margin-top: 56px; padding-top: 32px; }
.partners .plabel {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--txt-3);
  margin-bottom: 18px;
}
.partners .logos { display: flex; flex-wrap: wrap; gap: 12px 28px; align-items: center; }
.partners .logos > span {
  font-weight: 600;
  font-size: 14px;
  color: var(--txt-2);
  opacity: 0.85;
  white-space: nowrap;
}

/* ============================================================
   Applications — deux modes qui ressortent
   ============================================================ */
.modes {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 16px;
  margin-top: 48px;
}
.mode {
  position: relative;
  background: var(--navy-2);
  border: 1px solid var(--line-d);
  border-radius: var(--r);
  padding: 32px 28px;
  transition: transform 0.3s cubic-bezier(0.2, 0.7, 0.3, 1), border-color 0.3s ease;
}
.mode:hover { border-color: color-mix(in srgb, var(--blue) 45%, var(--line-d)); }
.mode .n {
  font-family: var(--mono);
  font-size: 34px;
  font-weight: 500;
  color: var(--line-d);
  line-height: 1;
  margin-bottom: 14px;
}
.mode .k {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--blue-soft);
  margin-bottom: 10px;
}
.mode h3 { font-size: 22px; font-weight: 700; color: var(--paper); margin-bottom: 12px; line-height: 1.2; }
.mode p { color: var(--txt-2); font-size: 15px; }
.mode em { color: var(--txt); font-style: italic; }
.mode canvas { display: block; width: 100%; height: 150px; margin-top: 20px; }

/* ============================================================
   Secteurs
   ============================================================ */
.sectors { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 40px; }
.sectors > span {
  font-family: var(--mono);
  font-size: 12.5px;
  color: var(--txt-2);
  border: 1px solid var(--line-d);
  border-radius: 20px;
  padding: 9px 18px;
  background: color-mix(in srgb, var(--navy-2) 60%, transparent);
}

/* ============================================================
   Stats (compteurs)
   ============================================================ */
.stats {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 16px;
  margin: 54px 0 10px;
}
.stat {
  border: 1px solid var(--line-d);
  border-radius: var(--r);
  padding: 20px 22px;
  background: color-mix(in srgb, var(--navy-2) 60%, transparent);
}
.stat .n {
  font-family: var(--mono);
  font-size: clamp(26px, 3vw, 34px);
  font-weight: 500;
  color: var(--paper);
  line-height: 1.1;
  font-variant-numeric: tabular-nums;
}
.stat .n .u { font-size: 0.55em; color: var(--blue-soft); margin-left: 3px; }
.stat .l {
  font-family: var(--mono);
  font-size: 10.5px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--txt-3);
  margin-top: 8px;
}

/* ============================================================
   Pipeline
   ============================================================ */
.pipeline {
  margin-top: 56px;
  display: grid;
  grid-template-columns: 1fr auto 1fr auto 1fr;
  align-items: stretch;
}
.pl-stage { min-width: 0; }
.pl-stage .stage-name {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--txt-2);
  margin-bottom: 14px;
}
.pl-arrow { display: flex; align-items: center; padding: 34px 12px 0; color: var(--txt-3); }
.pl-arrow svg { display: block; overflow: visible; }
.pl-arrow .flow { fill: var(--blue-soft); }
.experts { display: grid; gap: 8px; }
.expert {
  display: flex;
  align-items: baseline;
  gap: 10px;
  background: var(--navy-2);
  border: 1px solid var(--line-d);
  border-radius: var(--r-sm);
  padding: 9px 13px;
  font-size: 13.5px;
  color: var(--txt-2);
  opacity: 0;
  transform: translateX(-8px);
  transition: border-color 0.25s ease, color 0.25s ease;
}
.expert.hot { border-color: color-mix(in srgb, var(--blue) 55%, var(--line-d)); color: var(--txt); }
.expert .id { font-family: var(--mono); font-size: 11px; color: var(--blue-soft); flex: none; width: 14px; }
.pl-core { display: grid; gap: 8px; align-content: start; }
.core-block {
  background: var(--navy-3);
  border: 1px solid var(--line-d);
  border-radius: var(--r-sm);
  padding: 14px 15px;
  opacity: 0;
  transform: translateX(-8px);
  transition: border-color 0.25s ease;
}
.core-block.hot { border-color: color-mix(in srgb, var(--blue) 55%, var(--line-d)); }
.core-block .t { font-weight: 600; font-size: 14px; color: var(--paper); margin-bottom: 4px; }
.core-block p { font-size: 12.5px; color: var(--txt-2); line-height: 1.45; }
.outputs { display: grid; gap: 8px; align-content: start; }
.output {
  display: flex;
  align-items: baseline;
  gap: 10px;
  border: 1px dashed var(--line-d);
  border-radius: var(--r-sm);
  padding: 9px 13px;
  font-size: 13.5px;
  color: var(--txt-2);
  opacity: 0;
  transform: translateX(-8px);
  transition: border-color 0.25s ease;
}
.output.hot { border-color: color-mix(in srgb, var(--out, var(--blue)) 70%, var(--line-d)); }
.output i {
  width: 7px; height: 7px;
  border-radius: 50%;
  background: var(--out, var(--blue));
  flex: none;
  align-self: center;
}
.pipeline.revealed .expert,
.pipeline.revealed .core-block,
.pipeline.revealed .output {
  animation: pl-in 0.55s cubic-bezier(0.2, 0.7, 0.3, 1) forwards;
  animation-delay: var(--d, 0s);
}
@keyframes pl-in { to { opacity: 1; transform: translateX(0); } }

.pipeline-note {
  margin-top: 30px;
  font-size: 13.5px;
  color: var(--txt-3);
  max-width: 70ch;
}

/* ============================================================
   Teaser vidéo — viseur
   ============================================================ */
.video-frame {
  margin-top: 44px;
  border: 1px solid var(--line-d);
  border-radius: var(--r);
  overflow: hidden;
  background: var(--navy-2);
  position: relative;
  box-shadow: 0 30px 90px -30px color-mix(in srgb, var(--blue) 22%, transparent);
}
.video-frame .bar {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 16px;
  border-bottom: 1px solid var(--line-d);
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--txt-3);
}
.video-frame .bar .dot {
  width: 7px; height: 7px;
  border-radius: 50%;
  background: var(--warn);
  box-shadow: 0 0 6px var(--warn);
}
.video-frame video { display: block; width: 100%; height: auto; }
/* écrin élargi façon film produit */
.video-bleed {
  max-width: 1400px;
  margin: 52px auto 0;
  padding: 0 var(--pad-x);
}
/* coins de visée */
.video-shell { position: relative; margin-top: 44px; }
.video-bleed .video-shell { margin-top: 0; }
.video-shell .video-frame { margin-top: 0; }
.video-shell .corner {
  position: absolute;
  width: 22px; height: 22px;
  border: 2px solid var(--blue);
  z-index: 2;
  opacity: 0.85;
}
.video-shell .c-tl { top: -8px; left: -8px; border-right: 0; border-bottom: 0; }
.video-shell .c-tr { top: -8px; right: -8px; border-left: 0; border-bottom: 0; }
.video-shell .c-bl { bottom: -8px; left: -8px; border-right: 0; border-top: 0; }
.video-shell .c-br { bottom: -8px; right: -8px; border-left: 0; border-top: 0; }

/* ============================================================
   Cas d'usage
   ============================================================ */
.cases {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 16px;
  margin-top: 48px;
}
.case {
  position: relative;
  background: var(--navy-2);
  border: 1px solid var(--line-d);
  border-radius: var(--r);
  padding: 26px 24px;
  overflow: hidden;
  transition: transform 0.3s cubic-bezier(0.2, 0.7, 0.3, 1), border-color 0.3s ease;
}
.case:hover { transform: translateY(-4px); border-color: color-mix(in srgb, var(--blue) 40%, var(--line-d)); }
.case::after {
  /* balayage au survol */
  content: "";
  position: absolute;
  top: 0; bottom: 0;
  left: -40%;
  width: 30%;
  background: linear-gradient(100deg, transparent, color-mix(in srgb, var(--blue) 7%, transparent), transparent);
  transform: skewX(-14deg);
  transition: left 0.7s cubic-bezier(0.3, 0, 0.2, 1);
  pointer-events: none;
}
.case:hover::after { left: 120%; }
.case .k {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--blue-soft);
  margin-bottom: 12px;
}
.case h3 { font-size: 18px; font-weight: 700; color: var(--paper); margin-bottom: 8px; }
.case p { color: var(--txt-2); font-size: 14.5px; }

/* ============================================================
   À propos
   ============================================================ */
.about-grid {
  display: grid;
  grid-template-columns: 1.2fr 1fr;
  gap: clamp(32px, 5vw, 72px);
  margin-top: 12px;
}
.about-grid p + p { margin-top: 16px; }
.about-grid p { color: var(--txt-2); font-size: 15.5px; }
.pillars { display: grid; gap: 12px; align-content: start; }
.pillar {
  background: var(--navy-2);
  border: 1px solid var(--line-d);
  border-radius: var(--r);
  padding: 18px 20px;
  transition: border-color 0.3s ease;
}
.pillar:hover { border-color: color-mix(in srgb, var(--blue) 35%, var(--line-d)); }
.pillar .t { font-weight: 600; font-size: 14.5px; color: var(--paper); margin-bottom: 4px; }
.pillar p { font-size: 13.5px; color: var(--txt-2); }

/* ============================================================
   Contact — balise radar
   ============================================================ */
.contact { text-align: center; overflow: hidden; }
.contact h2, .contact .lede { margin-inline: auto; }
.contact .hero-actions { justify-content: center; }
.beacon {
  position: relative;
  width: 14px; height: 14px;
  margin: 0 auto 30px;
}
.beacon .core {
  position: absolute;
  inset: 3px;
  border-radius: 50%;
  background: var(--blue);
  box-shadow: 0 0 10px var(--blue);
}
.beacon .ring {
  position: absolute;
  inset: 0;
  border-radius: 50%;
  border: 1px solid var(--blue);
  animation: ping 2.8s cubic-bezier(0.2, 0.6, 0.4, 1) infinite;
  opacity: 0;
}
.beacon .ring:nth-child(2) { animation-delay: 0.9s; }
.beacon .ring:nth-child(3) { animation-delay: 1.8s; }
@keyframes ping {
  0% { transform: scale(1); opacity: 0.8; }
  100% { transform: scale(7); opacity: 0; }
}

/* ============================================================
   Footer
   ============================================================ */
.site-footer { border-top: 1px solid var(--line-d); padding: 30px 0 40px; }
.site-footer .wrap {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px 28px;
  font-family: var(--mono);
  font-size: 11.5px;
  color: var(--txt-3);
}
.site-footer .brand .logo { font-size: 15px; }
.site-footer .right { margin-left: auto; display: flex; gap: 20px; }
.site-footer a { color: var(--txt-3); text-decoration: none; }
.site-footer a:hover { color: var(--txt-2); }

/* ============================================================
   Reveal au scroll
   ============================================================ */
.reveal {
  opacity: 0;
  transform: translateY(22px);
  transition: opacity 0.75s cubic-bezier(0.2, 0.7, 0.3, 1),
              transform 0.75s cubic-bezier(0.2, 0.7, 0.3, 1);
}
.reveal.in { opacity: 1; transform: none; }

/* ============================================================
   Responsive
   ============================================================ */
@media (max-width: 960px) {
  .site-nav { display: none; }
  .hero-grid { grid-template-columns: 1fr; min-height: 0; }
  .hero-visual { max-width: 560px; }
  .hero-face { min-height: 300px; }
  .pipeline { grid-template-columns: 1fr; }
  .pl-arrow { padding: 10px 0; justify-content: center; }
  .pl-arrow svg { transform: rotate(90deg); }
  .stats { grid-template-columns: repeat(2, 1fr); }
  .forecast { grid-template-columns: 1fr; }
  .modes { grid-template-columns: 1fr; }
}
@media (max-width: 760px) {
  .facts, .bento, .steps { grid-template-columns: 1fr; }
  .cases { grid-template-columns: 1fr; }
  .about-grid { grid-template-columns: 1fr; }
  .header-cta { display: none; }
  .fr-2 { display: none; }
}

/* ============================================================
   Transition — From → To
   ============================================================ */
.shift { text-align: center; }
.shift .eyebrow { justify-content: center; }
.shift .lede { margin: 26px auto 0; }
.shift-tagline {
  margin: 48px auto 0;
  max-width: 40ch;
  font-family: var(--sans);
  font-size: clamp(1.2rem, 2.4vw, 1.7rem);
  font-weight: 600;
  line-height: 1.5;
  color: var(--txt);
  text-wrap: balance;
}
.shift-tagline .hl {
  /* bright static blue — no animation (keeps it light on the GPU) */
  color: var(--blue-soft);
  font-weight: 700;
}
.shift-line {
  display: flex;
  flex-wrap: wrap;
  align-items: stretch;
  justify-content: center;
  gap: 18px;
  max-width: 100%;
  margin-inline: auto;
}
.shift-line .from, .shift-line .to {
  flex: 1 1 360px;
  max-width: 460px;
  text-align: left;
  background: var(--navy-2);
  border: 1px solid var(--line-d);
  border-radius: var(--r);
  padding: 24px 26px;
  font-size: clamp(20px, 2.4vw, 27px);
  font-weight: 700;
  line-height: 1.2;
  letter-spacing: -0.01em;
}
.shift-line .from { color: var(--txt-3); }
.shift-line .from b { color: var(--txt-2); font-weight: 700; }
.shift-line .to {
  color: var(--paper);
  border-color: color-mix(in srgb, var(--blue) 45%, var(--line-d));
  background: color-mix(in srgb, var(--blue) 7%, var(--navy-2));
}
.shift-line .to b { color: var(--blue-soft); font-weight: 700; }
.shift-line .tag-from, .shift-line .tag-to {
  display: block;
  font-family: var(--mono);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  margin-bottom: 12px;
}
.shift-line .tag-from { color: var(--txt-3); }
.shift-line .tag-to { color: var(--blue-soft); }
.shift-line .arrow {
  display: flex;
  align-items: center;
  color: var(--blue);
  flex: none;
}
@media (max-width: 820px) {
  .shift-line .arrow svg { transform: rotate(90deg); }
}

/* ============================================================
   Approche — cartes avec image au survol
   ============================================================ */
.steps { display: flex; flex-wrap: nowrap; gap: 16px; align-items: stretch; }
.step {
  flex: 1 1 0;
  min-width: 0;
  padding: 0;
  display: flex;
  align-items: stretch;
  overflow: hidden;
  transition: flex-grow 0.5s cubic-bezier(0.2, 0.7, 0.3, 1),
              border-color 0.3s ease;
}
.step:hover { transform: none; flex-grow: 2; }
.step-body { flex: 1 1 auto; min-width: 0; padding: 28px 24px; }
.step-img {
  flex: 0 0 0;
  width: 0;
  opacity: 0;
  overflow: hidden;
  align-self: stretch;
  border-left: 0 solid var(--line-d);
  transition: flex-basis 0.5s cubic-bezier(0.2, 0.7, 0.3, 1),
              opacity 0.45s ease,
              width 0.5s cubic-bezier(0.2, 0.7, 0.3, 1);
}
.step-img img { display: block; width: 100%; height: 100%; min-height: 100%; object-fit: cover; }
.step:hover .step-img {
  flex: 0 0 46%;
  width: auto;
  opacity: 1;
  border-left: 1px solid var(--line-d);
}
@media (max-width: 760px) {
  .steps { flex-direction: column; }
  .step { flex: 1 1 auto; flex-direction: column; }
  .step:hover { flex-grow: 1; }
  .step-img {
    flex: 0 0 auto;
    width: 100%;
    opacity: 1;
    height: 190px;
    border-left: 0;
    border-top: 1px solid var(--line-d);
  }
  .step:hover .step-img { flex: 0 0 auto; border-left: 0; border-top: 1px solid var(--line-d); }
}

/* ============================================================
   Différenciation — tableau comparatif
   ============================================================ */
.compare {
  margin-top: 44px;
  display: grid;
  grid-template-columns: 1fr 1fr;
  background: var(--navy-2);
  border: 1px solid var(--line-d);
  border-radius: var(--r);
  overflow: hidden;
}
.compare-col + .compare-col { border-left: 1px solid var(--line-d); }
.compare-new { background: color-mix(in srgb, var(--blue) 6%, var(--navy-2)); }
.compare-head { padding: 22px 26px; border-bottom: 1px solid var(--line-d); }
.compare-tag {
  display: flex;
  align-items: center;
  gap: 9px;
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--txt-3);
}
.compare-new .compare-tag { color: var(--blue-soft); }
.compare-name {
  display: block;
  margin-top: 7px;
  font-size: 18px;
  font-weight: 700;
  color: var(--txt-2);
}
.compare-new .compare-name { color: var(--paper); }
.cdot { width: 8px; height: 8px; border-radius: 50%; background: var(--blue); box-shadow: 0 0 8px var(--blue); flex: none; }
.compare ul { list-style: none; }
.compare li {
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 17px 26px;
  border-bottom: 1px solid var(--line-d);
  font-size: 15px;
  color: var(--txt-2);
}
.compare li:last-child { border-bottom: 0; }
.compare li::before { content: ""; width: 7px; height: 7px; border-radius: 50%; flex: none; }
.compare-old li::before { background: var(--txt-3); opacity: 0.5; }
.compare-new li { color: var(--txt); }
.compare-new li::before { background: var(--blue); }
.compare-new li b { color: var(--blue-soft); font-weight: 600; }
.compare-old li b { color: var(--txt-2); font-weight: 600; }
@media (max-width: 700px) {
  .compare { grid-template-columns: 1fr; }
  .compare-col + .compare-col { border-left: 0; border-top: 1px solid var(--line-d); }
}

/* pilliers sur une ligne + logos partenaires en images */
.pillars-row { grid-template-columns: repeat(3, 1fr); margin-top: 44px; }
@media (max-width: 760px) { .pillars-row { grid-template-columns: 1fr; } }

.partners .logos { gap: 18px 22px; align-items: center; }
.partners .logos img {
  flex: 0 0 auto;
  height: 60px;
  width: auto;
  max-width: 190px;
  object-fit: contain;
  /* La plaque reste BLANCHE dans les deux themes : les logos clients sont
     dessines pour du blanc, les teinter les casserait. En theme clair elle
     disparaitrait sur la page — d'ou le filet, transparent en sombre. */
  background: var(--logo-plate);
  border: 1px solid var(--logo-plate-line);
  border-radius: 8px;
  padding: 10px 16px;
  opacity: 0.92;
  transition: opacity 0.2s ease, transform 0.2s ease;
}
.partners .logos img:hover { opacity: 1; transform: translateY(-2px); }

/* ============================================================
   Segments ciblés — allumage de gauche à droite
   ============================================================ */
.segments { margin-top: 56px; padding-top: 32px; }
.segments-label {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--txt-3);
  margin-bottom: 18px;
}
/* Tuiles de secteurs — chacune montre son environnement reel.
   Remplace une cascade `sector-glow` qui allumait six pastilles de texte en
   boucle : rien ne la declenchait, elle ne s'arretait jamais, et elle attirait
   l'oeil vers un mouvement qui ne voulait rien dire. */
.seg-tiles {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 14px;
}
.seg-tile {
  position: relative; display: block; overflow: hidden;
  height: 132px; border-radius: var(--r);
  border: 1px solid var(--line-d); background: var(--navy-2);
  text-decoration: none;
  transition: border-color .45s ease, transform .45s cubic-bezier(.2,.7,.3,1);
}
.seg-tile img {
  width: 100%; height: 100%; object-fit: cover; display: block;
  /* Les photos sont plus claires que le fond navy : sans ce traitement, six
     vignettes vives cote a cote ecrasent le reste de la page. On les calme au
     repos et on les rend nettes au survol — l'attention suit le curseur. */
  filter: saturate(.62) brightness(.62);
  transform: scale(1.02);
  transition: filter .5s ease, transform .7s cubic-bezier(.2,.7,.3,1);
}
.seg-ov {
  position: absolute; inset: 0;
  /* --media-veil et non --navy : ce voile ASSOMBRIT une photo. Avec --navy il
     devenait blanc en thème clair et délavait les six vignettes. */
  background: linear-gradient(180deg, rgba(var(--media-veil), .25) 0%,
                                      rgba(var(--media-veil), .88) 100%);
}
.seg-name {
  position: absolute; left: 0; right: 0; bottom: 0;
  padding: 0 16px 14px;
  font-family: var(--mono); font-size: 12.5px; font-weight: 500;
  letter-spacing: .03em; color: var(--on-media);
  text-shadow: 0 1px 10px rgba(var(--media-veil), .8);
}
.seg-tile:hover, .seg-tile:focus-visible {
  border-color: color-mix(in srgb, var(--blue) 60%, var(--line-d));
  transform: translateY(-2px);
}
.seg-tile:hover img, .seg-tile:focus-visible img {
  filter: saturate(1) brightness(.9);
  transform: scale(1.06);
}
@media (max-width: 900px) { .seg-tiles { grid-template-columns: 1fr 1fr; } }
@media (max-width: 520px) { .seg-tiles { grid-template-columns: 1fr; } .seg-tile { height: 112px; } }
/* Le survol reste, mais plus aucun mouvement automatique. */
@media (prefers-reduced-motion: reduce) {
  .seg-tile, .seg-tile img { transition: none; }
}

/* ============================================================
   Popup — Essayez par vous-même
   ============================================================ */
.modal {
  position: fixed;
  inset: 0;
  z-index: 100;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: clamp(16px, 4vw, 40px);
}
.modal[hidden] { display: none; }
.modal-backdrop {
  position: absolute;
  inset: 0;
  background: color-mix(in srgb, var(--navy) 72%, black);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  animation: modal-fade 0.25s ease;
}
.modal-panel {
  position: relative;
  width: min(560px, 100%);
  max-height: calc(100vh - 48px);
  overflow-y: auto;
  background: var(--navy-2);
  border: 1px solid var(--line-d);
  border-radius: var(--r);
  box-shadow: 0 40px 120px -30px color-mix(in srgb, var(--blue) 30%, transparent);
  animation: modal-pop 0.3s cubic-bezier(0.2, 0.7, 0.3, 1);
}
@keyframes modal-fade { from { opacity: 0; } to { opacity: 1; } }
@keyframes modal-pop { from { opacity: 0; transform: translateY(14px) scale(0.98); } to { opacity: 1; transform: none; } }
.modal-close {
  position: absolute;
  top: 12px; right: 14px;
  width: 34px; height: 34px;
  border: 1px solid var(--line-d);
  border-radius: var(--r-sm);
  background: transparent;
  color: var(--txt-2);
  font-size: 22px;
  line-height: 1;
  cursor: pointer;
  z-index: 2;
}
.modal-close:hover { color: var(--paper); border-color: var(--txt-3); }
.modal-body { padding: clamp(26px, 4vw, 40px); }
.modal-body h2 { font-size: clamp(24px, 3vw, 32px); margin-bottom: 12px; max-width: none; }
.modal-lede { color: var(--txt-2); font-size: 15px; margin-bottom: 24px; }
.modal-form { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
.modal-form .field { display: flex; flex-direction: column; gap: 6px; }
.modal-form .field-full { grid-column: 1 / -1; }
.modal-form label {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--txt-3);
}
.modal-form input,
.modal-form select,
.modal-form textarea {
  font-family: var(--sans);
  font-size: 15px;
  color: var(--txt);
  background: var(--navy);
  border: 1px solid var(--line-d);
  border-radius: var(--r-sm);
  padding: 11px 13px;
  width: 100%;
  transition: border-color 0.2s ease;
}
.modal-form input:focus,
.modal-form select:focus,
.modal-form textarea:focus { outline: none; border-color: var(--blue); }
.modal-form textarea { resize: vertical; min-height: 76px; }
.modal-form select { appearance: none; cursor: pointer; }
.modal-actions {
  grid-column: 1 / -1;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px 20px;
  margin-top: 4px;
}
.modal-actions .btn { flex: none; }
.modal-privacy { font-size: 12.5px; color: var(--txt-3); flex: 1 1 200px; margin: 0; }
.modal-success {
  grid-column: 1 / -1;
  margin: 4px 0 0;
  padding: 12px 14px;
  border-radius: var(--r-sm);
  background: color-mix(in srgb, var(--ok) 14%, var(--navy));
  border: 1px solid color-mix(in srgb, var(--ok) 45%, var(--line-d));
  color: var(--txt);
  font-size: 14px;
}
.modal-success[hidden] { display: none; }
body.modal-open { overflow: hidden; }
@media (max-width: 560px) {
  .modal-form { grid-template-columns: 1fr; }
}

/* ============================================================
   Cartes flottantes (glass) + réactivité souris
   ============================================================ */
.float-card {
  position: relative;
  background: color-mix(in srgb, var(--navy-2) 60%, transparent);
  border: 1px solid color-mix(in srgb, var(--blue-soft) 13%, var(--line-d));
  border-radius: var(--r);
  backdrop-filter: blur(9px) saturate(1.1);
  -webkit-backdrop-filter: blur(9px) saturate(1.1);
  box-shadow: 0 24px 60px -30px rgba(var(--shadow), var(--shadow-a1)),
              inset 0 1px 0 color-mix(in srgb, var(--blue-soft) 10%, transparent);
  will-change: transform;
}
/* la position parallax est posée par JS via --mx/--my ; le survol ajoute un léger lift */
.float-card { transition: box-shadow 0.3s ease, border-color 0.3s ease; }

/* ============================================================
   Hero — bloc ASLAN ENGINE
   ============================================================ */
.engine-band { margin-top: clamp(38px, 5vw, 60px); position: relative; z-index: 2; }
.engine-eyebrow {
  display: flex; align-items: center; justify-content: center; gap: 12px;
  font-family: var(--mono); font-size: 11px; letter-spacing: 0.18em;
  text-transform: uppercase; color: var(--txt-3); margin-bottom: clamp(22px, 3vw, 34px);
  text-align: center;
}
.engine-eyebrow .dot { width: 5px; height: 5px; border-radius: 50%; background: var(--blue); box-shadow: 0 0 8px var(--blue); flex: none; }

.engine-diagram {
  position: relative;
  display: grid;
  grid-template-columns: minmax(190px, 240px) minmax(240px, 1fr) minmax(210px, 300px);
  gap: clamp(16px, 3.5vw, 56px);
  align-items: center;
}
.engine-flow { position: absolute; inset: 0; width: 100%; height: 100%; z-index: 0; pointer-events: none; }
.ef-dot { filter: drop-shadow(0 0 3px currentColor); }
.ef-teal { fill: var(--s-vig); color: var(--s-vig); }
.ef-blue { fill: var(--blue); color: var(--blue); }
.ef-soft { fill: var(--blue-soft); color: var(--blue-soft); }
.eng-inputs, .eng-center, .eng-output { position: relative; z-index: 1; }

/* colonne d'entrées */
.eng-inputs { display: flex; flex-direction: column; gap: 8px; }
.eng-glabel {
  font-family: var(--mono); font-size: 10px; letter-spacing: 0.16em;
  text-transform: uppercase; color: var(--txt-3); margin: 2px 0;
}
.eng-glabel-env { color: color-mix(in srgb, var(--s-vig) 75%, var(--txt-2)); margin-top: 14px; }
.eng-glabel-hum { color: var(--blue-soft); }
.eng-src {
  display: flex; align-items: center;
  padding: 12px 16px; border-radius: 10px; font-size: 13.5px; font-weight: 500; color: var(--txt);
  backdrop-filter: none; -webkit-backdrop-filter: none;
}
.eng-src[data-group="hum"] { border-left: 2px solid color-mix(in srgb, var(--blue) 60%, transparent); }
.eng-src[data-group="env"] { border-left: 2px solid color-mix(in srgb, var(--s-vig) 60%, transparent); }
.eng-lbl { min-width: 0; }

/* centre : ASLAN ENGINE */
.eng-center { display: flex; flex-direction: column; align-items: center; gap: 14px; }
.eng-tag {
  display: flex; align-items: center; gap: 9px;
  font-family: var(--mono); font-size: 11px; letter-spacing: 0.18em; color: var(--blue-soft);
}
.eng-tag .dot { width: 4px; height: 4px; border-radius: 50%; background: var(--blue-soft); box-shadow: 0 0 6px var(--blue-soft); }
.eng-core { width: 100%; max-width: 330px; padding: 20px 22px; }
.eng-steps { display: flex; align-items: center; gap: 8px; margin-bottom: 18px; }
.eng-step {
  width: 30px; height: 30px; border-radius: 50%; flex: none;
  display: grid; place-items: center; cursor: pointer;
  border: 1px solid var(--line-d); font-family: var(--mono); font-size: 11px; color: var(--txt-3);
  transition: all 0.3s ease;
}
.eng-step.active { background: var(--blue); border-color: var(--blue); color: var(--on-accent); box-shadow: 0 0 16px -2px var(--blue); }
.eng-steps i { flex: 1; height: 1px; background: var(--line-d); }
.eng-slide { min-height: 132px; }
.eng-num { font-family: var(--mono); font-size: 11px; letter-spacing: 0.14em; text-transform: uppercase; color: var(--s-vig); margin-bottom: 9px; }
.eng-title { font-size: 19px; font-weight: 700; color: var(--paper); line-height: 1.18; margin-bottom: 10px; }
.eng-desc { font-size: 12.5px; color: var(--txt-2); line-height: 1.5; }

/* sortie : alertes */
.eng-alerts { padding: 16px 18px; }
.eng-ahead { display: flex; align-items: center; gap: 9px; margin-bottom: 12px; }
.eng-adot { width: 8px; height: 8px; border-radius: 50%; background: var(--crit); box-shadow: 0 0 8px var(--crit); animation: beat 1.5s ease-in-out infinite; flex: none; }
.eng-atitle { font-size: 12.5px; font-weight: 600; color: var(--paper); }
.eng-arow { display: flex; gap: 10px; padding: 10px 0; border-top: 1px solid var(--line-d); }
.eng-arow.done { opacity: 0.5; }
.eng-aic { width: 26px; height: 26px; border-radius: 6px; display: grid; place-items: center; font-size: 12px; flex: none; }
.eng-aic.crit { background: color-mix(in srgb, var(--crit) 16%, transparent); }
.eng-aic.warn { background: color-mix(in srgb, var(--warn) 16%, transparent); }
.eng-aic.ok { background: color-mix(in srgb, var(--txt-3) 16%, transparent); }
.eng-atext { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.eng-atext b { font-size: 11.5px; font-weight: 600; color: var(--txt); line-height: 1.3; }
.eng-atime { font-family: var(--mono); font-size: 10px; color: var(--txt-3); }

/* sortie : cartes cyclées */
.eng-output { display: flex; flex-direction: column; gap: 12px; }
.eng-alerts { min-height: 214px; transition: opacity 0.35s ease; }
.eng-adot.blue { background: var(--blue); box-shadow: 0 0 8px var(--blue); }
.eng-adot.ok { background: var(--ok); box-shadow: 0 0 8px var(--ok); }
.eng-adot.teal { background: var(--s-vig); box-shadow: 0 0 8px var(--s-vig); }
.eng-dots { display: flex; justify-content: center; gap: 7px; }
.eng-dots span { width: 6px; height: 6px; border-radius: 50%; background: var(--line-d); cursor: pointer; transition: all 0.3s ease; }
.eng-dots span.active { background: var(--blue-soft); width: 18px; border-radius: 3px; }
.eng-gauge { display: flex; align-items: center; gap: 14px; margin-bottom: 10px; }
.eng-gnum { font-size: 30px; font-weight: 800; color: var(--paper); letter-spacing: -0.02em; line-height: 1; }
.eng-gnum s { font-size: 13px; color: var(--txt-3); font-weight: 600; text-decoration: none; }
.eng-gstate { font-size: 11px; font-weight: 700; margin-top: 4px; }
.eng-orow { display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 8px 0; border-top: 1px solid var(--line-d); font-size: 12px; }
.eng-orow.first { border-top: 0; }
.eng-orow .k { color: var(--txt-3); }
.eng-orow .v { color: var(--txt); font-weight: 600; font-variant-numeric: tabular-nums; }
.eng-orow .v.warn { color: var(--warn); }
.eng-orow .v.ok { color: var(--ok); }
.op-badge { font-size: 10px; padding: 3px 9px; border-radius: 20px; font-weight: 600; white-space: nowrap; }
.eng-bar { flex: 1; height: 5px; border-radius: 3px; background: color-mix(in srgb, var(--navy) 55%, transparent); overflow: hidden; margin: 0 10px; }
.eng-bar > i { display: block; height: 100%; border-radius: 3px; }

.engine-foot {
  display: flex; flex-wrap: wrap; justify-content: center; gap: 14px 30px;
  margin-top: clamp(26px, 4vw, 42px);
}
.engine-foot span { display: inline-flex; align-items: center; gap: 9px; font-size: 13.5px; color: var(--txt-2); }
.engine-foot i {
  width: 18px; height: 18px; border-radius: 5px; flex: none; font-style: normal; font-size: 11px;
  display: grid; place-items: center; color: var(--blue-soft);
  background: color-mix(in srgb, var(--blue) 18%, transparent);
}

@media (max-width: 900px) {
  .engine-diagram {
    grid-template-columns: 1fr;
    gap: 20px;
  }
  .engine-flow { display: none; }
  .eng-inputs { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
  .eng-glabel { grid-column: 1 / -1; }
  .eng-core { max-width: 100%; }
  .eng-output { max-width: 480px; margin: 0 auto; width: 100%; }
}
@media (max-width: 520px) {
  .eng-inputs { grid-template-columns: 1fr; }
}

/* ============================================================
   Carrousel de logos partenaires
   ============================================================ */
.logo-carousel {
  position: relative;
  overflow: hidden;
  margin-top: 6px;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 7%, #000 93%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 7%, #000 93%, transparent);
}
.logo-track {
  display: flex;
  align-items: center;
  gap: 56px;
  width: max-content;
  animation: logo-scroll 38s linear infinite;
}
.logo-carousel:hover .logo-track { animation-play-state: paused; }
@keyframes logo-scroll { from { transform: translateX(0); } to { transform: translateX(-50%); } }
.logo-chip {
  flex: none;
  display: grid;
  place-items: center;
  height: 56px;
  padding: 0 4px;
  background: transparent;
}
.logo-chip img {
  height: 40px; width: auto;
  object-fit: contain; display: block;
  opacity: 0.62;
  transition: opacity 0.25s ease;
}
.logo-chip img:hover { opacity: 1; }

/* Segment stagger is defined once, above (one-by-one chase for up to 10 items). */

/* ============================================================
   Approche — carte « Capter » déployée par défaut
   ============================================================ */
.step:first-child { flex-grow: 2.3; }
.step:first-child .step-img { flex: 0 0 46%; width: auto; opacity: 1; border-left: 1px solid var(--line-d); }
.steps:hover .step:first-child:not(:hover) { flex-grow: 1; }
.steps:hover .step:first-child:not(:hover) .step-img { flex: 0 0 0; width: 0; opacity: 0; border-left: 0; }
@media (max-width: 760px) {
  .step:first-child .step-img { border-left: 0; border-top: 1px solid var(--line-d); }
}

/* ============================================================
   Glass léger sur les cartes de sections + fond subtil
   ============================================================ */
body { background-image:
  radial-gradient(80% 50% at 15% 0%, color-mix(in srgb, var(--blue) 5%, transparent), transparent 60%),
  radial-gradient(70% 50% at 90% 20%, color-mix(in srgb, var(--s-drow) 4%, transparent), transparent 60%);
  background-attachment: fixed;
}
.step, .mode, .compare, .pillar, .stat, .fact {
  background: color-mix(in srgb, var(--navy-2) 72%, transparent);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}
.mode:hover, .compare:hover { box-shadow: 0 24px 60px -34px color-mix(in srgb, var(--blue) 55%, transparent); }

/* ============================================================
   Cartes réactives à la souris — glare + tilt 3D
   ============================================================ */
.has-glare::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  pointer-events: none;
  z-index: 3;
  background: radial-gradient(220px circle at var(--gx, 50%) var(--gy, 50%),
              color-mix(in srgb, var(--blue-soft) 20%, transparent), transparent 60%);
  opacity: var(--glare, 0);
  transition: opacity 0.7s ease;
}
/* 0,55 s au lieu de 0,28 s : le mouvement suit le curseur avec un peu de
   retard au lieu de coller image par image. C'est ce delai qui fait la
   difference entre « vivant » et « nerveux ». */
.tilt { transform-style: preserve-3d; transition: transform 0.55s cubic-bezier(0.2, 0.7, 0.3, 1); }

/* ============================================================
   Shift — balayage lumineux gauche → flèche → droite
   ============================================================ */
.shift-line .from, .shift-line .to { position: relative; }
.shift-line .from { animation: sweep-from 2.2s ease-in-out infinite; }
.shift-line .to { animation: sweep-to 2.2s ease-in-out infinite; }
.shift-line .lumina-shimmer { animation-duration: 2.2s; }
/* light travels through the words left → right, one after another */
.shift-line .sw { animation-delay: calc(var(--wi) * 0.13s); }
/* blue "to" words are lit with a white pulse so the sweep stays visible on them */
.shift-line .to b .sw {
  background-image: linear-gradient(100deg,
    currentColor 44%, var(--paper) 50%, currentColor 56%);
}
@keyframes sweep-from {
  0%, 6%, 30%, 100% { box-shadow: 0 0 0 0 transparent; }
  16% { box-shadow: 0 18px 50px -18px color-mix(in srgb, var(--blue) 45%, transparent),
                    inset 0 0 0 1px color-mix(in srgb, var(--blue) 40%, transparent); }
}
@keyframes sweep-to {
  0%, 48%, 72%, 100% { box-shadow: 0 0 0 0 transparent; }
  60% { box-shadow: 0 20px 60px -16px color-mix(in srgb, var(--blue) 62%, transparent),
                    inset 0 0 0 1px color-mix(in srgb, var(--blue) 58%, transparent); }
}
.shift-line .arrow { position: relative; }
.shift-line .arrow::before {
  content: "";
  position: absolute; top: 50%; left: 2px;
  width: 9px; height: 9px; margin-top: -4.5px;
  border-radius: 50%;
  background: var(--blue-soft);
  box-shadow: 0 0 12px 2px var(--blue-soft);
  opacity: 0;
  animation: shift-spark 2.2s ease-in-out infinite;
}
@keyframes shift-spark {
  0%, 26% { opacity: 0; transform: translateX(0); }
  32% { opacity: 1; }
  48% { opacity: 1; transform: translateX(34px); }
  54%, 100% { opacity: 0; transform: translateX(40px); }
}

/* ============================================================
   Titres lumineux — reflet qui balaie le texte
   ============================================================ */
.lumina-shimmer {
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  background-color: currentColor;
  background-image: linear-gradient(100deg,
    currentColor 43%, var(--blue-soft) 50%, currentColor 57%);
  background-size: 250% 100%;
  background-repeat: no-repeat;
  animation: lumina-shimmer 2.6s ease-in-out infinite;
}
/* le balayage occupe ~2,1 s puis marque une pause de ~0,5 s avant de repartir */
@keyframes lumina-shimmer {
  0% { background-position: 100% 0; }
  80%, 100% { background-position: 0% 0; }
}

/* ============================================================
   Différenciation — colonne ASLAN illuminée de haut en bas
   ============================================================ */
.compare-new { position: relative; }
.compare-new > * { position: relative; z-index: 1; }
.compare-new::before {
  content: "";
  position: absolute; left: 0; right: 0;
  top: -50%; height: 46%;
  background: linear-gradient(180deg, transparent,
              color-mix(in srgb, var(--blue) 18%, transparent), transparent);
  pointer-events: none;
  z-index: 0;
  /* ann_05 — c'etait `aslan-sweep 3.6s infinite`. Une bande lumineuse qui
     traverse un bloc de LECTURE toutes les 3,6 s, indefiniment, empeche de lire
     le bloc. Elle ne se joue plus qu'UNE fois, a l'arrivee du bloc dans le
     champ (`.reveal` pose `.in`), et deux fois plus lentement. */
  animation: none;
}
.compare.in .compare-new::before {
  animation: aslan-sweep 7s cubic-bezier(0.4, 0, 0.2, 1) 0.35s 1 both;
}
@keyframes aslan-sweep {
  0% { top: -50%; opacity: 0; }
  12% { opacity: 1; }
  88% { opacity: 1; }
  100% { top: 100%; opacity: 0; }
}

/* garder la transition d'expansion des étapes tout en ajoutant le tilt */
.step.tilt {
  transition: flex-grow 0.5s cubic-bezier(0.2, 0.7, 0.3, 1),
              border-color 0.3s ease,
              transform 0.28s cubic-bezier(0.2, 0.7, 0.3, 1);
}

/* ============================================================
   Pillars & stats — allumage lumineux en vague (comme les segments)
   ============================================================ */
/* ann_05 — meme correction que pour .compare : ces trois groupes de cartes
   clignotaient en boucle toutes les 5,5 s, en permanence. Une seule passe
   quand le groupe arrive a l'ecran, puis plus rien. */
.pillars-row .pillar, .stats .stat, .steps .step { animation: card-lit 6.5s ease-in-out 1 both; }
.pillars-row .pillar:nth-child(1) { animation-delay: 0s; }
.pillars-row .pillar:nth-child(2) { animation-delay: 0.5s; }
.pillars-row .pillar:nth-child(3) { animation-delay: 1s; }
.steps .step:nth-child(1) { animation-delay: 0s; }
.steps .step:nth-child(2) { animation-delay: 0.45s; }
.steps .step:nth-child(3) { animation-delay: 0.9s; }
.stats .stat:nth-child(1) { animation-delay: 0.2s; }
.stats .stat:nth-child(2) { animation-delay: 0.6s; }
.stats .stat:nth-child(3) { animation-delay: 1s; }
.stats .stat:nth-child(4) { animation-delay: 1.4s; }
@keyframes card-lit {
  0%, 52%, 100% {
    border-color: var(--line-d);
    box-shadow: none;
  }
  14%, 30% {
    border-color: color-mix(in srgb, var(--blue) 55%, var(--line-d));
    box-shadow: 0 0 0 1px color-mix(in srgb, var(--blue) 45%, transparent),
                0 12px 36px -12px color-mix(in srgb, var(--blue) 55%, transparent);
  }
}

/* ============================================================
   Mouvement réduit
   ============================================================ */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .logo-track { animation: none; }
  .pillars-row .pillar, .stats .stat, .steps .step { animation: none; }
  .engine-flow .ef-dot { display: none; }
  .float-card { transform: none !important; }
  .has-glare::after { display: none; }
  .tilt { transform: none !important; }
  .shift-line .from, .shift-line .to { animation: none; }
  .shift-line .arrow::before { animation: none; display: none; }
  .compare-new::before, .compare.in .compare-new::before { animation: none; display: none; }
  .lumina-shimmer { animation: none; background-position: 50% 0; }
  .reveal { opacity: 1; transform: none; transition: none; }
  .pipeline .expert, .pipeline .core-block, .pipeline .output {
    opacity: 1; transform: none; animation: none;
  }
  .ticker-track { animation: none; }
  .hero-kicker .dot { animation: none; }
  .beacon .ring { animation: none; }
  .fact .drift path { stroke-dashoffset: 0 !important; animation: none; }
  .case::after { display: none; }
  .fact, .axis, .case, .btn { transition: none; }
  .step, .step-img { transition: none; }
  .modal-backdrop, .modal-panel { animation: none; }
}

/* ============================================================
   ============  WEBSITE V2 — MULTI-PAGE COMPONENTS  ==========
   ============================================================ */

/* ---------- Utilities ---------- */
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.section-pad { padding: clamp(64px, 9vw, 120px) 0; }

/* ---------- Header: page nav active + mobile ---------- */
.site-nav a[aria-current="page"] {
  color: var(--paper);
  background: var(--navy-3);
  border-color: var(--line-d);
}
.nav-toggle {
  display: none;
  margin-left: auto;
  width: 40px; height: 40px;
  border: 1px solid var(--line-d);
  border-radius: var(--r-sm);
  background: transparent;
  cursor: pointer;
  padding: 0;
  flex-direction: column;
  align-items: center; justify-content: center;
  gap: 5px;
}
.nav-toggle span {
  display: block; width: 18px; height: 2px; border-radius: 2px;
  background: var(--txt); transition: transform .3s ease, opacity .2s ease;
}
.nav-toggle[aria-expanded="true"] span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.nav-toggle[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.nav-toggle[aria-expanded="true"] span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

/* ---------- Footer nav ---------- */
.site-footer .wrap { flex-wrap: wrap; gap: 18px 30px; }
.footer-nav { display: flex; gap: 20px; flex-wrap: wrap; }
.footer-nav a { font-size: 14px; }
.foot-legal { color: var(--txt-3); font-size: 13px; margin-left: auto; }
@media (max-width: 760px) { .foot-legal { margin-left: 0; flex-basis: 100%; } }

/* ---------- Hero video ---------- */
.hero-video { padding-top: clamp(40px, 6vw, 64px); padding-bottom: clamp(32px, 4vw, 48px); }
.header-cta.header-cta-active { background: var(--blue-deep); }
.hero-video .video-bleed { margin-top: 0; }
.hero-video .video-shell { max-width: var(--wrap); margin: 0 auto; }
.hero-video video { aspect-ratio: 16 / 9; background: var(--deep); object-fit: cover; }

/* ---------- Static ticker (value phrases) ---------- */
.ticker-track .tk { color: var(--txt-2); }
.ticker-track .tk b { color: var(--blue-soft); }

/* ---------- Shift figure with mouse spotlight ---------- */
.shift-figure {
  position: relative;
  margin: 12px auto 0;
  max-width: 1120px;
  border-radius: var(--r);
  overflow: hidden;
  border: 1px solid var(--line-d);
  background: var(--navy-2);
  isolation: isolate;
}
.shift-figure .shift-img {
  display: block; width: 100%; height: auto;
  filter: saturate(1.02);
  transition: transform .5s cubic-bezier(.2,.7,.3,1);
}
.shift-figure .spot {
  position: absolute; inset: 0;
  pointer-events: none; z-index: 2;
  opacity: 0; transition: opacity .3s ease;
  background: radial-gradient(220px circle at var(--sx,50%) var(--sy,50%),
              color-mix(in srgb, var(--blue) 16%, transparent), transparent 65%);
  mix-blend-mode: screen;
}
.shift-figure::after {
  content: ""; position: absolute; inset: 0; z-index: 3; pointer-events: none;
  border-radius: inherit;
  box-shadow: inset 0 0 0 1px transparent;
  transition: box-shadow .3s ease;
}
.shift-figure:hover .spot { opacity: 1; }
.shift-figure:hover::after { box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--blue-soft) 22%, transparent); }
.shift-figure:hover .shift-img { transform: scale(1.012); }
/* La phrase tenait sur une ligne quand elle etait plus courte ; le `nowrap`
   au-dessus de 900 px l'a suivie sans bouger et elle finissait TRONQUEE —
   scrollWidth 1245 pour clientWidth 1064 a 1280 comme a 1440 px, 1141 pour 928
   a 1024 px : « ...devienne une defaillance operation ». On la laisse passer a
   deux lignes ; `text-wrap: balance` (regle de base) les equilibre. */
.shift .shift-tagline { max-width: none; white-space: normal; }

/* ---------- Modes: 4-card grid + titles + placeholders ---------- */
.modes-4 { grid-template-columns: repeat(2, 1fr); }
.mode .mode-title { font-size: clamp(20px, 2.3vw, 26px); color: var(--blue-soft); font-weight: 700; letter-spacing: -0.01em; margin-bottom: 4px; text-transform: none; }
.mode .mode-sub { font-family: var(--mono); font-size: 12.5px; letter-spacing: 0.04em; color: var(--txt-3); text-transform: uppercase; margin-bottom: 14px; }
.mode-canvas { display: block; width: 100%; height: 150px; margin-top: 20px; }
.ph-visual {
  border: 1px dashed var(--line-d);
  border-radius: var(--r-sm);
  background:
    linear-gradient(color-mix(in srgb, var(--navy-3) 60%, transparent), color-mix(in srgb, var(--navy-3) 20%, transparent)),
    repeating-linear-gradient(45deg, transparent 0 10px, color-mix(in srgb, var(--blue) 5%, transparent) 10px 11px);
  display: grid; place-items: center;
  position: relative; overflow: hidden;
}
.ph-visual::before {
  content: ""; position: absolute; width: 46px; height: 46px; border-radius: 50%;
  border: 1px solid color-mix(in srgb, var(--blue) 50%, transparent);
  box-shadow: 0 0 0 8px color-mix(in srgb, var(--blue) 8%, transparent);
  top: 26%;
}
.ph-note { font-family: var(--mono); font-size: 11px; letter-spacing: .08em; text-transform: uppercase; color: var(--txt-3); }
@media (max-width: 760px) { .modes-4 { grid-template-columns: 1fr; } }

/* ---------- Sectors symmetric grid (3 x 2) ---------- */
.sectors-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 14px;
  margin-top: 40px;
}
.sectors-grid > span {
  justify-content: center;
  text-align: center;
  padding: 16px 14px;
  font-weight: 600;
}
@media (max-width: 640px) { .sectors-grid { grid-template-columns: repeat(2, 1fr); } }

/* ---------- Stats: 3-up + badge ---------- */
.stats-3 { grid-template-columns: repeat(3, 1fr); }
.stat .n.stat-badge { font-size: clamp(24px, 3vw, 34px); letter-spacing: 0.01em; }
.stat .n.stat-badge .u { display: block; font-size: 0.5em; color: var(--blue-soft); margin: 4px 0 0; }
@media (max-width: 760px) { .stats-3 { grid-template-columns: 1fr; } }

/* ---------- Accordion ---------- */
.accordion {
  max-width: 860px;
  margin: 40px auto 0;
  display: grid;
  gap: 12px;
}
.acc-item {
  border: 1px solid var(--line-d);
  border-radius: var(--r);
  background: var(--navy-2);
  overflow: hidden;
  transition: border-color .3s ease, background .3s ease;
}
.acc-item.open { border-color: color-mix(in srgb, var(--blue) 55%, var(--line-d)); }
.acc-head {
  width: 100%;
  display: flex; align-items: center; justify-content: space-between; gap: 20px;
  padding: 20px 22px;
  background: transparent; border: 0; cursor: pointer;
  font-family: var(--sans); font-size: clamp(17px, 2vw, 20px); font-weight: 600;
  color: var(--txt); text-align: left;
}
.acc-item.open .acc-head { color: var(--blue-soft); }
.acc-icon {
  position: relative; flex: none;
  width: 34px; height: 34px; border-radius: 50%;
  background: var(--navy-3); border: 1px solid var(--line-d);
  transition: background .3s ease, transform .3s ease;
}
.acc-icon::before, .acc-icon::after {
  content: ""; position: absolute; top: 50%; left: 50%;
  width: 13px; height: 2px; border-radius: 2px; background: var(--txt);
  transform: translate(-50%, -50%); transition: transform .3s ease, opacity .3s ease;
}
.acc-icon::after { transform: translate(-50%, -50%) rotate(90deg); }
.acc-item.open .acc-icon { background: var(--blue); border-color: var(--blue); }
.acc-item.open .acc-icon::before, .acc-item.open .acc-icon::after { background: var(--on-accent); }
.acc-item.open .acc-icon::after { transform: translate(-50%, -50%) rotate(0); opacity: 0; }
.acc-body {
  overflow: hidden;
  max-height: 0;
  transition: max-height .4s cubic-bezier(.2,.7,.3,1);
}
.acc-body p {
  padding: 0 22px 22px;
  color: var(--txt-2);
  font-size: 15.5px;
  max-width: 70ch;
}

/* ---------- CTA band ---------- */
.cta-band { text-align: center; padding: clamp(72px, 10vw, 130px) 0; }
.cta-band .lede { margin: 20px auto 0; }
.cta-band .hero-actions { justify-content: center; margin-top: 30px; }

/* ============================================================
   SOLUTIONS PAGE
   ============================================================ */
.page-hero { padding: clamp(56px, 8vw, 96px) 0 clamp(24px, 4vw, 40px); text-align: center; }
.page-hero h1 {
  font-size: clamp(34px, 6vw, 62px);
  font-weight: 700; letter-spacing: -0.02em; line-height: 1.04;
  color: var(--paper); max-width: 20ch; margin: 10px auto 0;
}
.page-hero .lede { margin: 22px auto 0; max-width: 62ch; }
.page-hero .eyebrow { justify-content: center; }

/* Detection mosaic */
.mosaic {
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  grid-auto-rows: 150px;
  gap: 14px;
  margin-top: 40px;
}
.mo-cell {
  position: relative; overflow: hidden;
  border-radius: var(--r);
  border: 1px solid var(--line-d);
  background: var(--navy-2);
}
.mo-cell img { width: 100%; height: 100%; object-fit: cover; display: block; transition: transform .6s cubic-bezier(.2,.7,.3,1); }
.mo-cell::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(180deg, transparent 40%, rgba(var(--media-veil), .72));
  opacity: .85; transition: opacity .3s ease;
}
.mo-cell .mo-label {
  position: absolute; left: 14px; bottom: 12px; z-index: 2;
  font-family: var(--mono); font-size: 11.5px; letter-spacing: .06em;
  text-transform: uppercase; color: var(--on-media);
  display: flex; align-items: center; gap: 7px;
}
.mo-cell .mo-label::before {
  content: ""; width: 7px; height: 7px; border-radius: 50%;
  background: var(--blue); box-shadow: 0 0 8px var(--blue);
}
.mo-cell:hover img { transform: scale(1.06); }
.mo-cell:hover::after { opacity: .55; }
/* ann_06 — « on ne le voit pas bien ». La cellule « Fatigue opérateur » faisait
   3 colonnes sur 1 rangée, soit 3,9:1 : aucun portrait ne tient dans un bandeau
   pareil, `object-fit: cover` en gardait une tranche à hauteur des yeux. Elle
   passe donc à 2 rangées — 1,85:1, presque exactement le format du fichier
   (476x270 = 1,76:1), donc quasiment plus de recadrage. Les quatre autres
   descendent en bandeaux de 3 colonnes : ce sont des scènes larges, le format
   leur convient, et la mosaïque garde deux formats au lieu de trois. */
.mo-a { grid-column: span 3; grid-row: span 2; }
.mo-b { grid-column: span 3; grid-row: span 2; }
.mo-c { grid-column: span 3; }
.mo-d { grid-column: span 3; }
.mo-e { grid-column: span 3; }
.mo-f { grid-column: span 3; }
/* Retour client — « de mauvaise qualité et mal coupée ». Le fichier faisait
   384x214 (le visage collé au bord droit, le cadre orange tronqué) là où ses
   voisines font 1400 px de large. Ré-exporté depuis la source propre, rogné de
   96 px A GAUCHE seulement : 1280x768, soit 1,667:1 — exactement le format de
   la cellule au bureau, donc plus aucun recadrage horizontal et le mot
   « tired » (qui s'arrête à 8 px du bord droit) reste entier. L'ancrage à
   droite ne sert qu'en dessous de 700 px, où la cellule redevient presque
   carrée : c'est alors les écrans flous qu'on sacrifie, pas le visage. */
.mo-b img { object-position: 100% 50%; }

/* ann_07 — encart vert au-dessus du libellé, symétrique de l'encart orange
   d'ann_05 : l'un signale un écart, l'autre un état conforme. */
.mo-cell .mo-flag {
  position: absolute; left: 14px; top: 12px; z-index: 2;
  display: inline-flex; align-items: center; gap: 7px;
  padding: 5px 10px; border-radius: 999px;
  font-family: var(--mono); font-size: 10.5px; letter-spacing: .06em;
  text-transform: uppercase; white-space: nowrap;
  color: var(--teal-soft);
  background: color-mix(in srgb, var(--navy) 82%, transparent);
  border: 1px solid color-mix(in srgb, var(--s-vig) 55%, var(--line-d));
}
.mo-cell .mo-flag::before {
  content: ""; width: 7px; height: 7px; border-radius: 50%;
  background: var(--s-vig); box-shadow: 0 0 8px var(--s-vig);
}
@media (max-width: 860px) {
  .mosaic { grid-template-columns: repeat(2, 1fr); grid-auto-rows: 130px; }
  .mo-a, .mo-b, .mo-c, .mo-d, .mo-e, .mo-f { grid-column: span 1; grid-row: span 1; }
  .mo-a { grid-column: span 2; grid-row: span 2; }
  /* En 2 colonnes une cellule fait ~160x130 : le portrait tient, pas besoin
     des 2 rangées du desktop. On les retire explicitement, sinon la règle
     `grid-row: span 2` de .mo-b l'emporterait par ordre d'écriture. */
  .mo-b { grid-column: span 1; grid-row: span 1; }
  .mo-flag { font-size: 9.5px; padding: 4px 8px; }
}

/* Multi-row moving marquee */
.marquee { display: grid; gap: 12px; margin-top: 12px; overflow: hidden; padding: 4px 0; position: relative; }
.marquee::before, .marquee::after {
  content: ""; position: absolute; top: 0; bottom: 0; width: 12%; z-index: 3; pointer-events: none;
}
.marquee::before { left: 0; background: linear-gradient(90deg, var(--navy), transparent); }
.marquee::after { right: 0; background: linear-gradient(-90deg, var(--navy), transparent); }
.mq-row { display: flex; gap: 12px; width: max-content; will-change: transform; }
.mq-row.left { animation: mq-left 46s linear infinite; }
.mq-row.right { animation: mq-right 52s linear infinite; }
.marquee:hover .mq-row { animation-play-state: paused; }
@keyframes mq-left { from { transform: translateX(0); } to { transform: translateX(-50%); } }
@keyframes mq-right { from { transform: translateX(-50%); } to { transform: translateX(0); } }
.mq-chip {
  flex: none;
  display: inline-flex; align-items: center; gap: 9px;
  padding: 11px 18px;
  border: 1px solid var(--line-d);
  border-radius: 999px;
  background: var(--navy-2);
  color: var(--txt-2);
  font-size: 14px; font-weight: 500; white-space: nowrap;
  transition: color .25s ease, border-color .25s ease, background .25s ease;
}
.mq-chip::before {
  content: ""; width: 6px; height: 6px; border-radius: 50%;
  background: var(--s-vig); flex: none;
}
.mq-chip:hover { color: var(--paper); border-color: color-mix(in srgb, var(--blue) 55%, var(--line-d)); background: var(--navy-3); }

/* Right fit (tailor-made deployment) */
.fit-grid {
  display: grid; grid-template-columns: 1.05fr 1fr; gap: clamp(28px, 5vw, 64px);
  align-items: center; margin-top: 36px;
}
.fit-list { display: grid; gap: 14px; margin-top: 26px; }
.fit-row {
  display: flex; gap: 16px; align-items: flex-start;
  padding: 18px 20px; border-radius: var(--r);
  border: 1px solid var(--line-d); background: var(--navy-2);
  transition: transform .3s ease, border-color .3s ease;
}
.fit-row:hover { transform: translateX(6px); border-color: color-mix(in srgb, var(--blue) 45%, var(--line-d)); }
.fit-ic {
  flex: none; width: 40px; height: 40px; border-radius: 50%;
  display: grid; place-items: center;
  background: var(--navy-3); border: 1px solid var(--line-d); color: var(--blue-soft);
}
.fit-ic svg { width: 20px; height: 20px; }
.fit-row h3 { font-size: 17px; color: var(--paper); margin-bottom: 3px; font-weight: 600; }
.fit-row p { font-size: 14.5px; color: var(--txt-2); }
.fit-visual { position: relative; border-radius: var(--r); overflow: hidden; border: 1px solid var(--line-d); isolation: isolate; }
.fit-visual img { display: block; width: 100%; height: 100%; object-fit: cover; transition: transform .5s cubic-bezier(.2,.7,.3,1); }
.fit-visual .spot {
  position: absolute; inset: 0; pointer-events: none; z-index: 2; opacity: 0;
  transition: opacity .3s ease; mix-blend-mode: screen;
  background: radial-gradient(240px circle at var(--sx,50%) var(--sy,50%), color-mix(in srgb, var(--blue) 20%, transparent), transparent 62%);
}
.fit-visual:hover .spot { opacity: 1; }
.fit-visual:hover img { transform: scale(1.02); }
@media (max-width: 860px) { .fit-grid { grid-template-columns: 1fr; } .fit-visual { order: -1; } }

/* Why ASLAN — 6 cards */
.why-cards {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; margin-top: 40px;
}
.why-card {
  border: 1px solid var(--line-d); border-radius: var(--r);
  background: var(--navy-2); padding: 26px 24px;
  transition: transform .3s ease, border-color .3s ease, background .3s ease;
}
.why-card:hover { transform: translateY(-5px); border-color: color-mix(in srgb, var(--blue) 45%, var(--line-d)); background: var(--navy-3); }
.why-ic {
  width: 44px; height: 44px; border-radius: 12px;
  display: grid; place-items: center; margin-bottom: 16px;
  background: linear-gradient(140deg, var(--blue), var(--blue-deep));
  color: var(--on-accent); box-shadow: 0 8px 22px -10px var(--blue);
}
.why-ic svg { width: 22px; height: 22px; }
.why-card h3 { font-size: 18px; color: var(--paper); margin-bottom: 8px; font-weight: 600; }
.why-card p { font-size: 14.5px; color: var(--txt-2); }
@media (max-width: 860px) { .why-cards { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 560px) { .why-cards { grid-template-columns: 1fr; } }

/* ============================================================
   USERS PAGE — WHO / WHERE
   ============================================================ */
.audience { display: grid; grid-template-columns: repeat(4, 1fr); gap: 16px; margin-top: 40px; }
.aud-card {
  position: relative; overflow: hidden;
  border: 1px solid var(--line-d); border-radius: var(--r);
  background: var(--navy-2); min-height: 230px;
  display: flex; flex-direction: column; justify-content: flex-end;
  padding: 24px 22px;
  transition: transform .35s ease, border-color .35s ease;
}
.aud-card:hover { transform: translateY(-6px); border-color: color-mix(in srgb, var(--blue) 50%, var(--line-d)); }
.aud-card .aud-figure {
  position: absolute; inset: 0; z-index: 0;
  background: radial-gradient(120% 100% at 50% 0, color-mix(in srgb, var(--blue) 20%, transparent), transparent 60%), var(--navy-2);
}
.aud-card .aud-figure img { width: 100%; height: 100%; object-fit: cover; opacity: .5; }
.aud-card::after { content: ""; position: absolute; inset: 0; z-index: 1; background: linear-gradient(180deg, transparent, rgba(var(--veil), .85)); }
.aud-num { position: relative; z-index: 2; font-family: var(--mono); font-size: 12px; color: var(--blue-soft); letter-spacing: .1em; margin-bottom: 10px; }
.aud-card h3 { position: relative; z-index: 2; font-size: 19px; color: var(--paper); font-weight: 600; }
.aud-card p { position: relative; z-index: 2; font-size: 13.5px; color: var(--txt-2); margin-top: 6px; }
@media (max-width: 860px) { .audience { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 480px) { .audience { grid-template-columns: 1fr; } }

.flow-arrow { display: grid; place-items: center; margin: 46px 0; color: var(--blue); }
.flow-arrow span {
  font-family: var(--mono); font-size: 12px; letter-spacing: .14em; text-transform: uppercase; color: var(--txt-3);
  margin-top: 10px;
}
.flow-arrow svg { width: 26px; height: 40px; }
.flow-arrow .down { animation: bob 2.4s ease-in-out infinite; }
@keyframes bob { 0%,100% { transform: translateY(0); } 50% { transform: translateY(7px); } }

/* ============================================================
   ABOUT PAGE
   ============================================================ */
.manifesto { max-width: 62ch; }
.manifesto p { color: var(--txt-2); font-size: clamp(16px, 1.6vw, 18px); margin-top: 18px; }
.manifesto p.lead { color: var(--txt); font-size: clamp(20px, 2.6vw, 28px); font-weight: 600; line-height: 1.4; }

.vm-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 20px; margin-top: 20px; }
.vm-card {
  border: 1px solid var(--line-d); border-radius: var(--r);
  background: var(--navy-2); padding: 34px 32px;
}
.vm-card .eyebrow { margin-bottom: 14px; }
.vm-card h3 { font-size: clamp(22px, 2.6vw, 30px); color: var(--paper); font-weight: 700; letter-spacing: -0.01em; margin-bottom: 14px; }
.vm-card p { color: var(--txt-2); font-size: 15.5px; }
@media (max-width: 760px) { .vm-grid { grid-template-columns: 1fr; } }

.values { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; margin-top: 40px; }
.value-card {
  border: 1px solid var(--line-d); border-radius: var(--r);
  background: var(--navy-2); padding: 30px 26px;
  position: relative; overflow: hidden;
  transition: transform .35s ease, border-color .35s ease;
}
.value-card:hover { transform: translateY(-6px); border-color: color-mix(in srgb, var(--blue) 50%, var(--line-d)); }
.value-card .v-num { font-family: var(--mono); font-size: 13px; color: var(--blue-soft); letter-spacing: .08em; }
.value-card h3 { font-size: 21px; color: var(--paper); margin: 12px 0 6px; font-weight: 700; letter-spacing: .02em; }
.value-card .v-lead { color: var(--txt); font-weight: 600; font-size: 16px; margin-bottom: 10px; }
.value-card p { color: var(--txt-2); font-size: 14.5px; }
.value-card::before {
  content: ""; position: absolute; top: -40px; right: -40px; width: 120px; height: 120px;
  border-radius: 50%; background: radial-gradient(circle, color-mix(in srgb, var(--blue) 18%, transparent), transparent 70%);
}
@media (max-width: 860px) { .values { grid-template-columns: 1fr; } }

.team { display: grid; grid-template-columns: repeat(4, 1fr); gap: 20px; margin-top: 40px; }
.team-card { text-align: center; }
.team-photo {
  width: 100%; max-width: 190px; aspect-ratio: 1; margin: 0 auto 16px;
  border-radius: 50%; overflow: hidden; position: relative;
  background: radial-gradient(120% 120% at 50% 15%, var(--navy-3), var(--navy-2));
  border: 1px solid var(--line-d);
  display: grid; place-items: center;
}
.team-photo img { width: 100%; height: 100%; object-fit: cover; }
.team-photo .ph-face { width: 46%; opacity: .5; }
.team-role { font-family: var(--mono); font-size: 11.5px; letter-spacing: .08em; text-transform: uppercase; color: var(--blue-soft); }
.team-name { font-size: 17px; color: var(--paper); font-weight: 600; margin-top: 4px; }
@media (max-width: 860px) { .team { grid-template-columns: repeat(2, 1fr); } }

/* ============================================================
   CONTACT PAGE
   ============================================================ */
.contact-split {
  display: grid; grid-template-columns: 0.9fr 1.1fr;
  gap: 0; margin-top: 20px;
  border: 1px solid var(--line-d); border-radius: 16px; overflow: hidden;
  background: var(--navy-2);
}
.contact-aside {
  position: relative; overflow: hidden;
  padding: clamp(36px, 5vw, 60px);
  display: flex; flex-direction: column; justify-content: space-between; gap: 40px;
  background:
    radial-gradient(120% 90% at 20% 10%, color-mix(in srgb, var(--blue) 22%, transparent), transparent 55%),
    linear-gradient(160deg, var(--navy-3), var(--navy));
}
.contact-aside .c-logo { width: 150px; }
.contact-aside h1 { font-size: clamp(28px, 4vw, 44px); color: var(--paper); font-weight: 700; letter-spacing: -0.02em; line-height: 1.08; }
.contact-aside p { color: var(--txt-2); margin-top: 16px; max-width: 40ch; }
.contact-aside .c-mail { margin-top: 22px; display: inline-flex; }
.contact-aside .c-mail a { color: var(--blue-soft); font-family: var(--mono); font-size: 14px; text-decoration: none; }
.contact-aside .c-orbit { position: absolute; inset: 0; z-index: 0; opacity: .5; }

.contact-form { padding: clamp(30px, 4vw, 52px); background: var(--navy-2); }
.cf-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 18px; }
.cf-field { display: flex; flex-direction: column; gap: 7px; }
.cf-field.full { grid-column: 1 / -1; }
.cf-field label { font-size: 13.5px; color: var(--txt-2); font-weight: 500; }
.cf-field label .req { color: var(--blue-soft); }
.cf-field input, .cf-field select, .cf-field textarea {
  appearance: none;
  background: var(--navy); color: var(--txt);
  border: 1px solid var(--line-d); border-radius: var(--r-sm);
  padding: 12px 14px; font: inherit; font-size: 15px;
  transition: border-color .2s ease, box-shadow .2s ease;
}
.cf-field select {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1l5 5 5-5' stroke='%238FA1B8' stroke-width='1.5' fill='none' stroke-linecap='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 14px center; padding-right: 36px;
}
.cf-field textarea { resize: vertical; min-height: 120px; }
.cf-field input:focus, .cf-field select:focus, .cf-field textarea:focus {
  outline: none; border-color: var(--blue);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--blue) 22%, transparent);
}
.cf-actions { display: flex; align-items: center; justify-content: space-between; gap: 16px; margin-top: 24px; flex-wrap: wrap; }
.cf-note { font-size: 12.5px; color: var(--txt-3); }
.cf-success {
  grid-column: 1 / -1; margin-top: 8px;
  color: var(--ok); font-size: 14px;
  border: 1px solid color-mix(in srgb, var(--ok) 40%, transparent);
  background: color-mix(in srgb, var(--ok) 10%, transparent);
  border-radius: var(--r-sm); padding: 12px 14px;
}
.cf-error {
  grid-column: 1 / -1; margin-top: 8px;
  color: var(--warn); font-size: 14px;
  border: 1px solid color-mix(in srgb, var(--warn) 40%, transparent);
  background: color-mix(in srgb, var(--warn) 10%, transparent);
  border-radius: var(--r-sm); padding: 12px 14px;
}
.cf-error a, .cf-success a { color: inherit; text-decoration: underline; }

/* Consentement RGPD : sans case cochee le service refuse le lead (400). */
.cf-consent { grid-column: 1 / -1; display: flex; gap: 10px; align-items: flex-start; }
.cf-consent input { margin-top: 3px; width: 16px; height: 16px; flex: none; accent-color: var(--blue); }
.cf-consent label { font-size: 12.5px; color: var(--txt-3); line-height: 1.5; }

/* Piege a robots. Surtout PAS `display:none` : les robots serieux ignorent les
   champs caches ainsi. On le sort de l'ecran tout en le laissant « visible »
   pour le DOM, et on le retire du parcours clavier + lecteurs d'ecran. */
.cf-hp {
  position: absolute; left: -9999px; top: auto;
  width: 1px; height: 1px; overflow: hidden;
}

/* Bouton en cours d'envoi */
.btn[aria-busy="true"] { opacity: .6; pointer-events: none; }

@media (max-width: 860px) { .contact-split { grid-template-columns: 1fr; } }
@media (max-width: 520px) { .cf-grid { grid-template-columns: 1fr; } }

/* ---------- Page de reservation (demo.html) ---------- */
.book-facts {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 14px;
  margin-top: clamp(18px, 3vw, 28px);
}
.book-fact {
  border: 1px solid var(--line-d); border-radius: var(--r-sm);
  background: var(--navy-2); padding: 16px 18px;
  display: flex; flex-direction: column; gap: 6px;
}
.book-fact-k {
  font-family: var(--mono); font-size: 12.5px; letter-spacing: .04em;
  text-transform: uppercase; color: var(--blue-soft);
}
.book-fact-v { font-size: 14px; color: var(--txt-2); line-height: 1.5; }

.book-embed {
  position: relative;
  /* 860 px, mesure et pas choisi au hasard. Cal.com dimensionne sa carte selon
     la largeur qu'on lui donne :
       cadre 1160 -> calendrier 1040 (marge 60)  | formulaire 760 (marge 200)
       cadre  860 -> calendrier  860 (marge  0)  | formulaire 660 (marge 100)
       cadre  720 -> bascule en disposition EMPILEE (mobile), a eviter
     A pleine largeur, le formulaire flottait dans 200 px de noir de chaque cote
     — c'est ce qui se lisait comme un defaut de centrage. A 860 le calendrier
     remplit le cadre exactement, et on garde de la marge avant le point de
     bascule mobile. */
  max-width: 860px; margin-inline: auto;
  border: 1px solid var(--line-d); border-radius: var(--r);
  /* Pas de fond ici : Cal.com dessine deja son propre panneau a l'interieur du
     cadre. En poser un second donnait un encadrement dans l'encadrement, avec
     deux noirs legerement differents — c'est ce qui trahissait le plus
     l'iframe. On ne garde que la bordure, qui raccroche le bloc a la charte. */
  overflow: hidden;
  /* Hauteur fixe : l'iframe est cross-origin, on ne peut pas mesurer son
     contenu depuis ici. 640 px cadre le mois sans laisser la grande bande
     vide qu'on avait a 720. */
  min-height: 640px;
}
/* Hauteur de depart seulement : js/pages.js la reajuste des que Cal.com
   annonce la sienne. La transition evite le a-coup au moment du recalage. */
.book-embed iframe { display: block; width: 100%; height: 640px; border: 0;
  transition: height .35s cubic-bezier(.2,.7,.3,1); }
.book-embed { transition: min-height .35s cubic-bezier(.2,.7,.3,1); }
@media (prefers-reduced-motion: reduce) {
  .book-embed, .book-embed iframe { transition: none; }
}
.book-embed-loading {
  position: absolute; inset: 0; display: grid; place-items: center;
  font-family: var(--mono); font-size: 13px; color: var(--txt-3);
}
/* Piege classique : `display: grid` ci-dessus l'emporte sur le display:none que
   le navigateur applique a [hidden]. Sans cette ligne, masquer l'element en JS
   ne fait rien du tout et le « Chargement… » reste par-dessus le calendrier. */
.book-embed-loading[hidden], .book-fallback[hidden], .book-alt[hidden] { display: none; }

.book-fallback {
  margin-top: 16px; font-size: 13.5px; line-height: 1.6; text-align: center;
  color: var(--warn);
  border: 1px solid color-mix(in srgb, var(--warn) 40%, transparent);
  background: color-mix(in srgb, var(--warn) 10%, transparent);
  border-radius: var(--r-sm); padding: 12px 14px;
}
.book-fallback a { color: inherit; text-decoration: underline; }

/* Ligne discrete toujours affichee : elle rend le lien direct et le formulaire
   accessibles meme quand le calendrier fonctionne parfaitement. */
.book-alt {
  margin-top: 14px; font-size: 13px; color: var(--txt-3);
  text-align: center; line-height: 1.6;
}

@media (max-width: 860px) { .book-facts { grid-template-columns: 1fr; } }
/* Sur mobile Cal.com empile le calendrier SOUS les details de l'evenement :
   il lui faut nettement plus de hauteur, sinon la liste des creneaux est
   coupee et l'iframe scrolle dans le scroll de la page. */
@media (max-width: 640px) {
  .book-embed, .book-embed iframe { min-height: 900px; height: 900px; }
}

/* ---------- Mobile nav drawer (all pages) ---------- */
@media (max-width: 960px) {
  .nav-toggle { display: flex; }
  .lang-toggle { margin-left: 12px; }
  .site-nav {
    position: fixed; inset: 76px 0 auto 0;
    display: flex; flex-direction: column; gap: 4px;
    background: color-mix(in srgb, var(--navy) 96%, transparent);
    backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px);
    border-bottom: 1px solid var(--line-d);
    padding: 16px var(--pad-x) 24px;
    transform: translateY(-12px); opacity: 0; pointer-events: none;
    transition: transform .28s ease, opacity .28s ease;
    z-index: 49;
  }
  .site-nav.open { transform: none; opacity: 1; pointer-events: auto; }
  .site-nav a { padding: 14px 12px; font-size: 16px; }
}
@media (max-width: 760px) {
  .header-cta { display: none; }
}

/* reduced motion additions */
@media (prefers-reduced-motion: reduce) {
  .mq-row.left, .mq-row.right { animation: none; }
  .flow-arrow .down { animation: none; }
  .aud-card, .why-card, .value-card, .fit-row, .mo-cell img, .shift-figure .shift-img { transition: none; }
}

/* Users page: 5-up "where" grid + role icons */
.audience-5 { grid-template-columns: repeat(5, 1fr); }
@media (max-width: 980px) { .audience-5 { grid-template-columns: repeat(3, 1fr); } }
@media (max-width: 620px) { .audience-5 { grid-template-columns: repeat(2, 1fr); } }
.aud-ic {
  position: relative; z-index: 2;
  width: 42px; height: 42px; border-radius: 11px; margin-bottom: auto;
  display: grid; place-items: center;
  background: color-mix(in srgb, var(--blue) 16%, transparent);
  border: 1px solid color-mix(in srgb, var(--blue) 40%, var(--line-d));
  color: var(--blue-soft);
}
.aud-ic svg { width: 22px; height: 22px; }
.aud-card { justify-content: space-between; gap: 14px; }

/* ============================================================
   ============  ROUND 2 — new visuals, animations, cards  ====
   ============================================================ */

/* ---------- Home hero (restored text + image, horizontal) ---------- */
.hero.hero-intro { padding-top: clamp(46px, 7vw, 84px); padding-bottom: clamp(20px, 3vw, 32px); }
.hero-figure {
  position: relative; border-radius: var(--r); overflow: hidden;
  border: 1px solid var(--line-d); background: var(--navy-2);
  isolation: isolate;
}
.hero-figure img { display: block; width: 100%; height: 100%; object-fit: cover; aspect-ratio: 16 / 11; }
.hero-figure .spot {
  position: absolute; inset: 0; pointer-events: none; z-index: 2; opacity: 0;
  transition: opacity .3s ease; mix-blend-mode: screen;
  background: radial-gradient(220px circle at var(--sx,50%) var(--sy,50%), color-mix(in srgb, var(--blue) 18%, transparent), transparent 62%);
}
.hero-figure:hover .spot { opacity: 1; }
.hero-figure .fig-tag {
  position: absolute; left: 14px; bottom: 12px; z-index: 3;
  font-family: var(--mono); font-size: 11px; letter-spacing: .06em; text-transform: uppercase;
  color: var(--txt); display: flex; align-items: center; gap: 7px;
}
.hero-figure .fig-tag::before { content:""; width:7px; height:7px; border-radius:50%; background:var(--blue); box-shadow:0 0 8px var(--blue); }

/* ---------- Mode card placeholders now hold images ---------- */
.mode-canvas.mode-img { padding: 0; border: 1px solid var(--line-d); overflow: hidden; height: 170px; }
.mode-canvas.mode-img img { width: 100%; height: 100%; object-fit: cover; display: block; transition: transform .5s cubic-bezier(.2,.7,.3,1); }
.mode:hover .mode-canvas.mode-img img { transform: scale(1.05); }

/* ---------- Compare table: continuous cascade illumination ---------- */
.compare li { transition: color .3s ease, background .3s ease, box-shadow .3s ease; border-radius: 6px; }
.compare li.lit {
  color: var(--paper);
  background: color-mix(in srgb, var(--blue) 16%, transparent);
  box-shadow: inset 2px 0 0 var(--blue-soft);
}
.compare-new li.lit { background: color-mix(in srgb, var(--blue) 22%, transparent); }

/* ---------- Accordion "+" sequential glow ---------- */
/* Le « + » s'allume au survol ou au focus clavier — jamais tout seul.
   `.glow` etait pose par une boucle JS supprimee ; on garde le selecteur au cas
   ou du markup l'utiliserait encore, mais plus rien ne l'ajoute. */
.acc-item:hover .acc-icon,
.acc-head:focus-visible .acc-icon,
.acc-icon.glow {
  background: var(--blue); border-color: var(--blue);
  box-shadow: 0 0 0 5px color-mix(in srgb, var(--blue) 14%, transparent);
}
.acc-item:hover .acc-icon::before, .acc-item:hover .acc-icon::after,
.acc-head:focus-visible .acc-icon::before, .acc-head:focus-visible .acc-icon::after,
.acc-icon.glow::before, .acc-icon.glow::after { background: var(--on-accent); }

/* ---------- Users: sector cards (image + expandable detail + animated +) ---------- */
.sectors-cards { display: grid; grid-template-columns: repeat(3, 1fr); gap: 18px; margin-top: 40px; align-items: start; }
@media (max-width: 900px) { .sectors-cards { grid-template-columns: 1fr 1fr; } }
@media (max-width: 620px) { .sectors-cards { grid-template-columns: 1fr; } }
.sector-card {
  position: relative; overflow: hidden;
  border: 1px solid var(--line-d); border-radius: var(--r); background: var(--navy-2);
  transition: border-color .35s ease;
}
.sector-card.open { border-color: color-mix(in srgb, var(--blue) 55%, var(--line-d)); }
.sector-media { position: relative; height: 170px; overflow: hidden; }
.sector-media img { width: 100%; height: 100%; object-fit: cover; display: block; transition: transform .6s cubic-bezier(.2,.7,.3,1); }
.sector-card:hover .sector-media img { transform: scale(1.05); }
.sector-media .ov { position: absolute; inset: 0; background: linear-gradient(180deg, transparent 35%, rgba(var(--media-veil), .88)); }
.sector-head {
  position: relative; z-index: 2;
  display: flex; align-items: center; justify-content: space-between; gap: 14px;
  margin-top: -46px; padding: 0 20px 4px;
}
.sector-head h3 { color: var(--on-media); font-size: 20px; font-weight: 700; }
.sector-toggle {
  flex: none; width: 40px; height: 40px; border-radius: 50%; cursor: pointer;
  border: 1px solid color-mix(in srgb, var(--blue) 55%, var(--line-d));
  background: color-mix(in srgb, var(--navy) 55%, transparent); position: relative;
  transition: background .3s ease, border-color .3s ease, box-shadow .3s ease;
}
/* Le halo ne part qu'au survol de la carte ou au focus clavier du bouton —
   avant, `plus-pulse` tournait en boucle sur les cinq cartes a la fois. */
.sector-card:hover .sector-toggle,
.sector-toggle:focus-visible {
  box-shadow: 0 0 0 7px color-mix(in srgb, var(--blue) 14%, transparent);
  border-color: var(--blue);
}
.sector-toggle::before, .sector-toggle::after {
  content: ""; position: absolute; top: 50%; left: 50%; width: 14px; height: 2px; border-radius: 2px;
  background: var(--blue-soft); transform: translate(-50%,-50%); transition: transform .3s ease, opacity .3s ease;
}
.sector-toggle::after { transform: translate(-50%,-50%) rotate(90deg); }
.sector-card.open .sector-toggle { background: var(--blue); border-color: var(--blue); }
.sector-card.open .sector-toggle::before, .sector-card.open .sector-toggle::after { background: var(--on-accent); }
.sector-card.open .sector-toggle::after { transform: translate(-50%,-50%) rotate(0); opacity: 0; }
.sector-body { overflow: hidden; max-height: 0; transition: max-height .45s cubic-bezier(.2,.7,.3,1); }
.sector-body-inner { padding: 8px 20px 22px; }
.sector-block + .sector-block { margin-top: 16px; }
.sector-block h4 {
  font-family: var(--mono); font-size: 11px; letter-spacing: .08em; text-transform: uppercase;
  color: var(--blue-soft); margin-bottom: 8px;
}
.sector-block ul { list-style: none; display: grid; gap: 6px; }
.sector-block li { position: relative; padding-left: 16px; color: var(--txt-2); font-size: 14px; }
.sector-block li::before { content: ""; position: absolute; left: 0; top: 9px; width: 5px; height: 5px; border-radius: 50%; background: var(--s-vig); }
.sector-block.enables li::before { background: var(--blue); }
@media (prefers-reduced-motion: reduce) { .sector-toggle { animation: none; } }

/* ---------- Users: "From observation to operational intelligence" apps ---------- */
.apps { display: grid; grid-template-columns: repeat(4, 1fr); gap: 16px; margin-top: 40px; }
@media (max-width: 1000px) { .apps { grid-template-columns: 1fr 1fr; } }
@media (max-width: 540px) { .apps { grid-template-columns: 1fr; } }
.app-card {
  position: relative; overflow: hidden; border: 1px solid var(--line-d);
  border-radius: var(--r); background: var(--navy-2);
  transition: transform .35s ease, border-color .35s ease;
}
.app-card:hover { border-color: color-mix(in srgb, var(--blue) 50%, var(--line-d)); }
.app-media { height: 150px; overflow: hidden; position: relative; }
.app-media img { width: 100%; height: 100%; object-fit: cover; display: block; transition: transform .6s cubic-bezier(.2,.7,.3,1); }
.app-card:hover .app-media img { transform: scale(1.05); }
.app-media.ph { display: grid; place-items: center; border-bottom: 1px dashed var(--line-d);
  background: linear-gradient(color-mix(in srgb, var(--navy-3) 60%, transparent), color-mix(in srgb, var(--navy-3) 15%, transparent)),
    repeating-linear-gradient(45deg, transparent 0 10px, color-mix(in srgb, var(--blue) 5%, transparent) 10px 11px); }
.app-media.ph .ph-note { font-family: var(--mono); font-size: 10.5px; letter-spacing: .08em; text-transform: uppercase; color: var(--txt-3); }
.app-num { font-family: var(--mono); font-size: 12px; color: var(--blue-soft); }
.app-body { padding: 22px 20px; }
.app-title { color: var(--blue-soft); font-size: 18px; font-weight: 700; margin: 8px 0 4px; }
.app-sub { color: var(--txt); font-weight: 600; font-size: 14.5px; margin-bottom: 8px; }
.app-desc { color: var(--txt-2); font-size: 14px; }

/* ---------- Contact: face animation in the aside blank space ---------- */
.contact-aside { justify-content: flex-start; }
.c-face { position: relative; flex: 1 1 auto; min-height: 260px; margin: 8px 0; }
.c-face canvas { position: absolute; inset: 0; width: 100%; height: 100%; }
@media (max-width: 860px) { .c-face { min-height: 220px; } }

/* ============================================================
   ============  ROUND 3 — hero recentred, cascades, popup ====
   ============================================================ */

/* ---------- Home hero: centred layout (Orasio-style) ---------- */
.hero-centered { text-align: center; padding-bottom: clamp(14px, 2vw, 24px); }
.hero-centered .hero-kicker { margin-left: auto; margin-right: auto; }
.hero-centered h1 { margin: 20px auto 0; max-width: 20ch; }
.hero-centered .hero-sub { margin: 22px auto 0; max-width: 60ch; }
.hero-video.hero-after { padding-top: clamp(10px, 2vw, 24px); }

/* ---------- Generic continuous cascade illumination (sectors, vm, values) ---------- */
.sectors-grid > span { transition: border-color .55s ease, box-shadow .55s ease, color .55s ease; }
.vm-card, .value-card { transition: border-color .55s ease, box-shadow .55s ease; }
.sectors-grid > span.lit, .vm-card.lit, .value-card.lit {
  border-color: color-mix(in srgb, var(--blue) 60%, var(--line-d));
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--blue) 42%, transparent),
              0 0 28px -6px color-mix(in srgb, var(--blue) 55%, transparent);
}
.sectors-grid > span.lit { color: var(--paper); background: color-mix(in srgb, var(--blue) 12%, var(--navy-2)); }

/* ---------- Stats: ensure mouse-overlay (glare) works ---------- */
.stat { position: relative; overflow: hidden; }

/* ---------- Users sector cards: equal height + content moved to popup ---------- */
.sectors-cards { align-items: stretch; }
.sector-card { display: flex; flex-direction: column; }
.sector-head { min-height: 58px; align-items: center; padding-bottom: 8px; }
.sector-body { display: none; }              /* details now shown in the popup */
/* (le pulse permanent a ete retire — voir .sector-card:hover .sector-toggle) */

/* ---------- Sector detail popup (reuses .modal) ---------- */
body.modal-open { overflow: hidden; }
.sector-modal .modal-panel { width: min(620px, 100%); }
.sm-media { height: 180px; overflow: hidden; border-radius: var(--r) var(--r) 0 0; position: relative; }
.sm-media img { width: 100%; height: 100%; object-fit: cover; display: block; }
.sm-media .ov { position: absolute; inset: 0; background: linear-gradient(180deg, transparent 40%, rgba(var(--media-veil), .9)); }
.sm-media h2 { position: absolute; left: 24px; bottom: 16px; z-index: 2; color: var(--on-media); font-size: clamp(22px,3vw,30px); margin: 0; }
.sm-body { padding: clamp(22px, 3vw, 32px); }
.sm-body .sector-block + .sector-block { margin-top: 18px; }
/* Retour client — « cliquer sur une carte ouvre la popup mais pas la page
   dediee ». users.html n'avait AUCUN lien vers les six pages secteur : les
   cartes n'etaient que des declencheurs de popup, et le contenu de la popup
   est justement ce que la page secteur reprend mot pour mot. Le lien ferme la
   boucle sans rien deplacer : il est ecrit dans .sector-body-inner, donc le
   `body.innerHTML = inner.innerHTML` de pages.js l'emporte dans la popup. */
.sector-more { margin-top: 20px; padding-top: 16px; border-top: 1px solid var(--line-d); }
.sector-more a {
  display: inline-flex; align-items: center; gap: 8px;
  color: var(--blue-soft); text-decoration: none;
  font-weight: 600; font-size: 15px;
}
.sector-more a::after { content: "→"; transition: transform .25s ease; }
.sector-more a:hover { color: var(--paper); }
.sector-more a:hover::after { transform: translateX(3px); }

/* ============================================================
   ============  ROUND 4 — hover effects + app visuals  =======
   ============================================================ */

/* ---------- Accordion: hover effect ---------- */
.acc-item { transition: border-color .3s ease, background .3s ease, transform .3s ease, box-shadow .3s ease; }
.acc-item:hover {
  border-color: color-mix(in srgb, var(--blue) 48%, var(--line-d));
  background: var(--navy-3);
  transform: translateY(-2px);
  box-shadow: 0 12px 30px -18px color-mix(in srgb, var(--blue) 60%, transparent);
}
.acc-item:hover .acc-head { color: var(--blue-soft); }
.acc-item:hover .acc-icon { border-color: color-mix(in srgb, var(--blue) 55%, var(--line-d)); box-shadow: 0 0 0 4px color-mix(in srgb, var(--blue) 12%, transparent); }

/* ---------- Sector popup: hover effects ---------- */
.sm-media img { transition: transform .55s cubic-bezier(.2,.7,.3,1); }
.sm-media:hover img { transform: scale(1.045); }
.sm-body .sector-block li { transition: color .25s ease, transform .25s ease; }
.sm-body .sector-block li:hover { color: var(--paper); transform: translateX(5px); }
.sm-body .sector-block li:hover::before { box-shadow: 0 0 9px currentColor; }

/* ============================================================
   ============  ASLAN ORB — capteur de leads (bas-droit)  ====
   ============================================================
   Markup injecte par js/site.js (section 19). Pas de HTML a editer
   dans les six pages : une seule source, un seul style.
   ============================================================ */

.orb-host {
  position: fixed;
  right: clamp(14px, 2.2vw, 28px);
  bottom: clamp(14px, 2.2vw, 28px);
  z-index: 90;                      /* sous les modales de secteur, au-dessus du reste */
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 12px;
  pointer-events: none;             /* seul ce qui est cliquable reprend la main */
}
.orb-host > * { pointer-events: auto; }

/* ---------- le lanceur : l'orbe constellation ---------- */
.orb-launch {
  position: relative;
  width: 66px; height: 66px;
  padding: 0;
  border: 1px solid color-mix(in srgb, var(--blue) 34%, var(--line-d));
  border-radius: 50%;
  background:
    radial-gradient(circle at 34% 28%, color-mix(in srgb, var(--blue) 22%, transparent), transparent 62%),
    color-mix(in srgb, var(--navy-2) 88%, transparent);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  box-shadow:
    0 14px 34px -14px rgba(var(--shadow), var(--shadow-a1)),
    0 0 0 0 color-mix(in srgb, var(--blue) 30%, transparent);
  cursor: pointer;
  transition: transform .34s cubic-bezier(.2,.7,.3,1),
              border-color .3s ease, box-shadow .34s ease;
}
.orb-launch:hover,
.orb-launch:focus-visible {
  transform: translateY(-3px) scale(1.06);
  border-color: color-mix(in srgb, var(--blue) 62%, var(--line-d));
  box-shadow:
    0 20px 44px -16px rgba(var(--shadow), var(--shadow-a2)),
    0 0 0 5px color-mix(in srgb, var(--blue) 12%, transparent);
}
.orb-launch:focus-visible { outline: 2px solid var(--blue-soft); outline-offset: 4px; }
/* Le canvas est VOLONTAIREMENT plus grand que l'orbe et centre dessus : pendant
   la salve les points s'echappent hors de la boule, et un canvas a la taille du
   bouton les trancherait net au bord. Pas de border-radius pour la meme raison.
   `pointer-events: none` : le survol et le clic doivent rester sur le bouton. */
.orb-canvas {
  position: absolute;
  left: 50%; top: 50%;
  transform: translate(-50%, -50%);
  width: 152px; height: 152px;
  pointer-events: none;
}

/* Halo qui respire. Retire lorsque le panneau est ouvert : a ce moment-la
   le visiteur lit, il n'a plus besoin qu'on l'appelle. */
.orb-launch-ring {
  position: absolute; inset: -1px;
  border-radius: 50%;
  border: 1px solid color-mix(in srgb, var(--blue) 42%, transparent);
  animation: orbHalo 3.6s ease-out infinite;
  pointer-events: none;
}
@keyframes orbHalo {
  0%   { transform: scale(1);    opacity: .55; }
  70%  { transform: scale(1.42); opacity: 0; }
  100% { transform: scale(1.42); opacity: 0; }
}
.orb-host.is-open .orb-launch-ring { animation: none; opacity: 0; }
.orb-host.is-open .orb-launch { transform: scale(.9); }

/* ---------- le panneau ---------- */
.orb-panel {
  position: relative;
  width: min(340px, calc(100vw - 32px));
  max-height: min(76vh, 620px);
  overflow-y: auto;
  overflow-x: hidden;   /* le piege a robots vit a left:-9999px */
  padding: 22px 20px 20px;
  border: 1px solid var(--line-d);
  border-radius: 14px;
  background:
    radial-gradient(120% 90% at 88% 0%, color-mix(in srgb, var(--blue) 11%, transparent), transparent 58%),
    color-mix(in srgb, var(--navy-2) 96%, transparent);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  box-shadow: 0 28px 64px -22px rgba(var(--shadow), var(--shadow-a3));
  animation: orbIn .3s cubic-bezier(.2,.7,.3,1) both;
}
@keyframes orbIn {
  from { opacity: 0; transform: translateY(10px) scale(.97); }
  to   { opacity: 1; transform: none; }
}
.orb-panel[hidden] { display: none; }

.orb-close {
  position: absolute; top: 10px; right: 10px;
  width: 28px; height: 28px;
  border: 1px solid var(--line-d);
  border-radius: 8px;
  background: transparent;
  cursor: pointer;
  transition: border-color .25s ease, background .25s ease;
}
.orb-close::before, .orb-close::after {
  content: ""; position: absolute; left: 8px; top: 13px;
  width: 11px; height: 1px; background: var(--txt-2);
}
.orb-close::before { transform: rotate(45deg); }
.orb-close::after  { transform: rotate(-45deg); }
.orb-close:hover { border-color: color-mix(in srgb, var(--blue) 50%, var(--line-d)); background: var(--navy-3); }
.orb-close:hover::before, .orb-close:hover::after { background: var(--paper); }

.orb-panel-head { padding-right: 26px; }
.orb-eyebrow {
  display: inline-flex; align-items: center; gap: 7px;
  font: 600 10px/1 var(--mono);
  letter-spacing: .18em; text-transform: uppercase;
  color: var(--blue-soft);
}
.orb-dot {
  width: 5px; height: 5px; border-radius: 50%;
  background: var(--blue);
  box-shadow: 0 0 8px var(--blue);
}
.orb-panel h3 {
  margin: 10px 0 6px;
  font-size: 19px; line-height: 1.25; font-weight: 600;
  color: var(--paper);
}
.orb-panel-head p {
  margin: 0;
  font-size: 13px; line-height: 1.55;
  color: var(--txt-2);
}

/* ---------- les tuiles d'action ---------- */
.orb-tiles { display: grid; gap: 8px; margin-top: 16px; }
.orb-tile {
  display: grid;
  grid-template-columns: 34px 1fr 14px;
  align-items: center; gap: 11px;
  padding: 11px 12px;
  border: 1px solid var(--line-d);
  border-radius: 10px;
  background: color-mix(in srgb, var(--navy-3) 62%, transparent);
  text-decoration: none;
  transition: border-color .25s ease, background .25s ease, transform .25s ease;
}
.orb-tile:hover {
  border-color: color-mix(in srgb, var(--blue) 52%, var(--line-d));
  background: var(--navy-3);
  transform: translateX(3px);
}
.orb-tile-ico {
  width: 34px; height: 34px;
  display: grid; place-items: center;
  border: 1px solid color-mix(in srgb, var(--blue) 28%, var(--line-d));
  border-radius: 9px;
  background: color-mix(in srgb, var(--blue) 10%, transparent);
}
.orb-tile:hover .orb-tile-ico {
  border-color: color-mix(in srgb, var(--blue) 58%, var(--line-d));
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--blue) 10%, transparent);
}
/* Icones en CSS pur — aucun fichier a charger pour deux glyphes. */
.orb-tile-ico::before {
  content: ""; display: block;
  width: 15px; height: 15px;
  background: var(--blue-soft);
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
  -webkit-mask-size: contain;      mask-size: contain;
  -webkit-mask-position: center;   mask-position: center;
}
[data-orb-icon="calendar"] .orb-tile-ico::before {
  -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round'%3E%3Crect x='3' y='5' width='18' height='16' rx='2'/%3E%3Cpath d='M3 10h18M8 3v4M16 3v4'/%3E%3C/svg%3E");
          mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round'%3E%3Crect x='3' y='5' width='18' height='16' rx='2'/%3E%3Cpath d='M3 10h18M8 3v4M16 3v4'/%3E%3C/svg%3E");
}
[data-orb-icon="linkedin"] .orb-tile-ico::before {
  -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23000'%3E%3Cpath d='M4.98 3.5a2.5 2.5 0 1 1 0 5 2.5 2.5 0 0 1 0-5zM3 9h4v12H3zM9 9h3.8v1.7h.05c.53-.95 1.83-1.95 3.77-1.95 4.03 0 4.78 2.5 4.78 5.76V21h-4v-5.6c0-1.34-.03-3.06-1.9-3.06-1.9 0-2.2 1.45-2.2 2.96V21H9z'/%3E%3C/svg%3E");
          mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23000'%3E%3Cpath d='M4.98 3.5a2.5 2.5 0 1 1 0 5 2.5 2.5 0 0 1 0-5zM3 9h4v12H3zM9 9h3.8v1.7h.05c.53-.95 1.83-1.95 3.77-1.95 4.03 0 4.78 2.5 4.78 5.76V21h-4v-5.6c0-1.34-.03-3.06-1.9-3.06-1.9 0-2.2 1.45-2.2 2.96V21H9z'/%3E%3C/svg%3E");
}
.orb-tile-txt { display: grid; gap: 2px; min-width: 0; }
.orb-tile-txt b { font-size: 13.5px; font-weight: 600; color: var(--txt); }
.orb-tile-txt i { font-style: normal; font-size: 11.5px; color: var(--txt-3); }
.orb-tile:hover .orb-tile-txt b { color: var(--paper); }
.orb-tile-arrow {
  width: 14px; height: 1px;
  background: var(--txt-3);
  position: relative;
  transition: background .25s ease, transform .25s ease;
}
.orb-tile-arrow::after {
  content: ""; position: absolute; right: 0; top: -3px;
  width: 6px; height: 6px;
  border-top: 1px solid currentColor; border-right: 1px solid currentColor;
  color: var(--txt-3);
  transform: rotate(45deg);
  transition: color .25s ease;
}
.orb-tile:hover .orb-tile-arrow { background: var(--blue-soft); transform: translateX(3px); }
.orb-tile:hover .orb-tile-arrow::after { color: var(--blue-soft); }

/* ---------- le formulaire e-mail ---------- */
.orb-form {
  margin-top: 16px;
  padding-top: 15px;
  border-top: 1px solid var(--line-d);
}
.orb-lbl {
  display: block;
  margin-bottom: 8px;
  font: 600 10px/1 var(--mono);
  letter-spacing: .14em; text-transform: uppercase;
  color: var(--txt-3);
}
.orb-row { display: grid; grid-template-columns: 1fr 40px; gap: 7px; }
.orb-row input {
  min-width: 0;
  padding: 10px 12px;
  border: 1px solid var(--line-d);
  border-radius: 9px;
  background: color-mix(in srgb, var(--navy) 70%, transparent);
  color: var(--txt);
  font: 400 13.5px/1.2 var(--sans);
  transition: border-color .25s ease, box-shadow .25s ease;
}
.orb-row input::placeholder { color: var(--txt-3); }
.orb-row input:focus {
  outline: none;
  border-color: color-mix(in srgb, var(--blue) 58%, var(--line-d));
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--blue) 13%, transparent);
}
.orb-send {
  position: relative;
  border: 1px solid transparent;
  border-radius: 9px;
  background: var(--blue);
  cursor: pointer;
  transition: background .25s ease, transform .2s ease;
}
.orb-send::before {
  content: ""; position: absolute; inset: 0; margin: auto;
  width: 15px; height: 15px;
  background: var(--on-accent);
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 12h13M12 5l7 7-7 7'/%3E%3C/svg%3E") center/contain no-repeat;
          mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 12h13M12 5l7 7-7 7'/%3E%3C/svg%3E") center/contain no-repeat;
}
.orb-send:hover { background: var(--blue-deep); transform: translateX(2px); }
.orb-send[aria-busy="true"] { opacity: .55; pointer-events: none; }

.orb-consent { display: grid; grid-template-columns: 15px 1fr; align-items: start; gap: 8px; margin-top: 11px; }
.orb-consent input { margin: 2px 0 0; accent-color: var(--blue); }
.orb-consent label { font-size: 10.5px; line-height: 1.5; color: var(--txt-3); }

.orb-msg { margin: 11px 0 0; font-size: 12px; line-height: 1.5; }
.orb-msg[hidden] { display: none; }
.orb-ok { color: var(--ok); }
.orb-ko { color: var(--warn); }

/* ---------- mobile ---------- */
@media (max-width: 560px) {
  .orb-panel { width: calc(100vw - 28px); }
  .orb-launch { width: 56px; height: 56px; }
  .orb-canvas { width: 129px; height: 129px; }
}

/* ---------- mouvement reduit ---------- */
@media (prefers-reduced-motion: reduce) {
  .orb-launch-ring { animation: none; opacity: .3; }
  .orb-panel { animation: none; }
  .orb-launch, .orb-tile, .orb-tile-arrow, .orb-send { transition: none; }
}

/* =============================================================================
   2026-08-27 — Retours client (remarque-aslan-website.json) + audit SEO.
   Chaque bloc porte le numero d'annotation qui l'a motive.
   ============================================================================= */

/* ---------------------------------------------------------------- ann_06 / ann_10
   L'anneau de la bande CTA devient une cible cliquable vers /contact.
   Le point visible fait 14 px — bien en dessous des 24 px minimum d'une cible
   tactile. On elargit donc la zone de clic a 48 px avec un pseudo-element,
   sans toucher au dessin. */
.beacon-link {
  display: block;
  text-decoration: none;
  cursor: pointer;
  border-radius: 50%;
}
.beacon-link::before {
  content: "";
  position: absolute;
  left: 50%; top: 50%;
  width: 48px; height: 48px;
  transform: translate(-50%, -50%);
  border-radius: 50%;
}
.beacon-link:hover .core,
.beacon-link:focus-visible .core {
  box-shadow: 0 0 18px var(--blue), 0 0 34px color-mix(in srgb, var(--blue) 45%, transparent);
}
.beacon-link:hover .ring { border-color: var(--blue-soft); }
.beacon-link:focus-visible { outline: 2px solid var(--blue-soft); outline-offset: 14px; }

/* ---------------------------------------------------------------- ann_11
   Lien LinkedIn sur la photo d'un membre de l'equipe. Le badge est visible en
   permanence mais discret : cache jusqu'au survol, personne ne devinerait que
   la photo est cliquable. */
/* `height: 100%` ne suffisait pas : `.team-photo` est une grille en
   `place-items: center`, donc son enfant n'est PAS etire, et un pourcentage de
   hauteur sur une piste dimensionnee par son contenu est indefini — il retombe
   sur `auto`, c'est-a-dire sur la taille de l'IMAGE. Mesure du 2026-08-31 :
   `.team-li` faisait 188x188 sur un portrait et 188x195,6 sur l'autre, pour la
   meme photo de 190 px. Le badge, pose en pourcentage de CETTE boite, tombait
   donc 5,6 px trop bas sur le second et sortait du disque — 97,7 px pour un
   rayon de 95, a toutes les largeurs, dans les deux langues.
   `inset: 0` sur un parent `position: relative` donne une boite DEFINIE dans les
   deux axes, identique a la photo : le repere du badge redevient celui du
   disque qui le decoupe. C'est exactement la regle de D-029, qu'on avait
   appliquee au badge sans verifier la boite qui lui servait de reference. */
.team-li { display: block; position: absolute; inset: 0; }
/* Retour client (batch_ry82g0, ann_03) : « the linkedin logo is not visible ».
   Le badge etait pose a 8 px du coin bas-droit de `.team-photo` — or cette boite
   est un CERCLE (`border-radius: 50%` + `overflow: hidden`) : le coin d'un carre
   est entierement HORS du disque inscrit, la pastille etait donc decoupee, a
   100 %, sur les quatre photos. Elle rentre a 15 % des bords : sur un disque, le
   point a 45 degres est a 50 % + 35,4 %, soit 85,4 % — a 15 % la pastille est
   dedans avec une marge, quelle que soit la taille de la photo (elle est fluide,
   d'ou les pourcentages et non des pixels).

   2026-08-31 — ce raisonnement placait le CENTRE du badge ; ce qui est decoupe,
   c'est son COIN. Pour une boite de cote S et un retrait p, le coin le plus
   eloigne est a S(1/2 - p)V2 du centre, qu'il faut garder sous R = S/2 : p doit
   valoir au moins 14,64 %. A 15 % il restait 1 % du rayon, soit 0,95 px sur une
   photo de 190 — autant dire rien, et le badge a ete resignale trois fois.
   A 18 % le coin tombe a 90,5 % du rayon : 9 px de blanc sur 190. */
.team-li-badge {
  position: absolute;
  right: 18%; bottom: 18%;
  width: 26px; height: 26px;
  display: grid; place-items: center;
  border-radius: 6px;
  background: color-mix(in srgb, var(--navy) 78%, transparent);
  border: 1px solid var(--line-d);
  color: var(--blue-soft);
  transition: background .25s ease, color .25s ease, border-color .25s ease;
}
.team-li-badge svg { width: 14px; height: 14px; fill: currentColor; }
.team-li:hover .team-li-badge,
.team-li:focus-visible .team-li-badge {
  background: var(--blue);
  border-color: var(--blue);
  color: var(--paper);
}
.team-li:focus-visible { outline: 2px solid var(--blue-soft); outline-offset: 3px; }

/* ---------------------------------------------------------------- ann_07
   Annotation posee sur une image. La position est calculee en pixels par
   js/pages.js (section 10) : elle depend du recadrage `cover`, pas du
   conteneur. Tant qu'elle n'est pas calculee, le cadre reste invisible —
   sinon il apparaitrait une fraction de seconde en haut a gauche. */
.mo-cell { position: relative; }
.annot {
  position: absolute;
  display: block;
  opacity: 0;
  pointer-events: none;
  z-index: 2;
  transition: opacity .4s ease;
}
.annot.placed { opacity: 1; }
.annot-box {
  position: absolute;
  inset: 0;
  border: 1.5px solid var(--warn);
  border-radius: 3px;
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--navy) 55%, transparent),
              0 0 16px color-mix(in srgb, var(--warn) 45%, transparent);
}
.annot-box::before, .annot-box::after {
  content: "";
  position: absolute;
  width: 7px; height: 7px;
  border: 1.5px solid var(--warn);
}
.annot-box::before { left: -1.5px; top: -1.5px; border-right: 0; border-bottom: 0; }
.annot-box::after { right: -1.5px; bottom: -1.5px; border-left: 0; border-top: 0; }
.annot-tag {
  position: absolute;
  left: 50%;
  bottom: calc(100% + 8px);
  transform: translateX(-50%);
  display: grid;
  gap: 1px;
  white-space: nowrap;
  padding: 6px 9px;
  border-radius: var(--r-sm);
  background: color-mix(in srgb, var(--navy) 88%, transparent);
  border: 1px solid color-mix(in srgb, var(--warn) 45%, var(--line-d));
  font-family: var(--mono);
  font-size: 10px;
  line-height: 1.35;
  letter-spacing: .04em;
  color: var(--txt-2);
}
.annot-tag b { color: var(--warn); font-weight: 600; text-transform: uppercase; letter-spacing: .08em; }
@media (max-width: 720px) { .annot-tag { display: none; } }

/* ---------------------------------------------------------------- ann_02
   « Le changement » : reconstruction du visuel en HTML/CSS/SVG.
   Voir le commentaire dans src/index.html — ce qui etait une image de 40 Ko par
   langue est devenu du texte lisible par un moteur de recherche. */
.shift-diagram {
  /* .shift centre tout son contenu : le diagramme, lui, se lit de gauche a
     droite comme une frise. */
  text-align: left;
  display: grid;
  /* Deux rangees : les intitules, puis les cartes. La fleche traverse les
     deux, sinon elle se retrouvait centree sur les cartes seules et pointait
     trop bas. */
  grid-template-columns: 1fr auto 1fr;
  grid-template-rows: auto 1fr;
  align-items: stretch;
  column-gap: clamp(10px, 1.6vw, 22px);
  row-gap: clamp(8px, 1.1vw, 14px);
  border: 0;
  background: none;
  padding: 0;
}
.sd-kicker-today { grid-column: 1; grid-row: 1; }
.sd-kicker-aslan { grid-column: 3; grid-row: 1; }
.sd-today { grid-column: 1; grid-row: 2; }
.sd-shift { grid-column: 2; grid-row: 1 / span 2; }
.sd-aslan { grid-column: 3; grid-row: 2; }
.sd-panel {
  position: relative;
  display: flex;
  flex-direction: column;
  padding: clamp(18px, 2.2vw, 30px);
  border: 1px solid var(--line-d);
  border-radius: 14px;
  background: linear-gradient(160deg,
              color-mix(in srgb, var(--navy-2) 92%, transparent),
              color-mix(in srgb, var(--navy) 92%, transparent));
  overflow: hidden;
}
.sd-aslan {
  border-color: color-mix(in srgb, var(--blue) 34%, var(--line-d));
  background: linear-gradient(160deg,
              color-mix(in srgb, var(--blue) 7%, var(--navy-2)),
              color-mix(in srgb, var(--navy) 94%, transparent));
}
/* Retour client — « rendre "Sans ASLAN" et "Avec ASLAN" plus visibles ». Les
   sur-titres etaient du mono 11 px en --txt-3, la couleur la plus sourde de la
   palette : ils se lisaient comme une legende technique alors qu'ils portent
   l'opposition sur laquelle repose toute la figure. Ils passent a 16 px, en
   demi-gras, blanc a gauche et bleu clair a droite. --blue-soft est conserve
   plutot que --blue : sur le fond marine c'est LUI le plus contraste. */
.sd-kicker {
  font-family: var(--mono);
  font-size: 16px;
  font-weight: 600;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--paper);
  margin: 0 0 6px;
  padding-left: 2px;
}
.sd-kicker-on { color: var(--blue-soft); }

/* --- la frise --- */
.sd-plot { position: relative; flex: 1; min-height: clamp(120px, 15vw, 168px); }
.sd-op {
  font-size: clamp(11px, 1.05vw, 13px);
  font-weight: 700;
  line-height: 1.25;
  text-transform: uppercase;
  letter-spacing: .04em;
  color: var(--txt);
  margin-bottom: 10px;
}
.sd-flow {
  display: flex;
  align-items: center;
  gap: 0;
  position: relative;
  z-index: 2;
  margin-top: 4px;
}
.sd-seg { flex: 1; height: 2px; border-radius: 2px; }
.sd-seg-short { flex: 0 0 clamp(14px, 2vw, 28px); }
.sd-seg-grey { background: linear-gradient(90deg, var(--txt-3), color-mix(in srgb, var(--txt-3) 40%, transparent)); }
.sd-seg-blue { background: linear-gradient(90deg, var(--blue-deep), var(--blue)); }
.sd-seg-dim { background: color-mix(in srgb, var(--txt-3) 45%, transparent); }

.sd-mark { position: relative; flex: none; display: grid; place-items: center; }
.sd-mark-incident svg { width: 17px; height: 17px; fill: var(--crit); display: block; }
.sd-mark-drift, .sd-mark-act {
  width: 11px; height: 11px;
  border-radius: 50%;
  background: var(--blue-soft);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--blue) 26%, transparent);
}
.sd-mark-act { background: var(--ok); box-shadow: 0 0 0 3px color-mix(in srgb, var(--ok) 26%, transparent); }
.sd-mark-lab {
  position: absolute;
  top: calc(100% + 5px);
  left: 50%;
  transform: translateX(-50%);
  font-family: var(--mono);
  font-size: 9.5px;
  letter-spacing: .1em;
  text-transform: uppercase;
  white-space: nowrap;
  color: var(--crit);
}
.sd-lab-up { top: auto; bottom: calc(100% + 5px); color: var(--blue-soft); }
.sd-lab-down { color: var(--ok); text-align: center; white-space: normal; width: 9em; }
.sd-out {
  flex: none;
  font-family: var(--mono);
  font-size: 10.5px;
  letter-spacing: .08em;
  text-transform: uppercase;
  padding-left: 7px;
}
.sd-out-fail { color: var(--crit); }
.sd-out-dim { color: var(--txt-3); text-decoration: line-through; text-decoration-color: color-mix(in srgb, var(--ok) 70%, transparent); }

/* --- encadre d'etat (ann_02) ------------------------------------------------
   C'etait une simple pastille ; le visuel d'origine montre un BLOC avec ses
   releves. La difference n'est pas decorative : a gauche les courbes disent
   qu'on regarde des donnees deja perimees, a droite les pictogrammes disent
   que le systeme se surveille en continu. */
.sd-status {
  position: relative;
  z-index: 2;
  /* L'etiquette « intervention anticipee » descend sur deux lignes sous la
     frise : sans cette marge l'encadre lui passe dessus. */
  margin-top: clamp(44px, 5.5vw, 64px);
  display: inline-grid;
  gap: 7px;
  padding: 8px 10px;
  border-radius: var(--r-sm);
  max-width: 100%;
}
.sd-status-head {
  display: flex;
  align-items: center;
  gap: 7px;
  margin: 0;
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: .09em;
  text-transform: uppercase;
  line-height: 1.2;
}
.sd-status-ico { width: 12px; height: 12px; flex: none; }
.sd-badge-dot { width: 6px; height: 6px; border-radius: 50%; flex: none; }
.sd-tiles { display: flex; gap: 5px; }
.sd-tile {
  display: grid;
  place-items: center;
  padding: 4px 6px;
  border-radius: 4px;
  border: 1px solid currentColor;
  /* Les vignettes sont du DECOR chiffre : elles doivent se lire comme un
     releve, pas concurrencer l'en-tete. */
  opacity: .5;
}
.sd-tile svg { display: block; height: 14px; width: auto; }
.sd-status-alert {
  color: var(--crit);
  border: 1px solid color-mix(in srgb, var(--crit) 45%, transparent);
  background: color-mix(in srgb, var(--crit) 12%, transparent);
}
.sd-status-ok {
  color: var(--ok);
  border: 1px solid color-mix(in srgb, var(--ok) 42%, transparent);
  background: color-mix(in srgb, var(--ok) 10%, transparent);
}
.sd-status-ok .sd-badge-dot { background: var(--ok); }

/* --- les deux puces qui encadrent la derive (ann_02) --- */
.sd-watch { position: relative; flex: 1; display: flex; align-items: center; }
.sd-chip {
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
  padding: 2px 6px;
  border-radius: 3px;
  border: 1px dashed color-mix(in srgb, var(--blue) 60%, transparent);
  background: color-mix(in srgb, var(--navy) 85%, transparent);
  font-family: var(--mono);
  font-size: 8.5px;
  letter-spacing: .1em;
  line-height: 1.4;
  color: var(--blue-soft);
}
/* Le trait pointille qui relie la puce a la frise. */
.sd-chip::after {
  content: "";
  position: absolute;
  left: 50%;
  width: 0;
  border-left: 1px dashed color-mix(in srgb, var(--blue) 50%, transparent);
  height: 7px;
}
.sd-chip-up { bottom: calc(100% + 9px); }
.sd-chip-up::after { top: 100%; }
.sd-chip-down { top: calc(100% + 9px); }
.sd-chip-down::after { bottom: 100%; }
@media (max-width: 560px) { .sd-chip { display: none; } }

/* --- decor : la ligne de production, en trace --- */
.sd-scene {
  position: absolute;
  right: -6%;
  bottom: -6%;
  width: 58%;
  max-width: 260px;
  opacity: .3;
  pointer-events: none;
  z-index: 1;
}
.sd-scene-line { stroke: var(--txt-3); stroke-width: 1.4; }
.sd-today .sd-scene-debris { fill: color-mix(in srgb, var(--crit) 55%, transparent); }
.sd-aslan .sd-scene-line { stroke: var(--blue-soft); }
.sd-aslan .sd-scene-ok { stroke: var(--ok); stroke-width: 1.6; fill: none; }
.sd-aslan .sd-scene { opacity: .3; }

.sd-claim {
  position: relative;
  z-index: 2;
  margin-top: clamp(16px, 2.4vw, 26px);
  font-size: clamp(17px, 2.05vw, 27px);
  font-weight: 700;
  line-height: 1.24;
  letter-spacing: -0.01em;
  color: var(--paper);
  text-wrap: balance;
}
.sd-claim b { font-weight: 700; }
/* `.hl` n'existait que sous .shift-tagline — la seconde phrase ressortait en
   blanc au lieu du bleu de la maquette. */
.sd-claim .hl { color: var(--blue-soft); }
.sd-today .sd-claim b { color: var(--txt); }

/* --- la fleche centrale --- */
.sd-shift {
  position: relative;
  align-self: center;
  display: grid;
  place-items: center;
  width: clamp(74px, 9vw, 118px);
}
.sd-arrow { width: 100%; height: auto; display: block; }
.sd-mark-logo {
  position: absolute;
  width: 58%;
  height: auto;
  filter: brightness(0) saturate(100%) invert(72%) sepia(24%) saturate(1400%) hue-rotate(178deg) brightness(103%);
}

@media (max-width: 860px) {
  /* Une seule colonne : on rend leur place aux elements, sinon les regles
     `grid-column` du desktop les laisseraient empiles sur la colonne 1.
     Il faut AUSSI reordonner : dans le DOM les deux intitules se suivent (ils
     coiffent les deux colonnes du desktop), donc en pile ils se retrouvaient
     tous les deux en tete, l'un sur l'autre, avant la premiere carte. */
  .shift-diagram { grid-template-columns: 1fr; grid-template-rows: none; }
  .sd-kicker-today, .sd-kicker-aslan, .sd-today, .sd-shift, .sd-aslan {
    grid-column: auto; grid-row: auto;
  }
  .sd-kicker-today { order: 1; }
  .sd-today        { order: 2; }
  .sd-shift        { order: 3; }
  .sd-kicker-aslan { order: 4; margin-top: 4px; }
  .sd-aslan        { order: 5; }
  /* En colonne, la fleche pointe vers le bas — mais c'est la FLECHE qui pivote,
     pas le conteneur : faire tourner le conteneur mettait le logo ASLAN a la
     verticale, illisible. */
  .sd-shift { width: clamp(56px, 16vw, 84px); margin: -6px auto; }
  .sd-arrow { transform: rotate(90deg); }
  .sd-scene { width: 46%; opacity: .22; }
}

/* ---------------------------------------------------------------- ann_08
   Visuel de deploiement. Il a d'abord ete un schema a libelles (ann_09), qui
   repetait mot pour mot le panneau d'a cote ; il redevient ce qu'il etait a
   l'origine — un point central relie a des appareils, sans texte. Le propos
   est porte par le panneau voisin, pas par l'image. */
.fit-hub {
  position: relative;
  display: grid;
  place-items: center;
  min-height: 320px;
  padding: clamp(18px, 2.6vw, 30px);
  background: linear-gradient(150deg,
              color-mix(in srgb, var(--blue) 9%, var(--navy-2)),
              var(--navy));
}
.fh-svg {
  width: 100%;
  max-width: 420px;
  height: auto;
  display: block;
  color: color-mix(in srgb, var(--blue-soft) 62%, transparent);
}
.fh-wire { opacity: .55; }
.fh-node { opacity: .8; }
.fh-ico { color: var(--paper); opacity: .9; }
/* Le halo est ce qui fait du point central un emetteur et non une pastille
   de plus : sans lui les cinq cercles se valent. */
.fh-core-halo { fill: color-mix(in srgb, var(--blue) 22%, transparent); }
.fh-core { fill: var(--paper); }
.fh-core-dot { fill: var(--blue); }
/* Le nom de la marque reste du TEXTE, pas un trace — mais du texte SVG, place
   dans le repere du viewBox.
   Retour client : « des elements se chevauchent ». C'etait vrai et mesurable.
   Le mot etait un <p> pose en absolu sur le schema, dimensionne en `vw` : le
   SVG, lui, fait min(100%, 420px) de sa colonne. Sous ~1024 px le schema
   retrecit (312 px de large a 390 px de fenetre) pendant que le mot, indexe
   sur la fenetre, ne bougeait presque pas — a 24 px pour un schema a 74 % de
   sa taille, il debordait sur le fil qui monte vers la camera en haut a
   droite. L'ancien commentaire affirmait « il suit » : il ne suivait pas.
   En unites du viewBox, il suit vraiment, a toutes les largeurs. */
.fh-word {
  font-size: 38px;          /* unites du viewBox, pas des pixels d'ecran */
  font-weight: 700;
  letter-spacing: .04em;
  fill: var(--paper);
}
@media (max-width: 620px) {
  .fit-hub { min-height: 250px; }
}

/* ---------------------------------------------------------------- ann_04
   Pages secteur. Le gabarit est src/_sector.html, le contenu src/_sectors.mjs. */
.crumbs {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  font-family: var(--mono); font-size: 11px; letter-spacing: .06em;
  color: var(--txt-3); margin-bottom: 20px;
}
.crumbs a { color: var(--txt-3); text-decoration: none; }
.crumbs a:hover { color: var(--blue-soft); }
.crumbs .crumb-current { color: var(--txt-2); }

.sector-hero { text-align: left; }
.sector-hero .eyebrow { justify-content: flex-start; }
.sector-hero h1 { margin-inline: 0; max-width: 20ch; }
.sector-hero .lede { margin: 22px 0 0; max-width: 58ch; }
.sector-hero .hero-actions { justify-content: flex-start; margin-top: 28px; }

.sector-split { display: grid; grid-template-columns: 1.05fr 1fr; gap: clamp(20px, 3vw, 42px); align-items: center; }
@media (max-width: 860px) { .sector-split { grid-template-columns: 1fr; } }
.sector-shot {
  position: relative; overflow: hidden; border-radius: var(--r);
  border: 1px solid var(--line-d); isolation: isolate; aspect-ratio: 16 / 10;
}
.sector-shot img { width: 100%; height: 100%; object-fit: cover; display: block; }
.sector-shot .ov {
  position: absolute; inset: 0;
  background: linear-gradient(200deg, transparent 35%, rgba(var(--media-veil), .72));
}
.sector-copy h2 { font-size: clamp(19px, 2.1vw, 27px); line-height: 1.3; margin-top: 8px; }
.sector-proof {
  margin-top: 18px; padding-left: 14px;
  border-left: 2px solid color-mix(in srgb, var(--blue) 55%, transparent);
  color: var(--txt-2); font-size: 14px; line-height: 1.6;
}
.sector-cols { display: grid; grid-template-columns: repeat(3, 1fr); gap: 18px; margin-top: 36px; }
@media (max-width: 900px) { .sector-cols { grid-template-columns: 1fr; } }
.sector-cols .sector-block {
  margin-top: 0;
  padding: 22px 20px;
  border: 1px solid var(--line-d);
  border-radius: var(--r);
  background: var(--navy-2);
}
.sector-cols .sector-block.enables { border-color: color-mix(in srgb, var(--blue) 34%, var(--line-d)); }
.sector-cols .sector-block h3 {
  font-family: var(--mono); font-size: 11px; letter-spacing: .08em; text-transform: uppercase;
  color: var(--blue-soft); margin-bottom: 12px; font-weight: 500;
}
.seg-tiles-other { margin-top: 26px; }

/* SD:BEGIN studio — genere par studio/emit.mjs, ne pas editer a la main */
/* Variantes retenues : scene=scenarios · connector=passerelle-dense · frame=verre · timeline=mixte · claim=actuel · ambient=aucun */
/* Scène industrielle — Les quatre scénarios (rotation) */
/* kit · poste · La console */
.shift-diagram .iso-desk-top .fc-top { fill: color-mix(in srgb, var(--txt-2) 40%, transparent); }
/* kit · poste · L'écran */
.shift-diagram .iso-scr-glass { fill: color-mix(in srgb, var(--deep) 74%, transparent);
  stroke: color-mix(in srgb, var(--txt-3) 45%, transparent); stroke-width: .5; }
.shift-diagram .iso-scr-trace { fill: none; stroke-width: 1.15; stroke-linecap: round; stroke-linejoin: round; }
.shift-diagram .iso-scr-foot { stroke: color-mix(in srgb, var(--txt-3) 50%, transparent); stroke-width: .9; }
.shift-diagram .sd-today .iso-scr-trace { stroke: var(--crit); }
.shift-diagram .sd-today .iso-scr-glass { stroke: color-mix(in srgb, var(--crit) 45%, transparent); }
.shift-diagram .sd-aslan .iso-scr-trace { stroke: var(--blue-soft); }
.shift-diagram .sd-aslan .iso-scr-glass { stroke: color-mix(in srgb, var(--blue-soft) 40%, transparent); }
/* kit · poste · Le siège */
.shift-diagram .iso-chair-seat .fc-top { fill: color-mix(in srgb, var(--txt-3) 40%, transparent); }
.shift-diagram .iso-chair-post { stroke: color-mix(in srgb, var(--txt-3) 55%, transparent); stroke-width: 1; }
/* kit · poste · La baie technique */
.shift-diagram .iso-rack-body .fc-top { fill: color-mix(in srgb, var(--txt-2) 24%, transparent); }
.shift-diagram .iso-rack-led { fill: color-mix(in srgb, var(--txt-2) 60%, transparent); }
.shift-diagram .sd-today .iso-rack-led { fill: color-mix(in srgb, var(--crit) 70%, transparent); }
.shift-diagram .sd-aslan .iso-rack-led { fill: color-mix(in srgb, var(--blue-soft) 60%, transparent); }
/* kit · humain · Opérateur assis */
.shift-diagram .iso-worker { fill: var(--txt-2); color: var(--txt-2); }
.shift-diagram .sd-today .iso-worker-down { fill: var(--crit); color: var(--crit); }
.shift-diagram .sd-aslan .iso-worker { fill: var(--blue-soft); color: var(--blue-soft); }
/* kit · capteur · La webcam */
.shift-diagram .iso-cam-head { fill: color-mix(in srgb, var(--txt-2) 55%, transparent); }
.shift-diagram .iso-cam-lens { fill: var(--txt-2); }
.shift-diagram .sd-aslan .iso-cam-head { fill: color-mix(in srgb, var(--blue-soft) 55%, transparent); }
.shift-diagram .sd-aslan .iso-cam-lens { fill: var(--blue-soft); }
/* kit · capteur · Le gyrophare */
.shift-diagram .iso-beacon-post { stroke: color-mix(in srgb, var(--txt-3) 60%, transparent); stroke-width: 1; }
.shift-diagram .sd-today .iso-beacon-lamp { fill: var(--alarm); }
.shift-diagram .sd-today .iso-beacon-halo { fill: color-mix(in srgb, var(--crit) 58%, transparent);
  filter: blur(.8px); }
.shift-diagram .sd-aslan .iso-beacon-lamp { fill: var(--blue-soft); }
.shift-diagram .sd-aslan .iso-beacon-halo { fill: color-mix(in srgb, var(--blue-soft) 22%, transparent); filter: blur(.8px); }

/* Le gyrophare bat. Un SEUL objet bouge, et c'est celui qui alerte : deux
   animations concurrentes dans un decor a 78 % d'opacite se lisent comme un
   bug, pas comme une alarme. */
.shift-diagram .sd-today .iso-beacon { animation: sd-beacon 1.6s steps(1, end) infinite; }
@keyframes sd-beacon { 0%, 55% { opacity: 1; } 56%, 100% { opacity: .32; } }
/* kit · capteur · Le cône de champ de vue */
.shift-diagram .iso-gaze { fill: color-mix(in srgb, var(--txt-3) 13%, transparent); }
.shift-diagram .sd-aslan .iso-gaze { fill: color-mix(in srgb, var(--blue-soft) 13%, transparent); }
/* kit · jumeau · L'anneau de veille */
.shift-diagram .sd-aslan .iso-watch { fill: none; stroke: var(--ok); stroke-width: .7;
  stroke-dasharray: 2.6 2.2; opacity: .9; transform-box: fill-box;
  transform-origin: 50% 50%; animation: sd-watch 7s linear infinite; }
@keyframes sd-watch { to { transform: rotate(360deg); } }
/* kit · jumeau · Le repère de dérive */
.shift-diagram .sd-aslan .iso-fore-mark { stroke: var(--ok); stroke-width: .7; stroke-dasharray: 1.6 1.4; }
.shift-diagram .sd-aslan .iso-fore-dot { fill: var(--ok);
  filter: drop-shadow(0 0 2.5px color-mix(in srgb, var(--ok) 80%, transparent)); }
.shift-diagram .sd-aslan .iso-fore { animation: sd-fore 3.4s ease-in-out infinite; }
@keyframes sd-fore { 0%, 100% { opacity: .55; } 50% { opacity: 1; } }
/* kit · lieu · Le sol */
.shift-diagram .iso-floor { fill: color-mix(in srgb, var(--navy) 55%, transparent); }
/* kit · lieu · La cloison */
.shift-diagram .iso-wall .fc-top { fill: color-mix(in srgb, var(--navy-3) 70%, transparent); }
.shift-diagram .iso-wall .fc-left { fill: color-mix(in srgb, var(--navy-2) 80%, transparent); }
.shift-diagram .iso-wall .fc-right { fill: color-mix(in srgb, var(--navy-2) 55%, transparent); }
/* kit · industrie · Convoyeur */
.shift-diagram .iso-belt { fill: color-mix(in srgb, var(--txt-3) 22%, transparent); }
.shift-diagram .iso-roller { stroke: color-mix(in srgb, var(--txt-2) 45%, transparent); stroke-width: .6; }
.shift-diagram .iso-beam .fc-top { fill: color-mix(in srgb, var(--txt-2) 34%, transparent); }
.shift-diagram .sd-aslan .iso-roller { stroke: color-mix(in srgb, var(--blue-soft) 40%, transparent); }
.shift-diagram .sd-aslan .iso-beam .fc-top { fill: color-mix(in srgb, var(--blue-soft) 26%, transparent); }
/* kit · industrie · Portique */
.shift-diagram .iso-mouth { fill: color-mix(in srgb, var(--deep) 78%, transparent); }
.shift-diagram .sd-today .iso-mouth { fill: color-mix(in srgb, var(--crit) 22%, var(--deep)); }
/* kit · industrie · Colis */
.shift-diagram .iso-crate .fc-top   { fill: color-mix(in srgb, var(--txt-2) 34%, transparent); }
.shift-diagram .iso-crate .fc-left  { fill: color-mix(in srgb, var(--txt-3) 38%, transparent); }
.shift-diagram .iso-crate .fc-right { fill: color-mix(in srgb, var(--txt-3) 20%, transparent); }
.shift-diagram .sd-today .iso-crate-down .fc-top,
.shift-diagram .sd-today .iso-crate-down .fc-left,
.shift-diagram .sd-today .iso-crate-down .fc-right { fill: color-mix(in srgb, var(--crit) 28%, transparent); }
/* kit · industrie · Bras robotisé */
.shift-diagram .iso-arm { color: var(--txt-2); }
.shift-diagram .iso-arm-base { fill: color-mix(in srgb, var(--txt-3) 42%, transparent); }
.shift-diagram .iso-arm-joint { fill: color-mix(in srgb, var(--txt-2) 55%, transparent); }
.shift-diagram .sd-aslan .iso-arm { color: var(--blue-soft); }
.shift-diagram .sd-aslan .iso-arm-joint { fill: var(--blue-soft); }
/* kit · industrie · Palette */
.shift-diagram .iso-pallet-deck .fc-top { fill: color-mix(in srgb, var(--txt-2) 22%, transparent); }
.shift-diagram .iso-pallet-foot .fc-top { fill: color-mix(in srgb, var(--txt-3) 26%, transparent); }
/* kit · industrie · Machine-outil */
.shift-diagram .iso-machine-hood { fill: color-mix(in srgb, var(--txt-2) 30%, transparent); }
.shift-diagram .iso-machine-door { fill: color-mix(in srgb, var(--deep) 60%, transparent);
  stroke: color-mix(in srgb, var(--txt-3) 40%, transparent); stroke-width: .5; }
.shift-diagram .sd-today .iso-machine-door { stroke: color-mix(in srgb, var(--crit) 50%, transparent); }
.shift-diagram .sd-aslan .iso-machine-door { stroke: color-mix(in srgb, var(--blue-soft) 40%, transparent); }
/* kit · industrie · Les débris */
.shift-diagram .sd-today .iso-debris { fill: color-mix(in srgb, var(--crit) 45%, transparent); }
/* kit · industrie · Les étincelles */
.shift-diagram .sd-today .iso-spark {
  stroke: var(--crit); stroke-width: 1.1; stroke-linecap: round; fill: none;
  filter: drop-shadow(0 0 3px color-mix(in srgb, var(--crit) 70%, transparent));
}
/* kit · poste · La console */
.shift-diagram .iso-desk-top .fc-top { fill: color-mix(in srgb, var(--txt-2) 40%, transparent); }
/* kit · poste · L'écran */
.shift-diagram .iso-scr-glass { fill: color-mix(in srgb, var(--deep) 74%, transparent);
  stroke: color-mix(in srgb, var(--txt-3) 45%, transparent); stroke-width: .5; }
.shift-diagram .iso-scr-trace { fill: none; stroke-width: 1.15; stroke-linecap: round; stroke-linejoin: round; }
.shift-diagram .iso-scr-foot { stroke: color-mix(in srgb, var(--txt-3) 50%, transparent); stroke-width: .9; }
.shift-diagram .sd-today .iso-scr-trace { stroke: var(--crit); }
.shift-diagram .sd-today .iso-scr-glass { stroke: color-mix(in srgb, var(--crit) 45%, transparent); }
.shift-diagram .sd-aslan .iso-scr-trace { stroke: var(--blue-soft); }
.shift-diagram .sd-aslan .iso-scr-glass { stroke: color-mix(in srgb, var(--blue-soft) 40%, transparent); }
/* kit · poste · Le siège */
.shift-diagram .iso-chair-seat .fc-top { fill: color-mix(in srgb, var(--txt-3) 40%, transparent); }
.shift-diagram .iso-chair-post { stroke: color-mix(in srgb, var(--txt-3) 55%, transparent); stroke-width: 1; }
/* kit · poste · La baie technique */
.shift-diagram .iso-rack-body .fc-top { fill: color-mix(in srgb, var(--txt-2) 24%, transparent); }
.shift-diagram .iso-rack-led { fill: color-mix(in srgb, var(--txt-2) 60%, transparent); }
.shift-diagram .sd-today .iso-rack-led { fill: color-mix(in srgb, var(--crit) 70%, transparent); }
.shift-diagram .sd-aslan .iso-rack-led { fill: color-mix(in srgb, var(--blue-soft) 60%, transparent); }
/* kit · poste · Le pupitre */
.shift-diagram .iso-pupitre-top { fill: color-mix(in srgb, var(--txt-3) 34%, transparent); }
.shift-diagram .iso-pupitre-key { fill: color-mix(in srgb, var(--txt-2) 62%, transparent); }
.shift-diagram .sd-aslan .iso-pupitre-key { fill: var(--blue-soft); }
/* kit · humain · Opérateur debout */
.shift-diagram .iso-operator { fill: var(--txt-2); color: var(--txt-2); }
.shift-diagram .sd-aslan .iso-operator { fill: var(--blue-soft); color: var(--blue-soft); }
.shift-diagram .sd-aslan .iso-helmet { fill: var(--ok); }
/* kit · humain · Opérateur assis */
.shift-diagram .iso-worker { fill: var(--txt-2); color: var(--txt-2); }
.shift-diagram .sd-today .iso-worker-down { fill: var(--crit); color: var(--crit); }
.shift-diagram .sd-aslan .iso-worker { fill: var(--blue-soft); color: var(--blue-soft); }
/* kit · humain · Opérateur en marche */
.shift-diagram .iso-walker { fill: var(--txt-2); color: var(--txt-2); }
.shift-diagram .sd-aslan .iso-walker { fill: var(--blue-soft); color: var(--blue-soft); }
/* kit · humain · Superviseur */
.shift-diagram .iso-supervisor { fill: var(--txt-2); color: var(--txt-2); }
.shift-diagram .iso-tablet { fill: color-mix(in srgb, var(--txt-2) 70%, transparent); }
.shift-diagram .sd-aslan .iso-supervisor { fill: var(--blue-soft); color: var(--blue-soft); }
.shift-diagram .sd-aslan .iso-tablet { fill: var(--blue-soft); }
/* kit · capteur · La webcam */
.shift-diagram .iso-cam-head { fill: color-mix(in srgb, var(--txt-2) 55%, transparent); }
.shift-diagram .iso-cam-lens { fill: var(--txt-2); }
.shift-diagram .sd-aslan .iso-cam-head { fill: color-mix(in srgb, var(--blue-soft) 55%, transparent); }
.shift-diagram .sd-aslan .iso-cam-lens { fill: var(--blue-soft); }
/* kit · capteur · La caméra sur mât */
.shift-diagram .iso-cammat-post { stroke: color-mix(in srgb, var(--txt-3) 60%, transparent); stroke-width: .9; }
.shift-diagram .sd-aslan .iso-cammat-post { stroke: color-mix(in srgb, var(--blue-soft) 45%, transparent); }
/* kit · capteur · Le gyrophare */
.shift-diagram .iso-beacon-post { stroke: color-mix(in srgb, var(--txt-3) 60%, transparent); stroke-width: 1; }
.shift-diagram .sd-today .iso-beacon-lamp { fill: var(--alarm); }
.shift-diagram .sd-today .iso-beacon-halo { fill: color-mix(in srgb, var(--crit) 58%, transparent);
  filter: blur(.8px); }
.shift-diagram .sd-aslan .iso-beacon-lamp { fill: var(--blue-soft); }
.shift-diagram .sd-aslan .iso-beacon-halo { fill: color-mix(in srgb, var(--blue-soft) 22%, transparent); filter: blur(.8px); }

/* Le gyrophare bat. Un SEUL objet bouge, et c'est celui qui alerte : deux
   animations concurrentes dans un decor a 78 % d'opacite se lisent comme un
   bug, pas comme une alarme. */
.shift-diagram .sd-today .iso-beacon { animation: sd-beacon 1.6s steps(1, end) infinite; }
@keyframes sd-beacon { 0%, 55% { opacity: 1; } 56%, 100% { opacity: .32; } }
/* kit · capteur · Le boîtier capteur */
.shift-diagram .iso-sensor-body .fc-top { fill: color-mix(in srgb, var(--txt-2) 30%, transparent); }
.shift-diagram .iso-sensor-eye { fill: color-mix(in srgb, var(--txt-2) 70%, transparent); }
.shift-diagram .sd-aslan .iso-sensor-eye { fill: var(--blue-soft); }
/* kit · capteur · Le cône de champ de vue */
.shift-diagram .iso-gaze { fill: color-mix(in srgb, var(--txt-3) 13%, transparent); }
.shift-diagram .sd-aslan .iso-gaze { fill: color-mix(in srgb, var(--blue-soft) 13%, transparent); }
/* kit · capteur · La zone couverte */
.shift-diagram .sd-aslan .iso-sweep {
  fill: color-mix(in srgb, var(--ok) 16%, transparent);
  filter: blur(1px);
}
/* kit · jumeau · La trajectoire */
.shift-diagram .iso-track-line { fill: none; stroke: color-mix(in srgb, var(--txt-3) 60%, transparent);
  stroke-width: .7; stroke-dasharray: 2.4 2; }
.shift-diagram .iso-track-head { fill: color-mix(in srgb, var(--txt-2) 70%, transparent); }
.shift-diagram .sd-aslan .iso-track-line { stroke: color-mix(in srgb, var(--blue-soft) 55%, transparent); }
.shift-diagram .sd-aslan .iso-track-head { fill: var(--blue-soft); }
/* kit · jumeau · L'anneau de veille */
.shift-diagram .sd-aslan .iso-watch { fill: none; stroke: var(--ok); stroke-width: .7;
  stroke-dasharray: 2.6 2.2; opacity: .9; transform-box: fill-box;
  transform-origin: 50% 50%; animation: sd-watch 7s linear infinite; }
@keyframes sd-watch { to { transform: rotate(360deg); } }
/* kit · jumeau · Le repère de dérive */
.shift-diagram .sd-aslan .iso-fore-mark { stroke: var(--ok); stroke-width: .7; stroke-dasharray: 1.6 1.4; }
.shift-diagram .sd-aslan .iso-fore-dot { fill: var(--ok);
  filter: drop-shadow(0 0 2.5px color-mix(in srgb, var(--ok) 80%, transparent)); }
.shift-diagram .sd-aslan .iso-fore { animation: sd-fore 3.4s ease-in-out infinite; }
@keyframes sd-fore { 0%, 100% { opacity: .55; } 50% { opacity: 1; } }
/* kit · jumeau · La bande d'incertitude */
.shift-diagram .iso-band { fill: color-mix(in srgb, var(--txt-3) 18%, transparent); }
.shift-diagram .sd-aslan .iso-band { fill: color-mix(in srgb, var(--blue-soft) 16%, transparent); }
/* kit · logistique · Le transpalette */
.shift-diagram .iso-jack { color: var(--txt-3); }
.shift-diagram .iso-jack-wheel { fill: color-mix(in srgb, var(--txt-3) 60%, transparent); }
.shift-diagram .sd-aslan .iso-jack { color: color-mix(in srgb, var(--blue-soft) 55%, transparent); }
/* kit · logistique · Le rayonnage */
.shift-diagram .iso-shelf-deck .fc-top { fill: color-mix(in srgb, var(--txt-2) 22%, transparent); }
.shift-diagram .iso-shelf-post .fc-top { fill: color-mix(in srgb, var(--txt-3) 34%, transparent); }
/* kit · qualite · Le poste de contrôle */
.shift-diagram .iso-inspect-arm { stroke: color-mix(in srgb, var(--txt-3) 60%, transparent); stroke-width: .9; fill: none; }
.shift-diagram .iso-inspect-lens { fill: color-mix(in srgb, var(--txt-2) 16%, transparent);
  stroke: color-mix(in srgb, var(--txt-2) 60%, transparent); stroke-width: .5; }
.shift-diagram .iso-inspect-part .fc-top { fill: color-mix(in srgb, var(--txt-2) 45%, transparent); }
.shift-diagram .sd-aslan .iso-inspect-lens { stroke: var(--blue-soft); }
/* kit · qualite · Le bac de rebut */
.shift-diagram .iso-bin-body { fill: color-mix(in srgb, var(--txt-3) 26%, transparent);
  stroke: color-mix(in srgb, var(--txt-3) 55%, transparent); stroke-width: .5; }
.shift-diagram .iso-bin-part .fc-top { fill: color-mix(in srgb, var(--txt-2) 34%, transparent); }
.shift-diagram .sd-today .iso-bin-body { stroke: color-mix(in srgb, var(--crit) 50%, transparent); }
/* kit · qualite · Le marqueur de défaut */
.shift-diagram .iso-defect-x { stroke: var(--crit); stroke-width: 1; stroke-linecap: round; fill: none; }
.shift-diagram .iso-defect-halo { fill: color-mix(in srgb, var(--crit) 22%, transparent); }
/* kit · qualite · L'écran mural */
.shift-diagram .iso-board-glass { fill: color-mix(in srgb, var(--deep) 70%, transparent);
  stroke: color-mix(in srgb, var(--txt-3) 40%, transparent); stroke-width: .5; }
.shift-diagram .iso-board-tile { fill: color-mix(in srgb, var(--txt-2) 26%, transparent); }
.shift-diagram .sd-today .iso-board-tile { fill: color-mix(in srgb, var(--crit) 34%, transparent); }
.shift-diagram .sd-aslan .iso-board-tile { fill: color-mix(in srgb, var(--blue-soft) 34%, transparent); }

.shift-diagram .sd-scene { right: -6%; bottom: -7%; width: 58%; max-width: 300px; opacity: .78; }
.shift-diagram .sd-scene * { vector-effect: non-scaling-stroke; }

.shift-diagram .fc-top   { fill: color-mix(in srgb, var(--txt-2) 30%, transparent); }
.shift-diagram .fc-left  { fill: color-mix(in srgb, var(--txt-3) 34%, transparent); }
.shift-diagram .fc-right { fill: color-mix(in srgb, var(--txt-3) 18%, transparent); }
.shift-diagram .iso-floor { fill: color-mix(in srgb, var(--navy) 38%, transparent); }

.shift-diagram .sd-scenario { opacity: 0; animation: sd-scenario 22s linear infinite; }
/* La premiere scene est l'etat de BASE : c'est elle qui reste quand
   l'animation est coupee. Voir le point 1 ci-dessus. */
.shift-diagram .sd-scenario-1 { opacity: 1; animation-delay: -0.65s; }
.shift-diagram .sd-scenario-2 { animation-delay: 4.85s; }
.shift-diagram .sd-scenario-3 { animation-delay: 10.35s; }
.shift-diagram .sd-scenario-4 { animation-delay: 15.85s; }
@keyframes sd-scenario {
  0%          { opacity: 0; }
  2.95%    { opacity: 1; }
  25%      { opacity: 1; }
  27.95%   { opacity: 0; }
  100%        { opacity: 0; }
}
/* Liaison centrale — Passerelle de flux */
.shift-diagram .sd-arrow { width: 100%; height: auto; display: block; overflow: visible; }
.shift-diagram .sd-flowlines path {
  fill: none; stroke: url(#sdFlow); stroke-width: 1.6; stroke-linecap: round;
  stroke-dasharray: 8 10;
  animation: sd-flow 2.6s linear infinite;
  animation-delay: calc(var(--i) * -.34s);
}
@keyframes sd-flow { to { stroke-dashoffset: -36; } }
.shift-diagram .sd-ring { fill: color-mix(in srgb, var(--navy) 88%, transparent); stroke: var(--blue); stroke-width: 1.6; }
.shift-diagram .sd-ring-halo { fill: none; stroke: var(--blue); stroke-width: 3; opacity: .6; }
.shift-diagram .sd-mark-logo { width: 40%; filter: brightness(0) saturate(100%) invert(72%) sepia(24%) saturate(1400%)
    hue-rotate(178deg) brightness(103%) drop-shadow(0 0 5px color-mix(in srgb, var(--blue) 70%, transparent)); }
@media (max-width: 860px) { .shift-diagram .sd-arrow { transform: rotate(90deg); } }
/* Liaison centrale — Passerelle dense */
/* Le rang de chaque courbe module son epaisseur et son opacite : c'est
   l'irregularite qui fait lire « flux » plutot que « hachures ». */
.shift-diagram .sd-flowlines path { stroke-width: calc(1 + var(--w) * 1.3); opacity: calc(.35 + var(--w) * .65); }
.shift-diagram .sd-ring-orbit {
  fill: none; stroke: color-mix(in srgb, var(--blue-soft) 55%, transparent);
  stroke-width: 1; stroke-dasharray: 3 7;
  transform-origin: 60px 75px; animation: sd-orbit 14s linear infinite;
}
@keyframes sd-orbit { to { transform: rotate(360deg); } }
/* Cadre des panneaux — Verre biseauté */
.shift-diagram .sd-panel {
  border: 1px solid color-mix(in srgb, var(--line-d) 80%, transparent);
  border-radius: 16px;
  background: linear-gradient(158deg, color-mix(in srgb, var(--navy-2) 96%, transparent),
              color-mix(in srgb, var(--navy) 97%, transparent));
  box-shadow: inset 0 1px 0 color-mix(in srgb, var(--paper) 12%, transparent),
              0 18px 44px rgba(var(--shadow), var(--shadow-a1));
}
/* Le halo est un pseudo-element : en « background » il aurait ete recouvert par
   le degrade du panneau. */
.shift-diagram .sd-panel::before {
  content: ""; position: absolute; inset: -30% 40% 55% -20%;
  background: radial-gradient(60% 60% at 50% 50%, color-mix(in srgb, var(--paper) 8%, transparent), transparent 70%);
  pointer-events: none;
}
.shift-diagram .sd-aslan {
  border-color: color-mix(in srgb, var(--blue) 38%, var(--line-d));
  box-shadow: inset 0 1px 0 color-mix(in srgb, var(--blue-soft) 26%, transparent),
              0 18px 48px rgba(var(--shadow), var(--shadow-a2)),
              0 0 0 1px color-mix(in srgb, var(--blue) 10%, transparent);
}
.shift-diagram .sd-aslan::before { background: radial-gradient(60% 60% at 50% 50%,
    color-mix(in srgb, var(--blue-soft) 14%, transparent), transparent 70%); }
/* Frise temporelle — Déréglée à gauche · droite + nœuds pulsés à droite */
.shift-diagram .sd-today .sd-flow { display: block; position: relative; z-index: 2; margin-top: 2px; height: 46px; }
.shift-diagram .sd-today .sd-track-svg { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; }
.shift-diagram .sd-today .sd-track-svg path { fill: none; vector-effect: non-scaling-stroke; stroke-linecap: round;
  stroke-linejoin: round; }
.shift-diagram .sd-today .sd-track-line { stroke-width: 2.2; }

/* LE DEGRADE EST TEINTE ICI, PAS DANS LE MARKUP. Les arrets du
   linearGradient sont des noeuds comme les autres : "stop-color" se pose en
   CSS, donc avec les jetons de css/site.css. Un degrade ecrit en dur dans
   render.mjs aurait fige deux couleurs hors du systeme, invisibles a la
   bascule de theme comme a toute retouche de palette. */
.shift-diagram .sd-today .sd-sec-s0 { stop-color: var(--txt-3); }
.shift-diagram .sd-today .sd-sec-s1 { stop-color: color-mix(in srgb, var(--crit) 55%, var(--txt-3)); }
.shift-diagram .sd-today .sd-sec-s2 { stop-color: var(--crit); }


.shift-diagram .sd-today .sd-track-tail { stroke: color-mix(in srgb, var(--txt-3) 45%, transparent); stroke-width: 2; }
.shift-diagram .sd-today .sd-track-arrow { stroke: var(--crit); stroke-width: 2; }
.shift-diagram .sd-today .sd-track-head { fill: var(--crit); stroke: none; }

/* Les reperes sont poses en POURCENTAGE DU RAIL et portent leur "top" en
   ligne : contrairement a la variante courbe, la ligne n'est pas a la meme
   hauteur sous chacun d'eux. Un "top: 50%" commun les decollerait du trace. */
.shift-diagram .sd-today .sd-flow .sd-mark { position: absolute; transform: translate(-50%, -50%); }
.shift-diagram .sd-today .sd-flow .sd-out { position: absolute; top: 43.5%; right: 0; transform: translateY(-50%); padding-left: 0; }
.shift-diagram .sd-today .sd-flow .sd-seg { display: none; }
/* LES BORNES SONT CELLES DE LA VARIANTE COURBE, ET C'EST UNE CORRECTION.
   A left: 44% / right: 30% la puce basse tombait DANS le libelle
   « intervention anticipee » — la planche-contact rendait « IANTERVENTION ».
   Le repere d'intervention est remonte a 70 % pour la meme raison : son
   libelle est centre sous lui et deborde vers la gauche. */
.shift-diagram .sd-today .sd-watch { position: absolute; left: 38%; right: 26%; top: 46%; height: 0; }

.shift-diagram .sd-aslan .sd-flow { display: flex; align-items: center; position: relative; z-index: 2; margin-top: 4px; }
.shift-diagram .sd-aslan .sd-seg { flex: 1; height: 2px; border-radius: 2px; }

.shift-diagram .sd-aslan .sd-mark-drift, .shift-diagram .sd-aslan .sd-mark-act { animation: sd-node-breathe 2.8s ease-in-out infinite; }
.shift-diagram .sd-aslan .sd-mark-act { animation-delay: .5s; }
@keyframes sd-node-breathe {
  0%, 100% { box-shadow: 0 0 0 3px color-mix(in srgb, var(--blue) 26%, transparent); }
  50%      { box-shadow: 0 0 0 7px color-mix(in srgb, var(--blue) 8%, transparent); }
}

/* L'ONDE, SUR UN SEGMENT DROIT. La variante courbe-pulse la faisait courir le
   long d'un path par stroke-dasharray ; il n'y a pas de trace ici, seulement
   une boite de 2 px. On empile donc deux fonds : la lueur qui se deplace
   PAR-DESSUS le degrade d'origine, qui reste intact — le remplacer aurait fait
   perdre au segment sa couleur de socle (css/site.css, .sd-seg-blue).
   Elle ne court que sur le segment SURVEILLE, celui qui est entre les deux
   puces IA : une onde sur toute la frise dirait « ca clignote », pas « c'est
   cette portion-la qui est sous surveillance ». */
.shift-diagram .sd-aslan .sd-watch .sd-seg-blue {
  background-image: linear-gradient(90deg, transparent, color-mix(in srgb, var(--ice) 85%, transparent), transparent),
                    linear-gradient(90deg, var(--blue-deep), var(--blue));
  background-size: 26% 100%, 100% 100%;
  background-repeat: no-repeat, no-repeat;
  animation: sd-seg-pulse 3.2s linear infinite;
}
@keyframes sd-seg-pulse {
  from { background-position: -30% 0, 0 0; }
  to   { background-position: 130% 0, 0 0; }
}
/* Typographie du claim — Actuel */
.shift-diagram .sd-claim { font-size: clamp(17px, 2.05vw, 27px); line-height: 1.24; letter-spacing: -.01em;
  margin-top: clamp(16px, 2.4vw, 26px); }

/* Une variante ne s'impose jamais a qui a demande moins de mouvement. */
@media (prefers-reduced-motion: reduce) {
  .shift-diagram *, .shift-diagram *::before, .shift-diagram *::after {
    animation: none !important; transition: none !important;
  }
}
/* SD:END studio */
