/* ============================================================
   NegoFlow — negoflow.ai
   « La vitrine keynote de l'Atelier de Verre »
   Charte : BRAND.md · Système : DESIGN.md (workspace racine)
   Palette stricte : #000000 · #FBFBFB · #FFFFFF · accent #007BFF
   Mesh (canvas uniquement) : lignes #0A46F0 · nœuds #2F6BFF
   ============================================================ */

/* ---------- Police ---------- */
@font-face {
  font-family: 'Montserrat';
  src: url('../fonts/montserrat-var-latin.woff2') format('woff2-variations');
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}

/* ---------- Tokens ---------- */
:root {
  --ink: #000000;
  --surface: #FBFBFB;
  --paper: #FFFFFF;
  --accent: #007BFF;
  --accent-deep: #0A46F0;          /* hover boutons (DESIGN.md) */
  --pale: #F2F6FB;                 /* bleu-gris très pâle (bas de dégradé) */
  --pill-bg: #E5F1FF;              /* fond pill de donnée */

  --font: 'Montserrat', system-ui, sans-serif;

  /* Échelle fluide « à pente réelle ».
     Les clamp() d'origine avaient un plancher atteint dès 1077 px : sous
     cette largeur la taille ne bougeait plus, si bien qu'un téléphone de
     390 px recevait exactement la typo d'un écran de 1000 px (display à
     40 px, titre d'accueil sur cinq lignes). La pente est reprise pour que
     le plancher ne s'applique qu'aux très petits écrans (< 340 px) : les
     valeurs de bureau sont inchangées au pixel près, seul le mobile
     descend. Formule : min + pente·vw, calée sur 390 px et 1140 px. */
  --fs-display: clamp(1.9375rem, 1.3rem + 3.1vw, 3.5rem);   /* 33 → 56 px */
  --fs-h2: clamp(1.4375rem, 0.98rem + 2.15vw, 2.5rem);      /* 24 → 40 px */
  --fs-h3: clamp(1rem, 0.94rem + 0.24vw, 1.125rem);         /* 17 → 18 px */
  --fs-lead: clamp(0.9375rem, 0.86rem + 0.56vw, 1.25rem);   /* 16 → 20 px */
  --fs-body: 1rem;
  --fs-label: 0.8125rem;           /* 13px */

  --r-sm: 6px;
  --r-md: 8px;
  --r-pill: 999px;

  --sp-xs: 8px;
  --sp-sm: 18px;
  --sp-md: 24px;
  --sp-lg: 48px;
  --sp-xl: 80px;

  --container: 1140px;
  --gutter: 24px;

  --shadow-contact: 0 2px 8px rgba(0, 0, 0, .10);
  --shadow-depth: 0 32px 64px -32px rgba(10, 30, 70, .22);
  --halo-accent: drop-shadow(0 4px 10px rgba(10, 70, 240, .18));

  --ease-out: cubic-bezier(.2, .8, .2, 1);
}

/* ---------- Reset ---------- */
*, *::before, *::after { box-sizing: border-box; }
html {
  scroll-behavior: smooth;
  -webkit-text-size-adjust: 100%;
  /* Le système n'a pas de mode sombre (DESIGN.md). On le déclare, sinon les
     ascenseurs et les contrôles natifs virent au sombre chez un utilisateur
     dont l'OS est en thème sombre, en contradiction avec la charte. */
  color-scheme: light;
}
body {
  margin: 0;
  font-family: var(--font);
  font-size: var(--fs-body);
  line-height: 1.6;
  color: var(--ink);
  background: var(--surface);
  overflow-x: hidden;
}
/* Menu mobile ouvert : le fond ne défile plus derrière le panneau */
body.menu-open { overflow: hidden; }
img, video { max-width: 100%; height: auto; display: block; }
h1, h2, h3, h4, p { margin: 0; overflow-wrap: break-word; }
ul { margin: 0; padding: 0; list-style: none; }
a { color: var(--accent); text-decoration: none; }
button { font: inherit; border: 0; background: none; cursor: pointer; color: inherit; padding: 0; }

/* Tactile : supprime le délai de 300 ms au tap (double-tap zoom) et remplace
   le flash gris par défaut d'iOS par notre propre teinte d'accent. */
a, button, [role="tab"], summary, label {
  touch-action: manipulation;
  -webkit-tap-highlight-color: rgba(0, 123, 255, .12);
}

:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
  border-radius: var(--r-sm);
}

/* Texte réservé aux technologies d'assistance */
.sr-only {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

.skip-link {
  position: absolute; top: -48px; left: 16px; z-index: 200;
  background: var(--accent); color: #fff;
  padding: 10px 18px; border-radius: var(--r-md);
  font-size: var(--fs-label); font-weight: 600;
  transition: top .2s var(--ease-out);
}
.skip-link:focus { top: 12px; }

/* ---------- Typo ---------- */
.display {
  font-size: var(--fs-display);
  font-weight: 800;
  line-height: 1.08;
  letter-spacing: -0.02em;
  text-wrap: balance;
  max-width: 780px;
}
.h2 {
  font-size: var(--fs-h2);
  font-weight: 800;
  line-height: 1.15;
  letter-spacing: -0.015em;
  text-wrap: balance;
}
.h3 {
  font-size: var(--fs-h3);
  font-weight: 600;
  line-height: 1.4;
}
.lead {
  font-size: var(--fs-lead);
  line-height: 1.55;
  max-width: 560px;
}
.kicker {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  font-size: var(--fs-label);
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--accent);
}
.kicker::before {
  content: "";
  width: 22px; height: 2px;
  background: var(--accent);
  border-radius: 2px;
}

/* ---------- Structure ---------- */
.container {
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: var(--gutter);
}
/* Même pente qu'avant (10vw, plafond à 1280 px) : seul le plancher descend.
   À 80 px il s'appliquait dès 800 px de large, donc un téléphone héritait
   du souffle d'une tablette et deux sections voisines étaient séparées de
   160 px de vide. Le plancher ne mord plus qu'en dessous de 560 px. */
.section { padding-block: clamp(46px, 10vw, 128px); }
/* La nav flotte au-dessus du flux : une cible d'ancre doit s'arrêter
   sous elle, pas dessous. La sous-nav des agents ajoute sa propre hauteur. */
section[id], header[id], article[id] { scroll-margin-top: 96px; }
#agents-ia, #agent-copilote { scroll-margin-top: 148px; }
/* La tête de section s'aligne sur la largeur du contenu qu'elle annonce.
   À 720px, les titres cassaient en deux ou trois lignes alors que le bento,
   les fiches et les tarifs occupaient les 1140px du conteneur : le bloc de
   texte paraissait rentré par rapport à tout le reste de la page.
   Le chapeau garde une mesure lisible, en `ch` et non en pixels : il suit
   ainsi la taille de police au lieu d'être calé sur une largeur fixe. */
.section-head { max-width: 960px; margin-bottom: clamp(24px, 6vw, 72px); }
.section-head .h2 { margin-top: 14px; }
.section-head .lead { margin-top: 16px; max-width: 68ch; }
/* Certaines sections se lisent mieux sur l'axe central (FAQ, soutiens,
   équipe) : le titre ET le bloc qui suit sont recentrés ensemble, sinon un
   chapeau centré au-dessus d'une liste calée à gauche se voit tout de suite. */
.section-head.is-centered { margin-inline: auto; text-align: center; }
.section-head.is-centered .lead { margin-inline: auto; }
/* Le filet du kicker ne tient que d'un côté quand le bloc est aligné à
   gauche. Centré, il lui faut son pendant, sinon il se lit comme un défaut. */
.section-head.is-centered .kicker::after {
  content: "";
  width: 22px; height: 2px;
  background: var(--accent);
  border-radius: 2px;
}

/* ---------- Boutons ---------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 14px 28px;
  border-radius: var(--r-md);
  font-size: var(--fs-label);
  font-weight: 600;
  letter-spacing: 0.02em;
  line-height: 1.2;
  transition: background-color .2s var(--ease-out), color .2s var(--ease-out),
              transform .2s var(--ease-out), box-shadow .2s var(--ease-out);
  white-space: nowrap;
}
.btn-primary {
  background: var(--accent);
  color: #fff;
  box-shadow: var(--shadow-contact), 0 10px 24px -10px rgba(0, 123, 255, .5);
}
.btn-primary:hover { background: var(--accent-deep); transform: translateY(-1px); }
.btn-primary:active { transform: translateY(0); }
.btn-ghost { background: transparent; color: var(--accent); }
.btn-ghost:hover { background: rgba(0, 123, 255, .07); }
.btn .arrow { transition: transform .2s var(--ease-out); }
.btn:hover .arrow { transform: translateX(3px); }

/* ---------- Pill de donnée ---------- */
.data-pill {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 6px 14px;
  border-radius: var(--r-pill);
  background: var(--pill-bg);
  color: var(--accent);
  font-size: var(--fs-label);
  font-weight: 600;
  letter-spacing: 0.02em;
}
.data-pill .dot {
  width: 7px; height: 7px; border-radius: 50%;
  background: var(--accent);
  filter: var(--halo-accent);
}

/* ---------- Panneau de verre (composant signature) ----------
   Épaisseur visible : arête haute lumineuse + tranche basse teintée.
   Ombre de contact + profondeur douce. Glow interne accent. */
.glass {
  position: relative;
  background: linear-gradient(180deg, rgba(255, 255, 255, .82), rgba(255, 255, 255, .58));
  -webkit-backdrop-filter: blur(16px) saturate(1.2);
  backdrop-filter: blur(16px) saturate(1.2);
  border-radius: var(--r-md);
  border: 1px solid rgba(255, 255, 255, .95);
  box-shadow:
    inset 0 1.5px 0 rgba(255, 255, 255, 1),
    inset 0 0 0 1px rgba(0, 123, 255, .12),
    inset 0 -10px 24px -18px rgba(0, 123, 255, .35),
    var(--shadow-contact),
    var(--shadow-depth);
}
.glass::after {
  /* la tranche : épaisseur du verre */
  content: "";
  position: absolute;
  left: 8px; right: 8px; bottom: -7px;
  height: 7px;
  border-radius: 0 0 var(--r-md) var(--r-md);
  background: linear-gradient(180deg, rgba(0, 123, 255, .38), rgba(0, 123, 255, .10));
  z-index: -1;
}

/* Reflet au sol, sous les objets posés */
.ground {
  position: relative;
}
.ground::after {
  content: "";
  position: absolute;
  left: 10%; right: 10%; bottom: -26px;
  height: 26px;
  background: radial-gradient(ellipse 50% 100% at 50% 0%, rgba(10, 30, 70, .16), transparent 70%);
  pointer-events: none;
}

/* ============================================================
   NAVIGATION
   ============================================================ */
.nav-wrap {
  position: fixed;
  top: 0; left: 0; right: 0;
  z-index: 100;
  /* Encoches : en paysage sur iPhone, la nav se cognerait sinon au capteur */
  padding-top: calc(14px + env(safe-area-inset-top));
  padding-right: calc(var(--gutter) + env(safe-area-inset-right));
  padding-left: calc(var(--gutter) + env(safe-area-inset-left));
  padding-bottom: 0;
  pointer-events: none;
}
.nav {
  pointer-events: auto;
  max-width: var(--container);
  margin-inline: auto;
  display: flex;
  align-items: center;
  gap: 20px;
  padding: 10px 14px 10px 20px;
  border-radius: var(--r-md);
  background: rgba(255, 255, 255, .72);
  -webkit-backdrop-filter: blur(18px) saturate(1.2);
  backdrop-filter: blur(18px) saturate(1.2);
  border: 1px solid rgba(255, 255, 255, .95);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 1),
    inset 0 0 0 1px rgba(0, 123, 255, .05),
    0 2px 8px rgba(0, 0, 0, .06);
  transition: box-shadow .3s var(--ease-out), background-color .3s var(--ease-out);
}
.nav.scrolled {
  background: rgba(255, 255, 255, .86);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 1),
    inset 0 0 0 1px rgba(0, 123, 255, .06),
    0 2px 8px rgba(0, 0, 0, .08),
    0 18px 40px -20px rgba(10, 30, 70, .25);
}
.nav-logo { display: inline-flex; align-items: center; flex-shrink: 0; }
.nav-logo img { height: 28px; width: auto; }
.nav-links {
  display: flex;
  align-items: center;
  gap: 4px;
  margin-inline: auto;
}
.nav-links a {
  color: var(--ink);
  font-size: 0.875rem;
  font-weight: 500;
  padding: 8px 12px;
  border-radius: var(--r-sm);
  white-space: nowrap;
  transition: color .2s var(--ease-out), background-color .2s var(--ease-out);
}
.nav-links a:hover { color: var(--accent); background: rgba(0, 123, 255, .06); }
.nav-links a[aria-current="page"] { color: var(--accent); }
.nav-actions { display: flex; align-items: center; gap: 6px; flex-shrink: 0; }
.nav-actions .btn { padding: 11px 20px; }
/* Le numéro dans la barre : mobile seulement, et c'est mesuré.
   La barre est plafonnée à la largeur du conteneur (1140 px) : l'élargir
   n'ajoute rien, quelle que soit la taille de l'écran. Or logo (142) +
   liens (586) + actions (326) + gouttières (74) occupent déjà 1128 px,
   soit 12 px de marge. Le numéro en demande 169 et la pastille seule 48 :
   ni l'un ni l'autre n'entre sans rogner les six liens, qui passent alors
   sur deux lignes. En dessous de 1021 px les liens disparaissent et la
   place existe : la pastille d'appel apparaît là, à côté du burger, c'est
   d'ailleurs l'écran depuis lequel on appelle vraiment.
   Sur ordinateur le relais est pris par le bloc du hero, l'appel final et
   le pied de page. */
.nav-tel { display: none; }
.nav-tel svg { flex-shrink: 0; }
@media (max-width: 1020px) {
  .nav-tel {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 42px; height: 42px;
    border-radius: var(--r-sm);
    color: var(--accent);
    background: rgba(0, 123, 255, .08);
  }
  .nav-tel span { display: none; }
}
.nav-burger {
  display: none;
  width: 42px; height: 42px;
  border-radius: var(--r-sm);
  position: relative;
}
.nav-burger span, .nav-burger span::before, .nav-burger span::after {
  content: "";
  position: absolute;
  left: 11px; right: 11px;
  height: 2px;
  border-radius: 2px;
  background: var(--ink);
  transition: transform .3s var(--ease-out), opacity .2s var(--ease-out);
}
.nav-burger span { top: 50%; margin-top: -1px; }
.nav-burger span::before { left: 0; right: 0; top: -6px; }
.nav-burger span::after { left: 0; right: 0; top: 6px; }
.nav-burger[aria-expanded="true"] span { background: transparent; }
.nav-burger[aria-expanded="true"] span::before { transform: translateY(6px) rotate(45deg); }
.nav-burger[aria-expanded="true"] span::after { transform: translateY(-6px) rotate(-45deg); }

