/* switch.css — the Orionix page switch, verbatim numbers.

   Source of truth: orionix.framer.website's compiled router config
   (script_main.2dzOGF4g.mjs), read 2026-08-29:
     exit  : opacity->0, scale->0.9, y->-10%, tween 1s, ease [.8,0,.2,1]
     enter : from opacity 0, y +30%, hard-edge wipe; tween 1s, delay .01s,
             same ease. Both run together — the new page rises as a solid
             sheet over the old one shrinking beneath it.

   Mechanism: cross-document View Transitions (same-origin MPA navigation,
   Chrome 126+ / Safari 18.4+). Each page still boots as its own document —
   no SPA router, nothing about per-page JS changes. Browsers without the
   API fall back to a plain instant navigation. The instant-load half lives
   in site-shell.js (speculation-rules prerender on hover intent).

   The enter sheet holds full opacity from ~18% in: the reference reveals a
   solid sheet (its mask is a hard edge, width 0%), so a 1s linear fade-in
   would read as a translucent ghost the reference never shows. */

@view-transition {
  navigation: auto;
}

/* Both snapshots are viewport-sized; % translate = % of viewport. */
::view-transition-old(root) {
  animation: kls-switch-exit 1000ms cubic-bezier(0.8, 0, 0.2, 1) both;
}

::view-transition-new(root) {
  animation: kls-switch-enter 1000ms cubic-bezier(0.8, 0, 0.2, 1) 10ms both;
}

@keyframes kls-switch-exit {
  from { opacity: 1; transform: none; }
  to   { opacity: 0; transform: translateY(-10%) scale(0.9); }
}

/* The enter is a WIPE, not a pre-cut sheet — the reference's mask
   (wipe, angle 270, hard edge) reveals the incoming page bottom-to-top
   across the FULL viewport while the content settles upward from +30%.
   The visible reveal edge therefore sweeps the whole screen over the
   second (position + clip combined), instead of a sheet that already
   covers the bottom 70% and only crawls the top band — which left the
   old page hanging visibly "swiping up" at the top (Giovani's catch). */
@keyframes kls-switch-enter {
  from { opacity: 1; transform: translateY(30%); clip-path: inset(100% 0 0 0); }
  to   { opacity: 1; transform: none; clip-path: inset(0 0 0 0); }
}

/* The ground the old page shrinks against — the site's own black, never a
   UA-white flash. */
::view-transition {
  background: #06070a;
}


/* The header does NOT ride the sheet — reference behaviour. Orionix's nav
   persists while pages swap beneath it; frame captures show the arriving
   page's header already at rest while the body still rises. Naming the
   header gives it its own snapshot group: it renders above both sheets,
   swaps instantly (no crossfade ghosting between the home and interior
   header variants), and reads as one continuous bar. */
.site-nav {
  view-transition-name: kls-header;
}

::view-transition-group(kls-header) {
  z-index: 10;
  animation: none;
}

::view-transition-old(kls-header) {
  display: none;
}

::view-transition-new(kls-header) {
  animation: none;
}

/* The bar-state handshake (site-shell's pageswap/pagereveal pair): the
   instant swap above is only continuous when BOTH pages wear the solid bar.
   The homepage never does — its header is an open gradient — so a switch
   out of home popped a black bar in at frame zero, and a switch back home
   vanished it just as hard. The shell stamps the outgoing bar state and the
   arriving page classes <html> with the matching choreography. */

/* Leaving home: no bar existed, so the interior bar LOWERS itself while the
   page lands — starts once the sheet is underway, rests just before it. */
html.kls-nav-drop ::view-transition-new(kls-header) {
  animation: kls-nav-drop 680ms cubic-bezier(0.22, 0.61, 0.21, 1) 240ms both;
}
@keyframes kls-nav-drop {
  from { transform: translateY(-110%); }
  to   { transform: none; }
}

/* Arriving home: the solid bar dissolves into the open hero instead of
   cutting to nothing. */
html.kls-nav-fade ::view-transition-old(kls-header) {
  display: block;
  animation: kls-nav-out 420ms ease both;
}
html.kls-nav-fade ::view-transition-new(kls-header) {
  animation: kls-nav-in 420ms ease 120ms both;
}
@keyframes kls-nav-out { to { opacity: 0; } }
@keyframes kls-nav-in { from { opacity: 0; } }

/* Throttled device (kls-lowpower, set by the refused-autoplay tell): the
   1s dual-sheet switch drops frames and reads as flash glitches there. The
   swap goes instant instead - still the site's own black underneath, never
   a broken half-animation. */
html.kls-lowpower ::view-transition-old(root),
html.kls-lowpower ::view-transition-new(root),
html.kls-lowpower.kls-nav-drop ::view-transition-new(kls-header),
html.kls-lowpower.kls-nav-fade ::view-transition-old(kls-header),
html.kls-lowpower.kls-nav-fade ::view-transition-new(kls-header) {
  animation: none;
}

@media (prefers-reduced-motion: reduce) {
  ::view-transition-old(root),
  ::view-transition-new(root),
  html.kls-nav-drop ::view-transition-new(kls-header),
  html.kls-nav-fade ::view-transition-old(kls-header),
  html.kls-nav-fade ::view-transition-new(kls-header) {
    animation: none;
  }
}
