/* Motion layer (docs/design-system.md, Motion). Loaded last. Only transform and opacity move; colours change by transition.
   Entries: translate + fade (--dur-2, --ease-out). Exits: shorter (--dur-1, --ease-in). Reduced motion: the same names become a short fade. */
:root{--dir:1}
[dir="rtl"]{--dir:-1}

@keyframes mq-in-up{from{opacity:0;transform:translateY(var(--rise))}}
@keyframes mq-in-down{from{opacity:0;transform:translateY(calc(var(--rise) * -1))}}
@keyframes mq-in-x{from{opacity:0;transform:translateX(calc(var(--slide) * var(--dir)))}}
@keyframes mq-fade{from{opacity:0}}
@keyframes mq-pop{from{opacity:0;transform:scale(.85)}}
@keyframes mq-node{0%{transform:scale(.7)}60%{transform:scale(1.08)}100%{transform:scale(1)}}
@keyframes mq-bump{40%{transform:scale(1.25)}}
@keyframes mq-grow-y{from{transform:scaleY(0)}}
@keyframes mq-out{to{opacity:0}}
@keyframes mq-out-up{to{opacity:0;transform:translateY(calc(var(--rise) * -.5))}}
@keyframes mq-out-down{to{opacity:0;transform:translateY(100%)}}
@keyframes mq-out-x{to{opacity:0;transform:translateX(calc(var(--slide) * var(--dir) * -1))}}
@keyframes mq-out-pop{to{opacity:0;transform:scale(.6)}}
@keyframes mq-reveal{to{opacity:1;transform:none}}

/* Generic markers set by static/js/motion.js */
[data-motion="in"]{animation:mq-in-up var(--dur-2) var(--ease-out) both}
[data-motion="fade"]{animation:mq-fade var(--dur-2) var(--ease-out) both}
[data-motion="bump"]{animation:mq-bump var(--dur-3) var(--ease-out)}
[data-motion="out"]{animation:mq-out var(--dur-1) var(--ease-in) forwards}
.mq-ghost{z-index:35}
.mq-ghost *,.mq-ghost *::before,.mq-ghost *::after{animation:none!important;transition:none!important}
.sheet.mq-ghost[data-motion="out"]{animation:mq-out-down var(--dur-1) var(--ease-in) forwards}
.ex.mq-ghost{overflow:hidden}
.ex.mq-ghost[data-motion="out"]{animation:mq-out-x var(--dur-1) var(--ease-in) forwards}
.pop[data-motion="out"]{animation:mq-out-pop var(--dur-1) var(--ease-in) forwards}

/* Player */
.player-foot>.row{animation:mq-in-up var(--dur-2) var(--ease-out) backwards}
.flash-answer:not([hidden]){animation:mq-in-up var(--dur-2) var(--ease-out) backwards}
.sheet .sheet-title i{animation:mq-pop var(--dur-2) var(--ease-out) 60ms backwards}
.btn{transition:transform .06s,box-shadow .06s,background-color var(--dur-1) var(--ease-std),color var(--dur-1) var(--ease-std)}
.opt,.word,.hk-btn,.key{transition:border-color var(--dur-1) var(--ease-std),background-color var(--dur-1) var(--ease-std),box-shadow var(--dur-1) var(--ease-std),color var(--dur-1) var(--ease-std),transform .06s}
.opt:active:not(:disabled),.word:active:not(:disabled){transform:translateY(3px);box-shadow:0 0 0 transparent}
.tile,.slot,.combo,.combo i{transition:border-color var(--dur-1) var(--ease-std),background-color var(--dur-1) var(--ease-std),box-shadow var(--dur-1) var(--ease-std),color var(--dur-1) var(--ease-std)}
/* Bars: a full-width fill moved by translateX(--fill), never width. Elements given only an inline width keep the old behaviour. */
:is(.progress,.meter) i:is([style*="--fill"],:not([style])){width:100%!important;transform:translateX(calc(var(--fill,0%) - 100%));transition:transform var(--dur-3) var(--ease-out)}
[dir="rtl"] :is(.progress,.meter) i:is([style*="--fill"],:not([style])){transform:translateX(calc(100% - var(--fill,0%)))}

