/* ==========================================================================
   Help The Poor Initiative — Motion
   --------------------------------------------------------------------------
   Everything here animates ONLY `transform` and `opacity`, the two properties
   the browser can move on the compositor without re-laying-out the page. That
   is what keeps it smooth rather than merely busy.

   SAFETY: the hidden "before" states are all scoped to `html.js`, a class set
   by a tiny inline script in the <head>. If JavaScript never runs, nothing is
   ever hidden and the page renders as plain static content.

   The whole file is disabled under `prefers-reduced-motion: reduce` at the
   bottom — everything simply appears.
   ========================================================================== */

:root {
  /* Expo-out — a long, soft deceleration. This is the "glide" that makes the
     motion feel heavy and smooth rather than snappy. */
  --ease-glide: cubic-bezier(.16, 1, .3, 1);
  --ease-out-soft: cubic-bezier(.22, .61, .36, 1);
  --ease-back: cubic-bezier(.34, 1.56, .64, 1);   /* slight overshoot */

  --reveal-distance: 42px;
  --reveal-speed: 1.05s;
}

/* --------------------------------------------------------------------------
   1. Scroll-reveal system
   Usage:  <div data-reveal>              → rises and fades in
           <div data-reveal="left">       → slides in from the left
           <ul data-stagger>              → children reveal one after another
   -------------------------------------------------------------------------- */
.js [data-reveal] {
  opacity: 0;
  transform: translate3d(0, var(--reveal-distance), 0);
  transition:
    opacity var(--reveal-speed) var(--ease-glide),
    transform var(--reveal-speed) var(--ease-glide);
  will-change: opacity, transform;
}

.js [data-reveal="down"]  { transform: translate3d(0, calc(var(--reveal-distance) * -1), 0); }
.js [data-reveal="left"]  { transform: translate3d(calc(var(--reveal-distance) * -1.4), 0, 0); }
.js [data-reveal="right"] { transform: translate3d(calc(var(--reveal-distance) * 1.4), 0, 0); }
.js [data-reveal="zoom"]  { transform: scale(.90); }
.js [data-reveal="fade"]  { transform: none; }

.js [data-reveal="blur-up"] {
  transform: translate3d(0, var(--reveal-distance), 0);
  filter: blur(10px);
  transition:
    opacity var(--reveal-speed) var(--ease-glide),
    transform var(--reveal-speed) var(--ease-glide),
    filter var(--reveal-speed) var(--ease-glide);
}

/* The revealed state — one rule wins for every variant */
.js [data-reveal].is-revealed {
  opacity: 1;
  transform: translate3d(0, 0, 0) scale(1);
  filter: blur(0);
}

/* Once it has played, stop hinting the compositor */
.js [data-reveal].is-revealed { will-change: auto; }

/* --------------------------------------------------------------------------
   2. Hero entrance — plays once, on load
   -------------------------------------------------------------------------- */
.js .hero-mark,
.js .hero-title-main,
.js .hero-title-sub,
.js .hero-rule,
.js .hero-tagline,
.js .hero-cta,
.js .focus-item { opacity: 0; }

.hero.is-entered .hero-mark {
  animation: heroMark 1.5s var(--ease-glide) .15s forwards;
}

.hero.is-entered .hero-title-main {
  animation: heroRise 1.25s var(--ease-glide) .45s forwards;
}

/* The tracking on INITIATIVE settles outward — it reads as the word
   "opening up" rather than merely fading. */
.hero.is-entered .hero-title-sub {
  animation: heroTrack 1.5s var(--ease-glide) .68s forwards;
}

.hero.is-entered .hero-rule {
  animation: heroRule 1.2s var(--ease-glide) .95s forwards;
}

.hero.is-entered .hero-tagline {
  animation: heroRise 1.15s var(--ease-glide) 1.1s forwards;
}

.hero.is-entered .hero-cta {
  animation: heroPop 1s var(--ease-back) 1.3s forwards;
}

.hero.is-entered .focus-item {
  animation: heroRise 1s var(--ease-glide) forwards;
  animation-delay: calc(1.45s + var(--i, 0) * .09s);
}

@keyframes heroMark {
  0%   { opacity: 0; transform: translate3d(0, 34px, 0) scale(.72); }
  100% { opacity: 1; transform: translate3d(0, 0, 0) scale(1); }
}

@keyframes heroRise {
  0%   { opacity: 0; transform: translate3d(0, 38px, 0); }
  100% { opacity: 1; transform: translate3d(0, 0, 0); }
}

