/* Motion layer. Everything here is opt-in through .js and prefers-reduced-motion: no-preference.
   Without JS or with reduced motion, every element sits in its final state. */

/* ---------- Page transitions (cross-document View Transitions) ---------- */

@view-transition {
  navigation: auto;
}

::view-transition-old(root),
::view-transition-new(root) {
  animation-duration: 300ms;
  animation-timing-function: var(--ease-out);
}

::view-transition-group(*) {
  animation-duration: 500ms;
  animation-timing-function: var(--ease-out-expo);
}

.site-header {
  view-transition-name: site-header;
}

@media (prefers-reduced-motion: no-preference) {
  /* ---------- Hero: sun spins in, letters rise one by one ---------- */

  .hero__sun {
    animation: sun-spin-in 1100ms var(--ease-out-expo) both;
  }

  .hero__char {
    display: inline-block;
    animation: char-rise 900ms var(--ease-out-expo) both;
    animation-delay: calc(120ms + var(--i) * 45ms);
  }

  .hero__dot {
    animation-name: dot-drop;
    animation-duration: 700ms;
    animation-timing-function: cubic-bezier(0.34, 1.56, 0.64, 1);
  }

  /* Scroll-linked rotation, value set by main.js */
  [data-spin] {
    rotate: calc(var(--spin, 0) * 1deg);
  }

  /* ---------- Reveal on scroll ---------- */

  .js [data-reveal] {
    opacity: 0;
    transform: translateY(40px);
    transition:
      opacity var(--dur-reveal) var(--ease-out-expo),
      transform var(--dur-reveal) var(--ease-out-expo);
    transition-delay: calc(var(--d, 0) * var(--stagger));
  }

  .js [data-reveal].is-in {
    opacity: 1;
    transform: none;
  }

  /* Project cards: the image is uncovered from the bottom, then settles */
  .js .card[data-reveal] {
    opacity: 1;
    transform: none;
  }

  .js .card[data-reveal] .card__media {
    clip-path: inset(100% 0 0 0);
    transition: clip-path 1000ms var(--ease-out-expo);
    transition-delay: calc(var(--d, 0) * 120ms);
  }

  .js .card[data-reveal] .card__media picture {
    display: block;
    height: 100%;
    scale: 1.18;
    transition: scale 1400ms var(--ease-out-expo);
    transition-delay: calc(var(--d, 0) * 120ms);
  }

  .js .card[data-reveal] :is(.card__meta, .card__title, .card__summary) {
    opacity: 0;
    transform: translateY(16px);
    transition:
      opacity 600ms var(--ease-out-expo),
      transform 600ms var(--ease-out-expo);
  }

  .js .card[data-reveal] .card__meta { transition-delay: calc(var(--d, 0) * 120ms + 350ms); }
  .js .card[data-reveal] .card__title { transition-delay: calc(var(--d, 0) * 120ms + 420ms); }
  .js .card[data-reveal] .card__summary { transition-delay: calc(var(--d, 0) * 120ms + 490ms); }

  .js .card[data-reveal].is-in .card__media {
    clip-path: inset(0);
  }

  .js .card[data-reveal].is-in .card__media picture {
    scale: 1;
  }

  .js .card[data-reveal].is-in :is(.card__meta, .card__title, .card__summary) {
    opacity: 1;
    transform: none;
  }

  /* Hover: the image breathes, the title slides */
  .card__title {
    transition: translate var(--dur-base) var(--ease-out);
  }

  @media (hover: hover) {
    .card:hover .card__title {
      translate: 6px 0;
    }
  }

  /* Band: each line comes up from below */
  .js .band__word[data-reveal] {
    transform: translateY(0.6em);
  }

  /* ---------- Inner page heads settle on load ---------- */

  .page-head > * {
    animation: rise 800ms var(--ease-out-expo) both;
  }

  .page-head > :nth-child(2) { animation-delay: 70ms; }
  .page-head > :nth-child(3) { animation-delay: 140ms; }
  .page-head > :nth-child(4) { animation-delay: 210ms; }
  .page-head > :nth-child(5) { animation-delay: 280ms; }

  /* ---------- Clients marquee ---------- */

  .marquee__track {
    animation: marquee 38s linear infinite;
  }

  .marquee:hover .marquee__track {
    animation-play-state: paused;
  }

  /* Hero posters are dealt onto the table after the name */
  .stack__card {
    animation: deal-in 900ms var(--ease-out-expo) backwards;
    animation-delay: calc(550ms + var(--n) * 130ms);
  }

  /* "Available" square next to Contact breathes */
  .nav__status::after {
    content: "";
    position: absolute;
    inset: 0;
    background: var(--color-accent);
    animation: status-pulse 2.4s var(--ease-out) infinite;
  }

  /* ---------- Sunrise (desktop): the sun travels the arc, steps light up as it passes ---------- */

  @media (min-width: 1024px) {
    .js .sunrise__x {
      transform: translateX(0);
    }

    .js .sunrise__y {
      transform: translateY(100%);
    }

    .js .sunrise__sun {
      rotate: -90deg;
    }

    .js .sunrise__arc path {
      stroke-dashoffset: 0;
      clip-path: inset(0 100% 0 0);
    }

    .js .sunrise .sunrise__step[data-reveal] {
      opacity: 0.25;
      transform: none;
      transition: opacity 500ms var(--ease-out);
    }

    .js .sunrise__num {
      color: transparent;
      -webkit-text-stroke: 2px var(--color-cream-muted);
      transition:
        color 500ms var(--ease-out),
        -webkit-text-stroke-color 500ms var(--ease-out);
    }

    .js .sunrise.is-in .sunrise__x {
      animation: sun-x var(--dur-sunrise) linear forwards;
    }

    .js .sunrise.is-in .sunrise__y {
      animation: sun-y var(--dur-sunrise) var(--ease-out-quad) forwards;
    }

    .js .sunrise.is-in .sunrise__sun {
      animation: sun-turn var(--dur-sunrise) var(--ease-out) forwards;
    }

    .js .sunrise.is-in .sunrise__arc path {
      animation: arc-draw var(--dur-sunrise) linear forwards;
    }

    /* Step n lights up when the sun is above it: t = n / 3 of the travel */
    .js .sunrise.is-in .sunrise__step[data-reveal] {
      opacity: 1;
      transition-delay: calc(var(--n) * var(--dur-sunrise) / 3);
    }

    .js .sunrise.is-in .sunrise__num {
      color: var(--color-accent);
      -webkit-text-stroke-color: transparent;
      transition-delay: calc(var(--n) * var(--dur-sunrise) / 3);
    }
  }

  /* ---------- FAQ: answers unfold ---------- */

  .faq {
    interpolate-size: allow-keywords;
  }

  .faq__item::details-content {
    height: 0;
    overflow: clip;
    transition:
      height 300ms var(--ease-out),
      content-visibility 300ms allow-discrete;
  }

  .faq__item[open]::details-content {
    height: auto;
  }

  /* ---------- Footer: the sun comes up from behind as the footer scrolls in ---------- */

  @supports (animation-timeline: view()) {
    .site-footer__sun {
      animation: footer-sun linear both;
      animation-timeline: view();
      animation-range: entry 0% entry 100%;
    }
  }
}

