/* The close's tunnel (index.html #download, close-tiles.js). Written from scratch for this page.
   A pinned stage starts as the page's ground with the app icon, small, in its exact center. Scrolling: real app screens come out
   of the center along their own rays and fly past (each one grows and slides outward, like going through a tunnel of screens,
   and fades as it leaves the edges) while the icon grows to its resting size and moves to its place; then the close's words
   settle in around it with the page's shared spring (motion.css tokens). The screens are gone before the words begin, so
   nothing sits behind the text. Everything is transform and opacity.
   - Default CSS (no scroll-driven animation, Reduce Motion, short windows) = the close alone: the screen layer is display:none,
     the icon is full size, the words are in place.
   - Chrome, Edge, Safari: the track is ~ (stage + --ct-pin) tall, the stage is sticky, and every piece rides one named view
     timeline (--ct) on the track. Each piece has its slice of the pin in percent (--r0 to --r1 on the piece): the icon grows 0 to 66 and rises to its place 52 to 72,
     the screens start 0 to 30 and fly for 40 each (the last is gone at 70), the words 70 to 97, so the last 3% holds the finished close.
   - Firefox (html.mo-once, motion.js): the same sequence plays once over ~2.4 s (--ct-ms per percent) when the close first
     shows, not scrubbed. */
.close {
  --ct-w: clamp(150px, min(15vw, 24svh), 300px);   /* a screen's width at rest (phone stills are 4:5; the desktop shots are wider) */
  --ct-s0: .07;     /* a screen's scale where it leaves the center (it starts tiny, behind the icon) */
  --ct-xk: 1; --ct-yk: 1;   /* stretch the rays sideways / up and down (phones fly mostly up and down, so the screens stay in view longer) */
  --ct-s1: 3.2;     /* ...and where it leaves the page: past the edges, faded by then */
  --ct-icon-s: .54; /* the icon's size at the start, as a share of its resting 120 px (about 65 px) */
  --ct-pin: 140svh; /* how long the stage stays pinned ([closebanner] was 170svh: the words come sooner) */
  --ct-ms: 24ms;    /* the one-shot fallback: one percent of the sequence (100 of them = 2.4 s) */
  --ct-stage-h: calc(100svh - var(--film-top, 0px) - var(--film-bottom, 0px));
}
.close-tiles { display: none; }
.close-wrap { position: relative; z-index: 2; }

/* ---- the layer's own look (shared by both modes) ---- */
.ct-screen {
  position: absolute; inset: 0; margin: auto; width: var(--ct-w); aspect-ratio: 4 / 5; border-radius: clamp(8px, 1vw, 14px); overflow: hidden; background: var(--t-to);
  box-shadow: 0 0 0 1px rgba(255, 255, 255, .12), 0 18px 40px -18px rgba(0, 0, 0, .7); opacity: 0;
}
.ct-screen.is-wide { width: calc(var(--ct-w) * 1.7); aspect-ratio: 16 / 10; }
.ct-screen img { display: block; width: 100%; height: 100%; object-fit: cover; }

/* a screen: the same ray, in screen-widths (--x, --y), scales up as it flies, so it slides outward the way a real screen would
   as it comes toward you (the farther along, the faster); it fades in just after it leaves the center and out as it passes the edges */
@keyframes ct-fly {
  from { transform: translate3d(calc(var(--x) * var(--ct-xk) * var(--ct-w) * var(--ct-s0)), calc(var(--y) * var(--ct-yk) * var(--ct-w) * var(--ct-s0)), 0) scale(var(--ct-s0)); }
  to { transform: translate3d(calc(var(--x) * var(--ct-xk) * var(--ct-w) * var(--ct-s1)), calc(var(--y) * var(--ct-yk) * var(--ct-w) * var(--ct-s1)), 0) scale(var(--ct-s1)); }
}
@keyframes ct-screen-opacity { 0% { opacity: 0; } 14% { opacity: .85; } 66% { opacity: .95; } 100% { opacity: 0; } }
@keyframes ct-icon-scale { from { scale: var(--ct-icon-s); } to { scale: 1; } }
@keyframes ct-icon-move { from { translate: var(--ct-icon-dx, 0px) var(--ct-icon-dy, 0px); } to { translate: 0 0; } }   /* ([closebanner] + dx: its place is on the card's left now) */
/* [closebanner] the card grows out of the icon's own box (--cb-t/r/b/l, the icon's insets in the card: close-tiles.js) to the whole card */
@keyframes ct-card { from { clip-path: inset(var(--cb-t, 45%) var(--cb-r, 45%) var(--cb-b, 45%) var(--cb-l, 45%) round 20px); opacity: 0; } 6% { opacity: 1; } to { clip-path: inset(0 round 28px); opacity: 1; } }   /* (unseen until its slice starts: no dark square waiting where the icon lands) */
@keyframes ct-fade { from { opacity: 0; } to { opacity: 1; } }
@keyframes ct-glow { from { opacity: 1; } to { opacity: 0; } }
@keyframes ct-words { from { opacity: 0; transform: translate3d(0, var(--mo-dist), 0); pointer-events: none; } to { opacity: 1; transform: none; pointer-events: auto; } }

