/* =============================================
   40 Metric Card Animation Variants
   Each test picks one random variant for all cards.
   JS adds .anim-N class alongside .revealed
   ============================================= */

/* === Base: pseudo-element reset for all variants === */
.metric-card::before,
.metric-card::after {
  content: "";
  position: absolute;
  pointer-events: none;
}

.metric-card::before {
  inset: 0;
  z-index: 0;
}

.metric-card::after {
  top: 0; left: 0;
  width: 100%; height: 100%;
  z-index: 1;
}

/* Rating colors */
.metric-card[data-rating="good"] { --metric-fill: var(--green); }
.metric-card[data-rating="needs-improvement"] { --metric-fill: var(--yellow); }
.metric-card[data-rating="poor"] { --metric-fill: var(--red); }

/* Text above overlays */
.metric-label,
.metric-value,
.metric-detail {
  position: relative;
  z-index: 2;
}

/* ========== 1. Fill Up ========== */
.anim-1 .metric-card::before,
.anim-1.metric-card::before {
  background: linear-gradient(to top, var(--metric-fill, var(--accent)), transparent);
  opacity: 0;
  transform: translateY(100%);
}
.anim-1 .metric-card.revealed::before,
.anim-1.metric-card.revealed::before {
  animation: a1-fill 0.5s ease-out forwards;
}
.anim-1 .metric-card::after,
.anim-1.metric-card::after {
  left: -100%;
  width: 60%;
  background: linear-gradient(105deg, transparent 30%, rgba(255,255,255,0.10) 45%, rgba(255,255,255,0.22) 50%, rgba(255,255,255,0.10) 55%, transparent 70%);
}
.anim-1 .metric-card.revealed::after,
.anim-1.metric-card.revealed::after {
  animation: a1-shine 0.7s 0.2s ease-out forwards;
}
@keyframes a1-fill {
  0% { transform: translateY(100%); opacity: 0.35; }
  100% { transform: translateY(0); opacity: 0.15; }
}
@keyframes a1-shine {
  0% { left: -100%; }
  100% { left: 200%; }
}

/* ========== 2. Fill Down ========== */
.anim-2.metric-card::before {
  background: linear-gradient(to bottom, var(--metric-fill, var(--accent)), transparent);
  opacity: 0;
  transform: translateY(-100%);
}
.anim-2.metric-card.revealed::before {
  animation: a2-fill 0.5s ease-out forwards;
}
@keyframes a2-fill {
  0% { transform: translateY(-100%); opacity: 0.35; }
  100% { transform: translateY(0); opacity: 0.15; }
}

/* ========== 3. Fill Left ========== */
.anim-3.metric-card::before {
  background: linear-gradient(to right, var(--metric-fill, var(--accent)), transparent);
  opacity: 0;
  transform: translateX(-100%);
}
.anim-3.metric-card.revealed::before {
  animation: a3-fill 0.5s ease-out forwards;
}
@keyframes a3-fill {
  0% { transform: translateX(-100%); opacity: 0.35; }
  100% { transform: translateX(0); opacity: 0.15; }
}

/* ========== 4. Fill Right ========== */
.anim-4.metric-card::before {
  background: linear-gradient(to left, var(--metric-fill, var(--accent)), transparent);
  opacity: 0;
  transform: translateX(100%);
}
.anim-4.metric-card.revealed::before {
  animation: a4-fill 0.5s ease-out forwards;
}
@keyframes a4-fill {
  0% { transform: translateX(100%); opacity: 0.35; }
  100% { transform: translateX(0); opacity: 0.15; }
}

/* ========== 5. Radial Burst ========== */
.anim-5.metric-card::before {
  background: radial-gradient(circle at center, var(--metric-fill, var(--accent)) 0%, transparent 70%);
  opacity: 0;
  transform: scale(0);
}
.anim-5.metric-card.revealed::before {
  animation: a5-burst 0.6s ease-out forwards;
}
@keyframes a5-burst {
  0% { transform: scale(0); opacity: 0.4; }
  100% { transform: scale(1.5); opacity: 0.12; }
}

