/* =========================================================================
   Rocket page transition (js/rocket-nav.js)

   Leaving a page: a rocket flies from the link, hits a screen edge, and the
   blast covers the screen before the browser navigates. Arriving: the page
   starts covered (html.rt-arriving, set before first paint by the <head> boot
   script) and opens from the same impact point.

   Its own file so the whole feature comes out cleanly: delete this, the
   script, and the four lines it added to each page's <head>.
   ========================================================================= */

/* Above everything: the nav (1000), the grain (1100) and the modals (1200). */
.rt-fx {
    position: fixed;
    inset: 0;
    z-index: 2147483000;
    overflow: hidden;
    pointer-events: none;
}

.rt-canvas {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
}

/* The blast wave: a circle growing from the impact point (the script sets the
   clip-path each frame) until it has swallowed the screen; then we navigate.
   The page's own ground colour, so it follows the lamp switch too. */
.rt-cover {
    position: absolute;
    inset: 0;
    background: var(--surface-0, #0d0d0d);
    clip-path: circle(0px at 50% 50%);
}

/* The negative margins put the element's CENTRE at its (0,0), so GSAP's x/y
   are the rocket's centre and rotation happens about it. */
.rt-rocket {
    position: absolute;
    left: 0;
    top: 0;
    width: 48px;
    height: 88px;
    margin: -44px 0 0 -24px;
    opacity: 0;
    visibility: hidden;
    will-change: transform;
}

.rt-rocket__art {
    position: relative;
    display: block;
    width: 100%;
    height: 100%;
    max-width: none;
    overflow: visible;
}

/* The flame hangs from the nozzle and sits behind the artwork. */
.rt-flame {
    position: absolute;
    left: 50%;
    top: 92%;
    width: 22px;
    height: 72px;
    margin-left: -11px;
    transform-origin: 50% 0;
}

.rt-flame::before {
    content: '';
    position: absolute;
    left: 50%;
    top: -14px;
    width: 76px;
    height: 76px;
    margin-left: -38px;
    border-radius: 50%;
    background: radial-gradient(circle, rgba(255, 176, 90, .55) 0%, rgba(255, 120, 40, 0) 70%);
}

.rt-flame span {
    position: absolute;
    left: 50%;
    top: 0;
    display: block;
    border-radius: 50% 50% 50% 50% / 24% 24% 76% 76%;
    transform-origin: 50% 0;
}

.rt-flame span:nth-child(1) {
    width: 22px;
    height: 72px;
    margin-left: -11px;
    background: radial-gradient(ellipse 50% 62% at 50% 22%, #ffd27a 0%, #ff8c3a 42%, rgba(255, 84, 30, .6) 70%, rgba(255, 60, 20, 0) 100%);
    filter: blur(1.6px);
}

.rt-flame span:nth-child(2) {
    width: 13px;
    height: 44px;
    margin-left: -6.5px;
    background: radial-gradient(ellipse 50% 60% at 50% 22%, #fffbea 0%, #ffe28e 48%, rgba(255, 170, 60, 0) 100%);
    filter: blur(.8px);
}

.rt-flame span:nth-child(3) {
    width: 6px;
    height: 20px;
    margin-left: -3px;
    background: #fffef7;
    filter: blur(.5px);
}

/* Sized per launch from the viewport (--fb), centred on its (0,0). */
.rt-fireball {
    --fb: 420px;
    position: absolute;
    left: 0;
    top: 0;
    width: var(--fb);
    height: var(--fb);
    margin: calc(var(--fb) / -2) 0 0 calc(var(--fb) / -2);
    border-radius: 50%;
    opacity: 0;
    background: radial-gradient(circle,
            #fffdf3 0%, #fff0c4 12%, #ffc766 26%, #ff8a2e 42%,
            rgba(232, 72, 28, .75) 56%, rgba(150, 40, 16, .35) 66%, rgba(90, 24, 10, 0) 74%);
    filter: blur(5px);
}

/* Radial tongues of flame; the fireball rotates as it grows, so they swirl. */
.rt-fireball::before {
    content: '';
    position: absolute;
    inset: 8%;
    border-radius: 50%;
    background: repeating-conic-gradient(from 0deg,
            rgba(255, 170, 70, 0) 0deg 14deg,
            rgba(255, 120, 40, .5) 18deg 22deg,
            rgba(255, 170, 70, 0) 26deg 34deg);
    -webkit-mask: radial-gradient(circle, transparent 30%, #000 46%, transparent 70%);
    mask: radial-gradient(circle, transparent 30%, #000 46%, transparent 70%);
    filter: blur(6px);
    mix-blend-mode: screen;
}

.rt-flash {
    position: absolute;
    inset: 0;
    opacity: 0;
    background: radial-gradient(circle at var(--fx, 50%) var(--fy, 0px),
            rgba(255, 252, 240, .95) 0%,
            rgba(255, 214, 160, .6) 18%,
            rgba(255, 170, 90, .18) 42%,
            rgba(255, 150, 80, 0) 65%);
}

/* Composited only while a transition runs, so these screen-sized layers do
   not exist for the rest of the page's life. */
.rt-fx.is-live .rt-flash {
    will-change: opacity;
}

.rt-fx.is-live .rt-fireball {
    will-change: transform, opacity;
}

/* Camera shake on impact. The independent `translate` property, so it
   composes with anything these already do, and only while shaking. Nothing
   position:fixed lives inside <main>, so this cannot displace it. */
html.rt-shaking .site-nav,
html.rt-shaking main,
html.rt-shaking .site-footer {
    translate: var(--rt-sx, 0px) var(--rt-sy, 0px);
}

/* Arriving: covered from the very first paint, then a hole opens from the
   impact point as the script grows --rt-r. The default of -2px keeps it fully
   covered until then. pointer-events:none so even a stuck cover could never
   trap a click; the boot script's timeout removes it regardless. */
html.rt-arriving::before {
    content: '';
    position: fixed;
    inset: 0;
    z-index: 2147482999;
    pointer-events: none;
    background: var(--surface-0, #0d0d0d);
    -webkit-mask-image: radial-gradient(circle at var(--rt-x, 50%) var(--rt-y, 50%),
            transparent var(--rt-r, -2px), #000 calc(var(--rt-r, -2px) + 1.5px));
    mask-image: radial-gradient(circle at var(--rt-x, 50%) var(--rt-y, 50%),
            transparent var(--rt-r, -2px), #000 calc(var(--rt-r, -2px) + 1.5px));
}
