/* ===========================================================================
 * Homepage Hero Animated Image
 * ---------------------------------------------------------------------------
 * Stage canvas: 800 x 600 (matches the source SVG viewBox).
 * Each layer's PNG includes its own drop shadow which extends asymmetrically
 * (mostly downward). To keep the VISIBLE CARD anchored to the design point,
 * each layer defines a custom rest-pose translate via --rest-x / --rest-y.
 * That offset is auto-derived from the visible-content bbox vs the PNG bbox.
 *
 * Choreography summary (each numbered block below has its own
 * "WHEN / HOW / FROM / TO" header for easy editing):
 *
 *   1. background           0ms     fade in + scale 0.95 -> 1
 *   2. logos-box-background 450ms   fade in + slide up 20px
 *   3. logos-box            600ms   fade in + slide in from left 40px
 *   4. contract-box         950ms   fade in + scale 0.85 -> 1
 *   5. checkmark            1150ms  fade in + scale 0 -> 1.12 -> 1 overshoot
 *   6. order-in-progress    1500ms  fade in + slide down from above 30px
 *   7. price-duration       1800ms  fade in + scale 0.9 -> 1
 *   8. paid-button          2050ms  fade in + slide in from left 40px
 *
 * Every adjustable knob is called out with a "EDIT:" comment.
 * =========================================================================== */

:root {
  /* =====================================================================
   *  TIMING KNOBS — edit these two values to retime the whole sequence.
   *  Both knobs apply to every entrance delay/duration and to the start
   *  delay of the ambient float effect (but NOT to the float's cycle
   *  speed — that stays as its own ambient pace).
   * ===================================================================== */
  --hero-anim-scale: 1.3;       /* 1 = current speed; 2 = 2× slower; 0.5 = 2× faster */
  --hero-anim-start: 250ms;     /* extra delay before the whole sequence begins */

  --hero-ease-out:       cubic-bezier(0.22, 0.61, 0.36, 1);
  --hero-ease-overshoot: cubic-bezier(0.34, 1.56, 0.64, 1);
}

/* Registered custom property so the browser can smoothly interpolate it via
 * @keyframes. Without @property, the var would snap between values rather
 * than animate. Supported in Chrome 85+, Safari 16.4+, Firefox 128+. */
@property --float-y {
  syntax: "<length>";
  inherits: false;
  initial-value: 0px;
}

/* ===========================================================================
 *  SECTION + STAGE
 * =========================================================================== */

section.hero-anim-img {
  width: 100%;
  display: flex;
  justify-content: center;
  overflow-x: clip;
}

.hero-anim-img__stage {
  position: relative;
  width: 100%;
  aspect-ratio: 800 / 600;
  margin: 0 auto;
}

@supports not (aspect-ratio: 1) {
  .hero-anim-img__stage::before {
    content: "";
    display: block;
    padding-top: 75%;
  }
}

/* ===========================================================================
 *  LAYER BASE
 *  Defaults that every layer inherits. Per-layer rest-pose offsets and
 *  reveal states are in the labeled blocks below.
 *
 *  Each layer sets --rest-x and --rest-y (translate percentages) so that the
 *  visible card content lands on the design coordinate, regardless of how
 *  much shadow bleed the PNG carries.
 * =========================================================================== */

.hero-anim-img__layer {
  position: absolute;
  height: auto;
  max-width: none;
  pointer-events: none;
  user-select: none;
  -webkit-user-drag: none;
  will-change: transform, opacity;
  opacity: 0;                                  /* EDIT: starting opacity (all layers) */
  --rest-x: -50%;                              /* default — overridden per layer */
  --rest-y: -50%;
  transform: translate(var(--rest-x), var(--rest-y));
  transition:
    opacity   calc(600ms * var(--hero-anim-scale)) var(--hero-ease-out),   /* EDIT: default fade duration */
    transform calc(700ms * var(--hero-anim-scale)) var(--hero-ease-out);   /* EDIT: default move/scale duration */
}