/* ========== 6. Corner Fill ========== */
.anim-6.metric-card::before {
  background: conic-gradient(from 0deg at 0% 0%, var(--metric-fill, var(--accent)) 0deg, transparent 90deg);
  opacity: 0;
}
.anim-6.metric-card.revealed::before {
  animation: a6-corner 0.6s ease-out forwards;
}
@keyframes a6-corner {
  0% { opacity: 0; }
  50% { opacity: 0.25; }
  100% { opacity: 0.12; }
}

/* ========== 7. Diagonal Wipe ========== */
.anim-7.metric-card::before {
  background: linear-gradient(135deg, transparent 0%, var(--metric-fill, var(--accent)) 45%, var(--metric-fill, var(--accent)) 55%, transparent 100%);
  opacity: 0;
  transform: translateX(-150%) translateY(-150%);
}
.anim-7.metric-card.revealed::before {
  animation: a7-wipe 0.6s ease-out forwards;
}
@keyframes a7-wipe {
  0% { transform: translateX(-150%) translateY(-150%); opacity: 0.3; }
  50% { opacity: 0.25; }
  100% { transform: translateX(150%) translateY(150%); opacity: 0; }
}

/* ========== 8. Gradient Wave ========== */
.anim-8.metric-card::before {
  background: linear-gradient(90deg, transparent 0%, var(--metric-fill, var(--accent)) 30%, var(--metric-fill, var(--accent)) 70%, transparent 100%);
  background-size: 200% 100%;
  background-position: -100% 0;
  opacity: 0;
}
.anim-8.metric-card.revealed::before {
  animation: a8-wave 0.8s ease-in-out forwards;
}
@keyframes a8-wave {
  0% { background-position: -100% 0; opacity: 0.25; }
  100% { background-position: 200% 0; opacity: 0.1; }
}

/* ========== 9. Double Sweep ========== */
.anim-9.metric-card::before {
  background: linear-gradient(90deg, var(--metric-fill, var(--accent)) 0%, transparent 50%);
  opacity: 0;
  transform: translateX(-100%);
}
.anim-9.metric-card::after {
  background: linear-gradient(270deg, var(--metric-fill, var(--accent)) 0%, transparent 50%);
  opacity: 0;
  transform: translateX(100%);
}
.anim-9.metric-card.revealed::before {
  animation: a9-left 0.5s ease-out forwards;
}
.anim-9.metric-card.revealed::after {
  animation: a9-right 0.5s ease-out forwards;
}
@keyframes a9-left {
  0% { transform: translateX(-100%); opacity: 0.3; }
  100% { transform: translateX(0); opacity: 0.12; }
}
@keyframes a9-right {
  0% { transform: translateX(100%); opacity: 0.3; }
  100% { transform: translateX(0); opacity: 0.12; }
}

/* ========== 10. Border Trace CW ========== */
.anim-10.metric-card.revealed {
  animation: a10-trace 0.8s ease-out forwards;
}
@keyframes a10-trace {
  0% { box-shadow: inset 2px 0 0 0 var(--metric-fill, var(--accent)); }
  25% { box-shadow: inset 0 2px 0 0 var(--metric-fill, var(--accent)), inset 2px 0 0 0 var(--metric-fill, var(--accent)); }
  50% { box-shadow: inset -2px 0 0 0 var(--metric-fill, var(--accent)), inset 0 2px 0 0 var(--metric-fill, var(--accent)), inset 2px 0 0 0 var(--metric-fill, var(--accent)); }
  75% { box-shadow: inset 0 -2px 0 0 var(--metric-fill, var(--accent)), inset -2px 0 0 0 var(--metric-fill, var(--accent)), inset 0 2px 0 0 var(--metric-fill, var(--accent)), inset 2px 0 0 0 var(--metric-fill, var(--accent)); }
  100% { box-shadow: inset 0 0 0 2px var(--metric-fill, var(--accent)); opacity: 0.5; }
}

