/*
  Cove — motion layer.
  Only what the Style panel cannot hold lives here: keyframes, scroll-reveal states
  (attribute selectors), scroll-linked parallax and hover choreography that targets a
  child from its parent. All visual styling stays in webcontra.css.

  Reveals are opt-in: nothing is hidden unless scripts/main.js has added
  html.has-motion, and main.js never adds it for prefers-reduced-motion.
*/

@media (prefers-reduced-motion: no-preference) {
  html {
    scroll-behavior: smooth;
  }
}

/* ------------------------------------------------------------------ */
/* Scroll reveals                                                      */
/* ------------------------------------------------------------------ */

.has-motion [data-reveal]:not([data-revealed="done"]) {
  transition:
    opacity 1s var(--ease-out),
    transform 1.25s var(--ease-out),
    clip-path 1.4s var(--ease-out),
    scale 1.8s var(--ease-out);
  transition-delay: var(--d, 0s);
}

/* Stagger: direct children of a [data-stagger] group enter one after another. */
.has-motion [data-stagger] > :nth-child(2) { --d: 0.12s; }
.has-motion [data-stagger] > :nth-child(3) { --d: 0.24s; }
.has-motion [data-stagger] > :nth-child(4) { --d: 0.36s; }
.has-motion [data-stagger] > :nth-child(5) { --d: 0.48s; }
.has-motion [data-stagger] > :nth-child(6) { --d: 0.6s; }
.has-motion [data-delay="0.2"] { --d: 0.2s; }
.has-motion [data-delay="0.35"] { --d: 0.35s; }

/* up — rise and fade */
.has-motion [data-reveal="up"]:not([data-revealed]) {
  opacity: 0;
  transform: translate3d(0, 44px, 0);
}

/* down — the navigation settles in from above */
.has-motion [data-reveal="down"]:not([data-revealed]) {
  opacity: 0;
  transform: translate3d(0, -18px, 0);
}

/* fade */
.has-motion [data-reveal="fade"]:not([data-revealed]) {
  opacity: 0;
}

/* zoom — photographs ease back from a slight push-in */
.has-motion [data-reveal="zoom"]:not([data-revealed]) {
  opacity: 0;
  scale: 1.22;
}

/* wipe — line drawings are drawn in from the left */
.has-motion [data-reveal="wipe"]:not([data-revealed="done"]) {
  transition-duration: 1s, 1.25s, 2.4s, 1.8s;
  transition-timing-function: var(--ease-out), var(--ease-out), var(--ease-soft), var(--ease-out);
}
.has-motion [data-reveal="wipe"]:not([data-revealed]) {
  clip-path: inset(0 100% 0 0);
}
.has-motion [data-reveal="wipe"][data-revealed] {
  clip-path: inset(0 0 0 0);
}

/* wipe-up — the skyline rises out of the ground */
.has-motion [data-reveal="wipe-up"]:not([data-revealed="done"]) {
  transition-duration: 1s, 1.25s, 2.2s, 1.8s;
  transition-timing-function: var(--ease-out), var(--ease-out), var(--ease-soft), var(--ease-out);
}
.has-motion [data-reveal="wipe-up"]:not([data-revealed]) {
  clip-path: inset(100% 0 0 0);
}
.has-motion [data-reveal="wipe-up"][data-revealed] {
  clip-path: inset(0 0 0 0);
}

/* line — rules and meters draw across */
.has-motion [data-reveal="line"]:not([data-revealed="done"]) {
  transition-delay: calc(var(--d, 0s) + 0.25s);
}
.has-motion [data-reveal="line"]:not([data-revealed]) {
  transform: scaleX(0);
}

/* rise — the footer wordmark lifts out from behind a mask */
.has-motion [data-reveal="rise"]:not([data-revealed="done"]) {
  transition-duration: 1s, 1.6s, 1.6s, 1.8s;
}
.has-motion [data-reveal="rise"]:not([data-revealed]) {
  transform: translate3d(0, 60%, 0);
  clip-path: inset(0 0 100% 0);
}
.has-motion [data-reveal="rise"][data-revealed] {
  clip-path: inset(-10% -10% -10% -10%);
}

