/* =====================================================================
   MICRO — the motion every page shares (2026-10-18).

   Naveen: "Where possible apply the animations, and micro-interactions…
   from the landing page until the full process."

   The scroll story on the landing (journey-stack, eclipse), the quiz's
   celebrations, the sliding tab indicators and the dialogs already move.
   This file adds what was missing between and around them:

     1. tokens        two springs, the way Framer Motion writes them
     2. pages         one cross-fade from the landing to the report
     3. touch         hover lifts that stuck on a phone after a tap
     4. forms         errors, the password eye, the tick, the submit button
     5. quiz          the chosen answer, the bar going back, Previous
     6. app           saves, ticks, menus, tiles, decide, card hovers

   Press feedback (every button and card gives a little under the finger)
   is in js/micro.js, because one rule here would overwrite each element's
   own `transition` list. It animates the `scale` property, which composes
   with every hover `transform` already written.

   Loaded last on every page, after the page's own CSS, so it can win.
   Off or gentler under prefers-reduced-motion, section by section.
   ===================================================================== */

/* ---------------------------------------------------------------- 1. tokens
   --mo-ease (app.css) and --ease (console.css, the landing) are the same
   strong ease-out, cubic-bezier(.22,1,.36,1); this file uses them with that
   curve as the fallback, and only adds what neither has.

   The springs are Framer Motion's `{ type: "spring", duration, bounce }`,
   sampled into CSS linear() (stiffness (2π/duration)², damping ratio
   1 - bounce, mass 1, run until it settles within 0.1%):
     --mo-settle  duration .5,  bounce .2  → 680ms, peaks at 1.5% over
     --mo-pop     duration .35, bounce .3  → 580ms, peaks at 4.6% over   */
:root{
  --mo-out:var(--mo-ease, cubic-bezier(.22,1,.36,1));
  --mo-io:cubic-bezier(.77,0,.175,1);
  /* 2026-10-24: one calm language (console.css --m-*): the springs no longer
     overshoot. --mo-settle and --mo-pop keep their names, so every rule that
     uses them stays; they are now the enter curve at --m-4 and --m-3. */
  --mo-settle-ms:400ms;
  --mo-settle:cubic-bezier(.22,1,.36,1);
  --mo-pop-ms:240ms;
  --mo-pop:cubic-bezier(.22,1,.36,1);
}

/* ----------------------------------------------------------------- 2. pages
   Every page in the flow (landing → sign up → Dashboard → Discovery →
   report) cross-fades into the next instead of cutting to white. Inside
   the app, css/transitions.css keeps its own rule: the sidebar stays put and
   only the main column fades. Entering the app from outside (sign up →
   Dashboard, Discovery → report) js/micro.js marks the transition
   `mo-enter`, and the whole page fades in once, sidebar included. */
@view-transition{navigation:auto}
@keyframes mo-page-out{to{opacity:0}}
@keyframes mo-page-in{from{opacity:0; transform:translateY(12px)}}
@keyframes mo-page-fade{from{opacity:0}}

html:not(:has(> body[data-page]))::view-transition-old(root){animation:mo-page-out .2s var(--mo-out) both}
html:not(:has(> body[data-page]))::view-transition-new(root){animation:mo-page-in .42s var(--mo-out) both}

html:active-view-transition-type(mo-enter)::view-transition-old(root){display:block; animation:mo-page-out .2s var(--mo-out) both}
html:active-view-transition-type(mo-enter)::view-transition-new(root),
html:active-view-transition-type(mo-enter)::view-transition-new(app-col){animation:mo-page-in .42s var(--mo-out) both}

@media (prefers-reduced-motion:reduce){
  @view-transition{navigation:none}
}

/* ----------------------------------------------------------------- 3. touch
   A phone fires :hover on a tap and keeps it until the next tap somewhere
   else, so a card that rose under a mouse stayed risen under a thumb. On a
   screen with no hover nothing lifts; the press in js/micro.js is the
   feedback there. */
@media (hover:none){
  :is(.btn, .hd-btn, .wp-cta, .dq-cta, .ax-arr, .wt, .wk, .ct, .cc, .cn-card, .cn-day, .cn-todo a, .pc-c .pc-save,
      .main-careers .pc.pw, .cv-worlds a, .pp .tile, .db-dd, .db-dt, .st-card, .wc, .prod, .pk2):hover,
  :is(.btn-lg, .ax-go, .cv-worlds a, .pp .big-row):hover :is(.i, .ax-go-i, .wart){transform:none !important}
}

/* ----------------------------------------------------------------- 4. forms
   An error says where it is: the field's message slides in under it, the
   alert icon pops in the box (js/micro.js gives the box one short shake). */
@keyframes mo-msg-in{from{opacity:0; transform:translateY(-4px)}}
@keyframes mo-pop-in{from{opacity:0; scale:.5}}
.fld-hint:not([hidden]), .ax-err:not([hidden]), .ax-note{animation:mo-msg-in .22s var(--mo-out) both}
.fld[data-invalid] .fld-err{animation:mo-pop-in var(--mo-pop-ms) var(--mo-pop) both}

/* the password eye: the icon that appears grows in, it doesn't blink */
.fld-btn svg{animation:mo-pop-in .2s var(--mo-out) both}