@keyframes heroTrack {
  0%   { opacity: 0; letter-spacing: .12em; transform: translate3d(0, 18px, 0); }
  100% { opacity: 1; letter-spacing: .40em; transform: translate3d(0, 0, 0); }
}

@keyframes heroRule {
  0%   { opacity: 0; transform: scaleX(.2); }
  100% { opacity: 1; transform: scaleX(1); }
}

@keyframes heroPop {
  0%   { opacity: 0; transform: translate3d(0, 26px, 0) scale(.88); }
  100% { opacity: 1; transform: translate3d(0, 0, 0) scale(1); }
}

/* The logo keeps breathing gently once it has landed.
   opacity is set explicitly here rather than being inherited from the
   entrance animation's `forwards` fill — swapping in sunFloat replaces
   heroMark, and with it that fill, which would drop the mark back to the
   hidden base state. */
.hero.is-entered.is-settled .hero-mark {
  opacity: 1;
  animation: sunFloat 7s ease-in-out infinite;
}

@keyframes sunFloat {
  0%, 100% { transform: translate3d(0, 0, 0); }
  50%      { transform: translate3d(0, -10px, 0); }
}

/* --------------------------------------------------------------------------
   3. Hero parallax
   main.js writes --scroll-y (px scrolled within the hero).
   -------------------------------------------------------------------------- */
.hero-bg {
  transform: translate3d(0, calc(var(--scroll-y, 0) * .34px), 0) scale(1.08);
  will-change: transform;
}

.hero-inner {
  transform: translate3d(0, calc(var(--scroll-y, 0) * .16px), 0);
  opacity: calc(1 - var(--scroll-y, 0) * .0016);
}

/* --------------------------------------------------------------------------
   4. Section furniture
   -------------------------------------------------------------------------- */

/* --------------------------------------------------------------------------
   5. Hover motion
   -------------------------------------------------------------------------- */

/* Focus strip icons lift and brighten */
.focus-item .focus-icon {
  transition: transform .55s var(--ease-back), filter .4s var(--ease-out-soft);
}

.focus-item:hover .focus-icon {
  transform: translateY(-5px) scale(1.14);
  filter: drop-shadow(0 6px 12px rgba(238, 124, 32, .45));
}

.focus-item {
  transition: background-color .45s var(--ease-out-soft);
}

.focus-item:hover { background: rgba(255, 255, 255, .05); }

/* Program cards: an accent bar sweeps across the top on hover */
.program-card::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 3px;
  z-index: 3;
  background: var(--accent);
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform .6s var(--ease-glide);
}

.program-card:hover::before { transform: scaleX(1); }

/* A soft light sweeps across the image */
.program-card .media::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 2;
  background: linear-gradient(105deg,
    transparent 35%,
    rgba(255, 255, 255, .30) 50%,
    transparent 65%);
  transform: translateX(-120%);
  transition: transform .95s var(--ease-out-soft);
  pointer-events: none;
}

.program-card:hover .media::before { transform: translateX(120%); }

/* Buttons get a travelling sheen */
.btn {
  position: relative;
  overflow: hidden;
}

.btn::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(105deg,
    transparent 38%,
    rgba(255, 255, 255, .28) 50%,
    transparent 62%);
  transform: translateX(-130%);
  transition: transform .85s var(--ease-out-soft);
  pointer-events: none;
}

.btn:hover::after { transform: translateX(130%); }

.btn > * { position: relative; z-index: 1; }

/* Nav links grow an underline from the centre */
.nav-link::after {
  content: "";
  position: absolute;
  left: 13px;
  right: 13px;
  bottom: 4px;
  height: 2px;
  border-radius: 2px;
  background: var(--orange-warm);
  transform: scaleX(0);
  transition: transform .45s var(--ease-glide);
}

.nav-link { position: relative; }

.nav-link:hover::after,
.nav-link[aria-expanded="true"]::after,
.nav-link.is-active::after { transform: scaleX(1); }

/* Dropdown items cascade in */
.dropdown li {
  opacity: 0;
  transform: translateX(-10px);
  transition: opacity .4s var(--ease-out-soft), transform .4s var(--ease-out-soft);
}

.dropdown.is-open li {
  opacity: 1;
  transform: translateX(0);
}

.dropdown.is-open li:nth-child(1) { transition-delay: .04s; }
.dropdown.is-open li:nth-child(2) { transition-delay: .08s; }
.dropdown.is-open li:nth-child(3) { transition-delay: .12s; }
.dropdown.is-open li:nth-child(4) { transition-delay: .16s; }
.dropdown.is-open li:nth-child(5) { transition-delay: .20s; }
.dropdown.is-open li:nth-child(6) { transition-delay: .24s; }

