/* ═══════════════════════════════════════════════════════════════════
   Aadhyayan — "Campus journey" hero scene
   Colleges & Universities page.

   A four-act story on one shared 24s timeline:
     Act 1  0–25%   Arrival — guard salutes, boom barrier lifts, student walks in
     Act 2 25–50%   Reception — student crosses the lobby, receptionist waves
     Act 3 50–75%   Guidance — receptionist explains courses, student listens
     Act 4 75–100%  Admitted — offer letter, confetti, celebration

   Everything is driven by percentage windows on ONE duration, so the acts
   can never drift out of sync with each other the way independent loops do.
   No JS, no requestAnimationFrame — the compositor runs it all.

   Only `transform` and `opacity` are animated (both GPU-composited); no
   layout or paint properties, so this stays cheap on mid-range Android
   where the directory grid below is already doing work.
   ═══════════════════════════════════════════════════════════════════ */

.cs-wrap {
  --cs-dur: 24s;
  position: relative;
  width: 100%;
  max-width: 560px;
  margin-inline: auto;
}

.cs-stage {
  width: 100%;
  height: auto;
  display: block;
  overflow: visible;
  /* fill-box keeps every rotation origin local to its own shape rather
     than the whole SVG canvas — without it, limbs swing around the sky. */
  transform-box: fill-box;
}

.cs-stage * { transform-box: fill-box; }

/* ── Act visibility ────────────────────────────────────────────────── */
.cs-act { opacity: 0; }
.cs-act > * { transform-box: fill-box; }

.cs-act-1 { animation: csAct1 var(--cs-dur) linear infinite; }
.cs-act-2 { animation: csAct2 var(--cs-dur) linear infinite; }
.cs-act-3 { animation: csAct3 var(--cs-dur) linear infinite; }
.cs-act-4 { animation: csAct4 var(--cs-dur) linear infinite; }

@keyframes csAct1 { 0% {opacity:0} 1.5%,22% {opacity:1} 24.5%,100% {opacity:0} }
@keyframes csAct2 { 0%,23% {opacity:0} 26.5%,47% {opacity:1} 49.5%,100% {opacity:0} }
@keyframes csAct3 { 0%,48% {opacity:0} 51.5%,72% {opacity:1} 74.5%,100% {opacity:0} }
@keyframes csAct4 { 0%,73% {opacity:0} 76.5%,97.5% {opacity:1} 100% {opacity:0} }

/* Each act drifts in slightly — a gentle camera push that makes the cut
   read as a scene change rather than a slide swap. */
.cs-push-1 { animation: csPush1 var(--cs-dur) linear infinite; }
.cs-push-2 { animation: csPush2 var(--cs-dur) linear infinite; }
.cs-push-3 { animation: csPush3 var(--cs-dur) linear infinite; }
.cs-push-4 { animation: csPush4 var(--cs-dur) linear infinite; }

@keyframes csPush1 { 0% {transform:scale(1.04)} 24% {transform:scale(1)} 100% {transform:scale(1)} }
@keyframes csPush2 { 0%,25% {transform:scale(1.04)} 49% {transform:scale(1)} 100% {transform:scale(1)} }
@keyframes csPush3 { 0%,50% {transform:scale(1.04)} 74% {transform:scale(1)} 100% {transform:scale(1)} }
@keyframes csPush4 { 0%,75% {transform:scale(1.05)} 99% {transform:scale(1)} 100% {transform:scale(1)} }

/* ── Ambient: clouds drift the whole way through ───────────────────── */
.cs-cloud-a { animation: csCloudA 38s linear infinite; }
.cs-cloud-b { animation: csCloudB 52s linear infinite; }
@keyframes csCloudA { from {transform:translateX(-40px)} to {transform:translateX(600px)} }
@keyframes csCloudB { from {transform:translateX(-120px)} to {transform:translateX(620px)} }

/* ═══ ACT 1 — ARRIVAL ══════════════════════════════════════════════ */

/* Boom barrier. Anticipation: it dips a touch before lifting, which is
   what makes a hinge read as having weight instead of snapping. */
.cs-barrier {
  animation: csBarrier var(--cs-dur) linear infinite;
}
@keyframes csBarrier {
  0%, 7%      { transform: rotate(0deg); }
  8.5%        { transform: rotate(3deg); }        /* dip — anticipation */
  13%         { transform: rotate(-74deg); }      /* lift */
  14.5%       { transform: rotate(-69deg); }      /* small settle back */
  15.5%, 22%  { transform: rotate(-72deg); }
  24%, 100%   { transform: rotate(0deg); }
}