/* All layers fade in when the stage scrolls into view. Per-layer transforms
 * and delays are set in the blocks below. (The checkmark overrides this via
 * its own @keyframes — that's intentional.) */
.hero-anim-img__stage.is-visible .hero-anim-img__layer {
  opacity: 1;
}


/* ===========================================================================
 *  ╔══════════════════════════════════════════════════════════════════════╗
 *  ║  LAYER 1 — BACKGROUND                                                ║
 *  ║  The big rounded card with the blue strip on top (sits behind all).  ║
 *  ║  PNG: 2400 x 1752  |  shadow offset from PNG center: (0, -10) px     ║
 *  ║  WHEN: 0ms     HOW: fade in + scale 0.95 -> 1                        ║
 *  ╚══════════════════════════════════════════════════════════════════════╝ */
.hero-anim-img__layer--background {
  --rest-x: -50.00%;
  --rest-y: -49.40%;
  /* Position ------------------------------------------------------------- */
  left:  50.00%;
  top:   50.00%;
  width: 100.00%;                                /* EDIT: PNG width as % of stage */
  z-index: 1;
  /* Start state — scaled down 5% ---------------------------------------- */
  transform: translate(var(--rest-x), var(--rest-y)) scale(0.95);  /* EDIT: start scale */
}
.hero-anim-img__stage.is-visible .hero-anim-img__layer--background {
  transform: translate(var(--rest-x), var(--rest-y)) scale(1);
  transition-delay: calc(0ms * var(--hero-anim-scale) + var(--hero-anim-start));     /* EDIT: when this layer starts */
  transition-duration:
    calc(800ms * var(--hero-anim-scale)),
    calc(800ms * var(--hero-anim-scale));        /* EDIT: how long this layer takes */
}


/* ===========================================================================
 *  ╔══════════════════════════════════════════════════════════════════════╗
 *  ║  LAYER 2 — LOGOS BOX BACKGROUND                                      ║
 *  ║  The white card that sits behind the supplier rows.                  ║
 *  ║  PNG: 1008 x 996   |  shadow offset from PNG center: (0, -49) px     ║
 *  ║  WHEN: 450ms   HOW: fade in + slide up 20px                          ║
 *  ╚══════════════════════════════════════════════════════════════════════╝ */
.hero-anim-img__layer--logos-box-background {
  --rest-x: -50.05%;
  --rest-y: -45.08%;
  /* Position ------------------------------------------------------------- */
  left:  47.92%;
  top:   34.45%;
  width: 42.00%;
  z-index: 2;
  /* Start state — 20px below rest ---------------------------------------- */
  transform: translate(var(--rest-x), calc(var(--rest-y) + 20px));   /* EDIT: 20px = how far below it starts */
}
.hero-anim-img__stage.is-visible .hero-anim-img__layer--logos-box-background {
  transform: translate(var(--rest-x), var(--rest-y));
  transition-delay: calc(450ms * var(--hero-anim-scale) + var(--hero-anim-start));    /* EDIT: when this layer starts */
}


/* ===========================================================================
 *  ╔══════════════════════════════════════════════════════════════════════╗
 *  ║  LAYER 3 — LOGOS BOX                                                 ║
 *  ║  The Charles River / CrownBio / PHARBARON ratings rows.              ║
 *  ║  PNG: 671 x 623    |  shadow offset from PNG center: (0, -2) px      ║
 *  ║  WHEN: 600ms   HOW: fade in + slide in from left 40px                ║
 *  ╚══════════════════════════════════════════════════════════════════════╝ */
.hero-anim-img__layer--logos-box {
  --rest-x: -49.93%;
  --rest-y: -49.60%;
  /* Position ------------------------------------------------------------- */
  left:  47.91%;
  top:   32.33%;
  width: 27.96%;
  z-index: 3;
  /* Start state — 40px left of rest -------------------------------------- */
  transform: translate(calc(var(--rest-x) - 40px), var(--rest-y));   /* EDIT: -40px = how far left it starts */
}
.hero-anim-img__stage.is-visible .hero-anim-img__layer--logos-box {
  transform: translate(var(--rest-x), var(--rest-y));
  transition-delay: calc(600ms * var(--hero-anim-scale) + var(--hero-anim-start));    /* EDIT: when this layer starts */
}


