/* IS Digital - motion design « Du réseau au trait » (prototype Maël, 29/10/2026). Chargé APRÈS site.css.
   Le réseau lumineux ne reste que dans le hero de l'accueil ; ensuite, un trait clair guide la lecture (rayure, soulignés, traits qui se dessinent).
   Animations : transform et opacity (clip-path : seulement celui que le site utilise déjà). Easing commun : --m-ease (expo.out).
   Sans JavaScript, rien n'est caché (états cachés liés à .m-on, posé par motion.js). Mouvement réduit (.rm) : rendu final, immobile.
   Charte bleue uniquement : #0453A5, #033D7A, #07152B, #F5F1EA, #9CC8FF (+ vert WhatsApp). */
:root{--m-ease:cubic-bezier(.16,1,.3,1);--stk:5.5rem}

/* ===== grammaire commune : mots dans un masque (titres ligne par ligne, phrase de bascule) =====
   padding + marge négative identiques : le mot garde exactement sa place (aucun décalage), accents et jambages ne sont pas coupés */
.m-w{display:inline-block;vertical-align:top;overflow:hidden;padding:.1em .06em .16em;margin:-.1em -.06em -.16em}
.m-wi{display:inline-block}
.m-on [data-m="lines"] .m-wi{opacity:0;transform:translate3d(0,112%,0);transition:transform 1.05s var(--m-ease) calc(var(--l,0) * 95ms),opacity .6s ease calc(var(--l,0) * 95ms)}
.m-on [data-m="lines"].is-in .m-wi{opacity:1;transform:none}

/* ===== 2. Pour qui ? : la bascule (« budget » se raye, la réponse monte puis se surligne mot à mot) ===== */
.prob__flip .m-x{position:relative;display:inline-block}
.prob__flip .m-x::after{content:"";position:absolute;left:-.08em;right:-.08em;top:54%;height:max(2px,.085em);border-radius:1em;background:var(--blue);transform:rotate(-2.5deg) scaleX(0);transform-origin:0 50%;transition:transform .75s var(--m-ease) .2s}
.prob__flip.is-in .m-x::after{transform:rotate(-2.5deg) scaleX(1)}
.prob__flip .flip__b .m-wi{position:relative;isolation:isolate}
.prob__flip .flip__b .m-wi::before{content:"";position:absolute;left:0;right:0;bottom:0;height:14%;z-index:-1;background:rgba(156,200,255,.75);transform:scaleX(0);transform-origin:0 50%;transition:transform .6s var(--m-ease) calc(1.3s + var(--k,0) * 90ms)}
.prob__flip.is-in .flip__b .m-wi::before{transform:none}
.m-on .prob__flip .flip__b .m-wi{opacity:0;transform:translate3d(0,112%,0);transition:transform 1s var(--m-ease) calc(.7s + var(--k,0) * 75ms),opacity .5s ease calc(.7s + var(--k,0) * 75ms)}
.m-on .prob__flip.is-in .flip__b .m-wi{opacity:1;transform:none}
.rm .prob__flip .m-x::after,.rm .prob__flip .flip__b .m-wi::before{transition:none}

/* ===== 6. Chiffres : compteurs à rouleaux (le chiffre final réserve sa place : aucun décalage) ===== */
.odo__n{display:inline-flex}
.odo__d{position:relative;display:block;clip-path:inset(0 -.3em)}
.odo__s{visibility:hidden}
.odo__r{position:absolute;left:0;right:0;top:0;display:flex;flex-direction:column;align-items:center;transform:translate3d(0,0,0);transition:transform 2s var(--m-ease) calc(var(--d,0s) + var(--c,0) * 110ms)}
.odo__r>span{display:block;height:1em;line-height:1}
.odo.is-run .odo__r{transform:translate3d(0,calc(var(--n,0) * -1em),0)}

