/* ==========================================================================
   SCHOLARBRIDGE — scroll animations.
   IMPORTANT: hiding (opacity:0) is declared ONLY under the `.js` class,
   so content is always visible if JavaScript is disabled or fails.
   A safety-net in main.js force-reveals everything a few seconds after load.
   ========================================================================== */

/* ---------- Base reveal states (JS-on only) ---------- */
.js .reveal{opacity:0;transform:translateY(26px);transition:opacity .7s ease,transform .7s cubic-bezier(.22,.61,.36,1)}
.js .reveal-zoom{opacity:0;transform:scale(.94);transition:opacity .7s ease,transform .8s cubic-bezier(.22,.61,.36,1)}
.js .reveal-left{opacity:0;transform:translateX(-30px);transition:opacity .7s ease,transform .7s cubic-bezier(.22,.61,.36,1)}
.js .reveal-right{opacity:0;transform:translateX(30px);transition:opacity .7s ease,transform .7s cubic-bezier(.22,.61,.36,1)}
.js .reveal-up{opacity:0;transform:translateY(-24px);transition:opacity .7s ease,transform .7s cubic-bezier(.22,.61,.36,1)}

.js .reveal.revealed,
.js .reveal-zoom.revealed,
.js .reveal-left.revealed,
.js .reveal-right.revealed,
.js .reveal-up.revealed{opacity:1;transform:none}

/* Staggered children */
.js .stagger>*{opacity:0;transform:translateY(24px);transition:opacity .6s ease,transform .6s ease}
.js .stagger.revealed>*{opacity:1;transform:none}
.js .stagger.revealed>*:nth-child(1){transition-delay:.05s}
.js .stagger.revealed>*:nth-child(2){transition-delay:.13s}
.js .stagger.revealed>*:nth-child(3){transition-delay:.21s}
.js .stagger.revealed>*:nth-child(4){transition-delay:.29s}
.js .stagger.revealed>*:nth-child(5){transition-delay:.37s}
.js .stagger.revealed>*:nth-child(6){transition-delay:.45s}

/* Prefers-reduced-motion: never hide content */
@media (prefers-reduced-motion:reduce){
  .js .reveal,.js .reveal-zoom,.js .reveal-left,.js .reveal-right,.js .reveal-up,.js .stagger>*{opacity:1!important;transform:none!important;transition:none!important}
}

/* ---------- Text reveal (split lines, JS-driven) ---------- */
.text-mask{overflow:hidden;display:block}
.text-mask>*{display:block;transform:translateY(110%);transition:transform .8s cubic-bezier(.22,.61,.36,1)}
.js .revealed .text-mask>*{transform:none}
.js .reveal.revealed .text-mask>*{transform:none}

/* ---------- Counter dots / floaters ---------- */
.floating{animation:floaty 6s ease-in-out infinite}
.floating.slow{animation-duration:9s}
@keyframes floaty{0%,100%{transform:translateY(0)}50%{transform:translateY(-16px)}}

@media (prefers-reduced-motion:reduce){.floating{animation:none}}

/* ---------- Timeline dots pulse ---------- */
.t-step-num{animation:pulse-ring 3.2s ease-out infinite}
@keyframes pulse-ring{0%{box-shadow:0 0 0 0 rgba(240,163,48,.45);}70%{box-shadow:0 0 0 14px rgba(240,163,48,0);}100%{box-shadow:0 0 0 0 rgba(240,163,48,0)}}
@media (prefers-reduced-motion:reduce){.t-step-num{animation:none}}

/* ---------- Parallax helpers ---------- */
.parallax-bg{background-attachment:fixed;background-size:cover;background-position:center}
@media (hover:none),(max-width:820px){.parallax-bg{background-attachment:scroll}}

/* ---------- Gradient shift ---------- */
.gradient-anim{background:linear-gradient(120deg,#17233f,#22335e,#2f9e77,#17233f);background-size:400% 400%;animation:gradshift 16s ease infinite}
@keyframes gradshift{0%,100%{background-position:0% 50%}50%{background-position:100% 50%}}
@media (prefers-reduced-motion:reduce){.gradient-anim{animation:none;background-size:100%}}

/* ---------- Skeleton shimmer (progress-aware) ---------- */
.skeleton{position:relative;overflow:hidden;background:#edf1f7}
.skeleton::after{content:"";position:absolute;inset:0;background:linear-gradient(90deg,transparent,rgba(255,255,255,.65),transparent);animation:shimmer 1.4s infinite}
@keyframes shimmer{from{transform:translateX(-100%)}to{transform:translateX(100%)}}
@media (prefers-reduced-motion:reduce){.skeleton::after{animation:none}}