/* Making a cross-surah move look like one page rather than two.

   WHAT IS ACTUALLY BEING FIXED, and it is two complaints with one cause. A
   reader following a verse chip out of surah 8 into surah 26 leaves one
   document and enters another, and between them the browser paints white --
   masthead, panel and all -- before the new page arrives with the panel shut
   and slides it out again. Neither is a bug in any one file. Both are what a
   full document load looks like when the page it lands on is a study surface
   the reader had already arranged.

   Cross-document view transitions fix the first half here, and the second half
   is markup: routes/quran.py renders the panel with is-open already on it when
   the address carries a ?study=, so the transition's incoming snapshot has an
   open panel in it and there is no state left to animate. Both are the same
   flag, QURAN_VIEW_TRANSITIONS, because either alone reads worse than neither:
   a cross-fade that holds a shut panel where an open one was is a held
   mistake rather than a held page.

   PURE ENHANCEMENT, WHICH IS WHY THERE IS NO FALLBACK ANYWHERE. A browser that
   does not know @view-transition ignores the block and navigates exactly as it
   does today -- Firefox, at the time of writing, and every browser more than a
   year old. Nothing below changes a layout, a colour or a size; take the whole
   file away and every page computes what it computed before it existed.

   NAMED ELEMENTS ARE KEPT TO TWO, and the reason is a failure mode rather than
   taste: a view-transition-name that appears twice in one document makes the
   browser skip the transition entirely and silently. So the masthead, of which
   there is exactly one, and the open panel -- named through .is-open so that
   the five shut panels, which are rendered and merely invisible, never carry
   it. Everything else, the recite strip and the scrims included, rides the
   root cross-fade, which is the right treatment for content that is genuinely
   being replaced.

   WHY THE WHOLE FILE IS INSIDE ONE MEDIA QUERY. This is motion, and a reader
   who has asked for less of it must get the instant swap they have now. The
   universal transition clamp in base.css cannot reach ::view-transition
   pseudo-elements -- they are not in the document tree and no * selector
   matches them -- so the opt-in itself has to sit behind the preference, and
   the honest way to do that is to not opt in at all. */

@media (prefers-reduced-motion: no-preference) {
  @view-transition { navigation: auto; }

  /* The one band that is the same thing on both sides of the move: the
     wordmark, the search field the reader may have just used, the account
     chip. Holding it still is what makes the rest read as the page beneath it
     changing rather than the whole window being replaced.

     `.quran` AND NOT `.masthead` ALONE, and this cost a browser pin to find.
     A view-transition-name makes its element a stacking context, and on the
     LANDING page the masthead is position:static with z-index:auto -- so
     naming it there trapped the Arabic keyboard, which drops out of the
     masthead and had been painting in the root stacking context, underneath
     the relatively-positioned screenshot in <main>. The keyboard opened, the
     first letter typed, and the second key was unclickable: visible, enabled,
     and behind an image.

     On the study pages there is nothing to introduce. `.quran .masthead` is
     already position:sticky with z-index:92, which is already a stacking
     context -- section 1 of quran.css says so in as many words, because the
     display panel inside it resolves against that number. So the name is
     scoped to exactly the pages where it changes nothing about paint order,
     which are also the pages a reader crosses between: surah to surah, surah
     to the index, surah to a root page.

     The landing page keeps the root cross-fade, which is what it wants
     anyway: its masthead is a different shape from the study pages' and has
     no still position to hold. */
  .quran .masthead { view-transition-name: qs-masthead; }

  /* And the panel, but ONLY when it is open. Six panels are rendered on every
     surah page and five of them are shut at any moment; naming the element
     rather than the open state would put six copies of one name in the
     document and cost the transition altogether. */
  .tafsir.is-open .tafsir__panel { view-transition-name: qs-panel; }
  .reflections.is-open .reflections__panel { view-transition-name: qs-panel; }
  .wstudy.is-open .wstudy__panel { view-transition-name: qs-panel; }
  .lectures.is-open .lectures__panel { view-transition-name: qs-panel; }
  .hadith.is-open .hadith__panel { view-transition-name: qs-panel; }
  .notebook.is-open .notebook__panel { view-transition-name: qs-panel; }
}


/* ---- The mark that a new page is on its way --------------------------------

   AND THIS PART IS DELIBERATELY OUTSIDE THE MEDIA QUERY ABOVE, which is the
   one exception to this file's own rule and is argued rather than assumed.
   Everything above is decoration: it makes a move that already works look
   continuous, and a reader who asks for less motion is right to be given the
   instant swap instead. This is not decoration. It is the only thing on
   screen that says the press landed, during a wait that can run to a second
   and a half -- longer on a slow machine -- while the browser holds the old
   page and nothing else changes. Withholding information is not the same
   courtesy as withholding movement. So the mark appears for everyone, and
   only its SPIN is held back below.

   THE 400ms DELAY IS THE DESIGN. Most moves finish before it elapses and show
   nothing at all, which is what makes the mark mean something when it does
   appear: it is not "a page is loading", it is "this one is taking a while".
   No JavaScript timer anywhere -- depart.js adds a class and this waits.

   It rides the old page's transition snapshot and cross-fades out with it,
   which is correct: it belongs to the page being left. Centred, so it clears
   the masthead and the panel, both of which are separately named above and
   animate on their own. */

html.qs-departing::after {
  content: "";
  position: fixed;
  /* Centred without a transform, so nothing here is a containing block and
     nothing competes with the transition's own snapshots. */
  inset: 0;
  margin: auto;
  inline-size: 2rem;
  block-size: 2rem;
  border-radius: 50%;
  /* A ring, not a disc: it is a mark, not a veil, and the page behind it
     stays legible. The accent for the arc that leads, so the shape reads as
     an instrument of this site rather than a borrowed default. */
  border: 3px solid var(--rule);
  border-block-start-color: var(--accent);
  /* Above the ladder's ceiling at 97, below nothing that matters: this is the
     last thing drawn on a page that is leaving. */
  z-index: 98;
  /* It must never take a press. The reader may still click anything while the
     next page is coming, including the Back that cancels this one. */
  pointer-events: none;
  opacity: 0;
  animation: qs-depart-in 200ms var(--ease-calm) 400ms forwards;
}

@keyframes qs-depart-in {
  to { opacity: 1; }
}

/* The spin is the decorative half, and the only half held back: a reader who
   asked for less motion gets the same mark, standing still. It says the same
   thing -- something is happening and it is taking a moment -- without the
   part they declined. */
@media (prefers-reduced-motion: no-preference) {
  html.qs-departing::after {
    animation: qs-depart-in 200ms var(--ease-calm) 400ms forwards,
               qs-depart-spin 900ms linear 400ms infinite;
  }
}

@keyframes qs-depart-spin {
  to { transform: rotate(360deg); }
}