/* lines — headings rise line by line from behind a baseline mask */
.has-motion [data-reveal="lines"] .line {
  transition:
    transform 1.25s var(--ease-out),
    clip-path 1.25s var(--ease-out);
  transition-delay: calc(var(--d, 0s) + var(--ld, 0s));
}
.has-motion [data-reveal="lines"] .line:nth-child(2) { --ld: 0.09s; }
.has-motion [data-reveal="lines"] .line:nth-child(3) { --ld: 0.18s; }
.has-motion [data-reveal="lines"] .line:nth-child(4) { --ld: 0.27s; }
.has-motion [data-reveal="lines"] .line:nth-child(5) { --ld: 0.36s; }
.has-motion [data-reveal="lines"]:not([data-revealed]) .line {
  transform: translate3d(0, 105%, 0);
  clip-path: inset(0 0 100% 0);
}
.has-motion [data-reveal="lines"][data-revealed] .line {
  clip-path: inset(-25% -6% -25% -6%);
}
.has-motion [data-reveal="lines"][data-revealed="done"] .line {
  clip-path: none;
}

/* The little rule inside a sentence draws itself once its paragraph is in. */
.has-motion .dash {
  transition: transform 1.1s var(--ease-out);
  transition-delay: calc(var(--d, 0s) + 0.45s);
}
.has-motion [data-reveal]:not([data-revealed]) .dash {
  transform: scaleX(0);
}

/* ------------------------------------------------------------------ */
/* Scroll-linked depth (browsers with scroll timelines)                */
/* ------------------------------------------------------------------ */

@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    .hero-portrait,
    .hero-sketch,
    .leaders-portrait,
    .leaders-sketch,
    .rank-bg,
    .vision-sketch {
      animation: cove-drift linear both;
      animation-timeline: view();
    }

    /* Hero: as the page scrolls away the portrait sinks and the drawing lifts. */
    .hero-portrait {
      --drift-from: 0px;
      --drift-to: 70px;
      animation-range: exit 0% exit 100%;
    }
    .hero-sketch {
      --drift-from: 0px;
      --drift-to: -50px;
      animation-range: exit 0% exit 100%;
    }

    /* Leaders: the founder and the skyline rise into place at different speeds. */
    .leaders-portrait {
      --drift-from: 90px;
      --drift-to: 0px;
      animation-range: entry 10% cover 55%;
    }
    .leaders-sketch {
      --drift-from: 40px;
      --drift-to: 0px;
      animation-range: entry 0% cover 50%;
    }

    .rank-bg {
      --drift-from: -24px;
      --drift-to: 24px;
      animation-range: cover 0% cover 100%;
    }
    .vision-sketch {
      --drift-from: 26px;
      --drift-to: -26px;
      animation-range: cover 0% cover 100%;
    }
  }
}

@keyframes cove-drift {
  from { translate: 0 var(--drift-from, 0px); }
  to { translate: 0 var(--drift-to, 0px); }
}

/* ------------------------------------------------------------------ */
/* Hover choreography (parent hover moves a child)                     */
/* ------------------------------------------------------------------ */

@media (hover: hover) {
  .u-link:hover {
    animation: cove-underline 0.75s var(--ease-soft);
  }

  .nav-link:hover .nav-plus {
    transform: rotate(90deg);
  }

  .photo-card:hover .photo-card-img,
  .rank-card:hover .rank-bg {
    transform: scale(1.06);
  }

  .rank-number {
    transition: translate 0.8s var(--ease-out);
  }
  .rank-card:hover .rank-number {
    translate: 10px 0;
  }

  .project-card:hover .project-img {
    transform: scale(1.07);
  }
  .project-title {
    transition: translate 0.7s var(--ease-out), color 0.3s ease;
  }
  .project-card:hover .project-title {
    translate: 6px 0;
    color: var(--color-teal);
  }
  .project-card:hover .project-arrow {
    transform: rotate(-45deg);
    background-color: rgba(255, 255, 255, 0.28);
  }

  .social:hover .social-icon {
    filter: invert(1);
  }
}

.news-form:focus-within {
  border-bottom-color: var(--color-teal);
}

@keyframes cove-underline {
  0% { background-size: 100% 1px; background-position: 100% 100%; }
  45% { background-size: 0% 1px; background-position: 100% 100%; }
  46% { background-size: 0% 1px; background-position: 0% 100%; }
  100% { background-size: 100% 1px; background-position: 0% 100%; }
}

/* Keyboard users get a clear, on-brand focus ring everywhere. */
:focus-visible {
  outline: 2px solid var(--color-teal);
  outline-offset: 3px;
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}
