/* rusty begin new code | 2026-09-02 18:05 */
/* Action: Global FX layer, extracted out of master.blade.php (which was carrying an inline
   <style> + <script> pair for the cursor and had lost the portal's DOM node entirely).
   Owns two effects:
     1. #wormhole-container - the Three.js warp portal surface, rebuilt on the brand palette
        with a radial vignette and a faint scanline overlay.
     2. The cursor reticle - replaces the old "meteor" (14px neon core with a four-layer
        glow and a 0.12s steps() flicker, plus 14 trail dots).
   Behaviour lives in macblash-fx.js. Both effects are desktop-pointer only and both
   collapse entirely under prefers-reduced-motion. */


/* ============================================================================
   1. WARP PORTAL SURFACE
   ========================================================================= */
#wormhole-container {
    position: fixed;
    inset: 0;
    width: 100vw;
    height: 100vh;
    z-index: 99999;
    /* Off-black rather than #000 (SKILL.md 8.B: pure values kill depth). */
    background: #030615;
    opacity: 0;
    pointer-events: none;
    transition: opacity .35s cubic-bezier(.16, 1, .3, 1);
    overflow: hidden;
}

#wormhole-container.is-active {
    opacity: 1;
    pointer-events: auto;
}

#wormhole-container canvas {
    display: block;
}

/* Radial vignette: pulls the eye to the tunnel mouth and hides the flat edges of the
   star field. Pseudo-elements are pointer-events:none and sit on a fixed, non-scrolling
   container, which is the only place SKILL.md 6.E allows this kind of overlay. */
#wormhole-container::before {
    content: "";
    position: absolute;
    inset: 0;
    z-index: 2;
    pointer-events: none;
    background: radial-gradient(ellipse at center,
                transparent 30%,
                rgba(3, 6, 21, .55) 72%,
                rgba(3, 6, 21, .92) 100%);
}

/* Faint scanlines for the CRT/HUD read. Deliberately low contrast. */
#wormhole-container::after {
    content: "";
    position: absolute;
    inset: 0;
    z-index: 3;
    pointer-events: none;
    opacity: .5;
    background: repeating-linear-gradient(
        0deg,
        rgba(255, 255, 255, .035) 0px,
        rgba(255, 255, 255, .035) 1px,
        transparent 1px,
        transparent 3px
    );
}

/* While the portal runs, freeze the page behind it. */
body.portal-active {
    overflow: hidden;
}


/* ============================================================================
   2. LOGO CURSOR
   The MacBlash mark is the pointer. A purple/magenta flame aura sits behind it and
   trails on a spring lag (GSAP lerp in macblash-fx.js), so the fire "floats" a beat
   behind the logo. State changes on hover / press are the motivated part
   (SKILL.md 5: motion communicates affordance).
   ========================================================================= */
/* rusty begin update | 2026-09-04 15:00 */
/* Action: Hardened the custom cursor against click/scroll blocking. pointer-events was
   already none here and the z-indexes were already 999999/999998, so this is belt-and-
   braces !important armouring against any later rule (or third-party stylesheet)
   overriding it — not a behaviour change. Layering is deliberately NOT flattened to a
   single 999999: the flame is an aura that must stay BEHIND the logo mark, so it keeps
   999998. Collapsing both to the same value would let DOM order decide and break the
   intended depth. */
#mb-cursor-logo,
#mb-cursor-flame {
    position: fixed;
    top: 0;
    left: 0;
    pointer-events: none !important;
    opacity: 0;
    will-change: transform, opacity;
    /* Non-GSAP fallback centering; GSAP overrides with xPercent/yPercent. */
    transform: translate3d(-50%, -50%, 0);
    transition: opacity .25s ease;
}

/* ── The flame aura (behind) ─────────────────────────────────────────────────
   The host element is positioned by GSAP (transform = x/y). The ::before does the
   flicker on its OWN transform, so the two never fight over the same property. */
