/* ============================================================
   MTDOX MOTION+ — ambient depth, cursor light, ripples, staggers
   Loaded after mtdox.css so it can layer on top of the base motion.
   The auth layer is intentionally never touched here: login and
   registration must stay completely static.
   ============================================================ */

:root {
  --fx-violet: 139, 92, 246;
  --fx-rose: 251, 113, 133;
  --fx-cyan: 56, 189, 248;
}

/* ---------- Ambient atmosphere ---------- */

.fx-ambient {
  position: fixed;
  inset: 0;
  z-index: 2;
  overflow: hidden;
  pointer-events: none;
  contain: strict;
}

.fx-orb {
  position: absolute;
  border-radius: 50%;
  opacity: 0;
  animation: fxOrbDrift 22s ease-in-out infinite alternate, fxOrbIn 1.6s ease both;
  will-change: transform;
}

.fx-orb-a {
  top: -12vmax;
  left: -8vmax;
  width: 46vmax;
  height: 46vmax;
  background: radial-gradient(circle, rgba(var(--fx-violet), .3), transparent 66%);
  animation-delay: 0s, .1s;
}

.fx-orb-b {
  right: -14vmax;
  bottom: -16vmax;
  width: 52vmax;
  height: 52vmax;
  background: radial-gradient(circle, rgba(var(--fx-cyan), .16), transparent 68%);
  animation-duration: 28s, 1.6s;
  animation-delay: -6s, .25s;
}

.fx-orb-c {
  top: 38%;
  left: 46%;
  width: 30vmax;
  height: 30vmax;
  background: radial-gradient(circle, rgba(var(--fx-rose), .13), transparent 70%);
  animation-duration: 34s, 1.6s;
  animation-delay: -13s, .4s;
}

.fx-scan {
  position: absolute;
  inset: -10%;
  background: repeating-linear-gradient(
    to bottom,
    rgba(255, 255, 255, .02) 0 1px,
    transparent 1px 4px
  );
  opacity: .38;
  animation: fxScan 9s linear infinite;
}

.fx-scan::after {
  position: absolute;
  inset: 0;
  background: linear-gradient(
    to bottom,
    transparent 0%,
    rgba(var(--fx-violet), .1) 46%,
    rgba(var(--fx-cyan), .08) 50%,
    transparent 54%
  );
  content: "";
  animation: fxScanSweep 7.5s ease-in-out infinite;
}

/* Occasional shooting streaks across the sky. */
.fx-streak {
  position: absolute;
  top: var(--fx-y, 20%);
  left: -24vw;
  width: 22vw;
  height: 1px;
  background: linear-gradient(90deg, transparent, rgba(255, 255, 255, .55), rgba(var(--fx-cyan), .35), transparent);
  opacity: 0;
  transform: rotate(var(--fx-r, 14deg));
  animation: fxStreak var(--fx-dur, 11s) var(--fx-delay, 0s) linear infinite;
}

/* The auth screen stays completely static: no ambient layers behind it. */
body.auth-open .fx-ambient,
body.auth-open .fx-cursor {
  display: none;
}

/* ---------- Cursor light ---------- */

.fx-cursor {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 3;
  width: 460px;
  height: 460px;
  margin: -230px 0 0 -230px;
  border-radius: 50%;
  background: radial-gradient(
    circle,
    rgba(var(--fx-violet), .16) 0%,
    rgba(var(--fx-cyan), .07) 38%,
    transparent 68%
  );
  opacity: 0;
  pointer-events: none;
  transform: translate3d(-100vw, -100vh, 0);
  transition: opacity .5s ease;
  will-change: transform;
}

.fx-cursor.is-live { opacity: 1; }

/* ---------- Click ripple ---------- */

.fx-ripple {
  position: fixed;
  z-index: 90;
  width: 16px;
  height: 16px;
  margin: -8px 0 0 -8px;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(255, 255, 255, .5), rgba(var(--fx-violet), .3) 55%, transparent 72%);
  pointer-events: none;
  animation: fxRippleOut .62s cubic-bezier(.2, .7, .3, 1) forwards;
}

/* ---------- Shared entrances ---------- */

/* User rows have no entrance animation of their own, so they get one here.
   Admin rows keep their gradient animation untouched (JS skips them). */
.user-row.fx-in {
  animation: fxFadeRise .5s cubic-bezier(.2, .85, .25, 1) both;
  animation-delay: calc(var(--fx-i, 0) * 42ms);
}

/* Comments already animate in; stagger them without replacing commentIn. */
.comment.fx-in {
  animation-delay: calc(var(--fx-i, 0) * 42ms);
}

/* ---------- Paste page polish ---------- */