/* ========== 11. Border Trace CCW ========== */
.anim-11.metric-card.revealed {
  animation: a11-trace 0.8s ease-out forwards;
}
@keyframes a11-trace {
  0% { box-shadow: inset -2px 0 0 0 var(--metric-fill, var(--accent)); }
  25% { box-shadow: inset 0 2px 0 0 var(--metric-fill, var(--accent)), inset -2px 0 0 0 var(--metric-fill, var(--accent)); }
  50% { box-shadow: inset 2px 0 0 0 var(--metric-fill, var(--accent)), inset 0 2px 0 0 var(--metric-fill, var(--accent)), inset -2px 0 0 0 var(--metric-fill, var(--accent)); }
  75% { box-shadow: inset 0 -2px 0 0 var(--metric-fill, var(--accent)), inset 2px 0 0 0 var(--metric-fill, var(--accent)), inset 0 2px 0 0 var(--metric-fill, var(--accent)), inset -2px 0 0 0 var(--metric-fill, var(--accent)); }
  100% { box-shadow: inset 0 0 0 2px var(--metric-fill, var(--accent)); opacity: 0.5; }
}

/* ========== 12. Border Pulse ========== */
.anim-12.metric-card.revealed {
  animation: a12-pulse 1s ease-out forwards;
}
@keyframes a12-pulse {
  0% { box-shadow: inset 0 0 0 0 var(--metric-fill, var(--accent)); }
  20% { box-shadow: inset 0 0 0 3px var(--metric-fill, var(--accent)); }
  40% { box-shadow: inset 0 0 0 1px var(--metric-fill, var(--accent)); }
  60% { box-shadow: inset 0 0 0 3px var(--metric-fill, var(--accent)); }
  80% { box-shadow: inset 0 0 0 1px var(--metric-fill, var(--accent)); }
  100% { box-shadow: inset 0 0 0 0 transparent; }
}

/* ========== 13. Neon Glow ========== */
.anim-13.metric-card.revealed {
  animation: a13-glow 0.8s ease-out forwards;
}
@keyframes a13-glow {
  0% { box-shadow: 0 0 0 0 transparent; }
  30% { box-shadow: 0 0 20px 4px var(--metric-fill, var(--accent)); }
  100% { box-shadow: 0 0 0 0 transparent; }
}

/* ========== 14. Corner Brackets ========== */
.anim-14.metric-card::before {
  inset: 4px;
  border: 2px solid var(--metric-fill, var(--accent));
  background: none;
  clip-path: polygon(0 0, 20% 0, 20% 2px, 2px 2px, 2px 20%, 0 20%, 0 80%, 2px 80%, 2px 98%, 20% 98%, 20% 100%, 0 100%, 100% 100%, 80% 100%, 80% 98%, 98% 98%, 98% 80%, 100% 80%, 100% 20%, 98% 20%, 98% 2px, 80% 2px, 80% 0, 100% 0);
  opacity: 0;
}
.anim-14.metric-card.revealed::before {
  animation: a14-brackets 0.6s ease-out forwards;
}
@keyframes a14-brackets {
  0% { opacity: 0; transform: scale(0.9); }
  50% { opacity: 0.6; }
  100% { opacity: 0.3; transform: scale(1); }
}

/* ========== 15. Scale Pop ========== */
.anim-15.metric-card.revealed {
  animation: a15-pop 0.4s cubic-bezier(0.175, 0.885, 0.32, 1.275) forwards;
}
@keyframes a15-pop {
  0% { transform: scale(0.95); }
  60% { transform: scale(1.03); }
  100% { transform: scale(1); }
}

/* ========== 16. Scale Up ========== */
.anim-16.metric-card.revealed {
  animation: a16-scaleup 0.5s ease-out forwards;
}
@keyframes a16-scaleup {
  0% { transform: scale(0.9); opacity: 0.5; }
  100% { transform: scale(1); opacity: 1; }
}