#mb-cursor-flame {
    z-index: 999998 !important; /* rusty update 2026-09-04 15:00 — aura stays one layer under the logo */
    width: 62px;
    height: 62px;
    mix-blend-mode: screen;
    transition: opacity .25s ease, width .3s cubic-bezier(.16, 1, .3, 1),
                height .3s cubic-bezier(.16, 1, .3, 1);
}

#mb-cursor-flame::before {
    content: "";
    position: absolute;
    inset: 0;
    border-radius: 50%;
    /* Layered radials: white-hot centre -> magenta -> purple -> out. */
    background:
        radial-gradient(circle at 50% 55%, rgba(255, 255, 255, .55) 0%, rgba(255, 255, 255, 0) 38%),
        radial-gradient(circle at 50% 60%, rgba(232, 64, 248, .55) 0%, rgba(232, 64, 248, 0) 55%),
        radial-gradient(circle at 50% 65%, rgba(139, 92, 246, .45) 0%, rgba(139, 92, 246, 0) 72%);
    filter: blur(6px) drop-shadow(0 0 10px rgba(168, 47, 192, .55));
    animation: mb-flame-flicker 1.4s ease-in-out infinite;
}

/* Slow, low-cost flicker: transform + opacity only. */
@keyframes mb-flame-flicker {
    0%, 100% { transform: scale(1)    translateY(0);      opacity: 1; }
    45%      { transform: scale(1.09) translateY(-4%);    opacity: .82; }
    70%      { transform: scale(.95)  translateY(2%);     opacity: .92; }
}

/* ── The logo mark (front) ──────────────────────────────────────────────────
   Scale/press states use the standalone `scale` property, NOT `transform`, so they
   compose with the GSAP-written positional transform instead of overwriting it. */
#mb-cursor-logo {
    z-index: 999999 !important; /* rusty update 2026-09-04 15:00 — logo mark always the topmost layer */
    width: 30px;
    height: 30px;
    object-fit: contain;
    /* Its own soft purple glow so the mark reads on any background. */
    filter: drop-shadow(0 0 4px rgba(232, 64, 248, .7)) drop-shadow(0 0 9px rgba(139, 92, 246, .5));
    scale: 1;
    transition: opacity .25s ease, scale .18s cubic-bezier(.16, 1, .3, 1);
}

/* Fallback when settings('logo') is unavailable: a gradient lozenge. */
#mb-cursor-logo.mb-cursor-logo--fallback {
    border-radius: 8px;
    background: linear-gradient(135deg, #E840F8, #8b5cf6);
}

/* ── Interactive states ─────────────────────────────────────────────────── */
/* Over a link/button: logo lifts, flame swells. */
#mb-cursor-logo.is-target {
    scale: 1.28;
}

#mb-cursor-flame.is-target {
    width: 82px;
    height: 82px;
}

/* Press: everything contracts (tactile ack, SKILL.md 4.5). */
#mb-cursor-logo.is-down {
    scale: .82;
}

#mb-cursor-flame.is-down {
    width: 46px;
    height: 46px;
}

/* Hide the system cursor only while the custom one is live. macblash-fx.js adds this
   class to <html>, so if the script never runs the real cursor is untouched. */
html.mb-cursor-active,
html.mb-cursor-active a,
html.mb-cursor-active button,
html.mb-cursor-active [role="button"],
html.mb-cursor-active label,
html.mb-cursor-active summary {
    cursor: none;
}

/* Text entry keeps a real caret: hiding the cursor in a field is hostile. */
html.mb-cursor-active input,
html.mb-cursor-active textarea,
html.mb-cursor-active select,
html.mb-cursor-active [contenteditable="true"] {
    cursor: auto;
}


/* ============================================================================
   3. REDUCED MOTION
   Both effects disappear completely and the system cursor comes back.
   ========================================================================= */
