/* ==================================================================
   The wipe — overlay styles.
   ==================================================================

   Two elements and nothing else.

   The veil is a DOM node rather than a canvas fill because the sky it
   shows is the same nebula stack the body paints in base.css, and a
   gradient the browser rasterises once at device resolution stays
   smooth where a canvas repaint of it would band. Its shape is a
   clip-path polygon that wipe.js rewrites every frame.

   The canvas holds everything that moves *with* the front: the chrome
   edge, the star swarm, the shards. It sits above the veil so a
   trailing star reads as being over the new sky, and above the page so
   a leading star reads as being over the old one.

   A page adopting this needs tokens.css for the palette and this file;
   wipe.js supplies its own markup.
   ================================================================== */

.cs-wipe {
    position: fixed;
    inset: 0;
    z-index: 9000;
    /* Idle it must not eat a click. cover() turns this on for the
       duration so a second click cannot start a second navigation
       while the first one is still crossing the screen. */
    pointer-events: none;
    /* display rather than opacity: an idle overlay should cost no
       compositing layer at all on a page that is being dragged on. */
    display: none;
}

.cs-wipe.is-active { display: block; }
.cs-wipe.is-blocking { pointer-events: auto; }

/* The sky behind the front. Same three offset nebulae as the body in
   base.css, over the same chassis tone, so the wipe closing on a
   Champstar page looks like the page's own background sliding across
   rather than a black card dropped on top. A shade denser, because
   this one has to hide what is underneath it. */
.cs-wipe-veil {
    position: absolute;
    inset: 0;
    background:
        radial-gradient(ellipse 92% 72% at 50% 36%, rgba(28,42,70,.46), transparent 62%),
        radial-gradient(ellipse 72% 56% at 84% 94%, rgba(17,29,52,.38), transparent 70%),
        radial-gradient(ellipse 62% 52% at 10% 6%,  rgba(23,34,60,.30), transparent 68%),
        var(--cs-void, #050607);
    /* Starts hidden. Every frame of a sweep replaces this. */
    clip-path: polygon(0 0, 0 0, 0 0);
    will-change: clip-path;
}

/* width/height are explicit and not left to inset:0, for the reason
   base.css spells out on #sky — a <canvas> is a replaced element, and
   an over-constrained box falls back to its bitmap size, which the
   script then sizes from the layout box. */
.cs-wipe-canvas {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    display: block;
}

/* ---------------- the instant cover ----------------
   The veil covering everything, no canvas, no travel. This is not a
   reduced-motion path — that gate is gone and the wipe now animates for
   everyone. It is the parked state: coverInstantly() uses it to hold a
   clean full cover at the end of a sweep, where a leftover shard would
   otherwise hang over a page about to be replaced. */
.cs-wipe--cut .cs-wipe-veil { clip-path: none; }
.cs-wipe--cut .cs-wipe-canvas { display: none; }


/* ---------------- the stand-in veil ----------------

   Set by transition/guard.js, which runs blocking in the <head> — the
   only place early enough to dress a document before it first paints.
   The module that owns the real overlay is deferred and therefore always
   too late: by the time it runs, the destination has already been on
   screen for a frame, and a cover applied then lands after the eye has
   seen what it was meant to hide.

   So this is not the overlay. It is a stand-in that holds the same
   ground, in the same colours, from the first paint until arm.js has the
   real one mounted — at which point arm.js takes the class off and the
   sweep runs underneath where this used to be. Both are up together for
   that handoff, deliberately: it is the one moment where a gap would
   show, so they overlap instead of meeting.

   Above .cs-wipe rather than below it, because during the overlap this
   is the one that must be trusted; the overlay beneath it may still be
   mid-mount.

   The arriving page is not hidden by any of this. The front uncovers the
   real content, already laid out and already there, so the reveal is the
   arrival rather than a curtain lifted before one. */
html.cs-crossing::before {
    content: '';
    position: fixed;
    inset: 0;
    z-index: 9001;
    pointer-events: none;
    background:
        radial-gradient(ellipse 92% 72% at 50% 36%, rgba(28,42,70,.46), transparent 62%),
        radial-gradient(ellipse 72% 56% at 84% 94%, rgba(17,29,52,.38), transparent 70%),
        radial-gradient(ellipse 62% 52% at 10% 6%,  rgba(23,34,60,.30), transparent 68%),
        var(--cs-void, #050607);
}
