/* ---------- Purposeful motion (owner round 10). The rule: motion explains (where a thing came from or went), confirms (a saved payment, a copied
   value) or guides (a changed figure, a new row, a fold opening); never decoration. 160 to 320 ms, the app's one easing, transform and opacity only,
   interruptible (the classes are removed when the animation ends), and everything here is off under Reduce Motion (the block at the end), where
   a plain fade or nothing takes its place. The JS side is app/js/motion.js (flipList, leaveThen, swapText, shake, settleCard). ---------- */
:root{ --mo-fast:160ms; --mo:220ms; --mo-slow:320ms; --mo-ease:cubic-bezier(.2,.8,.2,1) }

/* a list that redraws in place (motion.js flipList): a row that stays slides from where it was to where it is now (an inline transform set by the
   script), a new row rises in, a row that leaves fades and shrinks a little first (leaveThen), so a paid unit is seen moving down the list or going */
.mo-in{ animation:moIn var(--mo) var(--mo-ease) both }
@keyframes moIn{ from{ opacity:0; transform:translate3d(0,6px,0) } to{ opacity:1; transform:none } }
.mo-out{ opacity:0; transform:scale(.96); transition:opacity var(--mo-fast) ease, transform var(--mo-fast) var(--mo-ease); pointer-events:none }

/* a figure that changed since the last draw (the Collection summary and chip counts, the Overview cards after a poll): the new value rises in.
   Never while amounts are hidden (motion.js swapText checks), so nothing draws the eye to a masked value. */
.mo-num{ animation:moNum var(--mo) var(--mo-ease) both }
@keyframes moNum{ from{ opacity:0; transform:translate3d(0,4px,0) } to{ opacity:1; transform:none } }

/* the card whose status just changed (a payment recorded from its sheet): a green ring that fades over a second, the status tag's own colour does the rest */
.mo-settled{ animation:moSettle 1.2s ease-out both }
@keyframes moSettle{ 0%,30%{ box-shadow:inset 0 0 0 2px var(--nile), var(--sh-1) } 100%{ box-shadow:inset 0 0 0 0 transparent, var(--sh-1) } }

/* a save the sheet refused before sending anything (a missing field): the button shakes once, the toast says what is missing. Sparingly: a server
   error after a round-trip does not shake (motion.js shake is called only for a refusal that came at once). */
.mo-shake{ animation:moShake var(--mo-slow) var(--mo-ease) }
@keyframes moShake{ 20%{ transform:translate3d(-5px,0,0) } 40%{ transform:translate3d(5px,0,0) } 60%{ transform:translate3d(-3px,0,0) } 80%{ transform:translate3d(3px,0,0) } }

/* the tick drawn in a confirmation toast (state.js toastDone): the stroke draws itself in 320 ms, after the toast has risen */
.mo-tick{ width:calc(18px * var(--dt,1)); height:calc(18px * var(--dt,1)); vertical-align:-4px; margin-inline-end:6px; flex:none; fill:none; stroke:currentColor; stroke-width:2.4; stroke-linecap:round; stroke-linejoin:round }
.mo-tick path{ stroke-dasharray:24; stroke-dashoffset:24; animation:moTick var(--mo-slow) var(--mo-ease) 80ms forwards }
@keyframes moTick{ to{ stroke-dashoffset:0 } }

/* chips, segments and the choice buttons in sheets: the fill cross-fades instead of snapping, and a press scales a touch (the segment had this already) */
.cchip, .choice button, .chips .chip{ transition:background var(--mo-fast) ease, color var(--mo-fast) ease, border-color var(--mo-fast) ease, box-shadow var(--mo-fast) ease, transform var(--mo-fast) var(--mo-ease) }
.cchip:active, .choice button:active, .chips .chip:active{ transform:scale(.96) }

/* cards that open something press like buttons (the Overview cards had this already) */
.ucard[data-card]{ cursor:pointer }
.ucard[data-card]:active, .pcard:active{ transform:scale(.985) }
.pcard{ transition:transform var(--mo-fast) var(--mo-ease) }
@media(min-width:901px){ .ucard[data-card]:active{ transform:none } }   /* on a wide screen the card does not open a sheet (wire.js), so it does not press */

/* an empty state after a filter or a search rises in, instead of popping where the rows were */
.empty{ animation:moIn var(--mo) ease both }

/* a fold opening (More options in the payment sheet, More details in the property and unit sheets, "Different amount or date"): the revealed fields
   rise in under the summary line; the height change itself is the browser's, the fields only fade and move 4 px */
details.more[open] > :not(summary), .mo-fold{ animation:moFold var(--mo) var(--mo-ease) both }
@keyframes moFold{ from{ opacity:0; transform:translate3d(0,-4px,0) } to{ opacity:1; transform:none } }

/* ---------- Reduce Motion: nothing moves. A new row, a changed figure and a fold are simply there; the tick is drawn; a leaving row fades only. ---------- */
@media(prefers-reduced-motion:reduce){
  .mo-in, .mo-num, .mo-settled, .mo-shake, .mo-tick path, .empty, details.more[open] > :not(summary), .mo-fold{ animation:none }
  .mo-tick path{ stroke-dashoffset:0 }
  .mo-out{ transition:opacity var(--mo-fast) ease; transform:none }
  .cchip, .choice button, .chips .chip, .pcard{ transition:none }
  .cchip:active, .choice button:active, .chips .chip:active, .ucard[data-card]:active, .pcard:active{ transform:none }
}