.nav-mobile {
  display: none;
  position: fixed;
  inset: calc(74px + env(safe-area-inset-top))
         calc(16px + env(safe-area-inset-right)) auto
         calc(16px + env(safe-area-inset-left));
  z-index: 99;
  padding: 18px;
  border-radius: var(--r-md);
  flex-direction: column;
  gap: 4px;
}
/* Le panneau tient à l'écran sur un téléphone tenu droit. Il ne devient une
   zone défilante qu'en paysage ou sur un très petit écran, et seulement là :
   `overflow` sur un `.glass` ferait compter sa tranche (7 px sous le bord,
   décorative) comme du contenu à faire défiler, avec un ascenseur pour rien.
   Le fond, lui, est déjà bloqué par `body.menu-open`. */
@media (max-height: 600px) {
  .nav-mobile {
    max-height: calc(100dvh - 96px - env(safe-area-inset-top));
    overflow-y: auto;
    overscroll-behavior: contain;
  }
  .nav-mobile::after { display: none; }
}
.nav-mobile.open { display: flex; }
.nav-mobile a {
  color: var(--ink);
  font-weight: 600;
  font-size: 1rem;
  padding: 12px 14px;
  border-radius: var(--r-sm);
}
.nav-mobile a:hover { background: rgba(0, 123, 255, .06); color: var(--accent); }
.nav-mobile .btn-primary { color: #fff; margin-top: 10px; }
/* Le numéro ferme le menu mobile, sur toute la largeur : c'est le geste le
   plus naturel depuis un téléphone, et le seul endroit du menu où le
   contenu vaut d'être lu avant d'être cliqué. */
.nav-mobile .nav-mobile-tel {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: 8px;
  padding: 12px 14px;
  border: 1px solid rgba(0, 123, 255, .22);
  color: var(--accent);
  font-weight: 800;
  font-variant-numeric: tabular-nums;
}
.nav-mobile .nav-mobile-tel svg { flex-shrink: 0; }

/* Sélecteur de langue (SPEC-i18n.md § 6). Absent du HTML (chaîne vide) tant
   qu'une page n'a pas de lang_urls : STATIC_PAGES n'en fournit pas encore.
   Pas de transition d'ouverture : comme .nav-mobile, un simple bascule
   d'affichage n'a rien à respecter de prefers-reduced-motion. */
.lang-switch { position: relative; flex-shrink: 0; }
.lang-switch-toggle {
  width: 42px; height: 42px;
  border-radius: var(--r-sm);
  color: var(--ink);
  font-size: .75rem;
  font-weight: 700;
  letter-spacing: .02em;
}
.lang-switch-toggle:hover { background: rgba(0, 123, 255, .06); color: var(--accent); }
.lang-switch-menu {
  display: none;
  position: absolute;
  top: calc(100% + 8px);
  right: 0;
  min-width: 160px;
  padding: 8px;
}
.lang-switch.open .lang-switch-menu { display: block; }
/* .glass porte le fond/flou/bordure/ombre ; .glass::after sa tranche (règle
   non négociable du contrat de direction visuelle, tête d'index.html). */
.lang-switch-menu.glass { z-index: 1; }
.lang-switch-menu a {
  display: block;
  padding: 8px 10px;
  border-radius: var(--r-sm);
  color: var(--ink);
  font-size: .875rem;
  font-weight: 500;
}
.lang-switch-menu a:hover { color: var(--accent); background: rgba(0, 123, 255, .06); }
.lang-switch-menu a[aria-current="true"] { color: var(--accent); font-weight: 700; }

/* Repli mobile : une rangée de liens dans le menu plein écran, pas de
   sous-menu déroulant (déjà dans un panneau ouvert/fermé). */
.lang-switch-mobile {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-top: 8px;
  padding-top: 8px;
  border-top: 1px solid rgba(0, 123, 255, .12);
}
.lang-switch-mobile a {
  padding: 6px 12px;
  border-radius: var(--r-sm);
  color: var(--ink);
  font-size: .8125rem;
  font-weight: 600;
}
.lang-switch-mobile a:hover { color: var(--accent); background: rgba(0, 123, 255, .06); }
.lang-switch-mobile a[aria-current="true"] { color: var(--accent); background: rgba(0, 123, 255, .08); }

/* ============================================================
   HERO — la scène d'ouverture
   ============================================================ */
.hero {
  position: relative;
  padding: clamp(112px, 16vh, 190px) 0 clamp(46px, 9vw, 120px);
  background: linear-gradient(180deg, #FFFFFF 0%, var(--surface) 55%, var(--pale) 100%);
  overflow: hidden;
}
.hero-mesh {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
}
.hero-grid {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1.05fr) minmax(0, .95fr);
  gap: clamp(40px, 5vw, 72px);
  align-items: center;
}
.hero-copy { max-width: 620px; }
.hero-copy .data-pill { margin-bottom: 22px; }
.hero-copy .display { margin-bottom: 20px; }
.hero-copy .lead { margin-bottom: 32px; max-width: 540px; }
.hero-ctas { display: flex; flex-wrap: wrap; gap: 10px; margin-bottom: 20px; }
/* ── L'appel téléphonique, premier écran ─────────────────────────
   Placé sous les deux boutons plutôt qu'à côté : en troisième bouton il
   aurait concurrencé la demande de démonstration, alors qu'il s'adresse
   à qui veut parler tout de suite. Le numéro porte la graisse et la
   taille, le libellé reste petit : c'est le numéro qu'on vient chercher,
   pas la phrase. Cible tactile pleine hauteur sur la ligne entière. */
.tel-cta {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 30px;
  padding: 10px 16px 10px 12px;
  border: 1px solid rgba(0, 0, 0, .08);
  border-radius: var(--r-md);
  background: rgba(255, 255, 255, .72);
  transition: border-color .2s var(--ease-out), background-color .2s var(--ease-out);
}
.tel-cta:hover { border-color: rgba(0, 123, 255, .38); background: #FFFFFF; }
.tel-cta-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: 38px; height: 38px;
  border-radius: 50%;
  color: var(--accent);
  background: rgba(0, 123, 255, .09);
}
.tel-cta-txt { display: flex; flex-direction: column; line-height: 1.2; }
.tel-cta-txt span {
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: rgba(0, 0, 0, .55);
}
.tel-cta-txt b {
  margin-top: 3px;
  font-size: 1.125rem;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.005em;
  color: var(--ink);
  transition: color .2s var(--ease-out);
}
.tel-cta:hover .tel-cta-txt b { color: var(--accent); }
.hero-trust {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 22px;
  font-size: var(--fs-label);
  font-weight: 600;
  letter-spacing: 0.02em;
}
.hero-trust li { display: inline-flex; align-items: center; gap: 8px; }
.hero-trust svg { color: var(--accent); flex-shrink: 0; }

/* ============================================================
   HERO « SCROLL-MORPH » — le désordre administratif qui se range
   ------------------------------------------------------------
   La promesse est au centre, les pièces du quotidien tournent
   autour puis se rangent au scroll. Monté par motion.js, module 1.
   Deux chorégraphies, un seul récit : anneau qui s'ouvre en arc sur
   grand écran, tas qui se déplie en éventail sur téléphone.
   ============================================================ */
.hero-morph {
  min-height: 100vh;
  min-height: 100svh;
  display: grid;
  place-items: center;
  padding: clamp(96px, 13vh, 150px) 0 clamp(40px, 7vh, 90px);
}
/* Le texte passe devant les cartes, toujours. */
.hero-morph .container { position: relative; z-index: 3; }

.morph-copy {
  max-width: 730px;
  margin: 0 auto;
  text-align: center;
  will-change: transform;
}
.morph-copy .data-pill { margin-bottom: 22px; }
.morph-copy .display { margin-bottom: 20px; }
.morph-copy .lead { margin: 0 auto 30px; max-width: 620px; }
.morph-copy .hero-ctas { justify-content: center; margin-bottom: 0; }
.morph-copy .hero-trust { justify-content: center; margin-top: 26px; }
/* Ce qui s'efface quand l'arc se forme : le titre et l'action restent. */
.hm-fade { will-change: opacity; }

.morph-stage {
  position: absolute; inset: 0; z-index: 1;
  pointer-events: none;
  overflow: hidden;
}
.morph-stage-inner {
  position: absolute; left: 50%; top: 50%;
  width: 0; height: 0;
}

/* La carte. Pas de backdrop-filter ici, contrairement à .glass :
   vingt flous simultanés effondrent le framerate. Le verre est imité
   par un dégradé blanc + arête + tranche, ce qui tient à cette taille. */
.mcard {
  position: absolute;
  left: -52px; top: -72px;          /* centrée sur son point d'ancrage */
  width: 104px; height: 144px;
  pointer-events: auto;
  will-change: transform;
  transform-origin: 50% 50%;
}
.mcard-face {
  position: absolute; inset: 0;
  display: flex; flex-direction: column;
  padding: 11px 11px 10px;
  border-radius: var(--r-md);
  background: linear-gradient(180deg, rgba(255, 255, 255, .97), rgba(255, 255, 255, .88));
  border: 1px solid rgba(255, 255, 255, .95);
  box-shadow:
    inset 0 1.5px 0 rgba(255, 255, 255, 1),
    inset 0 0 0 1px rgba(0, 123, 255, .13),
    inset 0 -12px 26px -20px rgba(0, 123, 255, .40),
    var(--shadow-contact),
    0 22px 44px -24px rgba(10, 30, 70, .30);
  transition: box-shadow .25s var(--ease-out);
}
/* La tranche : l'épaisseur du verre, non négociable */
.mcard-face::after {
  content: "";
  position: absolute; left: 7px; right: 7px; bottom: -6px;
  height: 6px;
  border-radius: 0 0 var(--r-md) var(--r-md);
  background: linear-gradient(180deg, rgba(0, 123, 255, .38), rgba(0, 123, 255, .08));
  z-index: -1;
}
/* Survol : c'est l'ÉLÉVATION qui répond, pas la couleur. Un halo
   chromatique plus fort que celui de .glass sortirait la carte du
   système au moment précis où on la regarde. */
.mcard.is-hot .mcard-face {
  box-shadow:
    inset 0 1.5px 0 rgba(255, 255, 255, 1),
    inset 0 0 0 1px rgba(0, 123, 255, .18),
    inset 0 -12px 26px -20px rgba(0, 123, 255, .40),
    var(--shadow-contact),
    0 34px 60px -22px rgba(10, 30, 70, .34);
}

.mc-kicker {
  font-size: 8px; font-weight: 800; line-height: 1.2;
  letter-spacing: .10em; text-transform: uppercase;
  color: var(--accent);
}
.mc-title {
  margin-top: 7px;
  font-size: 12px; font-weight: 800; line-height: 1.15;
  letter-spacing: -.01em; color: var(--ink);
  font-variant-numeric: tabular-nums;
}
.mc-rule {
  margin-top: 9px; height: 1px;
  background: linear-gradient(90deg, rgba(0, 123, 255, .34), rgba(0, 123, 255, 0));
}
.mc-val {
  margin-top: auto;
  font-size: 10.5px; font-weight: 700; line-height: 1.2;
  color: rgba(0, 0, 0, .58);
  font-variant-numeric: tabular-nums;
}

/* Carte « agent » : le portrait remplace l'en-tête de document.
   Le pastel ne sort jamais du portrait, l'anneau reste blanc. */
.mcard.is-agent .mcard-face { padding: 10px; align-items: center; text-align: center; }
.mc-portrait {
  width: 52px; height: 52px;
  border-radius: 50%;
  overflow: hidden;
  flex-shrink: 0;
  background: var(--pill-bg);
  box-shadow: 0 0 0 2px var(--paper), 0 0 0 3px rgba(0, 123, 255, .22);
}
.mc-portrait img { width: 100%; height: 100%; object-fit: cover; }
.mc-name {
  margin-top: 9px;
  font-size: 12.5px; font-weight: 800; line-height: 1.1;
  color: var(--ink);
}
.mc-fn {
  margin-top: 4px;
  font-size: 8.5px; font-weight: 700; line-height: 1.25;
  letter-spacing: .02em; color: rgba(0, 0, 0, .55);
}

/* Repli : téléphone, tablette, écran bas, mouvement réduit.
   Le plateau quitte le plein cadre et redevient un bloc posé sous le
   texte. `prefers-reduced-motion` est dans la liste pour la même
   raison que les autres : sans lui, sur un grand écran, l'éventail
   figé se posait au milieu du hero, donc par-dessus le titre. */
@media (max-width: 1020px), (max-height: 719px), (prefers-reduced-motion: reduce) {
  .hero-morph { min-height: auto; }
  .morph-stage {
    position: relative;
    inset: auto;
    /* `place-items: center` pose `justify-items: center` : sans largeur
       explicite ce bloc se réduit à la largeur de son contenu, or son
       contenu est en position absolue. Il mesurait 0 px de large et
       `overflow: hidden` masquait tout. */
    width: 100%;
    /* Et il passe SOUS le texte : dans le flux il est écrit avant le
       conteneur, donc il s'afficherait au-dessus du titre. */
    order: 2;
    height: clamp(230px, 30vw, 260px);
    margin-top: 42px;
  }
  .morph-stage.is-static .mcard { will-change: auto; }
}

/* --- Mini-démo : l'agent en action --- */
.demo-scene {
  position: relative;
  perspective: 1200px;
}
.demo-tilt {
  position: relative;
  transform-style: preserve-3d;
  will-change: transform;
}
.demo-lot {
  position: relative;
  z-index: 1;
  width: min(88%, 380px);
  margin-left: auto;
  padding: 20px 22px 18px;
}
.demo-lot-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 14px;
}
.demo-lot-head .tag {
  font-size: var(--fs-label);
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: rgba(0, 0, 0, .55);
}
.demo-chip {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font-size: 12px;
  font-weight: 600;
  color: var(--accent);
  background: var(--pill-bg);
  border-radius: var(--r-pill);
  padding: 4px 12px;
}
.demo-chip .pulse {
  width: 7px; height: 7px; border-radius: 50%;
  background: var(--accent);
  animation: pulse 2s ease-in-out infinite;
}
@keyframes pulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(0, 123, 255, .45); }
  50% { box-shadow: 0 0 0 6px rgba(0, 123, 255, 0); }
}
.demo-lot-title {
  font-size: 1rem;
  font-weight: 700;
  letter-spacing: -0.01em;
  margin-bottom: 12px;
}
.demo-rows { display: grid; gap: 8px; margin-bottom: 12px; }
.demo-row {
  display: flex;
  justify-content: space-between;
  gap: 14px;
  font-size: 0.875rem;
}
.demo-row span { color: rgba(0, 0, 0, .55); }
/* Les valeurs changent d'un run à l'autre : chasse fixe, sinon les chiffres
   se décalent latéralement à chaque bascule. */
.demo-row b { font-weight: 600; font-variant-numeric: tabular-nums; }
.demo-total {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  border-top: 1px solid rgba(0, 123, 255, .14);
  padding-top: 12px;
  font-size: 0.875rem;
}
.demo-total span { color: rgba(0, 0, 0, .55); }
.demo-total em {
  font-style: normal;
  font-size: 1.35rem;
  font-weight: 800;
  letter-spacing: -0.02em;
  color: var(--accent);
  font-variant-numeric: tabular-nums;
}

