{"title":"Software","description":"\u003cp\u003eColección de todos nuestros productos de software y aplicaciones digitales.\u003c\/p\u003e","products":[{"product_id":"sgp-tactical-app","title":"SGP tactical (apk)","description":"\u003cbody\u003e\n\n\n    \u003cmeta charset=\"UTF-8\"\u003e\n    \u003cmeta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"\u003e\n    \u003ctitle\u003eSGP TACTICAL - Field Operations\u003c\/title\u003e\n    \n    \u003clink rel=\"preconnect\" href=\"https:\/\/fonts.googleapis.com\"\u003e\n    \u003clink rel=\"preconnect\" href=\"https:\/\/fonts.gstatic.com\" crossorigin\u003e\n    \u003clink href=\"https:\/\/fonts.googleapis.com\/css2?family=Inter:wght@400;500;600\u0026amp;family=Space+Grotesk:wght@700;800\u0026amp;display=swap\" rel=\"stylesheet\"\u003e\n    \n    \u003cstyle\u003e\n        :root {\n            --bg-color: #e0e5ec;\n            --text-main: #2d3748;\n            --text-muted: #718096;\n            --accent: #d97706; \n            --success: #059669;\n            --danger: #dc2626;\n            \n            --shadow-light: rgba(255, 255, 255, 0.9);\n            --shadow-dark: rgba(163, 177, 198, 0.7);\n            \n            --neu-out: 9px 9px 16px var(--shadow-dark), -9px -9px 16px var(--shadow-light);\n            --neu-out-sm: 5px 5px 10px var(--shadow-dark), -5px -5px 10px var(--shadow-light);\n            --neu-in: inset 6px 6px 10px var(--shadow-dark), inset -6px -6px 10px var(--shadow-light);\n            \n            --radius-xl: 40px;\n            --radius-lg: 30px;\n            --radius-pill: 100px;\n        }\n\n        * { box-sizing: border-box; margin: 0; padding: 0; }\n        \n        body { \n            background-color: var(--bg-color); \n            color: var(--text-main); \n            font-family: 'Inter', sans-serif; \n            line-height: 1.6; \n            padding: 40px 20px; \n            overflow-x: hidden; \n        }\n        \n        h1, h2, h3 { \n            font-family: 'Space Grotesk', sans-serif; \n            font-weight: 800; \n            color: var(--text-main); \n            margin-bottom: 15px; \n            letter-spacing: -0.5px; \n        }\n\n        .container { max-width: 1100px; margin: 0 auto; }\n\n        \/* Header *\/\n        .header-section { text-align: center; margin-bottom: 60px; padding-top: 20px; }\n        \n        .badge { \n            display: inline-block; \n            background: var(--bg-color); \n            box-shadow: var(--neu-in); \n            padding: 10px 24px; \n            border-radius: var(--radius-pill); \n            font-size: 14px; \n            font-weight: 700; \n            color: var(--accent); \n            text-transform: uppercase; \n            letter-spacing: 2px; \n            margin-bottom: 20px; \n        }\n        \n        .main-title { \n            font-size: clamp(40px, 8vw, 72px); \n            background: linear-gradient(135deg, #1e293b 0%, #475569 100%); \n            -webkit-background-clip: text; \n            -webkit-text-fill-color: transparent; \n            margin-bottom: 15px; \n            line-height: 1.1;\n        }\n        \n        .subtitle { font-size: 18px; color: var(--text-muted); font-weight: 500; max-width: 700px; margin: 0 auto; }\n\n        \/* Video Wrapper *\/\n        .video-wrapper { \n            margin-bottom: 60px; \n            border-radius: var(--radius-lg); \n            background: var(--bg-color); \n            box-shadow: var(--neu-out); \n            padding: 15px; \n        }\n        .video-wrapper video { \n            width: 100%; \n            border-radius: calc(var(--radius-lg) - 10px); \n            display: block; \n            box-shadow: var(--neu-in); \n            background-color: #000; \/* Fondo negro por si tarda en cargar *\/\n        }\n\n        .section-title { text-align: center; font-size: 30px; margin-bottom: 50px; text-transform: uppercase; }\n        \n        \/* Features Grid *\/\n        .features-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 40px; margin-bottom: 60px; }\n\n        .neu-card-sm { background: var(--bg-color); border-radius: var(--radius-lg); box-shadow: var(--neu-out); padding: 35px; display: flex; flex-direction: column; gap: 15px; transition: transform 0.3s ease; }\n        .neu-card-sm:hover { transform: translateY(-5px); }\n        \n        .neu-icon { width: 65px; height: 65px; border-radius: 50%; background: var(--bg-color); box-shadow: var(--neu-out); display: flex; align-items: center; justify-content: center; color: var(--accent); margin-bottom: 10px; }\n        .svg-icon { width: 30px; height: 30px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }\n\n        .feature-title { font-size: 20px; margin-bottom: 5px; }\n        .feature-desc { color: var(--text-muted); font-size: 15px; }\n\n        \/* Disclaimer *\/\n        .neu-sunken { background: var(--bg-color); border-radius: var(--radius-lg); box-shadow: var(--neu-in); padding: 35px; }\n        .disclaimer { margin-top: 60px; text-align: center; border-left: 4px solid var(--danger); border-right: 4px solid var(--danger); }\n        .disclaimer h4 { color: var(--danger); font-size: 14px; text-transform: uppercase; margin-bottom: 5px; }\n        .disclaimer p { font-size: 13px; color: var(--text-muted); margin-top: 10px; }\n\n        .reveal { animation: reveal 0.8s cubic-bezier(0.2, 0.8, 0.2, 1) forwards; }\n        @keyframes reveal { from { opacity: 0; transform: translateY(30px); } to { opacity: 1; transform: translateY(0); } }\n    \u003c\/style\u003e\n\n\n\n\u003cdiv class=\"container reveal\"\u003e\n\n    \u003c!-- HEADER --\u003e\n    \u003cheader class=\"header-section\"\u003e\n        \u003cdiv class=\"badge\"\u003eSGP TACTICAL APK\u003c\/div\u003e\n        \u003ch1 class=\"main-title\"\u003eSGP TACTICAL\u003c\/h1\u003e\n        \u003cp class=\"subtitle\"\u003eThe ultimate field operations suite designed for \u003cstrong\u003etactical military use and special operations\u003c\/strong\u003e. Professional tools for network analysis, secure global communication, and operational field planning.\u003c\/p\u003e\n    \u003c\/header\u003e\n\n    \u003c!-- VIDEO EXPLICATIVO --\u003e\n    \u003cdiv class=\"video-wrapper\"\u003e\n        \u003cvideo controls autoplay muted loop playsinline\u003e\n            \u003csource src=\"https:\/\/cdn.shopify.com\/videos\/c\/o\/v\/12131ea67d3b40ea88521af39209ec7d.mp4\" type=\"video\/mp4\"\u003e\n            Tu navegador no soporta el elemento de video.\n        \u003c\/source\u003e\u003c\/video\u003e\n    \u003c\/div\u003e\n\n    \u003c!-- OPERATOR TOOLS --\u003e\n    \u003ch2 class=\"section-title\"\u003eOperator Tools\u003c\/h2\u003e\n    \u003cdiv class=\"features-grid\"\u003e\n        \n        \u003cdiv class=\"neu-card-sm\"\u003e\n            \u003cdiv class=\"neu-icon\"\u003e\u003csvg class=\"svg-icon\" viewbox=\"0 0 24 24\"\u003e\u003cpath d=\"M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z\"\u003e\u003c\/path\u003e\u003c\/svg\u003e\u003c\/div\u003e\n            \u003ch3 class=\"feature-title\"\u003eSignal Analysis Suite\u003c\/h3\u003e\n            \u003cp class=\"feature-desc\"\u003eAdvanced module for local network security analysis, signal scanning, and packet inspection. Professional-grade field functionality.\u003c\/p\u003e\n        \u003c\/div\u003e\n\n        \u003cdiv class=\"neu-card-sm\"\u003e\n            \u003cdiv class=\"neu-icon\"\u003e\u003csvg class=\"svg-icon\" viewbox=\"0 0 24 24\"\u003e\u003cpath d=\"M12 2a10 10 0 0 1 10 10c0 5.5-4.5 10-10 10S2 17.5 2 12 6.5 2 12 2z\"\u003e\u003c\/path\u003e\u003cpath d=\"M2 12h20\"\u003e\u003c\/path\u003e\u003cpath d=\"M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z\"\u003e\u003c\/path\u003e\u003c\/svg\u003e\u003c\/div\u003e\n            \u003ch3 class=\"feature-title\"\u003eGlobal Live Radio\u003c\/h3\u003e\n            \u003cp class=\"feature-desc\"\u003eVisualize and tune into live public radio frequencies from anywhere in the world. Embedded SDR (Software Defined Radio) wide-band signal reception.\u003c\/p\u003e\n        \u003c\/div\u003e\n\n        \u003cdiv class=\"neu-card-sm\"\u003e\n            \u003cdiv class=\"neu-icon\"\u003e\u003csvg class=\"svg-icon\" viewbox=\"0 0 24 24\"\u003e\u003ccircle cx=\"12\" cy=\"12\" r=\"10\"\u003e\u003c\/circle\u003e\u003ccircle cx=\"12\" cy=\"12\" r=\"6\"\u003e\u003c\/circle\u003e\u003ccircle cx=\"12\" cy=\"12\" r=\"2\"\u003e\u003c\/circle\u003e\u003c\/svg\u003e\u003c\/div\u003e\n            \u003ch3 class=\"feature-title\"\u003eWi-Fi Scan Radar\u003c\/h3\u003e\n            \u003cp class=\"feature-desc\"\u003eScan the local electromagnetic spectrum to physically map and triangulate hidden emitters (Wi-Fi Routers, BLE beacons, trackers).\u003c\/p\u003e\n        \u003c\/div\u003e\n\n        \u003cdiv class=\"neu-card-sm\"\u003e\n            \u003cdiv class=\"neu-icon\"\u003e\u003csvg class=\"svg-icon\" viewbox=\"0 0 24 24\"\u003e\u003cpath d=\"M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z\"\u003e\u003c\/path\u003e\u003c\/svg\u003e\u003c\/div\u003e\n            \u003ch3 class=\"feature-title\"\u003eEncrypted P2P Chat\u003c\/h3\u003e\n            \u003cp class=\"feature-desc\"\u003eShielded communications using strong asymmetric encryption. Features dynamic routing and immediate message self-destruction.\u003c\/p\u003e\n        \u003c\/div\u003e\n\n        \u003cdiv class=\"neu-card-sm\"\u003e\n            \u003cdiv class=\"neu-icon\"\u003e\u003csvg class=\"svg-icon\" viewbox=\"0 0 24 24\"\u003e\u003cpath d=\"M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2\"\u003e\u003c\/path\u003e\u003ccircle cx=\"9\" cy=\"7\" r=\"4\"\u003e\u003c\/circle\u003e\u003cpath d=\"M23 21v-2a4 4 0 0 0-3-3.87\"\u003e\u003c\/path\u003e\u003cpath d=\"M16 3.13a4 4 0 0 1 0 7.75\"\u003e\u003c\/path\u003e\u003c\/svg\u003e\u003c\/div\u003e\n            \u003ch3 class=\"feature-title\"\u003eSquad Link System\u003c\/h3\u003e\n            \u003cp class=\"feature-desc\"\u003eForm networked operational units. View health status, precise position, and live telemetry of your squad members directly on your tactical display.\u003c\/p\u003e\n        \u003c\/div\u003e\n        \n        \u003cdiv class=\"neu-card-sm\"\u003e\n            \u003cdiv class=\"neu-icon\"\u003e\u003csvg class=\"svg-icon\" viewbox=\"0 0 24 24\"\u003e\u003cpolygon points=\"12 2 2 7 12 12 22 7 12 2\"\u003e\u003c\/polygon\u003e\u003cpolyline points=\"2 17 12 22 22 17\"\u003e\u003c\/polyline\u003e\u003cpolyline points=\"2 12 12 17 22 12\"\u003e\u003c\/polyline\u003e\u003c\/svg\u003e\u003c\/div\u003e\n            \u003ch3 class=\"feature-title\"\u003eMulti-Style Geo-Intelligence\u003c\/h3\u003e\n            \u003cp class=\"feature-desc\"\u003eAccess over 8 different map styles modifiable in real-time to adapt to the operational terrain (Infrastructure, Topographic, Thermal, etc).\u003c\/p\u003e\n        \u003c\/div\u003e\n\n    \u003c\/div\u003e\n\n    \u003c!-- DISCLAIMER --\u003e\n    \u003cdiv class=\"disclaimer neu-sunken\"\u003e\n        \u003ch4\u003e⚠️ ATTENTION: Restricted Compatibility\u003c\/h4\u003e\n        \u003cp\u003e\u003cstrong\u003eThis mobile application is exclusively compatible with Android mobile devices and tablets.\u003c\/strong\u003e It requires low-level hardware access to network interfaces for radar and signal analysis functions that only the Android architecture provides. iOS and other mobile platforms are not supported.\u003c\/p\u003e\n    \u003c\/div\u003e\n\n\u003c\/div\u003e\n\n\n\u003c\/body\u003e","brand":"sgpstore","offers":[{"title":"Default Title","offer_id":57854124982604,"sku":null,"price":19.0,"currency_code":"EUR","in_stock":true}],"thumbnail_url":"\/\/cdn.shopify.com\/s\/files\/1\/1057\/9807\/4700\/files\/rn-image_picker_lib_temp_3d383d81-ea36-4627-aeb9-6f848ebc5af0.png?v=1781909939"},{"product_id":"wifi-csi","title":"wifi csi (software)","description":"\u003cbody\u003e\n\n\n    \u003cmeta charset=\"UTF-8\"\u003e\n    \u003cmeta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"\u003e\n    \u003ctitle\u003eWi-Fi CSI Program - SGP\u003c\/title\u003e\n    \n    \u003c!-- Google Fonts: Space Grotesk (Headers) and Inter (Body) --\u003e\n    \u003clink rel=\"preconnect\" href=\"https:\/\/fonts.googleapis.com\"\u003e\n    \u003clink rel=\"preconnect\" href=\"https:\/\/fonts.gstatic.com\" crossorigin\u003e\n    \u003clink href=\"https:\/\/fonts.googleapis.com\/css2?family=Inter:wght@400;500;600\u0026amp;family=Space+Grotesk:wght@700;800\u0026amp;display=swap\" rel=\"stylesheet\"\u003e\n\n    \u003cstyle\u003e\n        :root {\n            \/* Neumorphic Color Palette *\/\n            --bg-color: #e0e5ec;\n            --text-main: #2d3748;\n            --text-muted: #718096;\n            --accent: #eab308; \/* Premium Amber\/Gold *\/\n            --success: #38a169;\n            --danger: #e53e3e;\n            \n            \/* Shadows (Extrusion\/Sunken Effects) *\/\n            --shadow-light: rgba(255, 255, 255, 0.8);\n            --shadow-dark: rgba(163, 177, 198, 0.6);\n            --neu-out: 9px 9px 16px var(--shadow-dark), -9px -9px 16px var(--shadow-light);\n            --neu-out-sm: 5px 5px 10px var(--shadow-dark), -5px -5px 10px var(--shadow-light);\n            --neu-in: inset 6px 6px 10px var(--shadow-dark), inset -6px -6px 10px var(--shadow-light);\n            \n            \/* Border Radii *\/\n            --radius-xl: 40px;\n            --radius-lg: 30px;\n            --radius-pill: 100px;\n            --transition: all 0.25s ease-in-out;\n        }\n\n        * { box-sizing: border-box; margin: 0; padding: 0; }\n\n        body {\n            background-color: var(--bg-color);\n            color: var(--text-main);\n            font-family: 'Inter', sans-serif;\n            line-height: 1.6;\n            -webkit-font-smoothing: antialiased;\n            padding: 20px;\n            overflow-x: hidden;\n            display: flex;\n            flex-direction: column;\n            align-items: center;\n            min-height: 100vh;\n        }\n\n        h1, h2, h3, h4 {\n            font-family: 'Space Grotesk', sans-serif;\n            font-weight: 800;\n            color: var(--text-main);\n            margin-bottom: 15px;\n            letter-spacing: -0.5px;\n        }\n\n        .product-container { \n            max-width: 800px; \n            width: 100%;\n            margin: 40px auto; \n            padding-bottom: 60px; \n        }\n        \n        .neu-card { background: var(--bg-color); border-radius: var(--radius-xl); box-shadow: var(--neu-out); padding: 40px; margin-bottom: 40px; }\n        .neu-sunken { background: var(--bg-color); border-radius: var(--radius-lg); box-shadow: var(--neu-in); padding: 25px; }\n\n        \/* Header *\/\n        .header-section { text-align: center; margin-bottom: 40px; padding-top: 20px; }\n        .badge { \n            display: inline-block; \n            background: var(--bg-color); \n            box-shadow: var(--neu-in); \n            padding: 8px 20px; \n            border-radius: var(--radius-pill); \n            font-size: 14px; \n            font-weight: 700; \n            color: var(--danger); \n            text-transform: uppercase; \n            letter-spacing: 1px; \n            margin-bottom: 20px; \n        }\n        .main-title { font-size: clamp(36px, 6vw, 64px); background: linear-gradient(135deg, #2d3748 0%, #718096 100%); -webkit-background-clip: text; -webkit-text-fill-color: transparent; margin-bottom: 20px; }\n        .subtitle { font-size: clamp(16px, 2.5vw, 22px); color: var(--text-main); font-weight: 600; margin: 0 auto 30px auto; }\n\n        \/* Terminal Window *\/\n        .terminal-window {\n            background: #1a202c;\n            border-radius: var(--radius-lg);\n            padding: 20px;\n            box-shadow: var(--neu-out);\n            font-family: monospace;\n            color: #a0aec0;\n            font-size: 14px;\n            margin-bottom: 40px;\n        }\n        .terminal-header {\n            display: flex;\n            gap: 8px;\n            margin-bottom: 20px;\n        }\n        .terminal-dot { width: 12px; height: 12px; border-radius: 50%; }\n        .dot-red { background: #fc8181; }\n        .dot-yellow { background: #f6e05e; }\n        .dot-green { background: #68d391; }\n        \n        .terminal-text span { color: #68d391; }\n        .terminal-text .warning { color: #f6e05e; }\n\n        \/* Text Content *\/\n        .content-text { font-size: 18px; color: var(--text-main); margin-bottom: 20px; text-align: justify; }\n        .highlight-box {\n            border-left: 4px solid var(--accent);\n            padding-left: 20px;\n            margin-top: 30px;\n        }\n\n        \/* Media Grid (Videos) *\/\n        .media-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 30px; margin-bottom: 40px; width: 100%; }\n        .video-container { border-radius: var(--radius-lg); overflow: hidden; box-shadow: var(--neu-out); position: relative; background: var(--bg-color); padding: 10px; }\n        .video-container video { width: 100%; aspect-ratio: 16\/9; object-fit: cover; border-radius: 20px; display: block; }\n\n        \/* Disclaimer *\/\n        .disclaimer { margin-top: 20px; text-align: center; }\n        .disclaimer h4 { color: var(--danger); font-size: 16px; margin-bottom: 10px; text-transform: uppercase; }\n        .disclaimer p { font-size: 14px; color: var(--text-muted); }\n\n        \/* --- SIMULATION HUD STYLES --- *\/\n        .sim-wrapper {\n            background: var(--bg-color);\n            border-radius: var(--radius-xl);\n            box-shadow: var(--neu-out);\n            padding: 15px;\n            margin-bottom: 40px;\n            width: 100%;\n        }\n        .sim-container {\n            position: relative;\n            width: 100%;\n            height: 450px;\n            background-color: #000;\n            font-family: 'Courier New', Courier, monospace;\n            color: #00ff33;\n            overflow: hidden;\n            border-radius: 25px;\n        }\n        .sim-container * { box-sizing: border-box; }\n        .sim-container #sim-canvas-container { position: absolute; top: 0; left: 0; width: 100%; height: 100%; z-index: 1; }\n        .sim-container #tactical-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; z-index: 10; pointer-events: none; background: radial-gradient(circle at center, transparent 40%, rgba(0, 10, 0, 0.8) 100%), linear-gradient(rgba(0, 255, 0, 0.03) 50%, rgba(0, 0, 0, 0.1) 50%); background-size: 100% 100%, 100% 4px; box-shadow: inset 0 0 100px rgba(0, 255, 0, 0.2); }\n        .sim-container .hud-element { position: absolute; background: rgba(0, 20, 0, 0.6); border: 1px solid #00ff33; padding: 10px; box-shadow: 0 0 10px rgba(0, 255, 51, 0.2), inset 0 0 10px rgba(0, 255, 51, 0.1); backdrop-filter: blur(2px); z-index: 20;}\n        .sim-container .hud-element::before, .sim-container .hud-element::after { content: ''; position: absolute; width: 6px; height: 6px; border-color: #00ff33; border-style: solid; }\n        .sim-container .top-left { top: 15px; left: 15px; border-left: 2px solid #00ff33; }\n        .sim-container .top-right { top: 15px; right: 15px; text-align: right; border-right: 2px solid #00ff33; }\n        .sim-container .bottom-left { bottom: 15px; left: 15px; }\n        .sim-container .bottom-right { bottom: 15px; right: 15px; width: 160px; }\n        .sim-container .blink { animation: sim-blinker 1.5s linear infinite; }\n        @keyframes sim-blinker { 50% { opacity: 0.3; } }\n        .sim-container h1, .sim-container h2, .sim-container h3 { margin: 0 0 5px 0; font-size: 12px; letter-spacing: 1px; text-transform: uppercase; color: #00ff33; font-family: 'Courier New', Courier, monospace;}\n        .sim-container p { margin: 2px 0; font-size: 10px; color: #00ff33; font-family: 'Courier New', Courier, monospace;}\n        .sim-container .crosshair { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); width: 60px; height: 60px; z-index: 10; pointer-events: none; }\n        .sim-container .crosshair::before, .sim-container .crosshair::after { content: ''; position: absolute; background: rgba(0, 255, 51, 0.5); }\n        .sim-container .crosshair::before { top: 50%; left: 0; width: 100%; height: 1px; }\n        .sim-container .crosshair::after { top: 0; left: 50%; width: 1px; height: 100%; }\n        .sim-container .crosshair .circle { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); width: 40px; height: 40px; border: 1px solid rgba(0, 255, 51, 0.3); border-radius: 50%; }\n        .sim-container .signal-bars { display: flex; align-items: flex-end; height: 25px; gap: 2px; margin-top: 5px; }\n        .sim-container .bar { flex: 1; background-color: #00ff33; width: 6px; animation: sim-signal-bounce 0.5s infinite alternate; opacity: 0.8; }\n        .sim-container .bar:nth-child(1) { animation-delay: 0.1s; }\n        .sim-container .bar:nth-child(2) { animation-delay: 0.3s; }\n        .sim-container .bar:nth-child(3) { animation-delay: 0.5s; }\n        .sim-container .bar:nth-child(4) { animation-delay: 0.2s; }\n        .sim-container .bar:nth-child(5) { animation-delay: 0.4s; }\n        .sim-container .bar:nth-child(6) { animation-delay: 0.6s; }\n        .sim-container .bar:nth-child(7) { animation-delay: 0.1s; }\n        .sim-container .bar:nth-child(8) { animation-delay: 0.5s; }\n        @keyframes sim-signal-bounce { 0% { height: 10%; } 100% { height: 100%; } }\n        .sim-container .controls-info { position: absolute; bottom: 15px; left: 50%; transform: translateX(-50%); text-align: center; font-size: 9px; opacity: 0.7; pointer-events: none; z-index: 10; width: 100%; }\n\n        \/* Animación Fade *\/\n        @keyframes fadeUp { from { opacity: 0; transform: translateY(30px); } to { opacity: 1; transform: translateY(0); } }\n    .reveal { animation: fadeUp 0.8s cubic-bezier(0.16, 1, 0.3, 1) forwards; }\n\n    @media (max-width: 768px) { .neu-card { padding: 25px; } .main-title { font-size: 38px; } }\n\u003c\/style\u003e\n\n\n\n\u003cdiv class=\"product-container reveal\"\u003e\n\n    \u003cheader class=\"header-section\"\u003e\n        \u003ch1 class=\"main-title\"\u003eWIFI CSI PROGRAM\u003c\/h1\u003e\n        \n        \u003cdiv class=\"neu-sunken\" style=\"display: inline-block; padding: 15px 30px;\"\u003e\n            \u003cdiv class=\"badge\"\u003eATTENTION\u003c\/div\u003e\n            \u003cp class=\"subtitle\" style=\"margin-bottom: 0;\"\u003e\n                With the purchase of the \u003cstrong\u003eSGP Card Mini\u003c\/strong\u003e you will have access to this code completely for \u003cstrong\u003eFREE\u003c\/strong\u003e.\n            \u003c\/p\u003e\n        \u003c\/div\u003e\n    \u003c\/header\u003e\n\n    \u003cdiv class=\"neu-card\"\u003e\n        \u003cp class=\"content-text\"\u003e\n            This code is made for those who want to test the functions of \u003cstrong\u003eWi-Fi CSI in an extreme way\u003c\/strong\u003e.\n        \u003c\/p\u003e\n        \n        \u003cp class=\"content-text\"\u003e\n            This program detects presence and movement within your own test environment \u003cstrong\u003eusing Wi-Fi sensing\u003c\/strong\u003e, for research and educational use. It is a fully editable code so that you can use it with any open-source device.\n        \u003c\/p\u003e\n\n        \u003cdiv class=\"highlight-box\"\u003e\n            \u003cp class=\"content-text\" style=\"font-size: 16px; margin-bottom: 0;\"\u003e\n                Although it is compatible with different hardware, \u003cstrong\u003ewe highly recommend using one of our devices\u003c\/strong\u003e. For better accuracy, the \u003cstrong\u003eSGP Card Mini\u003c\/strong\u003e should be used. In fact, it is recommended to use this code with \u003cstrong\u003e4 connected SGP Card Minis\u003c\/strong\u003e to achieve excellent detection in the environment.\n            \u003c\/p\u003e\n        \u003c\/div\u003e\n    \u003c\/div\u003e\n\n    \u003c!-- Live Simulation Box --\u003e\n    \u003cdiv class=\"sim-wrapper\"\u003e\n        \u003ch3 style=\"text-align: center; padding-top: 5px; margin-bottom: 15px;\"\u003eLIVE TRACKER SIMULATION\u003c\/h3\u003e\n        \u003cdiv class=\"sim-container\"\u003e\n            \u003cdiv id=\"sim-canvas-container\"\u003e\u003c\/div\u003e\n            \u003cdiv id=\"tactical-overlay\"\u003e\n                \u003cdiv class=\"crosshair\"\u003e\n                    \u003cdiv class=\"circle\"\u003e\u003c\/div\u003e\n                \u003c\/div\u003e\n            \u003c\/div\u003e\n\n            \u003c!-- UI \/ HUD Neon (Translated to English) --\u003e\n            \u003cdiv class=\"hud-element top-left\"\u003e\n                \u003ch1 class=\"blink\"\u003eC.S.I. SYSTEM ACTIVE\u003c\/h1\u003e\n                \u003cp\u003eTYPE: WIFI SIGNAL REFRACTION\u003c\/p\u003e\n                \u003cp\u003eFREQ: 5.8 GHz [HIGH BAND]\u003c\/p\u003e\n                \u003cp id=\"time-display\"\u003eT: 00:00:00:00\u003c\/p\u003e\n            \u003c\/div\u003e\n\n            \u003cdiv class=\"hud-element top-right\"\u003e\n                \u003ch2\u003ePRESENCE DETECTED\u003c\/h2\u003e\n                \u003cp\u003eDISTANCE: \u003cspan id=\"dist-val\"\u003e4.2\u003c\/span\u003em\u003c\/p\u003e\n                \u003cp\u003eSIGNAL STABILITY: \u003cspan class=\"blink\"\u003e78 %\u003c\/span\u003e\u003c\/p\u003e\n                \u003cp\u003eSTATUS: \u003cspan id=\"status-val\" style=\"color: #fff;\"\u003eMOTION DETECTED\u003c\/span\u003e\u003c\/p\u003e\n            \u003c\/div\u003e\n\n            \u003cdiv class=\"hud-element bottom-left\"\u003e\n                \u003ch3\u003eSENSOR ARRAY\u003c\/h3\u003e\n                \u003cp\u003eMULTIPATH: COMPENSATED\u003c\/p\u003e\n                \u003cp\u003eAMBIENT NOISE: 12%\u003c\/p\u003e\n                \u003cp\u003eSPATIAL RES: SUB-MILLIMETER\u003c\/p\u003e\n            \u003c\/div\u003e\n\n            \u003cdiv class=\"hud-element bottom-right\"\u003e\n                \u003ch3\u003eSUBCARRIER AMPLITUDE\u003c\/h3\u003e\n                \u003cdiv class=\"signal-bars\"\u003e\n                    \u003cdiv class=\"bar\"\u003e\u003c\/div\u003e\n\u003cdiv class=\"bar\"\u003e\u003c\/div\u003e\n\u003cdiv class=\"bar\"\u003e\u003c\/div\u003e\n                    \u003cdiv class=\"bar\"\u003e\u003c\/div\u003e\n\u003cdiv class=\"bar\"\u003e\u003c\/div\u003e\n                \u003c\/div\u003e\n                \u003cp style=\"margin-top:10px; font-size:0.6rem;\"\u003eREAL-TIME SPECTRUM ANALYSIS\u003c\/p\u003e\n            \u003c\/div\u003e\n\n            \u003cdiv class=\"controls-info\"\u003e\n                [ LEFT CLICK: ROTATE ] - [ WHEEL: ZOOM ] - [ RIGHT CLICK: PAN ]\n            \u003c\/div\u003e\n        \u003c\/div\u003e\n    \u003c\/div\u003e\n\n    \u003c!-- Video Section --\u003e\n    \u003cdiv class=\"media-grid\"\u003e\n        \u003cdiv class=\"video-container\"\u003e\n            \u003cvideo autoplay loop muted playsinline controls\u003e\n                \u003csource src=\"https:\/\/cdn.shopify.com\/videos\/c\/o\/v\/1c5a6763b9fc410eb95d7ecca54f226c.mp4\" type=\"video\/mp4\"\u003e\n                Your browser does not support HTML5 video.\n            \u003c\/source\u003e\u003c\/video\u003e\n        \u003c\/div\u003e\n        \u003cdiv class=\"video-container\"\u003e\n            \u003cvideo autoplay loop muted playsinline controls\u003e\n                \u003csource src=\"https:\/\/cdn.shopify.com\/videos\/c\/o\/v\/a75a0ebd9c3d401d935577b1109b1f33.mp4\" type=\"video\/mp4\"\u003e\n                Your browser does not support HTML5 video.\n            \u003c\/source\u003e\u003c\/video\u003e\n        \u003c\/div\u003e\n    \u003c\/div\u003e\n\n    \u003cdiv class=\"disclaimer neu-sunken\"\u003e\n        \u003ch4\u003eResearch Use and Beta Phase\u003c\/h4\u003e\n        \u003cp\u003e\n            \u003cstrong\u003eATTENTION:\u003c\/strong\u003e The use of this code is purely for research. \n            Please note that it is in a \u003cstrong\u003ebeta\u003c\/strong\u003e state and may have minor errors depending on detection distances or electromagnetic environmental conditions.\n        \u003c\/p\u003e\n    \u003c\/div\u003e\n\n\u003c\/div\u003e\n\n\u003c!-- Three.js Scripts --\u003e\n\u003cscript src=\"https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/three.js\/r128\/three.min.js\"\u003e\u003c\/script\u003e\n\u003cscript src=\"https:\/\/cdn.jsdelivr.net\/npm\/three@0.128.0\/examples\/js\/controls\/OrbitControls.js\"\u003e\u003c\/script\u003e\n\n\u003cscript\u003e\n    \/\/ Self-invoking function to prevent global scope pollution\n    (function() {\n        const container = document.getElementById('sim-canvas-container');\n        if (!container) return;\n\n        \/\/ --- CONFIGURACIÓN DE THREE.JS ---\n        const scene = new THREE.Scene();\n        scene.fog = new THREE.FogExp2(0x001100, 0.05);\n\n        \/\/ Se usa container.clientWidth en lugar de window.innerWidth\n        const camera = new THREE.PerspectiveCamera(45, container.clientWidth \/ container.clientHeight, 0.1, 1000);\n        camera.position.set(0, 1.5, 4); \n\n        const renderer = new THREE.WebGLRenderer({ antialias: true });\n        renderer.setSize(container.clientWidth, container.clientHeight);\n        renderer.setClearColor(0x000500); \n        container.appendChild(renderer.domElement);\n\n        const controls = new THREE.OrbitControls(camera, renderer.domElement);\n        controls.target.set(0, 1, 0);\n        controls.enableDamping = true;\n        controls.dampingFactor = 0.05;\n        controls.maxPolarAngle = Math.PI \/ 2 + 0.1; \n\n        \/\/ --- ILUMINACIÓN ---\n        const ambientLight = new THREE.AmbientLight(0x003300); \n        scene.add(ambientLight);\n\n        const pointLight = new THREE.PointLight(0x00ff33, 2, 10);\n        pointLight.position.set(0, 3, 2);\n        scene.add(pointLight);\n\n        \/\/ --- ENTORNO NEON (GRID) ---\n        const gridHelper = new THREE.GridHelper(20, 40, 0x00ff33, 0x003300);\n        gridHelper.position.y = 0;\n        gridHelper.material.transparent = true;\n        gridHelper.material.opacity = 0.4;\n        scene.add(gridHelper);\n\n        const circleGeo = new THREE.RingGeometry(1.5, 1.55, 32);\n        const circleMat = new THREE.MeshBasicMaterial({ color: 0x00ff33, side: THREE.DoubleSide, transparent: true, opacity: 0.3 });\n        const radarCircle = new THREE.Mesh(circleGeo, circleMat);\n        radarCircle.rotation.x = Math.PI \/ 2;\n        scene.add(radarCircle);\n\n        \/\/ --- ESTRUCTURA DEL ESQUELETO ---\n        const baseJoints = {\n            headTop: new THREE.Vector3(0, 1.85, 0),\n            head: new THREE.Vector3(0, 1.75, 0),\n            neck: new THREE.Vector3(0, 1.6, 0),\n            shoulderL: new THREE.Vector3(-0.25, 1.5, 0),\n            shoulderR: new THREE.Vector3(0.25, 1.5, 0),\n            elbowL: new THREE.Vector3(-0.35, 1.15, 0),\n            elbowR: new THREE.Vector3(0.35, 1.15, 0),\n            handL: new THREE.Vector3(-0.35, 0.8, 0),\n            handR: new THREE.Vector3(0.35, 0.8, 0),\n            spineTop: new THREE.Vector3(0, 1.4, 0),\n            spineMid: new THREE.Vector3(0, 1.2, 0),\n            pelvis: new THREE.Vector3(0, 0.95, 0),\n            hipL: new THREE.Vector3(-0.15, 0.9, 0),\n            hipR: new THREE.Vector3(0.15, 0.9, 0),\n            kneeL: new THREE.Vector3(-0.15, 0.45, 0),\n            kneeR: new THREE.Vector3(0.15, 0.45, 0),\n            footL: new THREE.Vector3(-0.15, 0.05, 0),\n            footR: new THREE.Vector3(0.15, 0.05, 0),\n        };\n\n        const joints = {};\n        const targetJoints = {};\n        for (let key in baseJoints) {\n            joints[key] = baseJoints[key].clone();\n            targetJoints[key] = baseJoints[key].clone();\n        }\n\n        const bodyVolumes = [\n            { start: 'headTop', end: 'head', radius: 0.12, type: 'head' }, \n            { start: 'head', end: 'neck', radius: 0.08, type: 'neck' }, \n            { start: 'neck', end: 'spineTop', radius: 0.1, type: 'torso' }, \n            { start: 'spineTop', end: 'spineMid', radius: 0.12, type: 'torso' }, \n            { start: 'spineMid', end: 'pelvis', radius: 0.13, type: 'torso' }, \n            { start: 'spineTop', end: 'shoulderL', radius: 0.09, type: 'torso' }, \n            { start: 'shoulderL', end: 'elbowL', radius: 0.07, type: 'arm' }, \n            { start: 'elbowL', end: 'handL', radius: 0.06, type: 'arm' }, \n            { start: 'spineTop', end: 'shoulderR', radius: 0.09, type: 'torso' }, \n            { start: 'shoulderR', end: 'elbowR', radius: 0.07, type: 'arm' }, \n            { start: 'elbowR', end: 'handR', radius: 0.06, type: 'arm' }, \n            { start: 'pelvis', end: 'hipL', radius: 0.11, type: 'leg' }, \n            { start: 'hipL', end: 'kneeL', radius: 0.09, type: 'leg' }, \n            { start: 'kneeL', end: 'footL', radius: 0.08, type: 'leg' }, \n            { start: 'pelvis', end: 'hipR', radius: 0.11, type: 'leg' }, \n            { start: 'hipR', end: 'kneeR', radius: 0.09, type: 'leg' }, \n            { start: 'kneeR', end: 'footR', radius: 0.08, type: 'leg' }, \n        ];\n\n        \/\/ --- NUBE DE PUNTOS CSI ---\n        const particlesCount = 12000; \n        const particlesGeo = new THREE.BufferGeometry();\n        const particlesPos = new Float32Array(particlesCount * 3);\n        const particlesColor = new Float32Array(particlesCount * 3); \n        \n        for(let i=0; i \u003c particlesCount * 3; i+=3) {\n            particlesColor[i] = 0;\n            particlesColor[i+1] = 0.5;\n            particlesColor[i+2] = 0;\n        }\n\n        particlesGeo.setAttribute('position', new THREE.BufferAttribute(particlesPos, 3));\n        particlesGeo.setAttribute('color', new THREE.BufferAttribute(particlesColor, 3));\n\n        const particlesMat = new THREE.PointsMaterial({\n            size: 0.015, \n            vertexColors: true,\n            transparent: true,\n            opacity: 0.7,\n            blending: THREE.AdditiveBlending\n        });\n\n        const particleSystem = new THREE.Points(particlesGeo, particlesMat);\n        scene.add(particleSystem);\n\n        let clock = new THREE.Clock();\n        let currentState = 'walk';\n        let lastStateChange = 0;\n        let stateDuration = 5; \n\n        function getRandomPointInCylinder(start, end, radius) {\n            const axis = new THREE.Vector3().subVectors(end, start);\n            const len = axis.length();\n            axis.normalize();\n\n            let perp = new THREE.Vector3(1, 0, 0);\n            if (Math.abs(axis.x) \u003e 0.9) perp = new THREE.Vector3(0, 1, 0);\n            perp.cross(axis).normalize();\n\n            const perp2 = new THREE.Vector3().crossVectors(axis, perp).normalize();\n\n            const angle = Math.random() * Math.PI * 2;\n            const r = Math.sqrt(Math.random()) * radius; \n            const h = Math.random() * len; \n\n            const point = new THREE.Vector3().copy(start)\n                .addScaledVector(axis, h)\n                .addScaledVector(perp, r * Math.cos(angle))\n                .addScaledVector(perp2, r * Math.sin(angle));\n            \n            return point;\n        }\n\n        function getRandomPointInSphere(center, radius) {\n            const u = Math.random();\n            const v = Math.random();\n            const theta = u * 2.0 * Math.PI;\n            const phi = Math.acos(2.0 * v - 1.0);\n            const r = Math.cbrt(Math.random()) * radius;\n            const sinTheta = Math.sin(theta);\n            const cosTheta = Math.cos(theta);\n            const sinPhi = Math.sin(phi);\n            const cosPhi = Math.cos(phi);\n            const x = r * sinPhi * cosTheta;\n            const y = r * sinPhi * sinTheta;\n            const z = r * cosPhi;\n            return new THREE.Vector3(center.x + x, center.y + y, center.z + z);\n        }\n\n        function updateSkeleton(time) {\n            if (time - lastStateChange \u003e stateDuration) {\n                lastStateChange = time;\n                const rand = Math.random();\n                const statusElement = document.getElementById('status-val');\n                \n                if (rand \u003c 0.35) {\n                    currentState = 'walk';\n                    stateDuration = 4 + Math.random() * 5; \n                    statusElement.innerText = \"MOTION (WALKING)\";\n                } else if (rand \u003c 0.55) {\n                    currentState = 'wave';\n                    stateDuration = 3 + Math.random() * 2; \n                    statusElement.innerText = \"GESTURE: WAVING\";\n                } else if (rand \u003c 0.8) {\n                    currentState = 'idle';\n                    stateDuration = 4 + Math.random() * 4; \n                    statusElement.innerText = \"IDLE (OBSERVING)\";\n                } else {\n                    currentState = 'point';\n                    stateDuration = 2.5 + Math.random() * 2; \n                    statusElement.innerText = \"GESTURE: POINTING\";\n                }\n            }\n\n            for (let key in targetJoints) {\n                targetJoints[key].copy(baseJoints[key]);\n            }\n\n            const breath = Math.sin(time * 2) * 0.015;\n            targetJoints.spineTop.y += breath;\n            targetJoints.spineMid.y += breath * 0.5;\n            targetJoints.shoulderL.y += breath;\n            targetJoints.shoulderR.y += breath;\n            targetJoints.neck.y += breath;\n            targetJoints.head.y += breath;\n            targetJoints.headTop.y += breath;\n\n            if (currentState === 'walk') {\n                const walkSpeed = 3;\n                const t = time * walkSpeed;\n                const bounce = Math.abs(Math.sin(t)) * 0.05;\n                \n                for (let key in targetJoints) targetJoints[key].y += bounce;\n\n                targetJoints.handL.z += Math.sin(t) * 0.3;\n                targetJoints.elbowL.z += Math.sin(t) * 0.15;\n                targetJoints.handR.z += Math.sin(t + Math.PI) * 0.3;\n                targetJoints.elbowR.z += Math.sin(t + Math.PI) * 0.15;\n\n                targetJoints.footL.z += Math.sin(t + Math.PI) * 0.3;\n                targetJoints.footL.y += Math.max(0, Math.sin(t + Math.PI) * 0.1);\n                targetJoints.kneeL.z += Math.sin(t + Math.PI) * 0.15 + 0.1;\n\n                targetJoints.footR.z += Math.sin(t) * 0.3;\n                targetJoints.footR.y += Math.max(0, Math.sin(t) * 0.1);\n                targetJoints.kneeR.z += Math.sin(t) * 0.15 + 0.1;\n\n                targetJoints.shoulderL.z -= Math.sin(t) * 0.05;\n                targetJoints.shoulderR.z -= Math.sin(t + Math.PI) * 0.05;\n            } \n            else if (currentState === 'wave') {\n                targetJoints.shoulderR.y += 0.05; \n                targetJoints.elbowR.set(0.45, 1.45, 0); \n                targetJoints.handR.set(0.5, 1.8, Math.sin(time * 12) * 0.15); \n                \n                targetJoints.head.x += 0.05;\n                targetJoints.headTop.x += 0.08;\n                targetJoints.headTop.y -= 0.02; \n            }\n            else if (currentState === 'idle') {\n                const lookX = Math.sin(time * 1.2) * 0.08; \n                const lookZ = Math.cos(time * 0.8) * 0.05; \n                targetJoints.head.x += lookX;\n                targetJoints.headTop.x += lookX * 1.5;\n                targetJoints.head.z += lookZ;\n                targetJoints.headTop.z += lookZ * 1.5;\n                \n                targetJoints.handL.x -= 0.03;\n                targetJoints.handL.z -= 0.05;\n                targetJoints.handR.x += 0.03;\n                targetJoints.handR.z -= 0.05;\n            }\n            else if (currentState === 'point') {\n                targetJoints.shoulderL.z += 0.1; \n                targetJoints.shoulderL.y += 0.05;\n                targetJoints.elbowL.set(-0.3, 1.3, 0.2); \n                targetJoints.handL.set(-0.2, 1.35, 0.6); \n                \n                targetJoints.spineTop.z += 0.05;\n                targetJoints.head.z += 0.08;\n                targetJoints.headTop.z += 0.1;\n                targetJoints.headTop.y -= 0.02;\n            }\n\n            const lerpFactor = 0.08; \n            for (let key in joints) {\n                joints[key].lerp(targetJoints[key], lerpFactor);\n            }\n\n            const pPositions = particleSystem.geometry.attributes.position.array;\n            const pColors = particleSystem.geometry.attributes.color.array;\n            const pointsPerVolume = Math.floor(particlesCount \/ bodyVolumes.length);\n            let pIndex = 0;\n\n            bodyVolumes.forEach(vol =\u003e {\n                const start = joints[vol.start];\n                const end = joints[vol.end];\n                \n                for(let j=0; j \u003c pointsPerVolume; j++) {\n                    let point;\n                    if (vol.type === 'head') {\n                         point = getRandomPointInSphere(start, vol.radius); \n                    } else {\n                         point = getRandomPointInCylinder(start, end, vol.radius);\n                    }\n                    \n                    let px = point.x;\n                    let py = point.y;\n                    let pz = point.z;\n\n                    const rfWave1 = Math.sin(px * 3 + pz * 1.5 + time * 4);\n                    const rfWave2 = Math.cos(py * 4 - time * 2);\n                    const distFromCenter = Math.sqrt(px*px + pz*pz);\n                    const rfWave3 = Math.sin(distFromCenter * 5 - time * 3);\n\n                    let combinedRF = (rfWave1 + rfWave2 + rfWave3) \/ 3;\n                    combinedRF = (combinedRF + 1) \/ 2; \n\n                    const waveIntensity = Math.pow(combinedRF, 3);\n\n                    let r = 0.0;\n                    let g = 0.2 + (Math.random() * 0.1); \n                    let b = 0.05;\n\n                    g += waveIntensity * 0.8; \n                    b += waveIntensity * 0.4; \n                    r += waveIntensity * 0.1; \n\n                    const noise = 0.025; \n                    px += (Math.random() - 0.5) * noise;\n                    py += (Math.random() - 0.5) * noise;\n                    pz += (Math.random() - 0.5) * noise;\n\n                    if(waveIntensity \u003e 0.85 \u0026\u0026 Math.random() \u003e 0.98) {\n                         px += (Math.random() - 0.5) * 0.2;\n                    }\n\n                    pPositions[pIndex] = px;\n                    pPositions[pIndex+1] = py;\n                    pPositions[pIndex+2] = pz;\n                    \n                    pColors[pIndex] = r;\n                    pColors[pIndex+1] = g;\n                    pColors[pIndex+2] = b;\n\n                    pIndex += 3;\n                }\n            });\n            while (pIndex \u003c particlesCount * 3) { \n                pPositions[pIndex] = 0; \n                pColors[pIndex] = 0; \n                pIndex++;\n            }\n            particleSystem.geometry.attributes.position.needsUpdate = true;\n            particleSystem.geometry.attributes.color.needsUpdate = true; \n        }\n\n        function updateHUD(time) {\n            const millis = Math.floor(time * 1000).toString().padStart(4, '0').substring(0, 2);\n            document.getElementById('time-display').innerText = `T: 00:${Math.floor(time\/60).toString().padStart(2,'0')}:${(Math.floor(time)%60).toString().padStart(2,'0')}:${millis}`;\n\n            if(Math.random() \u003e 0.95) {\n                const mockDist = (4.0 + Math.random() * 0.5).toFixed(2);\n                document.getElementById('dist-val').innerText = mockDist;\n            }\n        }\n\n        function animate() {\n            requestAnimationFrame(animate);\n            \n            const elapsedTime = clock.getElapsedTime();\n            \n            updateSkeleton(elapsedTime);\n            updateHUD(elapsedTime);\n            \n            controls.update();\n\n            radarCircle.scale.x = 1 + Math.sin(elapsedTime * 2) * 0.02;\n            radarCircle.scale.y = 1 + Math.sin(elapsedTime * 2) * 0.02;\n\n            renderer.render(scene, camera);\n        }\n\n        window.addEventListener('resize', () =\u003e {\n            camera.aspect = container.clientWidth \/ container.clientHeight;\n            camera.updateProjectionMatrix();\n            renderer.setSize(container.clientWidth, container.clientHeight);\n        });\n\n        animate();\n    })();\n\u003c\/script\u003e\n\n\n\u003c\/body\u003e","brand":"sgpstore","offers":[{"title":"Default Title","offer_id":57872990863692,"sku":null,"price":49.0,"currency_code":"EUR","in_stock":true}],"thumbnail_url":"\/\/cdn.shopify.com\/s\/files\/1\/1057\/9807\/4700\/files\/rn-image_picker_lib_temp_c2ed273f-a959-43a2-ac9a-fe663cb01a04.png?v=1782242329"},{"product_id":"sin-titulo-3jul_2-23-43","title":"SGP TACTICAL ULTRA (APK) — also for Mac \u0026 Windows","description":"\u003c!-- ===== SGP TACTICAL (Mac + Windows + Android APK) - Shopify product description (EN). Paste into the product description \"Edit HTML\" (\u003c\u003e) view. ===== --\u003e\n\u003cdiv class=\"sgp-pd\"\u003e\n  \u003cstyle\u003e\n    .sgp-pd{--g:#35e06a;--gold:#ffc63a;--tx:#e9f5ee;--mut:#9fb6aa;\n      background:radial-gradient(120% 120% at 80% 0%,rgba(53,224,106,.10),transparent 45%),linear-gradient(180deg,#060b08,#02110a);\n      color:var(--tx);border-radius:18px;padding:34px 26px;font-family:-apple-system,BlinkMacSystemFont,\"Segoe UI\",Roboto,Arial,sans-serif;line-height:1.6;max-width:960px;margin:0 auto;border:1px solid rgba(53,224,106,.18)}\n    .sgp-pd *{box-sizing:border-box}\n    .sgp-pd .vid{position:relative;border-radius:14px;overflow:hidden;border:1px solid rgba(53,224,106,.25);box-shadow:0 18px 50px rgba(0,0,0,.5);margin-bottom:26px}\n    .sgp-pd video{width:100%;display:block}\n    .sgp-pd h1{font-size:40px;line-height:1.05;letter-spacing:1px;margin:6px 0 10px;font-weight:800;text-shadow:0 0 28px rgba(53,224,106,.35)}\n    .sgp-pd .kick{color:var(--g);letter-spacing:4px;font-size:12px;font-weight:700;text-transform:uppercase}\n    .sgp-pd .sub{font-size:19px;color:#cfe9db;margin:0 0 18px;max-width:720px}\n    .sgp-pd .badges{display:flex;flex-wrap:wrap;gap:10px;margin:0 0 26px}\n    .sgp-pd .badge{border:1px solid rgba(53,224,106,.35);background:rgba(53,224,106,.07);color:#dcf3e6;padding:7px 13px;border-radius:999px;font-size:13px;font-weight:600}\n    .sgp-pd .lead{color:var(--mut);font-size:16px;max-width:760px;margin:0 0 30px}\n    .sgp-pd h2{font-size:15px;letter-spacing:3px;text-transform:uppercase;color:var(--g);margin:34px 0 16px;border-top:1px solid rgba(53,224,106,.15);padding-top:22px}\n    .sgp-pd .grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(250px,1fr));gap:14px}\n    .sgp-pd .card{background:linear-gradient(180deg,rgba(255,255,255,.03),rgba(255,255,255,.01));border:1px solid rgba(255,255,255,.08);border-radius:14px;padding:18px}\n    .sgp-pd .card.top{border-color:rgba(255,198,58,.45);box-shadow:0 0 0 1px rgba(255,198,58,.10) inset}\n    .sgp-pd .card h3{margin:0 0 7px;font-size:17px;font-weight:700;display:flex;align-items:center;gap:8px}\n    .sgp-pd .star{color:var(--gold)}\n    .sgp-pd .card p{margin:0;color:var(--mut);font-size:14.5px}\n    .sgp-pd .pro{margin-top:34px;text-align:center;border:1px solid rgba(255,198,58,.4);border-radius:16px;padding:26px;background:radial-gradient(100% 120% at 50% 0%,rgba(255,198,58,.10),transparent 60%)}\n    .sgp-pd .pro h2{border:0;padding:0;margin:0 0 8px;color:var(--gold)}\n    .sgp-pd .cta{display:inline-block;margin-top:18px;background:linear-gradient(90deg,#35e06a,#22c55e);color:#04140a;font-weight:800;letter-spacing:.5px;padding:14px 30px;border-radius:999px;text-decoration:none;font-size:16px}\n    .sgp-pd .trust{margin-top:26px;text-align:center;color:var(--mut);font-size:14px}\n    @media(max-width:600px){.sgp-pd h1{font-size:30px}.sgp-pd{padding:24px 16px}}\n  \u003c\/style\u003e\n\n  \u003cdiv class=\"vid\"\u003e\n    \u003cvideo controls autoplay muted loop playsinline preload=\"metadata\" src=\"https:\/\/cdn.shopify.com\/videos\/c\/o\/v\/bf7668530a9b41ffa3916adc25014a22.mov\"\u003e\u003c\/video\u003e\n  \u003c\/div\u003e\n\n  \u003cdiv class=\"kick\"\u003eSmart Global Projection\u003c\/div\u003e\n  \u003ch1\u003eSGP TACTICAL\u003c\/h1\u003e\n  \u003cp class=\"sub\"\u003eThe full tactical toolkit on your Mac, PC and Android phone — map, radar, AR, live satellites and encrypted team comms. Works even offline.\u003c\/p\u003e\n\n  \u003cdiv class=\"badges\"\u003e\n    \u003cspan class=\"badge\"\u003emacOS\u003c\/span\u003e\n    \u003cspan class=\"badge\"\u003eWindows\u003c\/span\u003e\n    \u003cspan class=\"badge\"\u003eAndroid (APK)\u003c\/span\u003e\n    \u003cspan class=\"badge\"\u003eWorks offline\u003c\/span\u003e\n    \u003cspan class=\"badge\"\u003eNo subscription\u003c\/span\u003e\n  \u003c\/div\u003e\n\n  \u003cp class=\"lead\"\u003eRun operations from your computer, then take the exact same toolkit into the field on your phone. The map, comms, the AI camera, live satellites and more — everything runs on your own device. No account, no cloud, nothing that expires.\u003c\/p\u003e\n\n  \u003ch2\u003eWhat's inside\u003c\/h2\u003e\n  \u003cdiv class=\"grid\"\u003e\n    \u003cdiv class=\"card\"\u003e\n\u003ch3\u003eTactical Map\u003c\/h3\u003e\n\u003cp\u003eMark allies, objectives, hazards and your HQ. Draw zones, measure distances, and read position, compass and heading, across several map styles.\u003c\/p\u003e\n\u003c\/div\u003e\n    \u003cdiv class=\"card top\"\u003e\n\u003ch3\u003e\n\u003cspan class=\"star\"\u003e★\u003c\/span\u003e AR Tactical HUD\u003c\/h3\u003e\n\u003cp\u003eThrough the camera, your waypoints and teammates show up over the live view, with bearings and distances laid onto the real world.\u003c\/p\u003e\n\u003c\/div\u003e\n    \u003cdiv class=\"card top\"\u003e\n\u003ch3\u003e\n\u003cspan class=\"star\"\u003e★\u003c\/span\u003e AI Camera\u003c\/h3\u003e\n\u003cp\u003eOn-device vision that reads objects, movement, poses and hand gestures, with night-vision and thermal views. It all runs on the device, so nothing leaves it.\u003c\/p\u003e\n\u003c\/div\u003e\n    \u003cdiv class=\"card top\"\u003e\n\u003ch3\u003e\n\u003cspan class=\"star\"\u003e★\u003c\/span\u003e Signal Radar\u003c\/h3\u003e\n\u003cp\u003eA live 3D radar that shows Bluetooth and Wi-Fi signals by strength, so you can read the wireless world around you (live scanning on Android).\u003c\/p\u003e\n\u003c\/div\u003e\n    \u003cdiv class=\"card top\"\u003e\n\u003ch3\u003e\n\u003cspan class=\"star\"\u003e★\u003c\/span\u003e 3D Building Scanner\u003c\/h3\u003e\n\u003cp\u003eTrace a building's footprint and watch it rise in 3D, floor by floor. Add measurements, plan evacuation routes and read heatmaps.\u003c\/p\u003e\n\u003c\/div\u003e\n    \u003cdiv class=\"card top\"\u003e\n\u003ch3\u003e\n\u003cspan class=\"star\"\u003e★\u003c\/span\u003e Orbital Satellites\u003c\/h3\u003e\n\u003cp\u003eSpin a live 3D globe of the satellites passing overhead, flags and all, and see what's above you right now.\u003c\/p\u003e\n\u003c\/div\u003e\n    \u003cdiv class=\"card\"\u003e\n\u003ch3\u003eNavigation\u003c\/h3\u003e\n\u003cp\u003ePlot a route with waypoints on foot, by car, bike, off-road or air. Real footpaths, elevation profiles, and quick alternate exits when you need them.\u003c\/p\u003e\n\u003c\/div\u003e\n    \u003cdiv class=\"card\"\u003e\n\u003ch3\u003eSky Mode\u003c\/h3\u003e\n\u003cp\u003eIdentify the Sun, Moon, planets and stars, with sunrise, sunset, golden hour and the moon phase. All of it offline.\u003c\/p\u003e\n\u003c\/div\u003e\n    \u003cdiv class=\"card top\"\u003e\n\u003ch3\u003e\n\u003cspan class=\"star\"\u003e★\u003c\/span\u003e Encrypted Team Comms\u003c\/h3\u003e\n\u003cp\u003eGroup chat, contacts by QR, private walkie channels and live team tracking. Messages are end-to-end encrypted, with group voice calls and a shared map everyone can see.\u003c\/p\u003e\n\u003c\/div\u003e\n    \u003cdiv class=\"card\"\u003e\n\u003ch3\u003eOffline \u0026amp; Resilient\u003c\/h3\u003e\n\u003cp\u003eDownload the areas you need and keep working with zero signal. Your data stays on your device.\u003c\/p\u003e\n\u003c\/div\u003e\n    \u003cdiv class=\"card\"\u003e\n\u003ch3\u003eField Tools\u003c\/h3\u003e\n\u003cp\u003eCompass, level, metal detector, sound meter, speedometer and a strobe light. The small stuff, all in one place.\u003c\/p\u003e\n\u003c\/div\u003e\n    \u003cdiv class=\"card\"\u003e\n\u003ch3\u003eSOS \u0026amp; Alerts\u003c\/h3\u003e\n\u003cp\u003eOne-tap SOS and alerts, wrapped in a clean, dark interface built for the field.\u003c\/p\u003e\n\u003c\/div\u003e\n  \u003c\/div\u003e\n\n  \u003cdiv class=\"pro\"\u003e\n    \u003ch2\u003eEverything included\u003c\/h2\u003e\n    \u003cp style=\"color:#cfe9db;margin:0;max-width:560px;display:inline-block\"\u003eNo subscription, no in-app paywalls, no codes — \u003cstrong\u003eevery edition is unlocked from the start\u003c\/strong\u003e. Pay once and it's yours.\u003c\/p\u003e\n    \u003cbr\u003e\n    \u003ca class=\"cta\" href=\"#\"\u003eGet SGP Tactical\u003c\/a\u003e\n  \u003c\/div\u003e\n\n  \u003cp class=\"trust\"\u003eYour data stays on your device. We don't sell it, ever.\u003c\/p\u003e\n\n  \u003cp style=\"text-align:center;margin-top:16px\"\u003e\n    \u003cspan style=\"display:inline-block;border:1px solid rgba(53,224,106,.35);background:rgba(53,224,106,.07);color:#dcf3e6;padding:8px 16px;border-radius:999px;font-size:13.5px;font-weight:600\"\u003eWorks on macOS, Windows and Android (APK)\u003c\/span\u003e\n  \u003c\/p\u003e\n\n  \u003cdiv style=\"margin:16px auto 0;max-width:720px;border:1px solid rgba(255,198,58,.35);background:rgba(255,198,58,.06);border-radius:14px;padding:16px 18px;color:#e9f5ee;font-size:14px;text-align:center\"\u003e\n    \u003cstrong style=\"color:#ffc63a\"\u003eTip:\u003c\/strong\u003e on the computer version a few features are limited — they rely on phone hardware, like \u003cstrong\u003ereal GPS and live Bluetooth \/ Wi-Fi scanning\u003c\/strong\u003e. To get the most out of SGP Tactical, use the \u003cstrong\u003eAndroid APK\u003c\/strong\u003e in the field.\n  \u003c\/div\u003e\n\u003c\/div\u003e","brand":"sgpstore","offers":[{"title":"Default Title","offer_id":57951249858892,"sku":null,"price":69.0,"currency_code":"EUR","in_stock":true}],"thumbnail_url":"\/\/cdn.shopify.com\/s\/files\/1\/1057\/9807\/4700\/files\/IMG-0461.png?v=1783210812"},{"product_id":"3d-urban-scanner","title":"3D Urban Scanner for Mac \u0026 Window","description":"\u003cmeta charset=\"utf-8\"\u003e\n\u003c!-- ============================================================\n     URBAN SCANNER 3D - Shopify product description (English)\n     Paste into the product description via the \"\u003c\u003e\" (Show HTML) view.\n     Static, self-contained (scoped styles only, no scripts).\n     File is UTF-8; Shopify pages are UTF-8, so all icons render fine.\n     ============================================================ --\u003e\n\u003cdiv id=\"us-shop\"\u003e\n  \u003cstyle\u003e\n    #us-shop{--g:#7dff8a;--g2:#46c95a;--amb:#ffb733;--cy:#7fe9ff;--bg:#070c08;--pan:#0d150e;--ln:rgba(122,255,140,.22);--tx:#cfeccb;--mut:#7f9c78;\n      background:var(--bg);color:var(--tx);border:1px solid var(--ln);border-radius:14px;overflow:hidden;\n      font-family:'Rajdhani','Segoe UI',system-ui,-apple-system,Arial,sans-serif;line-height:1.5;max-width:960px;margin:0 auto}\n    #us-shop *{box-sizing:border-box}\n    #us-shop .mono{font-family:'Share Tech Mono',ui-monospace,Menlo,Consolas,monospace}\n    #us-shop .hero{position:relative;padding:34px 22px 28px;background:\n        radial-gradient(120% 90% at 50% -10%,rgba(43,212,106,.18),transparent 60%),\n        repeating-linear-gradient(0deg,rgba(0,0,0,0),rgba(0,0,0,0) 3px,rgba(0,25,0,.10) 4px),\n        linear-gradient(180deg,#0b140b,#070c08);border-bottom:1px solid var(--ln);text-align:center}\n    #us-shop .kick{font-family:'Share Tech Mono',monospace;color:var(--g);letter-spacing:4px;font-size:12px;text-transform:uppercase;opacity:.85}\n    #us-shop h1{font-family:'Share Tech Mono',monospace;font-size:38px;letter-spacing:3px;margin:8px 0 6px;color:#eafff0;text-shadow:0 0 16px rgba(125,255,138,.45)}\n    #us-shop h1 span{color:var(--g)}\n    #us-shop .sub{font-size:18px;color:var(--tx);max-width:620px;margin:6px auto 16px}\n    #us-shop .badges{display:flex;flex-wrap:wrap;gap:8px;justify-content:center;margin-top:8px}\n    #us-shop .badge{font-family:'Share Tech Mono',monospace;font-size:11px;letter-spacing:1px;color:var(--g);border:1px solid var(--ln);border-radius:20px;padding:5px 12px;background:rgba(10,20,10,.6)}\n    #us-shop h2{font-family:'Share Tech Mono',monospace;color:var(--g);letter-spacing:2px;font-size:15px;text-transform:uppercase;margin:0 0 14px;display:flex;align-items:center;gap:10px}\n    #us-shop h2::before{content:\"\";width:22px;height:2px;background:var(--g);box-shadow:0 0 8px var(--g)}\n    #us-shop .grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(232px,1fr));gap:12px;margin-top:4px}\n    #us-shop .card{background:var(--pan);border:1px solid var(--ln);border-radius:10px;padding:14px 15px;position:relative}\n    #us-shop .card .ic{font-size:22px;line-height:1}\n    #us-shop .card h3{font-family:'Share Tech Mono',monospace;font-size:13px;letter-spacing:.5px;color:#eafff0;margin:8px 0 5px}\n    #us-shop .card p{font-size:13.5px;color:var(--tx);margin:0}\n    #us-shop .sect{padding:24px 22px;border-bottom:1px solid var(--ln)}\n    #us-shop .src{display:flex;flex-wrap:wrap;gap:10px}\n    #us-shop .src .s{flex:1;min-width:180px;background:var(--pan);border:1px solid var(--ln);border-radius:10px;padding:13px 15px}\n    #us-shop .src .s b{color:var(--g);font-family:'Share Tech Mono',monospace}\n    #us-shop .trust{display:flex;flex-wrap:wrap;gap:8px;justify-content:center;padding:22px}\n    #us-shop .trust .t{font-family:'Share Tech Mono',monospace;font-size:12px;color:var(--tx);border:1px solid var(--ln);border-radius:8px;padding:9px 13px;background:rgba(10,20,10,.5)}\n    #us-shop .trust .t b{color:var(--cy)}\n    #us-shop .cta{text-align:center;padding:26px 22px 30px;background:linear-gradient(180deg,#0b140b,#070c08)}\n    #us-shop .cta .big{font-family:'Share Tech Mono',monospace;font-size:20px;letter-spacing:2px;color:#eafff0;margin-bottom:6px}\n    #us-shop .cta .plats{color:var(--mut);font-family:'Share Tech Mono',monospace;font-size:12px;letter-spacing:1px}\n    #us-shop .fine{font-size:11.5px;color:var(--mut);text-align:center;padding:0 22px 22px}\n    @media(max-width:560px){#us-shop h1{font-size:28px}}\n  \u003c\/style\u003e\n\n  \u003c!-- HERO --\u003e\n  \u003cdiv class=\"hero\"\u003e\n    \u003cdiv class=\"kick\"\u003e3D Building \u0026amp; Site Intelligence\u003c\/div\u003e\n    \u003ch1\u003eURBAN\u003cspan\u003e\/\/\u003c\/span\u003eSCANNER \u003cspan\u003e3D\u003c\/span\u003e\n\u003c\/h1\u003e\n    \u003cdiv class=\"sub\"\u003eScan \u003cb\u003eany building on Earth\u003c\/b\u003e from official data, rebuild it in 3D, and analyze everything —\n      layout, people flow, evacuation, sunlight, energy and more. Runs on your own device.\u003c\/div\u003e\n    \u003cdiv class=\"badges\"\u003e\n      \u003cspan class=\"badge\"\u003e🪟 Windows\u003c\/span\u003e\n      \u003cspan class=\"badge\"\u003e🍎 macOS\u003c\/span\u003e\n      \u003cspan class=\"badge\"\u003e🌐 Web App (any device)\u003c\/span\u003e\n      \u003cspan class=\"badge\"\u003e⚡ Engine works offline\u003c\/span\u003e\n      \u003cspan class=\"badge\"\u003e🔒 No account · no API keys\u003c\/span\u003e\n    \u003c\/div\u003e\n  \u003c\/div\u003e\n\n  \u003c!-- FEATURES --\u003e\n  \u003cdiv class=\"sect\"\u003e\n    \u003ch2\u003eEverything it does\u003c\/h2\u003e\n    \u003cdiv class=\"grid\"\u003e\n      \u003cdiv class=\"card\"\u003e\n\u003cdiv class=\"ic\"\u003e🌍\u003c\/div\u003e\n\u003ch3\u003eWorldwide scanning\u003c\/h3\u003e\n\u003cp\u003ePull real buildings from official sources — Spanish Cadastre, USA FEMA and OpenStreetMap. Real areas, floor counts and footprints.\u003c\/p\u003e\n\u003c\/div\u003e\n      \u003cdiv class=\"card\"\u003e\n\u003cdiv class=\"ic\"\u003e🏙️\u003c\/div\u003e\n\u003ch3\u003eInstant 3D model\u003c\/h3\u003e\n\u003cp\u003eBuildings reconstructed from their real footprint. X-ray or solid view, floor-by-floor isolation, adjustable roof types.\u003c\/p\u003e\n\u003c\/div\u003e\n      \u003cdiv class=\"card\"\u003e\n\u003cdiv class=\"ic\"\u003e🧠\u003c\/div\u003e\n\u003ch3\u003eAI interior generator\u003c\/h3\u003e\n\u003cp\u003eThe on-device engine lays out rooms, corridors, doors and staircases — a different plan for every floor.\u003c\/p\u003e\n\u003c\/div\u003e\n      \u003cdiv class=\"card\"\u003e\n\u003cdiv class=\"ic\"\u003e📐\u003c\/div\u003e\n\u003ch3\u003e2D floor plans\u003c\/h3\u003e\n\u003cp\u003eClean, printable blueprints for each floor, ready to export to PDF.\u003c\/p\u003e\n\u003c\/div\u003e\n      \u003cdiv class=\"card\"\u003e\n\u003cdiv class=\"ic\"\u003e🧩\u003c\/div\u003e\n\u003ch3\u003eDisassemble view\u003c\/h3\u003e\n\u003cp\u003eExplode the building and see each floor laid out separately in 3D.\u003c\/p\u003e\n\u003c\/div\u003e\n      \u003cdiv class=\"card\"\u003e\n\u003cdiv class=\"ic\"\u003e🚶\u003c\/div\u003e\n\u003ch3\u003eCrowd \u0026amp; occupancy\u003c\/h3\u003e\n\u003cp\u003eAnimated people, live density heatmaps and occupancy estimates by floor and building type.\u003c\/p\u003e\n\u003c\/div\u003e\n      \u003cdiv class=\"card\"\u003e\n\u003cdiv class=\"ic\"\u003e🏃\u003c\/div\u003e\n\u003ch3\u003eEvacuation modeling\u003c\/h3\u003e\n\u003cp\u003eEveryone routes to the nearest exit and you get an estimated clearance time — great for safety planning.\u003c\/p\u003e\n\u003c\/div\u003e\n      \u003cdiv class=\"card\"\u003e\n\u003cdiv class=\"ic\"\u003e📏\u003c\/div\u003e\n\u003ch3\u003eMeasure \u0026amp; annotate\u003c\/h3\u003e\n\u003cp\u003eMeasure distances, drop site markers \u0026amp; notes, and lay out routes\/paths directly in the 3D scene.\u003c\/p\u003e\n\u003c\/div\u003e\n      \u003cdiv class=\"card\"\u003e\n\u003cdiv class=\"ic\"\u003e👁️\u003c\/div\u003e\n\u003ch3\u003eLine-of-sight analysis\u003c\/h3\u003e\n\u003cp\u003ePick a vantage point and instantly see what is visible or blocked, with distance and bearing to any marker.\u003c\/p\u003e\n\u003c\/div\u003e\n      \u003cdiv class=\"card\"\u003e\n\u003cdiv class=\"ic\"\u003e🏊\u003c\/div\u003e\n\u003ch3\u003eParcel features\u003c\/h3\u003e\n\u003cp\u003eDetects pool, garden, parking, sports areas, garage and solar panels around the parcel and places them in 3D.\u003c\/p\u003e\n\u003c\/div\u003e\n      \u003cdiv class=\"card\"\u003e\n\u003cdiv class=\"ic\"\u003e🌦️\u003c\/div\u003e\n\u003ch3\u003eLive environment\u003c\/h3\u003e\n\u003cp\u003eReal-time temperature, humidity, pressure and wind for the exact location.\u003c\/p\u003e\n\u003c\/div\u003e\n      \u003cdiv class=\"card\"\u003e\n\u003cdiv class=\"ic\"\u003e☀️\u003c\/div\u003e\n\u003ch3\u003eSun \u0026amp; solar study\u003c\/h3\u003e\n\u003cp\u003eReal sun path by time of day, plus an estimate of the roof solar \/ PV potential.\u003c\/p\u003e\n\u003c\/div\u003e\n      \u003cdiv class=\"card\"\u003e\n\u003cdiv class=\"ic\"\u003e📊\u003c\/div\u003e\n\u003ch3\u003eAI assessments\u003c\/h3\u003e\n\u003cp\u003eSite complexity index, evacuation-time estimate and energy potential, computed on-device.\u003c\/p\u003e\n\u003c\/div\u003e\n      \u003cdiv class=\"card\"\u003e\n\u003cdiv class=\"ic\"\u003e📄\u003c\/div\u003e\n\u003ch3\u003eOne-click report\u003c\/h3\u003e\n\u003cp\u003eGenerate a full, printable dossier (PDF) of the whole analysis in a single click.\u003c\/p\u003e\n\u003c\/div\u003e\n      \u003cdiv class=\"card\"\u003e\n\u003cdiv class=\"ic\"\u003e✏️\u003c\/div\u003e\n\u003ch3\u003eDraw your own\u003c\/h3\u003e\n\u003cp\u003eNo data for a remote house? Trace its corners on the map and the app builds it — roof and interior included.\u003c\/p\u003e\n\u003c\/div\u003e\n      \u003cdiv class=\"card\"\u003e\n\u003cdiv class=\"ic\"\u003e🗺️\u003c\/div\u003e\n\u003ch3\u003eWhole-zone scan\u003c\/h3\u003e\n\u003cp\u003eBox-select an area and render every building in it at once, with combined occupancy.\u003c\/p\u003e\n\u003c\/div\u003e\n    \u003c\/div\u003e\n  \u003c\/div\u003e\n\n  \u003c!-- DATA SOURCES --\u003e\n  \u003cdiv class=\"sect\"\u003e\n    \u003ch2\u003eBuilt on real, official data\u003c\/h2\u003e\n    \u003cdiv class=\"src\"\u003e\n      \u003cdiv class=\"s\"\u003e\n\u003cb\u003e🇪🇸 Spain\u003c\/b\u003e\u003cbr\u003eOfficial Cadastre — exact parcel, built area, floors and units.\u003c\/div\u003e\n      \u003cdiv class=\"s\"\u003e\n\u003cb\u003e🇺🇸 USA\u003c\/b\u003e\u003cbr\u003eFEMA national building footprints with real heights.\u003c\/div\u003e\n      \u003cdiv class=\"s\"\u003e\n\u003cb\u003e🌍 Worldwide\u003c\/b\u003e\u003cbr\u003eOpenStreetMap building \u0026amp; feature data for the rest of the planet.\u003c\/div\u003e\n    \u003c\/div\u003e\n  \u003c\/div\u003e\n\n  \u003c!-- TRUST --\u003e\n  \u003cdiv\u003e\n    \u003cdiv class=\"trust\"\u003e\n      \u003cdiv class=\"t\"\u003e🖥️ \u003cb\u003eNative apps\u003c\/b\u003e for Windows \u0026amp; macOS\u003c\/div\u003e\n      \u003cdiv class=\"t\"\u003e🌐 \u003cb\u003eWeb app\u003c\/b\u003e installable on any device\u003c\/div\u003e\n      \u003cdiv class=\"t\"\u003e⚡ Engine runs \u003cb\u003eon your device\u003c\/b\u003e\n\u003c\/div\u003e\n      \u003cdiv class=\"t\"\u003e🔒 \u003cb\u003eNo subscription\u003c\/b\u003e, no login, no API keys\u003c\/div\u003e\n      \u003cdiv class=\"t\"\u003e🛰️ Uses \u003cb\u003efree public\u003c\/b\u003e map \u0026amp; weather data\u003c\/div\u003e\n    \u003c\/div\u003e\n  \u003c\/div\u003e\n\n  \u003c!-- CTA --\u003e\n  \u003cdiv class=\"cta\"\u003e\n    \u003cdiv class=\"big\"\u003eONE PURCHASE · ALL PLATFORMS\u003c\/div\u003e\n    \u003cdiv class=\"sub\" style=\"margin:6px auto 12px\"\u003eDownload it for Windows, macOS, or install the web app on any phone, tablet or computer.\u003c\/div\u003e\n    \u003cdiv class=\"plats\"\u003eWINDOWS 10\/11 · macOS (Intel \u0026amp; Apple Silicon) · WEB \/ PWA\u003c\/div\u003e\n  \u003c\/div\u003e\n  \u003cdiv class=\"fine\"\u003eAn internet connection is required to fetch live map, cadastre and weather data. All analysis figures\n    (occupancy, layouts, energy, evacuation) are model-based estimates for planning and study.\u003c\/div\u003e\n\u003c\/div\u003e","brand":"sgpstore","offers":[{"title":"Default Title","offer_id":57986733867340,"sku":null,"price":59.0,"currency_code":"EUR","in_stock":true}],"thumbnail_url":"\/\/cdn.shopify.com\/s\/files\/1\/1057\/9807\/4700\/files\/IMG-0639.png?v=1783301604"}],"url":"https:\/\/sgpstore.net\/collections\/software.oembed","provider":"sgpstore","version":"1.0","type":"link"}