/* Guard raises an arm to wave the student through, then lowers it. */
.cs-guard-arm { animation: csGuardArm var(--cs-dur) linear infinite; }
@keyframes csGuardArm {
  0%, 5%     { transform: rotate(0deg); }
  8%, 13%    { transform: rotate(-104deg); }
  18%        { transform: rotate(-96deg); }
  21%, 100%  { transform: rotate(0deg); }
}
/* Weight shift as he turns to follow the student. */
.cs-guard { animation: csGuard var(--cs-dur) linear infinite; }
@keyframes csGuard {
  0%, 6%    { transform: translateX(0) rotate(0deg); }
  10%       { transform: translateX(1px) rotate(-2deg); }
  20%, 100% { transform: translateX(0) rotate(0deg); }
}

/* Student 1 — walks in from off-stage left, pauses at the barrier,
   then continues through once it is up. */
.cs-s1 { animation: csS1Walk var(--cs-dur) cubic-bezier(.45,.05,.55,.95) infinite; }
/* Offsets are relative to the figure's base translate(236 230), so x=-270
   puts him at scene x=-34 — genuinely off-stage on the road, not popped in
   mid-frame. He halts at x=108, short of both the guard (150) and the
   barrier pivot (182), then walks clear through to x=340. */
@keyframes csS1Walk {
  0%        { transform: translateX(-270px); }  /* off-stage, on the road */
  9%        { transform: translateX(-128px); }  /* reaches the gate */
  12%       { transform: translateX(-128px); }  /* waits for the barrier */
  22%       { transform: translateX(104px); }   /* walks through */
  24%, 100% { transform: translateX(104px); }
}
/* Vertical bob, twice per stride — the thing that stops a walk looking
   like a sprite sliding across the floor. */
.cs-s1-bob { animation: csBob 0.52s ease-in-out infinite; }
@keyframes csBob {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(-1.6px); }
}
.cs-s1-legF { animation: csLegF 1.04s ease-in-out infinite; }
.cs-s1-legB { animation: csLegB 1.04s ease-in-out infinite; }
.cs-s1-armF { animation: csArmF 1.04s ease-in-out infinite; }
.cs-s1-armB { animation: csArmB 1.04s ease-in-out infinite; }

/* Counter-phase limbs: front leg forward while front arm swings back. */
@keyframes csLegF {
  0%, 100% { transform: rotate(24deg); }
  50%      { transform: rotate(-22deg); }
}
@keyframes csLegB {
  0%, 100% { transform: rotate(-22deg); }
  50%      { transform: rotate(24deg); }
}
@keyframes csArmF {
  0%, 100% { transform: rotate(-20deg); }
  50%      { transform: rotate(18deg); }
}
@keyframes csArmB {
  0%, 100% { transform: rotate(18deg); }
  50%      { transform: rotate(-20deg); }
}

/* ═══ ACT 2 — RECEPTION ════════════════════════════════════════════ */

.cs-s2 { animation: csS2Walk var(--cs-dur) cubic-bezier(.4,.05,.5,.95) infinite; }
@keyframes csS2Walk {
  0%, 26%   { transform: translateX(-290px); }  /* enters off-stage left */
  40%       { transform: translateX(14px); }    /* reaches the desk at x=250 */
  49%, 100% { transform: translateX(14px); }
}
.cs-s2-bob  { animation: csBob 0.52s ease-in-out infinite; }
.cs-s2-legF { animation: csLegF 1.04s ease-in-out infinite; }
.cs-s2-legB { animation: csLegB 1.04s ease-in-out infinite; }
.cs-s2-armF { animation: csArmF 1.04s ease-in-out infinite; }
.cs-s2-armB { animation: csArmB 1.04s ease-in-out infinite; }

/* Receptionist waves hello as he approaches. */
.cs-rec-arm { animation: csRecWave var(--cs-dur) linear infinite; }
@keyframes csRecWave {
  0%, 29%          { transform: rotate(0deg); }
  32%              { transform: rotate(-112deg); }
  34%, 38%, 42%    { transform: rotate(-96deg); }
  36%, 40%         { transform: rotate(-124deg); }
  45%, 100%        { transform: rotate(0deg); }
}

/* Desk monitor glow pulses, so the lobby isn't static while he crosses. */
.cs-screen { animation: csScreen 3.2s ease-in-out infinite; }
@keyframes csScreen { 0%,100% {opacity:.55} 50% {opacity:1} }

