/* ToxicsGuard 4.1 - motion for the staff dashboard and the player website (with motion.js).
   Rules: transform + opacity only, 150-300ms, nothing that moves layout, and nothing at all with reduced motion
   (the system setting, or the dashboard's Appearance > "Reduce motion" which sets html[data-motion=reduce]). */
:root {
  --m-ease: cubic-bezier(.2, .8, .2, 1);
  --m-out: cubic-bezier(.4, 0, 1, 1);
  --m-spring: cubic-bezier(.34, 1.4, .64, 1);
  --m-fast: 150ms; --m-mid: 220ms; --m-slow: 300ms;}

/* ---- no layout jumps while a page loads: the footer starts below the fold instead of being pushed down (website) */
#main.page { min-height: calc(100vh - var(--topH, 64px) + 1px); min-height: calc(100dvh - var(--topH, 64px) + 1px);}

/* ---- page content rising in (motion.js adds .m-rise + --m-i to the first dozen blocks of a new page) */
@keyframes m-rise { from { opacity: 0; transform: translate3d(0, 10px, 0) scale(.992); } }
.m-rise { animation: m-rise var(--m-slow) var(--m-ease) both; animation-delay: calc(var(--m-i, 0) * 32ms);}
/* bars / meters grow from the left on a new page */
@keyframes m-grow { from { transform: scaleX(0); } }
.m-enter .meter > i, .m-enter .bar > i, .m-enter .sbar .bar > i { transform-origin: left center; animation: m-grow 300ms var(--m-ease) both; animation-delay: 80ms;}

/* ---- buttons: lift on hover, press down on click */
.btn { transition: background .14s ease, border-color .14s ease, filter .14s ease, box-shadow .16s ease, color .14s ease, transform var(--m-fast) var(--m-ease); will-change: auto;}
@media (hover: hover) {
  .btn:not(:disabled):not(.disabled):hover { transform: translate3d(0, -1px, 0);}
  .card.click:hover, a.card:hover, .tchip:hover { transform: translate3d(0, -2px, 0);}
}
.btn:not(:disabled):not(.disabled):active { transform: translate3d(0, 0, 0) scale(.97); transition-duration: 60ms;}
.card.click, a.card, .tchip { transition: transform var(--m-mid) var(--m-ease), box-shadow var(--m-mid) ease, border-color .15s ease, background .15s ease;}

/* ---- toasts: spring in, slide out */
@keyframes m-toast-in { from { opacity: 0; transform: translate3d(28px, 0, 0) scale(.96); } }
@keyframes m-toast-out { to { opacity: 0; transform: translate3d(22px, 0, 0) scale(.98); } }
#toasts > .toast, .toasts > .toast { animation: m-toast-in 300ms var(--m-spring) both;}
#toasts > .toast.m-out, .toasts > .toast.m-out { animation: m-toast-out 220ms var(--m-out) forwards; pointer-events: none;}

/* ---- dialogs: scale in; side panel: slide with a softer curve */
@keyframes m-modal { from { opacity: 0; transform: translate3d(0, 10px, 0) scale(.965); } }
.modal { animation: m-modal 240ms var(--m-spring) both;}
.qv { transform: translate3d(36px, 0, 0); transition: transform 280ms var(--m-ease), opacity 200ms ease;}
.qv.on { transform: none;}

/* ---- skeletons: the shimmer is a moving layer (composited), not a repainted background */
.sk { position: relative; overflow: hidden; animation: none; background: var(--panel, rgba(var(--fg, 255,255,255), .05));}
.sk::after { content: ""; position: absolute; inset: 0; transform: translate3d(-100%, 0, 0);
  background: linear-gradient(90deg, transparent, rgba(255, 255, 255, .055), transparent); animation: m-shimmer 1.25s ease-in-out infinite;}
[data-theme="light"] .sk::after { background: linear-gradient(90deg, transparent, rgba(255, 255, 255, .7), transparent);}
[data-theme="light"] .sk { background: rgba(0, 0, 0, .055);}
@keyframes m-shimmer { to { transform: translate3d(100%, 0, 0); } }

/* ---- tabs: one underline slides to the selected tab (motion.js sets --ink-x / --ink-w) */
.tabs.m-inked { position: relative;}
.tabs.m-inked > .on, .tabs.m-inked > [aria-selected="true"] { border-bottom-color: transparent;}
.tabs.m-inked::after { content: ""; position: absolute; left: 0; bottom: 0; width: 1px; height: 2px; border-radius: 2px; pointer-events: none;
  background: var(--accent, var(--acc)); transform-origin: left center; transform: translate3d(var(--ink-x, 0), 0, 0) scaleX(var(--ink-w, 0));
  transition: transform 260ms var(--m-ease);}
.tabs.m-ink-still::after { transition: none;}

/* ---- light / dark switch: colours glide for a moment instead of snapping */
html.m-theming, html.m-theming body, html.m-theming *, html.m-theming *::before, html.m-theming *::after {
  transition: background-color 320ms ease, color 320ms ease, border-color 320ms ease, fill 320ms ease, stroke 320ms ease, box-shadow 320ms ease !important;}

/* ---- website hero art: motion.js moves it a little with scroll / mouse */
.hero2 .hero-art { will-change: transform; transition: transform 120ms linear;}

/* ---- website: moving between pages (Chrome / Edge cross-page transitions; others just load) */
@media (prefers-reduced-motion: no-preference) {
  @view-transition { navigation: auto;}
  header.top { view-transition-name: m-top;}
  ::view-transition-old(root) { animation: m-vt-out 160ms var(--m-out) both;}
  ::view-transition-new(root) { animation: m-vt-in 260ms var(--m-ease) both;}
  @keyframes m-vt-out { to { opacity: 0; transform: translate3d(0, -6px, 0); } }
  @keyframes m-vt-in { from { opacity: 0; transform: translate3d(0, 10px, 0); } }
}
:root[data-motion="reduce"] { view-transition-name: none;}

/* ---- reduced motion: everything above off */
@media (prefers-reduced-motion: reduce) {
  .m-rise, .m-enter .meter > i, .m-enter .bar > i, .m-enter .sbar .bar > i, .modal, #toasts > .toast, .toasts > .toast { animation: none !important;}
  .sk::after { animation: none; display: none;}
  .btn, .card.click, a.card, .tchip, .qv, .tabs.m-inked::after, .hero2 .hero-art { transition: none !important; transform: none !important;}
}
:root[data-motion="reduce"] .sk::after { display: none;}
:root[data-motion="reduce"] .btn:hover, :root[data-motion="reduce"] .btn:active, :root[data-motion="reduce"] .tchip:hover { transform: none;}