/* Story rows slide slightly toward the reader */
.story {
  transition: transform .5s var(--ease-glide);
}

.story:hover { transform: translateX(6px); }

.story .media > img,
.story .media { transition: transform .6s var(--ease-glide); }
.story:hover .media { transform: scale(1.05); }

/* Newsletter envelope breathes */
.newsletter-icon {
  transition: transform .6s var(--ease-back);
}

.newsletter:hover .newsletter-icon { transform: scale(1.09) rotate(-5deg); }

.newsletter-icon::after {
  content: "";
  position: absolute;
  inset: -8px;
  border-radius: 50%;
  border: 2px solid rgba(255, 255, 255, .25);
  opacity: 0;
  animation: ringPulse 3.4s var(--ease-out-soft) infinite;
}

.newsletter-icon { position: relative; }

@keyframes ringPulse {
  0%   { opacity: .55; transform: scale(.86); }
  70%  { opacity: 0;   transform: scale(1.28); }
  100% { opacity: 0;   transform: scale(1.28); }
}

/* Footer links and socials */
.socials a { transition: transform .5s var(--ease-back), background-color .35s ease; }
.socials a:hover { transform: translateY(-6px) scale(1.1); }

/* --------------------------------------------------------------------------
   6. Scroll progress bar
   -------------------------------------------------------------------------- */
.scroll-progress {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  height: 3px;
  z-index: 200;
  background: linear-gradient(90deg, var(--green), var(--green-mid), var(--orange));
  transform: scaleX(var(--progress, 0));
  transform-origin: left center;
  pointer-events: none;
}

/* --------------------------------------------------------------------------
   7. Back-to-top
   -------------------------------------------------------------------------- */
.to-top {
  position: fixed;
  right: clamp(16px, 3vw, 32px);
  bottom: clamp(16px, 3vw, 32px);
  z-index: 150;
  display: grid;
  place-items: center;
  width: 50px;
  height: 50px;
  border-radius: 50%;
  color: #fff;
  background: var(--green);
  box-shadow: 0 10px 26px rgba(30, 92, 38, .40);
  opacity: 0;
  visibility: hidden;
  transform: translateY(22px) scale(.8);
  transition:
    opacity .55s var(--ease-glide),
    transform .55s var(--ease-back),
    visibility .55s,
    background-color .3s ease;
}

.to-top.is-visible {
  opacity: 1;
  visibility: visible;
  transform: translateY(0) scale(1);
}

.to-top:hover {
  background: var(--green-mid);
  transform: translateY(-4px) scale(1.06);
}

.to-top svg { transition: transform .45s var(--ease-back); }
.to-top:hover svg { transform: translateY(-3px); }

/* --------------------------------------------------------------------------
   8. Drawer contents cascade in
   -------------------------------------------------------------------------- */
.drawer-nav > li,
.drawer-cta {
  opacity: 0;
  transform: translateX(28px);
  transition: opacity .5s var(--ease-glide), transform .5s var(--ease-glide);
}

.drawer.is-open .drawer-nav > li,
.drawer.is-open .drawer-cta {
  opacity: 1;
  transform: translateX(0);
}

.drawer.is-open .drawer-nav > li:nth-child(1) { transition-delay: .10s; }
.drawer.is-open .drawer-nav > li:nth-child(2) { transition-delay: .16s; }
.drawer.is-open .drawer-nav > li:nth-child(3) { transition-delay: .22s; }
.drawer.is-open .drawer-nav > li:nth-child(4) { transition-delay: .28s; }
.drawer.is-open .drawer-nav > li:nth-child(5) { transition-delay: .34s; }
.drawer.is-open .drawer-nav > li:nth-child(6) { transition-delay: .40s; }
.drawer.is-open .drawer-cta                   { transition-delay: .48s; }

/* --------------------------------------------------------------------------
   9. Reduced motion — everything simply appears
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  .js [data-reveal],
  .js .hero-mark,
  .js .hero-title-main,
  .js .hero-title-sub,
  .js .hero-rule,
  .js .hero-tagline,
  .js .hero-cta,
  .js .focus-item,
  .dropdown li,
  .drawer-nav > li,
  .drawer-cta {
    opacity: 1 !important;
    transform: none !important;
    filter: none !important;
    animation: none !important;
    transition: none !important;
  }

  .hero-bg,
  .hero-inner { transform: none !important; opacity: 1 !important; }

  .program-card::before,
  .program-card .media::before,
  .btn::after,
  .newsletter-icon::after { display: none; }

  .to-top { transition: opacity .01ms; }
}
