/* ==========================================================================
   RIVANOVA HEALTHCARE — animations.css
   Keyframes · scroll-reveal states · decorative motion · reduced-motion guards
   --------------------------------------------------------------------------
   Everything here is transform/opacity driven so it stays on the compositor
   and never triggers layout. Reveal states are toggled by IntersectionObserver
   in /assets/js/animations.js.
   ========================================================================== */

/* ==========================================================================
   1. KEYFRAMES
   ========================================================================== */
@keyframes fade-up {
  from { opacity: 0; transform: translate3d(0, 26px, 0); }
  to   { opacity: 1; transform: none; }
}
@keyframes fade-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}
@keyframes spin { to { transform: rotate(360deg); } }

@keyframes pl-spin {
  0%   { transform: rotate(0deg);   stroke-dasharray: 40 220; }
  50%  { transform: rotate(220deg); stroke-dasharray: 170 90; }
  100% { transform: rotate(720deg); stroke-dasharray: 40 220; }
}
@keyframes pl-draw { to { stroke-dashoffset: 0; } }

@keyframes pulse-ring {
  0%   { box-shadow: 0 0 0 0 rgb(22 199 154 / 0.6); }
  70%  { box-shadow: 0 0 0 9px rgb(22 199 154 / 0); }
  100% { box-shadow: 0 0 0 0 rgb(22 199 154 / 0); }
}

@keyframes ripple-out {
  to { transform: scale(2.6); opacity: 0; }
}

@keyframes float-soft {
  0%, 100% { transform: translate3d(0, 0, 0) scale(1); }
  50%      { transform: translate3d(0, -18px, 0) scale(1.04); }
}
@keyframes float-alt {
  0%, 100% { transform: translate3d(0, 0, 0) rotate(0deg); }
  33%      { transform: translate3d(10px, -14px, 0) rotate(4deg); }
  66%      { transform: translate3d(-8px, -22px, 0) rotate(-3deg); }
}

@keyframes orb-drift {
  0%   { transform: translate3d(0, 0, 0) scale(1); }
  33%  { transform: translate3d(4%, -6%, 0) scale(1.09); }
  66%  { transform: translate3d(-5%, 4%, 0) scale(0.95); }
  100% { transform: translate3d(0, 0, 0) scale(1); }
}

@keyframes aurora-drift {
  from { transform: translateX(-50%) translateY(0) rotate(0deg); opacity: 0.85; }
  to   { transform: translateX(-46%) translateY(28px) rotate(6deg); opacity: 1; }
}

@keyframes shimmer {
  from { background-position: -180% 0; }
  to   { background-position: 180% 0; }
}

@keyframes marquee-x {
  from { transform: translate3d(0, 0, 0); }
  to   { transform: translate3d(-50%, 0, 0); }
}

@keyframes toast-in {
  from { opacity: 0; transform: translateY(22px) scale(0.97); }
  to   { opacity: 1; transform: none; }
}
@keyframes toast-out {
  to { opacity: 0; transform: translateY(14px) scale(0.97); }
}

/* Hero decor */
@keyframes dna-rotate { to { transform: rotateY(360deg); } }
@keyframes dash-flow  { to { stroke-dashoffset: -1000; } }
@keyframes capsule-bob {
  0%, 100% { transform: translate3d(0, 0, 0) rotate(var(--rot, -18deg)); }
  50%      { transform: translate3d(0, -26px, 0) rotate(calc(var(--rot, -18deg) + 8deg)); }
}
@keyframes ecg-sweep {
  0%   { stroke-dashoffset: 1400; opacity: 0; }
  8%   { opacity: 1; }
  85%  { opacity: 1; }
  100% { stroke-dashoffset: 0; opacity: 0; }
}
@keyframes ring-expand {
  0%   { transform: scale(0.6); opacity: 0.55; }
  100% { transform: scale(1.5); opacity: 0; }
}
@keyframes tick-in {
  from { stroke-dashoffset: 40; }
  to   { stroke-dashoffset: 0; }
}
@keyframes gradient-pan {
  0%   { background-position: 0% 50%; }
  50%  { background-position: 100% 50%; }
  100% { background-position: 0% 50%; }
}
@keyframes bob-slow {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(-10px); }
}

/* ==========================================================================
   2. SCROLL REVEAL
   The base state is applied only when JS is present (html.js), so the content
   remains fully visible for no-JS users and for crawlers.
   ========================================================================== */