/* ===========================================================================
 *  ╔══════════════════════════════════════════════════════════════════════╗
 *  ║  LAYER 4 — CONTRACT BOX                                              ║
 *  ║  CONTRACT card with placeholder lines (bottom-left).                 ║
 *  ║  PNG: 812 x 753    |  shadow offset from PNG center: (0, -94) px     ║
 *  ║  WHEN: 950ms   HOW: fade in + scale 0.85 -> 1                        ║
 *  ╚══════════════════════════════════════════════════════════════════════╝ */
.hero-anim-img__layer--contract-box {
  --rest-x: -49.94%;
  --rest-y: -37.58%;
  /* Position ------------------------------------------------------------- */
  left:  20.09%;
  top:   72.57%;
  width: 33.83%;
  z-index: 4;
  /* Start state — scaled down 15% ---------------------------------------- */
  transform: translate(var(--rest-x), var(--rest-y)) scale(0.85);    /* EDIT: start scale */
}
.hero-anim-img__stage.is-visible .hero-anim-img__layer--contract-box {
  transform: translate(var(--rest-x), var(--rest-y)) scale(1);
  transition-delay: calc(950ms * var(--hero-anim-scale) + var(--hero-anim-start));    /* EDIT: when this layer starts */
  transition-duration:
    calc(500ms * var(--hero-anim-scale)),
    calc(550ms * var(--hero-anim-scale));        /* EDIT: fade dur, scale dur */
}


/* ===========================================================================
 *  ╔══════════════════════════════════════════════════════════════════════╗
 *  ║  LAYER 5 — CHECKMARK                                                 ║
 *  ║  Gradient (purple → pink) checkmark badge atop contract-box.         ║
 *  ║  PNG: 409 x 438    |  shadow offset from PNG center: (-14, -75) px   ║
 *  ║  WHEN: 1150ms  HOW: fade in + scale 0 -> 1.12 -> 1 (overshoot)       ║
 *  ║  NOTE: uses @keyframes for the 1.12 overshoot.                       ║
 *  ╚══════════════════════════════════════════════════════════════════════╝ */
.hero-anim-img__layer--checkmark {
  --rest-x: -46.45%;
  --rest-y: -32.88%;
  /* Position ------------------------------------------------------------- */
  left:   7.91%;
  top:   60.38%;
  width: 17.04%;
  z-index: 5;
  /* Disable transitions so only the keyframe animation drives the entrance */
  transition: none;
  transform: translate(var(--rest-x), calc(var(--rest-y) + var(--float-y))) scale(0);
}
.hero-anim-img__stage.is-visible .hero-anim-img__layer--checkmark {
  /* Final pose — references --float-y so the float can take over after the
     pop animation finishes. `backwards` fill on the pop holds the 0%
     keyframe (opacity 0, scale 0) during the 1150ms delay, so the checkmark
     stays hidden until its pop fires — but we don't use `forwards`, so the
     element returns to this static rule after the pop ends, which lets the
     float animation drive --float-y from then on. */
  transform: translate(var(--rest-x), calc(var(--rest-y) + var(--float-y))) scale(1);
  animation:
    hero-checkmark-pop
      calc(650ms * var(--hero-anim-scale))
      var(--hero-ease-overshoot)
      calc(1150ms * var(--hero-anim-scale) + var(--hero-anim-start))
      1 backwards,
    hero-float-checkmark
      3s
      var(--hero-ease-out)
      calc(2200ms * var(--hero-anim-scale) + var(--hero-anim-start))
      infinite alternate;
  /* EDIT: pop delay/dur (1150ms/650ms); float starts at 2200ms, half-cycle 3s */
}

