/* ============================================================================
   JETTISON site shell: first-visit loader + cross-page route curtain.
   Mechanics layer only; consumes _lib/tokens.css (semantic mode layer), so
   the loader and curtain always match the active color mode.
   Fail-open discipline: both elements are inert by default. The inline head
   bootstrap (stamped from _lib/head.html) opts the loader in once per tab
   session via html.intro-pending, and flags incoming routed navigations via
   html.route-entering. If JS never runs, neither element ever shows and the
   page content is fully visible.
   ========================================================================= */

/* ================= FIRST-VISIT LOADER =================
   display:none by default; only the head bootstrap's intro-pending class
   shows it, so a storage or script failure can never trap the page. */
#site-loader{position:fixed;inset:0;z-index:9000;display:none;place-items:center;
  overflow:hidden;background:var(--ground,#131210);color:var(--ink,#E9EBDF);
  visibility:hidden;pointer-events:none;transform:translateY(0);
  transition:transform var(--dur-slow,400ms) var(--ease-sig,cubic-bezier(0.45,0,0.15,1)),
    visibility 0s linear var(--dur-slow,400ms);}
html.intro-pending #site-loader{display:grid;visibility:visible;pointer-events:auto;
  animation:jlFailOpen .01s linear 3.4s forwards;}
html.intro-pending.intro-done #site-loader{visibility:hidden;pointer-events:none;
  transform:translateY(-102%);}
.sl-stage{position:relative;display:grid;place-items:center;}
.sl-mark{display:block;width:76px;height:auto;color:var(--ink,#E9EBDF);overflow:visible;}
.sl-mark path{fill:currentColor;}
/* stage separation liftoff: the released piece detaches and ascends.
   One shot, --dur-liftoff, --ease-sig. Units are SVG user units. */
.sl-piece{animation:jlLiftoff var(--dur-liftoff,600ms) var(--ease-sig,cubic-bezier(0.45,0,0.15,1)) 140ms 1 forwards;}
html.intro-done .sl-stage{opacity:0;transform:translateY(-10px);
  transition:opacity .16s ease,transform .26s var(--ease-sig,cubic-bezier(0.45,0,0.15,1));}
@keyframes jlLiftoff{from{transform:translateY(0);}to{transform:translateY(-15px);}}
@keyframes jlFailOpen{to{visibility:hidden;pointer-events:none;}}

/* ================= PAGE CURTAIN =================
   One canvas sheet covers the outgoing document (route-leaving) and clears
   upward off the incoming one (route-entering -> route-ready). Explicit
   rather than API-dependent so file:// previews and every supported
   browser get the same route motion. Fail-open at every step. */
#page-transition{position:fixed;inset:0;z-index:8500;overflow:hidden;
  background:var(--ground,#131210);
  border-top:1px solid var(--line,rgba(233,235,223,0.13));
  visibility:hidden;pointer-events:none;transform:translateY(101%);}
html.route-leaving #page-transition{visibility:visible;pointer-events:auto;transform:translateY(0);
  transition:transform var(--dur-slow,400ms) var(--ease-sig,cubic-bezier(0.45,0,0.15,1)),visibility 0s;}
html.route-entering #page-transition{visibility:visible;pointer-events:auto;transform:translateY(0);
  animation:jlRouteFailOpen .01s linear 1.6s forwards;}
html.route-entering.route-ready #page-transition{visibility:hidden;pointer-events:none;
  transform:translateY(-101%);
  transition:transform .52s var(--ease-sig,cubic-bezier(0.45,0,0.15,1)) .04s,visibility 0s linear .56s;}
html.route-reset #page-transition{transition:none!important;animation:none!important;}
@keyframes jlRouteFailOpen{to{visibility:hidden;pointer-events:none;}}

/* ================= REDUCED MOTION: both moments are no-ops ================= */
@media (prefers-reduced-motion:reduce){
  html.intro-pending #site-loader{display:none;animation:none;}
  #page-transition{display:none!important;transition:none!important;animation:none!important;}
}