.js [data-reveal] {
  opacity: 0;
  transform: translate3d(0, 30px, 0);
  transition:
    opacity 900ms var(--ease-out),
    transform 900ms var(--ease-out);
  transition-delay: var(--reveal-delay, 0ms);
  will-change: opacity, transform;
}
.js [data-reveal='left']  { transform: translate3d(-42px, 0, 0); }
.js [data-reveal='right'] { transform: translate3d(42px, 0, 0); }
.js [data-reveal='zoom']  { transform: scale(0.93); }
.js [data-reveal='blur']  { filter: blur(12px); transform: translate3d(0, 22px, 0); transition-property: opacity, transform, filter; }
.js [data-reveal='clip']  {
  opacity: 1;
  transform: none;
  clip-path: inset(0 0 100% 0);
  transition: clip-path 1100ms var(--ease-out);
}
.js [data-reveal='fade']  { transform: none; }

.js [data-reveal].is-in {
  opacity: 1;
  transform: none;
  filter: none;
  clip-path: inset(0 0 0 0);
  will-change: auto;
}

/* Staggered children — the JS assigns --reveal-delay per index */
.js [data-reveal-group] > * {
  opacity: 0;
  transform: translate3d(0, 26px, 0);
  transition: opacity 800ms var(--ease-out), transform 800ms var(--ease-out);
  transition-delay: var(--reveal-delay, 0ms);
}
.js [data-reveal-group].is-in > * {
  opacity: 1;
  transform: none;
}

/* Word-by-word headline reveal (JS wraps each word in .word > span).
   The padding/negative-margin pair gives descenders (g, y, p) room inside the
   overflow mask; without it the mask shears the bottom off the type. */
.word {
  display: inline-block;
  overflow: hidden;
  vertical-align: bottom;
  padding-bottom: 0.16em;
  margin-bottom: -0.16em;
}
.word > span {
  display: inline-block;
  transform: translateY(105%);
  transition: transform 900ms var(--ease-out);
  transition-delay: var(--reveal-delay, 0ms);
}
.is-in .word > span { transform: none; }

/* ==========================================================================
   3. DECORATIVE BACKGROUND ELEMENTS
   ========================================================================== */

/* --- Soft gradient orbs --- */
.orb {
  position: absolute;
  border-radius: 50%;
  filter: blur(60px);
  pointer-events: none;
  opacity: 0.55;
  will-change: transform;
  animation: orb-drift 26s var(--ease-in-out) infinite;
}
.orb--a {
  width: clamp(280px, 34vw, 560px);
  aspect-ratio: 1;
  top: -14%;
  right: -8%;
  background: radial-gradient(circle, rgb(0 174 239 / 0.55), transparent 66%);
}
.orb--b {
  width: clamp(240px, 28vw, 480px);
  aspect-ratio: 1;
  bottom: -22%;
  left: -6%;
  background: radial-gradient(circle, rgb(22 199 154 / 0.42), transparent 66%);
  animation-duration: 32s;
  animation-direction: reverse;
}
.orb--c {
  width: clamp(200px, 22vw, 380px);
  aspect-ratio: 1;
  top: 32%;
  left: 38%;
  background: radial-gradient(circle, rgb(0 91 172 / 0.34), transparent 68%);
  animation-duration: 38s;
}
:root[data-theme='dark'] .orb { opacity: 0.4; }