@keyframes hero-checkmark-pop {
  0%   { opacity: 0; transform: translate(-46.45%, calc(-32.88% + var(--float-y))) scale(0);    }
  60%  { opacity: 1; transform: translate(-46.45%, calc(-32.88% + var(--float-y))) scale(1.12); }  /* EDIT: 1.12 = overshoot peak */
  100% { opacity: 1; transform: translate(-46.45%, calc(-32.88% + var(--float-y))) scale(1);    }
}


/* ===========================================================================
 *  ╔══════════════════════════════════════════════════════════════════════╗
 *  ║  LAYER 6 — ORDER IN PROGRESS                                         ║
 *  ║  Top-right pill with yellow dot.                                     ║
 *  ║  PNG: 1100 x 624   |  shadow offset from PNG center: (-1, -90) px    ║
 *  ║  WHEN: 1500ms  HOW: fade in + slide down 30px (from above)           ║
 *  ╚══════════════════════════════════════════════════════════════════════╝ */
.hero-anim-img__layer--order-in-progress {
  --rest-x: -49.91%;
  --rest-y: -35.50%;
  /* Position ------------------------------------------------------------- */
  left:  77.04%;
  top:   30.90%;
  width: 45.83%;
  z-index: 6;
  /* Start state — 30px above rest --------------------------------------- */
  transform: translate(var(--rest-x), calc(var(--rest-y) - 30px + var(--float-y)));   /* EDIT: -30px = how far above it starts */
}
.hero-anim-img__stage.is-visible .hero-anim-img__layer--order-in-progress {
  transform: translate(var(--rest-x), calc(var(--rest-y) + var(--float-y)));
  transition-delay: calc(1500ms * var(--hero-anim-scale) + var(--hero-anim-start));   /* EDIT: when this layer starts */
  animation: hero-float-order 3.2s var(--hero-ease-out)
    calc(2500ms * var(--hero-anim-scale) + var(--hero-anim-start))
    infinite alternate;
  /* EDIT: float starts at 2500ms (~200ms after entrance ends), 3.2s per half-cycle */
}


/* ===========================================================================
 *  ╔══════════════════════════════════════════════════════════════════════╗
 *  ║  LAYER 7 — PRICE / DURATION                                          ║
 *  ║  The $52,750.00 / 3 Months card (bottom-center).                     ║
 *  ║  PNG: 1362 x 1033  |  shadow offset from PNG center: (0, -40) px     ║
 *  ║  WHEN: 1800ms  HOW: fade in + scale 0.9 -> 1                         ║
 *  ╚══════════════════════════════════════════════════════════════════════╝ */
.hero-anim-img__layer--price-duration {
  --rest-x: -49.96%;
  --rest-y: -46.13%;
  /* Position ------------------------------------------------------------- */
  left:  60.19%;
  top:   72.57%;
  width: 56.75%;
  z-index: 7;
  /* Start state — scaled down 10% ---------------------------------------- */
  transform: translate(var(--rest-x), var(--rest-y)) scale(0.9);     /* EDIT: start scale */
}
.hero-anim-img__stage.is-visible .hero-anim-img__layer--price-duration {
  transform: translate(var(--rest-x), var(--rest-y)) scale(1);
  transition-delay: calc(1800ms * var(--hero-anim-scale) + var(--hero-anim-start));   /* EDIT: when this layer starts */
}


/* ===========================================================================
 *  ╔══════════════════════════════════════════════════════════════════════╗
 *  ║  LAYER 8 — PAID BUTTON                                               ║
 *  ║  Green pill badge with checkmark + "PAID" (bottom-right).            ║
 *  ║  PNG: 776 x 443    |  shadow offset from PNG center: (-2, -90) px    ║
 *  ║  WHEN: 2050ms  HOW: fade in + slide in from left 40px                ║
 *  ╚══════════════════════════════════════════════════════════════════════╝ */