@keyframes sun-spin-in {
  from {
    opacity: 0;
    transform: rotate(-200deg) scale(0.4);
  }
}

@keyframes char-rise {
  from {
    opacity: 0;
    transform: translateY(0.5em) rotate(6deg);
  }
}

@keyframes dot-drop {
  from {
    opacity: 0;
    transform: translateY(-1.2em);
  }
}

@keyframes rise {
  from {
    opacity: 0;
    transform: translateY(24px);
  }
}

@keyframes marquee {
  to {
    transform: translateX(-100%);
  }
}

@keyframes sun-x {
  from { transform: translateX(0); }
  to { transform: translateX(100%); }
}

@keyframes sun-y {
  from { transform: translateY(100%); }
  to { transform: translateY(0); }
}

@keyframes sun-turn {
  from { rotate: -90deg; }
  to { rotate: 180deg; }
}

@keyframes arc-draw {
  from { clip-path: inset(0 100% 0 0); }
  to { clip-path: inset(0 0 0 0); }
}

@keyframes footer-sun {
  from {
    translate: 0 70%;
    rotate: -40deg;
  }
}

@keyframes deal-in {
  from {
    opacity: 0;
    translate: 0 120px;
    rotate: -12deg;
    scale: 0.92;
  }
}

@keyframes status-pulse {
  0% { opacity: 0.7; transform: scale(1); }
  70%, 100% { opacity: 0; transform: scale(2.6); }
}

/* Reduced motion: the marquee becomes a plain wrapped list, the reel scrolls by hand */
@media (prefers-reduced-motion: reduce) {

  .marquee {
    flex-wrap: wrap;
    padding-inline: var(--gutter);
    -webkit-mask: none;
    mask: none;
  }

  .marquee__track {
    flex-wrap: wrap;
    white-space: normal;
    row-gap: var(--space-3);
  }

  .marquee__track[aria-hidden="true"] {
    display: none;
  }
}
