/* Entry: a step or card arriving — quiet, fast, no bounce theatrics */
@keyframes riseIn{
  from{opacity:0;transform:translateY(10px)}
  to{opacity:1;transform:translateY(0)}
}
.rise-in{animation:riseIn .38s var(--ease) both}

/* A chosen answer settling into place */
@keyframes settle{
  0%{transform:scale(1)}
  40%{transform:scale(.97)}
  100%{transform:scale(1)}
}
.settle{animation:settle .22s var(--ease)}

/* Gentle rejection — never a harsh error shake, just a nudge */
@keyframes nudge{
  0%,100%{transform:translateX(0)}
  30%{transform:translateX(-4px)}
  60%{transform:translateX(3px)}
}
.nudge{animation:nudge .28s var(--ease)}

/* Value entering the business (capital, cash) */
@keyframes flowIn{
  from{opacity:0;transform:translateY(8px) scale(.9)}
  to{opacity:1;transform:translateY(0) scale(1)}
}
.flow-in{animation:flowIn .42s var(--ease) both}

/* The reveal moment — a term (Debit/Credit) being named for the first time */
@keyframes reveal{
  from{opacity:0;letter-spacing:.4em}
  to{opacity:1;letter-spacing:.06em}
}
.reveal-term{animation:reveal .5s var(--ease) both}

/* A new asset appearing in the business's yard */
@keyframes popIn{
  0%{transform:scale(.3);opacity:0}
  70%{transform:scale(1.15)}
  100%{transform:scale(1);opacity:1}
}


/* STEP 7 — Brilliant-style micro-interactions: quick, purposeful, memorable. */
@keyframes screenIn{
  from{opacity:0;transform:translateY(8px)}
  to{opacity:1;transform:translateY(0)}
}
.screen-in{animation:screenIn .32s var(--ease) both}

@keyframes answerCorrect{
  0%{transform:scale(1)}
  35%{transform:scale(1.025)}
  70%{transform:scale(.99)}
  100%{transform:scale(1)}
}
.answer-correct{animation:answerCorrect .34s var(--ease) both}

@keyframes answerWrong{
  0%,100%{transform:translateX(0)}
  20%{transform:translateX(-6px)}
  45%{transform:translateX(5px)}
  70%{transform:translateX(-3px)}
}
.answer-wrong{animation:answerWrong .32s var(--ease) both}

@keyframes stageGlow{
  0%{box-shadow:0 0 0 0 rgba(217,164,65,0)}
  45%{box-shadow:0 0 0 5px rgba(217,164,65,.12)}
  100%{box-shadow:0 0 0 0 rgba(217,164,65,0)}
}
.stage-advance{animation:stageGlow .55s var(--ease) both}

@keyframes fillPop{
  0%{transform:scale(.985);opacity:.7}
  60%{transform:scale(1.012);opacity:1}
  100%{transform:scale(1);opacity:1}
}
.fill-pop{animation:fillPop .28s var(--ease) both}

@keyframes balanceGood{
  0%{transform:scale(1)}
  45%{transform:scale(1.025)}
  100%{transform:scale(1)}
}
.journal-balance.is-balanced{animation:balanceGood .3s var(--ease) both}

@keyframes rowIn{
  from{opacity:0;transform:translateY(-5px)}
  to{opacity:1;transform:translateY(0)}
}
.journal-editor-row-free{animation:rowIn .24s var(--ease) both}

@keyframes ripple{
  from{transform:scale(.15);opacity:.45}
  to{transform:scale(1.8);opacity:0}
}
.ui-ripple{position:absolute;border-radius:50%;background:currentColor;pointer-events:none;width:22px;height:22px;transform:translate(-50%,-50%) scale(.15);animation:ripple .42s var(--ease) forwards}

/* STEP 8 — CPA Juma: purposeful mentor motion */
@keyframes teacherFloat{0%,100%{transform:translateY(0)}50%{transform:translateY(-5px)}}
@keyframes teacherTalk{0%,100%{transform:translateY(0) rotate(0)}35%{transform:translateY(-2px) rotate(-1deg)}70%{transform:translateY(0) rotate(1deg)}}
@keyframes teacherThink{0%,100%{transform:translateY(0)}50%{transform:translateY(-3px) rotate(1deg)}}
.teacher-mood-idle{animation:teacherFloat 3.4s ease-in-out infinite}
.teacher-mood-celebrate{animation:teacherTalk .65s var(--ease) both}
.teacher-mood-think{animation:teacherThink 1.1s ease-in-out infinite}

