/* «Сигнал» — завантаження головної (js/intro-signal.js). Лише transform/opacity (scan — ще clip-path). */

/* ======== 1. ЗАВАНТАЖУВАЧ: декор довкола шестерні ========================== */
.fx-loader-core { position: relative; display: inline-flex; align-items: center; justify-content: center; width: 140px; height: 140px; margin-bottom: 4px; }
.fx-loader-core > :last-child { position: relative; z-index: 1; margin: 0 !important; }
.fx-loader-text { animation: none !important; transition: opacity .22s ease, transform .22s ease; min-height: 1.75rem; }
.fx-loader-text.fx-text-out { opacity: 0; transform: translateY(-8px); }
.fx-loader-text.fx-text-in  { opacity: 0; transform: translateY(8px); transition: none; }

/* radar (і початок crash): кола + орбіта */
.fx-ping { position: absolute; inset: 10px; border-radius: 50%; border: 3px solid rgba(139,92,246,.8); box-shadow: 0 0 12px rgba(139,92,246,.35);
    transform: scale(.35); opacity: 0; animation: fx-ping 2.4s cubic-bezier(.2,.6,.3,1) infinite; }
.fx-ping-2 { animation-delay: .8s; border-color: rgba(59,130,246,.75); box-shadow: 0 0 12px rgba(59,130,246,.35); }
.fx-ping-3 { animation-delay: 1.6s; }
.fx-orbit { position: absolute; inset: 16px; animation: fx-orbit 2.2s linear infinite; }
.fx-orbit i { position: absolute; left: 50%; top: 0; width: 7px; height: 7px; margin-left: -3.5px; border-radius: 50%;
    background: #8b5cf6; box-shadow: 0 0 8px #8b5cf6; transform-origin: 3.5px 54px; }
.fx-orbit i:nth-child(2) { transform: rotate(120deg); background: #3b82f6; box-shadow: 0 0 8px #3b82f6; }
.fx-orbit i:nth-child(3) { transform: rotate(240deg); background: #ec4899; box-shadow: 0 0 8px #ec4899; }

/* net: вузли й лінії, що «передають пакети» */
.fx-net { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; }
.fx-net-line { stroke: #8b5cf6; stroke-width: 2; stroke-dasharray: 4 6; opacity: .25; animation: fx-net-line 1.1s linear infinite; }
.fx-net-node { fill: #3b82f6; transform-box: fill-box; transform-origin: center; animation: fx-net-node 1.1s ease-in-out infinite; }
.fx-net-node:nth-of-type(2n) { fill: #ec4899; }

/* scan: рамка, промінь-сканер, біти летять угору */
.fx-scan-box { position: absolute; inset: 22px; border: 2px solid rgba(34,197,94,.45); border-radius: 14px; }
.fx-scan-line { position: absolute; left: 16px; right: 16px; top: 22px; height: 3px; border-radius: 2px; background: #22c55e;
    box-shadow: 0 0 10px #22c55e, 0 0 20px rgba(34,197,94,.5); animation: fx-scan 1.4s ease-in-out infinite alternate; }
.fx-bit { position: absolute; bottom: 4px; font: 700 12px/1 ui-monospace, monospace; color: #22c55e; opacity: 0; animation: fx-bit 1.6s ease-out infinite; }

/* sparks: промені з іскрами */
.fx-spark-ray { position: absolute; left: 50%; top: 50%; width: 0; height: 0; }
.fx-spark-ray i { position: absolute; left: -2.5px; top: -2.5px; width: 5px; height: 5px; border-radius: 50%; background: #fbbf24;
    box-shadow: 0 0 6px #f59e0b; opacity: 0; animation: fx-spark 1.1s ease-out infinite; }
.fx-l-sparks .gear-icon, .fx-l-sparks > :last-child { filter: drop-shadow(0 0 6px rgba(251,191,36,.6)); }

/* wifi: три дуги загоряються по черзі */
.fx-wifi { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; }
.fx-wifi-arc { fill: none; stroke: #8b5cf6; stroke-width: 5; stroke-linecap: round; opacity: .15; animation: fx-wifi 1.5s ease-in-out infinite; }
.fx-wifi-floor { position: absolute; left: 35px; right: 35px; bottom: 18px; height: 6px; border-radius: 50%; background: rgba(139,92,246,.25); animation: fx-floor 1.5s ease-in-out infinite; }

/* crash: шестерня нервує дедалі сильніше */
.fx-l-crash > :last-child { animation: fx-jitter .35s steps(2) infinite; }

@keyframes fx-ping     { 0% { transform: scale(.35); opacity: 1; } 70% { opacity: .35; } 100% { transform: scale(1.7); opacity: 0; } }
@keyframes fx-orbit    { to { transform: rotate(360deg); } }
@keyframes fx-net-line { 0% { stroke-dashoffset: 20; opacity: .2; } 50% { opacity: .9; } 100% { stroke-dashoffset: 0; opacity: .2; } }
@keyframes fx-net-node { 0%, 100% { transform: scale(.6); opacity: .4; } 50% { transform: scale(1.25); opacity: 1; } }
@keyframes fx-scan     { 0% { transform: translateY(0); } 100% { transform: translateY(94px); } }
@keyframes fx-bit      { 0% { transform: translateY(0); opacity: 0; } 20% { opacity: .9; } 100% { transform: translateY(-110px); opacity: 0; } }
@keyframes fx-spark    { 0% { transform: translateY(-14px) scale(1); opacity: 0; } 15% { opacity: 1; } 100% { transform: translateY(-66px) scale(.3); opacity: 0; } }
@keyframes fx-wifi     { 0%, 100% { opacity: .15; } 30%, 60% { opacity: 1; } }
@keyframes fx-floor    { 0%, 100% { transform: scaleX(.8); opacity: .5; } 50% { transform: scaleX(1); opacity: 1; } }
@keyframes fx-jitter   { 0% { transform: translate(-1px, 0) rotate(-4deg); } 100% { transform: translate(1px, -1px) rotate(5deg); } }

/* ======== 2. РОЗКРИТТЯ ===================================================== */
.fx-intro { position: fixed; inset: 0; z-index: 90; pointer-events: none; overflow: hidden; }
.fx-launch { position: absolute; left: var(--ox); top: var(--oy); transform: translate(-50%, -50%); animation: fx-launch .55s cubic-bezier(.2,.8,.2,1) forwards; }
.fx-launch > *, .fx-fall > * { margin: 0 !important; animation: none !important; }

/* хвиля: велике коло-кільце, яке масштабується від крапки до краю екрана */
.fx-wave { position: absolute; left: var(--ox); top: var(--oy); width: calc(var(--fx-r) * 2); height: calc(var(--fx-r) * 2);
    margin: calc(var(--fx-r) * -1) 0 0 calc(var(--fx-r) * -1); border-radius: 50%;
    background: radial-gradient(closest-side, transparent 93%, rgba(139,92,246,.7) 97%, transparent 100%);
    transform: scale(.02); opacity: 0; animation: fx-wave .9s cubic-bezier(.25,.6,.3,1) forwards; will-change: transform, opacity; }
.fx-wave-2 { background: radial-gradient(closest-side, transparent 95%, rgba(59,130,246,.55) 98%, transparent 100%); animation-delay: .14s; }
.fx-wave-thin { background: radial-gradient(closest-side, transparent 97%, rgba(139,92,246,.55) 99%, transparent 100%); }

/* scan: світлий промінь проходить екраном згори вниз */
.fx-sweep { position: absolute; left: 0; right: 0; top: 0; height: 4px; background: #22c55e;
    box-shadow: 0 0 16px #22c55e, 0 0 40px rgba(34,197,94,.5); animation: fx-sweep .8s cubic-bezier(.4,0,.6,1) forwards; }

/* sparks: сніп іскор із шестерні */
.fx-burst { position: absolute; left: var(--ox); top: var(--oy); width: 6px; height: 6px; margin: -3px; border-radius: 50%;
    background: #fbbf24; box-shadow: 0 0 8px #f59e0b; animation: fx-burst .7s cubic-bezier(.1,.8,.3,1) forwards; }

/* віджети — спільне: стартовий стан прозорий, загоряються із затримкою --fx-d */
.fx-w { opacity: 0; }
.fx-go .fx-w { opacity: 1; transition: opacity .45s ease var(--fx-d, 0ms), transform .6s cubic-bezier(.2,.8,.2,1) var(--fx-d, 0ms); }
.fx-w.fx-v-radar  { transform: perspective(900px) rotateX(9deg) translateY(18px) scale(.97); transform-origin: 50% 100%; }
.fx-w.fx-v-net    { opacity: .55; transform: translate(var(--fx-tx, 0), var(--fx-ty, 0)) scale(.25); }
.fx-w.fx-v-scan   { opacity: 1; clip-path: inset(0 0 100% 0); }
.fx-w.fx-v-sparks { transform: scale(.82); }
.fx-w.fx-v-wifi   { transform: perspective(1000px) rotateY(-60deg); transform-origin: 0 50%; }
.fx-go .fx-w.fx-v-radar, .fx-go .fx-w.fx-v-net, .fx-go .fx-w.fx-v-sparks, .fx-go .fx-w.fx-v-wifi { transform: none; }
.fx-go .fx-w.fx-v-net    { transition: opacity .3s ease var(--fx-d), transform .7s cubic-bezier(.2,.9,.25,1) var(--fx-d); }
.fx-go .fx-w.fx-v-scan   { clip-path: inset(0 0 0 0); transition: clip-path .45s cubic-bezier(.4,0,.2,1) var(--fx-d); }
.fx-go .fx-w.fx-v-sparks { transition: opacity .25s ease var(--fx-d), transform .55s cubic-bezier(.34,1.7,.5,1) var(--fx-d); }
.fx-go .fx-w.fx-v-wifi   { transition: opacity .35s ease var(--fx-d), transform .6s cubic-bezier(.2,.8,.2,1) var(--fx-d); }

/* crash: шестерня зривається й падає; плитки кольору фону тріскаються й осипаються */
.fx-fall { position: absolute; transform: translate(-50%, -50%); z-index: 2; animation: fx-fall .9s cubic-bezier(.5,0,.9,.6) forwards; }
.fx-crash-area { position: absolute; animation: fx-crack .18s steps(2) 2; }
.fx-tile { position: absolute; background: #f3f4f6; box-shadow: inset 0 0 0 1px rgba(100,116,139,.35);
    animation: fx-tile .75s cubic-bezier(.55,0,.95,.5) var(--d) forwards; }
.dark .fx-tile { background: #111827; box-shadow: inset 0 0 0 1px rgba(148,163,184,.25); }

@keyframes fx-launch { 0% { transform: translate(-50%, -50%) scale(1) rotate(0); opacity: 1; } 100% { transform: translate(-50%, -50%) scale(2.6) rotate(140deg); opacity: 0; } }
@keyframes fx-wave   { 0% { transform: scale(.02); opacity: 1; } 80% { opacity: .8; } 100% { transform: scale(1); opacity: 0; } }
@keyframes fx-sweep  { 0% { transform: translateY(-10px); opacity: 1; } 90% { opacity: 1; } 100% { transform: translateY(100vh); opacity: 0; } }
@keyframes fx-burst  { 0% { transform: rotate(var(--a)) translateY(0) scale(1); opacity: 1; } 100% { transform: rotate(var(--a)) translateY(calc(var(--r) * -1)) scale(.3); opacity: 0; } }
@keyframes fx-fall   { 0% { transform: translate(-50%, -50%) rotate(0); } 15% { transform: translate(-50%, -46%) rotate(-18deg); }
                       100% { transform: translate(-50%, 100vh) rotate(220deg); } }
@keyframes fx-crack  { 0% { transform: translate(-3px, 1px); } 100% { transform: translate(3px, -1px); } }
@keyframes fx-tile   { 0% { transform: translate(0, 0) rotate(0); opacity: 1; } 12% { transform: translate(0, 4px) rotate(calc(var(--rot) * .1)); }
                       100% { transform: translate(var(--dx), 110vh) rotate(var(--rot)); opacity: .9; } }

/* ======== 8-БІТ: усе кроками, квадратне ===================================== */
html.theme-8bit .fx-ping { border-radius: 0; border-width: 4px; border-color: #fcd000; box-shadow: none; animation-timing-function: steps(6); }
html.theme-8bit .fx-ping-2 { border-color: #3cbcfc; }
html.theme-8bit .fx-orbit { animation-timing-function: steps(12); }
html.theme-8bit .fx-orbit i, html.theme-8bit .fx-spark-ray i, html.theme-8bit .fx-burst { border-radius: 0; box-shadow: none; }
html.theme-8bit .fx-orbit i { background: #fcd000; }
html.theme-8bit .fx-orbit i:nth-child(2) { background: #3cbcfc; }
html.theme-8bit .fx-orbit i:nth-child(3) { background: #f878f8; }
html.theme-8bit .fx-net, html.theme-8bit .fx-wifi { shape-rendering: crispEdges; }
html.theme-8bit .fx-net-line, html.theme-8bit .fx-net-node, html.theme-8bit .fx-wifi-arc, html.theme-8bit .fx-bit,
html.theme-8bit .fx-spark-ray i, html.theme-8bit .fx-scan-line { animation-timing-function: steps(4) !important; }
html.theme-8bit .fx-scan-box { border-radius: 0; border-width: 3px; }
html.theme-8bit .fx-launch, html.theme-8bit .fx-fall, html.theme-8bit .fx-tile, html.theme-8bit .fx-burst, html.theme-8bit .fx-sweep { animation-timing-function: steps(6); }
html.theme-8bit .fx-tile { background: #0b0b1f; box-shadow: inset 0 0 0 2px #2a2a5a; }
html.theme-8bit .fx-wave { border-radius: 0; animation-timing-function: steps(8);
    background: linear-gradient(#fcd000, #fcd000) top/100% 6px no-repeat, linear-gradient(#fcd000, #fcd000) bottom/100% 6px no-repeat,
                linear-gradient(#fcd000, #fcd000) left/6px 100% no-repeat, linear-gradient(#fcd000, #fcd000) right/6px 100% no-repeat; }
html.theme-8bit .fx-wave-2 { background: linear-gradient(#3cbcfc, #3cbcfc) top/100% 6px no-repeat, linear-gradient(#3cbcfc, #3cbcfc) bottom/100% 6px no-repeat,
                linear-gradient(#3cbcfc, #3cbcfc) left/6px 100% no-repeat, linear-gradient(#3cbcfc, #3cbcfc) right/6px 100% no-repeat; }
/* віджети у 8-біт: незалежно від ефекту — «проявляються» смугами, але з затримками свого ефекту */
html.theme-8bit .fx-w { transform: none !important; clip-path: inset(0 0 100% 0); opacity: 1; }
html.theme-8bit.fx-go .fx-w { clip-path: inset(0 0 0 0); transition: clip-path .4s steps(5) var(--fx-d, 0ms); }

@media (prefers-reduced-motion: reduce) {
    .fx-intro, .fx-ping, .fx-orbit, .fx-net, .fx-scan-line, .fx-bit, .fx-spark-ray, .fx-wifi { display: none; }
    .fx-w { opacity: 1 !important; transform: none !important; clip-path: none !important; }
}