/* ========== 17. Rotate Flip Y ========== */
.anim-17.metric-card.revealed {
  animation: a17-flipy 0.5s ease-out forwards;
}
@keyframes a17-flipy {
  0% { transform: perspective(600px) rotateY(8deg); }
  100% { transform: perspective(600px) rotateY(0deg); }
}

/* ========== 18. Rotate Flip X ========== */
.anim-18.metric-card.revealed {
  animation: a18-flipx 0.5s ease-out forwards;
}
@keyframes a18-flipx {
  0% { transform: perspective(600px) rotateX(8deg); }
  100% { transform: perspective(600px) rotateX(0deg); }
}

/* ========== 19. Tilt Wobble ========== */
.anim-19.metric-card.revealed {
  animation: a19-wobble 0.6s ease-out forwards;
}
@keyframes a19-wobble {
  0% { transform: rotate(0deg); }
  20% { transform: rotate(-2deg); }
  40% { transform: rotate(2deg); }
  60% { transform: rotate(-1deg); }
  80% { transform: rotate(1deg); }
  100% { transform: rotate(0deg); }
}

/* ========== 20. Bounce In ========== */
.anim-20.metric-card.revealed {
  animation: a20-bounce 0.5s cubic-bezier(0.175, 0.885, 0.32, 1.275) forwards;
}
@keyframes a20-bounce {
  0% { transform: scale(0.8); opacity: 0.5; }
  70% { transform: scale(1.05); opacity: 1; }
  100% { transform: scale(1); }
}

/* ========== 21. Drop Shadow Pop ========== */
.anim-21.metric-card.revealed {
  animation: a21-shadow 0.6s ease-out forwards;
}
@keyframes a21-shadow {
  0% { box-shadow: 0 2px 4px rgba(0,0,0,0.1); }
  40% { box-shadow: 0 12px 32px rgba(0,0,0,0.25); }
  100% { box-shadow: 0 2px 8px rgba(0,0,0,0.1); }
}

/* ========== 22. Inner Glow ========== */
.anim-22.metric-card.revealed {
  animation: a22-inner 0.7s ease-out forwards;
}
@keyframes a22-inner {
  0% { box-shadow: inset 0 0 0 0 transparent; }
  40% { box-shadow: inset 0 0 30px 5px var(--metric-fill, var(--accent)); }
  100% { box-shadow: inset 0 0 0 0 transparent; }
}

/* ========== 23. Spotlight ========== */
.anim-23.metric-card::before {
  background: radial-gradient(circle 60px at var(--spot-x, -60px) 50%, rgba(255,255,255,0.25), transparent);
  opacity: 0;
}
.anim-23.metric-card.revealed::before {
  animation: a23-spot 0.8s ease-in-out forwards;
}
@keyframes a23-spot {
  0% { --spot-x: -60px; opacity: 1; }
  100% { --spot-x: calc(100% + 60px); opacity: 0; }
}
/* Fallback for browsers without @property */
.anim-23.metric-card::before {
  background: radial-gradient(circle 60px at 50% 50%, rgba(255,255,255,0.2), transparent);
}
.anim-23.metric-card.revealed::before {
  animation: a23-spot-fb 0.8s ease-in-out forwards;
}
@keyframes a23-spot-fb {
  0% { opacity: 0; transform: translateX(-100%); }
  50% { opacity: 0.3; }
  100% { opacity: 0; transform: translateX(100%); }
}

/* ========== 24. Lens Flare ========== */
.anim-24.metric-card::after {
  width: 30px;
  height: 30px;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(255,255,255,0.8), rgba(255,255,255,0.3) 40%, transparent 70%);
  top: 50%;
  left: -30px;
  opacity: 0;
}
.anim-24.metric-card.revealed::after {
  animation: a24-flare 0.6s ease-in-out forwards;
}
@keyframes a24-flare {
  0% { left: -30px; top: 80%; opacity: 0; }
  30% { opacity: 0.9; }
  100% { left: calc(100% + 30px); top: 20%; opacity: 0; }
}

