/* Site-wide motion + interaction system. Used alongside styles.css. */

/* Reduce-motion respect — every animation below is opt-out for accessibility */
@media (prefers-reduced-motion: reduce) {
  .jv-fadeup, .jv-rise, .jv-word, .jv-words > span,
  .jv-glow-hover, .jv-rotate-hover, .jv-scale-hover, .jv-magnetic {
    transition: none !important; animation: none !important;
    transform: none !important; opacity: 1 !important;
  }
}

/* ---------- Parallax-aware grid background ---------- */
/* Re-style the body::before from styles.css to react to mouse position */
body::before {
  transform: translate(calc(var(--jv-mx, 0) * 18px), calc(var(--jv-my, 0) * 18px));
  transition: transform .35s cubic-bezier(.2,.7,.2,1);
}
/* Floating cyan orb that drifts with the mouse — sits behind everything */
body {
  position: relative;
}
body::after {
  /* keep the existing scanline (defined in styles.css) — animations.css adds nothing */
}
.jv-orb-bg {
  position: fixed;
  inset: -25vmax -25vmax auto auto;
  width: 60vmax; height: 60vmax;
  pointer-events: none;
  z-index: 0;
  background: radial-gradient(circle at center, rgba(92,242,255,0.10) 0%, rgba(92,242,255,0.04) 30%, transparent 60%);
  filter: blur(40px);
  transform: translate(calc(var(--jv-mx,0) * -40px), calc(var(--jv-my,0) * -40px));
  transition: transform .5s cubic-bezier(.2,.7,.2,1);
}

/* ---------- Scroll-triggered fade-up + stagger ---------- */
.jv-fadeup {
  opacity: 0;
  transform: translateY(28px);
  transition: opacity .7s cubic-bezier(.2,.7,.2,1), transform .7s cubic-bezier(.2,.7,.2,1);
  will-change: opacity, transform;
}
.jv-fadeup.is-visible { opacity: 1; transform: translateY(0); }

.jv-stagger > * {
  opacity: 0; transform: translateY(20px);
  transition: opacity .55s cubic-bezier(.2,.7,.2,1), transform .55s cubic-bezier(.2,.7,.2,1);
}
.jv-stagger.is-visible > * { opacity: 1; transform: translateY(0); }
.jv-stagger.is-visible > *:nth-child(1) { transition-delay: .03s; }
.jv-stagger.is-visible > *:nth-child(2) { transition-delay: .09s; }
.jv-stagger.is-visible > *:nth-child(3) { transition-delay: .15s; }
.jv-stagger.is-visible > *:nth-child(4) { transition-delay: .21s; }
.jv-stagger.is-visible > *:nth-child(5) { transition-delay: .27s; }
.jv-stagger.is-visible > *:nth-child(6) { transition-delay: .33s; }
.jv-stagger.is-visible > *:nth-child(7) { transition-delay: .39s; }
.jv-stagger.is-visible > *:nth-child(8) { transition-delay: .45s; }

/* ---------- Word-by-word reveal (apply .jv-words to a heading) ---------- */
.jv-words > span {
  display: inline-block;
  opacity: 0;
  transform: translateY(16px);
  transition: opacity .5s ease, transform .5s cubic-bezier(.2,.7,.2,1);
}
.jv-words.is-visible > span { opacity: 1; transform: translateY(0); }
.jv-words.is-visible > span:nth-child(1)  { transition-delay: .04s; }
.jv-words.is-visible > span:nth-child(2)  { transition-delay: .10s; }
.jv-words.is-visible > span:nth-child(3)  { transition-delay: .16s; }
.jv-words.is-visible > span:nth-child(4)  { transition-delay: .22s; }
.jv-words.is-visible > span:nth-child(5)  { transition-delay: .28s; }
.jv-words.is-visible > span:nth-child(6)  { transition-delay: .34s; }
.jv-words.is-visible > span:nth-child(7)  { transition-delay: .40s; }
.jv-words.is-visible > span:nth-child(8)  { transition-delay: .46s; }
.jv-words.is-visible > span:nth-child(9)  { transition-delay: .52s; }
.jv-words.is-visible > span:nth-child(n+10) { transition-delay: .58s; }

