/* ---------------------------------------------------------------------------
   Motion. Everything here is opt-in behind `.js`, so without JavaScript the
   page renders complete and static rather than blank.
--------------------------------------------------------------------------- */

/* Page entrance -------------------------------------------------------- */

.js .content {
  animation: page-in 600ms var(--e-out) both;
}

.js body.is-leaving .content,
.js body.is-leaving .nav,
.js body.is-leaving .footer {
  opacity: 0;
  transition: opacity 380ms var(--e-inout);
}

@keyframes page-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}

/* Scroll reveal -------------------------------------------------------- */

.js .reveal {
  opacity: 0;
  transform: perspective(700px) translateY(46px) rotateX(-5deg);
  transform-origin: 50% 100%;
  transition: opacity var(--t-content) var(--e-out),
              transform var(--t-content) var(--e-out);
  will-change: opacity, transform;
}

.js .reveal.is-in {
  opacity: 1;
  transform: none;
  will-change: auto;
}

.js .reveal.d1 { transition-delay: 140ms; }
.js .reveal.d2 { transition-delay: 280ms; }
.js .reveal.d3 { transition-delay: 420ms; }

/* Masked line reveal for headings -------------------------------------- */

.js .split { --line-delay: 90ms; }

.js .split .line {
  display: block;
  /* The mask has to clear the descenders of the display face: at a tight
     line-height the box ends on the baseline and the tails of g/p/y get sliced
     off. The padding opens the mask, the negative margin gives the space back
     so the vertical rhythm is unchanged. */
  --descender: 0.26em;
  overflow: hidden;
  padding-bottom: var(--descender);
  margin-bottom: calc(var(--descender) * -1);
}

.js .split .line > span {
  display: block;
  /* Must clear the taller mask, not just its own box. */
  transform: translateY(135%);
  transition: transform 1000ms var(--e-out);
  transition-delay: calc(var(--i, 0) * var(--line-delay));
}

.js .split.is-in .line > span { transform: none; }

/* Media reveal: the image scales back as its mask opens ---------------- */

.js .media-reveal .ph {
  clip-path: inset(0 0 100% 0);
  transition: clip-path 1200ms var(--e-out);
}

.js .media-reveal .ph img {
  transform: scale(1.12);
  transition: transform 1600ms var(--e-out);
}

.js .media-reveal.is-in .ph { clip-path: inset(0 0 0 0); }
.js .media-reveal.is-in .ph img { transform: none; }

/* Magnetic targets keep their own transform channel -------------------- */

.js .magnetic {
  transition: transform 520ms var(--e-out);
}

.js .magnetic.is-pulled {
  transition: transform 120ms linear;
}

/* Line-drawing rules --------------------------------------------------- */

.js .rule-in {
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 900ms var(--e-inout);
}

.js .rule-in.is-in { transform: scaleX(1); }

/* Marquee-free counters ------------------------------------------------ */

.js .count-in { font-variant-numeric: tabular-nums; }

/* ------------------------------------------------------- reduced motion */

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }

  .js .content { animation: none; }
  .js body.is-leaving .content,
  .js body.is-leaving .nav,
  .js body.is-leaving .footer { opacity: 1; transition: none; }

  .js .reveal,
  .js .reveal.is-in {
    opacity: 1;
    transform: none;
    transition: none;
  }

  .js .split .line > span { transform: none; transition: none; }

  .js .media-reveal .ph { clip-path: none; transition: none; }
  .js .media-reveal .ph img { transform: none; transition: none; }

  .js .rule-in { transform: none; transition: none; }

  .preloader { display: none; }
  .cursor { display: none; }

  .card__link:hover .ph img { transform: none; }
  .card__frame .ph img { transition: none; }

  .drawer,
  .drawer.is-open,
  .drawer__item a,
  .drawer__veil { transition: none; }

  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
}