/* STEP 7 — Finotech micro-feedback layer: tactile, restrained, learning-first. */
@keyframes staggerRise{
  from{opacity:0;transform:translateY(7px)}
  to{opacity:1;transform:translateY(0)}
}
.stagger-in{animation:staggerRise .32s var(--ease) both;animation-delay:calc(var(--stagger,0) * 42ms)}

@keyframes successSpark{
  0%{transform:scale(.45);opacity:0}
  20%{opacity:.9}
  100%{transform:scale(1.35);opacity:0}
}
.success-spark{
  position:absolute;width:9px;height:9px;border:2px solid currentColor;border-radius:50%;
  pointer-events:none;animation:successSpark .62s var(--ease) both
}

@keyframes progressShimmer{from{transform:translateX(-110%)}to{transform:translateX(110%)}}
.learning-stage.is-current span{position:relative;overflow:hidden}
.learning-stage.is-current span::after{
  content:"";position:absolute;inset:-35%;background:linear-gradient(105deg,transparent 35%,rgba(255,255,255,.26),transparent 65%);
  transform:translateX(-110%);animation:progressShimmer 2.8s ease-in-out infinite
}



/* STEP 9 — World momentum layer. Scoped to Business World / accounting records. */
@keyframes worldStreakHeat{
  0%,100%{transform:scale(1)}
  45%{transform:scale(1.035)}
}
@keyframes worldXpGlow{
  0%,100%{box-shadow:0 0 0 rgba(217,164,65,0)}
  50%{box-shadow:0 0 14px rgba(217,164,65,.20)}
}
@keyframes chainTravel{
  from{opacity:0;transform:translateY(5px)}
  to{opacity:1;transform:translateY(0)}
}
@keyframes rewardIn{
  0%{opacity:0;transform:translateY(12px) scale(.97)}
  35%{opacity:1;transform:translateY(0) scale(1)}
  100%{opacity:1;transform:translateY(0) scale(1)}
}
.world-streak.is-hot{animation:worldStreakHeat .8s var(--ease) infinite}
.world-xp-track.is-near{animation:worldXpGlow 1.8s ease-in-out infinite}
.accounting-chain-notice .chain-flow span,
.accounting-chain-notice .chain-flow i{animation:chainTravel .32s var(--ease) both}
.accounting-chain-notice .chain-flow span:nth-child(2){animation-delay:.06s}
.accounting-chain-notice .chain-flow span:nth-child(4){animation-delay:.12s}
.accounting-chain-notice .chain-flow span:nth-child(6){animation-delay:.18s}
.accounting-chain-notice .chain-flow span:nth-child(8){animation-delay:.24s}
.world-reward-card{animation:rewardIn .42s var(--ease) both}

@media (prefers-reduced-motion: reduce){
  .world-streak.is-hot,
  .world-xp-track.is-near,
  .accounting-chain-notice .chain-flow span,
  .accounting-chain-notice .chain-flow i,
  .world-reward-card{animation:none!important}
}

/* STEP 10 — Business World achievement celebration. Scoped to the reward layer. */
@keyframes rewardCardIn{
  0%{opacity:0;transform:translateY(18px) scale(.94)}
  70%{opacity:1;transform:translateY(-2px) scale(1.01)}
  100%{opacity:1;transform:translateY(0) scale(1)}
}
@keyframes rewardGlow{
  0%,100%{box-shadow:0 24px 70px rgba(0,0,0,.58),0 0 0 rgba(217,164,65,0)}
  50%{box-shadow:0 24px 70px rgba(0,0,0,.58),0 0 38px rgba(217,164,65,.18)}
}
@keyframes rewardEmblem{
  0%{transform:scale(.65) rotate(-12deg);opacity:0}
  70%{transform:scale(1.08) rotate(2deg);opacity:1}
  100%{transform:scale(1) rotate(0);opacity:1}
}
@keyframes rewardConfetti{
  0%{opacity:0;transform:translate3d(0,-18px,0) rotate(0)}
  10%{opacity:1}
  100%{opacity:0;transform:translate3d(var(--drift),92vh,0) rotate(var(--rotate))}
}
@keyframes rewardTimer{
  from{width:0}
  to{width:100%}
}
@keyframes rewardClose{
  from{opacity:1;transform:scale(1)}
  to{opacity:0;transform:scale(.98)}
}
.world-reward-card{animation:rewardCardIn .48s var(--ease) both,rewardGlow 2.8s ease-in-out .5s infinite}
.world-reward-emblem{animation:rewardEmblem .55s var(--ease) .08s both}
.reward-confetti{animation:rewardConfetti var(--duration) ease-out var(--delay) both}
.world-reward-timer span{animation:rewardTimer 30s linear both}
.world-reward-layer.is-closing .world-reward-card{animation:rewardClose .22s ease both}
@media (prefers-reduced-motion: reduce){
  .world-reward-card,.world-reward-emblem,.reward-confetti,.world-reward-timer span{animation:none!important}
}