/* ========== 25. Shimmer ========== */
.anim-25.metric-card::before {
  background: linear-gradient(110deg, transparent 20%, rgba(255,255,255,0.08) 35%, rgba(255,255,255,0.18) 50%, rgba(255,255,255,0.08) 65%, transparent 80%);
  background-size: 200% 100%;
  opacity: 0;
}
.anim-25.metric-card.revealed::before {
  animation: a25-shimmer 1.2s ease-in-out forwards;
}
@keyframes a25-shimmer {
  0% { background-position: 200% 0; opacity: 1; }
  50% { opacity: 1; }
  100% { background-position: -200% 0; opacity: 0; }
}

/* ========== 26. Fade In Up ========== */
.anim-26.metric-card.revealed {
  animation: a26-fadeup 0.4s ease-out forwards;
}
@keyframes a26-fadeup {
  0% { transform: translateY(8px); opacity: 0.3; }
  100% { transform: translateY(0); opacity: 1; }
}

/* ========== 27. Fade In Down ========== */
.anim-27.metric-card.revealed {
  animation: a27-fadedown 0.4s ease-out forwards;
}
@keyframes a27-fadedown {
  0% { transform: translateY(-8px); opacity: 0.3; }
  100% { transform: translateY(0); opacity: 1; }
}

/* ========== 28. Fade In Scale ========== */
.anim-28.metric-card.revealed {
  animation: a28-fadescale 0.4s ease-out forwards;
}
@keyframes a28-fadescale {
  0% { transform: scale(0.92); opacity: 0.3; }
  100% { transform: scale(1); opacity: 1; }
}

/* ========== 29. Typewriter Reveal ========== */
.anim-29.metric-card::before {
  background: var(--metric-fill, var(--accent));
  opacity: 0.15;
  clip-path: inset(0 100% 0 0);
}
.anim-29.metric-card.revealed::before {
  animation: a29-type 0.6s ease-out forwards;
}
@keyframes a29-type {
  0% { clip-path: inset(0 100% 0 0); }
  100% { clip-path: inset(0 0% 0 0); }
}

/* ========== 30. Iris Open ========== */
.anim-30.metric-card::before {
  background: var(--metric-fill, var(--accent));
  opacity: 0.15;
  clip-path: circle(0% at 50% 50%);
}
.anim-30.metric-card.revealed::before {
  animation: a30-iris 0.6s ease-out forwards;
}
@keyframes a30-iris {
  0% { clip-path: circle(0% at 50% 50%); }
  100% { clip-path: circle(75% at 50% 50%); }
}

/* ========== 31. Venetian Blinds ========== */
.anim-31.metric-card::before {
  background: repeating-linear-gradient(
    180deg,
    var(--metric-fill, var(--accent)) 0px,
    var(--metric-fill, var(--accent)) 4px,
    transparent 4px,
    transparent 12px
  );
  opacity: 0;
  transform: scaleY(0);
  transform-origin: top;
}
.anim-31.metric-card.revealed::before {
  animation: a31-blinds 0.5s ease-out forwards;
}
@keyframes a31-blinds {
  0% { transform: scaleY(0); opacity: 0.25; }
  60% { transform: scaleY(1); opacity: 0.2; }
  100% { transform: scaleY(1); opacity: 0.1; }
}

/* ========== 32. Scan Lines ========== */
.anim-32.metric-card::before {
  background: repeating-linear-gradient(
    180deg,
    var(--metric-fill, var(--accent)) 0px,
    transparent 2px,
    transparent 6px
  );
  opacity: 0;
  transform: translateY(-100%);
}
.anim-32.metric-card.revealed::before {
  animation: a32-scan 0.7s ease-out forwards;
}
@keyframes a32-scan {
  0% { transform: translateY(-100%); opacity: 0.2; }
  70% { transform: translateY(0); opacity: 0.15; }
  100% { transform: translateY(0); opacity: 0.05; }
}