.hero-anim-img__layer--paid-button {
  --rest-x: -49.81%;
  --rest-y: -29.57%;
  /* Position ------------------------------------------------------------- */
  left:  72.31%;
  top:   84.93%;
  width: 32.33%;
  z-index: 8;
  /* Start state — 40px left of rest -------------------------------------- */
  transform: translate(calc(var(--rest-x) - 40px), calc(var(--rest-y) + var(--float-y)));   /* EDIT: -40px = how far left it starts */
}
.hero-anim-img__stage.is-visible .hero-anim-img__layer--paid-button {
  transform: translate(var(--rest-x), calc(var(--rest-y) + var(--float-y)));
  transition-delay: calc(2050ms * var(--hero-anim-scale) + var(--hero-anim-start));   /* EDIT: when this layer starts */
  animation: hero-float-paid 3.6s var(--hero-ease-out)
    calc(3000ms * var(--hero-anim-scale) + var(--hero-anim-start))
    infinite alternate;
  /* EDIT: float starts at 3000ms (~250ms after entrance ends), 3.6s per half-cycle */
}


/* ===========================================================================
 *  FLOATING EFFECT
 *  Three badge layers gently bob up-and-down after the entrance choreography
 *  completes. Each uses a slightly different cycle so they don't sync up,
 *  which keeps the motion feeling organic rather than mechanical.
 *
 *  Direction is `alternate`, so each animation goes 0 → target → 0 → target,
 *  i.e. it bobs up, back to rest, up, back to rest, forever.
 * =========================================================================== */

@keyframes hero-float-order {
  to { --float-y: -6px; }    /* EDIT: -6px = how far order-in-progress rises */
}
@keyframes hero-float-paid {
  to { --float-y: -7px; }    /* EDIT: -7px = how far paid-button rises */
}
@keyframes hero-float-checkmark {
  to { --float-y: -5px; }    /* EDIT: -5px = how far the checkmark rises */
}


/* ===========================================================================
 *  REDUCED MOTION
 *  Skip all animation when reduced-motion is preferred; keep each layer's
 *  per-card rest offset so the visible card still lands correctly.
 * =========================================================================== */

.hero-anim-img__stage.is-reduced .hero-anim-img__layer {
  opacity: 1;
  animation: none;
  transition: none;
}
.hero-anim-img__stage.is-reduced .hero-anim-img__layer { transform: translate(var(--rest-x), var(--rest-y)); }
.hero-anim-img__stage.is-reduced .hero-anim-img__layer--background,
.hero-anim-img__stage.is-reduced .hero-anim-img__layer--contract-box,
.hero-anim-img__stage.is-reduced .hero-anim-img__layer--checkmark,
.hero-anim-img__stage.is-reduced .hero-anim-img__layer--price-duration {
  transform: translate(var(--rest-x), var(--rest-y)) scale(1);
}

@media (prefers-reduced-motion: reduce) {
  .hero-anim-img__layer {
    opacity: 1;
    animation: none;
    transition: none;
    transform: translate(var(--rest-x), var(--rest-y));
  }
  .hero-anim-img__layer--background,
  .hero-anim-img__layer--contract-box,
  .hero-anim-img__layer--checkmark,
  .hero-anim-img__layer--price-duration {
    transform: translate(var(--rest-x), var(--rest-y)) scale(1);
  }
}


/* ===========================================================================
 *  CALIBRATION OVERLAY (debug aid)
 *  Add class "show-reference" to .hero-anim-img__stage in DevTools to render
 *  the flat composite at 35% opacity on top, for eyeballing positions.
 * =========================================================================== */

.hero-anim-img__stage.show-reference::after {
  content: "";
  position: absolute;
  inset: 0;
  background: url("https://info.scienceexchange.com/hubfs/Landing%20Page%20Assets/homepage-hero-animated-image-partials/reference.webp") no-repeat center / contain;
  opacity: 0.35;
  pointer-events: none;
  z-index: 100;
}


/* ===========================================================================
 *  RESPONSIVE
 * =========================================================================== */

@media (max-width: 600px) {
  .hero-anim-img__layer {
    transition-duration: 500ms, 600ms;
  }
}

@media (min-width:1030px) {
 .hero-anim-img {
   transform:scale(1.2);
   transform-origin:left center;
  }
}