.demo-agent {
  position: relative;
  z-index: 2;
  width: min(94%, 400px);
  margin-top: -16px;
  padding: 18px 20px 16px;
  transform: translateZ(40px);
}
.demo-agent-head {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 14px;
}
.agent-orb {
  position: relative;
  width: 34px; height: 34px;
  border-radius: 50%;
  flex-shrink: 0;
  background: radial-gradient(circle at 32% 28%, #7db9ff 0%, var(--accent) 45%, #0059c9 100%);
  box-shadow:
    inset 0 2px 4px rgba(255, 255, 255, .55),
    0 6px 14px -4px rgba(0, 123, 255, .6);
  filter: var(--halo-accent);
}
.agent-orb::after {
  content: "";
  position: absolute;
  top: 5px; left: 7px;
  width: 10px; height: 6px;
  border-radius: 50%;
  background: rgba(255, 255, 255, .85);
  filter: blur(1px);
  transform: rotate(-18deg);
}
.demo-agent-id { flex: 1; min-width: 0; }
.demo-agent-id b {
  display: block;
  font-size: 0.9375rem;
  font-weight: 700;
  letter-spacing: -0.01em;
}
.demo-agent-id span {
  display: block;
  font-size: 12px;
  color: rgba(0, 0, 0, .55);
}
.demo-steps { display: grid; gap: 7px; min-height: 148px; align-content: start; }
/* Bascule d'un run à l'autre : le contenu se fond au lieu de se couper net */
.demo-agent .demo-steps,
.demo-agent .demo-saved b,
.demo-lot .demo-lot-title,
.demo-lot .demo-rows,
.demo-lot .demo-total em {
  transition: opacity .3s var(--ease-out);
}
.demo-agent.swapping .demo-steps,
.demo-agent.swapping .demo-saved b,
.demo-lot.swapping .demo-lot-title,
.demo-lot.swapping .demo-rows,
.demo-lot.swapping .demo-total em { opacity: 0; }
.demo-step {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 0.8125rem;
  font-weight: 500;
  line-height: 1.35;
  opacity: 0;
  transform: translateY(6px);
  transition: opacity .45s var(--ease-out), transform .45s var(--ease-out);
}
.demo-step.on { opacity: 1; transform: none; }
.demo-step .ic {
  position: relative;
  width: 20px; height: 20px;
  border-radius: 50%;
  flex-shrink: 0;
  display: grid;
  place-items: center;
  border: 2px solid rgba(0, 123, 255, .35);
  border-top-color: var(--accent);
  animation: spin 1s linear infinite;
  transition: background-color .3s var(--ease-out), border-color .3s var(--ease-out);
}
.demo-step .ic svg { opacity: 0; transform: scale(.4); transition: opacity .25s var(--ease-out), transform .25s var(--ease-out); }
.demo-step.done .ic {
  animation: none;
  background: var(--accent);
  border-color: var(--accent);
}
.demo-step.done .ic svg { opacity: 1; transform: scale(1); }
@keyframes spin { to { transform: rotate(360deg); } }
.demo-badge {
  margin-left: auto;
  flex-shrink: 0;
  font-size: 11px;
  font-weight: 700;
  color: var(--accent);
  background: var(--pill-bg);
  border-radius: var(--r-pill);
  padding: 2px 9px;
  opacity: 0;
  transform: scale(.7);
  transition: opacity .3s var(--ease-out), transform .3s var(--ease-out);
}
.demo-step.done .demo-badge { opacity: 1; transform: scale(1); }
.demo-saved {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-top: 14px;
  padding-top: 12px;
  border-top: 1px solid rgba(0, 123, 255, .14);
  font-size: 0.8125rem;
  color: rgba(0, 0, 0, .55);
}
.demo-saved b {
  font-size: 1.05rem;
  font-weight: 800;
  color: var(--accent);
  letter-spacing: -0.01em;
  font-variant-numeric: tabular-nums;
}

/* ============================================================
   SCÈNES (sections keynote)
   ============================================================ */
.scene-problem { background: var(--paper); }
.scene-solution {
  background: linear-gradient(180deg, var(--paper) 0%, var(--pale) 100%);
}

.duo {
  display: grid;
  grid-template-columns: minmax(0, .85fr) minmax(0, 1.15fr);
  gap: clamp(28px, 6vw, 88px);
  align-items: start;
}
.duo-intro { position: sticky; top: 120px; }
.duo-intro .h2 { margin-top: 14px; }
.duo-intro .lead { margin-top: 16px; }

.point-list { display: grid; gap: 0; }
.point {
  display: grid;
  grid-template-columns: 52px minmax(0, 1fr);
  gap: 20px;
  padding: 26px 0;
  border-top: 1px solid rgba(0, 0, 0, .08);
}
.point:first-child { border-top: 0; padding-top: 0; }
.point-icon {
  width: 52px; height: 52px;
  border-radius: var(--r-md);
  display: grid;
  place-items: center;
  color: var(--accent);
  background: linear-gradient(180deg, rgba(255, 255, 255, .9), rgba(229, 241, 255, .55));
  border: 1px solid rgba(255, 255, 255, .95);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 1),
    inset 0 0 0 1px rgba(0, 123, 255, .07),
    var(--shadow-contact);
}
.point .h3 { margin-bottom: 6px; }
.point p { color: rgba(0, 0, 0, .68); max-width: 56ch; }

.scene-solution .point { border-top-color: rgba(0, 123, 255, .12); }
.scene-solution .point-icon {
  color: #fff;
  background: var(--accent);
  border-color: rgba(255, 255, 255, .5);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, .45),
    0 8px 18px -8px rgba(0, 123, 255, .65);
}

/* ============================================================
   TÉMOIGNAGE
   ============================================================ */
.scene-testimonial { background: var(--pale); }
.testimonial {
  max-width: 880px;
  margin-inline: auto;
  text-align: center;
}
.testimonial .quote-mark {
  color: var(--accent);
  margin-inline: auto;
  margin-bottom: 26px;
  filter: var(--halo-accent);
}
.testimonial blockquote {
  margin: 0 0 34px;
  font-size: clamp(1.0625rem, 0.72rem + 1.55vw, 1.625rem);
  font-weight: 600;
  line-height: 1.45;
  letter-spacing: -0.01em;
  text-wrap: balance;
}
.testimonial-author {
  display: inline-flex;
  align-items: center;
  gap: 16px;
  text-align: left;
}
.testimonial-author img {
  width: 58px; height: 58px;
  border-radius: 50%;
  object-fit: cover;
  box-shadow: var(--shadow-contact);
}
.testimonial-author b { display: block; font-weight: 700; }
.testimonial-author span { display: block; font-size: 0.875rem; color: rgba(0, 0, 0, .6); }

/* ============================================================
   FONCTIONNALITÉS — bento
   ============================================================ */
.scene-features { background: var(--paper); }
.bento {
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  gap: 16px;
}
.tile {
  grid-column: span 2;
  padding: 26px;
  border-radius: var(--r-md);
  background: linear-gradient(180deg, rgba(255, 255, 255, .92), rgba(246, 250, 255, .8));
  border: 1px solid rgba(255, 255, 255, .95);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 1),
    inset 0 0 0 1px rgba(0, 123, 255, .06),
    var(--shadow-contact);
  transition: transform .35s var(--ease-out), box-shadow .35s var(--ease-out);
}
.tile:hover {
  transform: translateY(-4px);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 1),
    inset 0 0 0 1px rgba(0, 123, 255, .1),
    var(--shadow-contact),
    0 24px 48px -20px rgba(10, 30, 70, .25);
}
.tile-wide { grid-column: span 4; }
.tile-half { grid-column: span 3; }
.tile-icon { color: var(--accent); margin-bottom: 16px; }
.tile b {
  display: block;
  font-size: var(--fs-h3);
  font-weight: 600;
  margin-bottom: 8px;
  letter-spacing: -0.01em;
}
.tile p { font-size: 0.9375rem; color: rgba(0, 0, 0, .68); }

/* mini-démo « pilotage » : barres qui prennent vie */
/* La courbe occupe toute la largeur de la tuile : bornée à 420 px, elle
   laissait la moitié droite vide et se lisait comme un graphique tronqué.
   Douze plots au lieu de sept, pour garder des barres fines : à pleine
   largeur, sept plots deviennent des dalles presque carrées. */
.mini-dash {
  display: flex;
  align-items: flex-end;
  gap: 8px;
  height: 96px;
  margin-bottom: 20px;
}
.mini-dash i {
  flex: 1;
  height: 100%;
  border-radius: 3px 3px 0 0;
  background: linear-gradient(180deg, rgba(0, 123, 255, .85), rgba(0, 123, 255, .35));
  transform-origin: bottom;
  transform: scaleY(.12);
  transition: transform .9s var(--ease-out);
  /* Le rang est porté en ligne (--i) plutôt qu'en une série de
     `nth-child` : la cascade suit le nombre de plots sans retouche. */
  transition-delay: calc(var(--i, 0) * .055s);
}
.in-view .mini-dash i { transform: scaleY(var(--h, .6)); }

/* mini-démo « reporting » : l'anneau se dessine */
.mini-ring {
  height: 56px;
  margin-bottom: 18px;
}
.mini-ring svg { height: 56px; width: 56px; overflow: visible; }
.mini-ring .track { stroke: rgba(0, 123, 255, .16); }
.mini-ring .arc {
  stroke: var(--accent);
  stroke-linecap: round;
  stroke-dasharray: 126;
  stroke-dashoffset: 126;
  transition: stroke-dashoffset 1.1s var(--ease-out);
}
.in-view .mini-ring .arc { stroke-dashoffset: 44; }

/* mini-démo « comptabilité » : les écritures se cochent une à une */
.mini-ledger {
  display: grid;
  gap: 7px;
  height: 56px;
  max-width: 240px;
  margin-bottom: 18px;
  align-content: center;
}
.mini-ledger span {
  display: grid;
  grid-template-columns: 1fr 13px;
  align-items: center;
  gap: 12px;
}
.mini-ledger i {
  height: 6px;
  border-radius: 3px;
  background: rgba(0, 123, 255, .18);
  transform-origin: left;
  transform: scaleX(.25);
  transition: transform .7s var(--ease-out), background-color .5s var(--ease-out);
}
.mini-ledger span:nth-child(2) i { justify-self: start; width: 76%; }
.mini-ledger b {
  width: 13px; height: 13px;
  flex-shrink: 0;
  border-radius: 50%;
  background: var(--accent);
  opacity: 0;
  transform: scale(.4);
  transition: opacity .35s var(--ease-out), transform .35s var(--ease-out);
}
.in-view .mini-ledger i { transform: scaleX(1); background: rgba(0, 123, 255, .32); }
.in-view .mini-ledger b { opacity: 1; transform: scale(1); }
.in-view .mini-ledger span:nth-child(2) i,
.in-view .mini-ledger span:nth-child(2) b { transition-delay: .12s; }
.in-view .mini-ledger span:nth-child(3) i,
.in-view .mini-ledger span:nth-child(3) b { transition-delay: .24s; }

/* mini-démo « risque client » : l'encours monte vers le plafond */
.mini-gauge {
  position: relative;
  height: 56px;
  max-width: 240px;
  margin-bottom: 18px;
  display: flex;
  align-items: center;
}
.mini-gauge .track {
  position: relative;
  width: 100%;
  height: 12px;
  border-radius: var(--r-pill);
  background: rgba(0, 123, 255, .12);
  overflow: hidden;
}
.mini-gauge .fill {
  position: absolute;
  inset: 0;
  border-radius: var(--r-pill);
  background: linear-gradient(90deg, rgba(0, 123, 255, .55), var(--accent));
  transform-origin: left;
  transform: scaleX(.06);
  transition: transform 1.1s var(--ease-out);
}
.in-view .mini-gauge .fill { transform: scaleX(.68); }
.mini-gauge .cap {
  position: absolute;
  left: 84%;
  top: -7px; bottom: -7px;
  width: 2px;
  border-radius: 2px;
  background: var(--accent);
  opacity: .55;
}

/* mini-démo « conformité » : le tampon se pose */
.mini-stamp {
  position: relative;
  height: 56px;
  margin-bottom: 18px;
}
.mini-stamp .sheet {
  position: absolute;
  left: 0; top: 3px;
  width: 40px; height: 50px;
  border-radius: 4px;
  background: #fff;
  border: 1px solid rgba(0, 123, 255, .22);
  box-shadow: var(--shadow-contact);
}
.mini-stamp .sheet::before, .mini-stamp .sheet::after {
  content: "";
  position: absolute;
  left: 8px;
  height: 3px;
  border-radius: 2px;
  background: rgba(0, 123, 255, .25);
}
.mini-stamp .sheet::before { top: 10px; right: 8px; }
.mini-stamp .sheet::after { top: 18px; right: 16px; }
.mini-stamp .seal {
  position: absolute;
  left: 26px; top: 14px;
  width: 32px; height: 32px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  color: #fff;
  background: var(--accent);
  box-shadow: 0 6px 14px -6px rgba(0, 123, 255, .7);
  opacity: 0;
  transform: scale(1.6) rotate(-14deg);
  transition: opacity .4s var(--ease-out), transform .55s var(--ease-out);
}
.in-view .mini-stamp .seal {
  opacity: 1;
  transform: scale(1) rotate(-8deg);
  transition-delay: .25s;
}

