/* ENDURIA — Base : reset, typographie, pattern diagonal (BRIEF §2.2 / §2.1). */

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

html {
  -webkit-text-size-adjust: 100%;
  /* overflow-x: hidden ICI (pas seulement sur body) : sur iOS Safari et certains
     mobiles, body { overflow-x: hidden } ne suffit pas — l'élément html garde sa
     scrollabilité horizontale si un descendant dépasse la largeur du viewport.
     Conséquence visible : décalage général de toute la page (toggle fixed qui sort
     de l'écran, navbar mal placée, etc.). Sources concrètes d'overflow horizontal
     ici : animation du panel 3 prospection (carte 312px + curseur "Agent Enduria"
     ~112px de large, qui s'étendent à droite du panel pendant le carry vers le
     panier "relance"). On contient à la racine. */
  overflow-x: hidden;
}

/* Lenis gère le scroll — pas de smooth natif qui entre en conflit */
html.lenis,
html.lenis body {
  height: auto;
}
.lenis.lenis-smooth {
  scroll-behavior: auto !important;
}

body {
  font-family: var(--font-body);
  font-size: var(--type-body);
  line-height: 1.6;
  color: var(--text-primary);
  background: var(--bg-primary);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
  transition: background 0.4s var(--ease-out), color 0.4s var(--ease-out);
}

/* ═══════════════════════════════════════════════════════════════════════════
   TRANSITIONS DE PAGE fade-in / fade-out (page-transition.js). SANS spinner
   (retiré Théo — juste le fade simple).
   .page-overlay : full-screen overlay couleur du fond, opacité pilotée par les
   classes .page-fade-in / .page-loaded / .page-leaving sur body. */
.page-overlay {
  position: fixed;
  inset: 0;
  z-index: 9998;
  background: var(--bg-primary);
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.35s ease;
}
body.page-fade-in .page-overlay { opacity: 1; }
body.page-fade-in.page-loaded .page-overlay { opacity: 0; }
body.page-leaving .page-overlay { opacity: 1; }
@media (prefers-reduced-motion: reduce) {
  .page-overlay { transition: none !important; }
}

/* Grain fin en overlay (§3.1) — casse le dégradé numérique plat */
body::after {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 1; /* au-dessus du fond, SOUS le contenu : pas d'artefact de blend sur les boutons */
  pointer-events: none;
  opacity: 0.035;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* Cache le contenu tant que le preloader n'a pas levé le rideau (mais reste dans le DOM) */
body:not(.is-ready) {
  overflow: hidden;
}

/* Lock scroll du fond quand la popup Cal.com est ouverte.
   cal-embed.js ajoute .cal-locked sur <html> ET <body> via MutationObserver
   sur <cal-modal-box>.

   Méthode CSS-only Ben Frain / CSS-Tricks — iOS-safe SANS position:fixed
   (qui cassait la page au rétablissement). La combo overflow:hidden +
   height:100% + touch-action:none + overscroll-behavior:none appliquée sur
   html ET body suffit à figer complètement le fond sur desktop ET iOS Safari,
   sans avoir à sauvegarder/restaurer la scroll position. Page reste
   visuellement à la même place, et le retrait des classes = retour 100%
   normal (pas de styles inline à nettoyer). */
html.cal-locked,
body.cal-locked,
html.menu-locked,
body.menu-locked {
  overflow: hidden;
  height: 100%;
  touch-action: none;
  -webkit-overflow-scrolling: auto;
  overscroll-behavior: none;
}

/* Modale Cal elle-même : garde son scroll interne (pour scroller dans le
   calendrier). touch-action:auto contre le touch-action:none propagé du fond
   si le user-agent le cascadait ; overflow:auto pour le scroll interne. */
cal-modal-box,
cal-modal-box * {
  touch-action: auto;
}

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

a {
  color: inherit;
  text-decoration: none;
}

button {
  font: inherit;
  color: inherit;
  background: none;
  border: none;
  cursor: pointer;
}

/* Focus visible global — accessibilité clavier. Ne s'affiche PAS au clic
   souris (:focus-visible n'active que la navigation clavier), donc pas
   d'impact visuel sur les interactions souris/tactile. */
:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
  border-radius: 2px;
}

/* Skip link "Aller au contenu principal" — invisible tant que non focus,
   apparaît au premier Tab pour les utilisateurs clavier. */
.skip-link {
  position: absolute;
  top: 0;
  left: 0;
  z-index: 10000;
  padding: 0.75rem 1rem;
  background: var(--accent);
  color: #fff;
  font-weight: 600;
  border-radius: 0 0 8px 0;
  transform: translateY(-120%);
  transition: transform 0.2s var(--ease-out);
}
.skip-link:focus {
  transform: translateY(0);
  outline: none;
}

::selection {
  background: var(--accent);
  color: var(--text-primary);
}

/* ---- Typographie ---- */
h1,
h2,
h3 {
  font-family: var(--font-display);
  font-weight: 600;
  text-wrap: balance;
}

