/* Animated project covers - shared by index.html and portfolio/ */
        /* covers (from production site) */
        /* ============================================================
           ANIMATED COVERS — each preview animates what its project
           actually DOES (signal flow, ranging, a route being traced,
           grayscale turning to colour…). Deliberately slow, low-opacity
           and ambient — never a generic pulse/heartbeat. Only the one
           selected cover is ever in the DOM, so only one animates.
           All motion is disabled under prefers-reduced-motion (below);
           every base state below is the finished static artwork.
           ============================================================ */
        .visual-bg svg.cover { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }
        .cover .flow { offset-rotate: 0deg; opacity: 0; }   /* travelling signal dots: hidden at rest */

        /* 0 · QPlace — the brain runs one turn, twice. A real query types itself
           character by character and fires into the constellation; candidate routes
           flicker and die while the winning path draws down to the depth ladder
           (DISCOVER); the query arcs out, real data arrives at the honesty gate,
           one padded result flushes red and falls, the survivors drop into the
           widgets and the screen composes. The second, shorter question types and
           routes to a different exit (DETAIL): one capsule. 12s, two halves; at
           rest the finished half-one answer, caret idling at the end of the ask. */
        @keyframes qp-caret { 0%, 48% { opacity: 1; } 52%, 100% { opacity: 0; } }
        @keyframes qp-tA { 0%, 1.5% { opacity: 1; clip-path: inset(0 100% 0 0); animation-timing-function: steps(31, end); } 10.5% { clip-path: inset(0 0 0 0); } 46% { opacity: 1; } 49%, 100% { opacity: 0; clip-path: inset(0 0 0 0); } }
        .cover--qplace .qp-tA { opacity: 1; animation: qp-tA 12s linear -5s infinite; }
        @keyframes qp-tB { 0%, 51.5% { opacity: 0; clip-path: inset(0 100% 0 0); } 52% { opacity: 1; clip-path: inset(0 100% 0 0); animation-timing-function: steps(17, end); } 57.5% { clip-path: inset(0 0 0 0); } 96% { opacity: 1; } 99%, 100% { opacity: 0; clip-path: inset(0 0 0 0); } }
        .cover--qplace .qp-tB { opacity: 0; animation: qp-tB 12s linear -5s infinite; }
        @keyframes qp-carA { 0% { opacity: 1; } 46% { opacity: 1; } 49%, 100% { opacity: 0; } }
        .cover--qplace .qp-carA { opacity: 1; animation: qp-carA 12s linear -5s infinite; }
        @keyframes qp-carB { 0%, 51% { opacity: 0; } 52% { opacity: 1; } 96% { opacity: 1; } 99%, 100% { opacity: 0; } }
        .cover--qplace .qp-carB { opacity: 0; animation: qp-carB 12s linear -5s infinite; }
        @keyframes qp-carAM { 0%, 1.5% { transform: translateX(-334px); animation-timing-function: steps(31, end); } 10.5%, 100% { transform: translateX(0); } }
        .cover--qplace .qp-carAM { animation: qp-caret 1.06s linear -5s infinite, qp-carAM 12s linear -5s infinite; }
        @keyframes qp-carBM { 0%, 52% { transform: translateX(-184px); animation-timing-function: steps(17, end); } 57.5%, 100% { transform: translateX(0); } }
        .cover--qplace .qp-carBM { animation: qp-caret 1.06s linear -5s infinite, qp-carBM 12s linear -5s infinite; }
        @keyframes qp-send { 0%, 11% { offset-distance: 0%; opacity: 0; } 11.5% { opacity: 1; } 13.5% { offset-distance: 100%; opacity: 1; } 14% { offset-distance: 100%; opacity: 0; } 15%, 58% { offset-distance: 0%; opacity: 0; } 58.5% { opacity: 1; } 60.5% { offset-distance: 100%; opacity: 1; } 61%, 100% { offset-distance: 100%; opacity: 0; } }
        .cover--qplace .qp-send { animation: qp-send 12s linear -5s infinite; }
        @keyframes qp-entry { 0%, 12.5% { opacity: 0; transform: scale(.5); } 15% { opacity: .85; transform: scale(1); } 19% { opacity: 0; transform: scale(1.9); } 56% { opacity: 0; transform: scale(.5); } 61.5% { opacity: .85; transform: scale(1); } 65%, 100% { opacity: 0; transform: scale(1.9); } }
        .cover--qplace .qp-entry { opacity: 0; transform-box: fill-box; transform-origin: center; animation: qp-entry 12s ease-out -5s infinite; }
        @keyframes qp-thinkA1 { 0%, 13% { opacity: 0; } 14% { opacity: .55; } 15% { opacity: .12; } 16% { opacity: .45; } 18%, 100% { opacity: 0; } }
        @keyframes qp-thinkA2 { 0%, 14% { opacity: 0; } 15% { opacity: .5; } 16% { opacity: .14; } 17% { opacity: .4; } 19%, 100% { opacity: 0; } }
        @keyframes qp-thinkB { 0%, 60% { opacity: 0; } 61% { opacity: .55; } 62% { opacity: .14; } 63% { opacity: .45; } 65%, 100% { opacity: 0; } }
        .cover--qplace .qp-thinkA1 { opacity: 0; animation: qp-thinkA1 12s linear -5s infinite; }
        .cover--qplace .qp-thinkA2 { opacity: 0; animation: qp-thinkA2 12s linear -5s infinite; }
        .cover--qplace .qp-thinkB { opacity: 0; animation: qp-thinkB 12s linear -5s infinite; }
        @keyframes qp-pathA { 0%, 15% { opacity: 0; } 17.5% { opacity: 1; } 46% { opacity: 1; } 49%, 100% { opacity: 0; } }
        .cover--qplace .qp-pathA { opacity: 1; animation: qp-pathA 12s ease-out -5s infinite; }
        @keyframes qp-drawA { 0%, 15% { stroke-dashoffset: 100; } 23%, 100% { stroke-dashoffset: 0; } }
        .cover--qplace .qp-drawA { stroke-dasharray: 100 100; stroke-dashoffset: 0; animation: qp-drawA 12s cubic-bezier(.3,.6,.2,1) -5s infinite; }
        @keyframes qp-pathB { 0%, 62% { opacity: 0; } 64.5% { opacity: 1; } 95% { opacity: 1; } 98%, 100% { opacity: 0; } }
        .cover--qplace .qp-pathB { opacity: 0; animation: qp-pathB 12s ease-out -5s infinite; }
        @keyframes qp-drawB { 0%, 62% { stroke-dashoffset: 100; } 69.5%, 100% { stroke-dashoffset: 0; } }
        .cover--qplace .qp-drawB { stroke-dasharray: 100 100; stroke-dashoffset: 100; animation: qp-drawB 12s cubic-bezier(.3,.6,.2,1) -5s infinite; }
        @keyframes qp-ladA { 0%, 22% { opacity: 0; } 25% { opacity: 1; } 46% { opacity: 1; } 49%, 100% { opacity: 0; } }
        .cover--qplace .qp-ladA { opacity: 1; animation: qp-ladA 12s ease-out -5s infinite; }
        @keyframes qp-ladB { 0%, 68.5% { opacity: 0; } 71% { opacity: 1; } 95% { opacity: 1; } 98%, 100% { opacity: 0; } }
        .cover--qplace .qp-ladB { opacity: 0; animation: qp-ladB 12s ease-out -5s infinite; }
        @keyframes qp-arcA { 0%, 23% { opacity: 0; } 25.5% { opacity: 1; } 46% { opacity: 1; } 49%, 100% { opacity: 0; } }
        .cover--qplace .qp-arcA { opacity: 1; animation: qp-arcA 12s ease-out -5s infinite; }
        @keyframes qp-arcDrawA { 0%, 23.5% { stroke-dashoffset: 100; } 27.5%, 100% { stroke-dashoffset: 0; } }
        .cover--qplace .qp-arcDrawA { stroke-dasharray: 100 100; stroke-dashoffset: 0; animation: qp-arcDrawA 12s ease-out -5s infinite; }
        @keyframes qp-arcB { 0%, 69.5% { opacity: 0; } 71.5% { opacity: 1; } 95% { opacity: 1; } 98%, 100% { opacity: 0; } }
        .cover--qplace .qp-arcB { opacity: 0; animation: qp-arcB 12s ease-out -5s infinite; }
        @keyframes qp-arcDrawB { 0%, 70% { stroke-dashoffset: 100; } 74%, 100% { stroke-dashoffset: 0; } }
        .cover--qplace .qp-arcDrawB { stroke-dasharray: 100 100; stroke-dashoffset: 100; animation: qp-arcDrawB 12s ease-out -5s infinite; }
        @keyframes qp-d1 { 0%, 27% { offset-distance: 0%; opacity: 0; } 28% { opacity: 1; } 31% { offset-distance: 72%; } 32.5% { offset-distance: 72%; } 34.5% { offset-distance: 100%; opacity: 1; } 36%, 100% { offset-distance: 100%; opacity: 0; } }
        @keyframes qp-d2 { 0%, 28.5% { offset-distance: 0%; opacity: 0; } 29.5% { opacity: 1; } 32.5% { offset-distance: 65%; } 34% { offset-distance: 65%; } 36% { offset-distance: 100%; opacity: 1; } 37.5%, 100% { offset-distance: 100%; opacity: 0; } }
        @keyframes qp-d3 { 0%, 30% { offset-distance: 0%; opacity: 0; } 31% { opacity: 1; } 34% { offset-distance: 51%; } 35.5% { offset-distance: 51%; } 37.5% { offset-distance: 100%; opacity: 1; } 39%, 100% { offset-distance: 100%; opacity: 0; } }
        @keyframes qp-rej { 0%, 29% { offset-distance: 0%; opacity: 0; fill: #8FB6F0; } 30% { opacity: 1; } 32.5% { offset-distance: 53%; fill: #8FB6F0; } 34% { offset-distance: 53%; fill: #E0705C; } 37% { offset-distance: 100%; opacity: .9; fill: #E0705C; } 38.5%, 100% { offset-distance: 100%; opacity: 0; } }
        @keyframes qp-dB { 0%, 72.5% { offset-distance: 0%; opacity: 0; } 73.5% { opacity: 1; } 76.5% { offset-distance: 72%; } 78% { offset-distance: 72%; } 80% { offset-distance: 100%; opacity: 1; } 81.5%, 100% { offset-distance: 100%; opacity: 0; } }
        .cover--qplace .qp-d1 { animation: qp-d1 12s linear -5s infinite; }
        .cover--qplace .qp-d2 { animation: qp-d2 12s linear -5s infinite; }
        .cover--qplace .qp-d3 { animation: qp-d3 12s linear -5s infinite; }
        .cover--qplace .qp-rej { animation: qp-rej 12s linear -5s infinite; }
        .cover--qplace .qp-dB { animation: qp-dB 12s linear -5s infinite; }
        @keyframes qp-wMap { 0%, 33% { opacity: 0; transform: translateY(8px); } 36% { opacity: 1; transform: translateY(0); } 46% { opacity: 1; } 49%, 100% { opacity: 0; } }
        @keyframes qp-wHero { 0%, 35.5% { opacity: 0; transform: translateY(8px); } 38.5% { opacity: 1; transform: translateY(0); } 46% { opacity: 1; } 49%, 100% { opacity: 0; } }
        @keyframes qp-wRail { 0%, 38% { opacity: 0; transform: translateY(8px); } 41% { opacity: 1; transform: translateY(0); } 46% { opacity: 1; } 49%, 100% { opacity: 0; } }
        .cover--qplace .qp-wMap { opacity: 1; transform-box: fill-box; transform-origin: center; animation: qp-wMap 12s ease-out -5s infinite; }
        .cover--qplace .qp-wHero { opacity: 1; transform-box: fill-box; transform-origin: center; animation: qp-wHero 12s ease-out -5s infinite; }
        .cover--qplace .qp-wRail { opacity: 1; transform-box: fill-box; transform-origin: center; animation: qp-wRail 12s ease-out -5s infinite; }
        @keyframes qp-wCap { 0%, 78.5% { opacity: 0; transform: translateY(8px); } 81.5% { opacity: 1; transform: translateY(0); } 95% { opacity: 1; } 98%, 100% { opacity: 0; } }
        .cover--qplace .qp-wCap { opacity: 0; transform-box: fill-box; transform-origin: center; animation: qp-wCap 12s ease-out -5s infinite; }
        @keyframes qp-shimA { 0%, 39% { transform: translateX(0); opacity: 0; } 40.5% { opacity: .22; } 44%, 100% { transform: translateX(236px); opacity: 0; } }
        .cover--qplace .qp-shimA { opacity: 0; animation: qp-shimA 12s ease-in-out -5s infinite; }
        @keyframes qp-shimB { 0%, 82% { transform: translateX(0); opacity: 0; } 83.5% { opacity: .25; } 86.5%, 100% { transform: translateX(184px); opacity: 0; } }
        .cover--qplace .qp-shimB { opacity: 0; animation: qp-shimB 12s ease-in-out -5s infinite; }
        @keyframes qp-lRoute { 0%, 11% { opacity: .3; } 14%, 22% { opacity: 1; } 26%, 57% { opacity: .3; } 60%, 67% { opacity: 1; } 71%, 100% { opacity: .3; } }
        @keyframes qp-lJudge { 0%, 26% { opacity: .3; } 29%, 37% { opacity: 1; } 41%, 70% { opacity: .3; } 73%, 79% { opacity: 1; } 83%, 100% { opacity: .3; } }
        @keyframes qp-lComp { 0%, 32% { opacity: .3; } 35%, 45% { opacity: 1; } 49%, 76% { opacity: .3; } 79%, 88% { opacity: 1; } 92%, 100% { opacity: .3; } }
        .cover--qplace .qp-lRoute { opacity: .55; animation: qp-lRoute 12s ease-in-out -5s infinite; }
        .cover--qplace .qp-lJudge { opacity: .55; animation: qp-lJudge 12s ease-in-out -5s infinite; }
        .cover--qplace .qp-lComp { opacity: .55; animation: qp-lComp 12s ease-in-out -5s infinite; }

        /* 1 · Mindplace — the agentic run console. The brief drops into the
           Supervisor hub, dispatch dots stagger out and each crew node lights as
           its log line appears below: role + what it is doing right now, a live
           spinner turning while it works (Claude Code style). The engines warm,
           the five keyframes render one by one, and each line flips to a teal
           check as its work lands; the play triangle appears when the cut is
           watchable. 12s; at rest the finished run, every line checked. */
        @keyframes mp-brief { 0%, 2% { offset-distance: 0%; opacity: 0; } 3% { opacity: 1; } 6% { offset-distance: 100%; opacity: 1; } 7%, 100% { offset-distance: 100%; opacity: 0; } }
        .cover--mindplace .mp-brief { offset-rotate: 0deg; opacity: 0; animation: mp-brief 12s ease-in -9s infinite; }
        @keyframes mp-hub { 0%, 5% { opacity: 0; } 8% { opacity: 1; } 14% { opacity: .25; } 20%, 100% { opacity: 0; } }
        .cover--mindplace .mp-hub { opacity: 0; animation: mp-hub 12s ease-in-out -9s infinite; }
        @keyframes mp-flow1 { 0%, 7% { offset-distance: 0%; opacity: 0; } 8% { opacity: .95; } 13% { offset-distance: 100%; opacity: .95; } 14%, 100% { offset-distance: 100%; opacity: 0; } }
        @keyframes mp-flow2 { 0%, 9% { offset-distance: 0%; opacity: 0; } 10% { opacity: .95; } 15% { offset-distance: 100%; opacity: .95; } 16%, 100% { offset-distance: 100%; opacity: 0; } }
        @keyframes mp-flow3 { 0%, 11% { offset-distance: 0%; opacity: 0; } 12% { opacity: .95; } 17% { offset-distance: 100%; opacity: .95; } 18%, 100% { offset-distance: 100%; opacity: 0; } }
        @keyframes mp-flow4 { 0%, 13% { offset-distance: 0%; opacity: 0; } 14% { opacity: .95; } 19% { offset-distance: 100%; opacity: .95; } 20%, 100% { offset-distance: 100%; opacity: 0; } }
        .cover--mindplace .mp-flow1 { animation: mp-flow1 12s ease-in-out -9s infinite; }
        .cover--mindplace .mp-flow2 { animation: mp-flow2 12s ease-in-out -9s infinite; }
        .cover--mindplace .mp-flow3 { animation: mp-flow3 12s ease-in-out -9s infinite; }
        .cover--mindplace .mp-flow4 { animation: mp-flow4 12s ease-in-out -9s infinite; }
        @keyframes mp-crew1 { 0%, 12.5% { opacity: 0; } 14% { opacity: 1; } 93% { opacity: 1; } 97%, 100% { opacity: 0; } }
        @keyframes mp-crew2 { 0%, 14.5% { opacity: 0; } 16% { opacity: 1; } 93% { opacity: 1; } 97%, 100% { opacity: 0; } }
        @keyframes mp-crew3 { 0%, 16.5% { opacity: 0; } 18% { opacity: 1; } 93% { opacity: 1; } 97%, 100% { opacity: 0; } }
        @keyframes mp-crew4 { 0%, 18.5% { opacity: 0; } 20% { opacity: 1; } 93% { opacity: 1; } 97%, 100% { opacity: 0; } }
        .cover--mindplace .mp-crew1 { opacity: 1; animation: mp-crew1 12s ease-out -9s infinite; }
        .cover--mindplace .mp-crew2 { opacity: 1; animation: mp-crew2 12s ease-out -9s infinite; }
        .cover--mindplace .mp-crew3 { opacity: 1; animation: mp-crew3 12s ease-out -9s infinite; }
        .cover--mindplace .mp-crew4 { opacity: 1; animation: mp-crew4 12s ease-out -9s infinite; }
        @keyframes mp-lg1 { 0%, 15% { opacity: 0; transform: translateX(-8px); } 17.5% { opacity: 1; transform: translateX(0); } 93% { opacity: 1; } 97%, 100% { opacity: 0; } }
        @keyframes mp-lg2 { 0%, 19% { opacity: 0; transform: translateX(-8px); } 21.5% { opacity: 1; transform: translateX(0); } 93% { opacity: 1; } 97%, 100% { opacity: 0; } }
        @keyframes mp-lg3 { 0%, 23% { opacity: 0; transform: translateX(-8px); } 25.5% { opacity: 1; transform: translateX(0); } 93% { opacity: 1; } 97%, 100% { opacity: 0; } }
        @keyframes mp-lg4 { 0%, 27% { opacity: 0; transform: translateX(-8px); } 29.5% { opacity: 1; transform: translateX(0); } 93% { opacity: 1; } 97%, 100% { opacity: 0; } }
        @keyframes mp-lg5 { 0%, 36% { opacity: 0; transform: translateX(-8px); } 38.5% { opacity: 1; transform: translateX(0); } 93% { opacity: 1; } 97%, 100% { opacity: 0; } }
        .cover--mindplace .mp-lg1 { opacity: 1; transform-box: fill-box; transform-origin: center; animation: mp-lg1 12s ease-out -9s infinite; }
        .cover--mindplace .mp-lg2 { opacity: 1; transform-box: fill-box; transform-origin: center; animation: mp-lg2 12s ease-out -9s infinite; }
        .cover--mindplace .mp-lg3 { opacity: 1; transform-box: fill-box; transform-origin: center; animation: mp-lg3 12s ease-out -9s infinite; }
        .cover--mindplace .mp-lg4 { opacity: 1; transform-box: fill-box; transform-origin: center; animation: mp-lg4 12s ease-out -9s infinite; }
        .cover--mindplace .mp-lg5 { opacity: 1; transform-box: fill-box; transform-origin: center; animation: mp-lg5 12s ease-out -9s infinite; }
        @keyframes mp-rot { to { transform: rotate(360deg); } }
        .cover--mindplace .mp-spin { transform-box: fill-box; transform-origin: center; animation: mp-rot 1.1s linear infinite; }
        @keyframes mp-sp1 { 0%, 15% { opacity: 0; } 17% { opacity: 1; } 39% { opacity: 1; } 41%, 100% { opacity: 0; } }
        @keyframes mp-sp2 { 0%, 19% { opacity: 0; } 21% { opacity: 1; } 45% { opacity: 1; } 47%, 100% { opacity: 0; } }
        @keyframes mp-sp3 { 0%, 23% { opacity: 0; } 25% { opacity: 1; } 51% { opacity: 1; } 53%, 100% { opacity: 0; } }
        @keyframes mp-sp4 { 0%, 27% { opacity: 0; } 29% { opacity: 1; } 57% { opacity: 1; } 59%, 100% { opacity: 0; } }
        @keyframes mp-sp5 { 0%, 36% { opacity: 0; } 38% { opacity: 1; } 63% { opacity: 1; } 65%, 100% { opacity: 0; } }
        .cover--mindplace .mp-sp1 { opacity: 0; animation: mp-sp1 12s linear -9s infinite; }
        .cover--mindplace .mp-sp2 { opacity: 0; animation: mp-sp2 12s linear -9s infinite; }
        .cover--mindplace .mp-sp3 { opacity: 0; animation: mp-sp3 12s linear -9s infinite; }
        .cover--mindplace .mp-sp4 { opacity: 0; animation: mp-sp4 12s linear -9s infinite; }
        .cover--mindplace .mp-sp5 { opacity: 0; animation: mp-sp5 12s linear -9s infinite; }
        @keyframes mp-ok1 { 0%, 39% { opacity: 0; } 41% { opacity: 1; } 93% { opacity: 1; } 97%, 100% { opacity: 0; } }
        @keyframes mp-ok2 { 0%, 45% { opacity: 0; } 47% { opacity: 1; } 93% { opacity: 1; } 97%, 100% { opacity: 0; } }
        @keyframes mp-ok3 { 0%, 51% { opacity: 0; } 53% { opacity: 1; } 93% { opacity: 1; } 97%, 100% { opacity: 0; } }
        @keyframes mp-ok4 { 0%, 57% { opacity: 0; } 59% { opacity: 1; } 93% { opacity: 1; } 97%, 100% { opacity: 0; } }
        @keyframes mp-ok5 { 0%, 63% { opacity: 0; } 65% { opacity: 1; } 93% { opacity: 1; } 97%, 100% { opacity: 0; } }
        .cover--mindplace .mp-ok1 { opacity: 1; animation: mp-ok1 12s ease-out -9s infinite; }
        .cover--mindplace .mp-ok2 { opacity: 1; animation: mp-ok2 12s ease-out -9s infinite; }
        .cover--mindplace .mp-ok3 { opacity: 1; animation: mp-ok3 12s ease-out -9s infinite; }
        .cover--mindplace .mp-ok4 { opacity: 1; animation: mp-ok4 12s ease-out -9s infinite; }
        .cover--mindplace .mp-ok5 { opacity: 1; animation: mp-ok5 12s ease-out -9s infinite; }
        @keyframes mp-eng { 0%, 26% { opacity: 0; } 32% { opacity: 1; } 93% { opacity: 1; } 97%, 100% { opacity: 0; } }
        .cover--mindplace .mp-eng { opacity: 1; animation: mp-eng 12s ease-out -9s infinite; }
        @keyframes mp-fr1 { 0%, 34% { opacity: 0; } 38% { opacity: 1; } 95% { opacity: 1; } 100% { opacity: 0; } }
        @keyframes mp-fr2 { 0%, 40% { opacity: 0; } 44% { opacity: 1; } 95% { opacity: 1; } 100% { opacity: 0; } }
        @keyframes mp-fr3 { 0%, 46% { opacity: 0; } 50% { opacity: 1; } 95% { opacity: 1; } 100% { opacity: 0; } }
        @keyframes mp-fr4 { 0%, 52% { opacity: 0; } 56% { opacity: 1; } 95% { opacity: 1; } 100% { opacity: 0; } }
        @keyframes mp-fr5 { 0%, 58% { opacity: 0; } 62% { opacity: 1; } 95% { opacity: 1; } 100% { opacity: 0; } }
        .cover--mindplace .mp-fr1 { opacity: 1; animation: mp-fr1 12s ease-out -9s infinite; }
        .cover--mindplace .mp-fr2 { opacity: 1; animation: mp-fr2 12s ease-out -9s infinite; }
        .cover--mindplace .mp-fr3 { opacity: 1; animation: mp-fr3 12s ease-out -9s infinite; }
        .cover--mindplace .mp-fr4 { opacity: 1; animation: mp-fr4 12s ease-out -9s infinite; }
        .cover--mindplace .mp-fr5 { opacity: 1; animation: mp-fr5 12s ease-out -9s infinite; }
        @keyframes mp-play { 0%, 62% { opacity: 0; } 65% { opacity: 1; } 95% { opacity: 1; } 100% { opacity: 0; } }
        .cover--mindplace .mp-play { opacity: 1; animation: mp-play 12s ease-out -9s infinite; }

        /* 2 · TravelerApp · Pacer — recorded track draws in, a location pin replays it, waypoints log as it passes */
        @keyframes tv-draw { from { stroke-dashoffset: 1200; } to { stroke-dashoffset: 0; } }
        .cover--traveler .tv-route { stroke-dasharray: 1200 1200; stroke-dashoffset: 0; animation: tv-draw 2.2s ease-out both; }
        @keyframes tv-run { 0% { offset-distance: 0%; opacity: 0; } 5% { opacity: 1; } 95% { opacity: 1; } 100% { offset-distance: 100%; opacity: 1; } }
        .cover--traveler .tv-marker { offset-rotate: 0deg; opacity: 0; animation: tv-run 6s 2.1s ease-in-out infinite; }
        @keyframes tv-f1 { 0%, 15% { opacity: 0; transform: scale(.4); } 21% { opacity: 1; transform: scale(1); } 97% { opacity: 1; } 100% { opacity: 0; } }
        @keyframes tv-f2 { 0%, 45% { opacity: 0; transform: scale(.4); } 51% { opacity: 1; transform: scale(1); } 97% { opacity: 1; } 100% { opacity: 0; } }
        @keyframes tv-f3 { 0%, 71% { opacity: 0; transform: scale(.4); } 77% { opacity: 1; transform: scale(1); } 97% { opacity: 1; } 100% { opacity: 0; } }
        .cover--traveler .tv-f1 { opacity: 0; transform-box: fill-box; transform-origin: center; animation: tv-f1 6s 2.1s ease-out infinite; }
        .cover--traveler .tv-f2 { opacity: 0; transform-box: fill-box; transform-origin: center; animation: tv-f2 6s 2.1s ease-out infinite; }
        .cover--traveler .tv-f3 { opacity: 0; transform-box: fill-box; transform-origin: center; animation: tv-f3 6s 2.1s ease-out infinite; }
        @keyframes tv-pin { 0%, 100% { opacity: .4; } 50% { opacity: 1; } }
        .cover--traveler .tv-pin { animation: tv-pin 3.2s ease-in-out infinite; }

        /* 3 · UWB · Nearby Interaction — a device walks the gate: BLE discovery → UWB ranging → ACTION access */
        @keyframes uw-tag { 0% { offset-distance: 0%; opacity: 0; } 6% { opacity: 1; } 90% { opacity: 1; } 100% { offset-distance: 100%; opacity: 0; } }
        .cover--uwb .uw-tag { offset-rotate: 0deg; offset-distance: 100%; opacity: 1; animation: uw-tag 7s ease-in-out infinite; }
        @keyframes uw-zBle { 0%, 4%, 40%, 100% { opacity: 0; } 12%, 34% { opacity: .85; } }
        @keyframes uw-zUwb { 0%, 40%, 72%, 100% { opacity: 0; } 48%, 66% { opacity: .85; } }
        @keyframes uw-zAct { 0%, 70%, 94%, 100% { opacity: 0; } 78%, 88% { opacity: 1; } }
        .cover--uwb .uw-zBle { opacity: 0; animation: uw-zBle 7s ease-in-out infinite; }
        .cover--uwb .uw-zUwb { opacity: 0; animation: uw-zUwb 7s ease-in-out infinite; }
        .cover--uwb .uw-zAct { opacity: 0; animation: uw-zAct 7s ease-in-out infinite; }
        @keyframes uw-lB { 0%, 4%, 40%, 100% { opacity: .32; } 12%, 34% { opacity: 1; } }
        @keyframes uw-lU { 0%, 40%, 72%, 100% { opacity: .32; } 48%, 66% { opacity: 1; } }
        @keyframes uw-lA { 0%, 70%, 94%, 100% { opacity: .32; } 78%, 88% { opacity: 1; } }
        .cover--uwb .uw-lB { opacity: .32; animation: uw-lB 7s ease-in-out infinite; }
        .cover--uwb .uw-lU { opacity: .32; animation: uw-lU 7s ease-in-out infinite; }
        .cover--uwb .uw-lA { opacity: .32; animation: uw-lA 7s ease-in-out infinite; }
        @keyframes uw-tof { 0%, 42% { offset-distance: 0%; opacity: 0; } 46% { opacity: 1; } 54% { offset-distance: 100%; } 58% { offset-distance: 100%; opacity: 1; } 66% { offset-distance: 0%; opacity: 1; } 70%, 100% { opacity: 0; } }
        .cover--uwb .uw-tof { offset-rotate: 0deg; opacity: 0; animation: uw-tof 7s linear infinite; }
        @keyframes uw-fire { 0%, 72%, 94%, 100% { opacity: 0; } 79%, 88% { opacity: 1; } }
        .cover--uwb .uw-fire { opacity: 0; animation: uw-fire 7s ease-in-out infinite; }

        /* 4 · CAN Bus · J1939 — bits streaming down the differential pair, identifier fields decoded left→right */
        @keyframes cb-bit { 0% { offset-distance: 0%; opacity: 0; } 6% { opacity: 1; } 94% { opacity: 1; } 100% { offset-distance: 100%; opacity: 0; } }
        .cover--canbus .cb-bit { offset-rotate: 0deg; opacity: 0; animation: cb-bit 3s linear infinite; }
        @keyframes cb-field { 0%, 100% { opacity: 0; } 50% { opacity: .5; } }
        .cover--canbus .cb-field { opacity: 0; animation: cb-field 4s ease-in-out infinite; }

        /* 5 · Face Recognition · NPU — detector scan sweep, landmark mesh live, 128-D embedding read out */
        @keyframes fn-scan { 0% { transform: translateY(-104px); } 100% { transform: translateY(108px); } }
        .cover--face .fn-scan { animation: fn-scan 3.8s ease-in-out infinite alternate; }
        @keyframes fn-mesh { 0%, 100% { opacity: .55; } 50% { opacity: 1; } }
        .cover--face .fn-mesh { animation: fn-mesh 3.4s ease-in-out infinite; }
        @keyframes fn-embed { 0% { transform: translateX(0); opacity: 0; } 12% { opacity: .85; } 88% { opacity: .85; } 100% { transform: translateX(392px); opacity: 0; } }
        .cover--face .fn-embed { opacity: 0; animation: fn-embed 3s linear infinite; }

        /* 6 · Neural Meta-Learner — forward pass up the winning path, probability streams flowing, head firing */
        @keyframes ml-pass { 0% { offset-distance: 0%; opacity: 0; } 14% { opacity: 1; } 86% { opacity: 1; } 100% { offset-distance: 100%; opacity: 0; } }
        .cover--meta .ml-pass { offset-rotate: 0deg; opacity: 0; animation: ml-pass 3.2s ease-in-out infinite; }
        @keyframes ml-win { 0%, 58%, 100% { opacity: 0; } 80% { opacity: 1; } }
        .cover--meta .ml-win { opacity: 0; animation: ml-win 3.2s ease-in-out infinite; }
        @keyframes ml-stream { to { stroke-dashoffset: -40; } }
        .cover--meta .ml-stream { stroke-dasharray: 5 13; animation: ml-stream 1.7s linear infinite; }

        /* 7 · Comparative ML Evaluation — leaderboard fills in, operating point sweeps the winning ROC curve */
        @keyframes me-bar { from { transform: scaleX(0); } to { transform: scaleX(1); } }
        .cover--mleval .me-bar { transform-box: fill-box; transform-origin: left center; animation: me-bar 1.1s cubic-bezier(.2,.7,.2,1) both; }
        @keyframes me-trace { 0% { offset-distance: 0%; opacity: 0; } 10% { opacity: 1; } 90% { opacity: 1; } 100% { offset-distance: 100%; opacity: 0; } }
        .cover--mleval .me-trace { offset-rotate: 0deg; opacity: 0; animation: me-trace 4.6s ease-in-out infinite; }

        /* 8 · DL Image Colorization — colour draws in left→right over the grayscale base; chrominance point drifts */
        @keyframes co-draw { 0% { stroke-dashoffset: 820; } 66% { stroke-dashoffset: 0; } 100% { stroke-dashoffset: 0; } }
        @keyframes co-fade { 0%, 86% { opacity: 1; } 100% { opacity: 0; } }
        .cover--color .co-color { stroke-dasharray: 820; stroke-dashoffset: 0; opacity: 1; animation: co-draw 5.5s ease-in-out infinite, co-fade 5.5s ease-in-out infinite; }
        @keyframes co-front { 0% { transform: translateX(0); opacity: 0; } 8% { opacity: .9; } 58% { opacity: .9; } 66% { transform: translateX(672px); opacity: 0; } 100% { opacity: 0; } }
        .cover--color .co-front { opacity: 0; animation: co-front 5.5s ease-in-out infinite; }
        @keyframes co-ab { 0%, 100% { transform: translate(0, 0); } 25% { transform: translate(11px, -8px); } 50% { transform: translate(3px, -15px); } 75% { transform: translate(-9px, -6px); } }
        .cover--color .co-ab { animation: co-ab 7s ease-in-out infinite; }

        /* 9 · Other Studies — an archive: the collection stack simply settles into place (entrance only) */
        @keyframes os-card { from { opacity: 0; transform: translateY(11px); } to { opacity: 1; transform: translateY(0); } }
        .cover--other .os-card { animation: os-card .7s cubic-bezier(.2,.7,.2,1) both; }

        /* Accessibility — no motion means the finished static cover, nothing half-drawn */
        @media (prefers-reduced-motion: reduce) {
            .visual-bg svg.cover, .visual-bg svg.cover * { animation: none !important; }
            .visual-bg { transition: none !important; transform: none !important; }  /* freeze the slow ken-burns too */
            .cover .flow,
            .cover--mindplace .mp-brief, .cover--mindplace .mp-hub,
            .cover--mindplace .mp-flow1, .cover--mindplace .mp-flow2, .cover--mindplace .mp-flow3, .cover--mindplace .mp-flow4,
            .cover--mindplace .mp-sp1, .cover--mindplace .mp-sp2, .cover--mindplace .mp-sp3, .cover--mindplace .mp-sp4, .cover--mindplace .mp-sp5,
            .cover--traveler .tv-marker, .cover--traveler .tv-f1, .cover--traveler .tv-f2, .cover--traveler .tv-f3,
            .cover--uwb .uw-tof, .cover--uwb .uw-fire, .cover--uwb .uw-zBle, .cover--uwb .uw-zUwb, .cover--uwb .uw-zAct,
            .cover--canbus .cb-bit, .cover--canbus .cb-field, .cover--face .fn-embed,
            .cover--meta .ml-pass, .cover--meta .ml-win, .cover--mleval .me-trace,
            .cover--qplace .qp-send, .cover--qplace .qp-entry,
            .cover--qplace .qp-thinkA1, .cover--qplace .qp-thinkA2, .cover--qplace .qp-thinkB,
            .cover--qplace .qp-tB, .cover--qplace .qp-carB,
            .cover--qplace .qp-pathB, .cover--qplace .qp-ladB, .cover--qplace .qp-arcB,
            .cover--qplace .qp-d1, .cover--qplace .qp-d2, .cover--qplace .qp-d3,
            .cover--qplace .qp-rej, .cover--qplace .qp-dB,
            .cover--qplace .qp-wCap, .cover--qplace .qp-shimA, .cover--qplace .qp-shimB,
            .cover--color .co-front { opacity: 0 !important; }
        }