/* mini-démo « documents » : feuilles qui s'éventent */
.mini-docs {
  position: relative;
  height: 56px;
  margin-bottom: 18px;
}
.mini-docs i {
  position: absolute;
  left: 0; top: 6px;
  width: 38px; height: 48px;
  border-radius: 4px;
  background: #fff;
  border: 1px solid rgba(0, 123, 255, .22);
  box-shadow: var(--shadow-contact);
  transition: transform .7s var(--ease-out);
}
.mini-docs i::before, .mini-docs i::after {
  content: "";
  position: absolute;
  left: 7px; right: 7px;
  height: 3px;
  border-radius: 2px;
  background: rgba(0, 123, 255, .25);
}
.mini-docs i::before { top: 9px; }
.mini-docs i::after { top: 17px; right: 14px; }
.mini-docs i:nth-child(2) { background: linear-gradient(180deg, #fff, #f4f9ff); }
.mini-docs i:nth-child(3) { background: linear-gradient(180deg, #fff, #ecf5ff); }
.in-view .mini-docs i:nth-child(1) { transform: translateX(0) rotate(-4deg); }
.in-view .mini-docs i:nth-child(2) { transform: translateX(26px) rotate(2deg); transition-delay: .08s; }
.in-view .mini-docs i:nth-child(3) { transform: translateX(52px) rotate(7deg); transition-delay: .16s; }

/* ============================================================
   VITRINES PRODUIT
   ============================================================ */
.showcase { display: grid; gap: clamp(34px, 9vw, 120px); }
.module {
  display: grid;
  grid-template-columns: minmax(0, .9fr) minmax(0, 1.1fr);
  gap: clamp(24px, 5vw, 72px);
  align-items: center;
}
.module:nth-child(even) .module-copy { order: 2; }
.module:nth-child(even) .module-visual { order: 1; }
/* Capture très panoramique : elle a besoin de toute la largeur pour rester
   lisible, sinon l'UI descend sous 5 px de hauteur de texte. */
.module-full { grid-template-columns: 1fr; gap: clamp(28px, 4vw, 44px); }
.module-full .module-copy { max-width: 640px; }
.module-full .module-copy p { max-width: 60ch; }
/* En pile, le titre annonce toujours la capture, quel que soit le rang */
.module-full .module-copy,
.module:nth-child(even).module-full .module-copy { order: 1; }
.module-full .module-visual,
.module:nth-child(even).module-full .module-visual { order: 2; }
/* Le panneau entre comme une plaque qu'on redresse, le texte suit le reveal
   standard : les deux plans ne bougent pas à l'identique. */
html.js .module .module-visual {
  opacity: 0;
  transform: perspective(1200px) rotateX(5deg) translateY(32px);
  transition: opacity .9s var(--ease-out), transform .9s var(--ease-out);
  transition-delay: .15s;
}
html.js .module.in-view .module-visual { opacity: 1; transform: none; }
.module-copy .h2 { font-size: clamp(1.125rem, 0.955rem + 1.47vw, 2rem); margin-bottom: 14px; }
.module-copy p { color: rgba(0, 0, 0, .68); max-width: 46ch; }
.module-visual { position: relative; }
.screen-frame {
  padding: 10px;
  border-radius: var(--r-md);
  overflow: visible;
}
.screen-frame .chrome {
  display: flex;
  gap: 5px;
  padding: 2px 4px 10px;
}
.screen-frame .chrome i {
  width: 8px; height: 8px;
  border-radius: 50%;
  background: rgba(0, 60, 130, .14);
}
.screen-frame img {
  border-radius: var(--r-sm);
  width: 100%;
  box-shadow: 0 1px 3px rgba(0, 0, 0, .08);
}

/* ============================================================
   AGENTS IA — le casting (accueil) + les fiches (page dédiée)
   ------------------------------------------------------------
   Un collectif de personnages nommés, pas une grille d'icônes.
   Le pastel n'existe qu'à l'intérieur du portrait (tolérance
   « avatars » de BRAND.md) : aucun pastel ne fuit dans le plan
   de la page, qui reste en trois neutres + #007BFF.
   ============================================================ */
.scene-agents { background: linear-gradient(180deg, var(--paper) 0%, var(--pale) 100%); }

.roster {
  display: grid;
  /* Une colonne par agent : ils sont six depuis le 06/09/2026. Cette
     liste n'est vue que sans JavaScript (repli de la constellation),
     en impression et en capture · elle doit donc rester juste. */
  grid-template-columns: repeat(6, 1fr);
  gap: 14px;
}
.roster-agent > a {
  display: flex;
  flex-direction: column;
  align-items: center;
  height: 100%;
  padding: 26px 18px 22px;
  border-radius: var(--r-md);
  text-align: center;
  color: inherit;
  background: linear-gradient(180deg, rgba(255, 255, 255, .92), rgba(246, 250, 255, .78));
  border: 1px solid rgba(255, 255, 255, .95);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 1),
    inset 0 0 0 1px rgba(0, 123, 255, .06),
    var(--shadow-contact);
  transition: transform .35s var(--ease-out), box-shadow .35s var(--ease-out);
}
.roster-agent > a:hover {
  transform: translateY(-4px);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 1),
    inset 0 0 0 1px rgba(0, 123, 255, .12),
    var(--shadow-contact),
    0 24px 48px -20px rgba(10, 30, 70, .25);
}
.roster-portrait {
  position: relative;
  width: 104px; height: 104px;
  margin-bottom: 16px;
  border-radius: 50%;
  overflow: hidden;
  /* L'anneau reste blanc : la couleur du personnage vit dans l'image. */
  box-shadow:
    0 0 0 3px var(--paper),
    0 0 0 4px rgba(0, 123, 255, .14),
    var(--shadow-contact);
}
.roster-portrait img {
  width: 100%; height: 100%;
  object-fit: cover;
  display: block;
  transition: transform .5s var(--ease-out);
}
.roster-agent > a:hover .roster-portrait img { transform: scale(1.05); }
.roster-agent b {
  font-size: var(--fs-h3);
  font-weight: 700;
  letter-spacing: -0.01em;
}
.roster-fn {
  display: block;
  margin-top: 3px;
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--accent);
}
.roster-agent p {
  margin-top: 12px;
  font-size: 0.875rem;
  line-height: 1.55;
  color: rgba(0, 0, 0, .68);
}
.roster-status {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  margin-top: auto;
  padding-top: 18px;
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.03em;
  color: rgba(0, 0, 0, .5);
}
.roster-status .pip {
  width: 7px; height: 7px;
  border-radius: 50%;
  background: rgba(0, 0, 0, .28);
}
.roster-status.is-live { color: var(--accent); }
.roster-status.is-live .pip {
  background: var(--accent);
  box-shadow: 0 0 0 0 rgba(0, 123, 255, .5);
  animation: pip-pulse 2.6s var(--ease-out) infinite;
}
@keyframes pip-pulse {
  0%   { box-shadow: 0 0 0 0 rgba(0, 123, 255, .5); }
  70%  { box-shadow: 0 0 0 7px rgba(0, 123, 255, 0); }
  100% { box-shadow: 0 0 0 0 rgba(0, 123, 255, 0); }
}

.roster-foot {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 22px;
  margin-top: clamp(36px, 4vw, 52px);
}
.roster-foot p {
  color: rgba(0, 0, 0, .68);
  font-size: 0.9375rem;
  max-width: 60ch;
}

/* ---------- Le collectif au complet (page Agents IA) ----------
   Photo de casting posée avant les fiches individuelles : on voit
   l'équipe, puis on fait connaissance un par un.

   Pas de cadre de verre ici. Le fond de l'illustration est déjà celui
   de la section (blanc en haut, bleu très pâle en bas, avec le motif
   de losanges de la marque) : l'encadrer en ferait « une image de
   l'équipe » au lieu de « l'équipe est là ». On dissout donc son
   rectangle au lieu de le souligner.

   Deux masques d'UNE seule couche chacun, et non un masque à deux
   couches sur le même élément : `mask-composite: intersect` n'est pas
   également supporté, alors que des masques imbriqués se composent
   naturellement. Le cadre porte le fondu du bas, l'image celui des
   côtés. Navigateur sans `mask-image` : le rectangle s'affiche tel
   quel, ce qui reste correct puisque son fond est déjà le bon. */
.troupe {
  margin: 0 auto clamp(36px, 5vw, 60px);
  max-width: 1000px;
}
/* Le fondu porte sur les DEUX bords horizontaux. Le fond de l'image est
   blanc en haut alors que la section y est déjà légèrement bleutée : sans
   fondu haut, le rectangle se signale par un filet net au-dessus des
   têtes. Les personnages ne commencent qu'à 27 % de la hauteur, la marge
   est donc large. */
.troupe-frame {
  display: block;
  -webkit-mask-image: linear-gradient(180deg, transparent 0, #000 12%, #000 76%, transparent 100%);
          mask-image: linear-gradient(180deg, transparent 0, #000 12%, #000 76%, transparent 100%);
}
.troupe img {
  display: block;
  width: 100%;
  height: auto;
  /* Le personnage le plus à gauche commence vers 7 % de la largeur :
     le fondu latéral s'arrête avant, il ne mange aucune épaule. */
  -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 5%, #000 95%, transparent 100%);
          mask-image: linear-gradient(90deg, transparent 0, #000 5%, #000 95%, transparent 100%);
}

/* Sur petit écran, l'illustration reprend les gouttières du conteneur :
   cinq personnages dans 342 px, ce serait cinq vignettes illisibles. */
@media (max-width: 700px) {
  .troupe { margin-inline: calc(var(--gutter) * -1); }
}

/* ---------- Fiches détaillées (page Agents IA) ---------- */
.agent-files { display: grid; gap: 22px; }
.agent-file {
  display: grid;
  grid-template-columns: 148px minmax(0, 1fr);
  gap: clamp(24px, 3vw, 40px);
  align-items: start;
  padding: clamp(28px, 3.4vw, 40px);
}
.agent-file-portrait {
  position: relative;
  width: 148px; height: 148px;
  border-radius: 50%;
  overflow: hidden;
  box-shadow:
    0 0 0 3px var(--paper),
    0 0 0 4px rgba(0, 123, 255, .14),
    var(--shadow-contact);
}
.agent-file-portrait img { width: 100%; height: 100%; object-fit: cover; display: block; }
.agent-file-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 8px 14px;
}
.agent-file-head h3 {
  font-size: clamp(1.25rem, 2vw, 1.5rem);
  font-weight: 800;
  letter-spacing: -0.02em;
}
.agent-file-head .roster-fn { margin-top: 0; }
.agent-file-head .roster-status { margin: 0 0 0 auto; padding-top: 0; }
.agent-file-claim {
  margin-top: 14px;
  font-size: var(--fs-lead);
  font-weight: 600;
  line-height: 1.45;
  letter-spacing: -0.01em;
  text-wrap: balance;
}
.agent-file .check-list { margin-top: 22px; }
.agent-file-link {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  margin-top: 22px;
  font-size: var(--fs-label);
  font-weight: 600;
  letter-spacing: 0.02em;
}
.agent-file-link:hover .arrow { transform: translateX(3px); }
.agent-file-link .arrow { transition: transform .2s var(--ease-out); }

.agent-guard {
  display: flex;
  align-items: flex-start;
  gap: 16px;
  margin-top: clamp(28px, 3.4vw, 40px);
  padding: 24px 28px;
  border-radius: var(--r-md);
  background: var(--pill-bg);
}
.agent-guard svg { color: var(--accent); flex-shrink: 0; transform: translateY(2px); }
.agent-guard p { color: rgba(0, 0, 0, .74); font-size: 0.9375rem; }
.agent-guard b { font-weight: 700; }

@media (prefers-reduced-motion: reduce) {
  .roster-status.is-live .pip { animation: none; }
}

/* ============================================================
   LA CONSTELLATION DES AGENTS (accueil)
   ------------------------------------------------------------
   Vingt disques de verre posés sur une sphère : les cinq agents
   et les quinze pièces qu'ils traitent. L'agent et sa matière
   sont dans le même objet, on voit l'orchestration au lieu de
   la lire.

   Pourquoi du CSS 3D et pas un canvas : les nœuds sont des
   <button> du DOM, donc le clavier, le lecteur d'écran et le
   rendu Montserrat sont gratuits. Un canvas en aurait fait une
   boîte noire pour l'accessibilité.

   Le masquage est conditionné à `html.js`, comme les révélations
   au scroll : sans JavaScript la constellation n'existe pas et
   la liste .roster reste servie. Ne pas retirer cette garde,
   la section deviendrait vide en impression et sans script.
   ============================================================ */
.constellation { display: none; }
html.js .constellation { display: block; }
html.js .roster { display: none; }

/* ---------- Le bandeau de filtres ----------
   Mêmes chips que le blog (des boutons, l'URL ne bouge pas, un
   re-clic relâche). Sous 640px la rangée défile horizontalement
   plutôt que de passer sur trois lignes. */
.constellation-filters {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin-bottom: clamp(28px, 3.4vw, 44px);
}

/* ---------- La mise en page : sphère + panneau ---------- */
.constellation-body {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 380px;
  gap: clamp(32px, 4vw, 56px);
  align-items: center;
}

/* ---------- Le plateau ----------
   `perspective` ici et `preserve-3d` sur la sphère : la
   profondeur est calculée par le compositeur, pas par nous.
   L'aspect carré évite que la sphère s'ovalise. */
.constellation-stage {
  position: relative;
  width: 100%;
  max-width: 520px;
  margin-inline: auto;
  aspect-ratio: 1;
  perspective: 1100px;
  touch-action: pan-y;          /* le défilement vertical reste au navigateur */
  cursor: grab;
}
.constellation-stage.is-dragging { cursor: grabbing; }
/* Pendant le glissé, le curseur ne redevient pas une main pointée au
   survol d'un disque : on manipule la sphère, on ne vise pas. */
.constellation-stage.is-dragging .cnode { cursor: grabbing; }

.constellation-mesh {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
}

.constellation-sphere {
  position: absolute;
  inset: 0;
  transform-style: preserve-3d;
}

/* ---------- Le panneau ----------
   Hauteur minimale figée : sans elle, passer d'une fiche à
   l'autre ferait sauter la page de plusieurs dizaines de pixels. */
.constellation-panel {
  padding: 28px 30px 30px;
  min-height: 340px;
  display: flex;
  align-items: center;
}
.cpanel-body { width: 100%; }
.cpanel-rest {
  color: rgba(0, 0, 0, .58);
  font-size: 0.9375rem;
  line-height: 1.55;
}

/* ---------- Les nœuds ----------
   Des disques de verre, pas des icônes dans des ronds : chacun porte
   soit un portrait, soit une vraie pièce du quotidien avec sa donnée.
   Aucune rotation propre n'est appliquée, ils font donc face à la
   caméra en permanence et restent lisibles sur les 360°. */
.cnode {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 96px;
  height: 96px;
  margin: -48px 0 0 -48px;
  padding: 0 8px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 1px;
  border: 1px solid rgba(255, 255, 255, .95);
  border-radius: 50%;
  background: linear-gradient(180deg, rgba(255, 255, 255, .96), rgba(242, 246, 251, .88));
  box-shadow:
    inset 0 1.5px 0 rgba(255, 255, 255, 1),
    inset 0 0 0 1px rgba(0, 123, 255, .10),
    0 10px 22px -12px rgba(10, 30, 70, .40);
  font-family: var(--font);
  text-align: center;
  cursor: pointer;
  overflow: hidden;
  /* Gestes tactiles : sans ces trois lignes, un appui prolongé sur un
     portrait ouvre le menu système iOS (« Copier l'image »), le libellé
     se surligne au moindre glissé, et un halo bleu clignote à chaque tap.
     Les trois se voient et donnent une impression de page cassée. */
  -webkit-tap-highlight-color: transparent;
  -webkit-touch-callout: none;
  -webkit-user-select: none;
  user-select: none;
  /* Pas de transition sur `transform` : la position vient de la boucle
     de rendu, une transition la ferait traîner d'une image sur l'autre.
     Le grossissement au survol est donc lissé PAR LA BOUCLE (site.js,
     HOVER_K / LIFT_Z), pas ici · il partage la même propriété que la
     position, on ne peut pas animer l'un sans traîner l'autre. */
  transition: box-shadow .2s var(--ease-out), filter .3s var(--ease-out);
}
.cnode:hover { box-shadow: inset 0 0 0 1px rgba(0, 123, 255, .45), 0 14px 26px -12px rgba(10, 30, 70, .48); }
.cnode:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }

.cnode-agent { padding: 0; }
.cnode-agent img {
  pointer-events: none;          /* la cible d'un geste est le bouton, jamais l'image */
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.cnode-label {
  position: relative;
  align-self: stretch;
  margin-top: auto;
  padding: 12px 4px 5px;
  background: linear-gradient(180deg, rgba(255, 255, 255, 0), rgba(255, 255, 255, .92) 55%);
  font-size: 0.6875rem;
  font-weight: 800;
  letter-spacing: .02em;
}

.cnode-k {
  color: var(--accent);
  font-size: 0.4375rem;
  font-weight: 700;
  letter-spacing: .07em;
  text-transform: uppercase;
  line-height: 1.2;
}
.cnode-t { font-size: 0.6875rem; font-weight: 800; line-height: 1.15; }
.cnode-v { color: rgba(0, 0, 0, .62); font-size: 0.625rem; font-weight: 600; }

/* Estompé, pas retiré : la sphère garde sa forme, ce qui est tout
   l'effet. L'opacité elle-même est posée par la boucle de rendu, qui
   la compose avec la profondeur. */
.cnode.is-dim { filter: saturate(0); pointer-events: none; }
.cnode.is-picked { box-shadow: inset 0 0 0 2px var(--accent), 0 14px 26px -12px rgba(10, 30, 70, .5); }

/* ---------- Le panneau : contenu ---------- */
.cpanel-body { transition: opacity .2s var(--ease-out); }
.cpanel-body.is-swapping { opacity: 0; }
.cpanel-head { display: flex; align-items: center; gap: 12px; margin-bottom: 16px; }
.cpanel-portrait {
  width: 56px; height: 56px; flex-shrink: 0;
  border-radius: 50%; overflow: hidden;
  border: 2px solid var(--paper);
  box-shadow: var(--shadow-contact);
}
.cpanel-portrait img { width: 100%; height: 100%; object-fit: cover; display: block; }
.cpanel-head > span:nth-child(2) { display: flex; flex-direction: column; }
.cpanel-head b { font-size: 1.125rem; font-weight: 800; }
.cpanel-head .roster-fn { margin-top: 2px; }
.cpanel-head .roster-status { margin: 0 0 0 auto; padding-top: 0; align-self: flex-start; }
.cpanel-claim {
  font-size: 0.9375rem;
  font-weight: 700;
  line-height: 1.45;
  padding-bottom: 14px;
  border-bottom: 1px solid rgba(0, 0, 0, .08);
}
.cpanel-pts { margin-top: 14px; display: grid; gap: 12px; }
.cpanel-pts b { display: block; font-size: 0.8125rem; font-weight: 800; }
.cpanel-pts p { margin-top: 3px; color: rgba(0, 0, 0, .66); font-size: 0.8125rem; line-height: 1.5; }
.constellation-panel .agent-file-link { margin-top: 18px; }

/* ---------- Paliers ----------
   Sous 1021px le panneau passe dessous : à 380px de colonne, il
   ne reste pas assez de largeur pour que la sphère respire. */
@media (max-width: 1020px) {
  .constellation-body { grid-template-columns: 1fr; }
  .constellation-stage { max-width: 420px; }
  .constellation-panel { min-height: 0; }
}
@media (max-width: 639px) {
  .constellation-stage { max-width: 300px; }
  .cnode { width: 86px; height: 86px; margin: -43px 0 0 -43px; }
  .cnode-t { font-size: 0.6875rem; }
  .constellation-filters {
    flex-wrap: nowrap;
    overflow-x: auto;
    scrollbar-width: none;
    margin-inline: calc(var(--gutter) * -1);
    padding-inline: var(--gutter);
  }
  .constellation-filters::-webkit-scrollbar { display: none; }
  .constellation-filters .chip { flex: 0 0 auto; }
  .constellation-panel { padding: 22px 20px 24px; }
}

/* ============================================================
   TARIFS
   ============================================================ */
.scene-pricing { background: linear-gradient(180deg, var(--pale) 0%, var(--paper) 40%); }
.pricing-toggle {
  display: inline-flex;
  align-items: center;
  gap: 0;
  position: relative;
  margin-top: 26px;
  padding: 4px;
  border-radius: var(--r-pill);
  background: rgba(0, 123, 255, .08);
}
.pricing-toggle button {
  position: relative;
  z-index: 1;
  min-width: 104px;
  padding: 10px 22px;
  border-radius: var(--r-pill);
  font-size: var(--fs-label);
  font-weight: 600;
  letter-spacing: 0.02em;
  color: rgba(0, 0, 0, .6);
  transition: color .25s var(--ease-out);
}
.pricing-toggle button[aria-pressed="true"] { color: #fff; }
.pricing-toggle .thumb {
  position: absolute;
  top: 4px; bottom: 4px; left: 0;
  border-radius: var(--r-pill);
  background: var(--accent);
  box-shadow: 0 4px 12px -4px rgba(0, 123, 255, .6);
  transition: transform .3s var(--ease-out);
}
/* Promotion en couche seulement pendant l'interaction : un will-change
   permanent garde une texture GPU vivante pour rien tout le reste du temps. */
.pricing-toggle:hover .thumb,
.pricing-toggle:focus-within .thumb { will-change: transform; }
.save-badge {
  margin-left: 14px;
  font-size: var(--fs-label);
  font-weight: 700;
  color: var(--accent);
  white-space: nowrap;
}

.plans {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 22px;
  align-items: stretch;
  margin-top: clamp(40px, 5vw, 56px);
}
.plan {
  display: flex;
  flex-direction: column;
  padding: 30px 28px;
}
.plan.featured {
  box-shadow:
    inset 0 1.5px 0 rgba(255, 255, 255, 1),
    inset 0 0 0 1.5px rgba(0, 123, 255, .35),
    inset 0 -12px 28px -18px rgba(0, 123, 255, .4),
    var(--shadow-contact),
    0 40px 80px -36px rgba(0, 123, 255, .45);
}
.plan-head { display: flex; align-items: center; gap: 12px; margin-bottom: 20px; }
.plan-head .plan-icon {
  width: 44px; height: 44px;
  border-radius: var(--r-md);
  display: grid;
  place-items: center;
  color: var(--accent);
  background: var(--pill-bg);
}
.plan-head b { display: block; font-size: 1.25rem; font-weight: 800; letter-spacing: -0.01em; color: var(--ink); }
.plan-head span { display: block; font-size: 0.8125rem; color: rgba(0, 0, 0, .55); }
.plan-price { display: flex; align-items: baseline; gap: 10px; margin-bottom: 24px; }
.plan-price em {
  font-style: normal;
  font-size: clamp(2rem, 3vw, 2.5rem);
  font-weight: 800;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
  color: var(--accent);
}
.plan-price span { font-size: 0.875rem; line-height: 1.35; color: rgba(0, 0, 0, .55); }
/* La périodicité tient sur deux lignes à droite du prix : « par mois HT »
   ne bouge pas, la mention d'engagement est ce que la bascule échange. */
.plan-price span i { display: block; font-style: normal; }
.plan-ideal {
  font-size: 0.8125rem;
  line-height: 1.5;
  color: rgba(0, 0, 0, .68);
  background: rgba(0, 123, 255, .05);
  border-radius: var(--r-sm);
  padding: 12px 14px;
  /* Dernier bloc de la carte : il se cale en bas pour que les trois
     encadrés s'alignent malgré des listes de longueurs différentes. */
  margin-top: auto;
}
/* Mention de mise en service : elle sort des cartes et se pose sous la
   grille. Un prix d'abonnement qui tait un frais obligatoire se paie en
   confiance au devis ; la note l'annonce sans afficher de montant, celui-ci
   dépendant du volume à reprendre (CGV art. 3.6). */
.pricing-note {
  margin: clamp(20px, 2.5vw, 28px) auto 0;
  max-width: 68ch;
  text-align: center;
  font-size: 0.875rem;
  line-height: 1.55;
  color: rgba(0, 0, 0, .55);
}
.plan-features {
  display: grid;
  gap: 12px;
  border-top: 1px solid rgba(0, 123, 255, .12);
  padding-top: 18px;
  margin-bottom: 18px;
  font-size: 0.875rem;
  line-height: 1.45;
}
.plan-features li { display: flex; align-items: flex-start; gap: 10px; }
.plan-features svg { flex-shrink: 0; color: var(--accent); margin-top: 3px; }
.plan-features b { font-weight: 700; }

/* ============================================================
   FAQ
   ============================================================ */
.scene-faq { background: var(--paper); }
.faq-list { max-width: 780px; margin-inline: auto; }
.faq-item { border-bottom: 1px solid rgba(0, 0, 0, .08); }
.faq-q {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
  text-align: left;
  padding: 22px 0;
  font-size: 1.0625rem;
  font-weight: 600;
  letter-spacing: -0.01em;
  transition: color .2s var(--ease-out);
}
.faq-q:hover { color: var(--accent); }
.faq-q .cross {
  position: relative;
  width: 22px; height: 22px;
  flex-shrink: 0;
}
.faq-q .cross::before, .faq-q .cross::after {
  content: "";
  position: absolute;
  top: 50%; left: 50%;
  background: var(--accent);
  border-radius: 2px;
  transition: transform .3s var(--ease-out);
}
.faq-q .cross::before { width: 14px; height: 2px; transform: translate(-50%, -50%); }
.faq-q .cross::after { width: 2px; height: 14px; transform: translate(-50%, -50%); }
.faq-item.open .faq-q .cross::after { transform: translate(-50%, -50%) rotate(90deg); }
.faq-item.open .faq-q { color: var(--accent); }
.faq-a {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows .35s var(--ease-out);
}
.faq-a > div { overflow: hidden; }
.faq-a p {
  padding: 0 44px 22px 0;
  color: rgba(0, 0, 0, .68);
  max-width: 68ch;
}
.faq-item.open .faq-a { grid-template-rows: 1fr; }

/* ============================================================
   CTA FINAL
   ============================================================ */
.scene-cta {
  position: relative;
  overflow: hidden;
  background: linear-gradient(180deg, var(--paper) 0%, var(--pale) 100%);
  text-align: center;
}
.cta-mesh {
  position: absolute;
  inset: 0;
  width: 100%; height: 100%;
  pointer-events: none;
}
.scene-cta .container { position: relative; }
.scene-cta .kicker { justify-content: center; }
.scene-cta .kicker::before { display: none; }
.scene-cta .h2 {
  margin: 18px auto 34px;
  max-width: 640px;
}
.cta-actions { display: flex; justify-content: center; flex-wrap: wrap; gap: 10px; }
/* Sous les deux boutons du bloc final : qui a fait défiler toute la page
   sans cliquer préfère parfois appeler. Le numéro est écrit en clair, pas
   caché derrière un « Nous contacter ». */
.cta-tel {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  margin-top: 22px;
  font-size: 1.0625rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: var(--ink);
  transition: color .2s var(--ease-out);
}
.cta-tel svg { color: var(--accent); flex-shrink: 0; }
.cta-tel span { font-weight: 500; color: rgba(0, 0, 0, .6); }
.cta-tel:hover { color: var(--accent); }

/* ============================================================
   SOUTIENS
   ============================================================ */
.scene-backers { background: var(--paper); }
.backers {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 22px;
  max-width: 920px;
  margin-inline: auto;
}
.backer {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 16px;
  padding: 30px;
}
.backer img { height: 44px; width: auto; object-fit: contain; }
.backer b { font-size: var(--fs-h3); font-weight: 700; letter-spacing: -0.01em; }
.backer p { font-size: 0.9375rem; color: rgba(0, 0, 0, .68); }
.backer a {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: var(--fs-label);
  font-weight: 600;
  letter-spacing: 0.02em;
}
.backer a:hover .arrow { transform: translateX(3px); }
.backer .arrow { transition: transform .2s var(--ease-out); }

/* ============================================================
   ÉQUIPE
   ============================================================ */
.scene-team { background: linear-gradient(180deg, var(--paper) 0%, var(--surface) 100%); }
.team {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 22px;
  max-width: 920px;
  margin-inline: auto;
}
.member { text-align: center; }
.member .portrait {
  position: relative;
  width: min(100%, 240px);
  margin: 0 auto 18px;
  border-radius: var(--r-md);
  overflow: hidden;
  box-shadow: var(--shadow-contact), var(--shadow-depth);
}
.member .portrait img {
  width: 100%;
  aspect-ratio: 4 / 5;
  object-fit: cover;
  transition: transform .5s var(--ease-out);
}
.member:hover .portrait img { transform: scale(1.035); }
.member b { display: block; font-size: var(--fs-h3); font-weight: 700; }
.member span { display: block; font-size: 0.875rem; color: rgba(0, 0, 0, .6); margin: 2px 0 10px; }
.member .li-link {
  display: inline-grid;
  place-items: center;
  width: 34px; height: 34px;
  border-radius: var(--r-sm);
  color: var(--accent);
  background: var(--pill-bg);
  transition: background-color .2s var(--ease-out), color .2s var(--ease-out);
}
.member .li-link:hover { background: var(--accent); color: #fff; }

/* ============================================================
   FOOTER
   ============================================================ */
.footer {
  background: linear-gradient(180deg, var(--surface) 0%, var(--pale) 100%);
  padding: clamp(56px, 7vw, 88px) 0 28px;
  border-top: 1px solid rgba(0, 123, 255, .08);
}
.footer-grid {
  display: grid;
  grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr) minmax(0, 1fr);
  gap: clamp(32px, 5vw, 64px);
  margin-bottom: 48px;
}
.footer-brand img { height: 30px; width: auto; margin-bottom: 14px; }
.footer-brand p { font-size: 0.9375rem; color: rgba(0, 0, 0, .6); max-width: 30ch; }
.footer h3 {
  font-size: var(--fs-label);
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  margin-bottom: 18px;
}
.footer-col li { margin-bottom: 12px; }
.footer-col a, .footer-col .line {
  display: inline-flex;
  align-items: flex-start;
  gap: 10px;
  color: rgba(0, 0, 0, .72);
  font-size: 0.9375rem;
}
.footer-col a:hover { color: var(--accent); }
.footer-col svg { color: var(--accent); flex-shrink: 0; transform: translateY(3px); }
.footer-bottom {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding-top: 24px;
  border-top: 1px solid rgba(0, 0, 0, .08);
  font-size: 0.8125rem;
  color: rgba(0, 0, 0, .55);
}
.footer-legal { display: flex; flex-wrap: wrap; gap: 20px; }
.footer-legal a { color: rgba(0, 0, 0, .55); }
.footer-legal a:hover { color: var(--accent); }

/* ============================================================
   PAGE AGENTS IA
   ============================================================ */
/* Chapeau des onglets : annonce la bascule « fiches » → « détail ». */
.subnav-intro {
  background: linear-gradient(180deg, var(--pale) 0%, var(--paper) 100%);
  padding-top: clamp(72px, 9vw, 112px);
}
.subnav-intro .section-head { margin-bottom: clamp(28px, 3.4vw, 40px); }

.subnav {
  position: sticky;
  top: 78px;
  z-index: 50;
  display: flex;
  justify-content: center;
  padding: 0 var(--gutter);
  pointer-events: none;
}
.subnav-inner {
  pointer-events: auto;
  display: inline-flex;
  gap: 4px;
  padding: 5px;
  border-radius: var(--r-pill);
  background: rgba(255, 255, 255, .8);
  -webkit-backdrop-filter: blur(16px);
  backdrop-filter: blur(16px);
  border: 1px solid rgba(255, 255, 255, .95);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 1), var(--shadow-contact);
}
.subnav [role="tab"] {
  padding: 9px 18px;
  border-radius: var(--r-pill);
  font-size: var(--fs-label);
  font-weight: 600;
  letter-spacing: 0.02em;
  color: rgba(0, 0, 0, .65);
  white-space: nowrap;
  transition: color .25s var(--ease-out), background-color .25s var(--ease-out);
}
.subnav [role="tab"]:hover { color: var(--accent); background: rgba(0, 123, 255, .08); }
.subnav [role="tab"][aria-selected="true"] {
  color: #fff;
  background: var(--accent);
  box-shadow: 0 4px 12px -4px rgba(0, 123, 255, .6);
}

/* L'onglet porte l'agent : portrait rond, prénom, fonction. Le visiteur
   vient de croiser Flo et Agathe dans le casting, il les reconnaît avant
   de lire l'intitulé. Le padding gauche se resserre pour que le disque
   affleure le bord de la pilule. */
.subnav [role="tab"] {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 6px 18px 6px 6px;
  text-align: left;
}
.subnav [role="tab"] img {
  flex: none;
  width: 38px;
  height: 38px;
  border-radius: 50%;
  object-fit: cover;
  /* L'anneau reste blanc, sur fond clair comme sur l'accent : le pastel
     du portrait ne sort jamais de son disque (direction branding § 9). */
  box-shadow: 0 0 0 2px #fff;
}
.tab-id {
  display: grid;
  gap: 1px;
  line-height: 1.2;
}
.tab-id b {
  font-size: 0.875rem;
  font-weight: 700;
  letter-spacing: -0.01em;
}
.tab-id > span {
  font-size: 0.75rem;
  font-weight: 500;
  color: rgba(0, 0, 0, .55);
}
/* Sur l'accent, la fonction repasse en blanc plein : la teinter
   l'amènerait sous le seuil de lisibilité au lieu de le frôler. */
.subnav [role="tab"][aria-selected="true"] .tab-id > span { color: #fff; }
.subnav [role="tab"]:hover .tab-id > span { color: inherit; }

/* ---------- Ouverture d'un panneau : l'agent entre en scène ----------
   Le visiteur vient de cliquer sur un portrait rond de 38 px : la scène
   le lui rend en grand, au travail, avant le premier argument. C'est
   aussi ce qui distingue les deux panneaux au moment de la bascule.

   Pas de cadre de verre autour de l'image : la scène a déjà ses propres
   panneaux de verre à l'intérieur, en encadrer un deuxième les mettrait
   en concurrence. Un simple coin arrondi, l'ombre de contact et l'ombre
   de profondeur, comme les vignettes de la galerie. `.scene-shot` porte
   ce traitement, ici comme dans la séquence d'analyse plus bas. */
.scene-shot {
  margin: 0;
  border-radius: var(--r-md);
  overflow: hidden;
  box-shadow: var(--shadow-contact), var(--shadow-depth);
}
.scene-shot img {
  display: block;
  width: 100%;
  height: auto;
}
/* Séquence de scènes en escalier. `.module` alterne l'ORDRE mais pas les
   largeurs de colonnes : un rang pair rendait donc sa scène dans la
   colonne étroite (.9fr), soit 100 px de moins que ses voisines. Ici les
   trois scènes portent le même poids, on inverse aussi les largeurs. */
.showcase-scenes .module:nth-child(even) {
  grid-template-columns: minmax(0, 1.1fr) minmax(0, .9fr);
}

.agent-stage-section { background: var(--paper); padding-bottom: 0; }
.agent-stage {
  display: grid;
  grid-template-columns: minmax(0, 1.2fr) minmax(0, .8fr);
  gap: clamp(32px, 4.5vw, 64px);
  align-items: center;
}
.agent-stage-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 8px 14px;
}
.agent-stage-head h2 {
  font-size: var(--fs-h2);
  font-weight: 800;
  letter-spacing: -0.03em;
  line-height: 1.05;
}
.agent-stage-head .roster-fn { margin-top: 0; }
.agent-stage-head .roster-status { margin-top: 0; padding-top: 0; }
.agent-stage-claim {
  margin-top: 18px;
  font-size: var(--fs-lead);
  font-weight: 600;
  line-height: 1.45;
  letter-spacing: -0.01em;
  text-wrap: balance;
}
.agent-stage-note {
  margin-top: 14px;
  color: rgba(0, 0, 0, .68);
  max-width: 46ch;
}

/* Panneau d'onglet : le contenu s'échange sur place, sans défilement. */
.agent-panel[hidden] { display: none; }
.agent-panel { animation: panel-in .4s var(--ease-out) both; }
@keyframes panel-in {
  from { opacity: 0; transform: translateY(10px); }
  to { opacity: 1; transform: none; }
}
@media (prefers-reduced-motion: reduce) {
  .agent-panel { animation: none; }
}

.gallery {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 14px;
  margin-top: clamp(36px, 5vw, 56px);
}
.gallery figure {
  margin: 0;
  border-radius: var(--r-md);
  overflow: hidden;
  box-shadow: var(--shadow-contact), var(--shadow-depth);
}
.gallery img {
  width: 100%;
  aspect-ratio: 3 / 4;
  object-fit: cover;
  transition: transform .5s var(--ease-out);
}
.gallery figure:hover img { transform: scale(1.04); }

.check-list { display: grid; gap: 16px; }
.check-list li { display: flex; align-items: flex-start; gap: 14px; }
/* Sans min-width, un mot long refuse de se couper et pousse la colonne */
.check-list li > span:last-child { min-width: 0; }
.check-list .ck {
  flex-shrink: 0;
  width: 24px; height: 24px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  background: var(--accent);
  color: #fff;
  transform: translateY(2px);
  box-shadow: 0 4px 10px -4px rgba(0, 123, 255, .6);
}
.check-list b { font-weight: 700; }
.check-list p { color: rgba(0, 0, 0, .68); font-size: 0.9375rem; margin-top: 2px; }

.agent-cta {
  text-align: center;
  padding: clamp(48px, 6vw, 72px) 32px;
}
.agent-cta .h2 { max-width: 620px; margin-inline: auto; }
.agent-cta p { margin: 16px auto 30px; color: rgba(0, 0, 0, .68); max-width: 56ch; }

.video-frame {
  margin: 0;              /* c'est une <figure> : la marge par défaut casserait le cadre */
  padding: 10px;
  border-radius: var(--r-md);
}
.video-frame video {
  border-radius: var(--r-sm);
  width: 100%;
  height: auto;
  display: block;
}

/* ============================================================
   BLOG — index
   ============================================================ */
.container-post { max-width: 760px; }

.blog-head {
  position: relative;
  overflow: hidden;
  padding: clamp(140px, 17vh, 200px) 0 clamp(48px, 6vw, 72px);
  background: linear-gradient(180deg, #FFFFFF 0%, var(--surface) 60%, var(--pale) 100%);
}
.blog-head .container { position: relative; }
.blog-head .data-pill { margin-bottom: 20px; }
.blog-head .display { margin-bottom: 16px; }
.blog-list { background: var(--paper); padding-top: clamp(48px, 6vw, 72px); }

/* Billet mis en avant */
.post-hero {
  display: grid;
  grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr);
  gap: clamp(24px, 3vw, 40px);
  align-items: center;
  padding: 18px;
  margin-bottom: clamp(48px, 6vw, 72px);
  color: var(--ink);
  transition: transform .35s var(--ease-out);
}
.post-hero:hover { transform: translateY(-3px); }
.post-hero-media { border-radius: var(--r-sm); overflow: hidden; }
.post-hero-media img {
  width: 100%;
  aspect-ratio: 1200 / 630;
  object-fit: cover;
  transition: transform .6s var(--ease-out);
}
.post-hero:hover .post-hero-media img { transform: scale(1.03); }
.post-hero-body { padding-right: 10px; }
.post-hero-body h2 {
  font-size: clamp(1.35rem, 2.4vw, 1.875rem);
  font-weight: 800;
  line-height: 1.2;
  letter-spacing: -0.015em;
  margin: 14px 0 12px;
  text-wrap: balance;
}
.post-hero-body p {
  color: rgba(0, 0, 0, .68);
  font-size: 0.9375rem;
  margin-bottom: 18px;
}

/* Grille des billets */
.post-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 28px;
}
.post-card a { display: block; color: var(--ink); }
.post-card-media {
  display: block;
  border-radius: var(--r-md);
  overflow: hidden;
  margin-bottom: 18px;
  box-shadow: var(--shadow-contact);
}
.post-card-media img {
  width: 100%;
  aspect-ratio: 3 / 2;
  object-fit: cover;
  transition: transform .6s var(--ease-out);
}
.post-card a:hover .post-card-media img { transform: scale(1.04); }
.post-card :is(h2, h3) {
  font-size: 1.0625rem;
  font-weight: 700;
  line-height: 1.35;
  letter-spacing: -0.01em;
  margin-bottom: 8px;
  text-wrap: balance;
  transition: color .2s var(--ease-out);
}
.post-card a:hover :is(h2, h3) { color: var(--accent); }
.post-card p {
  font-size: 0.875rem;
  color: rgba(0, 0, 0, .66);
  margin-bottom: 14px;
}
.post-meta {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 0.8125rem;
  color: rgba(0, 0, 0, .58);
}
.post-meta img { border-radius: 50%; object-fit: cover; flex-shrink: 0; }

/* ---------- Filtres du blog : secteur et sujet ----------
   Le filtre est un CONFORT, pas un chemin. Sans JavaScript la barre
   n'apparaît pas et la liste complète reste servie : aucun billet ne
   devient inatteignable, et le filtrage ne fabrique aucune URL. */
.filter-bar { display: none; }
html.js .filter-bar {
  display: flex;
  flex-direction: column;
  gap: 12px;
  margin-bottom: clamp(24px, 3vw, 32px);
}
.filter-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
}
.filter-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}
.filter-label {
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: rgba(0, 0, 0, .38);
  /* Largeur fixe : les deux rangées alignent leurs premières pastilles,
     sinon « Secteur » et « Sujet » décalent l'une par rapport à l'autre. */
  min-width: 76px;
}
.chip {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 8px 16px;
  border: 1px solid rgba(0, 0, 0, .12);
  border-radius: var(--r-pill);
  background: transparent;
  font-family: inherit;
  font-size: var(--fs-label);
  font-weight: 600;
  letter-spacing: 0.02em;
  color: rgba(0, 0, 0, .7);
  cursor: pointer;
  transition: background .2s var(--ease-out), color .2s var(--ease-out),
              border-color .2s var(--ease-out);
}
.chip:hover { border-color: var(--accent); color: var(--accent); }
.chip[aria-pressed="true"] {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--paper);
}
.chip-n {
  font-size: 0.75rem;
  font-weight: 700;
  opacity: .55;
  font-variant-numeric: tabular-nums;
}
.chip[aria-pressed="true"] .chip-n { opacity: .8; }
.filter-count {
  font-size: var(--fs-label);
  color: rgba(0, 0, 0, .5);
  margin: 0 0 clamp(24px, 3vw, 32px);
  min-height: 1.2em;
}
.filter-empty {
  font-size: var(--fs-body);
  color: rgba(0, 0, 0, .6);
  margin: 0 0 clamp(32px, 4vw, 48px);
}
.filter-reset {
  border: 0;
  padding: 0;
  background: none;
  font: inherit;
  font-weight: 600;
  color: var(--accent);
  cursor: pointer;
  text-decoration: underline;
}

