/* ---------------------------------------------------------------------------
 * Cache-busted by WOOLIE_VERSION (woolie/settings.py). The token is stamped onto
 * this file's URL by woolie/storage.py, so there is no query string to write in
 * the template. If you EDIT this file, BUMP WOOLIE_VERSION - otherwise the URL is
 * byte-identical after the deploy and returning users keep the cached copy.
 * (The rollup bundles are keyed to woolie_frontend/package.json instead.)
 * ------------------------------------------------------------------------ */
/* FILE: view-transitions.css
   DESCRIPTION: Page-to-page transitions (the cross-document View Transition API), so
                moving between Woolie pages - feed to Dashboard, profile to Patterns -
                animates instead of blinking. Plan:
                woolie-planning/plans/page-view-transitions-plan.md

   BOTH PAGES MUST OPT IN, so this file is linked from every base layout a user moves
   between: templates/woolie/head.html (base.html, base_no_rightbar.html and the rest)
   and templates/allauth/layouts/base.html (login, signup, password reset). A page
   without it just navigates normally. Nothing breaks.

   No JavaScript and nothing for the Svelte components to do: the incoming page is shown
   LIVE during the fade, so content that mounts on DOMContentLoaded or arrives by fetch
   appears inside the fade, the same way it appears without one.

   Browsers without cross-document support (Firefox, older Safari) ignore all of this. */

/* Opt in only when motion is welcome. Under prefers-reduced-motion: reduce the page never
   opts in, so navigation is the instant swap the user asked their system for. (Not
   `animation: none` on the pseudo-elements: that still captures and runs a transition,
   only without motion.) */
@media (prefers-reduced-motion: no-preference) {
  @view-transition {
    navigation: auto;
  }
}

/* ---- Chrome that holds still ----
   The site's bars are captured on their own, so they stay put while the content column
   changes beneath them.

   NAMED ONLY WHILE A TRANSITION RUNS (:active-view-transition), never at rest. A named
   element is captured as a separate layer, and the feed's fixed overlays, #modalDiv and
   the #feedWrapper z-index arrangement must not meet any new layering in normal use.

   Each bar exists once per page. Two RENDERED elements sharing a name would abort the
   transition, so never put one of these names on anything repeated. */
:root:active-view-transition .mobile-navbar {
  view-transition-name: site-navbar;
}

:root:active-view-transition .wool-rightbar {
  view-transition-name: site-rightbar;
}

/* Desktop only. Below 992px the left bar is a Bootstrap offcanvas: its panel is fixed and
   slides from off-screen, and capturing the aside would carry it along in the snapshot. */
@media (min-width: 992px) {
  :root:active-view-transition .wool-leftbar {
    view-transition-name: site-leftbar;
  }
}

/* ---- The content ----
   The old page leaves quickly, and the new one arrives with a softer fade and a 6px rise,
   on the long-tailed ease-out the dialogs use (woolie-modal.css .modal-motion,
   ModalOverlay.svelte), so a page change and a dialog feel like the same site. */
::view-transition-old(root) {
  animation: 450ms cubic-bezier(0.4, 0, 1, 1) both vt-fade-out;
}

::view-transition-new(root) {
  animation: 460ms cubic-bezier(0.16, 1, 0.3, 1) both vt-rise-in;
}

/* The bars that are the same on both pages swap in place rather than crossfade. The
   rightbar keeps the default: it exists on base.html pages only, so moving to or from a
   base_no_rightbar page fades it out or in. */
::view-transition-group(site-navbar),
::view-transition-group(site-leftbar) {
  animation-duration: 0s;
}

@keyframes vt-fade-out {
  to {
    opacity: 0;
  }
}

@keyframes vt-rise-in {
  from {
    opacity: 0;
    transform: translateY(6px);
  }
}