/* FORENSIC REMEDIATION — ledger-native motion hooks */
@keyframes ledgerPostFly{0%{opacity:1;transform:translate3d(0,0,0) scale(1)}100%{opacity:0;transform:translate3d(var(--post-x,0px),var(--post-y,0px),0) scale(.6)}}
.ledger-posting-ghost{position:fixed;left:0;top:0;z-index:10001;pointer-events:none;will-change:transform,opacity;animation:ledgerPostFly .62s var(--ease) both;font-weight:900;color:var(--entrust);text-shadow:0 2px 10px rgba(0,0,0,.45)}
@keyframes journalInkDry{from{opacity:.35;filter:blur(1.8px);transform:translateY(-2px)}to{opacity:1;filter:blur(0);transform:translateY(0)}}
.journal-posted-new{animation:journalInkDry .4s var(--ease) both}
/* Draws from the right, the direction a figure is read back and checked. */
@keyframes trialBalanceUnderline{from{transform:scaleX(0);transform-origin:right center}to{transform:scaleX(1);transform-origin:right center}}
/* The double rule beneath a balanced trial balance.
   It used to be a row-level pseudo-element spanning left:4% to right:4%, which
   is an arbitrary slice of the whole row: it began under the account names and
   stopped short of the credit figures, so the one mark that is supposed to say
   "these two columns agree" sat under neither of them.
   Accounting draws it under the FIGURES, and only the figures. Applying it to
   the two numeric cells means it lines up with the columns by construction —
   it cannot drift as the table widths change, because it IS the cells. */
.trial-balance-total.is-balanced td:nth-child(2),
.trial-balance-total.is-balanced td:nth-child(3){position:relative}
.trial-balance-total.is-balanced td:nth-child(2)::after,
.trial-balance-total.is-balanced td:nth-child(3)::after{content:"";position:absolute;left:8px;right:8px;bottom:2px;height:3px;border-top:1px solid var(--entrust);border-bottom:1px solid var(--entrust);transform:scaleX(0);transform-origin:right center;animation:trialBalanceUnderline .55s var(--ease) .08s both}
@keyframes contraUnderline{from{transform:scaleX(0);transform-origin:right center}to{transform:scaleX(1);transform-origin:right center}}
.is-contra{position:relative}
.is-contra::after{content:"";position:absolute;left:18%;right:18%;bottom:3px;height:1px;background:var(--entrust);transform:scaleX(0);animation:contraUnderline .5s var(--ease) .12s both}
@keyframes teacherConcern{0%,100%{transform:translateY(0) rotate(0)}50%{transform:translateY(0) rotate(-2deg)}}
.teacher-mood-concern{animation:teacherConcern 1.6s ease-in-out infinite}
@media (prefers-reduced-motion: reduce){
  .ledger-posting-ghost,.journal-posted-new,.trial-balance-total.is-balanced td::after,.is-contra::after,.teacher-mood-concern{animation:none!important}
}

/* Full reduced-motion coverage for all finite/infinite motion in this layer. */
@media (prefers-reduced-motion: reduce){
  .teacher-mood-idle,.teacher-mood-celebrate,.teacher-mood-think,.teacher-mood-concern,
  .success-spark,.learning-stage.is-current span::after,.stage-glow,.progress-shimmer,
  .ui-ripple,.world-streak.is-hot,.world-xp-track.is-near,.world-reward-card,
  .world-reward-emblem,.reward-confetti,.world-reward-timer span,.ledger-posting-ghost,
  .journal-posted-new,.trial-balance-total.is-balanced td::after,.is-contra::after{
    animation:none!important;
  }
}