/* ========== 33. Grid Flash ========== */
.anim-33.metric-card::before {
  background-image: radial-gradient(circle 1px, var(--metric-fill, var(--accent)) 1px, transparent 1px);
  background-size: 8px 8px;
  opacity: 0;
}
.anim-33.metric-card.revealed::before {
  animation: a33-grid 0.6s ease-out forwards;
}
@keyframes a33-grid {
  0% { opacity: 0; }
  30% { opacity: 0.25; }
  100% { opacity: 0; }
}

/* ========== 34. Noise Dissolve ========== */
.anim-34.metric-card::before {
  background: var(--metric-fill, var(--accent));
  opacity: 0;
  mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.8' numOctaves='4' /%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' /%3E%3C/svg%3E");
  -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.8' numOctaves='4' /%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' /%3E%3C/svg%3E");
}
.anim-34.metric-card.revealed::before {
  animation: a34-noise 0.8s ease-out forwards;
}
@keyframes a34-noise {
  0% { opacity: 0; }
  40% { opacity: 0.2; }
  100% { opacity: 0.08; }
}

/* ========== 35. Pixelate In ========== */
.anim-35.metric-card::before {
  background: var(--metric-fill, var(--accent));
  opacity: 0;
}
.anim-35.metric-card.revealed::before {
  animation: a35-pixel 0.6s steps(6) forwards;
}
@keyframes a35-pixel {
  0% { opacity: 0; transform: scale(1.5); filter: blur(8px); }
  50% { opacity: 0.2; filter: blur(4px); }
  100% { opacity: 0.12; transform: scale(1); filter: blur(0px); }
}

/* ========== 36. Heartbeat ========== */
.anim-36.metric-card.revealed {
  animation: a36-heart 0.6s ease-out forwards;
}
@keyframes a36-heart {
  0% { transform: scale(1); }
  14% { transform: scale(1.06); }
  28% { transform: scale(1); }
  42% { transform: scale(1.08); }
  56% { transform: scale(1); }
  100% { transform: scale(1); }
}

/* ========== 37. Elastic Slide ========== */
.anim-37.metric-card.revealed {
  animation: a37-elastic 0.7s cubic-bezier(0.68, -0.55, 0.265, 1.55) forwards;
}
@keyframes a37-elastic {
  0% { transform: translateX(-30px); opacity: 0.3; }
  100% { transform: translateX(0); opacity: 1; }
}

/* ========== 38. Stamp ========== */
.anim-38.metric-card.revealed {
  animation: a38-stamp 0.3s ease-out forwards;
}
@keyframes a38-stamp {
  0% { transform: scale(1.15) rotate(-3deg); opacity: 0.3; }
  60% { transform: scale(0.98) rotate(0.5deg); opacity: 1; }
  100% { transform: scale(1) rotate(0deg); }
}

/* ========== 39. Ripple ========== */
.anim-39.metric-card.revealed {
  animation: a39-ripple 0.8s ease-out forwards;
}
@keyframes a39-ripple {
  0% { box-shadow: inset 0 0 0 0 var(--metric-fill, var(--accent)); }
  30% { box-shadow: inset 0 0 0 4px var(--metric-fill, var(--accent)); }
  60% { box-shadow: inset 0 0 0 2px transparent, 0 0 0 4px var(--metric-fill, var(--accent)); }
  100% { box-shadow: inset 0 0 0 0 transparent, 0 0 0 8px transparent; }
}

/* ========== 40. Color Flash ========== */
.anim-40.metric-card::before {
  background: var(--metric-fill, var(--accent));
  opacity: 0;
}
.anim-40.metric-card.revealed::before {
  animation: a40-flash 0.5s ease-out forwards;
}
@keyframes a40-flash {
  0% { opacity: 0; }
  25% { opacity: 0.3; }
  100% { opacity: 0; }
}
