/* ============================================================
   SAGESSES MODERNES — MOTION
   Keyframes reproduced EXACTLY from palantir.com (definitions,
   durations, easings, iteration). No libraries; CSS + IO reveals.
   Loaded on every page. Fully disabled under prefers-reduced-motion.
   ============================================================ */

/* ---------- Exact Palantir keyframes ---------- */
@keyframes fadeInUp{0%{opacity:0;transform:translateY(20px)}100%{opacity:1;transform:translateY(0px)}}
@keyframes fadeIn{0%{opacity:0}100%{opacity:1}}
@keyframes fadeOutDown{0%{opacity:1;transform:translateY(0)}100%{opacity:0;transform:translateY(20px)}}
@keyframes slideUp{0%{transform:translateY(100%)}100%{transform:translateY(0px)}}
@keyframes heroReveal{0%{clip-path:inset(0px 0px 100%)}100%{clip-path:inset(0px)}}
@keyframes heroFadeIn{0%{opacity:0}100%{opacity:1}}
@keyframes heroLayerIn{0%{opacity:0;transform:translateY(1rem)}100%{opacity:1;transform:translateY(0px)}}
@keyframes coverReveal{0%{height:100%}100%{height:0px}}
@keyframes sideCoverReveal{0%{clip-path:polygon(35% 0px,35% 100%,calc(35% + 1px) 100%,35% 1px)}100%{clip-path:polygon(0px 0px,0px 100%,35% 100%,35% 0px)}}
@keyframes shimmer{0%{background-position:-200px 0px}100%{background-position:calc(100% + 200px) 0px}}
@keyframes glow{0%{opacity:0}50%{opacity:1}100%{opacity:0}}
@keyframes dash{0%{stroke-dashoffset:0}100%{stroke-dashoffset:860}}
@keyframes arrowBounce{0%,100%{transform:translateY(0px)}50%{transform:translateY(16px)}}
@keyframes bounce{0%,50%,100%{transform:translateZ(0px)}25%{transform:translate3d(0px,3px,0px)}75%{transform:translate3d(0px,-3px,0px)}}
@keyframes glitch{0%{transform:translateZ(0px)}10%{transform:translateZ(0px)}20%{transform:translateZ(0px)}30%{transform:translate3d(-50px,0px,0px)}40%{transform:translateZ(0px)}50%{transform:translateZ(0px)}60%{transform:translateZ(0px)}70%{transform:translate3d(100px,0px,0px)}80%{transform:translateZ(0px)}90%{transform:translateZ(0px)}100%{transform:translateZ(0px)}}
@keyframes gothamFlicker{0%{opacity:1}14%{opacity:1}15%{opacity:0}29%{opacity:0}30%{opacity:1}44%{opacity:1}45%{opacity:0}59%{opacity:0}60%{opacity:1}74%{opacity:1}75%{opacity:0}89%{opacity:0}90%{opacity:1}}
@keyframes flickerTemp{0%{opacity:1}2%{opacity:1}3%{opacity:.1}5%{opacity:.1}6%{opacity:1}8%{opacity:1}9%{opacity:.1}11%{opacity:.1}12%{opacity:1}15%{opacity:.1}16%{opacity:1}17%{opacity:.1}18%{opacity:1}90%{opacity:1}100%{opacity:1}}
@keyframes popUp{0%{clip-path:inset(0px 0px 100%);transform:translateY(20px)}100%{clip-path:inset(0px);transform:translateY(0px)}}
@keyframes expandSlideIn{0%{max-height:0px;opacity:0;transform:translateY(-20px)}100%{max-height:640px;opacity:1;transform:translateY(0px)}}
@keyframes moveGrayBackground{0%{transform:translateX(-100%)}100%{transform:translateX(0px)}}
@keyframes marquee{from{transform:translateX(0)}to{transform:translateX(-50%)}}
@keyframes navIn{0%{opacity:0;transform:translateY(-100%)}100%{opacity:1;transform:translateY(0)}}

/* ---------- Scroll reveals — fadeInUp (0.5s · cubic-bezier(.4,0,.2,1) · 0.1s · 20px) ---------- */
.reveal{opacity:0}
.reveal.in{animation:fadeInUp .5s cubic-bezier(.4,0,.2,1) .1s forwards}
/* list children pop in staggered — popUp (clip + translate) */
.pillars.in > *,.signals.in > *,.rowlist.in > *,.sindex.in > *,.why.in > *,.method__seq.in > *{
  animation:popUp .5s ease both}
