/* ============================================================
 * integ-lusion.css — animation layer for integration-lusion.html
 *
 *   1. #categories becomes a dark section with an animated radial
 *      vortex behind it (canvas, injected by the script)
 *   2. its card grid becomes a sticky deck — every card pins at the
 *      same offset so the next rises up and covers it exactly,
 *      the same technique maisy-stack.css uses for #capabilities
 *   3. choreographed entrances for the rest of the page
 *
 * Purely additive. Every rule is scoped under a class the script
 * adds, so nothing outside those sections is touched and no copy
 * changes. Loaded last, so two-class selectors win over the page's
 * own rules without !important.
 * ========================================================== */

.il-stacked{
  --il-top: 104px;      /* where every card pins, clearing the header */
  --il-gap: 15vh;       /* scroll distance between one pin and the next */
  --il-min: 52vh;       /* card height — no dead frame under a pinned card */
  /* The LAST card's entire stick room, and the surplus that keeps the
     FIRST card pinned until the last one arrives. With six cards the
     deck needs 5 x spacing of room; at 12vh the first card released
     ~80px early and only five ever stacked together. */
  --il-tail: 24vh;

  --il-ease: cubic-bezier(.22,.8,.3,1);
  --il-back: cubic-bezier(.34,1.32,.44,1);
}

/* ============================================================
 * 1. Dark section + vortex backdrop
 * ========================================================== */
.il-stage{
  position:relative;
  background:#fff;
  isolation:isolate;
  padding-bottom:0;
  /* deliberately NOT overflow:hidden — that would make this element a
     scroll container and kill the sticky vortex below. The vortex is
     viewport-sized and bounded by this box, so nothing can bleed out. */
}

/* Pinned to the viewport while the section scrolls past, so the viewer
   stays inside the swirl instead of watching a slice of one enormous
   circle. The negative margin removes it from flow, so it occupies no
   layout space; without it a 100vh block would push the section down.
   It also keeps the canvas viewport-sized rather than as tall as the
   whole deck — ~0.9M pixels a frame instead of 3.4M. */
.il-vortex{
  position:sticky;
  top:0;
  height:100vh;
  margin-bottom:-100vh;
  z-index:0;
  pointer-events:none;
  opacity:0;
  transition:opacity 1.3s var(--il-ease,ease);
}
.il-stage.il-on .il-vortex{opacity:1;}
.il-vortex canvas{display:block;width:100%;height:100%;}

/* On a white ground the arcs need lifting off the page rather than
   darkening down — a white veil, falling off toward the centre where
   the deck sits, so the strokes stay strongest at the margins. */
.il-vortex::after{
  content:"";
  position:absolute;inset:0;z-index:1;pointer-events:none;
  background:radial-gradient(118% 78% at 50% 45%, rgba(255,255,255,.88), rgba(255,255,255,.52) 62%, rgba(255,255,255,.18) 100%);
}
.il-stage > .container{position:relative;z-index:2;}

/* ---------- the heading scrolls away with the page ----------
 * It was pinned above the deck at one point; that left it hanging
 * over the cards passing beneath it, so it is plain flow content now,
 * matching van-sales-automation-lusion.html. No background either —
 * the cards no longer travel under it, and a white band would only
 * mask the vortex behind it. The first card simply rises over it,
 * which is what the deck is meant to look like.
 *
 * .section-head also carries the page's .reveal, which would fade the
 * whole block in on top of the per-element entrances this layer gives
 * the pill, the h2 and the lede. Cleared, so those play alone. */
.il-stage .section-head{
  margin-bottom:26px;
  opacity:1;
  transform:none;
  transition:none;
}

/* ============================================================
 * 2. The sticky deck
 * ========================================================== */
.il-stack.bento{display:block;margin-top:8px;}

/* A real in-flow spacer. A sticky box is constrained by its
   containing block's CONTENT box, so padding-bottom on .bento would
   not extend it and a margin on the last card collapses out of the
   parent entirely. Without this the final card has exactly zero
   stick room, never pins, and the cards above release early. */
.il-stack-tail{
  display:block;
  height:var(--il-tail,12vh);
  pointer-events:none;
}

