.mo_reveal-on-scroll {
  opacity: 0;
  transform: translateY(16px);
  will-change: opacity, transform;
}

.mo_slide-up {
  opacity: 0;
  transform: translateY(100px);
  will-change: transform, opacity;
}

/* --- Reveal presets (start state) --- */
/* .mo_reveal-up   { opacity:0; transform: translateY(100); will-change: transform, opacity; }
.mo_reveal-left { opacity:0; transform: translateX(-100); will-change: transform, opacity; }
.mo_reveal-right{ opacity:0; transform: translateX(100);  will-change: transform, opacity; } */
.mo_reveal-up   { opacity:0; transform: translateY(100px); }
.mo_reveal-left { opacity:0; transform: translateX(-100px); }
.mo_reveal-right{ opacity:0; transform: translateX(100px); }

.revealed { opacity: 1 !important; transform: none !important; will-change: auto !important; }

/* Start hidden for typical direct-children AND for explicit item class */
.mo_stagger > *,
.mo_stagger .mo_stagger-item {
  opacity: 0;
  transform: translateY(12px);
  will-change: opacity, transform;
}

/* Count-up numbers (style only; value comes from JS) */
.mo_count-up { font-variant-numeric: tabular-nums; }

/* “Neo node ping” target should be circular; glow handled by JS/CSS combo */
.mo_neo-node-ping {
  position: relative;
  border-radius: 9999px;
  box-shadow: 0 0 0 0 rgba(0,122,204,0.25);
}

/* Card lift baseline */
.mo_lift-on-hover {
  transition: box-shadow .2s ease;
  box-shadow: 0 6px 16px rgba(0,0,0,0.06);
}

/* Link underline slide (CSS-only microinteraction) */
.mo_link-underline {
  position: relative; text-decoration: none; color: inherit;
}
.mo_link-underline::after {
  content:""; position:absolute; left:0; right:100%; bottom:-2px; height:2px;
  background: currentColor; transition: right .25s ease;
}
.mo_link-underline:hover::after { right:0; }

/* SVG draw helper (optional default stroke) */
/* Keep SVG hidden until JS primes it (prevents the flash) */
.mo_draw-on-view,
.mo_draw-on-view svg { visibility: hidden; }

/* JS adds this when primed so it becomes visible (but still “empty”) */
.mo_draw-prepped { visibility: visible; }

/* Optional: consistent stroke width if SVG scales */
.mo_draw-on-view *, .mo_draw-on-view svg * { vector-effect: non-scaling-stroke; }

/* Respect reduced motion: show art immediately */
@media (prefers-reduced-motion: reduce) {
  .mo_draw-on-view, .mo_draw-on-view svg { visibility: visible !important; }
}

/* Reduce motion: just show final state */
@media (prefers-reduced-motion: reduce) {
  .mo_draw-on-view * { stroke-dasharray: none !important; stroke-dashoffset: 0 !important; }
}

/* Respect prefers-reduced-motion */
/* @media (prefers-reduced-motion: reduce) {
  .reveal-up, .reveal-left, .reveal-right, .stagger > * {
    opacity: 1 !important; transform: none !important;
  }
} */