.paste-brand em {
  background: linear-gradient(100deg, #c9a7ff 0%, #f4f1ff 42%, #8b5cf6 76%, #c9a7ff 100%);
  background-size: 260% 100%;
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  animation: fxTextFlow 7s linear infinite;
}

#paste-title {
  position: relative;
  background: linear-gradient(
    100deg,
    #ffffff 0%,
    #ffffff 24%,
    #d7c5ff 40%,
    #9d74ff 48%,
    #efe6ff 58%,
    #ffffff 74%,
    #ffffff 100%
  );
  background-size: 280% 100%;
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  animation: fxTextFlow 11s linear infinite;
}

.paste-doc:not([hidden]) {
  animation: fxPasteOpen .72s cubic-bezier(.16, 1, .3, 1) both;
}

.paste-doc:not([hidden]) .paste-meta,
.paste-doc:not([hidden]) .paste-place,
.paste-doc:not([hidden]) .paste-body,
.paste-doc:not([hidden]) .paste-foot {
  animation: fxFadeRise .6s cubic-bezier(.2, .85, .25, 1) both;
}
.paste-doc:not([hidden]) .paste-meta { animation-delay: .1s; }
.paste-doc:not([hidden]) .paste-place { animation-delay: .2s; }
.paste-doc:not([hidden]) .paste-body { animation-delay: .3s; }
.paste-doc:not([hidden]) .paste-foot { animation-delay: .4s; }

.paste-author,
.paste-return,
.paste-actions a {
  position: relative;
  transition: color .22s ease, transform .22s cubic-bezier(.2, .8, .2, 1);
}

.paste-author::after,
.paste-return::after,
.paste-actions a::after {
  position: absolute;
  left: 0;
  right: 0;
  bottom: -3px;
  height: 1px;
  background: linear-gradient(90deg, rgba(var(--fx-violet), .9), rgba(var(--fx-cyan), .7));
  content: "";
  transform: scaleX(0);
  transform-origin: left;
  transition: transform .3s cubic-bezier(.2, .8, .2, 1);
}

.paste-author:hover,
.paste-return:hover,
.paste-actions a:hover { transform: translateY(-1px); }

.paste-author:hover::after,
.paste-return:hover::after,
.paste-actions a:hover::after { transform: scaleX(1); }

.paste-glow {
  animation-duration: 22s, 26s;
}

/* ---------- Cards: light sweep + lift ---------- */

.dash-card,
.post-card,
.profile-card,
.note-view-card,
.ip-card {
  position: relative;
}

.dash-card::after,
.post-card::after {
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background: linear-gradient(120deg, transparent 36%, rgba(255, 255, 255, .07) 50%, transparent 64%);
  background-size: 260% 100%;
  content: "";
  opacity: 0;
  pointer-events: none;
  transition: opacity .3s ease;
}

.dash-card:hover::after,
.post-card:hover::after {
  opacity: 1;
  animation: fxCardSheen 1.4s ease-out;
}

/* ---------- Avatar halo ---------- */

.profile-avatar {
  animation: fxAvatarHalo 5.5s ease-in-out infinite;
}

.profile-edit-form:not([hidden]) .profile-avatar {
  animation-duration: 3.4s;
}

/* ---------- Heading underline shimmer ---------- */

.dash-head h2,
.inv-head-main h2,
.profile-title h2 {
  position: relative;
}

.dash-head h2::before,
.inv-head-main h2::before,
.profile-title h2::before {
  position: absolute;
  left: 0;
  right: 0;
  bottom: -5px;
  height: 1px;
  background: linear-gradient(90deg, rgba(var(--fx-violet), 0), rgba(var(--fx-violet), .85), rgba(var(--fx-cyan), .6), rgba(var(--fx-violet), 0));
  background-size: 220% 100%;
  content: "";
  opacity: .8;
  pointer-events: none;
  animation: fxUnderline 6s ease-in-out infinite;
}

/* ---------- Toast with a draining progress line ---------- */

.toast::after {
  position: absolute;
  left: 12px;
  right: 12px;
  bottom: 5px;
  height: 2px;
  border-radius: 2px;
  background: linear-gradient(90deg, rgba(var(--fx-violet), .9), rgba(var(--fx-cyan), .85));
  content: "";
  opacity: 0;
  pointer-events: none;
  transform-origin: left;
}

.toast.is-visible::after {
  animation: fxToastDrain 3.4s linear forwards;
}

/* ---------- Investigation board: breathing edges + node pulse ---------- */

.inv-edge {
  animation: edgeDraw .5s ease both, fxEdgeBreath 4.2s 1s ease-in-out infinite;
}

.inv-node {
  transition: box-shadow .25s ease, transform .25s cubic-bezier(.2, .8, .2, 1), border-color .25s ease;
}

.inv-node:hover {
  box-shadow: 0 0 0 1px rgba(var(--fx-violet), .35), 0 12px 30px rgba(0, 0, 0, .34), 0 0 24px rgba(var(--fx-violet), .2);
}