/* ===== 8. Pôles : cartes empilées. Mise en page en CSS seul (active dès l'affichage, sans attendre le script) ; motion.js ajoute le recul ===== */
.poles__grid .card:nth-child(2){--i:1}
.poles__grid .card:nth-child(3){--i:2}
.poles__grid .card:nth-child(4){--i:3}
.js:not(.rm) [data-m="stack"]{display:block;margin-top:2.4rem;perspective:none}
.js:not(.rm) [data-m="stack"]::after{content:"";display:block;height:14vh}
.js:not(.rm) [data-m="stack"] .card{position:sticky;top:calc(var(--stk) + 1rem + var(--i,0) * 16px);height:min(64vh,560px);aspect-ratio:auto;transform:scale(var(--sc,1));transform-origin:50% 0;transition:none;box-shadow:0 -28px 60px -30px rgba(0,0,0,.7)}
.js:not(.rm) [data-m="stack"] .card+.card{margin-top:4vh}
.js:not(.rm) [data-m="stack"] .card>img{opacity:calc(1 - var(--dk,0) * .55)}
.js:not(.rm) [data-m="stack"] .card:focus-within{z-index:5}   /* clavier : la carte qui a le focus passe devant (lien jamais masqué) */
@media (min-width:900px){
  .js:not(.rm) .poles__wrap{display:grid;grid-template-columns:minmax(0,.7fr) minmax(0,1.3fr);column-gap:clamp(2rem,5vw,4.5rem);align-items:start}
  .js:not(.rm) .poles__head{position:sticky;top:calc(var(--stk) + 1.5rem)}
  .js:not(.rm) [data-m="stack"]{margin-top:0}
}
@media (max-width:899px){
  :root{--stk:4.6rem}
  .js:not(.rm) [data-m="stack"] .card{height:min(58vh,440px);height:min(58svh,440px);top:calc(var(--stk) + .5rem + var(--i,0) * 12px)}
}

/* ===== 9. FAQ : la réponse glisse, un trait bleu se dessine sur sa ligne ===== */
.faq details{position:relative}
.m-on .faq details[open]>div>*{animation:m-ans .7s var(--m-ease) both}
.m-on .faq details[open]>div>*+*{animation-delay:.08s}
.m-on .faq details[open]>div::before{content:"";position:absolute;left:0;right:0;top:-1.5px;height:1.5px;background:var(--blue);transform-origin:0 50%;animation:m-draw .9s var(--m-ease) both}
@keyframes m-ans{from{opacity:0;transform:translate3d(0,-10px,0)}to{opacity:1;transform:none}}
@keyframes m-draw{from{transform:scaleX(0)}to{transform:none}}

/* ===== 10. Contact : halo bleu qui suit la souris (ordinateur) ou dérive lentement (tactile, en pause hors écran) ===== */
.m-halo::before{--hs:min(820px,125vw);content:"";position:absolute;left:0;top:0;z-index:1;width:var(--hs);height:var(--hs);margin:calc(var(--hs) / -2) 0 0 calc(var(--hs) / -2);border-radius:50%;pointer-events:none;background:radial-gradient(closest-side,rgba(156,200,255,.28),rgba(4,83,165,.3) 45%,rgba(4,83,165,0));transform:translate3d(var(--mx,72vw),var(--my,38vh),0);will-change:transform}
.m-halo .contact__grid{z-index:2}
@media (hover:none),(pointer:coarse){
  .m-halo::before{animation:m-drift 24s ease-in-out infinite alternate;animation-play-state:paused}
  .m-halo.is-vis::before{animation-play-state:running}
}
@keyframes m-drift{0%{transform:translate3d(18vw,22vh,0)}50%{transform:translate3d(82vw,40vh,0)}100%{transform:translate3d(38vw,78vh,0)}}
html.js.m-oncontact .cursor.is-on{opacity:0}

/* ===== pages intérieures (mêmes fichiers) ===== */
/* hero de page : un rideau encre se retire de la photo à l'arrivée (le titre monte comme aujourd'hui) */
.js:not(.rm) .hero--page .hero__bg::after{content:"";position:absolute;inset:0;background:var(--ink);transform-origin:100% 50%;animation:m-curtain 1.2s var(--m-ease) .12s both}
@keyframes m-curtain{to{transform:scaleX(0)}}
/* blocs « split » : sur ordinateur, la photo s'ouvre en volet depuis le côté du texte (mobile : ouverture par le bas, comme aujourd'hui).
   Jamais deux volets de suite : un split qui suit directement un autre split garde l'ouverture par le bas, le troisième reprend le volet.
   Seul l'état caché change (:not(.is-in)) ; l'état ouvert et la durée restent ceux de site.css. Sans :has(), on garde simplement le volet. */
