[data-animate="fade-up"] {
  opacity: 0;
  transform: translateY(20px);
  transition: opacity var(--transition-slow),
              transform var(--transition-slow);
}

[data-animate="fade-up"].is-visible {
  opacity: 1;
  transform: translateY(0);
}

/* --- Sitewide staggered reveal for grids/lists ---
   Every page already wraps its card grids, timelines, and stat rows in a
   single [data-animate="fade-up"] container (see js/animations.js —
   initFadeUpReveal toggles .is-visible via IntersectionObserver). Rather
   than hand-adding data-animate to every card on every page, the direct
   children of any revealed container get a light staggered pop the
   moment their parent becomes visible. This gives every page — home,
   about, events, get-involved, hackathon, past events, login, register —
   the same cascading entrance for free, with zero markup changes.
   prefers-reduced-motion is already handled globally in reset.css. */
[data-animate="fade-up"].is-visible > * {
  animation: stagger-pop-in 0.6s var(--ease-standard) both;
}

[data-animate="fade-up"].is-visible > *:nth-child(1) { animation-delay: 0.02s; }
[data-animate="fade-up"].is-visible > *:nth-child(2) { animation-delay: 0.09s; }
[data-animate="fade-up"].is-visible > *:nth-child(3) { animation-delay: 0.16s; }
[data-animate="fade-up"].is-visible > *:nth-child(4) { animation-delay: 0.23s; }
[data-animate="fade-up"].is-visible > *:nth-child(5) { animation-delay: 0.30s; }
[data-animate="fade-up"].is-visible > *:nth-child(6) { animation-delay: 0.37s; }
[data-animate="fade-up"].is-visible > *:nth-child(7) { animation-delay: 0.44s; }
[data-animate="fade-up"].is-visible > *:nth-child(8) { animation-delay: 0.51s; }
[data-animate="fade-up"].is-visible > *:nth-child(n+9) { animation-delay: 0.58s; }

@keyframes stagger-pop-in {
  from { opacity: 0; transform: translateY(16px) scale(0.97); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}

/* Nested containers (e.g. a card grid inside a section that is itself
   [data-animate="fade-up"]) shouldn't double-animate their own children
   before the grid itself has been revealed. */
[data-animate="fade-up"]:not(.is-visible) > * {
  animation: none;
}

/* Note: an earlier version of this file redefined .hero, .hero__overlay,
   .hero__fade, .hero__content and .hero__scroll-cue with a conflicting
   `overflow: hidden` on .hero. Since this file loads after layout.css,
   it was clipping the stat labels that intentionally spill below the
   hero's bottom edge (see layout.css). Those unused/duplicate rules
   have been removed — layout.css is the single source of truth for
   hero layout now. */

/* --- Home hero headline ---
   The hero text sits on a photo, not on the page background, so it must
   stay legible in BOTH light and dark mode — it does not inherit
   --color-text (that flips to dark ink in light mode and disappears
   against the photo, which is the bug being fixed here). "We Talk
   About" stays solid white for a readable anchor line; the AI Security
   headline gets an animated purple-to-white gradient fill for visual
   pop, with a soft shadow so it holds up over both dark and light
   patches of the photo. */
.hero__content h1 {
  color: #ffffff;
  text-shadow: 0 4px 24px rgba(0, 0, 0, 0.55);
}

.hero__content .small-text {
  display: inline-block;
  color: #ffffff;
  opacity: 0.92;
}

.hero__content .big-text {
  display: inline-block;
  background: linear-gradient(
    90deg,
    #ffffff 0%,
    #d9b6ff 25%,
    var(--brand-primary) 50%,
    #d9b6ff 75%,
    #ffffff 100%
  );
  background-size: 200% auto;
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: transparent;
  animation: hero-gradient-pan 6s linear infinite;
}

@keyframes hero-gradient-pan {
  to { background-position: 200% center; }
}

.hero__subtitle {
  color: #ffffff;
  opacity: 0.9;
  text-shadow: 0 2px 12px rgba(0, 0, 0, 0.5);
}

@media (prefers-reduced-motion: reduce) {
  .hero__content .big-text {
    animation: none;
  }
}

/* --- Past-event recap cards (home): whole card is a link to Past Events --- */
.recap-card {
  padding: 0;
  overflow: hidden;
  transition: transform var(--transition-base), border-color var(--transition-base);
}

.recap-card:hover,
.recap-card:focus-within {
  transform: translateY(-4px);
  border-color: var(--color-primary);
}

.recap-card__link {
  display: block;
  color: inherit;
  text-decoration: none;
}

.recap-card__link:hover .card__title,
.recap-card__link:focus-visible .card__title {
  color: var(--color-primary);
}