/* ---------- Chat: typing dots while the field has focus ---------- */

.chat-compose:focus-within textarea {
  box-shadow: 0 0 0 1px rgba(var(--fx-violet), .35), 0 0 22px rgba(var(--fx-violet), .12) inset;
}

/* ---------- Scroll progress (paste reader) ---------- */

.fx-scroll {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 80;
  width: 100%;
  height: 2px;
  background: linear-gradient(90deg, #8b5cf6, #38bdf8, #fb7185);
  transform: scaleX(0);
  transform-origin: left;
  pointer-events: none;
  opacity: 0;
  transition: opacity .3s ease;
}

body.fx-scrollable .fx-scroll { opacity: 1; }

/* ---------- Keyframes ---------- */

@keyframes fxOrbIn {
  from { opacity: 0; }
  to { opacity: 1; }
}

@keyframes fxOrbDrift {
  0% { transform: translate3d(0, 0, 0) scale(1); }
  50% { transform: translate3d(3vmax, 2vmax, 0) scale(1.08); }
  100% { transform: translate3d(-2vmax, 4vmax, 0) scale(.96); }
}

@keyframes fxScan {
  from { transform: translateY(0); }
  to { transform: translateY(4px); }
}

@keyframes fxScanSweep {
  0%, 100% { transform: translateY(-46%); opacity: .25; }
  50% { transform: translateY(46%); opacity: .75; }
}

@keyframes fxStreak {
  0%, 90% { opacity: 0; transform: translate3d(0, 0, 0) rotate(var(--fx-r, 14deg)); }
  92% { opacity: .75; }
  100% { opacity: 0; transform: translate3d(135vw, 38vh, 0) rotate(var(--fx-r, 14deg)); }
}

@keyframes fxRippleOut {
  0% { opacity: .85; transform: scale(.25); }
  100% { opacity: 0; transform: scale(9); }
}

@keyframes fxFadeRise {
  from { opacity: 0; transform: translateY(10px) scale(.988); }
  to { opacity: 1; transform: none; }
}

@keyframes fxPasteOpen {
  from { opacity: 0; transform: translateY(26px) scale(.985); filter: blur(5px); }
  to { opacity: 1; transform: none; filter: none; }
}

@keyframes fxTextFlow {
  from { background-position: 0% 50%; }
  to { background-position: 260% 50%; }
}

@keyframes fxCardSheen {
  from { background-position: 130% 50%; }
  to { background-position: -130% 50%; }
}

@keyframes fxAvatarHalo {
  0%, 100% { box-shadow: 0 0 0 1px rgba(var(--fx-violet), .22), 0 0 18px rgba(var(--fx-violet), .16); }
  50% { box-shadow: 0 0 0 1px rgba(var(--fx-cyan), .3), 0 0 26px rgba(var(--fx-violet), .34); }
}

@keyframes fxUnderline {
  0%, 100% { background-position: 0% 50%; opacity: .45; }
  50% { background-position: 100% 50%; opacity: .95; }
}

@keyframes fxToastDrain {
  0% { opacity: .9; transform: scaleX(1); }
  80% { opacity: .7; }
  100% { opacity: 0; transform: scaleX(0); }
}

@keyframes fxEdgeBreath {
  0%, 100% { stroke-opacity: .55; }
  50% { stroke-opacity: 1; }
}

/* ---------- Small screens: lighter atmosphere ---------- */

@media (max-width: 720px) {
  .fx-cursor { display: none; }
  .fx-ambient { opacity: .8; }
  .fx-scan { opacity: .28; }
  .dash-card::after,
  .post-card::after { display: none; }
}

/* ---------- Reduced motion: everything off ---------- */

@media (prefers-reduced-motion: reduce) {
  .fx-ambient,
  .fx-cursor,
  .fx-ripple,
  .fx-scroll { display: none !important; }

  .fx-in,
  .paste-brand em,
  #paste-title,
  .paste-doc:not([hidden]),
  .paste-doc:not([hidden]) .paste-meta,
  .paste-doc:not([hidden]) .paste-place,
  .paste-doc:not([hidden]) .paste-body,
  .paste-doc:not([hidden]) .paste-foot,
  .paste-glow,
  .profile-avatar,
  .dash-head h2::before,
  .inv-head-main h2::before,
  .profile-title h2::before,
  .inv-edge,
  .toast.is-visible::after {
    animation: none !important;
  }

  .dash-card::after,
  .post-card::after,
  .paste-author::after,
  .paste-return::after,
  .paste-actions a::after {
    display: none !important;
  }

  #paste-title,
  .paste-brand em {
    -webkit-text-fill-color: currentColor;
    background: none;
  }
}
