/*
 * The guided-step treatment, in one place (owner redline, 22 Sep 2026).
 *
 * WHY THIS FILE EXISTS. The student Today card is built by Vite and the parent
 * "Today's next step" card is rendered by PHP. They are different toolchains
 * on different pages, so the only way they can wear the same treatment is to
 * load the same bytes. This file is enqueued by both; neither one owns a copy.
 * Duplicating the keyframes into family-plan.css would work on the day it was
 * written and drift by the second change.
 *
 * THE TREATMENT: a pulsing spotlight border on the card, a bouncing "STEP n"
 * callout with a live beacon dot, radar rings behind the button, and shimmer,
 * heartbeat and sliding-arrow effects on the button itself.
 *
 * MOTION IS OPT-OUT, NOT DECORATION. Seven separate loops run here for as long
 * as the card is on screen. For a vestibular disorder that is not a flourish,
 * it is a reason to close the page — and for anyone reading with a screen
 * reader the callout must be announced once, by the card's own accessible
 * name, not a second time as loose text. Both are handled at the bottom of
 * this file, and `tests/php-journey-motion.test.php` asserts that every
 * `infinite` declared above the guard is answered by it.
 */

/* ── The card ─────────────────────────────────────────── */
.pg-today-first-step {
  border: 2.5px solid #2563eb !important;
  animation: pg-card-spotlight 3s infinite ease-in-out !important;
}
@keyframes pg-card-spotlight {
  0%, 100% {
    border-color: #2563eb;
    box-shadow: 0 0 0 4px rgba(37, 99, 235, 0.16), var(--pg-shadow-lift, 0 2px 4px rgba(15, 26, 52, .06), 0 18px 44px -16px rgba(21, 42, 92, .25));
  }
  50% {
    border-color: #3b82f6;
    box-shadow: 0 0 0 8px rgba(37, 99, 235, 0.28), 0 0 24px rgba(37, 99, 235, 0.22), var(--pg-shadow-lift, 0 2px 4px rgba(15, 26, 52, .06), 0 18px 44px -16px rgba(21, 42, 92, .25));
  }
}

/* ── The callout ──────────────────────────────────────── */
.pg-next-action-cta-wrap {
  display: flex;
  flex-direction: column;
  align-items: center;
  position: relative;
  flex-shrink: 0;
}
@media (max-width: 640px) {
  .pg-next-action-cta-wrap {
    align-items: flex-start;
    width: 100%;
  }
}
.pg-floating-callout {
  display: flex;
  flex-direction: column;
  align-items: center;
  margin-bottom: 8px;
  animation: pg-bounce-down 1.2s infinite ease-in-out;
  filter: drop-shadow(0 6px 14px rgba(37, 99, 235, 0.4));
  z-index: 2;
}
.pg-callout-inner {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  background: linear-gradient(135deg, #1e3a8a 0%, #1d4ed8 50%, #2563eb 100%);
  border: 1.5px solid #93c5fd;
  color: #ffffff;
  font-size: 13.5px;
  font-weight: 800;
  letter-spacing: 0.04em;
  padding: 7px 16px;
  border-radius: 999px;
  white-space: nowrap;
}
.pg-live-beacon-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: #22c55e;
  box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.8), 0 0 8px #22c55e;
  animation: pg-beacon-glow 1.2s infinite ease-in-out;
}
@keyframes pg-beacon-glow {
  0%, 100% {
    transform: scale(1);
    opacity: 1;
  }
  50% {
    transform: scale(1.4);
    opacity: 0.6;
  }
}
.pg-callout-spark {
  font-size: 14px;
  color: #fde047;
}
.pg-callout-text {
  font-family: 'Outfit', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
}
.pg-callout-arrow {
  display: block;
  margin-top: -1px;
  color: #2563eb;
  line-height: 0;
}
@keyframes pg-bounce-down {
  0%, 100% {
    transform: translateY(0);
  }
  50% {
    transform: translateY(-6px);
  }
}