@media (min-width:900px){
  .js:not(.rm) .split>[data-clip]:not(.is-in){clip-path:inset(0 100% 0 0)}
  .js:not(.rm) .split--rev>[data-clip]:not(.is-in){clip-path:inset(0 0 0 100%)}
  .js:not(.rm) section:has(.split>[data-clip])+section .split>[data-clip]:not(.is-in){clip-path:inset(100% 0 0 0)}
  .js:not(.rm) section:has(.split>[data-clip])+section:has(.split>[data-clip])+section .split>[data-clip]:not(.is-in){clip-path:inset(0 100% 0 0)}
  .js:not(.rm) section:has(.split>[data-clip])+section:has(.split>[data-clip])+section .split--rev>[data-clip]:not(.is-in){clip-path:inset(0 0 0 100%)}
}
/* hero sans photo (pages légales, merci, 404) : un trait d'horizon bleu ciel se dessine sous le titre, de gauche à droite */
.js:not(.rm) .hero--plain::after{content:"";position:absolute;left:0;right:0;bottom:0;z-index:2;height:1px;pointer-events:none;background:linear-gradient(90deg,rgba(156,200,255,0),rgba(156,200,255,.85) 28%,rgba(156,200,255,.85) 72%,rgba(156,200,255,0));transform-origin:0 50%;animation:m-draw 1.8s var(--m-ease) .45s both}
/* listes numérotées : un trait se dessine sur chaque ligne (bleu sur fond clair, bleu ciel sur fond sombre) */
.m-on .why__list li{position:relative}
.m-on .why__list li::before{content:"";position:absolute;left:0;right:0;top:-1px;height:1px;background:var(--blue);transform:scaleX(0);transform-origin:0 50%;transition:transform 1.2s var(--m-ease) calc(var(--d,0s) + .2s)}
.m-on .why__list--light li::before{background:rgba(156,200,255,.7)}
.m-on .why__list li.is-in::before{transform:none}
/* tuiles : elles se rabattent en cascade, comme des volets articulés en haut (le décalage vient des data-d existants) */
.js:not(.rm) .tiles>.tile[data-reveal]{transform:perspective(900px) rotateX(-28deg) translate3d(0,36px,0);transform-origin:50% 0;transition:opacity .7s ease var(--d,0s),transform 1.15s var(--m-ease) var(--d,0s)}
.js:not(.rm) .tiles>.tile[data-reveal].is-in{transform:none}

/* ===== fil conducteur (fil.js, pages dont le <main> porte data-fil) =====
   Calque .fil : premier enfant de <main>, z-index 1 = au-dessus des fonds de section, sous les contenus (.sec>.wrap, z-index 1, viennent après).
   Le canvas ne couvre que l'écran et un peu plus ; fil.js le déplace (transform) et règle sa hauteur. Surcouches .fil-o : posées dans
   l'étape du financement, la barre de la méthode, le titre collant des pôles et l'anneau de l'orbite. Aucun clic capté. */
main[data-fil]{position:relative}
.fil{position:absolute;left:0;top:0;width:100%;height:100%;z-index:1;overflow:hidden;pointer-events:none;contain:strict}
.fil>canvas{position:absolute;left:0;top:0;display:block;width:100%;will-change:transform}
.fil-o{position:absolute;left:0;top:0;display:block;pointer-events:none}
.o360__ring>.fil-o{width:100%;height:100%}
.rm .fil,.rm .fil-o{display:none}

/* ===== accueil : fond discret de la section « Chiffres » (canvas.net--bg créé par motion.js, dessiné par net.js) =====
   Rien à ajouter ici : .net (site.css) le place en absolu, plein cadre, au-dessus de la photo et sous le contenu, invisible puis en fondu à l'allumage. */

/* ===== hero de l'accueil (hero-gl.js) : anneau du curseur qui se charge pendant l'appui long ; au doigt, ni menu ni sélection sur la scène ===== */
.js:not(.rm) .cursor.is-charge{border-color:#9CC8FF;background:rgba(156,200,255,.14);box-shadow:0 0 22px rgba(156,200,255,.55),inset 0 0 12px rgba(156,200,255,.3)}
@media (hover:none),(pointer:coarse){
  .js:not(.rm) .hero{-webkit-touch-callout:none;-webkit-user-select:none;user-select:none}
}

/* impression : tout est visible (y compris ce qui n'a pas encore été révélé au défilement) */
@media print{
  .m-wi,[data-reveal],.tiles>.tile{opacity:1!important;transform:none!important}
  [data-clip]{clip-path:none!important}
  .hero--page .hero__bg::after,.m-halo::before,.fil,.fil-o,.net,.hero__gl{display:none!important}
}