.pillars.in > *:nth-child(2),.signals.in > *:nth-child(2),.rowlist.in > *:nth-child(2),.sindex.in > *:nth-child(2),.why.in > *:nth-child(2),.method__seq.in > *:nth-child(2){animation-delay:.07s}
.pillars.in > *:nth-child(3),.signals.in > *:nth-child(3),.rowlist.in > *:nth-child(3),.sindex.in > *:nth-child(3),.why.in > *:nth-child(3),.method__seq.in > *:nth-child(3){animation-delay:.14s}
.pillars.in > *:nth-child(4),.signals.in > *:nth-child(4),.rowlist.in > *:nth-child(4),.sindex.in > *:nth-child(4),.why.in > *:nth-child(4),.method__seq.in > *:nth-child(4){animation-delay:.21s}
.pillars.in > *:nth-child(n+5),.signals.in > *:nth-child(n+5),.rowlist.in > *:nth-child(n+5),.sindex.in > *:nth-child(n+5),.method__seq.in > *:nth-child(n+5){animation-delay:.28s}

/* ---------- Hero layered entrance (on load) ---------- */
.hero__title,.sol-title{animation:heroReveal .7s cubic-bezier(.65,0,.35,1) .1s both}
.hero__sub,.sol-lead{animation:heroFadeIn .7s cubic-bezier(.65,0,.35,1) .25s both}
.hero__kick,.sol-hero__code{animation:heroLayerIn .6s ease .05s both}
.hero__cta,.hero__meta,.sol-hero__cta{animation:heroLayerIn .6s ease .45s both}
.hero__figure{position:relative;animation:heroFadeIn .7s cubic-bezier(.65,0,.35,1) .4s both}
.rail{animation:heroLayerIn .6s ease .55s both}
/* cover-reveal curtain lifting off the hero photograph */
.hero__figure::after{content:"";position:absolute;left:0;top:0;width:100%;height:100%;
  background:var(--paper);z-index:3;pointer-events:none;animation:coverReveal .6s ease-out .5s forwards}
.photo__credit{animation:fadeIn .3s ease-in-out 1s both}

/* ---------- Gotham terminal flicker on the monospaced anchor codes ---------- */
.kicker,.acode{animation:gothamFlicker .9s steps(1,end) both}
.masthead.in .masthead__idx,.masthead.in .masthead__label,.vsec.in .vsec__n{animation:gothamFlicker .9s steps(1,end) both}
.rail__k{animation:flickerTemp 2s ease 1s both}
/* glitch on hover (steps(11), ±50/100px — exactly as Palantir) */
.acode:hover,.masthead__idx:hover,.vsec__n:hover{animation:glitch .4s steps(11) 1}

/* ---------- Navigation ---------- */
.nav{animation:navIn .6s cubic-bezier(.4,0,.2,1) both;transition:border-color .4s ease}
.nav.is-scrolled{border-bottom-color:var(--line-strong)}
.nav__link,.foot__col a,a.row,.sindex__row,.sol-nav a,.tlink{transition:color .25s ease-in-out,background-color .25s ease-in-out}
a.row:hover,.sindex__row:hover,.sol-nav a:hover{background:rgba(0,0,0,.02)}
/* slide-up the prev/next routing labels on reveal */
.sol-nav.in a{animation:slideUp .3s ease both,fadeIn .3s ease both}

/* ---------- CTA arrow motion (bounce ±3px on hover; arrowBounce 16px on scroll-cue) ---------- */
.btn:hover .btn__arw,.tlink:hover .tlink__arw{display:inline-block;animation:bounce 1s linear infinite}
.scroll-cue{display:inline-flex;margin-top:clamp(44px,5vw,76px);font-size:1.3rem;line-height:1;
  color:var(--faint);animation:arrowBounce 1.4s cubic-bezier(.4,0,.2,1) infinite}