.il-stack > .feat{
  position:sticky;
  top:var(--il-top,104px);
  margin-bottom:var(--il-gap,15vh);
  min-height:var(--il-min,52vh);
  width:100%;
  display:flex;
  flex-direction:column;
  justify-content:center;
  grid-column:auto;
  padding:38px 44px;
  background:var(--white,#fff);
  border:1px solid #EDF1F7;
  border-radius:var(--radius,18px);

  /* The pin IS the entrance, so the page's own .reveal offset has to
     be cleared: a transform on a sticky box fights the pin. */
  opacity:1;
  transform:none;
  transition:none;

  /* Soft ambient depth — four very low-alpha layers rather than one
     heavy drop, so the covering edge stays clean on a white ground. */
  box-shadow:
    0 1px 2px rgba(16,31,56,.030),
    0 4px 10px rgba(16,31,56,.032),
    0 12px 26px rgba(16,31,56,.038),
    0 28px 58px rgba(16,31,56,.045);
}
/* the stylesheet's lift-on-hover would fight the pin */
.il-stack > .feat:hover{transform:none;border-color:#E2D7F2;}
/* the tail already provides the run-out */
.il-stack > .feat.il-last{margin-bottom:0;}

/* the page's own grid-span rules are inert once this is block flow,
   but clear them so nothing re-applies at a breakpoint */
.il-stack > .feat.span2,
.il-stack > .feat.span3,
.il-stack > .feat.span6{grid-column:auto;}

/* number sits large in the corner of a tall card */
.il-stack > .feat .num{top:28px;right:34px;font-size:42px;}

/* ============================================================
 * 3. Card entrance — one class (.il-in) plays the whole sequence
 * ========================================================== */

/* suppress transitions while a card is rewound off screen, or a
   quick scroll back catches it mid-fade */
.il-stack .il-noanim,
.il-stack .il-noanim *{transition:none !important;animation:none !important;}

.il-stack > .feat .feat-ico{
  opacity:0;transform:scale(.66) rotate(-10deg);
  transition:opacity .5s var(--il-ease), transform .62s var(--il-back);
  transition-delay:60ms;
}
.il-stack > .feat.il-in .feat-ico{opacity:1;transform:none;}

.il-stack > .feat h3{
  opacity:0;transform:translateY(16px);
  clip-path:inset(0 0 100% 0);
  transition:opacity .55s var(--il-ease), transform .7s var(--il-ease), clip-path .7s var(--il-ease);
  transition-delay:150ms;
}
.il-stack > .feat.il-in h3{opacity:1;transform:none;clip-path:inset(0 0 0 0);}

.il-stack > .feat .tag{
  opacity:0;clip-path:inset(0 100% 0 0 round 999px);
  transition:opacity .35s var(--il-ease), clip-path .65s var(--il-ease);
  transition-delay:320ms;
}
.il-stack > .feat.il-in .tag{opacity:1;clip-path:inset(0 0 0 0 round 999px);}

.il-stack > .feat .num{
  opacity:0;transform:translateY(-14px) scale(1.3);filter:blur(6px);
  transition:opacity .7s var(--il-ease), transform .85s var(--il-ease), filter .7s var(--il-ease);
  transition-delay:90ms;
}
.il-stack > .feat.il-in .num{opacity:1;transform:none;filter:blur(0);}

.il-stack > .feat > p{
  opacity:0;transform:translateY(10px);
  transition:opacity .5s var(--il-ease), transform .6s var(--il-ease);
  transition-delay:260ms;
}
.il-stack > .feat.il-in > p{opacity:1;transform:none;}

.il-stack > .feat ul li{
  opacity:0;transform:translateY(10px);
  transition:opacity .45s var(--il-ease), transform .55s var(--il-ease);
  transition-delay:calc(300ms + var(--i,0) * 80ms);
}
.il-stack > .feat.il-in ul li{opacity:1;transform:none;}

/* ============================================================
 * 3b. Card layout: copy left, illustration right
 * ========================================================== */
.il-stack > .feat.il-has-vec{
  display:grid;
  grid-template-columns:minmax(0,1.04fr) minmax(0,.96fr);
  gap:46px;
  align-items:center;
}
.il-card-text{min-width:0;}
.il-card-vec{min-width:0;display:flex;align-items:center;justify-content:center;}
.il-card-vec svg{width:100%;height:auto;max-height:290px;overflow:visible;}

/* supporting lines, divided like the reference cards */
.il-points{list-style:none;margin:18px 0 0;padding:0;}
.il-points .il-point{
  position:relative;
  padding:11px 0 11px 26px;
  margin:0;
  border-top:1px solid var(--line-soft,#EDF1F6);
  font-size:14.5px;line-height:1.55;font-weight:600;
  color:var(--ink-soft,#5B6675);
}
.il-points .il-point::before{
  content:"";position:absolute;left:3px;top:19px;
  width:8px;height:8px;border-radius:50%;
  background:var(--grad,linear-gradient(135deg,#701893,#1308AD));
}
.il-stack > .feat .il-points .il-point{
  opacity:0;transform:translateY(12px);
  transition:opacity .5s var(--il-ease), transform .6s var(--il-ease);
  transition-delay:calc(420ms + var(--i,0) * 95ms);
}
.il-stack > .feat.il-in .il-points .il-point{opacity:1;transform:none;}

/* ============================================================
 * 3c. Illustration animations — all keyed off .il-in on the card
 * ========================================================== */

/* strokes draw themselves (lengths measured in script) */
.il-card-vec [data-il-draw]{
  stroke-dashoffset:var(--len,0);
  transition:stroke-dashoffset 1.3s var(--il-ease);
  transition-delay:var(--dd,0ms);
}
.il-in .il-card-vec [data-il-draw]{stroke-dashoffset:0;}

/* elements scale in, staggered by --p */
.il-card-vec .il-pop{
  opacity:0;transform:scale(.68);
  transform-box:fill-box;transform-origin:50% 50%;
  transition:opacity .5s var(--il-ease), transform .62s var(--il-back);
  transition-delay:calc(260ms + var(--p,0) * 100ms);
}
.il-in .il-card-vec .il-pop{opacity:1;transform:none;}

/* bars grow up from their baseline */
.il-card-vec .il-bar{
  transform:scaleY(0);
  transform-box:fill-box;transform-origin:50% 100%;
  transition:transform .8s var(--il-ease);
  transition-delay:calc(320ms + var(--p,0) * 95ms);
}
.il-in .il-card-vec .il-bar{transform:none;}

/* data travelling the connector paths */
.il-card-vec .il-flow{opacity:0;transition:opacity .5s ease .7s;}
.il-in .il-card-vec .il-flow{opacity:1;}

/* ambient loops — parked until the card lands, so nothing burns
   frames while it is still off screen */
.il-card-vec .il-float,
.il-card-vec .il-ring,
.il-card-vec .il-spin{animation-play-state:paused;}
.il-in .il-card-vec .il-float,
.il-in .il-card-vec .il-ring,
.il-in .il-card-vec .il-spin{animation-play-state:running;}

.il-card-vec .il-float{
  animation:ilFloat 4.4s ease-in-out infinite;
  transform-box:fill-box;transform-origin:50% 50%;
}
@keyframes ilFloat{0%,100%{transform:translateY(0)}50%{transform:translateY(-7px)}}

.il-card-vec .il-ring{
  fill:none;
  animation:ilRing 3s ease-out infinite;
  transform-box:fill-box;transform-origin:50% 50%;
}
@keyframes ilRing{0%{transform:scale(.72);opacity:.85}100%{transform:scale(1.5);opacity:0}}

.il-card-vec .il-spin{
  transform-box:view-box;
  animation:ilSpin 24s linear infinite;
}
@keyframes ilSpin{to{transform:rotate(360deg)}}

/* ============================================================
 * 4. Page-wide entrances (outside the deck)
 * ========================================================== */
.il-anim .reveal{opacity:1;transform:none;transition:none;}

.il-anim .il-pill{
  opacity:0;transform:translateY(12px) scale(.9);
  clip-path:inset(0 42% 0 42% round 999px);
  transition:opacity .55s var(--il-ease,ease), transform .7s var(--il-back,ease), clip-path .7s var(--il-ease,ease);
  transition-delay:var(--d,0ms);
}
.il-anim .il-pill.il-in{opacity:1;transform:none;clip-path:inset(0 0 0 0 round 999px);}

/* heading words hinge up out of a clip mask */
.il-w{
  display:inline-block;overflow:hidden;vertical-align:bottom;
  padding-bottom:.2em;margin-bottom:-.2em;
  perspective:680px;
}
.il-w > i{
  display:inline-block;font-style:inherit;
  transform:translateY(116%) rotateX(-68deg);
  transform-origin:50% 0%;
  opacity:0;filter:blur(5px);
  transition:transform 1.05s var(--il-ease,ease), opacity .62s var(--il-ease,ease), filter .62s var(--il-ease,ease);
  transition-delay:var(--d,0ms);
}
.il-split.il-in .il-w > i{transform:none;opacity:1;filter:blur(0);}

.il-anim .il-fade{
  opacity:0;transform:translateY(18px);
  transition:opacity .85s var(--il-ease,ease), transform .85s var(--il-ease,ease);
  transition-delay:var(--d,0ms);
}
.il-anim .il-fade.il-in{opacity:1;transform:none;}

/* plain cards outside the deck hinge up from their bottom edge */
.il-anim .il-card{
  opacity:0;
  transform:perspective(1300px) rotateX(11deg) translateY(50px) scale(.955);
  transform-origin:50% 100%;
  transition:opacity .8s var(--il-ease,ease), transform 1.05s var(--il-ease,ease);
  transition-delay:var(--d,0ms);
}
.il-anim .il-card.il-in{opacity:1;transform:none;}

/* ============================================================
 * 5. Smaller screens — the deck unstacks into a normal column.
 *    A sticky stack needs vertical room a phone frame does not have.
 * ========================================================== */
@media (max-width:991px){
  .il-stack.bento{display:grid;grid-template-columns:1fr;gap:26px;}
  .il-stack > .feat{
    position:relative;
    min-height:0;
    margin-bottom:0;
    padding:28px 26px;
  }
  .il-stack > .feat.il-last{margin-bottom:0;}
  .il-stack-tail{display:none;}
  .il-stack > .feat .num{top:20px;right:22px;font-size:32px;}
  .il-stage{padding-bottom:88px;}
  .il-stage .section-head{margin-bottom:34px;}
  /* copy first, illustration beneath it */
  .il-stack > .feat.il-has-vec{grid-template-columns:1fr;gap:24px;}
  .il-card-vec{order:2;}
  .il-card-vec svg{max-height:210px;}
}
@media (max-width:575px){
  .il-stack > .feat{padding:24px 22px;}
  .il-stack > .feat .num{top:18px;right:18px;font-size:28px;}
  .il-points .il-point{font-size:13.5px;padding:9px 0 9px 22px;}
  .il-points .il-point::before{top:16px;width:7px;height:7px;}
  .il-card-vec{display:none;}   /* copy wins the space on a phone */
}

/* ============================================================
 * 6. Reduced motion — the script does not stack at all in this
 *    case, but keep the guard so nothing animates if it ever does.
 * ========================================================== */
@media (prefers-reduced-motion:reduce){
  .il-vortex{display:none;}
  .il-stack > .feat{position:relative;min-height:0;margin-bottom:26px;}
  .il-stack-tail{display:none;}
  .il-stack > .feat .feat-ico,
  .il-stack > .feat h3,
  .il-stack > .feat .tag,
  .il-stack > .feat .num,
  .il-stack > .feat > p,
  .il-stack > .feat ul li,
  .il-stack > .feat .il-points .il-point,
  .il-card-vec .il-pop,.il-card-vec .il-flow,
  .il-anim .il-pill,.il-anim .il-fade,.il-anim .il-card{
    opacity:1 !important;transform:none !important;
    filter:none !important;clip-path:none !important;transition:none !important;
  }
  .il-w > i{transform:none !important;opacity:1 !important;filter:none !important;transition:none !important;}
  .il-card-vec .il-bar{transform:none !important;transition:none !important;}
  .il-card-vec [data-il-draw]{stroke-dashoffset:0 !important;transition:none !important;}
  .il-card-vec .il-float,.il-card-vec .il-ring,.il-card-vec .il-spin{animation:none !important;}
}
@media print{
  .il-vortex{display:none !important;}
}

/* ============================================================
 * 7. Support for lusion-motion.js
 *
 * That script is shared with aboutus-lusion.html, where these rules
 * live in lusion-hero.css. This page does not load that file, so the
 * three things it depends on are repeated here. They are not
 * optional: without the .lx-roll rules the letter-roll leaves BOTH
 * copies of every character in the flow and the nav reads doubled.
 * ========================================================== */

/* The page stylesheet sets html{scroll-behavior:smooth}. Left in
   place it makes every scrollTo() in the lerp start a NEW native
   smooth animation that the next frame cancels — the page stalls,
   then lurches. */
html.lx-smooth{scroll-behavior:auto !important;}

.lx-roll{
  display:inline-block;
  overflow:hidden;
  vertical-align:top;
  line-height:inherit;
}
.lx-roll__c{
  display:inline-block;
  position:relative;
  white-space:pre;
  transition:transform .52s cubic-bezier(.22,.61,.36,1);
  transition-delay:calc(var(--i) * 18ms);
  will-change:transform;
}
.lx-roll__c span{display:block;}
.lx-roll__c span:last-child{position:absolute;left:0;top:100%;}
.lx-roll:hover .lx-roll__c,
a:hover .lx-roll .lx-roll__c,
button:hover .lx-roll .lx-roll__c{transform:translateY(-100%);}

.lx-mag{will-change:transform;}
.lx-mag__inner{display:inline-flex;align-items:center;gap:inherit;will-change:transform;}

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