/* ==========================================================================
   Peak Compounding Pharmacy - motion

   Two rules govern everything in this file.

   1. NOTHING REQUIRED IS ANIMATED IN.
      Reveal styles are scoped behind html.js-motion, which main.js adds only
      after confirming the user has not asked for reduced motion. With
      JavaScript disabled, or blocked, or still loading, or failed, every
      element renders at full opacity in its final position. This is not a
      nicety. BRAND_GUIDE section 6 requires the compliance disclosures at full
      opacity and at least 4.5:1 contrast in the hero viewport, and an element
      sitting at opacity:0 waiting for an IntersectionObserver that never fires
      is a disclosure that does not exist. .disclosure is additionally excluded
      by name at the bottom of this file, belt and braces.

   2. THIS IS A PHARMACY, NOT A SHOWREEL.
      Short durations, small distances, no parallax, no scroll-jacking, no
      counters spinning up, no auto-playing carousels. Motion here does two
      jobs: it tells you the header became sticky, and it stages a long page so
      each band arrives as its own thought. Anything beyond that is noise on a
      site where someone may be anxious and looking for a phone number.
   ========================================================================== */

/* --- Scroll reveal -------------------------------------------------------
   Progressive enhancement. The opacity:0 start state exists ONLY when the
   html.js-motion class is present. */

html.js-motion [data-reveal] {
  opacity: 0;
  transform: translateY(18px);
  will-change: opacity, transform;
}

html.js-motion [data-reveal].is-visible {
  opacity: 1;
  transform: none;
  transition:
    opacity var(--dur-slow) var(--ease-out),
    transform var(--dur-slow) var(--ease-out);
}

/* Children of a revealed group stagger. Depth is capped at six: past that the
   last item waits long enough to read as a bug rather than as choreography. */
html.js-motion [data-reveal-group] > * { transition-delay: 0ms; }
html.js-motion [data-reveal-group].is-visible > *:nth-child(1) { transition-delay:   0ms; }
html.js-motion [data-reveal-group].is-visible > *:nth-child(2) { transition-delay:  70ms; }
html.js-motion [data-reveal-group].is-visible > *:nth-child(3) { transition-delay: 140ms; }
html.js-motion [data-reveal-group].is-visible > *:nth-child(4) { transition-delay: 210ms; }
html.js-motion [data-reveal-group].is-visible > *:nth-child(5) { transition-delay: 280ms; }
html.js-motion [data-reveal-group].is-visible > *:nth-child(6) { transition-delay: 350ms; }

html.js-motion [data-reveal-group] > * {
  opacity: 0;
  transform: translateY(14px);
}
html.js-motion [data-reveal-group].is-visible > * {
  opacity: 1;
  /* transform MUST be reset here. Without it the start-state translateY(14px)
     is never undone, so every child of every reveal group sits 14px low
     FOREVER and hangs out of the bottom of its band. It looked like a spacing
     bug in the trust strip and the card grids, and it was visible only with
     motion enabled, because the reduced-motion block below forces
     transform:none and quietly masked it. */
  transform: none;
  transition:
    opacity var(--dur-slow) var(--ease-out),
    transform var(--dur-slow) var(--ease-out);
}

/* --- Hero entrance ------------------------------------------------------
   The legacy reference stages its hero layers instead of dropping one static
   block at the top of the photograph. Keep that rhythm, but use short rises and
   fades rather than the reference slider's heavier effects. These selectors are
   behind js-motion, so content is never hidden when JS is absent or motion has
   been reduced. */

html.js-motion .pagehero :is(.crumbs, .eyebrow, h1, .pagehero__lede, .pagehero__ctas) {
  opacity: 0;
  transform: translateY(22px);
  animation: hero-layer-enter 720ms var(--ease-out) both;
}
html.js-motion .pagehero .crumbs          { animation-delay:  60ms; }
html.js-motion .pagehero .eyebrow         { animation-delay: 120ms; }
html.js-motion .pagehero h1               { animation-delay: 210ms; }
html.js-motion .pagehero .pagehero__lede  { animation-delay: 320ms; }
html.js-motion .pagehero .pagehero__ctas  { animation-delay: 430ms; }

