/* ==========================================================================
   MOTION — the typographic layer

   Everything here animates TEXT, and everything here is CSS driving elements
   that JavaScript only ever creates once. No library, no runtime, no frames
   being computed in script.

   Three ideas, in the order a reader meets them:

     1. words rise out of their own line, one after the next
     2. the accented word in a heading draws its own rule underneath it
     3. the beds behind the sections drift against the scroll

   The restraint is the point. Every one of these is a single gesture per
   element, at editorial speed — nothing bounces, nothing springs, nothing
   arrives from off-screen left. The brief calls that slop and it is right.

   WP Phase 2 target: enqueued with the rest, no PHP of its own.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. WORDS RISE

   A heading is split into words by site-ui.js — once, at load, preserving
   the <em> inside it. Each word is a box that clips, holding a box that
   moves. The stagger is per WORD, not per letter: letters are a party trick
   and they wreck the wrap law, because a line can then break mid-word.

   The padding/margin pair is load-bearing. `overflow: hidden` on the clip box
   would otherwise shave descenders and the overhang of the italic — so the
   box is grown by 0.16em and pulled back by the same, which clips the rise
   without clipping the letterforms.
   -------------------------------------------------------------------------- */

.u-word {
  display: inline-block;
  overflow: hidden;
  padding-block: 0.16em;
  margin-block: -0.16em;
  /* Keeps the word sitting on the same baseline it had before it was split. */
  vertical-align: bottom;
}

.u-word__in {
  display: inline-block;
  transform: translateY(var(--word-y, 0));
}

@media (prefers-reduced-motion: no-preference) {
  .is-split .u-word__in {
    transition:
      transform var(--dur-slow) var(--ease-out),
      opacity var(--dur-slow) var(--ease-out);
    transition-delay: calc(var(--i, 0) * 48ms);
  }

  /* Before it is shown. 118% rather than 100% so the descenders of the line
     above cannot peek under the mask. */
  .is-split:not(.is-shown) .u-word__in {
    --word-y: 118%;
    opacity: 0;
  }
}

/* --------------------------------------------------------------------------
   2. THE ACCENT DRAWS ITS OWN RULE

   The italic word in every heading is the one thing the eye is meant to
   catch. It gets a rule that draws itself left to right once the word has
   landed — a printer's flourish, not a highlighter.

   `scaleX` on a pseudo-element rather than `background-size`, because a
   transform is composited and a background repaint is not.
   -------------------------------------------------------------------------- */

.c-head__title em,
.c-shop__title em,
.c-consult__title em,
.c-contact__title em,
.c-about__title em,
.c-hero__title-line em {
  position: relative;
}

@media (prefers-reduced-motion: no-preference) {
  .c-head__title em::after,
  .c-shop__title em::after,
  .c-consult__title em::after,
  .c-contact__title em::after,
  .c-about__title em::after,
  .c-hero__title-line em::after {
    content: "";
    position: absolute;
    inset-block-end: -0.06em;
    inset-inline: 0;
    block-size: var(--bw-rule);
    background: currentColor;
    opacity: 0.5;
    transform: scaleX(0);
    transform-origin: left;
    transition: transform 0.9s var(--ease-out);
    /* After the words: the longest heading is around eight words, so this
       clears the last of them. */
    transition-delay: 0.5s;
  }

  .is-shown em::after { transform: scaleX(1); }
}

/* --------------------------------------------------------------------------
   3. THE EYEBROW SETTLES

   The mono labels above each heading open out of a tighter tracking. It is
   two hundredths of an em — invisible as a movement, felt as the label
   arriving rather than being there.
   -------------------------------------------------------------------------- */

@media (prefers-reduced-motion: no-preference) {
  .c-head__index,
  .c-about__eyebrow,
  .c-shop__eyebrow {
    transition:
      letter-spacing 1s var(--ease-out),
      opacity var(--dur-slow) var(--ease-out);
  }

  .is-armed .c-head__index,
  .is-armed .c-about__eyebrow,
  .is-armed .c-shop__eyebrow {
    letter-spacing: calc(var(--tr-mono-wide) + 0.22em);
  }
}

/* --------------------------------------------------------------------------
   4. THE BEDS DRIFT AGAINST THE SCROLL

   Native scroll-driven animation: `animation-timeline: view()` ties the
   progress of the animation to the element's own passage through the
   viewport. No scroll listener, no rAF loop, no layout read on every frame —
   the compositor runs it.

   Behind `@supports`, because Firefox does not have it yet. Where it is
   missing the bed simply sits still, which is what it did before.
   -------------------------------------------------------------------------- */

@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    .c-bed .c-bed__wash {
      animation: bed-parallax linear both;
      animation-timeline: view();
      animation-range: entry 0% exit 100%;
    }

    /* The hero is pinned at the top of the document, so it never "enters" —
       it would sit at 0% progress forever. It keeps its own drift. */
    .c-hero .c-bed__wash { animation: bed-drift 46s var(--ease-inout) infinite alternate; }
  }
}

@keyframes bed-parallax {
  from { translate: 0 -6%; }
  to   { translate: 0 6%; }
}

/* --------------------------------------------------------------------------
   5. THE TIMELINE'S RULE DRAWS DOWN

   The hairline between video entries grows as the list is read, so the
   column reads as one continuous thing rather than five detached rows.
   -------------------------------------------------------------------------- */

@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    .c-entry {
      animation: entry-rule linear both;
      animation-timeline: view();
      animation-range: entry 10% entry 70%;
    }
  }
}

@keyframes entry-rule {
  from { opacity: 0.35; translate: 0 1.5rem; }
  to   { opacity: 1; translate: 0 0; }
}

/* --------------------------------------------------------------------------
   6. PHOTOGRAPHS MOVE INSIDE THEIR FRAMES

   The tour cards and the video stills drift a little against the scroll,
   inside a frame that does not move. It is the difference between a picture
   printed on a page and a picture seen through a window.

   The image is oversized by the same amount it travels, so the frame is
   never uncovered at either end of the range. 108% for a 4% drift each way
   leaves a percent in hand.

   Scroll-driven, so there is no listener and no frame loop: the compositor
   advances it against the scroll position and nothing runs on the main
   thread. Behind @supports, and behind reduced-motion.
   -------------------------------------------------------------------------- */

@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    .c-tours__frame,
    .c-entry__media {
      overflow: clip;
    }

    .c-tours__frame img,
    .c-entry__image {
      block-size: 108%;
      object-fit: cover;
      animation: photo-drift linear both;
      animation-timeline: view();
      animation-range: entry 0% exit 100%;
    }
  }
}

@keyframes photo-drift {
  from { translate: 0 -4%; }
  to   { translate: 0 4%; }
}

/* --------------------------------------------------------------------------
   7. THERE IS NO READING RULE UNDER THE SECTION HEAD

   There was, briefly: a hairline that filled as each section was crossed.
   It had to go. The accent word in every heading already draws its own rule,
   and the section rule landed NINE PIXELS below it — two horizontal lines
   under one heading, which is the double underline it looked like.

   One rule per heading. The accent keeps it, because it marks the word that
   matters rather than the block it sits in.
   -------------------------------------------------------------------------- */