/* the tick in a checkbox lands instead of switching on */
.check::after{scale:.4; transition:opacity .15s var(--mo-out), scale var(--mo-pop-ms) var(--mo-pop)}
.check:checked::after{scale:1}

/* The submit button says it's working, then that it worked. js/micro.js
   sets data-mo="busy" while the account is made (the password hashing takes
   a moment) and data-mo="done" for a beat before the next page. The button
   stays at full strength instead of greying out to .4 while it waits. */
.btn[data-mo]{opacity:1 !important; cursor:default}
.btn[data-mo] > :is(.ax-go-i, .i){display:none}
.btn[data-mo="busy"]::after{content:""; flex:none; width:18px; height:18px; border-radius:50%;
  border:2px solid rgba(255,255,255,.35); border-top-color:#fff; animation:mo-spin .7s linear infinite}
@keyframes mo-spin{to{rotate:1turn}}
.btn .mo-check{flex:none; width:18px; height:18px; animation:mo-pop-in var(--mo-pop-ms) var(--mo-pop) both}
.btn .mo-check path{stroke-dasharray:1; stroke-dashoffset:1; animation:mo-draw .32s var(--mo-out) .06s forwards}
@keyframes mo-draw{to{stroke-dashoffset:0}}

/* ------------------------------------------------------------------ 5. quiz
   The chosen answer's number fills and gives a small pop, inside the 380ms
   the quiz already waits before the next statement; nothing is slower. */
@keyframes mo-badge{from{scale:.72}}
.dq-lesson .dq-opt.is-on .dq-opt-n{background:var(--brand-blue); border-color:var(--brand-blue); color:#fff;
  animation:mo-badge var(--mo-pop-ms) var(--mo-pop) both}

/* The bar springs a little past the mark going forward (discovery.css).
   Going back with Previous it now settles instead of bouncing the wrong
   way; js/micro.js marks the step back. */
.qz-progress > span[data-mo-back]{transition-timing-function:var(--mo-out), ease}

/* Previous fades in on the second statement instead of appearing */
.qz-foot-back{transition:color var(--dq-micro, 140ms) ease, border-color var(--dq-micro, 140ms) ease,
  opacity .24s var(--mo-out), visibility .24s}
.qz-foot-back[hidden]{opacity:0}

/* ------------------------------------------------------------------- 6. app */

/* A menu had two entrances at once: console.css's `pop` keyframe and
   transitions.css's @starting-style. One is enough, and the second closes
   the way it opened. */
.menu{animation:none}

/* the shadow a hovered button gets (cards.css) now eases in with it */
body[data-page] .btn{transition:transform .3s var(--mo-out), background-color .3s var(--mo-out), color .3s var(--mo-out),
  border-color .3s var(--mo-out), box-shadow .3s var(--mo-out)}

/* Save: the bookmark fills instead of switching, and js/micro.js gives the
   icon a pop when it becomes Saved. */
.cc-save .i, .sx-save .i, .pc-save .i, .cp-save .i{transition:fill .2s var(--mo-out), color .2s var(--mo-out)}

/* The world tiles rose 4px, the rest of the product 2px (cards.css: "one
   hover everywhere: a 2px rise"). Now they agree. */
.wt{transition:transform .3s var(--mo-out), box-shadow .3s var(--mo-out)}
@media (hover:hover) and (pointer:fine){ .wt:hover{transform:translateY(-2px)} }

/* the Dashboard tiles' dots grew on hover with no transition, so they jumped */
.db-dd, .db-dt{transition:transform .15s var(--mo-out)}

/* Decide: a choice fills in, its tick lands */
.db-dc label{transition:background-color .2s var(--mo-out)}
.db-dc .tick, .db-dc-r{transition:background-color .2s var(--mo-out), box-shadow .24s var(--mo-out)}
.db-dc .tick .i{scale:.5; transition:opacity .15s var(--mo-out), scale var(--mo-pop-ms) var(--mo-pop)}
.db-dc input:checked + .tick .i{scale:1}

/* A ticked task: the box pops and the check draws (js/micro.js finds the
   redrawn row and adds .mo-ticked for one play). */
@keyframes mo-tick{0%{scale:.78} 100%{scale:1}}
@keyframes mo-tick-i{from{opacity:0; scale:.4}}
.mo-ticked{animation:mo-tick var(--mo-pop-ms) var(--mo-pop) both}
.mo-ticked .i{animation:mo-tick-i var(--mo-pop-ms) var(--mo-pop) both}

/* a Save that becomes Saved */
@keyframes mo-save{0%{scale:.55} 100%{scale:1}}
.mo-saved{animation:mo-save var(--mo-pop-ms) var(--mo-pop) both}

@media (prefers-reduced-motion:reduce){
  .fld-hint:not([hidden]), .ax-err:not([hidden]), .ax-note, .fld-btn svg{animation:mo-page-fade .2s ease both}
  .fld[data-invalid] .fld-err, .dq-lesson .dq-opt.is-on .dq-opt-n, .btn .mo-check, .mo-ticked, .mo-ticked .i, .mo-saved{animation:none}
  .btn .mo-check path{animation:none; stroke-dashoffset:0}
  .check::after, .db-dc .tick .i{scale:1}
}