@media (max-width: 640px) {
  /* Sur téléphone, l'étiquette d'axe passe au-dessus de ses pastilles (en
     ligne, elle mange la largeur d'une pastille sur deux) et la rangée
     défile horizontalement. Empilées, les dix pastilles occupaient plus de
     la moitié de l'écran avant le premier article. */
  .filter-row { display: block; }
  .filter-label { display: block; min-width: 0; margin-bottom: 8px; }
  .filter-chips {
    flex-wrap: nowrap;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
    /* La rangée saigne jusqu'aux bords de l'écran : une pastille coupée au
       bord est ce qui dit qu'il y en a d'autres à côté. */
    margin: 0 calc(var(--gutter) * -1);
    padding: 2px var(--gutter) 6px;
  }
  .filter-chips::-webkit-scrollbar { display: none; }
  .filter-chips .chip { flex: 0 0 auto; }
}

/* Badge porté par une carte. Volontairement PAS un lien : il vit à
   l'intérieur du lien du billet, où un second lien serait invalide. */
.sector-tag {
  display: block;
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--accent);
  margin-bottom: 8px;
}
.post-hero-body .sector-tag { margin: 14px 0 0; }
/* Badge vide : il ne dit rien, il tient la ligne pour que les titres
   s'alignent entre un billet classé et un billet qui ne l'est pas. */
