/* The hero ripple — DESIGN.md §4, at marketing scale.
   Everything here is additive: with JavaScript off, none of it is created and
   the hero renders as plain Paper. */

.hero {
  position: relative;
  /* Once the wave has passed, the hero *is* the payload: it keeps the theme it
     was handed, which is the whole point of the demonstration. */
  background: var(--bg);
  color: var(--text);
}

/* The payload layer: the same hero, wearing another theme, revealed by a
   clip-path circle welded to the wavefront. Buttons stay buttons — the clipped
   region takes the pointer, the base hero keeps it everywhere else. */
.ripple-payload {
  position: absolute;
  inset: 0;
  z-index: 3;
  background: var(--bg);
  color: var(--text);
  clip-path: circle(0px at var(--impact-x) var(--impact-y));
  overflow: hidden;
}

.ripple-payload.running {
  animation: ripple-reveal var(--dur-wavefront) var(--ease-wavefront) forwards;
}

@keyframes ripple-reveal {
  from { clip-path: circle(0px at var(--impact-x) var(--impact-y)); }
  to   { clip-path: circle(var(--reach) at var(--impact-x) var(--impact-y)); }
}

/* The payload's own hero copy is laid out exactly like the base, so the two
   register pixel for pixel as the wave crosses. */
.ripple-payload > .hero-inner {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 120px 24px 80px;
}

/* ── 1. Fall — gravity, so ease-in only ─────────────────────────────────── */
.ripple-drop {
  position: absolute;
  z-index: 5;
  width: 14px;
  height: 14px;
  margin: -7px 0 0 -7px;
  border-radius: 50% 50% 50% 50% / 60% 60% 40% 40%;
  background: var(--drop-color, var(--accent));
  pointer-events: none;
  animation: ripple-fall var(--dur-fall) var(--ease-fall) forwards;
}

@keyframes ripple-fall {
  from { transform: translateY(var(--fall-from)) scaleY(1.35); opacity: 1; }
  92%  { transform: translateY(0) scaleY(1); opacity: 1; }
  to   { transform: translateY(0) scaleY(.6); opacity: 0; }
}

/* ── 2. Impact — a handful of particles, gone in 480ms ──────────────────── */
.ripple-particle {
  position: absolute;
  z-index: 5;
  width: 4px;
  height: 4px;
  margin: -2px 0 0 -2px;
  border-radius: 50%;
  background: var(--drop-color, var(--accent));
  pointer-events: none;
  animation: ripple-particle 480ms var(--ease-water) forwards;
}

@keyframes ripple-particle {
  from { transform: translate(0, 0) scale(1); opacity: .9; }
  to   { transform: translate(var(--px), var(--py)) scale(.2); opacity: 0; }
}

/* ── 3. Wavefront — constant speed, welded to the reveal ────────────────── */
.ripple-wavefront {
  position: absolute;
  z-index: 4;
  width: 2px;
  height: 2px;
  margin: -1px 0 0 -1px;
  border-radius: 50%;
  pointer-events: none;
  box-shadow:
    0 0 0 1px var(--drop-color, var(--accent)),
    0 0 26px 8px color-mix(in srgb, var(--drop-color, var(--accent)) 26%, transparent);
  animation: ripple-wavefront var(--dur-wavefront) var(--ease-wavefront) forwards;
}

@keyframes ripple-wavefront {
  from { transform: scale(1); opacity: .9; }
  to   { transform: scale(var(--reach)); opacity: 0; }
}

/* ── 4. Settle — elements arrive with the wave ──────────────────────────── */
.ripple-settle {
  animation: ripple-settle var(--dur-settle) var(--ease-settle) both;
}

@keyframes ripple-settle {
  from { opacity: .35; transform: translateY(10px); filter: blur(7px); }
  to   { opacity: 1; transform: translateY(0); filter: blur(0); }
}

/* ── The invitation, then the theme's name ──────────────────────────────── */
.hero > .ripple-caption { z-index: 2; }

/* The hero is clickable water, so say so with the cursor. Interactive things
   inside it keep their own cursor — they are not water. */
.hero.ripple-ready { cursor: pointer; }
.hero.ripple-ready a,
.hero.ripple-ready button,
.hero.ripple-ready input,
.hero.ripple-ready select,
.hero.ripple-ready textarea { cursor: revert; }

.ripple-caption {
  position: absolute;
  left: 50%;
  bottom: 28px;
  transform: translateX(-50%);
  z-index: 6;
  font-family: var(--font-mono);
  font-size: 11.5px;
  text-transform: uppercase;
  letter-spacing: .14em;
  color: var(--muted);
  pointer-events: none;
  animation: ripple-settle var(--dur-settle) var(--ease-settle) both;
}

/* ── Reduced motion: a 240ms crossfade, nothing else ─────────────────────── */
@media (prefers-reduced-motion: reduce) {
  .ripple-drop,
  .ripple-particle,
  .ripple-wavefront { display: none; }

  .ripple-payload.running {
    animation: none;
    clip-path: none;
    opacity: 0;
    animation: ripple-crossfade 240ms ease forwards;
  }

  @keyframes ripple-crossfade {
    from { opacity: 0; }
    to   { opacity: 1; }
  }

  .ripple-settle,
  .ripple-caption { animation: ripple-crossfade 240ms ease both; }
}