/* Safari-only override : `text-wrap: balance` est buggé sur WebKit — crée des
   lignes courtes forcées ("pyramides" de 3-4 lignes là où Chrome fait 1-2
   lignes propres). Chrome reste inchangé (validé), Safari revient au wrapping
   greedy natif qui donne un rendu quasi identique.
   Détection Safari via -webkit-named-image (propriété WebKit-only, retirée de
   Blink/Chrome). Couvre Safari desktop ET iOS. */
@supports (background: -webkit-named-image(i)) {
  h1,
  h2,
  h3 {
    text-wrap: wrap;
  }
}

.eyebrow {
  font-family: var(--font-body);
  font-weight: 500;
  font-size: var(--type-label);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--text-tertiary);
}

.eyebrow .idx {
  color: var(--text-secondary);
}

/* Mot-pivot — dégradé violet (signature client retrouvée) */
.pivot {
  background-image: linear-gradient(100deg, var(--accent) 0%, var(--accent-2) 100%);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}
/* Conservé au cas où, mais non utilisé par défaut */
.serif {
  font-family: var(--font-serif);
  font-style: italic;
  font-weight: 400;
  letter-spacing: -0.01em;
}

.text-accent {
  color: var(--accent);
}

p {
  max-width: 60ch;
  color: var(--text-secondary);
}

/* ---- Layout ---- */
.container {
  width: var(--container);
  margin-inline: auto;
}

.section {
  position: relative;
  padding-block: var(--space-section);
  border-top: 1px solid var(--border-subtle);
}
/* Retire le border-top de la section quand elle est précédée d'un divider design
   (évite le double trait gris + séparateur). */
.divider + .section {
  border-top: none;
}
/* Sections SANS divider ET SANS trait (Théo — retrait des séparateurs entre hero
   et Le Constat, et entre Le Constat et Notre différence). Aucun trait ni divider. */
#problem,
#mecanisme {
  border-top: none;
}

/* ═══════════════════════════════════════════════════════════════════════════
   SÉPARATEURS DE SECTIONS design (test 3 styles — Théo, choisir après).
   Base commune : pointer-events none, aria-hidden, overflow hidden. Chaque
   variante définit sa hauteur, son motif, son fondu latéral. Violet en dark,
   gris neutre en light. */
.divider {
  position: relative;
  width: 100%;
  pointer-events: none;
  overflow: hidden;
}