/* --- Fine grid veil --- */
.grid-veil {
  position: absolute;
  inset: 0;
  pointer-events: none;
  background-image:
    linear-gradient(to right, color-mix(in srgb, var(--text) 5%, transparent) 1px, transparent 1px),
    linear-gradient(to bottom, color-mix(in srgb, var(--text) 5%, transparent) 1px, transparent 1px);
  background-size: 64px 64px;
  mask-image: radial-gradient(ellipse 78% 62% at 50% 42%, #000 20%, transparent 78%);
  -webkit-mask-image: radial-gradient(ellipse 78% 62% at 50% 42%, #000 20%, transparent 78%);
  opacity: 0.7;
}

/* --- Dot matrix --- */
.dot-veil {
  position: absolute;
  inset: 0;
  pointer-events: none;
  background-image: radial-gradient(color-mix(in srgb, var(--text) 12%, transparent) 1px, transparent 1px);
  background-size: 26px 26px;
  mask-image: radial-gradient(ellipse 70% 60% at 50% 50%, #000 10%, transparent 76%);
  -webkit-mask-image: radial-gradient(ellipse 70% 60% at 50% 50%, #000 10%, transparent 76%);
  opacity: 0.5;
}

/* --- Noise grain for depth on dark panels --- */
.grain::after {
  content: '';
  position: absolute;
  inset: 0;
  pointer-events: none;
  opacity: 0.035;
  mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* --- Particle canvas --- */
.particles {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  opacity: 0.85;
}

/* ==========================================================================
   4. FLOATING PHARMACEUTICAL ELEMENTS (hero)
   ========================================================================== */
.floaties {
  position: absolute;
  inset: 0;
  pointer-events: none;
  overflow: hidden;
}
.floatie {
  position: absolute;
  display: grid;
  place-items: center;
  color: var(--brand);
  opacity: 0.9;
  animation: float-alt var(--dur, 13s) var(--ease-in-out) infinite;
  animation-delay: var(--delay, 0s);
  will-change: transform;
}
.floatie--glass {
  width: 56px; height: 56px;
  border-radius: 18px;
  background: var(--glass);
  border: 1px solid var(--glass-line);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  box-shadow: var(--shadow-md);
}
.floatie .ico { width: 24px; height: 24px; }

/* Capsule shapes */
.capsule {
  position: absolute;
  width: var(--w, 68px);
  height: var(--h, 27px);
  border-radius: var(--r-pill);
  overflow: hidden;
  transform: rotate(var(--rot, -18deg));
  box-shadow: 0 14px 30px -10px rgb(0 91 172 / 0.42);
  animation: capsule-bob var(--dur, 8s) var(--ease-in-out) infinite;
  animation-delay: var(--delay, 0s);
  will-change: transform;
  border: 1px solid rgb(255 255 255 / 0.35);
}
.capsule::before,
.capsule::after {
  content: '';
  position: absolute;
  top: 0; bottom: 0;
  width: 50%;
}
.capsule::before { left: 0;  background: linear-gradient(150deg, #FFFFFF, #DCEEFC); }
.capsule::after  { right: 0; background: var(--grad-brand); }
.capsule--accent::after { background: var(--grad-accent); }
.capsule--soft::before { background: linear-gradient(150deg, #FFFFFF, #E4FBF3); }

/* Tablet / pill discs */
.tablet {
  position: absolute;
  width: var(--size, 46px);
  aspect-ratio: 1;
  border-radius: 50%;
  background: linear-gradient(145deg, #FFFFFF 0%, #E8F3FC 55%, #CFE6F7 100%);
  border: 1px solid rgb(255 255 255 / 0.7);
  box-shadow: 0 14px 28px -10px rgb(0 91 172 / 0.35), inset 0 -3px 8px rgb(0 91 172 / 0.09);
  animation: float-soft var(--dur, 10s) var(--ease-in-out) infinite;
  animation-delay: var(--delay, 0s);
  will-change: transform;
}
.tablet::after {
  content: '';
  position: absolute;
  top: 50%; left: 22%; right: 22%;
  height: 1.5px;
  border-radius: 2px;
  background: rgb(0 91 172 / 0.22);
  transform: translateY(-50%);
}
:root[data-theme='dark'] .tablet {
  background: linear-gradient(145deg, #17293C 0%, #0F2033 60%, #0A1826 100%);
  border-color: rgb(255 255 255 / 0.1);
}
:root[data-theme='dark'] .capsule::before { background: linear-gradient(150deg, #22384F, #16283A); }

/* Concentric pulse rings */
.pulse-ring {
  position: absolute;
  border-radius: 50%;
  border: 1px solid color-mix(in srgb, var(--brand-2) 45%, transparent);
  animation: ring-expand var(--dur, 4.5s) var(--ease-out) infinite;
  animation-delay: var(--delay, 0s);
  pointer-events: none;
}

/* ==========================================================================
   5. DNA HELIX (SVG driven)
   ========================================================================== */
.dna {
  position: absolute;
  pointer-events: none;
  color: var(--brand-2);
  opacity: 0.5;
}
.dna__strand {
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-dasharray: 8 14;
  animation: dash-flow 22s linear infinite;
}
.dna__strand--b { color: var(--accent); animation-duration: 28s; animation-direction: reverse; }
.dna__rung {
  stroke: currentColor;
  stroke-width: 1.5;
  stroke-linecap: round;
  opacity: 0.42;
}
.dna__node { fill: currentColor; }

/* ECG / heartbeat line */
.ecg {
  fill: none;
  stroke: var(--accent);
  stroke-width: 2.2;
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-dasharray: 1400;
  animation: ecg-sweep 5.5s var(--ease-in-out) infinite;
}

/* Molecule ring rotation */
.molecule { animation: spin 46s linear infinite; transform-origin: center; }
.molecule--rev { animation-duration: 62s; animation-direction: reverse; }

/* ==========================================================================
   6. HOVER MICRO-INTERACTIONS
   ========================================================================== */
.hov-lift { transition: transform var(--t-base) var(--ease-out), box-shadow var(--t-base) var(--ease-out); }
.hov-lift:hover { transform: translateY(-6px); box-shadow: var(--shadow-lg); }

.hov-zoom { overflow: hidden; }
.hov-zoom img,
.hov-zoom .media__img {
  transition: transform 900ms var(--ease-out), filter 700ms var(--ease-out);
}
.hov-zoom:hover img,
.hov-zoom:hover .media__img { transform: scale(1.07); }

/* Underline that grows from the left */
.hov-underline {
  position: relative;
  display: inline-block;
}
.hov-underline::after {
  content: '';
  position: absolute;
  left: 0; bottom: -2px;
  width: 100%; height: 1.5px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: right;
  transition: transform var(--t-base) var(--ease-out);
}
.hov-underline:hover::after { transform: scaleX(1); transform-origin: left; }

/* 3D tilt container — JS sets --tilt-x / --tilt-y */
.tilt {
  transform-style: preserve-3d;
  transform: perspective(900px) rotateX(var(--tilt-x, 0deg)) rotateY(var(--tilt-y, 0deg));
  transition: transform 260ms var(--ease-out);
}
.tilt__inner { transform: translateZ(28px); }

/* Shimmer used on skeletons and the stat underline */
.shimmer {
  background: linear-gradient(100deg,
    transparent 20%,
    color-mix(in srgb, var(--brand-2) 26%, transparent) 45%,
    transparent 70%);
  background-size: 220% 100%;
  animation: shimmer 3.4s var(--ease-in-out) infinite;
}

/* Animated gradient fill (used on the CTA band) */
.grad-pan {
  background-size: 220% 220%;
  animation: gradient-pan 14s var(--ease-in-out) infinite;
}

/* ==========================================================================
   7. MARQUEE
   ========================================================================== */
.marquee {
  position: relative;
  overflow: hidden;
  mask-image: linear-gradient(90deg, transparent, #000 9%, #000 91%, transparent);
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 9%, #000 91%, transparent);
}
.marquee__track {
  display: flex;
  width: max-content;
  gap: var(--sp-12);
  animation: marquee-x var(--speed, 42s) linear infinite;
  will-change: transform;
}
.marquee:hover .marquee__track { animation-play-state: paused; }
.marquee--reverse .marquee__track { animation-direction: reverse; }

/* ==========================================================================
   8. PARALLAX
   JS writes --py (px) on [data-parallax]; CSS applies it on the compositor.
   ========================================================================== */
[data-parallax] {
  transform: translate3d(0, var(--py, 0px), 0);
  will-change: transform;
}
[data-parallax-scale] {
  transform: translate3d(0, var(--py, 0px), 0) scale(var(--ps, 1));
}

/* ==========================================================================
   9. COUNTERS
   ========================================================================== */
.counter {
  font-family: var(--font-display);
  font-size: var(--fs-stat);
  font-weight: 700;
  line-height: 1;
  letter-spacing: var(--ls-tight);
  font-variant-numeric: tabular-nums;
  background: var(--grad-text);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  -webkit-text-fill-color: transparent;
}
.counter--light {
  background: linear-gradient(100deg, #FFFFFF 0%, #A8E1F8 55%, #7CE3C6 100%);
  -webkit-background-clip: text;
  background-clip: text;
}

/* ==========================================================================
   10. REDUCED MOTION
   Decorative motion is switched off entirely; reveals resolve to visible.
   ========================================================================== */
@media (prefers-reduced-motion: reduce) {
  .js [data-reveal],
  .js [data-reveal-group] > * {
    opacity: 1 !important;
    transform: none !important;
    filter: none !important;
    clip-path: none !important;
  }
  .word > span { transform: none !important; }
  .orb, .floatie, .capsule, .tablet, .pulse-ring,
  .dna__strand, .ecg, .molecule, .marquee__track,
  .footer__aurora, .topbar__pulse, .shimmer, .grad-pan {
    animation: none !important;
  }
  .preloader__ring { animation: spin 1.4s linear infinite !important; }
  [data-parallax], [data-parallax-scale] { transform: none !important; }
}
