/* ============================================================
 * maisy-stack.css — sticky card stack + animated card artwork
 * for the "What mAIsy can do" grid (#capabilities).
 *
 * Same technique as newassests/css/lusion-hero.css uses for
 * #story / #beliefs on aboutus-lusion.html: every card pins at
 * the same offset, so the next one rises from below and covers
 * it exactly — a deck being dealt.
 *
 * Purely additive. Every rule is scoped under .mx-stacked or
 * .mx-stack, both of which are added from script, so the page
 * outside the capability grid is untouched and no copy changes.
 *
 * Loaded AFTER maisy.html's own <style> block, so the two-class
 * selectors here win over .mod-card / .mod-list / .reveal
 * without needing !important.
 * ========================================================== */

.mx-stacked{
  /* where every card pins — clears the sticky header */
  --mx-stack-top: 104px;
  /* scroll distance between one card pinning and the next */
  --mx-stack-gap: 15vh;
  /* card height: tall enough that no dead frame shows beneath
     the pinned card while the next one travels up */
  --mx-stack-min: 52vh;
  /* the LAST card's entire stick room (see .mx-stack-tail) */
  --mx-stack-tail: 12vh;

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

  /* The tail below already provides the run-out, so the section's
     own bottom padding would only add empty space. */
  padding-bottom: 0;
}

/* ============================================================
 * 1. The stack itself
 * ========================================================== */

/* Grid -> block flow. The markup and the copy are untouched. */
.mx-stack.mod-list{display:block; margin-top:8px;}

/* An empty in-flow spacer, injected as the stack's last child.
   It has to be a real element: a sticky box is constrained by its
   containing block's CONTENT box, so padding-bottom on .mod-list
   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 it
   release early. */
.mx-stack-tail{
  display:block;
  height:var(--mx-stack-tail, 12vh);
  pointer-events:none;
}

.mx-stack > .mod-card{
  position:sticky;
  top:var(--mx-stack-top, 104px);
  margin-bottom:var(--mx-stack-gap, 15vh);
  min-height:var(--mx-stack-min, 52vh);
  width:100%;
  display:block;
  padding:38px 44px;
  background:var(--white);
  border:1px solid #EDF1F7;
  border-radius:var(--radius, 18px);

  /* The pin IS the entrance here, so the page's own .reveal
     offset has to be cleared: a transform on a sticky box fights
     the pin and makes it jitter. */
  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. */
  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 — drop it. */
.mx-stack > .mod-card:hover{
  transform:none;
  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);
  border-color:#E2D7F2;
}

/* The tail is the last card's stick room, so its own gap is dead
   space once the deck releases. */
.mx-stack > .mod-card.mx-last{margin-bottom:0;}

/* ============================================================
 * 2. Card layout: copy left, illustration right
 * ========================================================== */

.mx-stack > .mod-card.mx-has-vec{
  display:grid;
  grid-template-columns:minmax(0,1.04fr) minmax(0,.96fr);
  gap:46px;
  align-items:center;
}

/* The text column keeps the card's original icon-left arrangement. */
.mx-card-text{
  display:grid;
  grid-template-columns:auto 1fr;
  gap:22px;
  min-width:0;
}

.mx-card-vec{
  min-width:0;
  display:flex;
  align-items:center;
  justify-content:center;
}
.mx-card-vec svg{width:100%; height:auto; max-height:300px; overflow:visible;}