/* the pieces' slices of the sequence ([closebanner]: the card between the icon and the words, all a little sooner) */
.close-icon { --r0: 0; --r1: 60; --m0: 48; --m1: 70; }   /* grows 0 to 60, flies from the center to its place on the card 48 to 70 */
.close-media { --r0: 60; --r1: 80; }                     /* the card grows out of the icon's box */
.close-copy .eyebrow { --r0: 72; --r1: 82; }
.close-copy h2 { --r0: 75; --r1: 85; }
.close-copy .lead { --r0: 78; --r1: 88; }
.close-body > .btn { --r0: 83; --r1: 92; }
.close-fine { --r0: 86; --r1: 95; }

/* ---- the stage's shared structure ---- */
@media (prefers-reduced-motion: no-preference) and (min-height: 640px) {
  @supports (animation-timeline: view()) {
    .close { padding-top: 0; --sec-bg: none; }
    .close-track {
      height: calc(var(--ct-stage-h) + var(--ct-pin));
      view-timeline: --ct block; view-timeline-inset: var(--film-top, 0px) var(--film-bottom, 0px);
    }
    .close-stage { position: sticky; top: var(--film-top, 0px); height: var(--ct-stage-h); display: grid; place-items: center; overflow: clip; margin-inline: calc(-1 * var(--pad-x)); padding-inline: var(--pad-x); }   /* (full width: the section pads its sides) */
    @media (min-width: 700px) { html:not(.in-film) .close-track { margin-bottom: -120px; } }   /* the footer rides up a little over the stage's empty lower part */
    html:not(.in-film) .close-stage { padding-top: var(--head-h, 68px); --ct-top: var(--head-h, 68px); }
    .close-stage::before { content: ""; position: absolute; inset: 0; pointer-events: none; background: radial-gradient(50% 40% at 50% 46%, var(--t-glow) 0%, transparent 70%); mix-blend-mode: lighten; }
    .close-tiles { display: block; position: absolute; inset: var(--ct-top, 0px) 0 0; z-index: 1; pointer-events: none; }   /* (below the sticky header, so the screens fly out of the close's center) */

    .ct-screen {
      animation: ct-fly both cubic-bezier(.55, .085, .68, .53), ct-screen-opacity both linear; animation-timeline: --ct, --ct;
      animation-range: contain calc(var(--r0) * 1%) contain calc(var(--r1) * 1%);
    }
    /* the icon: starts small in the exact center, grows to its size and settles at its place in the finished close */
    .close-icon {
      animation: ct-icon-scale both cubic-bezier(.4, 0, .2, 1), ct-icon-move both cubic-bezier(.45, 0, .2, 1); animation-timeline: --ct, --ct;
      animation-range: contain calc(var(--r0) * 1%) contain calc(var(--r1) * 1%), contain calc(var(--m0) * 1%) contain calc(var(--m1) * 1%);
    }
    .close-icon::before {
      content: ""; position: absolute; inset: -110%; border-radius: 50%; pointer-events: none;
      background: radial-gradient(closest-side, rgba(255, 175, 67, .5), rgba(255, 175, 67, .16) 55%, rgba(255, 175, 67, 0));
      animation: ct-glow both linear; animation-timeline: --ct; animation-range: contain calc(var(--m0) * 1%) contain calc(var(--m1) * 1%);
    }
    /* [closebanner] the card grows out of the icon (phones: it fades in, the footage sits above the words there) */
    .close-media {
      animation: ct-card both cubic-bezier(.65, 0, .35, 1); animation-timeline: --ct;
      animation-range: contain calc(var(--r0) * 1%) contain calc(var(--r1) * 1%);
    }
    @media (max-width: 760px) { .close-media { animation-name: ct-fade; } }
    /* the words rise in around it, one after another (backwards only: after the range the plain styles take over, so the button's hover still works) */
    .close-copy .eyebrow, .close-copy h2, .close-copy .lead, .close-body > .btn, .close-fine {
      animation: ct-words backwards var(--mo-ease); animation-timeline: --ct; animation-range: contain calc(var(--r0) * 1%) contain calc(var(--r1) * 1%);
    }
    /* a keyboard user who tabs to the button before scrolling gets the words at once */
    .close-wrap:has(:focus-visible) :is(.eyebrow, h2, .lead, .btn, .close-fine) { animation: none; }

    @media (max-width: 699px) {
      .close { --ct-w: min(36vw, 22svh); --ct-xk: .5; --ct-yk: 1.35; --ct-s1: 2.6; --ct-pin: 120svh; }
      .ct-screen:nth-child(even) { display: none; }   /* half the stream (every other screen, so it still runs the whole way) */
      .close-stage { place-items: end center; padding-bottom: 12px; }   /* (Q, Oct 10, iPhone: "too much space" under the card) phones: the card rests at the stage's foot, any spare height goes above it */
      /* [closefit] (Oct 18) a phone's card (footage on top, words under it) is taller than a phone's screen: the one-screen sticky stage
         cut off the button's lower half and everything under it. Here the stage grows to its card and isn't pinned; the stream of
         screens still plays on the scroll and is clipped only at the sides */
      .close-track { height: auto; }
      .close-stage { position: relative; height: auto; min-height: var(--ct-stage-h); overflow: visible; overflow-x: clip; }
    }
  }
}