@media (prefers-reduced-motion: reduce) {

    #mb-cursor-logo,
    #mb-cursor-flame {
        display: none !important;
    }

    html.mb-cursor-active,
    html.mb-cursor-active a,
    html.mb-cursor-active button,
    html.mb-cursor-active [role="button"],
    html.mb-cursor-active label,
    html.mb-cursor-active summary {
        cursor: auto;
    }

    #wormhole-container {
        display: none !important;
    }
}
/* rusty end new code */


/* rusty begin new code | 2026-09-03 03:05 */
/* ============================================================================
   4. PLAYER ID  -  first-visit language gate
   Replaces the legacy full-screen intro video. Deliberately NOT the paper/ticket
   look: same dark-glass HUD language as the rest of the site, built on
   --home-border / --home-radius tones with a backdrop blur and a restrained
   cyan-purple edge (SKILL.md 9.A: inner hairline + tinted lift, not a neon halo).
   Only rendered when Session('language') is unset, so returning visitors never
   receive this markup at all.
   ========================================================================= */

/* Perspective is declared on BOTH the overlay and the inner wrapper. The wrapper
   is the one that actually matters (it is the card's direct parent, and
   `perspective` only applies to children), but the overlay carries it too so the
   scene keeps real depth if the card is ever re-parented. */
#macblash-intro-overlay {
    position: fixed;
    inset: 0;
    z-index: 9999;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 1.25rem;
    background: rgba(3, 6, 21, .82);
    backdrop-filter: blur(8px);
    -webkit-backdrop-filter: blur(8px);
    perspective: 1200px;
    perspective-origin: center center;
}

.player-id-wrapper {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    perspective: 1200px;
    perspective-origin: center center;
    transform-style: preserve-3d;
}

/* Locks page scroll while the gate is up. JS adds/removes this on <html>. */
html.macblash-intro-open,
html.macblash-intro-open body {
    overflow: hidden;
}

/* ── The HUD panel ─────────────────────────────────────────────────────────── */
.macblash-intro-card {
    position: relative;
    width: min(30rem, 100%);
    padding: clamp(1.75rem, 5vw, 2.75rem) clamp(1.25rem, 4vw, 2.25rem);
    border: 1px solid rgba(139, 92, 246, .32);
    border-radius: 18px;
    background: linear-gradient(180deg, rgba(15, 10, 42, .78), rgba(8, 8, 18, .88));
    backdrop-filter: blur(20px);
    -webkit-backdrop-filter: blur(20px);
    /* Inner hairline + tinted lift, never an outer neon halo. */
    box-shadow:
        inset 0 1px 0 rgba(255, 255, 255, .07),
        inset 0 0 0 1px rgba(6, 182, 212, .07),
        0 28px 70px rgba(3, 6, 21, .7);
    text-align: center;
    overflow: hidden;
    transform-style: preserve-3d;
    /* The card is transformed for the whole 3s flight and then floats forever, so
       the compositor hint is earned rather than speculative. */
    will-change: transform, opacity;
    /* Starts hidden so it cannot paint at full size before GSAP takes over on
       DOMContentLoaded. The <noscript> block in master.blade.php reverses this for
       JS-off visitors, and the reduced-motion branch in JS sets it explicitly. */
    opacity: 0;
}

/* A single slow scan sweep. Motion justification (SKILL.md 5): it reads as a live
   terminal booting, which is the whole conceit of the panel. */
.macblash-intro-scan {
    position: absolute;
    inset-inline: 0;
    inset-block-start: 0;
    height: 140px;
    pointer-events: none;
    background: linear-gradient(180deg, rgba(6, 182, 212, .11), rgba(6, 182, 212, 0));
    animation: macblash-intro-scan 3.4s cubic-bezier(.4, 0, .2, 1) infinite;
}

@keyframes macblash-intro-scan {
    0%        { transform: translateY(-140px); opacity: 0; }
    18%, 62%  { opacity: 1; }
    100%      { transform: translateY(460px); opacity: 0; }
}

.macblash-intro-logo {
    display: block;
    max-height: 54px;
    width: auto;
    margin: 0 auto 1.25rem;
    object-fit: contain;
}