/* STYLE A — DOTS espacés (fine ligne de points violet-rosé). */
.divider--dots {
  height: 2px;
  max-width: 800px;
  margin: 3rem auto;
  background-image: radial-gradient(circle, rgba(139, 63, 245, 0.45) 0.9px, transparent 1.4px);
  background-size: 16px 2px;
  background-repeat: repeat-x;
  background-position: center;
  -webkit-mask-image: linear-gradient(to right, transparent 0%, #000 20%, #000 80%, transparent 100%);
          mask-image: linear-gradient(to right, transparent 0%, #000 20%, #000 80%, transparent 100%);
}
[data-theme="light"] .divider--dots {
  background-image: radial-gradient(circle, rgba(12, 13, 16, 0.35) 0.9px, transparent 1.4px);
}

/* STYLE B — STRIES diagonales (hachures fines -45deg). */
.divider--stripes {
  height: 16px;
  max-width: 800px;
  margin: 3rem auto;
  background-image: repeating-linear-gradient(
    -45deg,
    rgba(139, 63, 245, 0.14) 0 1px,
    transparent 1px 8px
  );
  -webkit-mask-image: linear-gradient(to right, transparent 0%, #000 15%, #000 85%, transparent 100%);
          mask-image: linear-gradient(to right, transparent 0%, #000 15%, #000 85%, transparent 100%);
}
[data-theme="light"] .divider--stripes {
  background-image: repeating-linear-gradient(
    -45deg,
    rgba(12, 13, 16, 0.10) 0 1px,
    transparent 1px 8px
  );
}

/* STYLE C — DOTGRID (fine bande de dot pattern avec fondu ellipse). */
.divider--dotgrid {
  height: 40px;
  max-width: 900px;
  margin: 3rem auto;
  background-image: radial-gradient(circle, rgba(139, 63, 245, 0.30) 1px, transparent 1.5px);
  background-size: 14px 14px;
  background-position: 0 0;
  -webkit-mask-image: radial-gradient(ellipse 70% 90% at center, #000 20%, transparent 90%);
          mask-image: radial-gradient(ellipse 70% 90% at center, #000 20%, transparent 90%);
}
[data-theme="light"] .divider--dotgrid {
  background-image: radial-gradient(circle, rgba(12, 13, 16, 0.22) 1px, transparent 1.5px);
}

/* Hairline qui se dessine (animée via JS scaleX) */
.section > .hairline {
  position: absolute;
  top: -1px;
  left: 0;
  right: 0;
  height: 1px;
  background: var(--border-strong);
  transform: scaleX(0);
  transform-origin: left;
}

/* ---- Halos atmosphériques (v2 §2.1/§3.5) — profondeur nuancée, jamais de noir plat ---- */
.halo {
  position: absolute;
  z-index: 0;
  pointer-events: none;
  border-radius: 50%;
  filter: blur(110px);
  opacity: 0;
  transition: opacity 1.6s var(--ease-out);
}
.is-ready .halo,
.halo.is-in {
  opacity: 1;
}
.halo--indigo { background: var(--halo-indigo); }
.halo--violet { background: var(--halo-violet); }
.halo--deep { background: var(--halo-deep); }

@keyframes halo-drift {
  0%, 100% { transform: translate(0, 0); }
  50% { transform: translate(5%, -4%); }
}
.halo--drift { animation: halo-drift 26s ease-in-out infinite; }

@media (prefers-reduced-motion: reduce) {
  .halo--drift { animation: none; }
}

/* ---- Pattern diagonal (texture officielle, doit se deviner) ---- */
.bg-pattern {
  position: relative;
}
.bg-pattern::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background-image:
    repeating-linear-gradient(-65deg, transparent 0 23px, rgba(244, 243, 239, 0.022) 23px 24px),
    repeating-linear-gradient(-65deg, transparent 0 6px, rgba(244, 243, 239, 0.014) 6px 7px);
  -webkit-mask-image: linear-gradient(to bottom, transparent, #000 28%, #000 72%, transparent);
  mask-image: linear-gradient(to bottom, transparent, #000 28%, #000 72%, transparent);
  opacity: 0;
  transition: opacity 1.5s var(--ease-out);
}
.is-ready .bg-pattern::before {
  opacity: 1;
}

/* Champ d'etoiles statique (cap DA reflect.app : profondeur neon, sans mouvement = pas de tournis) */
.bg-stars { position: relative; }
.bg-stars::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background-image:
    radial-gradient(1.5px 1.5px at 18% 28%, rgba(167, 139, 250, 0.40), transparent),
    radial-gradient(1px 1px at 64% 14%, rgba(167, 139, 250, 0.30), transparent),
    radial-gradient(1.5px 1.5px at 82% 58%, rgba(124, 79, 201, 0.34), transparent),
    radial-gradient(1px 1px at 34% 74%, rgba(167, 139, 250, 0.24), transparent),
    radial-gradient(1px 1px at 49% 42%, rgba(167, 139, 250, 0.26), transparent),
    radial-gradient(1.5px 1.5px at 9% 82%, rgba(124, 79, 201, 0.22), transparent),
    radial-gradient(1px 1px at 91% 33%, rgba(167, 139, 250, 0.26), transparent),
    radial-gradient(1px 1px at 73% 88%, rgba(167, 139, 250, 0.20), transparent);
  -webkit-mask-image: linear-gradient(to bottom, transparent, #000 18%, #000 82%, transparent);
  mask-image: linear-gradient(to bottom, transparent, #000 18%, #000 82%, transparent);
  opacity: 0;
  transition: opacity 1.8s var(--ease-out);
}
.is-ready .bg-stars::after { opacity: 1; }

/* Reveals de base (§3.4) — états initiaux gatés par .js : sans JS, tout reste visible */
.js [data-reveal] {
  opacity: 0;
  transform: translateY(48px) scale(0.96); /* DA Nina : reveal plus ample */
}

/* Fallback si les vendor libs échouent (app.js:38 → body.no-js-fallback +
   .preloader retiré). Dé-cache tout contenu masqué par les règles .js pour
   éviter un écran blanc. Priorité maximum via !important. */
body.no-js-fallback [data-reveal],
body.no-js-fallback .nav__inner > * {
  opacity: 1 !important;
  transform: none !important;
}

/* ---- Réduction de mouvement (OBLIGATOIRE §3.1) ---- */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.3s !important;
    scroll-behavior: auto !important;
  }
  [data-reveal] {
    opacity: 1;
    transform: none;
  }
  .bg-pattern::before {
    opacity: 1;
    transition: none;
  }
}

/* ===== DA Nina v2 — signatures reflect.app ===== */
/* Light-beam : source lumineuse fixe en haut, teinte toute la page (LA signature reflect) */
body::before {
  content: "";
  position: fixed;
  top: -42vh;
  left: 50%;
  transform: translateX(-50%);
  width: min(950px, 120vw);
  height: 950px;
  border-radius: 50%;
  background: radial-gradient(ellipse at center,
    rgba(124, 79, 201, 0.30) 0%,
    rgba(124, 79, 201, 0.12) 35%,
    rgba(124, 79, 201, 0.04) 60%,
    transparent 75%);
  pointer-events: none;
  z-index: 0;
}
main { position: relative; z-index: 1; }
@media (prefers-reduced-motion: reduce) { body::before { opacity: 0.7; } }