/* ---------- Hover utilities ---------- */
.jv-glow-hover {
  transition: box-shadow .25s ease, transform .25s cubic-bezier(.2,.7,.2,1), border-color .25s ease;
}
.jv-glow-hover:hover {
  box-shadow: 0 0 22px rgba(92,242,255,0.35), 0 0 60px rgba(92,242,255,0.15);
  border-color: var(--jv-cyan);
}

.jv-scale-hover { transition: transform .25s cubic-bezier(.2,.7,.2,1), box-shadow .25s ease; }
.jv-scale-hover:hover { transform: scale(1.03); }

.jv-rotate-hover { transition: transform .35s cubic-bezier(.2,.7,.2,1); }
.jv-rotate-hover:hover { transform: rotate(2deg) scale(1.02); }

/* Cyan rim around panels on hover */
.jv-panel { transition: border-color .25s ease, box-shadow .25s ease, transform .35s cubic-bezier(.2,.7,.2,1); }
.jv-panel:hover {
  border-color: rgba(92,242,255,0.45);
  box-shadow:
    inset 0 0 24px rgba(92,242,255,0.06),
    0 0 26px rgba(92,242,255,0.18);
}

/* Buttons get a magnetic + ripple feel */
.jv-btn { transition: background .15s ease, color .15s ease, box-shadow .15s ease, transform .12s cubic-bezier(.2,.7,.2,1), border-color .15s ease; }
.jv-btn:hover { transform: translateY(-1px); }
.jv-btn:active { transform: translateY(1px) scale(.98); }

/* ---------- Magnetic button ---------- */
.jv-magnetic { transition: transform .12s cubic-bezier(.2,.7,.2,1); will-change: transform; }

/* ---------- Cursor glow ---------- */
.jv-cursor-glow {
  position: fixed;
  width: 28px; height: 28px;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(92,242,255,0.55) 0%, rgba(92,242,255,0.0) 65%);
  pointer-events: none;
  z-index: 9997;
  mix-blend-mode: screen;
  transform: translate(-50%, -50%);
  transition: width .15s ease, height .15s ease, opacity .15s ease;
  opacity: 0;
}
.jv-cursor-glow.is-active { opacity: 1; }
.jv-cursor-glow.is-hot { width: 56px; height: 56px; }
@media (pointer: coarse) { .jv-cursor-glow { display: none; } }

/* ---------- Animated link underline ---------- */
a.jv-anchor {
  position: relative;
  text-decoration: none;
}
a.jv-anchor::after {
  content: ""; position: absolute; left: 0; bottom: -2px;
  width: 100%; height: 1px; background: var(--jv-cyan);
  transform: scaleX(0); transform-origin: right;
  transition: transform .35s cubic-bezier(.2,.7,.2,1);
}
a.jv-anchor:hover::after { transform: scaleX(1); transform-origin: left; }