/* ── Bilingual machine readout ─────────────────────────────────────────────── */
/* Forced LTR as a block because it is a machine readout, not prose. Each Arabic
   run is isolated so the bidi algorithm cannot swing the badge around the
   timestamp when the page itself is RTL. */
.macblash-intro-sys {
    display: inline-flex;
    align-items: center;
    flex-wrap: wrap;
    justify-content: center;
    gap: .35rem;
    margin: 0 0 1.5rem;
    padding: .35rem .85rem;
    border: 1px solid rgba(139, 92, 246, .22);
    border-radius: 999px;
    background: rgba(6, 182, 212, .06);
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: .68rem;
    letter-spacing: .08em;
    direction: ltr;
    unicode-bidi: isolate;
}

.macblash-intro-sys .badge-ar {
    color: #b9a6f5;
    font-family: 'Sukar', sans-serif;
    font-weight: 700;
    letter-spacing: 0;
    unicode-bidi: isolate;
}

.macblash-intro-sys-sep {
    color: rgba(232, 238, 247, .35);
}

.macblash-intro-sys .badge-en {
    color: #8b5cf6;
    font-weight: 700;
}

.macblash-intro-sys-val {
    color: #06b6d4;
    font-weight: 700;
    unicode-bidi: isolate;
}

/* ── Dual headings ─────────────────────────────────────────────────────────── */
.macblash-intro-headings {
    margin-block-end: 1.6rem;
}

.intro-title-ar {
    margin: 0 0 .3rem;
    color: #fff;
    font-family: 'Sukar', sans-serif;
    font-size: clamp(1.2rem, 4vw, 1.55rem);
    font-weight: 900;
    line-height: 1.35;
}

.intro-title-en {
    margin: 0;
    color: rgba(232, 238, 247, .62);
    font-size: clamp(.78rem, 2.4vw, .9rem);
    font-weight: 600;
    letter-spacing: .08em;
    text-transform: uppercase;
}

/* ── Language buttons: two-tier bilingual label ────────────────────────────── */
.macblash-intro-actions {
    display: flex;
    flex-wrap: wrap;
    gap: .75rem;
    justify-content: center;
}

.macblash-intro-btn {
    flex: 1 1 8.5rem;
    padding: .75rem 1.3rem;
    border: 1px solid rgba(6, 182, 212, .38);
    border-radius: 12px;
    background: rgba(6, 182, 212, .09);
    color: #e8eef7;
    text-decoration: none;
    transition: transform .25s cubic-bezier(.16, 1, .3, 1),
                background .25s ease, border-color .25s ease, color .25s ease;
}

.macblash-intro-btn:hover,
.macblash-intro-btn:focus-visible {
    transform: translateY(-2px);
    border-color: rgba(6, 182, 212, .7);
    background: rgba(6, 182, 212, .18);
    color: #fff;
    text-decoration: none;
}

.macblash-intro-btn:active {
    transform: translateY(0) scale(.98);
}

.macblash-intro-btn .btn-main {
    display: block;
    font-family: 'Sukar', sans-serif;
    font-size: 1.15rem;
    font-weight: 800;
    line-height: 1.25;
    /* No-op for the Arabic label (Arabic is caseless), so it is safe to apply to both. */
    text-transform: uppercase;
}

.macblash-intro-btn .btn-sub {
    display: block;
    margin-block-start: .15rem;
    font-size: .75rem;
    font-weight: 600;
    line-height: 1.3;
    opacity: .65;
}

/* ── Reduced motion: the gate still WORKS, it just stops performing. ───────── */
@media (prefers-reduced-motion: reduce) {

    .macblash-intro-scan {
        display: none;
    }

    .macblash-intro-card {
        /* JS skips its timeline under reduce, so the card must be visible on its own. */
        opacity: 1;
        will-change: auto;
    }

    .macblash-intro-card,
    .macblash-intro-btn {
        animation: none !important;
        transition: none !important;
    }
}
/* rusty end new code */