/* ---------- Marquee ticker (horizontalScrollingCardsTrack) ---------- */
.ticker{overflow:hidden;border-block:1px solid var(--line);padding-block:1.1rem}
.ticker__track{display:inline-flex;white-space:nowrap;animation:marquee 46s linear infinite;will-change:transform}
.ticker:hover .ticker__track{animation-play-state:paused}
.ticker__item{font-family:var(--mono);font-size:.72rem;letter-spacing:.2em;text-transform:uppercase;color:var(--faint);padding:0 2.2rem}
.ticker__item span{color:var(--line-strong);margin-left:2.2rem}

/* ---------- Reserved schematic blocks: shimmer · glow · dash · moving bg ---------- */
/* shimmer sweeps a lighter band across the reserved panel (loading-placeholder) */
.schematic{background:linear-gradient(90deg,#0A0C11 30%,#13161E 50%,#0A0C11 70%)!important;
  background-size:220% 100%!important;animation:shimmer 4s linear infinite}
.schematic__marker{color:rgba(255,255,255,.34)}
.schematic::before{animation:glow 4s ease-in-out infinite}        /* dashed frame glow-pulses */
.schematic__svg{position:absolute;inset:0;width:100%;height:100%;pointer-events:none;z-index:0}
.schematic__svg rect{fill:none;stroke:rgba(255,255,255,.16);stroke-width:1;stroke-dasharray:14 12;animation:dash 30s linear infinite}
.schematic__sweep{position:absolute;inset:0;z-index:0;pointer-events:none;
  background:linear-gradient(90deg,transparent,rgba(255,255,255,.05),transparent);animation:moveGrayBackground 8s linear infinite}

/* ---------- Mobile drawer ----------
   Le menu était un bandeau qui se dépliait sous l'en-tête :
   `expandSlideIn` plafonnait sa hauteur à 640 px et le décalait de
   -20 px. C'est désormais un calque PLEIN ÉCRAN (styles.css) — ce
   plafond le tronquait. Simple fondu, la géométrie vient de inset:0.
   Chargé après styles.css : cette règle doit rester compatible. */
.drawer.open{animation:drawerIn .22s ease both;overflow-y:auto}

/* ---------- Reduced motion ---------- */
@media(prefers-reduced-motion:reduce){
  *,*::before,*::after{animation-duration:.001ms!important;animation-iteration-count:1!important;transition-duration:.01ms!important}
  .reveal{opacity:1!important}
  .hero__figure::after{display:none}
  .schematic__marker{-webkit-text-fill-color:rgba(255,255,255,.55);color:rgba(255,255,255,.55);background:none}
}

/* homepage department cards — 6-up staggered pop-in */
.hp-roi__grid.in > *{animation:popUp .5s ease both}
.hp-roi__grid.in > *:nth-child(2){animation-delay:.07s}
.hp-roi__grid.in > *:nth-child(3){animation-delay:.14s}
.hp-roi__grid.in > *:nth-child(4){animation-delay:.21s}
.hp-roi__grid.in > *:nth-child(5){animation-delay:.28s}
.hp-roi__grid.in > *:nth-child(6){animation-delay:.35s}

/* department bullets — written-in, left→right, after each card pops */
@keyframes writeIn{from{clip-path:inset(0 100% 0 0);opacity:.15}to{clip-path:inset(0 0 0 0);opacity:1}}
.hp-roi__grid.in .hp-roi__pts li{animation:writeIn .45s ease both}
.hp-roi__grid.in > *:nth-child(1) .hp-roi__pts li:nth-child(1){animation-delay:0.34s}
.hp-roi__grid.in > *:nth-child(1) .hp-roi__pts li:nth-child(2){animation-delay:0.44s}
.hp-roi__grid.in > *:nth-child(1) .hp-roi__pts li:nth-child(3){animation-delay:0.54s}
.hp-roi__grid.in > *:nth-child(1) .hp-roi__pts li:nth-child(4){animation-delay:0.64s}
.hp-roi__grid.in > *:nth-child(2) .hp-roi__pts li:nth-child(1){animation-delay:0.41s}
.hp-roi__grid.in > *:nth-child(2) .hp-roi__pts li:nth-child(2){animation-delay:0.51s}
.hp-roi__grid.in > *:nth-child(2) .hp-roi__pts li:nth-child(3){animation-delay:0.61s}
.hp-roi__grid.in > *:nth-child(2) .hp-roi__pts li:nth-child(4){animation-delay:0.71s}
.hp-roi__grid.in > *:nth-child(3) .hp-roi__pts li:nth-child(1){animation-delay:0.48s}
.hp-roi__grid.in > *:nth-child(3) .hp-roi__pts li:nth-child(2){animation-delay:0.58s}
.hp-roi__grid.in > *:nth-child(3) .hp-roi__pts li:nth-child(3){animation-delay:0.68s}
.hp-roi__grid.in > *:nth-child(3) .hp-roi__pts li:nth-child(4){animation-delay:0.78s}
.hp-roi__grid.in > *:nth-child(4) .hp-roi__pts li:nth-child(1){animation-delay:0.55s}
.hp-roi__grid.in > *:nth-child(4) .hp-roi__pts li:nth-child(2){animation-delay:0.65s}
.hp-roi__grid.in > *:nth-child(4) .hp-roi__pts li:nth-child(3){animation-delay:0.75s}
.hp-roi__grid.in > *:nth-child(4) .hp-roi__pts li:nth-child(4){animation-delay:0.85s}
.hp-roi__grid.in > *:nth-child(5) .hp-roi__pts li:nth-child(1){animation-delay:0.62s}
.hp-roi__grid.in > *:nth-child(5) .hp-roi__pts li:nth-child(2){animation-delay:0.72s}
.hp-roi__grid.in > *:nth-child(5) .hp-roi__pts li:nth-child(3){animation-delay:0.82s}
.hp-roi__grid.in > *:nth-child(5) .hp-roi__pts li:nth-child(4){animation-delay:0.92s}
.hp-roi__grid.in > *:nth-child(6) .hp-roi__pts li:nth-child(1){animation-delay:0.69s}
.hp-roi__grid.in > *:nth-child(6) .hp-roi__pts li:nth-child(2){animation-delay:0.79s}
.hp-roi__grid.in > *:nth-child(6) .hp-roi__pts li:nth-child(3){animation-delay:0.89s}
.hp-roi__grid.in > *:nth-child(6) .hp-roi__pts li:nth-child(4){animation-delay:0.99s}

/* ═══ 004 — révélation par mot, flou → net, décalée (signature relevée sur gojiberry.ai) ═══ */
[data-split="words"] .w { display: inline-block; opacity: 0; filter: blur(8px);
  transform: translateY(10px); will-change: opacity, filter, transform; }
[data-split="words"].in .w { animation: wordIn .58s cubic-bezier(.22,.61,.36,1) both;
  animation-delay: calc(var(--i) * 40ms); }
@keyframes wordIn {
  from { opacity: 0; filter: blur(8px); transform: translateY(10px); }
  to   { opacity: 1; filter: blur(0);   transform: translateY(0); }
}
/* Titre non découpé (il contenait du balisage) : révélation simple, jamais invisible. */
[data-split="words"][data-split-done="skipped"] { animation: wordIn .58s cubic-bezier(.22,.61,.36,1) both; }

/* compteurs — l'écart du marché, jamais notre performance */
.mgap { display: grid; grid-template-columns: repeat(3, 1fr); gap: 28px; max-width: 780px;
  margin: 0 auto; grid-column: 1/-1; }
.mgap__n { font-size: clamp(2.2rem, 4.4vw, 3.4rem); font-weight: 600; letter-spacing: -.03em;
  line-height: 1; background: var(--hp-grad, linear-gradient(100deg,#8f78ea,#5896d8));
  -webkit-background-clip: text; background-clip: text; color: transparent; }
.mgap__l { font-size: .93rem; line-height: 1.45; color: #52525b; margin-top: 10px; }
.mgap__src { grid-column: 1/-1; font-family: var(--mono, monospace); font-size: 11px;
  letter-spacing: .04em; color: #a1a1aa; margin-top: 22px; text-align: center; }
@media (max-width: 620px) { .mgap { grid-template-columns: 1fr; gap: 22px; text-align: center; } }

/* ═══ FR-007 — « réduire les animations » : tout se fige, rien ne disparaît ═══ */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important; animation-iteration-count: 1 !important;
    transition-duration: .001ms !important; scroll-behavior: auto !important;
  }
  [data-split="words"] .w, [data-split="words"].in .w {
    opacity: 1 !important; filter: none !important; transform: none !important; animation: none !important;
  }
  .reveal, .reveal.in { opacity: 1 !important; transform: none !important; clip-path: none !important; }
  .mloop__pulse { display: none; }
}