/* ---------- Ticker pulse (number counters / live values) ---------- */
.jv-tick { transition: color .15s ease; }
.jv-tick.is-flash { color: #fff !important; text-shadow: 0 0 14px rgba(92,242,255,0.8); }

/* ---------- Plotly chart subtle glow on hover ---------- */
.jv-plot, .jv-takeover-plot {
  transition: filter .25s ease, transform .25s ease;
}
.jv-panel:hover .jv-plot {
  filter: drop-shadow(0 0 18px rgba(92,242,255,0.20));
}

/* ---------- Border-gradient sweep on focused inputs (atop existing styles) ---------- */
.jv-input { position: relative; }
.jv-input:focus { animation: input-rim 1.6s ease-out 1; }
@keyframes input-rim {
  0%   { box-shadow: 0 0 0 1px rgba(92,242,255,0.0), 0 0 28px rgba(92,242,255,0.0); }
  35%  { box-shadow: 0 0 0 1px rgba(92,242,255,0.5), 0 0 28px rgba(92,242,255,0.45); }
  100% { box-shadow: 0 0 0 3px rgba(92,242,255,0.10), 0 0 20px rgba(92,242,255,0.18); }
}

/* ---------- Smooth scroll ---------- */
html { scroll-behavior: smooth; }

/* ---------- Floating glow rim on cards ---------- */
.jv-rim::before {
  content: "";
  position: absolute; inset: -1px;
  border-radius: inherit;
  padding: 1px;
  background: linear-gradient(135deg, rgba(92,242,255,0.6), rgba(92,242,255,0.0) 40%, rgba(92,242,255,0) 60%, rgba(92,242,255,0.5));
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
          mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor; mask-composite: exclude;
  pointer-events: none; opacity: 0; transition: opacity .3s ease;
}
.jv-rim:hover::before { opacity: 1; }

/* =====================================================================
   ARC REACTOR — central animated centerpiece (Stark-HUD style)
   Pure CSS / SVG; zero JS for the visuals (data drives only the labels).
   ===================================================================== */
.jv-reactor {
  position: relative; width: 100%; aspect-ratio: 1 / 1;
  display: grid; place-items: center;
  filter: drop-shadow(0 0 24px rgba(92,242,255,0.30));
}
.jv-reactor svg { width: 100%; height: 100%; overflow: visible; }
.jv-reactor .ring        { transform-origin: 50% 50%; animation: jv-spin-cw  18s linear infinite; }
.jv-reactor .ring-rev    { transform-origin: 50% 50%; animation: jv-spin-ccw 26s linear infinite; }
.jv-reactor .ring-fast   { transform-origin: 50% 50%; animation: jv-spin-cw   9s linear infinite; }
.jv-reactor .sweep       { transform-origin: 50% 50%; animation: jv-spin-cw   4s linear infinite;
                           transform-box: fill-box; }
.jv-reactor .core        { animation: jv-pulse 2.4s ease-in-out infinite; transform-origin: 50% 50%;
                           transform-box: fill-box; }
.jv-reactor .core-ring   { animation: jv-breathe 3.6s ease-in-out infinite; transform-origin: 50% 50%;
                           transform-box: fill-box; }
.jv-reactor .tick        { animation: jv-flicker 5.2s steps(2, end) infinite; }
.jv-reactor[data-alert="warn"] { filter: drop-shadow(0 0 28px rgba(255,180,84,0.55)); }
.jv-reactor[data-alert="crit"] { filter: drop-shadow(0 0 32px rgba(255,85,119,0.70));
                                 animation: jv-shake 0.18s cubic-bezier(.2,.7,.2,1) infinite; }

@keyframes jv-spin-cw  { to { transform: rotate(360deg); } }
@keyframes jv-spin-ccw { to { transform: rotate(-360deg); } }
@keyframes jv-pulse {
  0%, 100% { transform: scale(1);    opacity: 0.95; filter: brightness(1); }
  50%      { transform: scale(1.06); opacity: 1;    filter: brightness(1.35); }
}
@keyframes jv-breathe {
  0%, 100% { stroke-opacity: 0.55; }
  50%      { stroke-opacity: 1; }
}
@keyframes jv-flicker {
  0%, 92%, 100% { opacity: 0.85; }
  93%, 95%, 97% { opacity: 0.25; }
  94%, 96%      { opacity: 1; }
}
@keyframes jv-shake {
  0%, 100% { transform: translate(0,0); }
  25%      { transform: translate(-1px, 1px); }
  50%      { transform: translate(1px, -1px); }
  75%      { transform: translate(-1px, -1px); }
}

/* Conic radar-sweep wedge inside the reactor.
   NOTE: linearGradient fills break when the parent <g> is CSS-rotated (gradient
   coordinate system doesn't follow the transform).  Use a plain fill instead. */
.jv-reactor .radar-wedge {
  fill: #5cf2ff;
  fill-opacity: 0.28;
  filter: drop-shadow(0 0 6px rgba(92,242,255,0.5));
}

/* =====================================================================
   TICKER — horizontal scrolling log bar
   ===================================================================== */
.jv-ticker {
  position: relative;
  overflow: hidden;
  border-top: 1px solid rgba(92,242,255,0.18);
  border-bottom: 1px solid rgba(92,242,255,0.18);
  background: linear-gradient(180deg, rgba(8,18,28,0.6), rgba(5,10,16,0.6));
}
.jv-ticker-track {
  display: inline-flex; gap: 3rem;
  padding: 0.4rem 0;
  white-space: nowrap;
  animation: jv-marquee 60s linear infinite;
  will-change: transform;
}
.jv-ticker:hover .jv-ticker-track { animation-play-state: paused; }
@keyframes jv-marquee {
  from { transform: translateX(0); }
  to   { transform: translateX(-50%); }
}

/* =====================================================================
   SPARKLINE bars  — used for per-core CPU
   ===================================================================== */
.jv-bar-row {
  display: grid; grid-template-columns: 36px 1fr 36px;
  gap: 6px; align-items: center;
  font-family: var(--font-mono); font-size: 10px;
  padding: 1px 0;
}
.jv-bar-row .bar-track {
  height: 6px; background: rgba(92,242,255,0.08);
  border-radius: 1px; overflow: hidden; position: relative;
}
.jv-bar-row .bar-fill {
  height: 100%;
  background: linear-gradient(90deg, var(--jv-cyan), var(--jv-amber));
  transition: width .35s cubic-bezier(.2,.7,.2,1);
  box-shadow: 0 0 8px rgba(92,242,255,0.55);
}
.jv-bar-row .bar-fill[data-hot="1"] {
  background: linear-gradient(90deg, var(--jv-amber), var(--jv-red));
  box-shadow: 0 0 10px rgba(255,85,119,0.55);
}

/* =====================================================================
   MEDICAL VITRUVIAN BODY — anatomical SVG with mapped vitals
   ===================================================================== */
.jv-vitruvian svg { width: 100%; height: 100%; }
.jv-vitruvian .organ {
  fill: rgba(92,242,255,0.10);
  stroke: var(--jv-cyan);
  stroke-width: 0.6;
  transition: fill .4s ease, filter .4s ease;
  filter: drop-shadow(0 0 4px rgba(92,242,255,0.30));
}
.jv-vitruvian .organ.is-hot {
  fill: rgba(255,180,84,0.22);
  stroke: var(--jv-amber);
  filter: drop-shadow(0 0 8px rgba(255,180,84,0.65));
}
.jv-vitruvian .organ.is-crit {
  fill: rgba(255,85,119,0.30);
  stroke: var(--jv-red);
  filter: drop-shadow(0 0 12px rgba(255,85,119,0.70));
  animation: jv-pulse 1.4s ease-in-out infinite;
}
.jv-vitruvian .skeleton {
  fill: none; stroke: rgba(92,242,255,0.45); stroke-width: 0.7;
}
.jv-vitruvian .scan-line {
  stroke: var(--jv-cyan); stroke-width: 0.7; opacity: 0.7;
  animation: jv-vit-scan 4s linear infinite;
}
@keyframes jv-vit-scan {
  0%   { transform: translateY(-5%); opacity: 0; }
  10%  { opacity: 0.9; }
  90%  { opacity: 0.9; }
  100% { transform: translateY(105%); opacity: 0; }
}

/* =====================================================================
   RADIAL CONIC SWEEP — for the globe + reactor halo
   ===================================================================== */
.jv-conic-sweep {
  position: absolute; inset: 0; pointer-events: none;
  background: conic-gradient(from 0deg,
              rgba(92,242,255,0) 0deg,
              rgba(92,242,255,0.35) 25deg,
              rgba(92,242,255,0) 60deg,
              rgba(92,242,255,0) 360deg);
  animation: jv-spin-cw 6s linear infinite;
  mix-blend-mode: screen;
  border-radius: inherit;
}

/* =====================================================================
   DATA DOTS — used as decorative readouts in the corners
   ===================================================================== */
.jv-dotgrid {
  display: grid;
  grid-template-columns: repeat(20, 1fr);
  gap: 2px;
  height: 24px;
}
.jv-dotgrid > i {
  display: block; height: 100%;
  background: rgba(92,242,255,0.10);
  border-radius: 1px;
}
.jv-dotgrid > i.on  { background: var(--jv-cyan); box-shadow: 0 0 6px rgba(92,242,255,0.7); }
.jv-dotgrid > i.hot { background: var(--jv-amber); box-shadow: 0 0 6px rgba(255,180,84,0.7); }

/* =====================================================================
   TINY PILL VARIANTS
   ===================================================================== */
.jv-pill-ok   { color: var(--jv-cyan); border-color: var(--jv-cyan); }
.jv-pill-warn { color: var(--jv-amber); border-color: var(--jv-amber); }
.jv-pill-bad  { color: var(--jv-red); border-color: var(--jv-red); }

/* Reduce motion */
@media (prefers-reduced-motion: reduce) {
  .jv-reactor .ring, .jv-reactor .ring-rev, .jv-reactor .ring-fast,
  .jv-reactor .sweep, .jv-reactor .core, .jv-reactor .core-ring,
  .jv-reactor .tick, .jv-conic-sweep, .jv-ticker-track,
  .jv-vitruvian .scan-line {
    animation: none !important;
  }
}