/* ═══ ACT 3 — GUIDANCE ════════════════════════════════════════════ */

/* Receptionist gestures while explaining — a small repeating arc. */
.cs-rec3-arm { animation: csExplain var(--cs-dur) ease-in-out infinite; }
@keyframes csExplain {
  0%, 52%        { transform: rotate(-54deg); }
  57%            { transform: rotate(-86deg); }
  62%            { transform: rotate(-48deg); }
  67%            { transform: rotate(-80deg); }
  72%, 100%      { transform: rotate(-54deg); }
}

/* Speech bubble pops in with a slight overshoot. */
.cs-bubble { animation: csBubble var(--cs-dur) linear infinite; }
@keyframes csBubble {
  0%, 52%   { transform: scale(0); opacity: 0; }
  55%       { transform: scale(1.08); opacity: 1; }
  57%, 71%  { transform: scale(1); opacity: 1; }
  73%, 100% { transform: scale(.9); opacity: 0; }
}
/* The three course icons inside it arrive one after another. */
.cs-chip { animation: csChip var(--cs-dur) linear infinite; }
.cs-chip-2 { animation-delay: calc(var(--cs-dur) * 0.025); }
.cs-chip-3 { animation-delay: calc(var(--cs-dur) * 0.05); }
@keyframes csChip {
  0%, 56%   { transform: translateY(6px); opacity: 0; }
  59%, 70%  { transform: translateY(0);   opacity: 1; }
  72%, 100% { transform: translateY(0);   opacity: 0; }
}

/* Student nods along — tiny, or it reads as a cartoon. */
.cs-s3-head { animation: csNod var(--cs-dur) ease-in-out infinite; }
@keyframes csNod {
  0%, 56%             { transform: rotate(0deg); }
  59%, 65%, 71%       { transform: rotate(7deg); }
  62%, 68%            { transform: rotate(0deg); }
  73%, 100%           { transform: rotate(0deg); }
}

/* ═══ ACT 4 — ADMITTED ════════════════════════════════════════════ */

/* Jump: crouch (anticipation) → launch → hang → land → settle.
   The squash on landing is what gives the body apparent mass. */
.cs-s4 { animation: csJump var(--cs-dur) linear infinite; }
@keyframes csJump {
  0%, 78%   { transform: translateY(0) scaleY(1); }
  80%       { transform: translateY(3px) scaleY(.94); }   /* crouch */
  83%       { transform: translateY(-26px) scaleY(1.04); } /* launch */
  85%       { transform: translateY(-30px) scaleY(1); }    /* hang */
  88%       { transform: translateY(0) scaleY(.93); }      /* land, squash */
  90%       { transform: translateY(0) scaleY(1.02); }
  92%, 100% { transform: translateY(0) scaleY(1); }
}
.cs-s4-arm-l { animation: csCheerL var(--cs-dur) ease-out infinite; }
.cs-s4-arm-r { animation: csCheerR var(--cs-dur) ease-out infinite; }
@keyframes csCheerL {
  0%, 79%   { transform: rotate(0deg); }
  84%, 92%  { transform: rotate(-150deg); }
  97%, 100% { transform: rotate(-140deg); }
}
@keyframes csCheerR {
  0%, 79%   { transform: rotate(0deg); }
  84%, 92%  { transform: rotate(150deg); }
  97%, 100% { transform: rotate(140deg); }
}

/* Offer letter handed over, then held aloft. */
.cs-letter { animation: csLetter var(--cs-dur) cubic-bezier(.2,.8,.3,1) infinite; }
@keyframes csLetter {
  0%, 77%   { transform: translate(-34px, 6px) rotate(-14deg); opacity: 0; }
  79%       { transform: translate(-34px, 6px) rotate(-14deg); opacity: 1; }
  84%       { transform: translate(0, -24px) rotate(9deg); opacity: 1; }
  97%, 100% { transform: translate(0, -22px) rotate(7deg); opacity: 1; }
}

/* "ADMITTED" stamp lands hard, then settles — a rubber-stamp beat. */
.cs-stamp { animation: csStamp var(--cs-dur) cubic-bezier(.3,1.6,.4,1) infinite; }
@keyframes csStamp {
  0%, 85%   { transform: scale(2.2) rotate(-16deg); opacity: 0; }
  87%       { transform: scale(1) rotate(-9deg);   opacity: 1; }
  89%       { transform: scale(1.06) rotate(-10deg); }
  91%, 97%  { transform: scale(1) rotate(-9deg);   opacity: 1; }
  100%      { transform: scale(1) rotate(-9deg);   opacity: 0; }
}