.sector-tag:empty { height: 1.2em; }

/* `hidden` doit battre les display du composant : sans ces règles, une
   carte filtrée resterait affichée (display:grid l'emporte sur le
   display:none par défaut de l'attribut). */
.post-card[hidden], .post-hero[hidden] { display: none !important; }

.crumb-sector { color: rgba(0, 0, 0, .45); }
.blog-head .breadcrumb { margin-bottom: 18px; }
.sector-body {
  margin: 0 0 clamp(40px, 5vw, 60px);
  font-size: 1.0625rem;
  color: rgba(0, 0, 0, .78);
}
/* Le reset global annule les marges de <p> : sans cette règle, les
   paragraphes du chapô se collent en un seul pavé. */
.sector-body p + p { margin-top: 1em; }
.sector-back {
  margin-top: clamp(40px, 5vw, 56px);
  font-weight: 600;
  font-size: var(--fs-label);
}
.sector-back a { color: var(--accent); }
.sector-back a:hover { text-decoration: underline; }

@media (prefers-reduced-motion: reduce) {
  .chip { transition: none; }
}

/* ============================================================
   BLOG — billet
   ============================================================ */
.post-head {
  padding: clamp(130px, 15vh, 178px) 0 clamp(28px, 3vw, 40px);
  background: linear-gradient(180deg, #FFFFFF 0%, var(--surface) 100%);
}
.breadcrumb {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: var(--fs-label);
  font-weight: 600;
  letter-spacing: 0.02em;
  margin-bottom: 22px;
  color: rgba(0, 0, 0, .45);
}
.breadcrumb a { color: var(--accent); }
.breadcrumb a:hover { text-decoration: underline; }
.post-head .display {
  font-size: clamp(2rem, 4.2vw, 2.875rem);
  margin-bottom: 18px;
}
.post-summary { max-width: 660px; color: rgba(0, 0, 0, .7); }

.post-byline {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 14px;
  margin-top: 30px;
  padding-top: 24px;
  border-top: 1px solid rgba(0, 123, 255, .12);
}
.post-byline > img { border-radius: 50%; object-fit: cover; }
.post-byline b { display: block; font-weight: 700; font-size: 0.9375rem; }
.post-byline b a { color: var(--ink); }
.post-byline b a:hover { color: var(--accent); }
.post-byline > span > span { font-size: 0.8125rem; color: rgba(0, 0, 0, .55); }
.post-byline-meta {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-left: auto;
  font-size: 0.8125rem;
  color: rgba(0, 0, 0, .55);
}

.post-cover {
  margin: 0 0 clamp(40px, 5vw, 64px);
  border-radius: var(--r-md);
  overflow: hidden;
  box-shadow: var(--shadow-contact), var(--shadow-depth);
}
.post-cover img {
  width: 100%;
  aspect-ratio: 1200 / 630;
  object-fit: cover;
}

/* Sommaire (billets longs) */
.post-toc {
  padding: 22px 26px;
  margin-bottom: clamp(36px, 4vw, 52px);
  border-radius: var(--r-md);
  background: rgba(0, 123, 255, .045);
  border: 1px solid rgba(0, 123, 255, .12);
}
.post-toc h2 {
  font-size: var(--fs-label);
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  margin-bottom: 14px;
}
.post-toc ol { counter-reset: toc; display: grid; gap: 9px; }
.post-toc li { counter-increment: toc; display: flex; gap: 12px; font-size: 0.9375rem; }
.post-toc li::before {
  content: counter(toc, decimal-leading-zero);
  color: var(--accent);
  font-weight: 700;
  font-size: 0.8125rem;
  flex-shrink: 0;
  padding-top: 2px;
}
.post-toc a { color: var(--ink); }
.post-toc a:hover { color: var(--accent); }

/* Corps de l'article. L'aération entre un H2 et le paragraphe qui suit est
   une exigence explicite du projet : elle se règle ici, jamais à coups de
   paragraphes vides dans le markdown. */
.post-body { font-size: 1.0625rem; line-height: 1.75; }
.post-body > * + * { margin-top: 22px; }
.post-body h2 {
  font-size: clamp(1.375rem, 2.4vw, 1.75rem);
  font-weight: 800;
  line-height: 1.22;
  letter-spacing: -0.015em;
  margin-top: 64px;
  margin-bottom: 20px;
  text-wrap: balance;
  scroll-margin-top: 96px;
}
.post-body h3 {
  font-size: 1.1875rem;
  font-weight: 700;
  line-height: 1.35;
  margin-top: 40px;
  margin-bottom: 14px;
  scroll-margin-top: 96px;
}
.post-body h2 + *, .post-body h3 + * { margin-top: 0; }
.post-body p { color: rgba(0, 0, 0, .82); }
.post-body a { text-decoration: underline; text-underline-offset: 3px; }
.post-body a:hover { color: var(--accent-deep); }
.post-body strong { font-weight: 700; color: var(--ink); }
.post-body ul, .post-body ol { display: grid; gap: 11px; padding-left: 4px; }
.post-body li { color: rgba(0, 0, 0, .82); padding-left: 26px; position: relative; }
.post-body ul li::before {
  content: "";
  position: absolute;
  left: 4px; top: 12px;
  width: 7px; height: 7px;
  border-radius: 50%;
  background: var(--accent);
}
.post-body ol { counter-reset: li; }
.post-body ol li { counter-increment: li; }
.post-body ol li::before {
  content: counter(li) ".";
  position: absolute;
  left: 0;
  color: var(--accent);
  font-weight: 700;
}
.post-body blockquote {
  margin: 34px 0;
  padding: 22px 26px;
  border-radius: var(--r-md);
  background: rgba(0, 123, 255, .05);
}
.post-body blockquote p {
  font-size: 1.125rem;
  font-weight: 600;
  line-height: 1.5;
  color: var(--ink);
}
.post-body figure { margin: 34px 0; }
.post-body figure img {
  width: 100%;
  border-radius: var(--r-md);
  box-shadow: var(--shadow-contact);
}
.post-body hr {
  border: 0;
  height: 1px;
  background: rgba(0, 0, 0, .1);
  margin: 44px 0;
}
.post-body code {
  font-size: .92em;
  padding: 2px 6px;
  border-radius: var(--r-sm);
  background: rgba(0, 123, 255, .08);
  color: var(--accent-deep);
}
.table-wrap { overflow-x: auto; margin: 30px 0; }
.post-body table { border-collapse: collapse; width: 100%; font-size: 0.9375rem; }
.post-body th, .post-body td {
  text-align: left;
  padding: 12px 14px;
  border-bottom: 1px solid rgba(0, 0, 0, .09);
}
.post-body th {
  font-weight: 700;
  font-size: var(--fs-label);
  letter-spacing: 0.02em;
  text-transform: uppercase;
  color: rgba(0, 0, 0, .6);
  border-bottom-color: rgba(0, 123, 255, .25);
}

/* Encart de conversion en cours d'article */
.post-cta {
  margin: clamp(48px, 6vw, 72px) 0;
  padding: 30px 32px;
  text-align: center;
}
.post-cta b {
  display: block;
  font-size: var(--fs-h3);
  font-weight: 700;
  letter-spacing: -0.01em;
  margin-bottom: 8px;
}
.post-cta p {
  color: rgba(0, 0, 0, .66);
  font-size: 0.9375rem;
  margin-bottom: 20px;
}

.post-faq { margin-top: clamp(48px, 6vw, 72px); }
.post-faq > h2 {
  font-size: clamp(1.375rem, 2.4vw, 1.75rem);
  font-weight: 800;
  letter-spacing: -0.015em;
  margin-bottom: 20px;
  scroll-margin-top: 96px;
}

.post-related { margin: clamp(56px, 7vw, 88px) 0 clamp(64px, 8vw, 104px); }
.post-related h2 {
  font-size: var(--fs-label);
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  margin-bottom: 22px;
}
.rel-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 18px; }
.rel-card {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 14px;
  border-radius: var(--r-md);
  color: var(--ink);
  background: rgba(0, 123, 255, .04);
  transition: background-color .25s var(--ease-out), transform .25s var(--ease-out);
}
.rel-card:hover { background: rgba(0, 123, 255, .09); transform: translateY(-2px); }
.rel-card img {
  width: 76px; height: 58px;
  border-radius: var(--r-sm);
  object-fit: cover;
  flex-shrink: 0;
}
.rel-card b {
  display: block;
  font-size: 0.9375rem;
  font-weight: 700;
  line-height: 1.3;
  margin-bottom: 4px;
}
.rel-card em {
  font-style: normal;
  font-size: 0.8125rem;
  color: rgba(0, 0, 0, .55);
}