/* Each carousel change restarts the sequence because .is-active is removed and
   added by the existing slider controller. The outgoing words disappear before
   the 600ms photograph cross-fade finishes, so two headlines never overlap. */
html.js-motion .slider__slide :is(.hero__badge, h1, h2, .slider__lede, .slider__ctas) {
  opacity: 0;
  transform: translateY(24px);
}
html.js-motion .slider__slide.is-active .hero__badge {
  animation: hero-layer-enter 700ms var(--ease-out) 140ms both;
}
html.js-motion .slider__slide.is-active :is(h1, h2) {
  animation: hero-layer-enter 760ms var(--ease-out) 230ms both;
}
html.js-motion .slider__slide.is-active .slider__lede {
  animation: hero-layer-enter 720ms var(--ease-out) 340ms both;
}
html.js-motion .slider__slide.is-active .slider__ctas {
  animation: hero-layer-enter 720ms var(--ease-out) 450ms both;
}

/* The active homepage photograph gently settles from a slight crop to its
   natural cover scale over the same seven seconds as the carousel interval.
   Removing .is-active immediately removes and resets the animation, so an
   inactive slide never keeps moving behind the current one. */
html.js-motion .slider__slide.is-active::after {
  animation: slider-photo-zoom-out 7000ms linear both;
  will-change: transform;
}

@keyframes slider-photo-zoom-out {
  from { transform: scale(1.05); }
  to   { transform: scale(1); }
}

@keyframes hero-layer-enter {
  from { opacity: 0; transform: translateY(24px); }
  to   { opacity: 1; transform: none; }
}

/* --- Decorative peak motif ----------------------------------------------
   The ridge line draws itself once, when its band scrolls into view, and never
   again. Deliberately NOT applied to the logo: a mark that re-animates is a
   toy, not a mark, and the logo has to look identical in an email signature, a
   favicon and a fax header where nothing can move at all. */

html.js-motion [data-peak-stroke] {
  stroke-dasharray: 240;
  stroke-dashoffset: 240;
}
html.js-motion .is-visible [data-peak-stroke],
html.js-motion [data-reveal].is-visible[data-peak-stroke] {
  animation: peak-draw 1100ms var(--ease-out) 120ms forwards;
}
@keyframes peak-draw { to { stroke-dashoffset: 0; } }

/* --- Reduced motion ------------------------------------------------------
   Honoured twice: main.js declines to add js-motion at all, and this block
   neutralises anything that slipped through, including a class added by a
   future script that forgets to check. */

@media (prefers-reduced-motion: reduce) {
  .slider__slide::after {
    transform: none !important;
    animation: none !important;
  }
  html.js-motion [data-reveal],
  html.js-motion [data-reveal].is-visible,
  html.js-motion [data-reveal-group] > *,
  html.js-motion [data-reveal-group].is-visible > * {
    opacity: 1 !important;
    transform: none !important;
    transition: none !important;
  }
  html.js-motion [data-peak-stroke] {
    stroke-dashoffset: 0 !important;
    animation: none !important;
  }
  html.js-motion .pagehero :is(.crumbs, .eyebrow, h1, .pagehero__lede, .pagehero__ctas),
  html.js-motion .slider__slide :is(.hero__badge, h1, h2, .slider__lede, .slider__ctas) {
    opacity: 1 !important;
    transform: none !important;
    animation: none !important;
  }
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
}

/* --- The hard exclusion --------------------------------------------------
   Regulatory text is never staged, faded, delayed, or transformed, under any
   combination of classes, in any browser state. If a future change makes a
   disclosure move, this block is the thing that was deleted. Do not delete it. */

.disclosure,
.disclosure *,
.formnote,
.formnote *,
html.js-motion .disclosure,
html.js-motion .disclosure *,
html.js-motion [data-reveal-group].is-visible .disclosure,
html.js-motion [data-reveal-group] .disclosure,
html.js-motion .formnote,
html.js-motion [data-reveal-group] .formnote {
  opacity: 1 !important;
  transform: none !important;
  transition: none !important;
  animation: none !important;
  filter: none !important;
  visibility: visible !important;
}