/* Shell */
.main{transition:opacity var(--dur-2) var(--ease-out),transform var(--dur-3) var(--ease-out)}
.main[data-hydrating]{transform:translateY(var(--rise));animation:mq-reveal 0s 3.2s forwards}
/* Hiding is instant, only the reveal moves. During a tab change the view transition is the only motion (docs/ux-ui.md). */
.main[data-hydrating],.main[data-nav]{transition:none}
:root:active-view-transition-type(nav) .main{view-transition-name:mq-main}
:root:active-view-transition-type(nav) .top{view-transition-name:mq-top}
:root:active-view-transition-type(nav) .tabs{view-transition-name:mq-tabs}
:root:active-view-transition-type(nav)::view-transition-old(root),
:root:active-view-transition-type(nav)::view-transition-new(root){animation:none}
::view-transition-group(mq-main),::view-transition-group(mq-top),::view-transition-group(mq-tabs){animation:none}
::view-transition-old(mq-top),::view-transition-new(mq-top),::view-transition-old(mq-tabs),::view-transition-new(mq-tabs){animation:none}
::view-transition-old(mq-main){animation:mq-out-up var(--dur-1) var(--ease-in) both}
::view-transition-new(mq-main){animation:mq-in-up var(--dur-3) var(--ease-out) both}
.tab{transition:background-color var(--dur-2) var(--ease-out),border-color var(--dur-2) var(--ease-out),color var(--dur-2) var(--ease-out)}
@starting-style{.tab[aria-current="page"]{background-color:transparent;border-color:transparent;color:var(--muted)}}
/* Counters: hidden until the first local render (no neutral "0"), then a bump when the value changes. */
.stats [data-stat] b{display:inline-block;transition:opacity var(--dur-2) var(--ease-out)}
.stats [data-stat]:not([data-shown]) b{opacity:0;animation:mq-reveal 0s 1.5s forwards}
.notice{animation:mq-in-down var(--dur-2) var(--ease-out) backwards}
.notice.is-toast{animation-name:mq-in-up}
.langmenu[open] ul{animation:mq-in-down var(--dur-2) var(--ease-out)}
@supports selector(::details-content){
  .langmenu::details-content{transition:content-visibility var(--dur-1) allow-discrete,opacity var(--dur-1) var(--ease-in)}
  .langmenu:not([open])::details-content{opacity:0}
}

/* Map */
.start{transition:opacity var(--dur-1) var(--ease-std),visibility var(--dur-1)}
[data-map]:has(.pop) .start{opacity:0}
.node.is-fresh :is(.face,.n),.node.is-fresh::before{animation:mq-node var(--dur-3) var(--ease-out)}

/* Reviews, shop, profile, forms (text entries use :where so the data-motion="out" marker wins) */
.bar{transform-origin:bottom;animation:mq-grow-y var(--dur-3) var(--ease-out) backwards}
.bar-col:nth-child(2) .bar{animation-delay:20ms}.bar-col:nth-child(3) .bar{animation-delay:40ms}.bar-col:nth-child(4) .bar{animation-delay:60ms}
.bar-col:nth-child(5) .bar{animation-delay:80ms}.bar-col:nth-child(6) .bar{animation-delay:100ms}.bar-col:nth-child(n+7) .bar{animation-delay:120ms}
.claimed{animation:mq-pop var(--dur-2) var(--ease-out) backwards}
.w-group{animation:mq-fade var(--dur-2) var(--ease-out) backwards}
:where([data-saved]:not(:empty),.lp-q-fb:not(:empty)){animation:mq-in-up var(--dur-2) var(--ease-out) backwards}
.choice span,.lang-choice button,.lang-choice a{transition:border-color var(--dur-1) var(--ease-std),box-shadow var(--dur-1) var(--ease-std),background-color var(--dur-1) var(--ease-std)}
.field input{transition:border-color var(--dur-1) var(--ease-std),background-color var(--dur-1) var(--ease-std)}
.form-error,.field-error,.auth-messages{animation:mq-in-down var(--dur-2) var(--ease-out) backwards}

/* Landing (hero excluded: LCP). Sections reveal with the scroll, no JavaScript; without support they are simply shown. */
@supports (animation-timeline:view()){
  @media (prefers-reduced-motion:no-preference){
    :is(.lp-demo,.lp-pain,.lp-how,.lp-rigor,.lp-program,.lp-who,.lp-proof,.lp-offers,.lp-faq,.lp-final)>*{
      --rise:28px;animation:mq-in-up linear both;animation-timeline:view();animation-range:entry 0px entry 260px}
  }
}
.lp-sticky{transition:transform var(--dur-2) var(--ease-out),opacity var(--dur-2) var(--ease-out),display var(--dur-2) allow-discrete}
.lp-sticky[hidden]{transform:translateY(100%);opacity:0;transition-duration:var(--dur-1);transition-timing-function:var(--ease-in)}
@starting-style{.lp-sticky:not([hidden]){transform:translateY(100%);opacity:0}}
.lp-q:not([hidden]){animation:mq-in-x var(--dur-2) var(--ease-out) backwards}
.lp-demo-next:not([hidden]),.lp-demo-end:not([hidden]){animation:mq-in-up var(--dur-2) var(--ease-out) backwards}

/* Reduced motion: same names, opacity only, durations already shortened in tokens.css. */
@media (prefers-reduced-motion:reduce){
  @keyframes mq-pop{from{opacity:0}}
  @keyframes mq-node{50%{opacity:.5}}
  @keyframes mq-bump{50%{opacity:.4}}
  @keyframes mq-grow-y{from{opacity:0}}
  @keyframes mq-out-down{to{opacity:0}}
  @keyframes mq-out-x{to{opacity:0}}
  @keyframes mq-out-pop{to{opacity:0}}
  @keyframes mq-out-up{to{opacity:0}}
  .sheet{animation:mq-fade var(--dur-1) linear}
  .pop{animation:mq-fade var(--dur-1) linear}
  .ex>*{animation:mq-fade var(--dur-1) linear backwards}
  .opt:active:not(:disabled),.word:active:not(:disabled){transform:none}
}