@media (max-width: 1020px) {
  .post-hero { grid-template-columns: 1fr; }
  .post-grid { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 640px) {
  .post-grid { grid-template-columns: 1fr; }
  .rel-grid { grid-template-columns: 1fr; }
  .post-byline-meta { margin-left: 0; width: 100%; }
  .post-body { font-size: 1rem; }
}

/* ============================================================
   PAGES LÉGALES
   ============================================================ */
.legal-hero {
  padding: clamp(150px, 18vh, 210px) 0 clamp(40px, 5vw, 64px);
  background: linear-gradient(180deg, #FFFFFF 0%, var(--surface) 100%);
}
.legal-hero .display { font-size: clamp(2rem, 4vw, 2.75rem); }
.legal-hero .updated { margin-top: 14px; color: rgba(0, 0, 0, .55); font-size: 0.9375rem; }
.legal-body { padding-bottom: clamp(80px, 10vw, 128px); }
.legal-body .container { max-width: 780px; }
.legal-hero .container { max-width: 780px; }
.legal-body h2 {
  font-size: 1.375rem;
  font-weight: 700;
  letter-spacing: -0.01em;
  margin: 44px 0 14px;
}
.legal-body p, .legal-body li { color: rgba(0, 0, 0, .78); }
.legal-body p { margin-bottom: 12px; }
.legal-body ul { list-style: none; display: grid; gap: 8px; margin-bottom: 12px; }
.legal-body ul li { padding-left: 18px; position: relative; }
.legal-body ul li::before {
  content: "–";
  position: absolute;
  left: 0;
  color: var(--accent);
  font-weight: 700;
}
.doc-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 18px;
  padding: 22px 26px;
  margin-bottom: 16px;
}
.doc-row b { display: block; font-weight: 700; }
.doc-row span { display: block; font-size: 0.8125rem; color: rgba(0, 0, 0, .55); margin-top: 2px; }

/* ============================================================
   RÉVÉLATIONS AU SCROLL
   ============================================================ */
/* Le masquage n'existe que si JS est là pour le lever : sans JS, en
   impression ou en capture, tout le contenu reste visible. */
html.js .reveal {
  opacity: 0;
  transform: translateY(26px);
  filter: blur(5px);
  transition: opacity .8s var(--ease-out), transform .8s var(--ease-out), filter .8s var(--ease-out);
}
html.js .reveal.in-view { opacity: 1; transform: none; filter: none; }
html.js .reveal-stagger > * {
  opacity: 0;
  transform: translateY(22px);
  transition: opacity .7s var(--ease-out), transform .7s var(--ease-out);
}
html.js .reveal-stagger.in-view > * { opacity: 1; transform: none; }
.reveal-stagger.in-view > *:nth-child(2) { transition-delay: .09s; }
.reveal-stagger.in-view > *:nth-child(3) { transition-delay: .18s; }
.reveal-stagger.in-view > *:nth-child(4) { transition-delay: .27s; }
.reveal-stagger.in-view > *:nth-child(5) { transition-delay: .36s; }
.reveal-stagger.in-view > *:nth-child(6) { transition-delay: .45s; }

/* ============================================================
   RESPONSIVE
   ============================================================ */
/* Bande étroite de bureau : la nav complète (logo, six liens, deux boutons)
   revient à 1021 px mais ne tient dans la barre qu'à partir de ~1110 px. Entre
   les deux, rien n'était compressible (logo et actions en `flex-shrink: 0`) :
   le bouton « Demander une démo » sortait de la barre et se faisait rogner par
   l'`overflow-x: hidden` du body, invisiblement. On resserre plutôt les
   respirations le temps de cette bande. */
@media (min-width: 1021px) and (max-width: 1140px) {
  .nav { gap: 12px; padding-left: 16px; }
  .nav-links a { padding: 8px 7px; }
  .nav-actions .btn { padding: 11px 16px; }
}
@media (max-width: 1020px) {
  .nav-links { display: none; }
  .nav-actions .btn-ghost { display: none; }
  .nav-burger { display: block; }
  .hero-grid { grid-template-columns: 1fr; gap: clamp(32px, 6vw, 56px); }
  .hero-copy { max-width: 640px; }
  .demo-scene { max-width: 460px; margin-inline: auto; }
  .duo { grid-template-columns: 1fr; }
  .duo-intro { position: static; }
  .bento { grid-template-columns: repeat(2, 1fr); }
  .tile, .tile-wide, .tile-half { grid-column: span 1; }
  .module, .module:nth-child(even) { grid-template-columns: 1fr; }
  .module:nth-child(even) .module-copy { order: 1; }
  .module:nth-child(even) .module-visual { order: 2; }
  .plans { grid-template-columns: 1fr; max-width: 460px; margin-inline: auto; }
  .gallery { grid-template-columns: repeat(2, 1fr); }
  .team { grid-template-columns: 1fr; gap: 40px; }
  .roster { grid-template-columns: repeat(2, 1fr); }
  /* Sur deux colonnes, une carte orpheline prend toute la largeur.
     Conditionné à un nombre IMPAIR d'agents (`nth-child(odd)`) : à six,
     la grille tombe juste et Mickael ne doit pas s'étaler seul. */
  .roster-agent:nth-child(odd):last-child { grid-column: 1 / -1; }
  .roster-agent:nth-child(odd):last-child > a { max-width: 340px; margin-inline: auto; }
  .roster-foot { flex-direction: column; align-items: flex-start; }
  .agent-file { grid-template-columns: 1fr; }
  .agent-file-head .roster-status { margin-left: 0; }
  /* En pile, la scène passe au-dessus de l'identité : c'est elle qui
     signale quel onglet est ouvert. */
  .agent-stage { grid-template-columns: 1fr; gap: 32px; }
  .footer-grid { grid-template-columns: 1fr; gap: 36px; }
}
@media (max-width: 640px) {
  .agent-files { gap: 16px; }
  .agent-file { gap: 18px; padding: 22px 20px; }
  .agent-file-portrait { width: 88px; height: 88px; }
  .agent-file-claim { margin-top: 12px; }
  .agent-file .check-list { margin-top: 16px; }
  .agent-file-link { margin-top: 16px; }
  .nav-actions .btn-primary { display: none; }
  /* Écrans très étroits : la barre d'onglets défile plutôt que de déborder */
  .subnav-inner { max-width: 100%; overflow-x: auto; scrollbar-width: none; }
  .subnav-inner::-webkit-scrollbar { display: none; }
  .subnav [role="tab"] { padding: 5px 14px 5px 5px; gap: 8px; }
  .subnav [role="tab"] img { width: 32px; height: 32px; }
  .tab-id b { font-size: 0.8125rem; }
  .tab-id > span { font-size: 0.6875rem; }
  .hero { padding-top: 108px; }
  .subnav { top: 72px; }
  .subnav a { padding: 8px 13px; }
  .faq-a p { padding-right: 0; }

  /* --- La mini-démo du hero ---------------------------------------
     Les deux panneaux se chevauchaient de 28 px alors qu'ils occupent
     tous les deux 100 % de la largeur : le panneau de l'agent recouvrait
     la ligne « Total HT », c'est-à-dire la chute de la scène, et masquait
     la tranche de verre du panneau du dessus. Sur bureau le décalage est
     lisible parce que les deux panneaux sont décalés horizontalement
     (88 % à droite, 94 % à gauche) ; empilés, il ne reste que l'occlusion.
     Ils se posent donc l'un sous l'autre.
     `transform: none` : combiné à la perspective du parent, le
     translateZ(40px) agrandissait le panneau de 3 %, soit 11 px de
     débordement hors du conteneur. */
  .demo-lot { width: 100%; }
  .demo-agent { width: 100%; margin-top: 16px; transform: none; }

  /* --- Le casting d'agents ------------------------------------------
     Les deux colonnes de la bande 641-1020 px sont conservées jusqu'en
     bas : cinq cartes empilées, c'était 1 000 px de défilement pour cinq
     phrases. Seules les échelles internes se resserrent, la cellule ne
     faisant plus que 158 px. Le cinquième agent occupe la dernière rangée
     et se cale à la largeur d'une colonne, pour ne pas se lire comme une
     carte d'un autre gabarit. L'anneau reste blanc et le pastel reste
     dans l'image (CLAUDE.md). */
  .roster { gap: 10px; }
  .roster-agent:last-child > a { max-width: 172px; }
  .roster-agent > a { padding: 16px 12px 14px; }
  .roster-portrait { width: 68px; height: 68px; margin-bottom: 10px; }
  .roster-agent b { font-size: 0.9375rem; }
  .roster-fn { margin-top: 2px; font-size: 0.625rem; letter-spacing: 0.03em; }
  .roster-agent p { margin-top: 8px; font-size: 0.8125rem; line-height: 1.45; }
  .roster-status { padding-top: 12px; font-size: 0.6875rem; gap: 6px; }
  .roster-foot { gap: 16px; margin-top: 24px; }

  /* --- Bento, soutiens, footer : deux colonnes ----------------------
     Une tuile par rangée gaspillait la moitié de la largeur pour trois
     lignes de texte. Les mini-scènes restent lisibles à 158 px : ce sont
     des barres, un anneau et des traits, pas des captures. */
  .bento { gap: 10px; }
  .tile { padding: 14px 13px 16px; }
  .tile b { font-size: 0.9375rem; margin-bottom: 5px; }
  .tile p { font-size: 0.8125rem; line-height: 1.45; }
  .tile-icon { margin-bottom: 10px; }
  .mini-dash { height: 58px; gap: 5px; margin-bottom: 14px; }
  .mini-ring, .mini-ledger, .mini-gauge, .mini-stamp, .mini-docs { margin-bottom: 12px; }

  .backers { gap: 12px; }
  .backer { padding: 16px 14px; gap: 10px; }
  .backer img { height: 32px; }
  .backer b { font-size: 0.9375rem; }
  .backer p { font-size: 0.8125rem; line-height: 1.45; }

  /* La colonne contact porte une adresse et un courriel, la colonne
     liens quatre mots : elles ne méritent pas la même largeur. */
  .footer-grid { grid-template-columns: minmax(0, 1.15fr) minmax(0, .85fr); gap: 24px 18px; }
  .footer-brand { grid-column: 1 / -1; }
  .footer h3 { margin-bottom: 12px; }
  .footer-col li { margin-bottom: 10px; }
  .footer-col a, .footer-col .line { font-size: 0.8125rem; gap: 8px; }

  /* --- Densité générale -------------------------------------------
     Les rembourrages de composants sont dimensionnés pour un conteneur
     de 1 140 px. Sur 327 px utiles, 26 à 30 px de marge intérieure de
     chaque côté mangent un sixième de la ligne de texte. */
  .point { grid-template-columns: 44px minmax(0, 1fr); gap: 14px; padding: 18px 0; }
  .point-icon { width: 44px; height: 44px; }
  .plans { gap: 14px; margin-top: 24px; }
  .plan { padding: 20px 18px; }
  .plan-head { margin-bottom: 16px; }
  .faq-q { padding: 16px 0; }
  .testimonial .quote-mark { margin-bottom: 14px; }
  .testimonial blockquote { margin-bottom: 20px; }
  .testimonial-author img { width: 48px; height: 48px; }
  .footer-grid { margin-bottom: 28px; }

  /* Les respirations internes d'un bloc de tête suivent la taille du
     titre : à 33 px de display, 20 px sous le titre valent 14 px. */
  .section-head .h2 { margin-top: 10px; }
  .section-head .lead { margin-top: 12px; }
  .duo-intro .h2 { margin-top: 10px; }
  .duo-intro .lead { margin-top: 12px; }
  .hero-copy .data-pill { margin-bottom: 16px; }
  .hero-copy .display { margin-bottom: 14px; }
  .hero-copy .lead { margin-bottom: 24px; }
  .hero-ctas { margin-bottom: 24px; }

  /* Trois portraits en pile faisaient 900 px. Deux colonnes, le
     troisième centré sous eux, comme le casting à 1 020 px. */
  .team { grid-template-columns: repeat(2, 1fr); gap: 24px 18px; }
  .member:last-child { grid-column: 1 / -1; }
  .member .portrait { margin-bottom: 12px; }
  /* Exactement une colonne, sinon le troisième portrait se lit comme
     un membre plus important que les deux autres. */
  .member:last-child .portrait { width: calc(50% - 9px); }
}

/* Le bloc d'appel en fin de billet : « Demander une démonstration » est en
   `white-space: nowrap` et mesure 287 px. Sous 480 px, le cadre ne lui en
   offrait que 193 : le bouton sortait de la carte et se faisait rogner sans
   bruit par l'`overflow-x: hidden` du body. Il prend toute la largeur, ce qui
   est de toute façon la bonne cible tactile sur téléphone. */
@media (max-width: 480px) {
  .post-cta { padding: 24px 18px; }
  .post-cta .btn {
    display: flex;
    width: 100%;
    padding-inline: 16px;
    white-space: normal;
  }
}

/* ============================================================
   REDUCED MOTION
   ============================================================ */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
  }
  html.js .reveal, html.js .reveal-stagger > * { opacity: 1; transform: none; filter: none; }
  html.js .module .module-visual { opacity: 1; transform: none; }
  .mini-dash i { transform: scaleY(var(--h, .6)); }
  .mini-docs i:nth-child(1) { transform: translateX(0) rotate(-4deg); }
  .mini-docs i:nth-child(2) { transform: translateX(26px) rotate(2deg); }
  .mini-docs i:nth-child(3) { transform: translateX(52px) rotate(7deg); }
  .mini-ring .arc { stroke-dashoffset: 44; }
  .mini-ledger i { transform: scaleX(1); background: rgba(0, 123, 255, .32); }
  .mini-ledger b { opacity: 1; transform: scale(1); }
  .mini-gauge .fill { transform: scaleX(.68); }
  .mini-stamp .seal { opacity: 1; transform: scale(1) rotate(-8deg); }
  .demo-step { opacity: 1; transform: none; }
}