/* ---- Firefox (no scroll-driven animations): the same sequence, once, when the close first shows ---- */
@media (prefers-reduced-motion: no-preference) and (min-height: 640px) {
  html.mo-once .close { padding-top: 0; --sec-bg: none; }
  html.mo-once .close-stage { position: relative; min-height: var(--ct-stage-h); display: grid; place-items: center; overflow: clip; margin-inline: calc(-1 * var(--pad-x)); padding-inline: var(--pad-x); }
  html.mo-once:not(.in-film) .close-stage { padding-top: var(--head-h, 68px); --ct-top: var(--head-h, 68px); }
  html.mo-once .close-tiles { display: block; position: absolute; inset: var(--ct-top, 0px) 0 0; z-index: 1; pointer-events: none; visibility: hidden; }
  html.mo-once .close.mo-in .close-tiles { visibility: visible; }
  html.mo-once .close.mo-in :is(.ct-screen, .close-copy .eyebrow, .close-copy h2, .close-copy .lead, .close-body > .btn, .close-fine) {
    animation-delay: calc(var(--r0) * var(--ct-ms)); animation-duration: calc((var(--r1) - var(--r0)) * var(--ct-ms));
  }
  html.mo-once .close.mo-in .ct-screen { animation: ct-fly both cubic-bezier(.55, .085, .68, .53), ct-screen-opacity both linear; }
  html.mo-once .close.mo-in .close-icon {
    animation: ct-icon-scale calc((var(--r1) - var(--r0)) * var(--ct-ms)) cubic-bezier(.4, 0, .2, 1) calc(var(--r0) * var(--ct-ms)) both,
      ct-icon-move calc((var(--m1) - var(--m0)) * var(--ct-ms)) cubic-bezier(.45, 0, .2, 1) calc(var(--m0) * var(--ct-ms)) both;
  }
  html.mo-once .close .close-media { clip-path: inset(var(--cb-t, 45%) var(--cb-r, 45%) var(--cb-b, 45%) var(--cb-l, 45%) round 20px); opacity: 0; }
  html.mo-once .close.mo-in .close-media { animation: ct-card calc((var(--r1) - var(--r0)) * var(--ct-ms)) cubic-bezier(.65, 0, .35, 1) calc(var(--r0) * var(--ct-ms)) both; }
  @media (max-width: 760px) { html.mo-once .close .close-media { clip-path: none; opacity: 0; } html.mo-once .close.mo-in .close-media { animation-name: ct-fade; } }
  html.mo-once .close.mo-in .close-icon::before {
    content: ""; position: absolute; inset: -110%; border-radius: 50%; pointer-events: none;
    background: radial-gradient(closest-side, rgba(255, 175, 67, .5), rgba(255, 175, 67, .16) 55%, rgba(255, 175, 67, 0));
    animation: ct-glow calc((var(--m1) - var(--m0)) * var(--ct-ms)) linear calc(var(--m0) * var(--ct-ms)) both;
  }
  html.mo-once .close.mo-in :is(.close-copy .eyebrow, .close-copy h2, .close-copy .lead, .close-body > .btn, .close-fine) { animation-name: ct-words; animation-fill-mode: backwards; animation-timing-function: var(--mo-ease); animation-timeline: auto; }
  @media (max-width: 699px) {
    html.mo-once .close { --ct-w: min(36vw, 22svh); --ct-xk: .5; --ct-yk: 1.35; --ct-s1: 2.6; }
    html.mo-once .ct-screen:nth-child(even) { display: none; }
    html.mo-once .close-stage { place-items: end center; padding-bottom: 12px; }
    html.mo-once .close-stage { overflow: visible; overflow-x: clip; }   /* [closefit] */
  }
}