/* Position marker, top-right of the card. */
.mx-num{
  position:absolute;
  top:30px; right:36px;
  font-size:13px; font-weight:900;
  letter-spacing:.1em;
  color:var(--ink, #1B2436);
  line-height:1;
}
.mx-num em{font-style:normal; font-weight:800; color:var(--ink-faint, #8A93A3);}

/* Supporting lines, divided like the reference cards. */
.mx-points{list-style:none; margin:18px 0 0; padding:0;}
.mx-points .mx-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);
}
.mx-points .mx-point::before{
  content:"";
  position:absolute; left:3px; top:19px;
  width:8px; height:8px; border-radius:50%;
  background:var(--grad, linear-gradient(135deg,#701893,#1308AD));
}

/* ============================================================
 * 3. Card entrance — everything keys off .mx-in on the card, so
 *    one class toggle plays (and rewinds) the whole sequence.
 *    All transform / opacity / clip-path, so it composites on
 *    the GPU.
 * ========================================================== */

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

/* --- icon: pops in, then its glyph settles --- */
.mx-stack > .mod-card .mod-ico{
  opacity:0;
  transform:scale(.66) rotate(-10deg);
  transition:opacity .5s var(--mx-ease), transform .62s var(--mx-back);
  transition-delay:60ms;
}
.mx-stack > .mod-card.mx-in .mod-ico{opacity:1; transform:none;}

/* --- heading: rises out of a clip mask --- */
.mx-stack > .mod-card .mod-head h3{
  opacity:0;
  transform:translateY(16px);
  clip-path:inset(0 0 100% 0);
  transition:opacity .55s var(--mx-ease), transform .7s var(--mx-ease), clip-path .7s var(--mx-ease);
  transition-delay:150ms;
}
.mx-stack > .mod-card.mx-in .mod-head h3{
  opacity:1; transform:none; clip-path:inset(0 0 0 0);
}

/* --- badge: wipes open from the left without distorting its text --- */
.mx-stack > .mod-card .mod-badge{
  opacity:0;
  clip-path:inset(0 100% 0 0 round 999px);
  transition:opacity .35s var(--mx-ease), clip-path .65s var(--mx-ease);
  transition-delay:320ms;
}
.mx-stack > .mod-card.mx-in .mod-badge{opacity:1; clip-path:inset(0 0 0 0 round 999px);}

/* --- position number: drops in out of focus --- */
.mx-stack > .mod-card .mx-num{
  opacity:0;
  transform:translateY(-14px) scale(1.3);
  filter:blur(6px);
  transition:opacity .7s var(--mx-ease), transform .85s var(--mx-ease), filter .7s var(--mx-ease);
  transition-delay:90ms;
}
.mx-stack > .mod-card.mx-in .mx-num{opacity:1; transform:none; filter:blur(0);}

/* --- the card's own bullets: stagger up, left to right --- */
.mx-stack > .mod-card ul li{
  opacity:0;
  transform:translateY(10px);
  transition:opacity .45s var(--mx-ease), transform .55s var(--mx-ease);
  transition-delay:calc(240ms + var(--i, 0) * 70ms);
}
.mx-stack > .mod-card.mx-in ul li{opacity:1; transform:none;}

/* --- injected supporting lines: later, and their rule wipes in --- */
.mx-stack > .mod-card .mx-points .mx-point{
  opacity:0;
  transform:translateY(12px);
  transition:opacity .5s var(--mx-ease), transform .6s var(--mx-ease);
  transition-delay:calc(420ms + var(--i, 0) * 95ms);
}
.mx-stack > .mod-card.mx-in .mx-points .mx-point{opacity:1; transform:none;}

/* ============================================================
 * 4. Illustration animations
 * ========================================================== */

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

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

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

/* ---- ambient loops: parked until the card lands, so nothing
        burns frames off screen ---- */
.mx-card-vec .mx-float,
.mx-card-vec .mx-ring,
.mx-card-vec .mx-eq{animation-play-state:paused;}
.mx-in .mx-card-vec .mx-float,
.mx-in .mx-card-vec .mx-ring,
.mx-in .mx-card-vec .mx-eq{animation-play-state:running;}

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

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

/* The equaliser starts only once the bars have grown, so the
   entrance transition is never cut short by the loop. */
.mx-card-vec .mx-eq{
  animation:mxEq 1.5s ease-in-out infinite;
  animation-delay:calc(1100ms + var(--p, 0) * 90ms);
  transform-box:fill-box; transform-origin:50% 100%;
}
@keyframes mxEq{0%,100%{transform:scaleY(1)} 50%{transform:scaleY(var(--a, .55))}}

/* ============================================================
 * 5. Smaller screens — the deck unstacks into a normal column.
 *    A sticky stack needs vertical room the phone frame does not
 *    have, so the cards simply flow, keeping their new artwork.
 * ========================================================== */
@media (max-width: 991px){
  .mx-stacked{padding-bottom:88px;}
  .mx-stack.mod-list{display:grid; grid-template-columns:1fr; gap:26px;}
  /* relative, not static: .mx-num is absolutely positioned and must
     stay anchored to its own card once the pin is dropped */
  .mx-stack > .mod-card{
    position:relative;
    min-height:0;
    margin-bottom:0;
    padding:28px 28px;
  }
  .mx-stack > .mod-card.mx-last{margin-bottom:0;}
  .mx-stack > .mod-card.mx-has-vec{grid-template-columns:1fr; gap:26px;}
  .mx-stack-tail{display:none;}
  .mx-card-vec{order:2;}
  .mx-card-vec svg{max-height:230px;}
  .mx-num{top:20px; right:22px;}
}

@media (max-width: 575px){
  .mx-card-text{grid-template-columns:1fr; gap:16px;}
  .mx-stack > .mod-card{padding:24px 22px;}
  .mx-num{top:18px; right:18px; font-size:12px;}
}

/* ============================================================
 * 6. Reduced motion — the script does not stack at all in this
 *    case, but keep the guard here so nothing can animate if the
 *    classes ever land anyway.
 * ========================================================== */
@media (prefers-reduced-motion: reduce){
  .mx-stack > .mod-card{position:relative; min-height:0; margin-bottom:26px;}
  .mx-stack-tail{display:none;}
  .mx-stack > .mod-card .mod-ico,
  .mx-stack > .mod-card .mod-head h3,
  .mx-stack > .mod-card .mod-badge,
  .mx-stack > .mod-card .mx-num,
  .mx-stack > .mod-card ul li,
  .mx-stack > .mod-card .mx-points .mx-point,
  .mx-card-vec .mx-pop{
    opacity:1 !important;
    transform:none !important;
    filter:none !important;
    clip-path:none !important;
    transition:none !important;
  }
  .mx-card-vec .mx-bar{transform:none !important; transition:none !important;}
  .mx-card-vec [data-mx-draw]{stroke-dashoffset:0 !important; transition:none !important;}
  .mx-card-vec .mx-float,
  .mx-card-vec .mx-ring,
  .mx-card-vec .mx-eq{animation:none !important;}
}