/* ============================================================
   SCÈNES DE MOUVEMENT  (accueil)
   ------------------------------------------------------------
   Styles des scènes pilotées par assets/js/motion.js, qui n'est
   chargé que par l'accueil. Mises en production le 05/08/2026, après
   une phase de prototype qui n'a plus lieu d'être dans le dépôt.

   RÈGLE DE REPLI, valable pour tout ce qui suit : sans JavaScript,
   sans GSAP, sous 900px ou en animations réduites, TOUT le contenu
   reste lisible en flux normal. Les superpositions ne s'activent
   que sous `.is-live`, posé par motion.js.
   ============================================================ */
/* ============================================================
   A. LA BASCULE  (remplace .scene-problem + .scene-solution)
   ============================================================ */

.scene-shift {
  background: var(--paper);
  overflow: clip;                    /* le pin de GSAP mesure mieux */
}

.shift-grid {
  display: grid;
  grid-template-columns: minmax(0, .82fr) minmax(0, 1.18fr);
  gap: clamp(36px, 5vw, 76px);
  align-items: start;
}

/* ---- Colonne de gauche : les deux titres qui se relaient ---- */

.shift-heads .lead { margin-top: 20px; max-width: 44ch; }

/* Le titre énonce le constat puis la promesse, d'un seul tenant. La
   seconde moitié porte l'accent : la transformation se lit dans la
   phrase, elle n'a pas besoin d'une bascule au défilement, qui obligeait
   à relire un titre déjà lu. Ce sont les panneaux qui se retournent. */
.shift-turn {
  display: block;
  color: var(--accent);
}

/* ---- Colonne de droite : les quatre panneaux ---- */

.shift-cards {
  display: grid;
  gap: 16px;
  list-style: none;
  padding: 0;
  margin: 0;
}

.shift-card {
  position: relative;
  isolation: isolate;
  padding: 22px 26px 22px 30px;
  border-radius: var(--r-md);
  border: 1px solid rgba(0, 0, 0, .08);
  background: var(--surface);
}

/* Le fond de verre : opacité pilotée au scrub, du mat vers le verre.
   C'est lui qui porte la matière, pas la carte, pour que l'état de
   départ reste franchement mat (une douleur n'est pas un objet fini). */
.shift-glass {
  position: absolute;
  inset: 0;
  z-index: -1;
  border-radius: inherit;
  opacity: 0;
  background: linear-gradient(180deg, rgba(255, 255, 255, .92), rgba(255, 255, 255, .66));
  -webkit-backdrop-filter: blur(16px) saturate(1.2);
  backdrop-filter: blur(16px) saturate(1.2);
  box-shadow:
    inset 0 1.5px 0 rgba(255, 255, 255, 1),
    inset 0 0 0 1px rgba(0, 123, 255, .14),
    inset 0 -10px 24px -18px rgba(0, 123, 255, .35),
    var(--shadow-contact);
  pointer-events: none;
}

/* La tranche accent, qui se remplit du haut vers le bas quand le
   panneau bascule. Même rôle que .glass::after : donner l'épaisseur. */
.shift-edge {
  position: absolute;
  left: 0; top: 8px; bottom: 8px;
  width: 3px;
  border-radius: 3px;
  background: linear-gradient(180deg, var(--accent), rgba(0, 123, 255, .35));
  transform: scaleY(0);
  transform-origin: 50% 0;
  pointer-events: none;
}

.shift-card .face h3 { margin-bottom: 6px; }
.shift-card .face p {
  color: rgba(0, 0, 0, .68);
  max-width: 54ch;
  font-size: .9375rem;
  line-height: 1.62;
}
.shift-card .face-gain h3 { color: var(--accent); }

/* Repli lisible : la douleur, un filet, le gain. */
.shift-card .face + .face {
  margin-top: 16px;
  padding-top: 16px;
  border-top: 1px solid rgba(0, 123, 255, .16);
}

/* Mode animé : les deux visages se superposent et se relaient. */
.shift-card.is-live {
  display: grid;
  min-height: 158px;
  align-content: center;
  overflow: hidden;
}
.shift-card.is-live .face { grid-area: 1 / 1; }
.shift-card.is-live .face + .face {
  margin-top: 0;
  padding-top: 0;
  border-top: 0;
}
.shift-card.is-live .face-gain { opacity: 0; }

/* ============================================================
   B. LA PILE  (remplace .showcase)
   ============================================================ */

.stack { display: grid; }

.stack-card {
  position: sticky;
  /* 96px de nav + 14px par carte : les tranches restent visibles,
     on voit que quelque chose s'empile au lieu de défiler. */
  top: calc(96px + var(--i) * 14px);
  /* z-index explicite, pas décoratif : GSAP pose un transform et une
     opacité sur chaque carte, donc chacune devient un contexte
     d'empilement. Sans ordre déclaré, le texte de la carte sortante
     transparaît à travers le panneau de la carte entrante. */
  z-index: calc(var(--i) + 1);
  transform-origin: 50% 0;
  will-change: transform;
}
.stack-card + .stack-card { margin-top: clamp(28px, 4vw, 48px); }

/* La section est sur fond blanc : une carte blanche y serait invisible
   une fois empilée. Le dégradé vers --pale (déjà un token du site) suffit
   à détacher chaque strate sans sortir des trois neutres + l'accent. */
.stack-inner {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, .78fr) minmax(0, 1.22fr);
  gap: clamp(24px, 3.5vw, 44px);
  align-items: center;
  padding: clamp(22px, 3vw, 34px);
  border-radius: var(--r-md);
  background: linear-gradient(180deg, var(--paper) 0%, var(--pale) 100%);
  border: 1px solid rgba(0, 123, 255, .12);
  box-shadow: var(--shadow-contact), var(--shadow-depth);
}

.stack-copy h3 { margin-bottom: 12px; }
.stack-copy p { color: rgba(0, 0, 0, .68); max-width: 46ch; }

/* La capture garde son cadre de verre : on ne réinvente pas le composant,
   on le repose dans un contenant différent.
   `isolation` est nécessaire, pas décoratif : .glass::after (la tranche)
   est en z-index -1, et le transform que GSAP pose sur .stack-card crée un
   contexte d'empilement. Sans ce contexte intermédiaire, la tranche
   passerait derrière le fond du panneau et le verre perdrait son épaisseur. */
.stack-shot { isolation: isolate; }
.stack-shot .screen-frame { margin: 0; }

/* Le voile, et non une opacité sur la carte.
   Baisser l'opacité de .stack-card rend la carte translucide DANS SON
   ENSEMBLE, fond compris : les cartes du dessous se lisent alors par
   transparence à travers celle du dessus (constaté à 0,92 déjà). Le
   voile, lui, est posé PAR-DESSUS le contenu et laisse le panneau
   parfaitement opaque. La strate s'éloigne dans la brume au lieu de
   devenir un calque. */
.stack-veil {
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background: var(--paper);
  opacity: 0;
  pointer-events: none;
}

/* ============================================================
   C. TITRES DE SECTION  ·  révélation ligne par ligne
   ------------------------------------------------------------
   Les .section-head n'ont plus la classe .reveal : le fondu-flou
   global du bloc est remplacé par un vrai décalage, sur-titre,
   puis lignes du titre qui montent derrière leur masque, puis
   chapeau. Sans JS, sans GSAP ou en animations réduites, rien
   n'est masqué du tout : les titres sont simplement là.
   ============================================================ */

/* .h2 est en line-height 1.15 et .display en 1.08 : la boîte de ligne
   serre les glyphes. Le masque de SplitText coupe au ras de cette
   boîte, donc les jambages de « q », « p », « g » seraient rognés
   (« équipe », « Questions », « NegoFlow »). Cette réserve les sauve. */
.head-line { padding-bottom: .14em; }

/* ============================================================
   D. NAV  ·  la section courante
   ------------------------------------------------------------
   La page est longue, et la scène épinglée la rallonge encore.
   Le lien de la section lue s'allume : c'est de l'information sur
   l'état, pas de la décoration, donc ce module reste actif même
   en animations réduites.
   Le filet reprend le motif du .kicker (22px, 2px, accent).
   ============================================================ */

.nav-links a[aria-current="location"] {
  color: var(--accent);
  position: relative;
}
.nav-links a[aria-current="location"]::after {
  content: "";
  position: absolute;
  left: 12px;
  bottom: 2px;
  width: 22px;
  height: 2px;
  border-radius: 2px;
  background: var(--accent);
}

/* ============================================================
   E. MICRO-MOTION
   ============================================================ */

/* Le bouton aimanté n'existe que si GSAP a pris la main. Sans lui,
   le :hover CSS d'origine reste le seul retour, et il suffit.
   `transform` sort de la liste des transitions : .btn le fait transiter
   en .2s, ce qui lisserait une deuxième fois ce que quickTo lisse déjà.
   Deux amortissements en série donnent un bouton qui traîne. */
.magnet {
  will-change: transform;
  transition: background-color .2s var(--ease-out),
              color .2s var(--ease-out),
              box-shadow .2s var(--ease-out);
}

/* ============================================================
   D. RESPONSIVE  ·  sous 900px, aucune scène épinglée
   ============================================================ */

@media (max-width: 900px) {
  .shift-grid { grid-template-columns: 1fr; gap: clamp(28px, 6vw, 44px); }

  /* La bascule redevient une lecture verticale : douleur puis gain. */
  .shift-card.is-live { display: block; min-height: 0; overflow: visible; }
  .shift-card.is-live .face { grid-area: auto; }
  .shift-card.is-live .face-gain { opacity: 1; }
  .shift-card.is-live .face + .face {
    margin-top: 16px;
    padding-top: 16px;
    border-top: 1px solid rgba(0, 123, 255, .16);
  }
  .shift-edge { transform: scaleY(1); }
  .shift-glass { opacity: 1; }

  .stack-card { position: static; top: auto; }
  .stack-inner { grid-template-columns: 1fr; }
}

/* ============================================================
   E. ANIMATIONS RÉDUITES
   Même état d'arrivée que le mobile : tout est lu, rien ne bouge.
   motion.js ne monte aucun ScrollTrigger dans ce mode, ces règles ne
   font que rattraper les états de départ posés en CSS.
   ============================================================ */

@media (prefers-reduced-motion: reduce) {
  .shift-card.is-live { display: block; min-height: 0; overflow: visible; }
  .shift-card.is-live .face-gain { opacity: 1; }
  .shift-card.is-live .face + .face {
    margin-top: 16px;
    padding-top: 16px;
    border-top: 1px solid rgba(0, 123, 255, .16);
  }
  .shift-edge { transform: scaleY(1); }
  .shift-glass { opacity: 1; }
  .stack-card { position: static; }
}
