/* The interaction set (ECHOSTUDIO-199, Iris's DIRECTION-199.md).
 *
 * Slow, warm and certain: every motion should feel like breathing out, and
 * anything noticed as an effect is too much. Motion belongs to titles, images
 * and the change between pages. Body copy keeps its fade.
 *
 * Everything here stops under prefers-reduced-motion. The script that sets
 * `mv` on <html> never sets it then, and the rules that hold anything back all
 * hang off `mv`, so nothing is ever left hidden.
 *
 * The first-visit preloader was dropped on 26 Sep: Beacon measured it at
 * +201ms desktop LCP on the home page, over the 100ms limit. */

/* ---- 1. page transition: oreana's line, over the old page ----------------
 * PageTransitions.tsx animates the clip-path on the new page. The browser's
 * own crossfade is switched off so the old page stays exactly where it is. */
::view-transition-old(root),
::view-transition-new(root) { animation: none !important; mix-blend-mode: normal; }
::view-transition-group(root) { z-index: auto !important; }
::view-transition-image-pair(root) { isolation: isolate; will-change: clip-path; z-index: 1; }
::view-transition-new(root) { z-index: 10000; }
::view-transition-old(root) { z-index: 1; }

/* ---- 3. title lines rise out of a mask -----------------------------------
 * site-behaviours splits titles into lines. On a first load, titles already
 * on screen are never touched, so nothing the page paints first is hidden
 * (Beacon measured what that cost LCP). During a client-side page change the
 * new page's titles are held back until they are split, with a failsafe: if
 * the script never gets there, they show after 2.5s regardless. */
@keyframes mv-show { to { visibility: visible; } }
html.mv[data-vt] main :is(h1.t-display, h1.t-title, h2.t-title, h2.t-display):not([data-lines]):not(.rv):not(.rv-h) {
  visibility: hidden;
  animation: mv-show 0s 2.5s forwards;
}
/* The titles are set solid (line-height 1), and Newsreader's accented capitals
 * rise .21em above the line box while descenders stop just inside it. The mask
 * was the line box plus .08em below, so accents were cut off once a line
 * landed, and a line pushed down 105% still showed its ascenders and accents
 * along the bottom before it rose (ECHOSTUDIO-207). A clip-path reaches .25em
 * above and .12em below the line without moving the layout, and the line
 * starts .45em further down, where nothing of it shows. */
[data-lines] .ln { display: block; clip-path: inset(-.25em -.1em -.12em -.1em); }
[data-lines] .ln-in {
  display: block;
  transform: translateY(calc(100% + .45em));
  transition: transform .9s cubic-bezier(0.2, 0.7, 0.2, 1);
  transition-delay: calc(var(--ln, 0) * 70ms);
}
[data-lines].in .ln-in { transform: none; }

/* ---- 5. hovers: pointer devices only ------------------------------------- */
@media (hover: hover) and (pointer: fine) {
  /* The CTA arrow leaves to the right and comes back in from the left. */
  .btn-cta:hover::after { transform: none; animation: mv-arrow .5s cubic-bezier(0.2, 0.7, 0.2, 1); }
  @keyframes mv-arrow {
    0% { background-position: 50% 50%; }
    45% { background-position: calc(50% + 2.4rem) 50%; }
    45.1% { background-position: calc(50% - 2.4rem) 50%; }
    100% { background-position: 50% 50%; }
  }

  /* Inline links in her words: the underline draws in from the left. */
  main :is(.prose, .sys-prose, .mt-body, .t-lede) a:not([class]) {
    text-decoration-color: currentColor;
    background: linear-gradient(currentColor, currentColor) 0 100% / 0 var(--space-hair) no-repeat;
    transition: background-size .45s cubic-bezier(0.2, 0.7, 0.2, 1), text-decoration-color .2s;
  }
  main :is(.prose, .sys-prose, .mt-body, .t-lede) a:not([class]):hover {
    text-decoration-color: transparent;
    background-size: 100% var(--space-hair);
  }

  /* Card photographs: a slow 1.04 inside their frame. */
  .tile .im img, .feat .im img, .jtile .im img, .mega-tile img, .photorow-im img {
    transition: transform 1.2s cubic-bezier(0.2, 0.7, 0.2, 1);
  }
  .tile:hover .im img, .feat:hover .im img, .jtile:hover .im img, .mega-tile:hover img, .photorow-im:hover img {
    transform: scale(1.04);
  }
  .tile:hover .im img.plx, .feat:hover .im img.plx, .jtile:hover .im img.plx {
    transition: transform 1.2s cubic-bezier(0.2, 0.7, 0.2, 1);
    transform: translate3d(0, var(--plx-y, 0px), 0) scale(calc(var(--plx-s, 1) * 1.04));
  }
  .tile .arr, .feat .arr, .jtile .arr { transition: transform .5s cubic-bezier(0.2, 0.7, 0.2, 1); }
  .tile:hover .arr, .feat:hover .arr, .jtile:hover .arr { transform: translateX(6px); }

  /* "Worth knowing" rows: the disc fills teal and the arrow eases along. */
  .rowlist > li > a.rowlist-ico:hover .ico-disc { background: var(--hue-teal-deep); color: var(--hue-parchment); }
  .rowlist > li > a.rowlist-ico:hover .arr { transform: translateX(6px); }
}

/* ---- reduced motion: all of it off -------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  [data-lines] .ln-in { transform: none; transition: none; }
  .btn-cta:hover::after { animation: none; }
  .ico-disc, .rowlist-ico .arr { transition: none; }
}
