/* =============================================================
   animations.css — scroll-reveal system, stagger, peek effect
   =============================================================

   PEEK STRATEGY
   ─────────────
   Goal: the viewer should see ~60px of the *next* section's
   content before they scroll to it — a natural editorial "teaser."

   How it works (no JS needed):
   1. Every section has generous padding-bottom (--space-3xl ≥ 56px).
   2. The first .reveal child in a new section starts life at
      translateY(30px) and opacity 0. Those 30px of downward offset
      plus the section's top padding mean the element is visually
      "hiding just below the fold" — the page chrome sits over it.
   3. Because no section sets overflow:hidden, the 30px downward
      ghost of the next section's heading bleeds ~60px into the
      current section's bottom-padding space once the next section
      is close enough to the viewport for its padding to reach the
      visible area, while the .reveal element is still invisible.
   4. The IntersectionObserver threshold (0.08) fires as soon as
      ~8% of the element enters the viewport — typically when only
      its top edge and that 30px offset peek into view — giving an
      instantaneous, satisfying pop-in as the user scrolls into it.

   Net effect: generous whitespace + the translate offset creates a
   natural content preview without any overflow tricks or negative
   margins.

   ============================================================= */

/* ── Respects user preference ──────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
  .reveal,
  .reveal-group > * {
    opacity: 1 !important;
    transform: none !important;
    transition: none !important;
  }
}

/* =============================================================
   REVEAL — base hidden state
   ============================================================= */

.reveal {
  opacity: 0;
  transform: translateY(30px);
  /*
    0.7s duration feels comfortable at editorial scroll pace —
    not snappy enough to look like a notification, not so slow
    it drags behind the user's hand.
    ease-out (--ease-out) means it accelerates into view quickly
    then eases to rest — gives weight without sluggishness.
  */
  transition:
    opacity   0.7s var(--ease-out),
    transform 0.7s var(--ease-out);
  will-change: opacity, transform;
}

.reveal.visible {
  opacity: 1;
  transform: translateY(0);
}

/* ── Variant: fade only (no vertical movement) ─────────────── */
.reveal--fade {
  transform: none;
}

.reveal--fade.visible {
  transform: none;
}

/* ── Variant: slide from left ──────────────────────────────── */
.reveal--left {
  transform: translateX(-24px);
}

.reveal--left.visible {
  transform: translateX(0);
}

/* ── Variant: slide from right ─────────────────────────────── */
.reveal--right {
  transform: translateX(24px);
}

.reveal--right.visible {
  transform: translateX(0);
}

/* ── Variant: scale up (cards, images) ─────────────────────── */
.reveal--scale {
  transform: scale(0.96) translateY(16px);
}

.reveal--scale.visible {
  transform: scale(1) translateY(0);
}

/* =============================================================
   REVEAL-GROUP — staggered children
   =============================================================

   Usage:
     <ul class="reveal-group">
       <li class="reveal">...</li>
       <li class="reveal">...</li>
       <li class="reveal">...</li>
     </ul>

   The parent gets .visible toggled by JS (same observer).
   Each direct child inherits the delay ladder below.
   Works up to 8 items; beyond that delays stop stacking.

   Note: children start hidden via the .reveal class on the
   element itself — this block only overrides transition-delay.
*/

.reveal-group > * {
  opacity: 0;
  transform: translateY(30px);
  transition:
    opacity   0.7s var(--ease-out),
    transform 0.7s var(--ease-out);
}

.reveal-group.visible > * {
  opacity: 1;
  transform: translateY(0);
}

.reveal-group.visible > *:nth-child(1) { transition-delay: 0ms;   }
.reveal-group.visible > *:nth-child(2) { transition-delay: 100ms; }
.reveal-group.visible > *:nth-child(3) { transition-delay: 200ms; }
.reveal-group.visible > *:nth-child(4) { transition-delay: 300ms; }
.reveal-group.visible > *:nth-child(5) { transition-delay: 400ms; }
.reveal-group.visible > *:nth-child(6) { transition-delay: 500ms; }
.reveal-group.visible > *:nth-child(7) { transition-delay: 600ms; }
.reveal-group.visible > *:nth-child(8) { transition-delay: 700ms; }

/*
  Cap for groups larger than 8: remaining items all share the
  max delay so they don't lag behind indefinitely.
*/
.reveal-group.visible > *:nth-child(n+9) { transition-delay: 700ms; }

/* =============================================================
   PAGE ENTRY — fires once on load, no JS
   ============================================================= */

/*
  Applied to the <main> element for a gentle page-level entrance.
  Keeps the first paint from being a hard cut.
*/
@keyframes pageEnter {
  from {
    opacity: 0;
    transform: translateY(12px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.page-enter {
  animation: pageEnter 0.6s var(--ease-out) both;
}

/* =============================================================
   SECTION-LABEL ENTRANCE
   =============================================================
   The section-label uses a tiny leftward slide to match its
   small scale — the 30px of the standard reveal would feel
   disproportionate on 12px text.
*/
.section-label.reveal {
  transform: translateX(-8px);
  transition-duration: 0.5s;
}

.section-label.reveal.visible {
  transform: translateX(0);
}

/* =============================================================
   INDIVIDUAL REVEAL DELAYS
   =============================================================
   For hero sections and other non-homogeneous layouts where
   staggering items manually is clearer than .reveal-group.

   Two usage patterns — pick whichever reads better in HTML:

   (a) CSS class:   <p class="reveal reveal--d2">...</p>
   (b) Inline style: <p class="reveal" style="transition-delay:200ms">

   Both are valid. The inline style is more explicit for
   one-off cases; the class is better when many elements share
   the same delay across pages.
   ============================================================= */

.reveal--d1 { transition-delay:  100ms; }
.reveal--d2 { transition-delay:  200ms; }
.reveal--d3 { transition-delay:  300ms; }
.reveal--d4 { transition-delay:  400ms; }
.reveal--d5 { transition-delay:  500ms; }
.reveal--d6 { transition-delay:  600ms; }

/* =============================================================
   SKELETON LOADER
   ============================================================= */

@keyframes shimmer {
  from { background-position: -200% 0; }
  to   { background-position:  200% 0; }
}

.skeleton {
  background: linear-gradient(
    90deg,
    var(--color-surface) 25%,
    var(--color-border)  50%,
    var(--color-surface) 75%
  );
  background-size: 200% 100%;
  animation: shimmer 1.6s infinite linear;
  border-radius: var(--radius-sm);
  color: transparent;
  user-select: none;
  pointer-events: none;
}

/* =============================================================
   HOVER LIFT — reusable on cards, images
   ============================================================= */

.hover-lift {
  transition:
    transform  var(--duration-base) var(--ease-out),
    box-shadow var(--duration-base) var(--ease-out);
}

.hover-lift:hover {
  transform: translateY(-4px);
  box-shadow: var(--shadow-lg);
}