/* ── Radar ping waves behind the CTA ──────────────────── */
.pg-radar-wrap {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.pg-radar-ring {
  position: absolute;
  inset: -6px;
  border-radius: 16px;
  pointer-events: none;
  border: 2px solid rgba(37, 99, 235, 0.6);
  animation: pg-radar-ping 2s cubic-bezier(0, 0, 0.2, 1) infinite;
}
.pg-radar-ring-2 {
  animation-delay: 0.75s;
}
@keyframes pg-radar-ping {
  0% {
    transform: scale(0.96);
    opacity: 0.9;
  }
  100% {
    transform: scale(1.35);
    opacity: 0;
  }
}

/* ── Shimmer beam and heartbeat pulse ─────────────────── */
.pg-shimmer-btn {
  position: relative;
  overflow: hidden;
  animation: pg-heartbeat 2.4s ease-in-out infinite !important;
}
.pg-shimmer-btn::after {
  content: '';
  position: absolute;
  top: -50%;
  left: -75%;
  width: 50%;
  height: 200%;
  background: linear-gradient(
    90deg,
    rgba(255, 255, 255, 0) 0%,
    rgba(255, 255, 255, 0.45) 50%,
    rgba(255, 255, 255, 0) 100%
  );
  transform: rotate(28deg);
  animation: pg-button-shimmer 2.5s infinite cubic-bezier(0.4, 0, 0.2, 1);
  pointer-events: none;
}
@keyframes pg-button-shimmer {
  0% {
    left: -75%;
  }
  50%, 100% {
    left: 140%;
  }
}
@keyframes pg-heartbeat {
  0%, 100% {
    transform: scale(1);
    box-shadow: 0 8px 20px -8px rgba(45, 126, 245, 0.55);
  }
  30% {
    transform: scale(1.045);
    box-shadow: 0 12px 28px -6px rgba(45, 126, 245, 0.75);
  }
  50% {
    transform: scale(1.015);
  }
  70% {
    transform: scale(1.04);
    box-shadow: 0 12px 28px -6px rgba(45, 126, 245, 0.75);
  }
}

/* ── Sliding arrow inside the button ──────────────────── */
@keyframes pg-arrow-slide {
  0%, 100% {
    transform: translateX(0);
  }
  50% {
    transform: translateX(5px);
  }
}
.pg-sliding-arrow {
  animation: pg-arrow-slide 1.2s infinite ease-in-out;
  display: inline-flex;
}

/* ── The parent card ──────────────────────────────────── */
/*
 * The parent page is server-rendered with its own `pgf-` names, so the step
 * classes are added to its existing markup rather than replacing it. Only the
 * positioning differs; every animation above is shared unchanged, which is the
 * whole point of this file.
 */
.pgf-today.pg-today-first-step {
  position: relative;
}
.pgf-today .pg-next-action-cta-wrap {
  align-items: flex-start;
}
.pgf-today .pg-floating-callout {
  align-items: flex-start;
  margin-bottom: 10px;
}

/* ── Reduced motion ───────────────────────────────────── */
/*
 * EVERY loop above is answered here. The card keeps its highlighted border and
 * the callout keeps its words and its place — a reader who cannot take motion
 * still needs to know which card is the next step, so this removes the
 * movement and none of the meaning. Written as explicit per-selector rules
 * rather than a blanket `* { animation: none }` so that a new loop added above
 * FAILS the motion test instead of being silently covered.
 */
@media (prefers-reduced-motion: reduce) {
  .pg-today-first-step {
    animation: none !important;
    /* The 50% keyframe, held still: the emphasis without the pulse. */
    box-shadow: 0 0 0 6px rgba(37, 99, 235, 0.22), var(--pg-shadow-lift, 0 2px 4px rgba(15, 26, 52, .06), 0 18px 44px -16px rgba(21, 42, 92, .25)) !important;
  }
  .pg-floating-callout {
    animation: none !important;
  }
  .pg-live-beacon-dot {
    animation: none !important;
  }
  .pg-radar-ring,
  .pg-radar-ring-2 {
    animation: none !important;
    /* Rings exist only to move; held still they are three stacked borders. */
    display: none !important;
  }
  .pg-shimmer-btn {
    animation: none !important;
  }
  .pg-shimmer-btn::after {
    animation: none !important;
    display: none !important;
  }
  .pg-sliding-arrow {
    animation: none !important;
  }
}
