[wave] {
  box-sizing: border-box;
  display: inline-block;
  position: relative;
  overflow: hidden;
  vertical-align: middle;
}

/* Simplified timings:
   - Two timing variables remain:
     --ripple-duration: transform/expansion duration
     --ripple-fade-duration: opacity fade duration
   - Blur removed; contain usage reduced to avoid layer/paint glitches.
*/

:root{
  --ripple-duration: 2500ms;
  --ripple-fade-duration: 800ms;

  /* gentle ease for expansion */
  --ripple-easing: cubic-bezier(0.12, 0.75, 0.24, 1);

  /* sheen tuning */
  --ripple-sheen-opacity: 0.82;
}

/* Respect user's reduced motion preference */
@media (prefers-reduced-motion: reduce) {
  :root {
    --ripple-fade-duration: 120ms;
    --ripple-duration: 220ms;
  }
}

.ripple {
  pointer-events: none;
  position: absolute;
  border-radius: 50%;
  width: 18px;
  height: 18px;
  background-color: currentColor;

  /* No filter/blur used */
  filter: none;

  /* Lighter shadow to reduce paint cost (static, NOT transitioned) */
  box-shadow: 0 4px 12px rgba(8, 12, 20, 0.04);

  opacity: 1;
  transform: scale(1) translate3d(0,0,0);
  transform-origin: 50% 50%;

  /* Only animate compositor-friendly properties */
  transition:
    transform var(--ripple-duration) var(--ripple-easing),
    opacity var(--ripple-fade-duration) cubic-bezier(0.4, 0, 0.2, 1);

  /* keep will-change stable via CSS so the compositor can prepare layers */
  will-change: transform, opacity;
  -webkit-backface-visibility: hidden;
  backface-visibility: hidden;
  -webkit-tap-highlight-color: transparent;
  /* push to its own layer aggressively */
  transform: translate3d(0,0,0) scale(1);
}

/* Subtle sheen */
.ripple::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 50%;
  pointer-events: none;
  background: radial-gradient(circle at 40% 35%, rgba(255,255,255,0.08) 0%, rgba(255,255,255,0.02) 28%, transparent 58%);
  opacity: var(--ripple-sheen-opacity, 0.82);
  transform: scale(1);
  transition:
    transform var(--ripple-duration) var(--ripple-easing),
    opacity var(--ripple-fade-duration) cubic-bezier(0.4, 0, 0.2, 1);
  will-change: transform, opacity;
}

.ripple.animating,
.ripple.fading {
  /* keep will-change static (handled by base .ripple), avoid changing box-shadow here */
}

/* Animating uses transform-only updates (compositor) */
.ripple.animating {
  transform: scale(var(--ripple-final-scale, 1)) translate3d(0,0,0);
  filter: none;
}
.ripple.animating::before {
  transform: scale(calc(var(--ripple-final-scale, 1) * 1.04));
  opacity: 1;
}

.ripple.fading {
  opacity: 0;
  filter: none;
}
.ripple.fading::before {
  opacity: 0;
}

.ripple, .ripple::before { box-sizing: border-box; }

/* Performance-specific tuning (shadow/pool only) */
:root.wave-low-performance {
  --ripple-sheen-opacity: 0.6;
  --ripple-shadow: 0 3px 8px rgba(8,12,20,0.03);
}

:root.wave-medium-performance {
  --ripple-sheen-opacity: 0.72;
}

:root.wave-high-performance {
  --ripple-sheen-opacity: 0.86;
}

.wave-low-performance .ripple.animating,
.wave-low-performance .ripple.fading {
  box-shadow: 0 3px 8px rgba(8,12,20,0.03);
}