/* Confetti. Each piece gets its own --cx/--cr/--cd from the markup so a
   single keyframe produces a scattered burst instead of a uniform sheet. */
.cs-conf {
  opacity: 0;
  animation: csConf var(--cs-dur) cubic-bezier(.25,.6,.4,1) infinite;
  animation-delay: calc(var(--cs-dur) * var(--cd, 0));
}
@keyframes csConf {
  0%, 83%  { transform: translate(0,0) rotate(0deg); opacity: 0; }
  84%      { opacity: 1; }
  96%      { transform: translate(var(--cx,20px), 150px) rotate(var(--cr,420deg)); opacity: 0; }
  100%     { opacity: 0; }
}

/* Receptionist applauds. */
.cs-clap-l { animation: csClapL var(--cs-dur) ease-in-out infinite; }
.cs-clap-r { animation: csClapR var(--cs-dur) ease-in-out infinite; }
@keyframes csClapL {
  0%, 83%                 { transform: rotate(-60deg); }
  85%, 88%, 91%, 94%      { transform: rotate(-34deg); }
  86.5%, 89.5%, 92.5%     { transform: rotate(-64deg); }
  97%, 100%               { transform: rotate(-60deg); }
}
@keyframes csClapR {
  0%, 83%                 { transform: rotate(60deg); }
  85%, 88%, 91%, 94%      { transform: rotate(34deg); }
  86.5%, 89.5%, 92.5%     { transform: rotate(64deg); }
  97%, 100%               { transform: rotate(60deg); }
}

/* ── Caption strip under the stage ─────────────────────────────────── */
.cs-caption { position: relative; height: 22px; }
.cs-cap {
  position: absolute; inset: 0;
  text-align: center;
  font-size: 13px; font-weight: 600;
  color: rgba(255,255,255,.88);
  opacity: 0;
}
.cs-cap-1 { animation: csAct1 var(--cs-dur) linear infinite; }
.cs-cap-2 { animation: csAct2 var(--cs-dur) linear infinite; }
.cs-cap-3 { animation: csAct3 var(--cs-dur) linear infinite; }
.cs-cap-4 { animation: csAct4 var(--cs-dur) linear infinite; }

/* Progress dots */
.cs-dots { display: flex; justify-content: center; gap: 6px; margin-top: 10px; }
.cs-dot {
  width: 6px; height: 6px; border-radius: 999px;
  background: rgba(255,255,255,.28);
}
.cs-dot-1 { animation: csDot var(--cs-dur) linear infinite; }
.cs-dot-2 { animation: csDot var(--cs-dur) linear infinite; animation-delay: calc(var(--cs-dur) * .25); }
.cs-dot-3 { animation: csDot var(--cs-dur) linear infinite; animation-delay: calc(var(--cs-dur) * .5); }
.cs-dot-4 { animation: csDot var(--cs-dur) linear infinite; animation-delay: calc(var(--cs-dur) * .75); }
@keyframes csDot {
  0%, 24%   { background: #D4A017; transform: scaleX(2.6); border-radius: 999px; }
  26%, 100% { background: rgba(255,255,255,.28); transform: scaleX(1); }
}

/* ── Reduced motion ────────────────────────────────────────────────
   Not "slower" — stopped. Everything parks on Act 4, the payoff frame:
   a student admitted and celebrating. The story still lands. */
@media (prefers-reduced-motion: reduce) {
  .cs-wrap * { animation: none !important; }
  .cs-act-1, .cs-act-2, .cs-act-3 { opacity: 0; }
  .cs-act-4 { opacity: 1; }
  .cs-cap-1, .cs-cap-2, .cs-cap-3 { opacity: 0; }
  .cs-cap-4 { opacity: 1; }
  .cs-dot-4 { background: #D4A017; }
  .cs-letter { transform: translate(0,-22px) rotate(7deg); opacity: 1; }
  .cs-stamp  { transform: rotate(-9deg); opacity: 1; }
  .cs-s4-arm-l { transform: rotate(-140deg); }
  .cs-s4-arm-r { transform: rotate(140deg); }
  .cs-clap-l { transform: rotate(-60deg); }
  .cs-clap-r { transform: rotate(60deg); }
  .cs-conf { opacity: 0; }
}
