/* Mentora motion: page changes, entrances, hover and press, folders, delete, dashboard numbers and bars, answer
   feedback and small celebrations. Only opacity, transform, clip-path and shadows animate; moves stay at 2–18px.
   Everything sits inside prefers-reduced-motion: no-preference, so with reduced motion nothing here applies and
   content is never hidden. motion.js drives folders, delete, counting numbers and celebrations. */
@media(prefers-reduced-motion:no-preference){
:root{--m-ease:cubic-bezier(.25,.8,.25,1);--m-ease-out:cubic-bezier(.16,1,.3,1);--m-fast:200ms;--m-med:360ms;--m-long:640ms;--m-shadow:rgba(33,78,67,.45)}

/* 0 · Page changes: moving between pages no longer blanks the screen. The sidebar and top bar stay put,
   the old page content fades up and away, the new one rises in. Posting back to the same page (checking an answer,
   saving) is a soft cross-fade, signing in or out a plain fade. Browsers without support load pages as before. */
@view-transition{navigation:auto}
.sidebar{view-transition-name:m-sidebar}
.topbar{view-transition-name:m-topbar}
main{view-transition-name:m-main}
::view-transition-group(m-sidebar),::view-transition-group(m-topbar),::view-transition-group(m-main){animation:none}
::view-transition-old(m-sidebar),::view-transition-old(m-topbar){display:none}
::view-transition-new(m-sidebar),::view-transition-new(m-topbar){animation:none}
::view-transition-old(root),::view-transition-new(root){animation-duration:260ms}
@keyframes m-vt-out{to{opacity:0;transform:translateY(-10px)}}
@keyframes m-vt-in{from{opacity:0;transform:translateY(18px)}}
@keyframes m-vt-fade-out{to{opacity:0}}
@keyframes m-vt-fade-in{from{opacity:0}}
::view-transition-old(m-main){animation:m-vt-out 240ms cubic-bezier(.4,0,1,1) both}
::view-transition-new(m-main){animation:m-vt-in 560ms var(--m-ease-out) 120ms both}
html.m-same::view-transition-old(m-main){animation:m-vt-fade-out 220ms ease both}
html.m-same::view-transition-new(m-main){animation:m-vt-fade-in 320ms ease both}
html.m-layout .sidebar,html.m-layout .topbar,html.m-layout main{view-transition-name:none}
html.m-layout::view-transition-old(m-sidebar),html.m-layout::view-transition-old(m-topbar),html.m-layout::view-transition-old(m-main){display:block;animation:m-vt-fade-out 220ms ease both}
html.m-layout::view-transition-old(root){animation:m-vt-fade-out 220ms ease both}
html.m-layout::view-transition-new(root){animation:m-vt-fade-in 380ms ease 80ms both}

/* 1 · Page entrance: the main blocks of a page rise 16px and fade in, 70ms apart, capped at six steps. Not in the
   practice and timed-test runners, never on dialogs, and only while the page first appears (motion.js then sets
   m-entered), so a panel shown later does not replay it. */
@keyframes m-rise{from{opacity:0;transform:translateY(16px)}to{opacity:1;transform:none}}
@keyframes m-drop{from{opacity:0;transform:translateY(-12px)}to{opacity:1;transform:none}}
html:not(.m-reloaded):not(.m-entered) body:not(.pa-body):not(.bb-body) main>:not(dialog){animation:m-rise var(--m-long) var(--m-ease-out) both}
html:not(.m-reloaded):not(.m-entered) body:not(.pa-body):not(.bb-body) main>:nth-child(2){animation-delay:70ms}
html:not(.m-reloaded):not(.m-entered) body:not(.pa-body):not(.bb-body) main>:nth-child(3){animation-delay:140ms}
html:not(.m-reloaded):not(.m-entered) body:not(.pa-body):not(.bb-body) main>:nth-child(4){animation-delay:210ms}
html:not(.m-reloaded):not(.m-entered) body:not(.pa-body):not(.bb-body) main>:nth-child(5){animation-delay:280ms}
html:not(.m-reloaded):not(.m-entered) body:not(.pa-body):not(.bb-body) main>:nth-child(n+6){animation-delay:350ms}
.notice{animation:m-drop var(--m-long) var(--m-ease-out) both}

/* 2 · Hover and press. Buttons: deepen, lift 2px with a green glow and a light sheen; press in to 97%.
   Cards lift 4px; rows tint with a green edge and their arrow slides; sidebar icons nudge. Mouse devices only. */
.button{transition:background-color var(--m-fast) var(--m-ease),color var(--m-fast) var(--m-ease),border-color var(--m-fast) var(--m-ease),transform var(--m-fast) var(--m-ease),box-shadow var(--m-med) var(--m-ease)}
.button:not(.secondary){position:relative;overflow:hidden;isolation:isolate}
.button:not(.secondary)::after{content:'';position:absolute;inset:0;z-index:-1;background:linear-gradient(110deg,transparent 25%,rgba(255,255,255,.22) 50%,transparent 75%);transform:translateX(-110%);pointer-events:none}
.course-card,.stats article,.practice-choice-card,.panel.ov-next .ov-step{transition:transform var(--m-med) var(--m-ease),box-shadow var(--m-med) var(--m-ease),border-color var(--m-med) var(--m-ease)}
.pa-tool,.course-nav>a,.sidebar nav a{transition:background-color var(--m-fast) var(--m-ease),color var(--m-fast) var(--m-ease),transform var(--m-fast) var(--m-ease)}
.sidebar nav a svg,.sidebar nav a img{transition:transform var(--m-med) var(--m-ease-out)}
.deadline-row,.list-row,.content-item{transition:background-color var(--m-fast) var(--m-ease),box-shadow var(--m-fast) var(--m-ease)}
.pa-choice{transition:border-color var(--m-fast) var(--m-ease),box-shadow var(--m-med) var(--m-ease),transform var(--m-fast) var(--m-ease),background-color var(--m-fast) var(--m-ease)}
.course-art>b,.stats article>:first-child{transition:transform var(--m-med) var(--m-ease-out)}
a.deadline-row>span,a.list-row>span:last-child{display:inline-block;transition:transform var(--m-fast) var(--m-ease)}
input:not([type=checkbox]):not([type=radio]):not([type=file]),select,textarea{transition:border-color var(--m-fast) var(--m-ease),box-shadow var(--m-med) var(--m-ease)}
input:not([type=checkbox]):not([type=radio]):not([type=file]):focus,select:focus,textarea:focus{box-shadow:0 0 0 4px var(--c-3272632b)}
@media(hover:hover){
  .button:not(.secondary):hover{transform:translateY(-2px);box-shadow:0 10px 20px -10px var(--m-shadow)}
  .button:not(.secondary):hover::after{transform:translateX(110%);transition:transform 700ms var(--m-ease)}
  .button.secondary:hover{transform:translateY(-2px);background:var(--c-edf3e8);border-color:var(--c-91ab8d);color:var(--dark);box-shadow:0 8px 16px -12px var(--m-shadow)}
  .course-card:hover{transform:translateY(-4px);box-shadow:0 20px 36px -22px var(--m-shadow)}
  .course-card:hover .course-art>b{transform:rotate(-12deg) scale(1.08)}
  .stats article:hover,.practice-choice-card:hover,.panel.ov-next .ov-step:hover{transform:translateY(-3px);box-shadow:0 16px 30px -20px var(--m-shadow);border-color:var(--c-91ab8d)}
  .stats article:hover>:first-child{transform:scale(1.1)}
  .sidebar nav a:hover svg,.sidebar nav a:hover img{transform:translateX(3px) scale(1.12)}
  a.deadline-row:hover,a.list-row:hover{background:var(--c-f6f8f2);box-shadow:inset 3px 0 0 var(--green);text-decoration:none}
  a.deadline-row:hover>span,a.list-row:hover>span:last-child{transform:translateX(5px)}
  .content-item:hover{background:var(--c-fbfcf9);box-shadow:inset 3px 0 0 var(--c-91ab8d)}
  label.pa-choice:hover{transform:translateY(-1px);box-shadow:0 8px 18px -14px var(--m-shadow);background:var(--c-fbfcf9)}
}
.button:active,.pa-tool:active{transform:scale(.97);box-shadow:none;transition-duration:90ms}
.course-card:active,.stats article:active{transform:translateY(-1px) scale(.99)}

/* 3 · Folders: height and content ease open (420ms) and closed (320ms); motion.js drives it. */
details.folder>summary,details.enrollment-panel>summary,details.ov-detail>summary{transition:background-color var(--m-fast) var(--m-ease)}
@media(hover:hover){details.folder>summary:hover{background:var(--c-f6f8f2)}}
.m-folder-anim{overflow:hidden}

/* 4 · Delete: the dialog rises and settles in over a dimmed page; the removed row fades and slides 16px right,
   then its space closes up smoothly. */
@keyframes m-dialog{from{opacity:0;transform:translateY(18px) scale(.96)}to{opacity:1;transform:none}}
@keyframes m-backdrop{from{opacity:0}}
dialog[open]{animation:m-dialog 420ms var(--m-ease-out)}
dialog[open]::backdrop{animation:m-backdrop 420ms var(--m-ease)}
.m-ghost{pointer-events:none;overflow:hidden}
@keyframes m-fade-in{from{opacity:0}}
.empty.m-new{animation:m-fade-in var(--m-long) var(--m-ease) both;animation-delay:500ms}

/* 5 · Dashboard statistics and charts: bars fill from the left one after another; the score marker drops in;
   numbers count up (motion.js). */
@keyframes m-draw{from{clip-path:inset(0 100% 0 0 round 8px)}to{clip-path:inset(0 0 0 0 round 8px)}}
@keyframes m-marker{from{opacity:0;transform:translate(-50%,-160%) scale(.6)}}
.meter-fill.m-play{animation:m-draw 1100ms var(--m-ease-out) both;animation-delay:calc(var(--m-i,0)*90ms)}
.sat-predict-bar span.m-play{animation:m-marker 700ms var(--m-ease-out) both;animation-delay:500ms}

/* 6 · Answer feedback: the message slides in; the right answer glows green twice; a wrong pick shakes gently. */
@keyframes m-ring-green{0%{box-shadow:0 0 0 0 rgba(47,125,87,.45)}70%,100%{box-shadow:0 0 0 12px rgba(47,125,87,0)}}
@keyframes m-nudge{0%,100%{transform:none}20%{transform:translateX(-5px)}40%{transform:translateX(5px)}60%{transform:translateX(-3px)}80%{transform:translateX(2px)}}
@keyframes m-pop{0%{opacity:0;transform:scale(.4)}60%{opacity:1;transform:scale(1.12)}100%{transform:none}}
.pa-alert.is-correct,.pa-alert.is-wrong{animation:m-rise var(--m-long) var(--m-ease-out) both}
.pa-choice.is-correct{animation:m-ring-green 900ms var(--m-ease) 2}
.pa-choice.is-wrong{animation:m-nudge 480ms var(--m-ease) 1}
.pa-choice.is-correct .choice-letter,.pa-choice.is-wrong .choice-letter,.pa-mark{animation:m-pop 480ms var(--m-ease-out) both}
.hw-result{animation:m-rise var(--m-long) var(--m-ease-out) both;animation-delay:calc(var(--m-i,0)*90ms)}
.hw-result.is-correct .hw-status,.hw-result.is-wrong .hw-status{animation:m-pop 480ms var(--m-ease-out) both;animation-delay:calc((var(--m-i,0)*90ms + 250ms))}

/* 7 · Celebrations: a check draws itself on the "submitted" notice with a spray of brand-coloured confetti;
   an Excellent grade (94%+, the site's own band) gets a light sweep and confetti. Each plays once per item. */
.notice.m-celebrated{position:relative;display:flex;align-items:center;gap:12px}
.m-check{flex:none;width:26px;height:26px;border-radius:50%;background:var(--dark);display:grid;place-items:center}
.m-check svg{width:15px;height:15px;stroke:var(--c-ffffff);stroke-width:3;fill:none;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:24;stroke-dashoffset:24;animation:m-stroke 520ms var(--m-ease-out) 300ms forwards}
.m-check{animation:m-pop 520ms var(--m-ease-out) both}
@keyframes m-stroke{to{stroke-dashoffset:0}}
.m-burst{position:absolute;left:30px;top:50%;width:0;height:0;pointer-events:none}
.m-burst i{position:absolute;width:6px;height:6px;border-radius:2px;opacity:0;animation:m-spark 1200ms cubic-bezier(.1,.7,.3,1) forwards;animation-delay:320ms}
@keyframes m-spark{0%{opacity:1;transform:translate(0,0) rotate(0) scale(1)}70%{opacity:1}100%{opacity:0;transform:translate(var(--x),var(--y)) rotate(var(--r)) scale(.6)}}
.m-shine{position:relative;overflow:hidden;isolation:isolate}
.m-shine::after{content:'';position:absolute;inset:0;background:linear-gradient(105deg,transparent 25%,rgba(255,255,255,.7) 50%,transparent 75%);transform:translateX(-120%);animation:m-sweep 1300ms var(--m-ease) 300ms 1 forwards;pointer-events:none}
@keyframes m-sweep{to{transform:translateX(120%)}}
.m-js .meter-fill:not(.m-play),.m-js .sat-predict-bar span:not(.m-play){clip-path:inset(0 100% 0 0);opacity:0}
}
/* Printed pages show every bar, also those never scrolled into view. */
@media print{.m-js .meter-fill,.m-js .sat-predict-bar span{clip-path:none!important;opacity:1!important;animation:none!important}}
