diff --git a/package-lock.json b/package-lock.json index a00f83c2..61e5b7c6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -154,6 +154,7 @@ "integrity": "sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.5", @@ -439,6 +440,7 @@ "resolved": "https://registry.npmjs.org/@codemirror/autocomplete/-/autocomplete-6.19.1.tgz", "integrity": "sha512-q6NenYkEy2fn9+JyjIxMWcNjzTL/IhwqfzOut1/G3PrIFkrbl4AL7Wkse5tLrQUUyqGoAKU5+Pi5jnnXxH5HGw==", "license": "MIT", + "peer": true, "dependencies": { "@codemirror/language": "^6.0.0", "@codemirror/state": "^6.0.0", @@ -487,6 +489,7 @@ "resolved": "https://registry.npmjs.org/@codemirror/lang-css/-/lang-css-6.3.1.tgz", "integrity": "sha512-kr5fwBGiGtmz6l0LSJIbno9QrifNMUusivHbnA1H6Dmqy4HZFte3UAICix1VuKo0lMPKQr2rqB+0BkKi/S3Ejg==", "license": "MIT", + "peer": true, "dependencies": { "@codemirror/autocomplete": "^6.0.0", "@codemirror/language": "^6.0.0", @@ -513,6 +516,7 @@ "resolved": "https://registry.npmjs.org/@codemirror/lang-html/-/lang-html-6.4.11.tgz", "integrity": "sha512-9NsXp7Nwp891pQchI7gPdTwBuSuT3K65NGTHWHNJ55HjYcHLllr0rbIZNdOzas9ztc1EUVBlHou85FFZS4BNnw==", "license": "MIT", + "peer": true, "dependencies": { "@codemirror/autocomplete": "^6.0.0", "@codemirror/lang-css": "^6.0.0", @@ -540,6 +544,7 @@ "resolved": "https://registry.npmjs.org/@codemirror/lang-javascript/-/lang-javascript-6.2.4.tgz", "integrity": "sha512-0WVmhp1QOqZ4Rt6GlVGwKJN3KW7Xh4H2q8ZZNGZaP6lRdxXJzmjm4FqvmOojVj6khWJHIb9sp7U/72W7xQgqAA==", "license": "MIT", + "peer": true, "dependencies": { "@codemirror/autocomplete": "^6.0.0", "@codemirror/language": "^6.6.0", @@ -740,6 +745,7 @@ "resolved": "https://registry.npmjs.org/@codemirror/language/-/language-6.11.3.tgz", "integrity": "sha512-9HBM2XnwDj7fnu0551HkGdrUrrqmYq/WC5iv6nbY2WdicXdGbhR/gfbZOH73Aqj4351alY1+aoG9rCNfiwS1RA==", "license": "MIT", + "peer": true, "dependencies": { "@codemirror/state": "^6.0.0", "@codemirror/view": "^6.23.0", @@ -816,6 +822,7 @@ "resolved": "https://registry.npmjs.org/@codemirror/state/-/state-6.5.2.tgz", "integrity": "sha512-FVqsPqtPWKVVL3dPSxy8wEF/ymIEuVzF1PK3VbUgrxXpJUSHQWWZz4JMToquRxnkw+36LTamCZG2iua2Ptq0fA==", "license": "MIT", + "peer": true, "dependencies": { "@marijn/find-cluster-break": "^1.0.0" } @@ -837,6 +844,7 @@ "resolved": "https://registry.npmjs.org/@codemirror/view/-/view-6.38.6.tgz", "integrity": "sha512-qiS0z1bKs5WOvHIAC0Cybmv4AJSkAXgX5aD6Mqd2epSLlVJsQl8NG23jCVouIgkh4All/mrbdsf2UOLFnJw0tw==", "license": "MIT", + "peer": true, "dependencies": { "@codemirror/state": "^6.5.0", "crelt": "^1.0.6", @@ -1164,6 +1172,7 @@ "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -1550,7 +1559,6 @@ "dev": true, "license": "BSD-2-Clause", "optional": true, - "peer": true, "dependencies": { "cross-dirname": "^0.1.0", "debug": "^4.3.4", @@ -1572,7 +1580,6 @@ "dev": true, "license": "MIT", "optional": true, - "peer": true, "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", @@ -2529,7 +2536,8 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/@lezer/common/-/common-1.3.0.tgz", "integrity": "sha512-L9X8uHCYU310o99L3/MpJKYxPzXPOS7S0NmBaM7UO/x2Kb2WbmMLSkfvdr1KxRIFYOpbY0Jhn7CfLSUDzL8arQ==", - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/@lezer/cpp": { "version": "1.1.3", @@ -2569,6 +2577,7 @@ "resolved": "https://registry.npmjs.org/@lezer/highlight/-/highlight-1.2.3.tgz", "integrity": "sha512-qXdH7UqTvGfdVBINrgKhDsVTJTxactNNxLk7+UMwZhU13lMHaOBlJe9Vqp907ya56Y3+ed2tlqzys7jDkTmW0g==", "license": "MIT", + "peer": true, "dependencies": { "@lezer/common": "^1.3.0" } @@ -2600,6 +2609,7 @@ "resolved": "https://registry.npmjs.org/@lezer/javascript/-/javascript-1.5.4.tgz", "integrity": "sha512-vvYx3MhWqeZtGPwDStM2dwgljd5smolYD2lR2UyFcHfxbBQebqx8yjmFmxtJ/E6nN6u1D9srOiVWm3Rb4tmcUA==", "license": "MIT", + "peer": true, "dependencies": { "@lezer/common": "^1.2.0", "@lezer/highlight": "^1.1.3", @@ -2622,6 +2632,7 @@ "resolved": "https://registry.npmjs.org/@lezer/lr/-/lr-1.4.2.tgz", "integrity": "sha512-pu0K1jCIdnQ12aWNaAVU5bzi7Bd1w54J3ECgANPmYLtQKP0HBj2cE/5coBD66MT10xbtIuUr7tg0Shbsvk0mDA==", "license": "MIT", + "peer": true, "dependencies": { "@lezer/common": "^1.0.0" } @@ -4845,6 +4856,7 @@ "integrity": "sha512-NMv9ASNARoKksWtsq/SHakpYAYnhBrQgGD8zkLYk/jaK8jUGn08CfEdTRgYhMypUQAfzSP8W6gNLe0q19/t4VA==", "devOptional": true, "license": "MIT", + "peer": true, "dependencies": { "@types/node": "*" } @@ -5002,6 +5014,7 @@ "resolved": "https://registry.npmjs.org/@types/express/-/express-5.0.5.tgz", "integrity": "sha512-LuIQOcb6UmnF7C1PCFmEU1u2hmiHL43fgFQX67sN3H4Z+0Yk0Neo++mFsBjhOAuLzvlQeqAAkeDOZrJs9rzumQ==", "license": "MIT", + "peer": true, "dependencies": { "@types/body-parser": "*", "@types/express-serve-static-core": "^5.0.0", @@ -5124,6 +5137,7 @@ "resolved": "https://registry.npmjs.org/@types/node/-/node-24.9.2.tgz", "integrity": "sha512-uWN8YqxXxqFMX2RqGOrumsKeti4LlmIMIyV0lgut4jx7KQBcBiW6vkDtIBvHnHIquwNfJhk8v2OtmO8zXWHfPA==", "license": "MIT", + "peer": true, "dependencies": { "undici-types": "~7.16.0" } @@ -5166,6 +5180,7 @@ "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.2.tgz", "integrity": "sha512-6mDvHUFSjyT2B2yeNx2nUgMxh9LtOWvkhIU3uePn2I2oyNymUAX1NIsdgviM4CH+JSrp2D2hsMvJOkxY+0wNRA==", "license": "MIT", + "peer": true, "dependencies": { "csstype": "^3.0.2" } @@ -5176,6 +5191,7 @@ "integrity": "sha512-9KQPoO6mZCi7jcIStSnlOWn2nEF3mNmyr3rIAsGnAbQKYbRLyqmeSc39EVgtxXVia+LMT8j3knZLAZAh+xLmrw==", "devOptional": true, "license": "MIT", + "peer": true, "peerDependencies": { "@types/react": "^19.2.0" } @@ -5343,6 +5359,7 @@ "integrity": "sha512-BnOroVl1SgrPLywqxyqdJ4l3S2MsKVLDVxZvjI1Eoe8ev2r3kGDo+PcMihNmDE+6/KjkTubSJnmqGZZjQSBq/g==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@typescript-eslint/scope-manager": "8.46.2", "@typescript-eslint/types": "8.46.2", @@ -5719,7 +5736,8 @@ "version": "5.5.0", "resolved": "https://registry.npmjs.org/@xterm/xterm/-/xterm-5.5.0.tgz", "integrity": "sha512-hqJHYaQb5OptNunnyAnkHyM8aCjZ1MEIDTQu1iIbbTD/xops91NB5yq1ZK/dC2JDbVWtF23zUtl9JE2NqwT87A==", - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/7zip-bin": { "version": "5.2.0", @@ -5754,6 +5772,7 @@ "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "dev": true, "license": "MIT", + "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -6176,6 +6195,7 @@ "integrity": "sha512-3yVdyZhklTiNrtg+4WqHpJpFDd+WHTg2oM7UcR80GqL05AOV0xEJzc6qNvFYoEtE+hRp1n9MpN6/+4yhlGkDXQ==", "hasInstallScript": true, "license": "MIT", + "peer": true, "dependencies": { "bindings": "^1.5.0", "prebuild-install": "^7.1.1" @@ -6310,6 +6330,7 @@ } ], "license": "MIT", + "peer": true, "dependencies": { "baseline-browser-mapping": "^2.8.19", "caniuse-lite": "^1.0.30001751", @@ -7313,6 +7334,7 @@ "integrity": "sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "env-paths": "^2.2.1", "import-fresh": "^3.3.0", @@ -7389,8 +7411,7 @@ "integrity": "sha512-+R08/oI0nl3vfPcqftZRpytksBXDzOUveBq/NBVx0sUp1axwzPQrKinNx5yd5sxPu8j1wIy8AfnVQ+5eFdha6Q==", "dev": true, "license": "MIT", - "optional": true, - "peer": true + "optional": true }, "node_modules/cross-spawn": { "version": "7.0.6", @@ -7849,6 +7870,7 @@ "integrity": "sha512-59CAAjAhTaIMCN8y9kD573vDkxbs1uhDcrFLHSgutYdPcGOU35Rf95725snvzEOy4BFB7+eLJ8djCNPmGwG67w==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "app-builder-lib": "26.0.12", "builder-util": "26.0.11", @@ -7946,8 +7968,7 @@ "version": "3.1.7", "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.1.7.tgz", "integrity": "sha512-VaTstWtsneJY8xzy7DekmYWEOZcmzIe3Qb3zPd4STve1OBTa+e+WmS1ITQec1fZYXI3HCsOZZiSMpG6oxoWMWQ==", - "license": "(MPL-2.0 OR Apache-2.0)", - "peer": true + "license": "(MPL-2.0 OR Apache-2.0)" }, "node_modules/dot-prop": { "version": "5.3.0", @@ -8299,7 +8320,6 @@ "dev": true, "hasInstallScript": true, "license": "MIT", - "peer": true, "dependencies": { "@electron/asar": "^3.2.1", "debug": "^4.1.1", @@ -8320,7 +8340,6 @@ "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "graceful-fs": "^4.1.2", "jsonfile": "^4.0.0", @@ -8336,7 +8355,6 @@ "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", "dev": true, "license": "MIT", - "peer": true, "optionalDependencies": { "graceful-fs": "^4.1.6" } @@ -8347,7 +8365,6 @@ "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">= 4.0.0" } @@ -8610,6 +8627,7 @@ "integrity": "sha512-iy2GE3MHrYTL5lrCtMZ0X1KLEKKUjmK0kzwcnefhR66txcEmXZD2YWgR5GNdcEwkNx3a0siYkSvl0vIC+Svjmg==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.1", @@ -10208,6 +10226,7 @@ } ], "license": "MIT", + "peer": true, "dependencies": { "@babel/runtime": "^7.27.6" }, @@ -11749,7 +11768,6 @@ "resolved": "https://registry.npmjs.org/marked/-/marked-14.0.0.tgz", "integrity": "sha512-uIj4+faQ+MgHgwUW1l2PsPglZLOLOT1uErt06dAPtx2kjteLAkbsd/0FiYg/MGS+i7ZKLb7w2WClxHkzOOuryQ==", "license": "MIT", - "peer": true, "bin": { "marked": "bin/marked.js" }, @@ -13777,7 +13795,6 @@ "dev": true, "license": "MIT", "optional": true, - "peer": true, "dependencies": { "commander": "^9.4.0" }, @@ -13795,7 +13812,6 @@ "dev": true, "license": "MIT", "optional": true, - "peer": true, "engines": { "node": "^12.20.0 || >=14" } @@ -14247,6 +14263,7 @@ "resolved": "https://registry.npmjs.org/react/-/react-19.2.0.tgz", "integrity": "sha512-tmbWg6W31tQLeB5cdIBOicJDJRR2KzXsV7uSK9iNfLWQ5bIZfxuPEHp7M8wiHyHnn0DD1i7w3Zmin0FtkrwoCQ==", "license": "MIT", + "peer": true, "engines": { "node": ">=0.10.0" } @@ -14256,6 +14273,7 @@ "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.0.tgz", "integrity": "sha512-UlbRu4cAiGaIewkPyiRGJk0imDN2T3JjieT6spoL2UeSf5od4n5LB/mQ4ejmxhCFT1tYe8IvaFulzynWovsEFQ==", "license": "MIT", + "peer": true, "dependencies": { "scheduler": "^0.27.0" }, @@ -14282,6 +14300,7 @@ "resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.66.0.tgz", "integrity": "sha512-xXBqsWGKrY46ZqaHDo+ZUYiMUgi8suYu5kdrS20EG8KiL7VRQitEbNjm+UcrDYrNi1YLyfpmAeGjCZYXLT9YBw==", "license": "MIT", + "peer": true, "engines": { "node": ">=18.0.0" }, @@ -14429,6 +14448,7 @@ "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-9.2.0.tgz", "integrity": "sha512-ROY9fvHhwOD9ySfrF0wmvu//bKCQ6AeZZq1nJNtbDC+kk5DuSuNX/n6YWYF/SYy7bSba4D4FSz8DJeKY/S/r+g==", "license": "MIT", + "peer": true, "dependencies": { "@types/use-sync-external-store": "^0.0.6", "use-sync-external-store": "^1.4.0" @@ -14637,7 +14657,8 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/redux/-/redux-5.0.1.tgz", "integrity": "sha512-M9/ELqF6fy8FwmkpnF0S3YKOqMyoWJ4+CS5Efg2ct3oY9daQvd/Pc71FpGZsVsbl3Cpb+IIcjBDUnnyBdQbq4w==", - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/redux-thunk": { "version": "3.1.0", @@ -15958,7 +15979,6 @@ "integrity": "sha512-yYrrsWnrXMcdsnu/7YMYAofM1ktpL5By7vZhf15CrXijWWrEYZks5AXBudalfSWJLlnen/QUJUB5aoB0kqZUGA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "mkdirp": "^0.5.1", "rimraf": "~2.6.2" @@ -15999,7 +16019,6 @@ "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "minimist": "^1.2.6" }, @@ -16014,7 +16033,6 @@ "deprecated": "Rimraf versions prior to v4 are no longer supported", "dev": true, "license": "ISC", - "peer": true, "dependencies": { "glob": "^7.1.3" }, @@ -16119,6 +16137,7 @@ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "license": "MIT", + "peer": true, "engines": { "node": ">=12" }, @@ -16324,6 +16343,7 @@ "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", "devOptional": true, "license": "Apache-2.0", + "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -16736,6 +16756,7 @@ "resolved": "https://registry.npmjs.org/vite/-/vite-7.1.12.tgz", "integrity": "sha512-ZWyE8YXEXqJrrSLvYgrRP7p62OziLW7xI5HYGWFzOvupfAlrLvURSzv/FyGyy0eidogEM3ujU+kUG1zuHgb6Ug==", "license": "MIT", + "peer": true, "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.5.0", @@ -16827,6 +16848,7 @@ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "license": "MIT", + "peer": true, "engines": { "node": ">=12" }, diff --git a/src/ui/components/LoadingOverlay.tsx b/src/ui/components/LoadingOverlay.tsx index a660cdab..d6869c8d 100644 --- a/src/ui/components/LoadingOverlay.tsx +++ b/src/ui/components/LoadingOverlay.tsx @@ -20,16 +20,22 @@ export function LoadingOverlay({ }: LoadingOverlayProps) { const [isShowing, setIsShowing] = useState(false); const [isFadingOut, setIsFadingOut] = useState(false); - const [animationType, setAnimationType] = useState<'glitch' | 'breathe' | 'typewriter' | 'scanner' | 'pulse'>('glitch'); + const [animationType, setAnimationType] = useState< + "glitch" | "breathe" | "typewriter" | "scanner" | "pulse" + >("glitch"); const showStartTimeRef = useRef(null); const minDurationTimerRef = useRef(null); useEffect(() => { if (visible) { // Randomly choose animation type from 5 options - const animations: ('glitch' | 'breathe' | 'typewriter' | 'scanner' | 'pulse')[] = [ - 'glitch', 'breathe', 'typewriter', 'scanner', 'pulse' - ]; + const animations: ( + | "glitch" + | "breathe" + | "typewriter" + | "scanner" + | "pulse" + )[] = ["glitch", "breathe", "typewriter", "scanner", "pulse"]; const randomIndex = Math.floor(Math.random() * 5); setAnimationType(animations[randomIndex]); @@ -448,7 +454,96 @@ export function LoadingOverlay({ } } - /* Breathe Animation Styles */ + /* Enhanced Glitch Fullscreen Effects */ + @keyframes rgb-split-bg { + 0%, 100% { + transform: translate(0, 0); + } + 33% { + transform: translate(-10px, 5px); + } + 66% { + transform: translate(10px, -5px); + } + } + + @keyframes signal-distort { + 0%, 100% { + clip-path: inset(0 0 0 0); + } + 10% { + clip-path: inset(20% 0 0 0); + } + 20% { + clip-path: inset(0 0 30% 0); + } + 30% { + clip-path: inset(40% 0 0 0); + } + 40% { + clip-path: inset(0 0 50% 0); + } + 50% { + clip-path: inset(0 0 0 0); + } + } + + .glitch-fullscreen { + position: absolute; + inset: 0; + overflow: hidden; + background: transparent; + } + + .rgb-split-layers { + position: absolute; + inset: 0; + pointer-events: none; + } + + .rgb-layer { + position: absolute; + inset: 0; + mix-blend-mode: screen; + animation: rgb-split-bg 0.5s steps(1, end) infinite; + } + + .rgb-layer.red { + background: radial-gradient(circle at 30% 40%, rgba(255, 0, 100, 0.15) 0%, transparent 50%); + animation-delay: 0s; + } + + .rgb-layer.green { + background: radial-gradient(circle at 70% 60%, rgba(0, 255, 100, 0.15) 0%, transparent 50%); + animation-delay: 0.1s; + } + + .rgb-layer.blue { + background: radial-gradient(circle at 50% 50%, rgba(0, 100, 255, 0.15) 0%, transparent 50%); + animation-delay: 0.2s; + } + + .signal-bars { + position: absolute; + inset: 0; + pointer-events: none; + animation: signal-distort 4s steps(1, end) infinite; + } + + .signal-bar { + position: absolute; + width: 100%; + height: 3px; + background: rgba(255, 255, 255, 0.1); + animation: signal-distort 3s steps(1, end) infinite; + } + + .signal-bar:nth-child(1) { top: 20%; animation-delay: 0s; } + .signal-bar:nth-child(2) { top: 40%; animation-delay: 0.5s; } + .signal-bar:nth-child(3) { top: 60%; animation-delay: 1s; } + .signal-bar:nth-child(4) { top: 80%; animation-delay: 1.5s; } + + /* Breathe Animation Styles - Elegant Dream Theme */ @keyframes breathe-glow { 0%, 100% { text-shadow: @@ -472,6 +567,88 @@ export function LoadingOverlay({ } } + @keyframes float-particle { + 0%, 100% { + transform: translate(0, 0) scale(1); + opacity: 0.3; + } + 25% { + transform: translate(var(--dx1), var(--dy1)) scale(1.2); + opacity: 0.6; + } + 50% { + transform: translate(var(--dx2), var(--dy2)) scale(0.8); + opacity: 0.4; + } + 75% { + transform: translate(var(--dx3), var(--dy3)) scale(1.1); + opacity: 0.5; + } + } + + @keyframes bg-gradient-shift { + 0%, 100% { + background-position: 0% 50%; + } + 50% { + background-position: 100% 50%; + } + } + + .breathe-fullscreen { + position: absolute; + inset: 0; + overflow: hidden; + background: radial-gradient(ellipse at 30% 40%, rgba(59, 130, 246, 0.15) 0%, transparent 50%), + radial-gradient(ellipse at 70% 60%, rgba(139, 92, 246, 0.15) 0%, transparent 50%), + radial-gradient(ellipse at 50% 50%, rgba(6, 182, 212, 0.1) 0%, transparent 60%); + background-size: 200% 200%; + animation: bg-gradient-shift 10s ease-in-out infinite; + } + + .breathe-particles-field { + position: absolute; + inset: 0; + pointer-events: none; + } + + .float-particle { + position: absolute; + width: 8px; + height: 8px; + background: radial-gradient(circle, rgba(59, 130, 246, 0.8) 0%, transparent 70%); + border-radius: 50%; + animation: float-particle 12s ease-in-out infinite; + box-shadow: 0 0 15px rgba(59, 130, 246, 0.6); + } + + .float-particle:nth-child(1) { left: 10%; top: 20%; --dx1: 60px; --dy1: -80px; --dx2: -40px; --dy2: 60px; --dx3: 20px; --dy3: -30px; animation-delay: 0s; } + .float-particle:nth-child(2) { left: 20%; top: 60%; --dx1: -50px; --dy1: -60px; --dx2: 70px; --dy2: 40px; --dx3: -30px; --dy3: -50px; animation-delay: -2s; } + .float-particle:nth-child(3) { left: 80%; top: 30%; --dx1: -60px; --dy1: 70px; --dx2: 40px; --dy2: -80px; --dx3: -20px; --dy3: 40px; animation-delay: -4s; } + .float-particle:nth-child(4) { left: 70%; top: 70%; --dx1: 50px; --dy1: 60px; --dx2: -60px; --dy2: -40px; --dx3: 30px; --dy3: 50px; animation-delay: -6s; } + .float-particle:nth-child(5) { left: 40%; top: 15%; --dx1: -70px; --dy1: 50px; --dx2: 60px; --dy2: -60px; --dx3: -40px; --dy3: 30px; animation-delay: -1s; } + .float-particle:nth-child(6) { left: 60%; top: 85%; --dx1: 40px; --dy1: -70px; --dx2: -50px; --dy2: 50px; --dx3: 60px; --dy3: -40px; animation-delay: -3s; } + .float-particle:nth-child(7) { left: 15%; top: 80%; --dx1: 70px; --dy1: -50px; --dx2: -60px; --dy2: 70px; --dx3: 40px; --dy3: -60px; animation-delay: -5s; } + .float-particle:nth-child(8) { left: 85%; top: 50%; --dx1: -40px; --dy1: 60px; --dx2: 50px; --dy2: -50px; --dx3: -70px; --dy3: 40px; animation-delay: -7s; } + .float-particle:nth-child(9) { left: 50%; top: 10%; --dx1: 30px; --dy1: 80px; --dx2: -70px; --dy2: -30px; --dx3: 50px; --dy3: 60px; animation-delay: -8s; } + .float-particle:nth-child(10) { left: 30%; top: 90%; --dx1: -80px; --dy1: -40px; --dx2: 60px; --dy2: 60px; --dx3: -50px; --dy3: -70px; animation-delay: -9s; } + .float-particle:nth-child(11) { left: 90%; top: 80%; --dx1: 60px; --dy1: 40px; --dx2: -80px; --dy2: -60px; --dx3: 70px; --dy3: 50px; animation-delay: -10s; } + .float-particle:nth-child(12) { left: 5%; top: 40%; --dx1: -50px; --dy1: -70px; --dx2: 80px; --dy2: 50px; --dx3: -60px; --dy3: -80px; animation-delay: -11s; } + + .float-particle.large { + width: 12px; + height: 12px; + background: radial-gradient(circle, rgba(139, 92, 246, 0.6) 0%, transparent 70%); + box-shadow: 0 0 20px rgba(139, 92, 246, 0.5); + } + + .float-particle.small { + width: 4px; + height: 4px; + background: radial-gradient(circle, rgba(6, 182, 212, 0.7) 0%, transparent 70%); + box-shadow: 0 0 10px rgba(6, 182, 212, 0.4); + } + @keyframes letter-appear { 0% { opacity: 0; @@ -640,7 +817,7 @@ export function LoadingOverlay({ .particle:nth-child(7) { left: 50%; top: 50%; --tx: -100px; --ty: 0px; animation-delay: 0.75s; } .particle:nth-child(8) { left: 50%; top: 50%; --tx: 100px; --ty: 0px; animation-delay: 1.05s; } - /* Typewriter Animation Styles */ + /* Typewriter Animation Styles - Retro Terminal Theme */ @keyframes type-letter { 0% { opacity: 0; @@ -655,21 +832,135 @@ export function LoadingOverlay({ @keyframes cursor-blink { 0%, 49% { opacity: 1; - background-color: rgba(59, 130, 246, 1); + background-color: rgba(0, 255, 0, 1); } 50%, 100% { opacity: 0; - background-color: rgba(59, 130, 246, 0); + background-color: rgba(0, 255, 0, 0); } } + @keyframes char-rain { + 0% { + transform: translateY(-20px); + opacity: 0; + } + 10% { + opacity: 0.7; + } + 90% { + opacity: 0.3; + } + 100% { + transform: translateY(100vh); + opacity: 0; + } + } + + @keyframes crt-scan { + 0% { + top: 0; + } + 100% { + top: 100%; + } + } + + @keyframes cursor-trail { + 0% { + transform: translate(0, 0); + opacity: 0.6; + } + 100% { + transform: translate(var(--trail-x), var(--trail-y)); + opacity: 0; + } + } + + .typewriter-fullscreen { + position: absolute; + inset: 0; + overflow: hidden; + background: + linear-gradient(rgba(0, 0, 0, 0) 50%, rgba(0, 20, 0, 0.05) 50%), + linear-gradient(90deg, rgba(255, 0, 0, 0.03), rgba(0, 255, 0, 0.02), rgba(0, 0, 255, 0.03)); + background-size: 100% 4px, 3px 100%; + } + + .terminal-chars-rain { + position: absolute; + inset: 0; + pointer-events: none; + font-family: 'Courier New', monospace; + font-size: 16px; + color: rgba(0, 255, 0, 0.4); + } + + .char-column { + position: absolute; + top: -50px; + animation: char-rain linear infinite; + text-shadow: 0 0 8px rgba(0, 255, 0, 0.6); + white-space: pre; + } + + .char-column:nth-child(1) { left: 8%; animation-duration: 6s; animation-delay: 0s; } + .char-column:nth-child(2) { left: 18%; animation-duration: 8s; animation-delay: -1s; } + .char-column:nth-child(3) { left: 28%; animation-duration: 7s; animation-delay: -2s; } + .char-column:nth-child(4) { left: 38%; animation-duration: 9s; animation-delay: -0.5s; } + .char-column:nth-child(5) { left: 48%; animation-duration: 6.5s; animation-delay: -1.5s; } + .char-column:nth-child(6) { left: 58%; animation-duration: 8.5s; animation-delay: -3s; } + .char-column:nth-child(7) { left: 68%; animation-duration: 7.5s; animation-delay: -2.5s; } + .char-column:nth-child(8) { left: 78%; animation-duration: 9.5s; animation-delay: -1.8s; } + .char-column:nth-child(9) { left: 88%; animation-duration: 6.8s; animation-delay: -0.8s; } + + .crt-scanline { + position: absolute; + width: 100%; + height: 100px; + left: 0; + top: 0; + background: linear-gradient( + to bottom, + transparent 0%, + rgba(0, 255, 0, 0.03) 50%, + transparent 100% + ); + animation: crt-scan 6s linear infinite; + pointer-events: none; + } + + .cursor-trails { + position: absolute; + inset: 0; + pointer-events: none; + } + + .cursor-trail { + position: absolute; + width: 3px; + height: 20px; + background: rgba(0, 255, 0, 0.6); + box-shadow: 0 0 10px rgba(0, 255, 0, 0.8); + animation: cursor-trail 3s ease-out infinite; + } + + .cursor-trail:nth-child(1) { left: 20%; top: 30%; --trail-x: 200px; --trail-y: -150px; animation-delay: 0s; } + .cursor-trail:nth-child(2) { left: 60%; top: 70%; --trail-x: -180px; --trail-y: 120px; animation-delay: 1s; } + .cursor-trail:nth-child(3) { left: 80%; top: 20%; --trail-x: -220px; --trail-y: 180px; animation-delay: 2s; } + .cursor-trail:nth-child(4) { left: 40%; top: 80%; --trail-x: 150px; --trail-y: -200px; animation-delay: 0.5s; } + .cursor-trail:nth-child(5) { left: 70%; top: 50%; --trail-x: -160px; --trail-y: -140px; animation-delay: 1.5s; } + .typewriter-container { position: relative; + z-index: 10; } .typewriter-text { - color: #fff; + color: #0f0; display: inline-flex; + text-shadow: 0 0 10px rgba(0, 255, 0, 0.6); + filter: drop-shadow(0 0 5px rgba(0, 255, 0, 0.4)); } .typewriter-text .type-letter { @@ -690,12 +981,13 @@ export function LoadingOverlay({ width: 3px; height: 1em; margin-left: 4px; - background-color: rgba(59, 130, 246, 1); + background-color: rgba(0, 255, 0, 1); animation: cursor-blink 1s infinite; animation-delay: 0.9s; + box-shadow: 0 0 8px rgba(0, 255, 0, 0.8); } - /* Scanner Animation Styles */ + /* Scanner Animation Styles - Matrix/Hacker Theme */ @keyframes vertical-scan { 0% { top: -20%; @@ -705,105 +997,179 @@ export function LoadingOverlay({ } } - @keyframes horizontal-scan { + @keyframes code-fall { 0% { - left: -20%; + transform: translateY(-100%); + opacity: 0; + } + 10% { + opacity: 1; + } + 90% { + opacity: 1; } 100% { - left: 120%; + transform: translateY(100vh); + opacity: 0; } } @keyframes scanner-glow { 0%, 100% { text-shadow: - 0 0 10px rgba(0, 255, 255, 0.3), - 0 0 20px rgba(0, 255, 255, 0.2); + 0 0 20px rgba(0, 255, 0, 0.6), + 0 0 40px rgba(0, 255, 0, 0.4), + 0 0 60px rgba(0, 255, 0, 0.2); + color: #0f0; } 50% { text-shadow: - 0 0 30px rgba(0, 255, 255, 1), - 0 0 60px rgba(0, 255, 255, 0.8), - 0 0 90px rgba(0, 255, 255, 0.6), - 0 0 120px rgba(0, 255, 255, 0.4); + 0 0 40px rgba(0, 255, 0, 1), + 0 0 80px rgba(0, 255, 0, 0.8), + 0 0 120px rgba(0, 255, 0, 0.6), + 0 0 160px rgba(0, 255, 0, 0.4); + color: #0ff; } } + @keyframes code-flicker { + 0%, 100% { + opacity: 0.05; + } + 50% { + opacity: 0.15; + } + } + + .scanner-fullscreen { + position: absolute; + inset: 0; + overflow: hidden; + background: radial-gradient(ellipse at center, rgba(0, 20, 0, 0.3) 0%, rgba(0, 0, 0, 0.95) 100%); + } + .scanner-container { position: relative; - overflow: hidden; + overflow: visible; + z-index: 10; } .scanner-text { - color: #fff; - animation: scanner-glow 3s ease-in-out infinite; + color: #0f0; + animation: scanner-glow 2s ease-in-out infinite; position: relative; - z-index: 1; + z-index: 10; + filter: drop-shadow(0 0 10px rgba(0, 255, 0, 0.8)); } + /* Matrix digital rain */ + .matrix-rain { + position: absolute; + inset: 0; + overflow: hidden; + pointer-events: none; + } + + .matrix-column { + position: absolute; + top: 0; + width: 20px; + height: 100%; + font-family: 'Courier New', monospace; + font-size: 14px; + color: #0f0; + opacity: 0.6; + animation: code-fall linear infinite; + text-shadow: 0 0 5px rgba(0, 255, 0, 0.8); + white-space: pre; + line-height: 20px; + } + + /* Stagger the columns */ + .matrix-column:nth-child(1) { left: 5%; animation-duration: 8s; animation-delay: 0s; } + .matrix-column:nth-child(2) { left: 15%; animation-duration: 10s; animation-delay: -2s; } + .matrix-column:nth-child(3) { left: 25%; animation-duration: 7s; animation-delay: -4s; } + .matrix-column:nth-child(4) { left: 35%; animation-duration: 9s; animation-delay: -1s; } + .matrix-column:nth-child(5) { left: 45%; animation-duration: 11s; animation-delay: -3s; } + .matrix-column:nth-child(6) { left: 55%; animation-duration: 8s; animation-delay: -5s; } + .matrix-column:nth-child(7) { left: 65%; animation-duration: 10s; animation-delay: -2.5s; } + .matrix-column:nth-child(8) { left: 75%; animation-duration: 9s; animation-delay: -4.5s; } + .matrix-column:nth-child(9) { left: 85%; animation-duration: 7s; animation-delay: -1.5s; } + .matrix-column:nth-child(10) { left: 95%; animation-duration: 10s; animation-delay: -3.5s; } + + /* Powerful scan beam */ .vertical-scan-line { position: absolute; width: 100%; - height: 80px; + height: 150px; left: 0; background: linear-gradient( to bottom, transparent 0%, - rgba(0, 255, 255, 0.1) 20%, - rgba(0, 255, 255, 0.8) 50%, - rgba(0, 255, 255, 0.1) 80%, + rgba(0, 255, 0, 0.05) 20%, + rgba(0, 255, 255, 0.4) 45%, + rgba(0, 255, 255, 1) 50%, + rgba(0, 255, 255, 0.4) 55%, + rgba(0, 255, 0, 0.05) 80%, transparent 100% ); - animation: vertical-scan 3s linear infinite; - z-index: 2; + animation: vertical-scan 4s linear infinite; + z-index: 5; pointer-events: none; - box-shadow: 0 0 30px rgba(0, 255, 255, 0.6); + box-shadow: + 0 0 50px rgba(0, 255, 255, 0.8), + 0 0 100px rgba(0, 255, 255, 0.4); + filter: blur(1px); } - .vertical-scan-line:nth-child(2) { - animation-delay: 1.5s; + .vertical-scan-line::before { + content: ''; + position: absolute; + inset: 0; background: linear-gradient( to bottom, - transparent 0%, - rgba(255, 0, 255, 0.1) 20%, - rgba(255, 0, 255, 0.6) 50%, - rgba(255, 0, 255, 0.1) 80%, - transparent 100% + transparent 48%, + rgba(255, 255, 255, 0.8) 50%, + transparent 52% ); - box-shadow: 0 0 30px rgba(255, 0, 255, 0.5); - } - - .horizontal-scan-line { - position: absolute; - width: 80px; - height: 100%; - top: 0; - background: linear-gradient( - to right, - transparent 0%, - rgba(0, 255, 255, 0.1) 20%, - rgba(0, 255, 255, 0.5) 50%, - rgba(0, 255, 255, 0.1) 80%, - transparent 100% - ); - animation: horizontal-scan 2.5s linear infinite; - z-index: 2; - pointer-events: none; - box-shadow: 0 0 30px rgba(0, 255, 255, 0.4); } + /* Dense grid */ .scanner-grid { position: absolute; - inset: -40px; + inset: 0; background-image: - linear-gradient(rgba(0, 255, 255, 0.1) 1px, transparent 1px), - linear-gradient(90deg, rgba(0, 255, 255, 0.1) 1px, transparent 1px); - background-size: 20px 20px; - opacity: 0.3; + linear-gradient(rgba(0, 255, 0, 0.15) 1px, transparent 1px), + linear-gradient(90deg, rgba(0, 255, 0, 0.15) 1px, transparent 1px); + background-size: 15px 15px; + opacity: 0.4; pointer-events: none; + animation: code-flicker 3s ease-in-out infinite; } - /* Pulse Ripple Animation Styles */ + /* Random code snippets */ + .code-fragments { + position: absolute; + inset: 0; + pointer-events: none; + font-family: 'Courier New', monospace; + font-size: 12px; + color: rgba(0, 255, 0, 0.3); + } + + .code-fragment { + position: absolute; + animation: code-flicker 2s ease-in-out infinite; + text-shadow: 0 0 5px rgba(0, 255, 0, 0.5); + } + + .code-fragment:nth-child(1) { top: 10%; left: 10%; animation-delay: 0s; } + .code-fragment:nth-child(2) { top: 20%; right: 15%; animation-delay: 0.5s; } + .code-fragment:nth-child(3) { top: 40%; left: 20%; animation-delay: 1s; } + .code-fragment:nth-child(4) { bottom: 30%; right: 25%; animation-delay: 1.5s; } + .code-fragment:nth-child(5) { bottom: 15%; left: 30%; animation-delay: 0.8s; } + + /* Pulse Ripple Animation Styles - Sonar/Radar Theme */ @keyframes wave-expand { 0% { width: 80px; @@ -846,6 +1212,130 @@ export function LoadingOverlay({ } } + @keyframes target-blink { + 0%, 100% { + opacity: 0.3; + transform: scale(1); + } + 50% { + opacity: 1; + transform: scale(1.2); + } + } + + @keyframes sonar-pulse { + 0% { + transform: scale(0.5); + opacity: 0; + } + 50% { + opacity: 0.8; + } + 100% { + transform: scale(2); + opacity: 0; + } + } + + .pulse-fullscreen { + position: absolute; + inset: 0; + overflow: hidden; + background: radial-gradient(circle at center, rgba(0, 30, 60, 0.3) 0%, rgba(0, 0, 0, 0.95) 100%); + } + + .radar-grid { + position: absolute; + inset: 0; + display: flex; + align-items: center; + justify-content: center; + pointer-events: none; + } + + .radar-circle { + position: absolute; + border: 1px solid rgba(59, 130, 246, 0.2); + border-radius: 50%; + opacity: 0.4; + } + + .radar-circle:nth-child(1) { width: 200px; height: 200px; } + .radar-circle:nth-child(2) { width: 350px; height: 350px; } + .radar-circle:nth-child(3) { width: 500px; height: 500px; } + .radar-circle:nth-child(4) { width: 650px; height: 650px; } + .radar-circle:nth-child(5) { width: 800px; height: 800px; } + + .radar-lines { + position: absolute; + inset: 0; + display: flex; + align-items: center; + justify-content: center; + pointer-events: none; + } + + .radar-line { + position: absolute; + width: 1px; + height: 100%; + background: linear-gradient(to bottom, transparent 45%, rgba(59, 130, 246, 0.15) 50%, transparent 55%); + } + + .radar-line:nth-child(1) { transform: rotate(0deg); } + .radar-line:nth-child(2) { transform: rotate(45deg); } + .radar-line:nth-child(3) { transform: rotate(90deg); } + .radar-line:nth-child(4) { transform: rotate(135deg); } + + .sonar-waves { + position: absolute; + inset: 0; + display: flex; + align-items: center; + justify-content: center; + pointer-events: none; + } + + .sonar-wave { + position: absolute; + border: 2px solid rgba(59, 130, 246, 0.6); + border-radius: 50%; + width: 100px; + height: 100px; + animation: sonar-pulse 3s ease-out infinite; + } + + .sonar-wave:nth-child(1) { animation-delay: 0s; } + .sonar-wave:nth-child(2) { animation-delay: 0.6s; } + .sonar-wave:nth-child(3) { animation-delay: 1.2s; } + .sonar-wave:nth-child(4) { animation-delay: 1.8s; } + .sonar-wave:nth-child(5) { animation-delay: 2.4s; } + + .radar-targets { + position: absolute; + inset: 0; + pointer-events: none; + } + + .radar-target { + position: absolute; + width: 8px; + height: 8px; + background: rgba(0, 255, 255, 0.8); + border-radius: 50%; + box-shadow: 0 0 15px rgba(0, 255, 255, 0.8); + animation: target-blink 2s ease-in-out infinite; + } + + .radar-target:nth-child(1) { left: 20%; top: 25%; animation-delay: 0s; } + .radar-target:nth-child(2) { left: 75%; top: 35%; animation-delay: 0.5s; } + .radar-target:nth-child(3) { left: 45%; top: 70%; animation-delay: 1s; } + .radar-target:nth-child(4) { left: 65%; top: 60%; animation-delay: 1.5s; } + .radar-target:nth-child(5) { left: 30%; top: 80%; animation-delay: 0.3s; } + .radar-target:nth-child(6) { left: 85%; top: 75%; animation-delay: 0.8s; } + .radar-target:nth-child(7) { left: 15%; top: 55%; animation-delay: 1.3s; } + .radar-target:nth-child(8) { left: 55%; top: 20%; animation-delay: 0.6s; } + .pulse-container { position: relative; } @@ -932,14 +1422,32 @@ export function LoadingOverlay({ className={cn( "absolute inset-0 flex items-center justify-center z-50 transition-opacity duration-300", isFadingOut ? "opacity-0" : "opacity-100", - className + className, )} style={{ backgroundColor: backgroundColor || "rgba(0, 0, 0, 0.92)" }} > - {animationType === 'glitch' ? ( + {animationType === "glitch" ? ( <> -
-
+ {/* Fullscreen Glitch Background */} +
+ {/* RGB Split Layers */} +
+
+
+
+
+ + {/* Signal Distortion Bars */} +
+ {Array.from({ length: 4 }).map((_, i) => ( +
+ ))} +
+ + {/* Original Effects */} +
+
+
@@ -947,8 +1455,10 @@ export function LoadingOverlay({
TERMIX @@ -959,7 +1469,7 @@ export function LoadingOverlay({
{message && ( -
+

{message}

@@ -967,8 +1477,24 @@ export function LoadingOverlay({ )}
- ) : animationType === 'breathe' ? ( + ) : animationType === "breathe" ? ( <> + {/* Fullscreen Elegant Background */} +
+ {/* Floating Particles Field */} +
+ {Array.from({ length: 12 }).map((_, i) => ( +
+ ))} +
+
+
{/* Pulse rings */} @@ -1000,7 +1526,8 @@ export function LoadingOverlay({
T @@ -1013,7 +1540,7 @@ export function LoadingOverlay({
{message && ( -
+

{message}

@@ -1021,15 +1548,38 @@ export function LoadingOverlay({ )}
- ) : animationType === 'typewriter' ? ( + ) : animationType === "typewriter" ? ( <> + {/* Fullscreen Retro Terminal Background */} +
+ {/* ASCII Character Rain */} +
+ {Array.from({ length: 9 }).map((_, i) => ( +
+ {`$\n>\n_\n{\n}\n[\n]\n|\n/\n\\\n-\n+\n*\n#\n@\n%`} +
+ ))} +
+ + {/* CRT Scanline */} +
+ + {/* Cursor Trails */} +
+ {Array.from({ length: 5 }).map((_, i) => ( +
+ ))} +
+
+
{/* TERMIX Typewriter Text */}
T @@ -1043,33 +1593,58 @@ export function LoadingOverlay({
{message && ( -
-

+

+

{message}

)}
- ) : animationType === 'scanner' ? ( + ) : animationType === "scanner" ? ( <> + {/* Fullscreen Matrix Background */} +
+ {/* Grid Background */} +
+ + {/* Matrix Digital Rain */} +
+ {Array.from({ length: 10 }).map((_, i) => ( +
+ {`01\n10\n11\n00\n01\n10\n11\n00\n01\n10\n11\n00\n01\n10\n11\n00\n01\n10\n11\n00`} +
+ ))} +
+ + {/* Random Code Fragments */} +
+
+ {"{"} ssh: 22 {"}"} +
+
+ {"<"} connect... {">"} +
+
0x4A3F2B1D
+
[SCANNING...]
+
{">"} _
+
+ + {/* Powerful Scan Beam */} +
+
+
- {/* Scanner Grid Background */} -
- - {/* Vertical Scan Lines */} -
-
- - {/* Horizontal Scan Line */} -
- {/* TERMIX Scanner Text */}
TERMIX @@ -1077,8 +1652,11 @@ export function LoadingOverlay({
{message && ( -
-

+

+

{message}

@@ -1087,6 +1665,37 @@ export function LoadingOverlay({ ) : ( <> + {/* Fullscreen Radar/Sonar Background */} +
+ {/* Radar Circular Grid */} +
+ {Array.from({ length: 5 }).map((_, i) => ( +
+ ))} +
+ + {/* Radar Cross Lines */} +
+ {Array.from({ length: 4 }).map((_, i) => ( +
+ ))} +
+ + {/* Sonar Pulse Waves */} +
+ {Array.from({ length: 5 }).map((_, i) => ( +
+ ))} +
+ + {/* Radar Targets (Detection Points) */} +
+ {Array.from({ length: 8 }).map((_, i) => ( +
+ ))} +
+
+
{/* Wave Rings */} @@ -1106,7 +1715,8 @@ export function LoadingOverlay({
TERMIX @@ -1114,7 +1724,7 @@ export function LoadingOverlay({
{message && ( -
+

{message}