<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Minijuegos - InstaTecno</title>
	<atom:link href="https://instatecno.net/category/minijuegos-aprendizaje/feed" rel="self" type="application/rss+xml" />
	<link>https://instatecno.net/category/minijuegos-aprendizaje</link>
	<description>En InstaTecno nos dedicamos a ofrecer tutoriales y guías prácticas sobre instalación de sistemas operativos, creación de USB de arranque y configuración de software en distintos dispositivos. Nuestro objetivo es ayudarte a dominar las herramientas informáticas más útiles, de forma sencilla y paso a paso.</description>
	<lastBuildDate>Tue, 02 Dec 2025 16:49:17 +0000</lastBuildDate>
	<language>es</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.4</generator>

<image>
	<url>https://instatecno.net/wp-content/uploads/2025/10/659efc22-191f-48d6-bac9-9161c1769f63-80x80.png</url>
	<title>Minijuegos - InstaTecno</title>
	<link>https://instatecno.net/category/minijuegos-aprendizaje</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>INSTATECNO: TRADING EMPIRE</title>
		<link>https://instatecno.net/minijuegos-aprendizaje/instatecno-trading-empire</link>
					<comments>https://instatecno.net/minijuegos-aprendizaje/instatecno-trading-empire#respond</comments>
		
		<dc:creator><![CDATA[David Sanchez]]></dc:creator>
		<pubDate>Thu, 20 Nov 2025 12:22:21 +0000</pubDate>
				<category><![CDATA[Minijuegos]]></category>
		<guid isPermaLink="false">https://instatecno.net/?p=982</guid>

					<description><![CDATA[<p>$0 DEUDA: $0 BANCO Interés 10% cada 10s PEDIR 1,000$ PEDIR 10,000$ PAGAR DEUDA [REINICIAR TODO] No tienes activos. 🏦 [&#8230;]</p>
<p>La entrada <a href="https://instatecno.net/minijuegos-aprendizaje/instatecno-trading-empire">INSTATECNO: TRADING EMPIRE</a> se publicó primero en <a href="https://instatecno.net">InstaTecno</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<div id="it-trader-mobile" style="width: 100%; max-width: 800px; margin: 0 auto; font-family: 'Segoe UI', sans-serif; color: #eee; user-select: none; box-sizing: border-box; background: #0a0a10; border-radius: 12px; overflow: hidden; border: 1px solid #333;">

    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0"/>

    <style>
        /* RESET & VARS */
        #it-trader-mobile * { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }
        #it-trader-mobile {
            --bg: #0a0a10; --card: #14141a; --border: #333;
            --green: #00e676; --red: #ff1744; --blue: #2979ff;
        }

        /* HEADER */
        .tm-header {
            background: #1a1a20; border-bottom: 1px solid var(--border); padding: 15px;
            display: flex; justify-content: space-between; align-items: center;
        }
        .tm-logo img { height: 30px; border-radius: 5px; }
        .tm-stats { text-align: right; font-family: monospace; }
        .tm-cash { color: var(--green); font-size: 16px; font-weight: bold; }
        .tm-debt { color: var(--red); font-size: 12px; }

        /* MAIN VIEW */
        .tm-view { padding: 15px; height: 500px; overflow-y: auto; display: none; }
        .tm-view.active { display: block; }

        /* MARKET CARDS */
        .m-card {
            background: var(--card); border: 1px solid var(--border); border-radius: 10px;
            padding: 15px; margin-bottom: 10px; display: flex; flex-direction: column; gap: 10px;
        }
        .m-top { display: flex; justify-content: space-between; align-items: center; }
        .m-icon svg { width: 30px; height: 30px; }
        .m-price { font-size: 18px; font-weight: bold; font-family: monospace; }
        .m-acts { display: flex; gap: 10px; }
        
        .btn { flex: 1; padding: 10px; border: none; border-radius: 6px; font-weight: bold; cursor: pointer; color: #000; }
        .btn-buy { background: var(--green); }
        .btn-sell { background: var(--red); color: white; }

        /* BANK PANEL */
        .bank-panel { background: #1a0505; border: 1px solid var(--red); padding: 20px; border-radius: 10px; text-align: center; }
        .bank-btn { width: 100%; background: #333; color: white; border: 1px solid #555; padding: 12px; margin-top: 10px; border-radius: 6px; cursor: pointer; }

        /* BOTTOM NAV */
        .tm-nav {
            display: flex; background: #1a1a20; border-top: 1px solid var(--border); height: 60px;
        }
        .nav-btn {
            flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center;
            color: #666; font-size: 10px; font-weight: bold; cursor: pointer;
        }
        .nav-btn.active { color: var(--blue); background: #111; border-top: 2px solid var(--blue); }
        .nav-icon { font-size: 20px; margin-bottom: 2px; }

        /* RESET */
        .reset { text-align: center; margin-top: 20px; color: #555; font-size: 10px; cursor: pointer; }
    </style>

    <div class="tm-header">
        <div class="tm-logo">
            <img decoding="async" src="https://instatecno.net/wp-content/uploads/2025/10/Captura-de-pantalla-2025-10-15-031513.png">
        </div>
        <div class="tm-stats">
            <div class="tm-cash" id="m-cash">$0</div>
            <div class="tm-debt">DEUDA: <span id="m-debt">$0</span></div>
        </div>
    </div>

    <div id="view-market" class="tm-view active">
        </div>

    <div id="view-bank" class="tm-view">
        <div class="bank-panel">
            <h2 style="margin:0; color:var(--red);">BANCO</h2>
            <p style="color:#aaa; font-size:12px;">Interés 10% cada 10s</p>
            <button class="bank-btn" onclick="MobileGame.loan(1000)">PEDIR 1,000$</button>
            <button class="bank-btn" onclick="MobileGame.loan(10000)">PEDIR 10,000$</button>
            <button class="bank-btn" style="background:var(--green); color:black; font-weight:bold;" onclick="MobileGame.repay()">PAGAR DEUDA</button>
        </div>
        <div class="reset" onclick="MobileGame.reset()">[REINICIAR TODO]</div>
    </div>

    <div id="view-port" class="tm-view">
        <div style="text-align:center; color:#777; margin-top:50px;" id="empty-msg">No tienes activos.</div>
        <div id="port-list"></div>
    </div>

    <div class="tm-nav">
        <div class="nav-btn" onclick="MobileGame.nav('bank', this)">
            <span class="nav-icon"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f3e6.png" alt="🏦" class="wp-smiley" style="height: 1em; max-height: 1em;" /></span> BANCO
        </div>
        <div class="nav-btn active" onclick="MobileGame.nav('market', this)">
            <span class="nav-icon"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f4c8.png" alt="📈" class="wp-smiley" style="height: 1em; max-height: 1em;" /></span> MERCADO
        </div>
        <div class="nav-btn" onclick="MobileGame.nav('port', this)">
            <span class="nav-icon"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f4bc.png" alt="💼" class="wp-smiley" style="height: 1em; max-height: 1em;" /></span> CARTERA
        </div>
    </div>

    <script>
    (function(){
        const ICONS = {
            inst: `<svg viewBox="0 0 100 100"><rect width="100" height="100" rx="20" fill="#00f2ea"/><path d="M30 50 L70 50 M50 30 L50 70" stroke="black" stroke-width="12"/></svg>`,
            btc: `<svg viewBox="0 0 100 100"><circle cx="50" cy="50" r="48" fill="#f7931a"/><text x="50" y="75" font-size="70" text-anchor="middle" fill="white" font-weight="bold" font-family="Arial">₿</text></svg>`,
            eth: `<svg viewBox="0 0 100 100"><path d="M50 5 L15 65 L50 85 L85 65 Z" fill="#627eea"/></svg>`,
            aapl: `<svg viewBox="0 0 100 100"><circle cx="50" cy="55" r="40" fill="#fff"/><circle cx="70" cy="25" r="15" fill="#fff"/><circle cx="85" cy="50" r="20" fill="#14141a"/></svg>`,
            tsla: `<svg viewBox="0 0 100 100"><path d="M10 20 L90 20 L50 50 L50 90" stroke="#e82127" stroke-width="12" fill="none" stroke-linecap="round"/></svg>`,
            nvda: `<svg viewBox="0 0 100 100"><rect width="100" height="100" fill="#76b900" rx="10"/><path d="M20 50 Q50 20 80 50" stroke="white" stroke-width="8" fill="none"/></svg>`
        };

        const ASSETS = [
            {id:'inst', n:'InstaTecno', p:1200, v:0.15, l:ICONS.inst},
            {id:'btc', n:'Bitcoin', p:92000, v:0.10, l:ICONS.btc},
            {id:'eth', n:'Ethereum', p:3400, v:0.08, l:ICONS.eth},
            {id:'nvda', n:'Nvidia', p:950, v:0.05, l:ICONS.nvida},
            {id:'tsla', n:'Tesla', p:180, v:0.07, l:ICONS.tsla},
            {id:'aapl', n:'Apple', p:195, v:0.03, l:ICONS.aapl}
        ];

        const KEY = "mobile_trader_final";

        window.MobileGame = {
            cash: 2500, debt: 0, port: {}, market: [],

            init: function() {
                this.market = ASSETS.map(a => ({...a, curP:a.p, prevP:a.p}));
                this.load();
                this.upd();
                this.renderM();
                
                setInterval(()=>this.tick(), 2000);
                setInterval(()=>this.bank(), 10000);
                setInterval(()=>this.save(), 5000);
            },

            tick: function() {
                this.market.forEach(a => {
                    let chg = (Math.random()-0.5)*a.v;
                    if(Math.random()>0.98) chg*=3;
                    a.prevP = a.curP;
                    a.curP = a.curP * (1+chg);
                    if(a.curP<1) a.curP=1;
                });
                this.renderM();
                this.renderP();
                this.upd();
            },

            bank: function() {
                if(this.debt>0) {
                    this.debt = Math.floor(this.debt*1.1);
                    this.upd();
                    if(this.debt > this.cash + 5000) alert("¡AVISO! Tu deuda es peligrosa.");
                }
            },

            buy: function(id) {
                let a = this.market.find(x=>x.id===id);
                if(this.cash >= a.curP) {
                    this.cash -= a.curP;
                    if(!this.port[id]) this.port[id]=0;
                    this.port[id]++;
                    this.upd(); this.renderM();
                } else alert("Falta dinero");
            },

            sell: function(id) {
                if(this.port[id]>0) {
                    let a = this.market.find(x=>x.id===id);
                    this.cash += a.curP;
                    this.port[id]--;
                    this.upd(); this.renderM(); this.renderP();
                }
            },

            loan: function(n) { this.cash+=n; this.debt+=n; this.upd(); },
            repay: function() {
                if(this.debt<=0) return;
                if(this.cash>=this.debt) { this.cash-=this.debt; this.debt=0; }
                else { this.debt-=this.cash; this.cash=0; }
                this.upd();
            },

            renderM: function() {
                const c = document.getElementById('view-market');
                c.innerHTML = '';
                this.market.forEach(a => {
                    let chg = ((a.curP-a.prevP)/a.prevP)*100;
                    let col = chg>=0?'#00e676':'#ff1744';
                    let own = this.port[a.id]||0;
                    
                    c.innerHTML += `
                    <div class="m-card">
                        <div class="m-top">
                            <div class="m-icon">${a.l}</div>
                            <div style="color:${col}; font-weight:bold; font-size:12px;">${chg.toFixed(1)}%</div>
                        </div>
                        <div style="font-weight:bold;">${a.n}</div>
                        <div class="m-price">$${Math.floor(a.curP).toLocaleString()}</div>
                        <div class="m-acts">
                            <button class="btn btn-sell" onclick="MobileGame.sell('${a.id}')">VENDER</button>
                            <button class="btn btn-buy" onclick="MobileGame.buy('${a.id}')">COMPRAR</button>
                        </div>
                        <div style="font-size:10px; color:#666; text-align:center;">En cartera: ${own}</div>
                    </div>`;
                });
            },

            renderP: function() {
                const c = document.getElementById('port-list');
                c.innerHTML = '';
                let empty = true;
                for(let id in this.port) {
                    if(this.port[id] > 0) {
                        empty = false;
                        let a = this.market.find(x=>x.id===id);
                        let val = this.port[id]*a.curP;
                        c.innerHTML += `
                        <div class="m-card" style="flex-direction:row; align-items:center; justify-content:space-between;">
                            <div>
                                <div style="font-weight:bold;">${a.n}</div>
                                <div style="font-size:12px; color:#888;">Cant: ${this.port[id]}</div>
                            </div>
                            <div style="text-align:right;">
                                <div style="font-weight:bold; color:#fff;">$${Math.floor(val).toLocaleString()}</div>
                                <button class="btn btn-sell" style="padding:5px 10px; margin-top:5px;" onclick="MobileGame.sell('${id}')">VENDER 1</button>
                            </div>
                        </div>`;
                    }
                }
                document.getElementById('empty-msg').style.display = empty ? 'block' : 'none';
            },

            upd: function() {
                document.getElementById('m-cash').innerText = '$' + Math.floor(this.cash).toLocaleString();
                document.getElementById('m-debt').innerText = '$' + Math.floor(this.debt).toLocaleString();
            },

            nav: function(id, btn) {
                document.querySelectorAll('.tm-view').forEach(v => v.classList.remove('active'));
                document.getElementById('view-'+id).classList.add('active');
                document.querySelectorAll('.nav-btn').forEach(b => b.classList.remove('active'));
                btn.classList.add('active');
                if(id === 'port') this.renderP();
            },

            save: function() { localStorage.setItem(KEY, JSON.stringify({c:this.cash, d:this.debt, p:this.port})); },
            load: function() {
                let s = localStorage.getItem(KEY);
                if(s) try{ let d=JSON.parse(s); this.cash=d.c; this.debt=d.d; this.port=d.p||{}; }catch(e){}
            },
            reset: function() { localStorage.removeItem(KEY); location.reload(); }
        };

        MobileGame.init();
    })();
    </script>
</div>



<p></p>
<p>La entrada <a href="https://instatecno.net/minijuegos-aprendizaje/instatecno-trading-empire">INSTATECNO: TRADING EMPIRE</a> se publicó primero en <a href="https://instatecno.net">InstaTecno</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://instatecno.net/minijuegos-aprendizaje/instatecno-trading-empire/feed</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>INSTATECNO TYCOON: MARKET EDITION.</title>
		<link>https://instatecno.net/minijuegos-aprendizaje/wall-street-edition</link>
					<comments>https://instatecno.net/minijuegos-aprendizaje/wall-street-edition#respond</comments>
		
		<dc:creator><![CDATA[David Sanchez]]></dc:creator>
		<pubDate>Wed, 19 Nov 2025 19:53:47 +0000</pubDate>
				<category><![CDATA[Minijuegos]]></category>
		<guid isPermaLink="false">https://instatecno.net/?p=974</guid>

					<description><![CDATA[<p>INSTATECNO EFECTIVO $0 💼 ¡Trabaja duro! +10 $/clic BANCO (Préstamos) DEUDA TOTAL $0 PEDIR 1K PEDIR 10K PAGAR 1K PAGAR [&#8230;]</p>
<p>La entrada <a href="https://instatecno.net/minijuegos-aprendizaje/wall-street-edition">INSTATECNO TYCOON: MARKET EDITION.</a> se publicó primero en <a href="https://instatecno.net">InstaTecno</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<div id="trader-responsive-wrapper" style="width: 100%; max-width: 1200px; margin: 0 auto; font-family: 'Segoe UI', sans-serif; color: #e0e0e0; user-select: none; box-sizing: border-box;">

    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0"/>

    <style>
        /* --- CORE RESPONSIVE --- */
        #trader-responsive-wrapper * { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }
        
        :root {
            --bg-app: #0a0a10;
            --bg-card: #14141a;
            --accent: #00f2ea;
            --green: #00e676;
            --red: #ff1744;
            --border: #333;
        }

        #app-container {
            background: var(--bg-app);
            border: 1px solid var(--border);
            border-radius: 0; /* Full screen on mobile */
            height: 90vh; /* Altura adaptable */
            min-height: 600px;
            display: flex;
            flex-direction: column;
            overflow: hidden;
            position: relative;
            box-shadow: 0 0 20px rgba(0,0,0,0.5);
        }
        
        @media (min-width: 768px) {
            #app-container { border-radius: 12px; height: 800px; }
        }

        /* HEADER */
        .app-header {
            height: 60px; background: #1a1a20; border-bottom: 1px solid var(--border);
            display: flex; align-items: center; justify-content: space-between; padding: 0 15px;
            flex-shrink: 0;
        }
        .logo-zone { display: flex; align-items: center; gap: 10px; }
        .logo-img { height: 32px; border-radius: 6px; }
        
        .wallet-zone { text-align: right; }
        .wallet-val { font-size: 16px; font-weight: 900; font-family: monospace; color: var(--green); }
        .wallet-label { font-size: 9px; color: #888; letter-spacing: 1px; }

        /* MAIN CONTENT (STACKS ON MOBILE, GRID ON PC) */
        .app-body {
            display: flex; flex-grow: 1; overflow: hidden; position: relative;
        }

        /* PANELS */
        .panel-section {
            display: none; /* Hidden by default on mobile */
            flex-direction: column;
            width: 100%; height: 100%;
            overflow-y: auto; padding: 15px; background: var(--bg-app);
        }
        .panel-section.active-view { display: flex; }

        @media (min-width: 768px) {
            .app-body { display: grid; grid-template-columns: 300px 1fr; }
            .panel-section { display: flex !important; border-right: 1px solid var(--border); }
            /* En PC ocultamos el panel 'cartera' del grid principal y lo mostramos como sidebar */
            #view-portfolio { border-left: 1px solid var(--border); }
            
            /* Ocultar navegación móvil en PC */
            .mobile-nav { display: none !important; }
        }

        /* MARKET GRID */
        .market-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); gap: 10px; }
        
        .card {
            background: var(--bg-card); border: 1px solid var(--border); border-radius: 8px;
            padding: 12px; display: flex; flex-direction: column; position: relative;
        }
        
        .card-top { display: flex; justify-content: space-between; align-items: center; margin-bottom: 5px; }
        .card-icon { font-size: 20px; } /* SVG container */
        .card-trend { font-size: 10px; padding: 2px 5px; border-radius: 4px; font-weight: bold; }
        .up { background: rgba(0, 230, 118, 0.15); color: var(--green); }
        .down { background: rgba(255, 23, 68, 0.15); color: var(--red); }
        
        .card-name { font-weight: bold; font-size: 13px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
        .card-price { font-size: 16px; font-weight: 900; font-family: monospace; color: #fff; margin: 5px 0; }
        
        .card-actions { display: grid; grid-template-columns: 1fr 1fr; gap: 5px; margin-top: auto; }
        .btn-act { border: none; padding: 6px; border-radius: 4px; font-size: 10px; font-weight: bold; cursor: pointer; color: #000; }
        .b-buy { background: var(--green); }
        .b-sell { background: var(--red); color: white; }

        .owned-cnt { font-size: 9px; color: #666; text-align: center; margin-top: 5px; }

        /* WORK / BANK AREA */
        .clicker-area { 
            background: #111; border-radius: 10px; padding: 20px; text-align: center; margin-bottom: 20px; border: 1px solid var(--border);
        }
        #work-btn {
            width: 80px; height: 80px; background: radial-gradient(circle, #00f2ea 0%, #0088ff 100%);
            border-radius: 50%; border: 3px solid #fff; margin: 0 auto 10px auto;
            display: flex; align-items: center; justify-content: center; font-size: 30px;
            cursor: pointer; box-shadow: 0 0 20px rgba(0, 242, 234, 0.3); transition: 0.05s;
        }
        #work-btn:active { transform: scale(0.9); }

        /* INVENTORY LIST */
        .inv-list { display: flex; flex-direction: column; gap: 8px; }
        .inv-item { 
            display: flex; align-items: center; justify-content: space-between; 
            background: var(--bg-card); padding: 10px; border-radius: 6px; border-bottom: 2px solid #333;
        }
        
        /* MOBILE NAV BAR */
        .mobile-nav {
            height: 60px; background: #1a1a20; border-top: 1px solid var(--border);
            display: flex; flex-shrink: 0;
        }
        .nav-item {
            flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center;
            color: #666; font-size: 10px; font-weight: bold; cursor: pointer;
        }
        .nav-item span { font-size: 20px; margin-bottom: 2px; }
        .nav-item.active { color: var(--accent); background: #111; border-top: 2px solid var(--accent); }

        /* MODAL */
        .modal { position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.9); z-index: 100; display: none; align-items: center; justify-content: center; flex-direction: column;}
        .modal.active { display: flex; }

        /* SVG FIXES */
        .svg-icon { width: 100%; height: 100%; }

    </style>

    <div id="app-container">
        
        <div class="app-header">
            <div class="logo-zone">
                <img decoding="async" src="https://instatecno.net/wp-content/uploads/2025/10/Captura-de-pantalla-2025-10-15-031513.png" class="logo-img">
                <div style="font-weight:bold; font-size:14px; display:none;">INSTATECNO</div>
            </div>
            <div class="wallet-zone">
                <div class="wallet-label">EFECTIVO</div>
                <div class="wallet-val">$<span id="val-cash">0</span></div>
            </div>
        </div>

        <div class="app-body">
            
            <div id="view-bank" class="panel-section active-view">
                <div class="clicker-area">
                    <div id="work-btn" onclick="Game.work()"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f4bc.png" alt="💼" class="wp-smiley" style="height: 1em; max-height: 1em;" /></div>
                    <div style="font-size:12px; color:#aaa;">¡Trabaja duro!</div>
                    <div style="font-size:14px; color:var(--green); font-weight:bold; margin-top:5px;">+<span id="val-ppc">10</span> $/clic</div>
                </div>

                <div style="font-size:12px; font-weight:bold; color:#666; margin-bottom:10px; text-transform:uppercase;">BANCO (Préstamos)</div>
                <div style="background:#1a0505; border:1px solid var(--red); padding:15px; border-radius:8px;">
                    <div style="display:flex; justify-content:space-between; margin-bottom:10px;">
                        <span style="color:#aaa; font-size:11px;">DEUDA TOTAL</span>
                        <span style="color:var(--red); font-weight:bold;">$<span id="val-debt">0</span></span>
                    </div>
                    <div style="display:grid; grid-template-columns: 1fr 1fr; gap:10px;">
                        <button class="btn-act" style="background:#333; color:#f88;" onclick="Game.loan(1000)">PEDIR 1K</button>
                        <button class="btn-act" style="background:#333; color:#f88;" onclick="Game.loan(10000)">PEDIR 10K</button>
                        <button class="btn-act" style="background:#030; color:#8f8;" onclick="Game.repay(1000)">PAGAR 1K</button>
                        <button class="btn-act" style="background:#030; color:#8f8;" onclick="Game.repay('all')">PAGAR TODO</button>
                    </div>
                </div>
            </div>

            <div id="view-market" class="panel-section">
                <div style="font-size:12px; font-weight:bold; color:var(--accent); margin-bottom:10px;">MERCADO DE VALORES</div>
                <div class="market-grid" id="market-grid">
                    </div>
            </div>

            <div id="view-portfolio" class="panel-section">
                <div style="display:flex; justify-content:space-between; margin-bottom:10px;">
                    <div style="font-size:12px; font-weight:bold; color:#aaa;">TUS ACTIVOS</div>
                    <button class="btn-act" style="background:var(--red); color:white; width:auto; padding:5px 10px;" onclick="Game.sellAll()">VENDER TODO</button>
                </div>
                <div class="inv-list" id="inv-list">
                    <div style="text-align:center; color:#555; padding:20px;">Vacío</div>
                </div>
                <div style="margin-top:auto; text-align:center;">
                    <span onclick="Game.reset()" style="font-size:10px; color:#444; cursor:pointer; text-decoration:underline;">[BORRAR DATOS]</span>
                </div>
            </div>

        </div>

        <div class="mobile-nav">
            <div class="nav-item active" onclick="Game.nav('bank', this)">
                <span><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f3e6.png" alt="🏦" class="wp-smiley" style="height: 1em; max-height: 1em;" /></span> BANCO
            </div>
            <div class="nav-item" onclick="Game.nav('market', this)">
                <span><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f4c8.png" alt="📈" class="wp-smiley" style="height: 1em; max-height: 1em;" /></span> MERCADO
            </div>
            <div class="nav-item" onclick="Game.nav('portfolio', this)">
                <span><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f4bc.png" alt="💼" class="wp-smiley" style="height: 1em; max-height: 1em;" /></span> CARTERA
            </div>
        </div>

        <div id="modal-go" class="modal">
            <h1 style="color:var(--red); font-size:30px;">BANCARROTA</h1>
            <p style="color:#ccc; text-align:center;">El banco te ha embargado.</p>
            <button class="btn-act b-buy" style="padding:15px 30px; font-size:14px; margin-top:20px;" onclick="Game.reset()">REINICIAR</button>
        </div>

    </div>

    <script>
    (function(){
        // LOGOS SVG (Vectoriales)
        const ICONS = {
            inst: `<svg viewBox="0 0 100 100" class="svg-icon"><rect width="100" height="100" rx="20" fill="#00f2ea"/><path d="M30 50 L70 50 M50 30 L50 70" stroke="black" stroke-width="12"/></svg>`,
            btc: `<svg viewBox="0 0 100 100" class="svg-icon"><circle cx="50" cy="50" r="48" fill="#f7931a"/><text x="50" y="75" font-size="70" text-anchor="middle" fill="white" font-weight="bold" font-family="Arial">₿</text></svg>`,
            eth: `<svg viewBox="0 0 100 100" class="svg-icon"><path d="M50 5 L15 65 L50 85 L85 65 Z" fill="#627eea"/></svg>`,
            aapl: `<svg viewBox="0 0 100 100" class="svg-icon"><circle cx="50" cy="55" r="40" fill="#fff"/><circle cx="70" cy="25" r="15" fill="#fff"/><circle cx="85" cy="50" r="20" fill="#14141a"/></svg>`,
            tsla: `<svg viewBox="0 0 100 100" class="svg-icon"><path d="M10 20 L90 20 L50 50 L50 90" stroke="#e82127" stroke-width="12" fill="none" stroke-linecap="round"/></svg>`,
            nvda: `<svg viewBox="0 0 100 100" class="svg-icon"><rect width="100" height="100" fill="#76b900" rx="10"/><path d="M20 50 Q50 20 80 50" stroke="white" stroke-width="8" fill="none"/></svg>`,
            amzn: `<svg viewBox="0 0 100 100" class="svg-icon"><path d="M20 70 Q50 95 80 60" stroke="#ff9900" stroke-width="8" fill="none" stroke-linecap="round"/><text x="15" y="55" fill="white" font-weight="bold" font-size="30">amz</text></svg>`
        };

        const ASSETS = [
            { id: 'inst', n: 'InstaTecno', p: 1200, v: 0.15, l: ICONS.inst },
            { id: 'btc', n: 'Bitcoin', p: 92000, v: 0.10, l: ICONS.btc },
            { id: 'eth', n: 'Ethereum', p: 3400, v: 0.08, l: ICONS.eth },
            { id: 'nvda', n: 'Nvidia', p: 950, v: 0.05, l: ICONS.nvida },
            { id: 'tsla', n: 'Tesla', p: 180, v: 0.07, l: ICONS.tsla },
            { id: 'aapl', n: 'Apple', p: 195, v: 0.03, l: ICONS.aapl },
            { id: 'amzn', n: 'Amazon', p: 178, v: 0.04, l: ICONS.amzn }
        ];

        const SAVE_KEY = "mobile_trader_v2";

        window.Game = {
            cash: 2500,
            debt: 0,
            portfolio: {}, 
            market: [],
            
            init: function() {
                this.market = ASSETS.map(a => ({ ...a, curP: a.p, prevP: a.p }));
                this.load();
                this.updateUI();
                this.renderMarket();
                this.renderPortfolio();

                // Force mobile view reset
                if(window.innerWidth < 768) this.nav('bank', document.querySelector('.nav-item'));

                setInterval(() => this.tickMarket(), 2000);
                setInterval(() => this.tickBank(), 10000);
                setInterval(() => this.save(), 5000);
            },

            // --- ENGINE ---
            work: function() {
                let net = this.calcNet();
                let gain = 10 + Math.floor(net * 0.002); // Escala suave
                this.cash += gain;
                // Anim button
                let b = document.getElementById('work-btn');
                b.style.transform = "scale(0.9)";
                setTimeout(()=>b.style.transform="scale(1)", 50);
                this.updateUI();
            },

            tickMarket: function() {
                this.market.forEach(a => {
                    let change = (Math.random() - 0.5) * a.v;
                    if(Math.random() > 0.98) change *= 3; // Pump/Dump
                    a.prevP = a.curP;
                    a.curP = a.curP * (1 + change);
                    if(a.curP < 1) a.curP = 1;
                });
                this.renderMarket();
                this.renderPortfolio();
                this.checkBankrupt();
            },

            tickBank: function() {
                if(this.debt > 0) {
                    this.debt = Math.floor(this.debt * 1.05); // 5% Interes
                    this.updateUI();
                    this.checkBankrupt();
                }
            },

            // --- TRADE ---
            buy: function(id) {
                let a = this.market.find(x => x.id === id);
                if(this.cash >= a.curP) {
                    this.cash -= a.curP;
                    if(!this.portfolio[id]) this.portfolio[id] = 0;
                    this.portfolio[id]++;
                    this.updateUI();
                    this.renderMarket();
                    this.renderPortfolio();
                } else {
                    alert("Falta dinero");
                }
            },

            sell: function(id) {
                if(this.portfolio[id] > 0) {
                    let a = this.market.find(x => x.id === id);
                    this.cash += a.curP;
                    this.portfolio[id]--;
                    this.updateUI();
                    this.renderMarket();
                    this.renderPortfolio();
                }
            },

            sellAll: function() {
                for(let id in this.portfolio) {
                    while(this.portfolio[id] > 0) this.sell(id);
                }
            },

            // --- BANK ---
            loan: function(amt) { this.cash += amt; this.debt += amt; this.updateUI(); },
            repay: function(amt) {
                if(amt === 'all') amt = this.debt;
                if(amt > this.debt) amt = this.debt;
                if(this.cash >= amt) { this.cash -= amt; this.debt -= amt; this.updateUI(); }
            },

            checkBankrupt: function() {
                if(this.calcNet() < -500) {
                    document.getElementById('modal-go').classList.add('active');
                    localStorage.removeItem(SAVE_KEY);
                }
            },

            // --- UI ---
            renderMarket: function() {
                const g = document.getElementById('market-grid');
                g.innerHTML = '';
                this.market.forEach(a => {
                    let chg = ((a.curP - a.prevP)/a.prevP)*100;
                    let col = chg >= 0 ? 'up' : 'down';
                    let sig = chg >= 0 ? '+' : '';
                    let own = this.portfolio[a.id] || 0;

                    g.innerHTML += `
                    <div class="card">
                        <div class="card-top">
                            <div class="card-icon" style="width:24px; height:24px;">${a.l}</div>
                            <div class="card-trend ${col}">${sig}${chg.toFixed(1)}%</div>
                        </div>
                        <div class="card-name">${a.n}</div>
                        <div class="card-price">$${Math.floor(a.curP).toLocaleString()}</div>
                        <div class="card-actions">
                            <button class="btn-act b-sell" onclick="Game.sell('${a.id}')">VENDER</button>
                            <button class="btn-act b-buy" onclick="Game.buy('${a.id}')">COMPRAR</button>
                        </div>
                        <div class="owned-cnt">Tienes: ${own}</div>
                    </div>`;
                });
            },

            renderPortfolio: function() {
                const l = document.getElementById('inv-list');
                l.innerHTML = '';
                let empty = true;
                for(let id in this.portfolio) {
                    let qty = this.portfolio[id];
                    if(qty > 0) {
                        empty = false;
                        let a = this.market.find(x=>x.id===id);
                        let val = qty * a.curP;
                        l.innerHTML += `
                        <div class="inv-item">
                            <div>
                                <div style="font-weight:bold; font-size:13px;">${a.n}</div>
                                <div style="font-size:11px; color:#888;">${qty} acciones</div>
                            </div>
                            <div style="text-align:right;">
                                <div style="font-weight:bold; font-family:monospace;">$${Math.floor(val).toLocaleString()}</div>
                            </div>
                        </div>`;
                    }
                }
                if(empty) l.innerHTML = '<div style="text-align:center; color:#555; margin-top:20px;">Cartera Vacía</div>';
            },

            updateUI: function() {
                document.getElementById('val-cash').innerText = Math.floor(this.cash).toLocaleString();
                document.getElementById('val-debt').innerText = Math.floor(this.debt).toLocaleString();
                
                let net = this.calcNet();
                let ppc = 10 + Math.floor(net * 0.002);
                document.getElementById('val-ppc').innerText = ppc;
            },

            calcNet: function() {
                let assetVal = 0;
                for(let id in this.portfolio) {
                    let a = this.market.find(x=>x.id===id);
                    if(a) assetVal += this.portfolio[id] * a.curP;
                }
                return this.cash + assetVal - this.debt;
            },

            nav: function(view, btn) {
                // Mobile Nav Switcher
                document.querySelectorAll('.panel-section').forEach(p => p.classList.remove('active-view'));
                document.getElementById('view-'+view).classList.add('active-view');
                
                document.querySelectorAll('.nav-item').forEach(n => n.classList.remove('active'));
                btn.classList.add('active');
            },

            save: function() { localStorage.setItem(SAVE_KEY, JSON.stringify({cash:this.cash, debt:this.debt, port:this.portfolio})); },
            load: function() {
                let s = localStorage.getItem(SAVE_KEY);
                if(s) { try { let d=JSON.parse(s); this.cash=d.cash; this.debt=d.debt; this.portfolio=d.port||{}; } catch(e){} }
            },
            reset: function() { localStorage.removeItem(SAVE_KEY); location.reload(); }
        };

        Game.init();
    })();
    </script>
</div>
<p>La entrada <a href="https://instatecno.net/minijuegos-aprendizaje/wall-street-edition">INSTATECNO TYCOON: MARKET EDITION.</a> se publicó primero en <a href="https://instatecno.net">InstaTecno</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://instatecno.net/minijuegos-aprendizaje/wall-street-edition/feed</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Simulador de PC</title>
		<link>https://instatecno.net/minijuegos-aprendizaje/970-2048-minijuegos</link>
					<comments>https://instatecno.net/minijuegos-aprendizaje/970-2048-minijuegos#respond</comments>
		
		<dc:creator><![CDATA[David Sanchez]]></dc:creator>
		<pubDate>Wed, 19 Nov 2025 19:25:31 +0000</pubDate>
				<category><![CDATA[Minijuegos]]></category>
		<guid isPermaLink="false">https://instatecno.net/?p=970</guid>

					<description><![CDATA[<p>VM Manager Win 11 Internet ⚡ Virtual Manager Máquinas Virtuales Host: InstaTecno &#124; Online Arch Linux (x86)🟢 Running &#124; JSLinux [&#8230;]</p>
<p>La entrada <a href="https://instatecno.net/minijuegos-aprendizaje/970-2048-minijuegos">Simulador de PC</a> se publicó primero en <a href="https://instatecno.net">InstaTecno</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<div id="syno-vmm-wrapper" style="width: 100%; max-width: 100%; overflow: hidden;">

<style>
    /* ESTILOS GENERALES */
    #syno-vmm-widget {
        font-family: 'Segoe UI', system-ui, sans-serif;
        background: url('image_e4a670.png') center/cover no-repeat;
        background-color: #0d1117; 
        width: 100%;
        height: 650px; /* Un poco más de altura para maniobrar */
        position: relative;
        overflow: hidden;
        border: 1px solid #333;
        border-radius: 8px;
        color: #333;
        box-sizing: border-box;
        text-align: left;
        line-height: normal;
    }
    #syno-vmm-widget * { box-sizing: border-box; }

    /* BARRA DE TAREAS */
    #syno-vmm-widget .taskbar {
        position: absolute; bottom: 0; left: 0; width: 100%; height: 45px;
        background: rgba(15, 23, 42, 0.95);
        backdrop-filter: blur(4px);
        display: flex; align-items: center; padding: 0 10px; z-index: 100;
        border-top: 1px solid rgba(255,255,255,0.1); color: white;
    }
    #syno-vmm-widget .start-btn {
        width: 32px; height: 32px; background: #007bff;
        border-radius: 4px; display: flex; align-items: center; justify-content: center;
        cursor: pointer; margin-right: 10px; font-weight: bold; color: white; font-size: 14px; flex-shrink: 0;
    }
    #syno-vmm-widget .taskbar-text { font-size: 11px; color: #ccc; }
    #syno-vmm-widget .taskbar-clock { font-size: 11px; font-weight:bold; margin-left: auto; }

    /* ICONOS */
    #syno-vmm-widget .desktop-area { padding: 15px; display: flex; flex-direction: column; gap: 15px; flex-wrap: wrap; height: 85%; align-content: flex-start; }
    #syno-vmm-widget .d-icon {
        width: 70px; text-align: center; color: white; text-shadow: 0 1px 3px black;
        cursor: pointer; display: flex; flex-direction: column; align-items: center; font-size: 11px; font-weight: 600;
    }
    #syno-vmm-widget .d-icon img { width: 40px; height: 40px; margin-bottom: 4px; border-radius: 8px; box-shadow: 0 4px 8px rgba(0,0,0,0.5); }

    /* VENTANAS */
    #syno-vmm-widget .window {
        position: absolute; background: #1e1e1e; border-radius: 6px;
        box-shadow: 0 10px 40px rgba(0,0,0,0.7); display: none;
        flex-direction: column; overflow: hidden; border: 1px solid #444;
        max-width: 98%; max-height: 90%; min-width: 250px;
    }
    #syno-vmm-widget .title-bar {
        height: 30px; background: #2d2d2d; border-bottom: 1px solid #444;
        display: flex; align-items: center; justify-content: space-between;
        padding: 0 8px; cursor: move; user-select: none; color: #ddd; font-size: 12px; flex-shrink: 0;
    }
    #syno-vmm-widget .win-controls div { width: 10px; height: 10px; border-radius: 50%; display: inline-block; margin-left: 5px; cursor: pointer; }
    #syno-vmm-widget .close-btn { background: #ff5f56; }
    #syno-vmm-widget .max-btn { background: #27c93f; }
    #syno-vmm-widget .window-content { flex: 1; background: #000; position: relative; height: 100%; overflow: hidden; }
    
    /* iframe estándar */
    #syno-vmm-widget iframe { width: 100%; height: 100%; border: 0; background: white; display: block; }

    /* ESTILOS MENU VMM */
    #syno-vmm-widget .vmm-ui { padding: 15px; height: 100%; overflow-y: auto; background: #1e1e1e; color: white; }
    #syno-vmm-widget .vm-card {
        background: #252526; border: 1px solid #333; border-radius: 4px;
        padding: 10px; margin-bottom: 10px; cursor: pointer;
        display: flex; flex-direction: column; gap: 5px;
    }
    #syno-vmm-widget .vm-card strong { font-size: 13px; }
    #syno-vmm-widget .vm-card:hover { border-color: #007bff; background: #2a2a2a; }
    #syno-vmm-widget .btn { background: #007bff; color: white; border: none; padding: 5px 10px; border-radius: 3px; cursor: pointer; font-size: 10px; font-weight: bold; width: 100%; margin-top:5px; }
</style>

<div id="syno-vmm-widget">
    
    <div class="desktop-area">
        <div class="d-icon" onclick="vmmWidget.openWindow('vmm')">
            <img decoding="async" src="https://cdn-icons-png.flaticon.com/512/2620/2620577.png" alt="VMM">
            <span>VM Manager</span>
        </div>
        <div class="d-icon" onclick="vmmWidget.openWindow('win11')">
            <img decoding="async" src="https://cdn-icons-png.flaticon.com/512/732/732221.png" alt="Win11">
            <span>Win 11</span>
        </div>
        <div class="d-icon" onclick="vmmWidget.openWindow('browser')">
            <img decoding="async" src="https://cdn-icons-png.flaticon.com/512/5968/5968815.png" alt="Web">
            <span>Internet</span>
        </div>
    </div>

    <div id="win-vmm" class="window" style="top: 10%; left: 5%; width: 90%; height: 75%; z-index: 20;">
        <div class="title-bar" onmousedown="vmmWidget.startDrag(event, 'win-vmm')">
            <span><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/26a1.png" alt="⚡" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Virtual Manager</span>
            <div class="win-controls"><div class="close-btn" onclick="vmmWidget.closeWindow('win-vmm')"></div></div>
        </div>
        <div class="window-content vmm-ui">
            <h3 style="margin-top:0; margin-bottom: 5px; color: #007bff; font-size: 16px;">Máquinas Virtuales</h3>
            <p style="color:#888; font-size:11px; margin-top:0;">Host: InstaTecno | Online</p>
            <hr style="border-color:#333; margin: 10px 0;">

            <div class="vm-card" onclick="vmmWidget.openWindow('linux')">
                <div><strong>Arch Linux (x86)</strong><span style="font-size:10px; color:#aaa; display:block;"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f7e2.png" alt="🟢" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Running | JSLinux</span></div>
                <button class="btn">TERMINAL</button>
            </div>

            <div class="vm-card" onclick="vmmWidget.openWindow('win11')">
                <div><strong>Windows 11 Pro</strong><span style="font-size:10px; color:#aaa; display:block;"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f7e2.png" alt="🟢" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Running | ReactOS</span></div>
                <button class="btn">PANTALLA</button>
            </div>
            
            <div class="vm-card" onclick="vmmWidget.openWindow('win98')">
                <div><strong>Windows 98 SE</strong><span style="font-size:10px; color:#aaa; display:block;"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f7e2.png" alt="🟢" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Running | v86 Emu</span></div>
                <button class="btn">ABRIR</button>
            </div>
        </div>
    </div>

    <div id="win-linux" class="window" style="top: 5%; left: 5%; width: 90%; height: 75%; z-index: 30;">
        <div class="title-bar" onmousedown="vmmWidget.startDrag(event, 'win-linux')">
            <span><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f427.png" alt="🐧" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Arch Linux</span>
            <div class="win-controls">
                <div class="max-btn" onclick="vmmWidget.maximize('win-linux')"></div>
                <div class="close-btn" onclick="vmmWidget.closeWindow('win-linux')"></div>
            </div>
        </div>
        <div class="window-content">
            <iframe src="https://bellard.org/jslinux/vm.html?url=alpine-x86.cfg&#038;mem=192"></iframe>
        </div>
    </div>

    <div id="win-win11" class="window" style="top: 2%; left: 2%; width: 96%; height: 85%; z-index: 31;">
        <div class="title-bar" onmousedown="vmmWidget.startDrag(event, 'win-win11')">
            <span><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1fa9f.png" alt="🪟" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Windows 11</span>
            <div class="win-controls">
                <div class="max-btn" onclick="vmmWidget.maximize('win-win11')"></div>
                <div class="close-btn" onclick="vmmWidget.closeWindow('win-win11')"></div>
            </div>
        </div>
        <div class="window-content" style="overflow: hidden;">
            <iframe src="https://win11.blueedge.me/" style="width: 133%; height: 133%; transform: scale(0.75); transform-origin: 0 0; border: none;"></iframe>
        </div>
    </div>

    <div id="win-win98" class="window" style="top: 15%; left: 10%; width: 80%; height: 65%; z-index: 32;">
        <div class="title-bar" onmousedown="vmmWidget.startDrag(event, 'win-win98')">
            <span><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f4be.png" alt="💾" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Windows 98 SE</span>
            <div class="win-controls">
                <div class="max-btn" onclick="vmmWidget.maximize('win-win98')"></div>
                <div class="close-btn" onclick="vmmWidget.closeWindow('win-win98')"></div>
            </div>
        </div>
        <div class="window-content">
            <iframe src="https://98.js.org/"></iframe>
        </div>
    </div>

    <div id="win-browser" class="window" style="top: 15%; left: 10%; width: 80%; height: 60%; z-index: 25;">
        <div class="title-bar" onmousedown="vmmWidget.startDrag(event, 'win-browser')">
            <span><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f310.png" alt="🌐" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Web</span>
            <div class="win-controls"><div class="close-btn" onclick="vmmWidget.closeWindow('win-browser')"></div></div>
        </div>
        <div class="window-content">
            <iframe src="https://www.bing.com/search?q=instatecno"></iframe>
        </div>
    </div>

    <div class="taskbar">
        <div class="start-btn" onclick="alert('InstaTecno OS')">IT</div>
        <span class="taskbar-text">InstaTecno OS v4</span>
        <span class="taskbar-clock">12:00</span>
    </div>
</div>

<script>
    var vmmWidget = {
        openWindow: function(id) {
            var winId = id.startsWith('win-') ? id : 'win-' + id;
            var win = document.getElementById(winId);
            if(win) {
                win.style.display = 'flex';
                this.bringToFront(win);
            }
        },
        closeWindow: function(id) {
            document.getElementById(id).style.display = 'none';
        },
        bringToFront: function(el) {
            var wins = document.querySelectorAll('#syno-vmm-widget .window');
            wins.forEach(function(w) { w.style.zIndex = 20; });
            el.style.zIndex = 50;
        },
        maximize: function(id) {
            var win = document.getElementById(id);
            if(win.style.width === '100%') {
                win.style.width = '90%'; win.style.height = '75%'; 
                win.style.top = '5%'; win.style.left = '5%';
            } else {
                win.style.width = '100%'; win.style.height = 'calc(100% - 45px)'; 
                win.style.top = '0'; win.style.left = '0';
            }
        },
        startDrag: function(e, id) {
            var win = document.getElementById(id);
            this.bringToFront(win);
            var widget = document.getElementById('syno-vmm-widget');
            var widgetRect = widget.getBoundingClientRect();
            var offsetX = e.clientX - win.getBoundingClientRect().left;
            var offsetY = e.clientY - win.getBoundingClientRect().top;

            function moveAt(pageX, pageY) {
                var newLeft = pageX - widgetRect.left - offsetX;
                var newTop = pageY - widgetRect.top - offsetY;
                var maxLeft = widgetRect.width - win.offsetWidth;
                
                if(newLeft < 0) newLeft = 0;
                if(newLeft > maxLeft) newLeft = maxLeft; 
                if(newTop < 0) newTop = 0;
                if(newTop > widgetRect.height - 30) newTop = widgetRect.height - 30;
                
                win.style.left = newLeft + 'px';
                win.style.top = newTop + 'px';
            }
            function onMouseMove(event) { moveAt(event.clientX, event.clientY); }
            document.addEventListener('mousemove', onMouseMove);
            document.onmouseup = function() {
                document.removeEventListener('mousemove', onMouseMove);
                document.onmouseup = null;
            };
        }
    };
</script>
</div>



<p></p>
<p>La entrada <a href="https://instatecno.net/minijuegos-aprendizaje/970-2048-minijuegos">Simulador de PC</a> se publicó primero en <a href="https://instatecno.net">InstaTecno</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://instatecno.net/minijuegos-aprendizaje/970-2048-minijuegos/feed</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>RUNNER INFINITO</title>
		<link>https://instatecno.net/minijuegos-aprendizaje/runner-infinito</link>
					<comments>https://instatecno.net/minijuegos-aprendizaje/runner-infinito#respond</comments>
		
		<dc:creator><![CDATA[David Sanchez]]></dc:creator>
		<pubDate>Wed, 19 Nov 2025 18:35:40 +0000</pubDate>
				<category><![CDATA[Minijuegos]]></category>
		<guid isPermaLink="false">https://instatecno.net/?p=967</guid>

					<description><![CDATA[<p>SCORE: 0 DATA RUNNER Corre. Salta. No te detengas. [ESPACIO] o [CLICK] para Saltar CORRER CRASHED Has chocado contra el [&#8230;]</p>
<p>La entrada <a href="https://instatecno.net/minijuegos-aprendizaje/runner-infinito">RUNNER INFINITO</a> se publicó primero en <a href="https://instatecno.net">InstaTecno</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<div id="runner-wrapper" style="width: 100%; max-width: 900px; margin: 0 auto; font-family: 'Verdana', sans-serif; user-select: none;">

    <style>
        #runner-container {
            position: relative;
            width: 100%;
            height: 500px;
            background: #121212;
            border: 4px solid #00d2ff;
            border-radius: 8px;
            overflow: hidden;
            box-shadow: 0 0 20px rgba(0, 210, 255, 0.3);
        }

        canvas { display: block; width: 100%; height: 100%; }

        /* UI ELEMENTS */
        .ui-layer {
            position: absolute; top: 0; left: 0; width: 100%; height: 100%;
            display: flex; flex-direction: column; justify-content: center; align-items: center;
            background: rgba(10, 10, 15, 0.85);
            z-index: 10; color: white; text-align: center;
            transition: opacity 0.2s;
        }
        .hidden { opacity: 0; pointer-events: none; }

        /* BOTONES */
        .run-btn {
            background: linear-gradient(45deg, #00d2ff, #3a7bd5);
            border: none; padding: 15px 50px; color: white; font-weight: bold; font-size: 20px;
            border-radius: 30px; cursor: pointer; margin-top: 20px;
            box-shadow: 0 5px 15px rgba(0, 210, 255, 0.4); transition: transform 0.1s;
        }
        .run-btn:hover { transform: scale(1.05); }
        .run-btn:active { transform: scale(0.95); }

        /* HUD */
        #score-hud {
            position: absolute; top: 20px; right: 20px;
            font-size: 24px; font-weight: bold; color: #00d2ff;
            text-shadow: 2px 2px 0 #000; z-index: 5;
        }
        
        /* ESTÉTICA */
        .neon-text {
            color: #fff; text-shadow: 0 0 10px #00d2ff, 0 0 20px #00d2ff;
            font-size: 40px; margin: 0; font-style: italic; text-transform: uppercase;
        }
    </style>

    <div id="runner-container">
        
        <div id="score-hud">SCORE: <span id="val-score">0</span></div>

        <div id="scr-start" class="ui-layer">
            <img decoding="async" src="https://instatecno.net/wp-content/uploads/2025/10/Captura-de-pantalla-2025-10-15-031513.png" style="max-width: 200px; margin-bottom: 20px; filter: drop-shadow(0 0 5px white);">
            <h1 class="neon-text">DATA RUNNER</h1>
            <p style="color:#ccc; font-size: 1.1em;">Corre. Salta. No te detengas.</p>
            <p style="font-size: 0.9em; margin-top:10px;">[ESPACIO] o [CLICK] para Saltar</p>
            <button class="run-btn" onclick="Runner.start()">CORRER</button>
        </div>

        <div id="scr-over" class="ui-layer hidden">
            <h1 class="neon-text" style="color:#ff4444; text-shadow: 0 0 20px red;">CRASHED</h1>
            <p>Has chocado contra el Firewall.</p>
            <h2>Score Final: <span id="final-score">0</span></h2>
            <button class="run-btn" onclick="Runner.start()">REINTENTAR</button>
        </div>

        <canvas id="run-canvas"></canvas>
    </div>

    <script>
        window.Runner = (function() {
            const canvas = document.getElementById('run-canvas');
            const ctx = canvas.getContext('2d');
            let W, H;

            // Configuración
            const GRAVITY = 0.6;
            const JUMP_FORCE = -12;
            const GROUND_H = 50;
            
            // Estado
            let running = false;
            let frame = 0;
            let score = 0;
            let speed = 5;

            // Entidades
            let player = {
                x: 50, y: 0, w: 40, h: 40, vy: 0, grounded: false, color: '#00d2ff',
                draw: function(ctx, f) {
                    // Dibujar Robot simple
                    ctx.fillStyle = this.color;
                    // Cuerpo
                    ctx.fillRect(this.x, this.y, this.w, this.h);
                    // Ojo
                    ctx.fillStyle = 'white';
                    ctx.fillRect(this.x + 25, this.y + 10, 10, 5);
                    // Efecto correr (piernas simples)
                    ctx.fillStyle = '#333';
                    if(this.grounded) {
                        let legOffset = Math.sin(f * 0.5) * 10;
                        ctx.fillRect(this.x + 10 + legOffset, this.y + this.h, 8, 10); // Pierna 1
                        ctx.fillRect(this.x + 20 - legOffset, this.y + this.h, 8, 10); // Pierna 2
                    }
                }
            };

            let obstacles = [];
            let particles = [];
            let bgStars = [];

            // --- CORE ---

            function resize() {
                const cont = document.getElementById('runner-container');
                W = canvas.width = cont.clientWidth;
                H = canvas.height = cont.clientHeight;
                player.y = H - GROUND_H - player.h; // Reset pos
                
                // Generar estrellas fondo
                bgStars = [];
                for(let i=0; i<50; i++){
                    bgStars.push({x: Math.random()*W, y: Math.random()*(H-GROUND_H), s: Math.random()*2, v: Math.random()*0.5 + 0.1});
                }
            }

            function start() {
                document.getElementById('scr-start').classList.add('hidden');
                document.getElementById('scr-over').classList.add('hidden');
                resize();
                
                running = true;
                score = 0;
                frame = 0;
                speed = 6; // Velocidad inicial
                
                player.y = H - GROUND_H - player.h;
                player.vy = 0;
                obstacles = [];
                particles = [];

                loop();
            }

            function loop() {
                if(!running) return;
                update();
                draw();
                frame++;
                requestAnimationFrame(loop);
            }

            function update() {
                // Física Jugador
                player.vy += GRAVITY;
                player.y += player.vy;

                // Suelo
                let groundY = H - GROUND_H - player.h;
                if (player.y >= groundY) {
                    player.y = groundY;
                    player.vy = 0;
                    player.grounded = true;
                } else {
                    player.grounded = false;
                }

                // Aumentar velocidad progresiva
                if(frame % 600 === 0) speed += 0.5;
                score = Math.floor(frame / 10);
                document.getElementById('val-score').innerText = score;

                // Obstáculos (Spawn)
                if (frame % 120 === 0 || (Math.random() < 0.01 &#038;&#038; frame > 200 && obstacles.length === 0)) {
                    let type = Math.random();
                    let obsH = 40 + Math.random() * 40;
                    let obsW = 30;
                    
                    // Tipo 1: Bloque suelo
                    // Tipo 2: Bloque aéreo (pájaro/drone)
                    let isFlying = type > 0.7; 
                    let obsY = isFlying ? H - GROUND_H - 90 - Math.random()*40 : H - GROUND_H - obsH;

                    obstacles.push({
                        x: W, y: obsY, w: obsW, h: isFlying?30:obsH, 
                        flying: isFlying, passed: false
                    });
                }

                // Mover Obstáculos
                for (let i = obstacles.length - 1; i >= 0; i--) {
                    let o = obstacles[i];
                    o.x -= speed;

                    // Colisión Simple (AABB)
                    if (player.x < o.x + o.w &#038;&#038;
                        player.x + player.w > o.x &&
                        player.y < o.y + o.h &#038;&#038;
                        player.y + player.h > o.y) {
                        gameOver();
                    }

                    if (o.x + o.w < 0) obstacles.splice(i, 1);
                }

                // Partículas (Estela)
                if(player.grounded &#038;&#038; frame%5===0) {
                    particles.push({x: player.x, y: player.y+player.h, vx: -speed, vy: -Math.random()*2, l: 1});
                }
                particles.forEach((p, i) => {
                    p.x += p.vx; p.y += p.vy; p.l -= 0.05;
                    if(p.l <= 0) particles.splice(i, 1);
                });

                // Fondo Parallax
                bgStars.forEach(s => {
                    s.x -= s.v * (speed * 0.1);
                    if(s.x < 0) s.x = W;
                });
            }

            function jump() {
                if (player.grounded) {
                    player.vy = JUMP_FORCE;
                    player.grounded = false;
                    
                    // Partículas salto
                    for(let i=0; i<5; i++){
                        particles.push({x: player.x+player.w/2, y: player.y+player.h, vx: (Math.random()-0.5)*5, vy: 1, l: 1});
                    }
                }
            }

            function gameOver() {
                running = false;
                document.getElementById('scr-over').classList.remove('hidden');
                document.getElementById('final-score').innerText = score;
            }

            function draw() {
                // Fondo
                ctx.fillStyle = '#111';
                ctx.fillRect(0, 0, W, H);

                // Estrellas (Fondo lejano)
                ctx.fillStyle = '#555';
                bgStars.forEach(s => {
                    ctx.fillRect(s.x, s.y, s.s, s.s);
                });

                // Suelo (Grid effect)
                ctx.fillStyle = '#050505';
                ctx.fillRect(0, H - GROUND_H, W, GROUND_H);
                ctx.strokeStyle = '#00d2ff';
                ctx.beginPath();
                ctx.moveTo(0, H - GROUND_H);
                ctx.lineTo(W, H - GROUND_H);
                ctx.stroke();
                
                // Lineas suelo movimiento
                let offset = (frame * speed) % 50;
                for(let i=0; i<W+50; i+=50) {
                    ctx.beginPath();
                    ctx.moveTo(i - offset, H - GROUND_H);
                    ctx.lineTo(i - offset - 20, H);
                    ctx.strokeStyle = 'rgba(0, 210, 255, 0.3)';
                    ctx.stroke();
                }

                // Jugador
                player.draw(ctx, frame);

                // Obstáculos
                ctx.fillStyle = '#ff4444';
                obstacles.forEach(o => {
                    ctx.fillRect(o.x, o.y, o.w, o.h);
                    // Borde neón
                    ctx.strokeStyle = '#ff0000';
                    ctx.strokeRect(o.x, o.y, o.w, o.h);
                });

                // Partículas
                particles.forEach(p => {
                    ctx.globalAlpha = p.l;
                    ctx.fillStyle = '#fff';
                    ctx.fillRect(p.x, p.y, 3, 3);
                });
                ctx.globalAlpha = 1;
            }

            // Inputs
            window.addEventListener('keydown', e => {
                if (e.code === 'Space' || e.code === 'ArrowUp') {
                    e.preventDefault();
                    if(!running && document.getElementById('scr-start').classList.contains('hidden') === false) start();
                    else jump();
                }
            });
            canvas.addEventListener('mousedown', jump);
            canvas.addEventListener('touchstart', (e) => { e.preventDefault(); jump(); });

            // Init
            setTimeout(resize, 100);

            return { start };
        })();
    </script>
</div>
<p>La entrada <a href="https://instatecno.net/minijuegos-aprendizaje/runner-infinito">RUNNER INFINITO</a> se publicó primero en <a href="https://instatecno.net">InstaTecno</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://instatecno.net/minijuegos-aprendizaje/runner-infinito/feed</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>INSTATECNO: SERVER DEFENSE</title>
		<link>https://instatecno.net/minijuegos-aprendizaje/minijuego-server</link>
					<comments>https://instatecno.net/minijuegos-aprendizaje/minijuego-server#respond</comments>
		
		<dc:creator><![CDATA[David Sanchez]]></dc:creator>
		<pubDate>Wed, 19 Nov 2025 18:31:56 +0000</pubDate>
				<category><![CDATA[Minijuegos]]></category>
		<guid isPermaLink="false">https://instatecno.net/?p=963</guid>

					<description><![CDATA[<p>VIDAS: 20 OLEADA: 1 DATOS ($): 100 Básico 50$ Sniper 120$ Rápido 200$ SERVER DEFENSE Coloca defensas. Protege el Servidor. [&#8230;]</p>
<p>La entrada <a href="https://instatecno.net/minijuegos-aprendizaje/minijuego-server">INSTATECNO: SERVER DEFENSE</a> se publicó primero en <a href="https://instatecno.net">InstaTecno</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<div id="td-wrapper" style="width: 100%; max-width: 900px; margin: 0 auto; font-family: 'Segoe UI', sans-serif; user-select: none;">

    <style>
        #td-container {
            position: relative;
            width: 100%;
            height: 600px;
            background: #222;
            border: 4px solid #444;
            border-radius: 8px;
            overflow: hidden;
            box-shadow: 0 10px 30px rgba(0,0,0,0.5);
        }

        canvas { display: block; width: 100%; height: 100%; background: #1a1a1a; }

        /* UI SUPERIOR */
        #td-top-bar {
            position: absolute; top: 0; left: 0; width: 100%; height: 50px;
            background: rgba(0,0,0,0.8); border-bottom: 1px solid #555;
            display: flex; align-items: center; justify-content: space-between;
            padding: 0 20px; box-sizing: border-box; color: white; z-index: 10;
        }
        .td-stat span { color: #00ffaa; font-weight: bold; font-size: 1.2em; }

        /* BARRA DE TORRES (ABAJO) */
        #td-bot-bar {
            position: absolute; bottom: 20px; left: 50%; transform: translateX(-50%);
            background: rgba(0,0,0,0.8); padding: 10px; border-radius: 10px;
            display: flex; gap: 10px; border: 1px solid #555; z-index: 10;
        }

        .tower-btn {
            width: 60px; height: 60px; border: 2px solid #555; border-radius: 5px;
            background: #333; cursor: pointer; position: relative; transition: 0.2s;
            display: flex; flex-direction: column; align-items: center; justify-content: center;
        }
        .tower-btn:hover { border-color: white; background: #444; }
        .tower-btn.selected { border-color: #00ffaa; box-shadow: 0 0 15px #00ffaa; }
        
        .t-icon { width: 20px; height: 20px; border-radius: 50%; margin-bottom: 5px; }
        .t-price { color: #ffd700; font-size: 12px; font-weight: bold; }
        .t-name { color: #ccc; font-size: 9px; text-transform: uppercase; }

        /* PANTALLAS */
        .td-screen {
            position: absolute; top: 0; left: 0; width: 100%; height: 100%;
            background: rgba(0,0,0,0.9); display: flex; flex-direction: column;
            justify-content: center; align-items: center; z-index: 20; color: white;
            transition: opacity 0.3s;
        }
        .hidden { opacity: 0; pointer-events: none; }
        
        .td-btn {
            padding: 15px 40px; background: #00ffaa; color: #000; border: none;
            font-weight: bold; font-size: 1.2em; cursor: pointer; border-radius: 5px;
            margin-top: 20px; text-transform: uppercase;
        }
        .td-btn:hover { background: white; }

    </style>

    <div id="td-container">
        
        <div id="td-top-bar">
            <div class="td-stat">VIDAS: <span id="val-lives" style="color:#ff4444">20</span></div>
            <div class="td-stat">OLEADA: <span id="val-wave" style="color:#fff">1</span></div>
            <div class="td-stat">DATOS ($): <span id="val-money">100</span></div>
        </div>

        <canvas id="td-canvas"></canvas>

        <div id="td-bot-bar">
            <div class="tower-btn" onclick="Game.selectTower(0)">
                <div class="t-icon" style="background:#00ffaa;"></div>
                <span class="t-name">Básico</span>
                <span class="t-price">50$</span>
            </div>
            <div class="tower-btn" onclick="Game.selectTower(1)">
                <div class="t-icon" style="background:#00ccff;"></div>
                <span class="t-name">Sniper</span>
                <span class="t-price">120$</span>
            </div>
            <div class="tower-btn" onclick="Game.selectTower(2)">
                <div class="t-icon" style="background:#ffaa00;"></div>
                <span class="t-name">Rápido</span>
                <span class="t-price">200$</span>
            </div>
        </div>

        <div id="scr-start" class="td-screen">
            <img decoding="async" src="https://instatecno.net/wp-content/uploads/2025/10/Captura-de-pantalla-2025-10-15-031513.png" style="max-width: 200px; margin-bottom: 20px;">
            <h1 style="margin:0; color:#00ffaa;">SERVER DEFENSE</h1>
            <p>Coloca defensas. Protege el Servidor.</p>
            <button class="td-btn" onclick="Game.start()">INICIAR</button>
        </div>

        <div id="scr-over" class="td-screen hidden">
            <h1 style="color:#ff4444;">SISTEMA CORRUPTO</h1>
            <p>Los virus han tomado el control.</p>
            <p>Oleada alcanzada: <span id="final-wave">0</span></p>
            <button class="td-btn" onclick="Game.start()">REINTENTAR</button>
        </div>

    </div>

    <script>
        window.Game = (function() {
            const canvas = document.getElementById('td-canvas');
            const ctx = canvas.getContext('2d');
            
            // Configuración del Juego
            const TILE_SIZE = 40;
            let width, height, cols, rows;
            
            // Mapa (0=Suelo, 1=Camino)
            // Un camino simple dibujado en una grid imaginaria
            const MAP_LAYOUT = [
                [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
                [1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
                [0,0,0,1,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0],
                [0,0,0,1,0,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0],
                [0,0,0,1,1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0],
                [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0],
                [0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,1,0,0,0,0],
                [0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,1,1,1,1,1], // Salida a la derecha
                [0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0],
                [0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0],
                [0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0],
                [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
            ];

            // Waypoints extraídos del mapa (coordenadas X, Y del centro de cada tile de camino)
            // Simplificado para este ejemplo: puntos clave del camino
            const WAYPOINTS = [
                {c:0,r:1}, {c:3,r:1}, {c:3,r:4}, {c:7,r:4}, {c:7,r:2}, {c:12,r:2}, {c:12,r:4}, 
                {c:15,r:4}, {c:15,r:7}, {c:19,r:7} // Final
            ];

            // Tipos de Torres
            const TOWERS_DB = [
                { name: 'Básico', cost: 50, range: 100, dmg: 20, rate: 30, color: '#00ffaa' },
                { name: 'Sniper', cost: 120, range: 200, dmg: 100, rate: 90, color: '#00ccff' },
                { name: 'Rápido', cost: 200, range: 80, dmg: 10, rate: 10, color: '#ffaa00' }
            ];

            // Estado
            let st = { running: false, money: 100, lives: 20, wave: 1, frame: 0 };
            let enemies = [];
            let towers = [];
            let projectiles = [];
            let particles = [];
            
            let selectedTowerIdx = -1;
            let mouse = { x: 0, y: 0, col: 0, row: 0 };

            // --- FUNCIONES CORE ---

            function resize() {
                const container = document.getElementById('td-container');
                canvas.width = container.clientWidth;
                canvas.height = container.clientHeight;
                width = canvas.width;
                height = canvas.height;
                cols = 20; rows = 12; // Basado en MAP_LAYOUT
            }

            function start() {
                document.getElementById('scr-start').classList.add('hidden');
                document.getElementById('scr-over').classList.add('hidden');
                resize();
                
                st = { running: true, money: 150, lives: 20, wave: 1, frame: 0 };
                enemies = [];
                towers = [];
                projectiles = [];
                particles = [];
                updateUI();
                loop();
            }

            function loop() {
                if (!st.running) return;
                update();
                draw();
                st.frame++;
                requestAnimationFrame(loop);
            }

            // --- UPDATE ---

            function update() {
                // Spawner (Oleadas)
                let spawnRate = Math.max(20, 100 - st.wave * 5);
                if (st.frame % spawnRate === 0) {
                    spawnEnemy();
                }
                
                // Incrementar dificultad
                if (st.frame % 600 === 0) st.wave++;

                // Actualizar Enemigos
                for (let i = enemies.length - 1; i >= 0; i--) {
                    let e = enemies[i];
                    moveEnemy(e);
                    if (e.finished) {
                        st.lives--;
                        enemies.splice(i, 1);
                        updateUI();
                        if (st.lives <= 0) gameOver();
                    } else if (e.hp <= 0) {
                        st.money += e.value;
                        createParticles(e.x, e.y, '#ff0000');
                        enemies.splice(i, 1);
                        updateUI();
                    }
                }

                // Torres Disparando
                towers.forEach(t => {
                    if (t.cd > 0) t.cd--;
                    else {
                        // Buscar objetivo
                        let target = enemies.find(e => Math.hypot(e.x - t.x, e.y - t.y) < t.range);
                        if (target) {
                            shoot(t, target);
                            t.cd = t.rate;
                        }
                    }
                });

                // Proyectiles
                for (let i = projectiles.length - 1; i >= 0; i--) {
                    let p = projectiles[i];
                    let dx = p.target.x - p.x;
                    let dy = p.target.y - p.y;
                    let dist = Math.hypot(dx, dy);
                    
                    if (dist < p.speed || !enemies.includes(p.target)) { // Impacto
                        if(enemies.includes(p.target)) p.target.hp -= p.dmg;
                        projectiles.splice(i, 1);
                    } else {
                        let angle = Math.atan2(dy, dx);
                        p.x += Math.cos(angle) * p.speed;
                        p.y += Math.sin(angle) * p.speed;
                    }
                }

                // Partículas
                particles.forEach(p => { p.x += p.vx; p.y += p.vy; p.life -= 0.05; });
                particles = particles.filter(p => p.life > 0);
            }

            function spawnEnemy() {
                // Encontrar coordenadas reales del tile de inicio (0,1)
                let startTile = {c:0, r:1}; 
                enemies.push({
                    x: 0, y: startTile.r * height/rows + (height/rows)/2,
                    wpIndex: 1, // Ir al siguiente waypoint
                    hp: 20 + (st.wave * 10),
                    speed: 1 + (st.wave * 0.1),
                    value: 5 + st.wave,
                    maxHp: 20 + (st.wave * 10)
                });
            }

            function moveEnemy(e) {
                // Movimiento simple hacia el centro del siguiente waypoint
                // Convertir Grid a Pixeles
                let targetC = WAYPOINTS[e.wpIndex].c;
                let targetR = WAYPOINTS[e.wpIndex].r;
                let targetX = targetC * (width/cols) + (width/cols)/2;
                let targetY = targetR * (height/rows) + (height/rows)/2;

                let dx = targetX - e.x;
                let dy = targetY - e.y;
                let dist = Math.hypot(dx, dy);

                if (dist < e.speed) {
                    // Llegó al waypoint
                    e.wpIndex++;
                    if (e.wpIndex >= WAYPOINTS.length) {
                        e.finished = true;
                    }
                } else {
                    let angle = Math.atan2(dy, dx);
                    e.x += Math.cos(angle) * e.speed;
                    e.y += Math.sin(angle) * e.speed;
                }
            }

            function shoot(tower, enemy) {
                projectiles.push({
                    x: tower.x, y: tower.y,
                    target: enemy,
                    dmg: tower.dmg,
                    speed: 10,
                    color: tower.color
                });
            }

            // --- INPUT & BUILD ---

            canvas.addEventListener('mousemove', e => {
                let rect = canvas.getBoundingClientRect();
                mouse.x = e.clientX - rect.left;
                mouse.y = e.clientY - rect.top;
                mouse.col = Math.floor(mouse.x / (width/cols));
                mouse.row = Math.floor(mouse.y / (height/rows));
            });

            canvas.addEventListener('click', () => {
                if (selectedTowerIdx === -1) return;
                
                // Validar construcción
                if (mouse.col < 0 || mouse.col >= cols || mouse.row < 0 || mouse.row >= rows) return;
                
                // No construir en camino
                if (MAP_LAYOUT[mouse.row][mouse.col] === 1) return;
                
                // No construir encima de otra
                let existing = towers.find(t => t.c === mouse.col && t.r === mouse.row);
                if (existing) return;

                let type = TOWERS_DB[selectedTowerIdx];
                if (st.money >= type.cost) {
                    st.money -= type.cost;
                    towers.push({
                        c: mouse.col, r: mouse.row,
                        x: mouse.col * (width/cols) + (width/cols)/2,
                        y: mouse.row * (height/rows) + (height/rows)/2,
                        ...type,
                        cd: 0
                    });
                    createParticles(mouse.x, mouse.y, '#fff');
                    updateUI();
                    selectedTowerIdx = -1; // Deseleccionar
                    renderBtns();
                }
            });

            function selectTower(idx) {
                selectedTowerIdx = idx;
                renderBtns();
            }

            function renderBtns() {
                document.querySelectorAll('.tower-btn').forEach((btn, i) => {
                    if (i === selectedTowerIdx) btn.classList.add('selected');
                    else btn.classList.remove('selected');
                });
            }

            function createParticles(x, y, color) {
                for(let i=0; i<5; i++) {
                    particles.push({
                        x:x, y:y, vx: (Math.random()-0.5)*5, vy:(Math.random()-0.5)*5,
                        life:1, color:color
                    });
                }
            }

            // --- DRAW ---

            function draw() {
                // Limpiar
                ctx.fillStyle = '#111';
                ctx.fillRect(0, 0, width, height);

                let tw = width / cols;
                let th = height / rows;

                // Dibujar Mapa (Camino)
                ctx.fillStyle = '#222';
                for (let r=0; r<rows; r++) {
                    for (let c=0; c<cols; c++) {
                        if (MAP_LAYOUT[r][c] === 1) {
                            ctx.fillRect(c*tw, r*th, tw, th);
                        }
                        // Grid sutil
                        ctx.strokeStyle = '#333';
                        ctx.strokeRect(c*tw, r*th, tw, th);
                    }
                }

                // Cursor de Construcción
                if (selectedTowerIdx !== -1) {
                    let tInfo = TOWERS_DB[selectedTowerIdx];
                    // Rango
                    ctx.beginPath();
                    ctx.arc(mouse.col*tw + tw/2, mouse.row*th + th/2, tInfo.range, 0, Math.PI*2);
                    ctx.fillStyle = 'rgba(255, 255, 255, 0.1)';
                    ctx.fill();
                    ctx.strokeStyle = 'rgba(255,255,255,0.3)';
                    ctx.stroke();
                    
                    // Cuadro verde/rojo
                    let valid = MAP_LAYOUT[mouse.row] &#038;&#038; MAP_LAYOUT[mouse.row][mouse.col] === 0 &#038;&#038; !towers.find(t=>t.c===mouse.col && t.r===mouse.row);
                    ctx.fillStyle = valid ? 'rgba(0, 255, 0, 0.3)' : 'rgba(255, 0, 0, 0.3)';
                    ctx.fillRect(mouse.col*tw, mouse.row*th, tw, th);
                }

                // Torres
                towers.forEach(t => {
                    ctx.fillStyle = t.color;
                    ctx.beginPath();
                    ctx.arc(t.x, t.y, 15, 0, Math.PI*2);
                    ctx.fill();
                    // Base
                    ctx.strokeStyle = '#fff';
                    ctx.lineWidth = 2;
                    ctx.stroke();
                });

                // Enemigos
                enemies.forEach(e => {
                    ctx.fillStyle = '#ff4444';
                    ctx.beginPath();
                    ctx.arc(e.x, e.y, 10, 0, Math.PI*2);
                    ctx.fill();
                    
                    // Barra Vida
                    let hpPct = e.hp / e.maxHp;
                    ctx.fillStyle = 'red';
                    ctx.fillRect(e.x-10, e.y-20, 20, 4);
                    ctx.fillStyle = '#0f0';
                    ctx.fillRect(e.x-10, e.y-20, 20*hpPct, 4);
                });

                // Proyectiles
                projectiles.forEach(p => {
                    ctx.fillStyle = p.color;
                    ctx.beginPath();
                    ctx.arc(p.x, p.y, 4, 0, Math.PI*2);
                    ctx.fill();
                });

                // Partículas
                particles.forEach(p => {
                    ctx.globalAlpha = p.life;
                    ctx.fillStyle = p.color;
                    ctx.fillRect(p.x, p.y, 3, 3);
                });
                ctx.globalAlpha = 1;
            }

            function updateUI() {
                document.getElementById('val-lives').innerText = st.lives;
                document.getElementById('val-wave').innerText = st.wave;
                document.getElementById('val-money').innerText = st.money;
            }

            function gameOver() {
                st.running = false;
                document.getElementById('scr-over').classList.remove('hidden');
                document.getElementById('final-wave').innerText = st.wave;
            }

            return { start, selectTower };
        })();
    </script>
</div>



<p></p>
<p>La entrada <a href="https://instatecno.net/minijuegos-aprendizaje/minijuego-server">INSTATECNO: SERVER DEFENSE</a> se publicó primero en <a href="https://instatecno.net">InstaTecno</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://instatecno.net/minijuegos-aprendizaje/minijuego-server/feed</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Arcade Retro de Naves</title>
		<link>https://instatecno.net/minijuegos-aprendizaje/minijuegos-arcadae</link>
					<comments>https://instatecno.net/minijuegos-aprendizaje/minijuegos-arcadae#respond</comments>
		
		<dc:creator><![CDATA[David Sanchez]]></dc:creator>
		<pubDate>Wed, 19 Nov 2025 18:26:34 +0000</pubDate>
				<category><![CDATA[Minijuegos]]></category>
		<guid isPermaLink="false">https://instatecno.net/?p=961</guid>

					<description><![CDATA[<p>SCORE: 0 HP: 100% WAVE: 1 SYSTEM DEFENDER Protege el núcleo. Destruye los Virus. CONTROLES: Usa el RATÓN para moverte. [&#8230;]</p>
<p>La entrada <a href="https://instatecno.net/minijuegos-aprendizaje/minijuegos-arcadae">Arcade Retro de Naves</a> se publicó primero en <a href="https://instatecno.net">InstaTecno</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<div id="arcade-wrapper" style="width: 100%; max-width: 900px; margin: 0 auto; font-family: 'Courier New', monospace;">

    <style>
        #arcade-container {
            position: relative;
            width: 100%;
            height: 600px;
            background: #050505;
            border: 4px solid #333;
            border-radius: 10px;
            overflow: hidden;
            box-shadow: 0 0 30px rgba(0, 255, 255, 0.1);
            cursor: none; /* Oculta el cursor dentro del juego */
        }

        canvas {
            display: block;
            width: 100%;
            height: 100%;
        }

        /* UI SUPERPUESTA */
        .ui-layer {
            position: absolute; top: 0; left: 0; width: 100%; height: 100%;
            pointer-events: none; /* Deja pasar los clicks al canvas si es necesario */
            display: flex; flex-direction: column; justify-content: center; align-items: center;
            text-align: center;
            z-index: 10;
        }

        .hidden { display: none !important; }
        .pointer-active { pointer-events: all !important; cursor: default; }

        /* TEXTOS */
        h1 {
            color: #0ff;
            font-size: 40px;
            text-shadow: 0 0 20px #0ff;
            margin: 0 0 20px 0;
            letter-spacing: 5px;
            text-transform: uppercase;
        }

        p { color: #fff; font-size: 18px; text-shadow: 0 0 5px #fff; }

        /* BOTONES */
        .arcade-btn {
            background: transparent;
            color: #0f0;
            border: 2px solid #0f0;
            padding: 15px 40px;
            font-size: 20px;
            font-family: inherit;
            font-weight: bold;
            cursor: pointer;
            text-transform: uppercase;
            transition: 0.2s;
            box-shadow: 0 0 10px #0f0;
            margin-top: 20px;
        }
        .arcade-btn:hover {
            background: #0f0;
            color: #000;
            box-shadow: 0 0 30px #0f0;
        }

        /* HUD IN-GAME */
        #game-hud {
            position: absolute; top: 20px; left: 20px;
            color: white; font-size: 20px; font-weight: bold;
            text-shadow: 1px 1px 0 #000;
            pointer-events: none;
            display: flex; gap: 30px;
            z-index: 5;
        }

        .logo-img { max-width: 200px; margin-bottom: 20px; filter: drop-shadow(0 0 10px rgba(255,255,255,0.5)); }
    </style>

    <div id="arcade-container">
        
        <div id="game-hud" class="hidden">
            <div>SCORE: <span id="score-val" style="color:#0ff">0</span></div>
            <div>HP: <span id="hp-val" style="color:#f00">100%</span></div>
            <div>WAVE: <span id="wave-val" style="color:#ff0">1</span></div>
        </div>

        <div id="screen-start" class="ui-layer pointer-active">
            <img decoding="async" src="https://instatecno.net/wp-content/uploads/2025/10/Captura-de-pantalla-2025-10-15-031513.png" alt="Logo" class="logo-img">
            <h1>SYSTEM DEFENDER</h1>
            <p>Protege el núcleo. Destruye los Virus.</p>
            <p style="font-size: 0.8em; color: #aaa; margin-top: 10px;">CONTROLES: Usa el RATÓN para moverte. Disparo Automático.</p>
            <button class="arcade-btn" onclick="ArcadeGame.start()">START MISSION</button>
        </div>

        <div id="screen-over" class="ui-layer pointer-active hidden">
            <h1 style="color:#f00; text-shadow: 0 0 20px #f00;">SYSTEM FAILURE</h1>
            <p>Tu sistema ha sido infectado.</p>
            <h2 style="color:white;">SCORE FINAL: <span id="final-score">0</span></h2>
            <button class="arcade-btn" onclick="ArcadeGame.restart()">RETRY</button>
        </div>

        <canvas id="game-canvas"></canvas>
    </div>

    <script>
        window.ArcadeGame = (function() {
            const canvas = document.getElementById('game-canvas');
            const ctx = canvas.getContext('2d');
            let width, height;
            
            // Estado del juego
            let state = {
                running: false,
                score: 0,
                hp: 100,
                wave: 1,
                frames: 0
            };

            // Entidades
            let player = { x: 0, y: 0, size: 20, color: '#0ff', speed: 0 };
            let bullets = [];
            let enemies = [];
            let particles = [];
            let mouse = { x: 0, y: 0 };

            // Configuración
            const PLAYER_SPEED_LAG = 0.15; // Suavizado movimiento
            const FIRE_RATE = 10; // Cada cuantos frames dispara

            // --- CORE FUNCTIONS ---

            function resize() {
                // Ajustar al contenedor real
                const container = document.getElementById('arcade-container');
                width = container.clientWidth;
                height = container.clientHeight;
                canvas.width = width;
                canvas.height = height;
            }

            function init() {
                resize();
                window.addEventListener('resize', resize);
                
                // Mouse tracking
                canvas.addEventListener('mousemove', e => {
                    const rect = canvas.getBoundingClientRect();
                    mouse.x = e.clientX - rect.left;
                    mouse.y = e.clientY - rect.top;
                });

                // Touch support básico
                canvas.addEventListener('touchmove', e => {
                    e.preventDefault();
                    const rect = canvas.getBoundingClientRect();
                    mouse.x = e.touches[0].clientX - rect.left;
                    mouse.y = e.touches[0].clientY - rect.top;
                }, {passive: false});

                player.x = width / 2;
                player.y = height - 100;
            }

            function start() {
                document.getElementById('screen-start').classList.add('hidden');
                document.getElementById('screen-over').classList.add('hidden');
                document.getElementById('game-hud').classList.remove('hidden');
                
                state = { running: true, score: 0, hp: 100, wave: 1, frames: 0 };
                bullets = [];
                enemies = [];
                particles = [];
                
                // Resetear posición ratón para que la nave no salte
                mouse.x = width / 2;
                mouse.y = height - 100;
                player.x = mouse.x;
                player.y = mouse.y;

                loop();
            }

            function restart() {
                start();
            }

            function gameOver() {
                state.running = false;
                document.getElementById('game-hud').classList.add('hidden');
                document.getElementById('screen-over').classList.remove('hidden');
                document.getElementById('final-score').innerText = state.score;
            }

            function updateUI() {
                document.getElementById('score-val').innerText = state.score;
                document.getElementById('hp-val').innerText = Math.ceil(state.hp) + '%';
                document.getElementById('wave-val').innerText = state.wave;
            }

            // --- GAME LOOP ---

            function loop() {
                if (!state.running) return;

                update();
                draw();
                updateUI();
                state.frames++;
                requestAnimationFrame(loop);
            }

            function update() {
                // Movimiento Player (Lerp para suavidad)
                player.x += (mouse.x - player.x) * PLAYER_SPEED_LAG;
                player.y += (mouse.y - player.y) * PLAYER_SPEED_LAG;

                // Disparo automático
                if (state.frames % FIRE_RATE === 0) {
                    bullets.push({ x: player.x, y: player.y - 20, v: 10, size: 4 });
                    // Doble disparo si score alto
                    if(state.score > 1000) {
                        bullets.push({ x: player.x - 10, y: player.y - 10, v: 9, size: 3 });
                        bullets.push({ x: player.x + 10, y: player.y - 10, v: 9, size: 3 });
                    }
                }

                // Spawner Enemigos
                let spawnRate = Math.max(20, 60 - (state.wave * 5));
                if (state.frames % spawnRate === 0) {
                    spawnEnemy();
                }

                // Aumentar dificultad
                if (state.score > state.wave * 500) state.wave++;

                // Actualizar Balas
                bullets.forEach(b => b.y -= b.v);
                bullets = bullets.filter(b => b.y > 0);

                // Actualizar Enemigos
                enemies.forEach(e => {
                    e.y += e.v;
                    e.angle += 0.05; // Rotación visual
                    
                    // Colisión con Jugador
                    let dist = Math.hypot(player.x - e.x, player.y - e.y);
                    if (dist < player.size + e.size) {
                        takeDamage(20);
                        e.dead = true;
                        createExplosion(e.x, e.y, '#f00', 10);
                    }
                });

                // Colisión Balas vs Enemigos
                bullets.forEach(b => {
                    enemies.forEach(e => {
                        if (!e.dead && !b.dead) {
                            let dist = Math.hypot(b.x - e.x, b.y - e.y);
                            if (dist < e.size + b.size) {
                                e.hp--;
                                b.dead = true;
                                createExplosion(b.x, b.y, '#0ff', 3);
                                if (e.hp <= 0) {
                                    e.dead = true;
                                    state.score += 100;
                                    createExplosion(e.x, e.y, '#fa0', 15);
                                }
                            }
                        }
                    });
                });

                // Limpieza arrays
                bullets = bullets.filter(b => !b.dead);
                enemies = enemies.filter(e => !e.dead && e.y < height + 50);
                if (enemies.some(e => e.y > height)) takeDamage(5); // Daño si se escapan

                // Partículas
                particles.forEach(p => {
                    p.x += p.vx;
                    p.y += p.vy;
                    p.life -= 0.05;
                });
                particles = particles.filter(p => p.life > 0);
            }

            function spawnEnemy() {
                let size = 15 + Math.random() * 15;
                let type = Math.random() > 0.8 ? 'tank' : 'basic';
                let speed = 2 + (state.wave * 0.2);
                let hp = 1 + Math.floor(state.wave / 2);

                if (type === 'tank') {
                    size = 30; hp *= 3; speed *= 0.5;
                }

                enemies.push({
                    x: Math.random() * (width - 40) + 20,
                    y: -50,
                    v: speed,
                    size: size,
                    hp: hp,
                    type: type,
                    angle: 0,
                    dead: false
                });
            }

            function takeDamage(amount) {
                state.hp -= amount;
                // Efecto de pantalla roja
                canvas.style.boxShadow = "inset 0 0 50px #f00";
                setTimeout(() => canvas.style.boxShadow = "0 0 30px rgba(0, 255, 255, 0.1)", 100);
                
                if (state.hp <= 0) {
                    state.hp = 0;
                    gameOver();
                }
            }

            function createExplosion(x, y, color, count) {
                for (let i = 0; i < count; i++) {
                    particles.push({
                        x: x, y: y,
                        vx: (Math.random() - 0.5) * 10,
                        vy: (Math.random() - 0.5) * 10,
                        life: 1.0,
                        color: color,
                        size: Math.random() * 3 + 1
                    });
                }
            }

            // --- DRAWING ---

            function draw() {
                // Fondo con efecto rastro (Motion Blur)
                ctx.fillStyle = 'rgba(5, 5, 5, 0.3)';
                ctx.fillRect(0, 0, width, height);

                // Estrellas/Grid fondo
                ctx.fillStyle = 'rgba(0, 255, 255, 0.1)';
                for(let i=0; i<10; i++) {
                    ctx.fillRect(Math.random()*width, Math.random()*height, 2, 2);
                }

                // Jugador
                ctx.save();
                ctx.translate(player.x, player.y);
                ctx.beginPath();
                ctx.moveTo(0, -20); // Punta
                ctx.lineTo(15, 15);
                ctx.lineTo(0, 5);   // Centro
                ctx.lineTo(-15, 15);
                ctx.closePath();
                ctx.fillStyle = '#000';
                ctx.strokeStyle = '#0ff';
                ctx.lineWidth = 2;
                ctx.shadowBlur = 15;
                ctx.shadowColor = '#0ff';
                ctx.fill();
                ctx.stroke();
                // Fuego motor
                ctx.beginPath();
                ctx.moveTo(-5, 10);
                ctx.lineTo(0, 25 + Math.random()*10);
                ctx.lineTo(5, 10);
                ctx.fillStyle = '#fa0';
                ctx.fill();
                ctx.restore();

                // Balas
                ctx.fillStyle = '#ff0';
                ctx.shadowBlur = 5;
                ctx.shadowColor = '#ff0';
                bullets.forEach(b => {
                    ctx.beginPath();
                    ctx.arc(b.x, b.y, b.size, 0, Math.PI * 2);
                    ctx.fill();
                });

                // Enemigos
                enemies.forEach(e => {
                    ctx.save();
                    ctx.translate(e.x, e.y);
                    ctx.rotate(e.angle);
                    
                    ctx.shadowBlur = 10;
                    ctx.lineWidth = 2;
                    if(e.type === 'tank') {
                        ctx.strokeStyle = '#f0f';
                        ctx.shadowColor = '#f0f';
                        ctx.strokeRect(-e.size/2, -e.size/2, e.size, e.size);
                    } else {
                        ctx.strokeStyle = '#f00';
                        ctx.shadowColor = '#f00';
                        ctx.beginPath();
                        ctx.moveTo(0, -e.size/2);
                        ctx.lineTo(e.size/2, e.size/2);
                        ctx.lineTo(-e.size/2, e.size/2);
                        ctx.closePath();
                        ctx.stroke();
                    }
                    
                    // Vida enemigo
                    ctx.fillStyle = `rgba(255, 0, 0, ${e.hp/3})`;
                    ctx.fill();
                    ctx.restore();
                });

                // Partículas
                particles.forEach(p => {
                    ctx.globalAlpha = p.life;
                    ctx.fillStyle = p.color;
                    ctx.shadowBlur = 0;
                    ctx.fillRect(p.x, p.y, p.size, p.size);
                });
                ctx.globalAlpha = 1.0;
            }

            // Init al cargar
            setTimeout(init, 100);

            return { start, restart };

        })();
    </script>
</div>



<p></p>
<p>La entrada <a href="https://instatecno.net/minijuegos-aprendizaje/minijuegos-arcadae">Arcade Retro de Naves</a> se publicó primero en <a href="https://instatecno.net">InstaTecno</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://instatecno.net/minijuegos-aprendizaje/minijuegos-arcadae/feed</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Chatarrero Tecno</title>
		<link>https://instatecno.net/minijuegos-aprendizaje/minijugos-tecno</link>
					<comments>https://instatecno.net/minijuegos-aprendizaje/minijugos-tecno#comments</comments>
		
		<dc:creator><![CDATA[David Sanchez]]></dc:creator>
		<pubDate>Sun, 16 Nov 2025 20:04:26 +0000</pubDate>
				<category><![CDATA[Minijuegos]]></category>
		<guid isPermaLink="false">https://instatecno.net/?p=906</guid>

					<description><![CDATA[<p>InstaTecno.net Presenta: CHATARRERO TECNO Trader Edition JUGAR 📅 1 💰 50€ ⚡ 100 🗑️ Buscar 🔧 Reparar 💸 Mercado 🖥️ [&#8230;]</p>
<p>La entrada <a href="https://instatecno.net/minijuegos-aprendizaje/minijugos-tecno">Chatarrero Tecno</a> se publicó primero en <a href="https://instatecno.net">InstaTecno</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<div id="chatarrero-wrapper" style="width: 100%; max-width: 900px; margin: 0 auto; font-family: 'Segoe UI', sans-serif; color: #333;">

    <style>
        /* Estilos encapsulados para no afectar tu web */
        #chatarrero-wrapper {
            --c-bg: #ecf0f1;
            --c-dark: #2c3e50;
            --c-blue: #2980b9;
            --c-green: #27ae60;
            --c-red: #c0392b;
            --c-yellow: #f39c12;
            --c-purple: #8e44ad;
        }

        #game-window {
            width: 100%;
            height: 650px; /* Altura fija para el bloque */
            background: var(--c-bg);
            border-radius: 8px;
            box-shadow: 0 4px 15px rgba(0,0,0,0.2);
            position: relative;
            overflow: hidden;
            display: flex;
            flex-direction: column;
            border: 1px solid #ccc;
        }

        /* Pantallas */
        .ct-screen {
            position: absolute; top: 0; left: 0; width: 100%; height: 100%;
            background: var(--c-bg);
            display: flex; flex-direction: column;
            opacity: 0; pointer-events: none; transition: opacity 0.3s; z-index: 0;
        }
        .ct-screen.active { opacity: 1; pointer-events: all; z-index: 10; }
        .ct-centered {
            justify-content: center; align-items: center; text-align: center;
            background: linear-gradient(135deg, #34495e, #2c3e50); color: white;
        }

        /* Interfaz */
        #ct-hud {
            height: 50px; background: var(--c-dark); color: white;
            display: flex; align-items: center; justify-content: space-around;
            font-weight: bold; flex-shrink: 0;
        }
        #ct-nav { display: flex; background: #bdc3c7; flex-shrink: 0; }
        .ct-nav-btn {
            flex: 1; padding: 10px; border: none; background: none; cursor: pointer;
            font-weight: bold; border-bottom: 4px solid transparent; color: #444;
        }
        .ct-nav-btn.active { background: var(--c-bg); color: var(--c-blue); border-bottom-color: var(--c-blue); }

        /* Contenido Scrollable */
        #ct-content { flex-grow: 1; padding: 15px; overflow-y: auto; position: relative; }
        .ct-view { display: none; }
        .ct-view.active { display: block; animation: ctFade 0.3s; }
        @keyframes ctFade { from {opacity:0; transform:translateY(5px);} to {opacity:1; transform:translateY(0);} }

        /* Filtros */
        .ct-filter-bar { display: flex; gap: 5px; margin-bottom: 10px; background: #dfe6e9; padding: 8px; border-radius: 5px; }
        .ct-input { flex: 1; padding: 5px; border: 1px solid #ccc; border-radius: 4px; }
        .ct-btn-filter { padding: 5px 10px; cursor: pointer; background: white; border: 1px solid #ccc; border-radius: 4px; }

        /* Items */
        .ct-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 10px; }
        .ct-card {
            background: white; padding: 10px; border: 1px solid #ccc; border-radius: 5px;
            position: relative; display: flex; flex-direction: column; justify-content: space-between;
        }
        .ct-card.broken { border-left: 4px solid var(--c-red); }
        .ct-card.working { border-left: 4px solid var(--c-green); }
        .ct-card.tier3 { border: 2px solid var(--c-purple); background: #f8effc; }
        .ct-badge {
            position: absolute; top: 5px; right: 5px; font-size: 10px; padding: 2px 5px; color: white; border-radius: 3px;
        }

        /* Botones */
        .ct-btn { width: 100%; padding: 8px; margin-top: 5px; cursor: pointer; border: none; border-radius: 4px; color: white; font-weight: bold; }
        .ct-btn:hover { opacity: 0.9; }
        .btn-blue { background: var(--c-blue); }
        .btn-green { background: var(--c-green); }
        .btn-yellow { background: var(--c-yellow); color: #333; }
        .btn-red { background: var(--c-red); }

        /* Slots Taller */
        .ct-workshop { display: grid; grid-template-columns: 1fr 250px; gap: 15px; height: 100%; }
        @media (max-width: 600px) { .ct-workshop { grid-template-columns: 1fr; } }
        
        .ct-slot {
            padding: 15px; margin-bottom: 10px; text-align: center; border: 2px dashed #999;
            color: #777; border-radius: 5px; background: rgba(255,255,255,0.5);
        }
        .ct-slot.drag-over { background: #d4e6f1; border-color: var(--c-blue); }
        .ct-slot.filled { background: var(--c-green); color: white; border-style: solid; }
        
        /* Consola */
        #ct-console { background: #2c3e50; color: #ecf0f1; height: 120px; overflow-y: auto; padding: 10px; font-family: monospace; font-size: 0.9em; margin-top: 10px; border-radius: 5px; }
        .log-r { color: var(--c-yellow); } .log-l { color: var(--c-purple); font-weight: bold; }

    </style>

    <div id="game-window">
        <div id="scr-start" class="ct-screen ct-centered active">
            <img decoding="async" src="https://instatecno.net/wp-content/uploads/2025/10/Captura-de-pantalla-2025-10-15-031513.png" alt="InstaTecno.net Logo" style="max-width: 200px; margin-bottom: 20px;">
            <p style="font-size: 1.5em; margin: 0; color: #bde0fe;">InstaTecno.net Presenta:</p>
            <h1>CHATARRERO TECNO</h1>
            <p style="font-size: 1.1em; margin-bottom: 30px;">Trader Edition</p>
            <button class="ct-btn btn-green" style="width: auto; padding: 15px 40px; font-size: 1.2em;" onclick="CTGame.start()">JUGAR</button>
        </div>

        <div id="scr-game" class="ct-screen">
            <div id="ct-hud">
                <div><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f4c5.png" alt="📅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> <span id="hud-day">1</span></div>
                <div><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f4b0.png" alt="💰" class="wp-smiley" style="height: 1em; max-height: 1em;" /> <span id="hud-money">50€</span></div>
                <div><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/26a1.png" alt="⚡" class="wp-smiley" style="height: 1em; max-height: 1em;" /> <span id="hud-energy">100</span></div>
            </div>

            <div id="ct-nav">
                <button class="ct-nav-btn active" onclick="CTGame.nav('desguace', this)"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f5d1.png" alt="🗑" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Buscar</button>
                <button class="ct-nav-btn" onclick="CTGame.nav('banco', this)"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f527.png" alt="🔧" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Reparar</button>
                <button class="ct-nav-btn" onclick="CTGame.nav('mercado', this)"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f4b8.png" alt="💸" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Mercado</button>
                <button class="ct-nav-btn" onclick="CTGame.nav('taller', this)"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f5a5.png" alt="🖥" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Taller</button>
                <button class="ct-nav-btn" onclick="CTGame.nav('tienda', this)"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f6d2.png" alt="🛒" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Tienda</button>
            </div>

            <div id="ct-content">
                <div id="view-desguace" class="ct-view active">
                    <button class="ct-btn btn-yellow" style="padding: 30px; font-size: 1.2em;" onclick="CTGame.scavenge()"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f50d.png" alt="🔍" class="wp-smiley" style="height: 1em; max-height: 1em;" /> REBUSCAR (-20 Energía)</button>
                    <div id="ct-console"></div>
                </div>

                <div id="view-banco" class="ct-view">
                    <h3>Reparación</h3>
                    <div id="list-broken" class="ct-grid"></div>
                </div>

                <div id="view-mercado" class="ct-view">
                    <div class="ct-filter-bar">
                        <input type="text" id="inp-market" class="ct-input" placeholder="Buscar..." onkeyup="CTGame.filterMarket()">
                        <button class="ct-btn-filter" onclick="CTGame.setCat('all')">Todo</button>
                        <button class="ct-btn-filter" onclick="CTGame.setCat('gpu')">GPU</button>
                        <button class="ct-btn-filter" onclick="CTGame.setCat('cpu')">CPU</button>
                    </div>
                    <div id="list-market" class="ct-grid"></div>
                </div>

                <div id="view-taller" class="ct-view">
                    <div class="ct-workshop">
                        <div style="display:flex; flex-direction:column; overflow:hidden;">
                            <div class="ct-filter-bar">
                                <input type="text" id="inp-taller" class="ct-input" placeholder="Filtro PC..." onkeyup="CTGame.filterTaller()">
                            </div>
                            <div id="list-taller" class="ct-grid" style="overflow-y:auto; flex:1; grid-template-columns: 1fr;"></div>
                        </div>
                        <div style="background: #ddd; padding: 10px; border-radius: 5px;">
                            <h4 style="margin-top:0; text-align:center;">PC BUILD</h4>
                            <div class="ct-slot" data-type="cpu">CPU</div>
                            <div class="ct-slot" data-type="mobo">PLACA</div>
                            <div class="ct-slot" data-type="ram">RAM</div>
                            <div class="ct-slot" data-type="gpu">GPU</div>
                            <button class="ct-btn btn-blue" onclick="CTGame.checkWin()">COMPROBAR</button>
                            <button class="ct-btn btn-red" onclick="CTGame.sleep()">DORMIR (-15€)</button>
                        </div>
                    </div>
                </div>

                <div id="view-tienda" class="ct-view">
                    <h3>Mejoras</h3>
                    <div class="ct-grid">
                        <div class="ct-card" style="text-align:center;">
                            <strong>Café</strong><small>+20 Energía Max</small>
                            <h3 style="color:#2980b9; margin:5px;">100€</h3>
                            <button class="ct-btn btn-blue" onclick="CTGame.buy('energy')">Comprar</button>
                        </div>
                        <div class="ct-card" style="text-align:center;">
                            <strong>Herramientas</strong><small>+15% Reparar</small>
                            <h3 style="color:#2980b9; margin:5px;">150€</h3>
                            <button class="ct-btn btn-blue" onclick="CTGame.buy('tools')">Comprar</button>
                        </div>
                        <div class="ct-card" style="text-align:center;">
                            <strong>Suerte</strong><small>Mejor Loot</small>
                            <h3 style="color:#2980b9; margin:5px;">250€</h3>
                            <button class="ct-btn btn-blue" onclick="CTGame.buy('luck')">Comprar</button>
                        </div>
                    </div>
                </div>
            </div>
        </div>

        <div id="scr-end" class="ct-screen ct-centered">
            <h1 id="end-title">FIN</h1>
            <p id="end-msg"></p>
            <button class="ct-btn btn-green" style="width:auto;" onclick="CTGame.restart()">REINICIAR</button>
        </div>
    </div>

    <script>
    (function(){
        // Encapsulamos todo en una función para no chocar con otros scripts de tu web
        const DB = [
            {n:'RAM 2GB',t:'ram',v:15,q:'common'},{n:'RAM 4GB',t:'ram',v:25,q:'common'},
            {n:'Fuente China',t:'psu',v:5,q:'junk'},{n:'Celeron',t:'cpu',v:10,q:'common'},
            {n:'GT 210',t:'gpu',v:12,q:'junk'},{n:'GTX 750 Ti',t:'gpu',v:60,q:'rare'},
            {n:'GTX 1060',t:'gpu',v:120,q:'rare'},{n:'i7 4790k',t:'cpu',v:110,q:'rare'},
            {n:'H81 Mobo',t:'mobo',v:30,q:'common'},
            // TIER 3
            {n:'i9-14900KS',t:'cpu',v:800,q:'tier3'},{n:'RTX 5090',t:'gpu',v:800,q:'tier3'},
            {n:'RAM 128GB',t:'ram',v:800,q:'tier3'},{n:'Placa Quantum',t:'mobo',v:800,q:'tier3'}
        ];

        window.CTGame = {
            st: { day:1, money:50, energy:100, maxEnergy:100, inv:[], pc:{cpu:null,mobo:null,ram:null,gpu:null}, stats:{rep:0.5,luck:1,rent:15}, cat:'all' },

            start: function(){
                document.getElementById('scr-start').classList.remove('active');
                document.getElementById('scr-game').classList.add('active');
                this.upd(); this.drag();
            },
            restart: function(){
                 this.st = { day:1, money:50, energy:100, maxEnergy:100, inv:[], pc:{cpu:null,mobo:null,ram:null,gpu:null}, stats:{rep:0.5,luck:1,rent:15}, cat:'all' };
                 document.querySelectorAll('.ct-slot').forEach(s=>{s.className='ct-slot'; s.innerHTML=s.dataset.type.toUpperCase();});
                 document.getElementById('ct-console').innerHTML = ''; // Limpiar consola
                 document.getElementById('scr-end').classList.remove('active');
                 document.getElementById('scr-start').classList.add('active');
            },
            nav: function(id, btn){
                document.querySelectorAll('.ct-view').forEach(v=>v.classList.remove('active'));
                document.getElementById('view-'+id).classList.add('active');
                document.querySelectorAll('.ct-nav-btn').forEach(b=>b.classList.remove('active'));
                btn.classList.add('active');
                if(id==='banco') this.rBroken();
                if(id==='mercado') this.filterMarket();
                if(id==='taller') this.filterTaller();
            },
            upd: function(){
                document.getElementById('hud-day').innerText = this.st.day;
                document.getElementById('hud-money').innerText = this.st.money + '€';
                document.getElementById('hud-energy').innerText = Math.floor(this.st.energy) + '/' + this.st.maxEnergy;
            },
            log: function(m,t){
                const d = document.createElement('div');
                d.innerHTML = '> '+m;
                if(t==='rare') d.className='log-r';
                if(t==='tier3') d.className='log-l';
                document.getElementById('ct-console').prepend(d);
            },
            scavenge: function(){
                if(this.st.energy<20) return this.log("¡Sin energía!");
                this.st.energy-=20; this.upd();
                let r = Math.random()*this.st.stats.luck, it;
                if(r>0.94) { it=DB.filter(i=>i.q==='tier3'); it=it[Math.floor(Math.random()*it.length)]; this.log("¡LEGENDARIO! "+it.n,'tier3'); }
                else if(r>0.75) { it=DB.filter(i=>i.q==='rare'); it=it[Math.floor(Math.random()*it.length)]; this.log("¡Raro! "+it.n,'rare'); }
                else { it=DB.filter(i=>i.q!=='tier3'&&i.q!=='rare'); it=it[Math.floor(Math.random()*it.length)]; this.log("Encontrado: "+it.n); }
                this.st.inv.push({...it, uid:Date.now()+Math.random(), s:'broken'});
            },
            rBroken: function(){
                const c = document.getElementById('list-broken'); c.innerHTML='';
                this.st.inv.filter(i=>i.s==='broken').forEach(i=>{
                    c.innerHTML+=`<div class="ct-card broken"><strong>${i.n}</strong><small>${i.v}€</small><button class="ct-btn btn-yellow" onclick="CTGame.repair(${i.uid})">Reparar</button></div>`;
                });
                if(!c.innerHTML) c.innerHTML='<p>Nada roto.</p>';
            },
            repair: function(id){
                if(this.st.energy<10) return alert("Falta energía");
                this.st.energy-=10; this.upd();
                let it=this.st.inv.find(i=>i.uid===id);
                if(Math.random()<this.st.stats.rep){ it.s='working'; alert("¡Reparado!"); }
                else { this.st.inv=this.st.inv.filter(i=>i.uid!==id); alert("Explotó."); }
                this.rBroken();
            },
            setCat: function(c){ this.st.cat=c; this.filterMarket(); },
            filterMarket: function(){
                const txt = document.getElementById('inp-market').value.toLowerCase();
                const c = document.getElementById('list-market'); c.innerHTML='';
                const inst = Object.values(this.st.pc);
                this.st.inv.filter(i=>i.s==='working' && !inst.includes(i.uid) && (this.st.cat==='all' || i.t===this.st.cat) && i.n.toLowerCase().includes(txt)).forEach(i=>{
                     let col = i.q==='tier3'?'#8e44ad':(i.q==='rare'?'#f1c40f':'#27ae60');
                     c.innerHTML+=`<div class="ct-card working" style="border-left-color:${col}">
                     <span class="ct-badge" style="background:${col}">${i.q}</span>
                     <strong>${i.n}</strong><small>${i.t}</small>
                     <button class="ct-btn btn-green" onclick="CTGame.sell(${i.uid})">VENDER ${i.v}€</button></div>`;
                });
            },
            sell: function(id){
                let idx=this.st.inv.findIndex(i=>i.uid===id);
                this.st.money+=this.st.inv[idx].v; this.st.inv.splice(idx,1);
                this.upd(); this.filterMarket();
            },
            filterTaller: function(){
                const txt = document.getElementById('inp-taller').value.toLowerCase();
                const c = document.getElementById('list-taller'); c.innerHTML='';
                const inst = Object.values(this.st.pc);
                this.st.inv.filter(i=>i.s==='working' && !inst.includes(i.uid) && i.n.toLowerCase().includes(txt)).forEach(i=>{
                    let d = document.createElement('div');
                    d.className = 'ct-card working'; d.draggable=true;
                    d.innerHTML = `<strong>${i.n}</strong><small>${i.t}</small>`;
                    d.addEventListener('dragstart', e=>e.dataTransfer.setData('d', JSON.stringify({u:i.uid,t:i.t})));
                    c.appendChild(d);
                });
            },
            drag: function(){
                document.querySelectorAll('.ct-slot').forEach(s=>{
                    s.ondragover=e=>{e.preventDefault();s.classList.add('drag-over');};
                    s.ondragleave=()=>s.classList.remove('drag-over');
                    s.ondrop=e=>{
                        e.preventDefault(); s.classList.remove('drag-over');
                        let d=JSON.parse(e.dataTransfer.getData('d'));
                        if(s.dataset.type===d.t){
                            this.st.pc[d.t]=d.u; let it=this.st.inv.find(i=>i.uid===d.u);
                            s.innerHTML=it.n; s.className='ct-slot filled '+(it.q==='tier3'?'tier3':'');
                            this.filterTaller();
                        } else alert("Slot incorrecto");
                    }
                });
            },
            sleep: function(){
                this.st.day++; this.st.money-=this.st.stats.rent; this.st.energy=this.st.maxEnergy;
                this.upd(); this.log(`Día ${this.st.day}: Alquiler pagado.`);
                if(this.st.money<0) this.end(false, "Bancarrota.");
                if(this.st.day>30) this.end(false, "Tiempo agotado.");
            },
            buy: function(t){
                let c = t==='energy'?100:t==='tools'?150:250;
                if(this.st.money>=c){
                    this.st.money-=c;
                    if(t==='energy'){this.st.maxEnergy+=20; this.st.energy=this.st.maxEnergy;}
                    if(t==='tools')this.st.stats.rep+=0.15;
                    if(t==='luck')this.st.stats.luck+=0.2;
                    this.upd(); alert("¡Comprado!");
                } else alert("Sin dinero.");
            },
            checkWin: function(){
                let ids=Object.values(this.st.pc);
                if(ids.includes(null)) return alert("PC Incompleto");
                let cnt = ids.map(u=>this.st.inv.find(i=>i.uid===u)).filter(i=>i.q==='tier3').length;
                if(cnt===4) this.end(true,"¡PC LEGENDARIO!");
                else alert(`Solo ${cnt}/4 piezas legendarias.`);
            },
            end: function(win,m){
                document.getElementById('scr-game').classList.remove('active');
                document.getElementById('scr-end').classList.add('active');
                document.getElementById('end-title').innerText=win?"VICTORIA":"GAME OVER";
                document.getElementById('end-title').style.color=win?"#2ecc71":"#e74c3c";
                document.getElementById('end-msg').innerText=m;
            }
        };
    })();
    </script>
</div>
«`http://googleusercontent.com/image_generation_content/1



<p></p>
<p>La entrada <a href="https://instatecno.net/minijuegos-aprendizaje/minijugos-tecno">Chatarrero Tecno</a> se publicó primero en <a href="https://instatecno.net">InstaTecno</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://instatecno.net/minijuegos-aprendizaje/minijugos-tecno/feed</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>El Código Completo: Reto de Phishing</title>
		<link>https://instatecno.net/minijuegos-aprendizaje/reto-de-phishing</link>
					<comments>https://instatecno.net/minijuegos-aprendizaje/reto-de-phishing#comments</comments>
		
		<dc:creator><![CDATA[David Sanchez]]></dc:creator>
		<pubDate>Sun, 16 Nov 2025 19:01:53 +0000</pubDate>
				<category><![CDATA[Minijuegos]]></category>
		<guid isPermaLink="false">https://instatecno.net/?p=901</guid>

					<description><![CDATA[<p>Instatecno: Reto de Phishing El Reto del Phishing de InstaTecno ¿Puedes diferenciar un mensaje real de un intento de estafa? [&#8230;]</p>
<p>La entrada <a href="https://instatecno.net/minijuegos-aprendizaje/reto-de-phishing">El Código Completo: Reto de Phishing</a> se publicó primero en <a href="https://instatecno.net">InstaTecno</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<!DOCTYPE html>
<html lang="es">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Instatecno: Reto de Phishing</title>

<style>
    /* --- VARIABLES DE MARCA (Tus colores) --- */
    :root {
        --color-primario-instatecno: #00A8E8;
        --color-secundario-instatecno: #95C11F;
        --color-fondo: #f4f7f6;
        --color-panel: #ffffff;
        --color-borde: #dfe6e9;
        --color-texto-oscuro: #333;
        --color-error: #e74c3c;
        --color-success: var(--color-secundario-instatecno);
        --color-phishing-btn: #eb4d4b;
        --color-legitimo-btn: #2ecc71;
        --font-ui: 'Segoe UI', Roboto, sans-serif;
    }

    /* --- CONTENEDOR PRINCIPAL DEL JUEGO --- */
    #phishing-game-container {
        font-family: var(--font-ui);
        background-color: var(--color-fondo);
        border: 1px solid var(--color-borde);
        border-radius: 8px;
        box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1);
        width: 100%;
        max-width: 800px;
        margin: 2rem auto;
        overflow: hidden;
    }

    /* --- PANTALLAS (Inicio, Juego, Fin) --- */
    .game-screen {
        padding: 20px 30px;
        box-sizing: border-box;
    }
    #game-start-screen, #game-end-screen {
        text-align: center;
    }
    #game-start-screen h2, #game-end-screen h2 {
        color: var(--color-texto-oscuro);
        margin-top: 0;
    }
    #game-start-screen p { font-size: 1.1em; }
    
    #game-play-screen {
        display: none; /* Oculto al inicio */
    }
    #game-end-screen {
        display: none; /* Oculto al inicio */
    }

    /* --- BOTONES --- */
    .game-btn {
        background-color: var(--color-primario-instatecno);
        color: white;
        border: none;
        border-radius: 5px;
        padding: 15px 30px;
        font-size: 1.1em;
        font-weight: bold;
        cursor: pointer;
        transition: transform 0.2s, box-shadow 0.2s;
    }
    .game-btn:hover {
        transform: translateY(-2px);
        box-shadow: 0 4px 10px rgba(0, 0, 0, 0.2);
    }
    
    /* Botones de respuesta */
    #game-answer-buttons {
        display: flex;
        justify-content: space-around;
        margin-top: 20px;
    }
    #btn-legitimo {
        background-color: var(--color-legitimo-btn);
    }
    #btn-phishing {
        background-color: var(--color-phishing-btn);
    }

    /* --- BARRA DE JUEGO (Puntos, Ronda, Timer) --- */
    #game-hud {
        display: flex;
        justify-content: space-between;
        align-items: center;
        margin-bottom: 20px;
        font-size: 1.1em;
        font-weight: bold;
    }
    #game-timer {
        width: 100%;
        height: 10px;
        background-color: var(--color-borde);
        border-radius: 5px;
        overflow: hidden;
    }
    #game-timer-bar {
        height: 100%;
        width: 100%;
        background-color: var(--color-primario-instatecno);
        transition: width 0.2s linear;
    }
    #game-score, #game-round {
        color: var(--color-texto-oscuro);
    }
    #game-round { text-align: right; }
    
    /* --- ZONA DEL ESCENARIO --- */
    #game-scenario-content {
        background-color: var(--color-panel);
        border: 1px solid var(--color-borde);
        border-radius: 8px;
        height: 400px;
        overflow-y: auto;
    }

    /* --- SIMULACIÓN DE ESCENARIOS (Email, WhatsApp, Login) --- */
    
    /* 1. Simulación de Email */
    .email-scenario {
        font-family: 'Arial', sans-serif;
    }
    .email-header {
        display: flex;
        align-items: center;
        border-bottom: 1px solid #ddd;
        padding: 15px;
        margin-bottom: 15px;
    }
    .email-logo {
        width: 50px;
        height: 50px;
        margin-right: 15px;
        object-fit: contain;
    }
    .email-header-info {
        flex-grow: 1;
    }
    .email-header-info h3 {
        margin: 0 0 5px 0;
        font-size: 1.2em;
        color: #222;
    }
    .email-header-info p {
        margin: 2px 0;
        font-size: 0.9em;
        color: #555;
    }
    .email-header-info p span {
        font-weight: bold;
        color: #222;
    }
    .email-body {
        font-size: 1em;
        line-height: 1.6;
        padding: 0 15px 15px 15px;
    }
    .email-body .highlight {
        background-color: #fffb8f;
        cursor: help;
    }
    .email-body a {
        color: #0000ee;
        text-decoration: underline;
        cursor: pointer;
    }
    
    /* 2. Simulación de Login */
    .login-scenario-wrapper {
        padding: 0;
    }
    .login-scenario {
        background-color: #fafafa;
        border-top: 1px solid #dbdbdb;
        text-align: center;
        padding: 40px 20px;
    }
    .login-logo-img {
        width: 180px;
        height: auto;
        margin-bottom: 30px;
        object-fit: contain;
    }
    .login-input {
        width: 80%;
        padding: 10px;
        margin: 5px 0;
        border: 1px solid #dbdbdb;
        border-radius: 3px;
        background: #fafafa;
    }
    .login-btn {
        width: 80%;
        padding: 10px;
        margin-top: 15px;
        background-color: #0095f6;
        color: white;
        border: none;
        border-radius: 5px;
        font-weight: bold;
    }
    
    /* Falso navegador para URL */
    .fake-browser-bar {
        background: #e9e9e9;
        padding: 8px 15px;
        border-radius: 8px 8px 0 0;
        text-align: left;
        font-family: monospace;
    }
    .fake-browser-bar span {
        background: #fff;
        padding: 4px 8px;
        border-radius: 3px;
        color: #333;
    }

    /* 3. Simulación de WhatsApp */
    .whatsapp-scenario {
        background-color: #e5ddd5;
        height: 100%;
        display: flex;
        flex-direction: column;
    }
    .whatsapp-header {
        background-color: #075e54;
        color: white;
        padding: 10px 15px;
        font-weight: bold;
        display: flex;
        align-items: center;
    }
    .whatsapp-sender-logo {
        width: 40px;
        height: 40px;
        border-radius: 50%;
        margin-right: 10px;
        background: #fff;
        padding: 5px; /* Para que el icono no toque el borde */
        box-sizing: border-box;
    }
    .whatsapp-body {
        flex-grow: 1;
        padding: 10px;
    }
    .bubble {
        background-color: #fff;
        border-radius: 8px;
        padding: 10px 15px;
        max-width: 80%;
        margin-bottom: 10px;
        line-height: 1.5;
    }
    .bubble.left {
        float: left;
        clear: both;
        background-color: #fff;
    }
    .bubble a {
        color: #0000ee;
        text-decoration: underline;
    }
    
    /* --- MODAL DE FEEDBACK (Oculto) --- */
    #game-feedback-modal {
        display: none; /* Oculto por defecto */
        position: fixed;
        z-index: 1000;
        left: 0;
        top: 0;
        width: 100%;
        height: 100%;
        background-color: rgba(0, 0, 0, 0.6);
        justify-content: center;
        align-items: center;
    }
    .modal-content {
        background-color: var(--color-panel);
        border-radius: 8px;
        padding: 30px;
        width: 90%;
        max-width: 600px;
        text-align: center;
        box-shadow: 0 5px 20px rgba(0,0,0,0.3);
    }
    #feedback-title {
        font-size: 2em;
        font-weight: bold;
        margin: 0 0 15px 0;
    }
    #feedback-title.correct { color: var(--color-success); }
    #feedback-title.incorrect { color: var(--color-error); }
    #feedback-explanation {
        font-size: 1.1em;
        line-height: 1.6;
        color: var(--color-texto-oscuro);
        margin-bottom: 25px;
    }
    #feedback-explanation strong {
        color: var(--color-error);
    }
</style>
</head>
<body>

    <div id="phishing-game-container">
        
        <div id="game-start-screen" class="game-screen">
            <h2>El Reto del Phishing de InstaTecno</h2>
            <p>¿Puedes diferenciar un mensaje real de un intento de estafa?</p>
            <p>Analiza cada escenario antes de que se acabe el tiempo. ¡Fíjate en los logos y las URLs!</p>
            <button id="btn-start" class="game-btn">¡Empezar Desafío!</button>
        </div>

        <div id="game-play-screen" class="game-screen">
            <div id="game-hud">
                <div id="game-score">Puntos: 0</div>
                <div id="game-round">Ronda: 1 / 6</div>
            </div>
            
            <div id="game-timer">
                <div id="game-timer-bar"></div>
            </div>
            
            <h3 id="game-question" style="text-align: center; margin: 20px 0;">¿Este mensaje es&#8230;</h3>
            
            <div id="game-scenario-content">
                </div>
            
            <div id="game-answer-buttons">
                <button id="btn-legitimo" class="game-btn">Legítimo</button>
                <button id="btn-phishing" class="game-btn">Phishing</button>
            </div>
        </div>
        
        <div id="game-end-screen" class="game-screen">
            <h2>¡Juego Terminado!</h2>
            <h3>Tu puntuación final es:</h3>
            <h1 id="game-final-score" style="font-size: 4em; margin: 10px 0; color: var(--color-primario-instatecno);">0</h1>
            <p>Sigue practicando para convertirte en un experto en ciberseguridad.</p>
            <button id="btn-restart" class="game-btn">Jugar de Nuevo</button>
        </div>
    </div>
    
    <div id="game-feedback-modal">
        <div class="modal-content">
            <h2 id="feedback-title"></h2>
            <p id="feedback-explanation"></p>
            <button id="btn-next-round" class="game-btn">Siguiente Ronda</button>
        </div>
    </div>

    <script>
    document.addEventListener('DOMContentLoaded', () => {

        // --- Elementos del DOM ---
        const startScreen = document.getElementById('game-start-screen');
        const playScreen = document.getElementById('game-play-screen');
        const endScreen = document.getElementById('game-end-screen');
        
        const scoreDisplay = document.getElementById('game-score');
        const roundDisplay = document.getElementById('game-round');
        const timerBar = document.getElementById('game-timer-bar');
        const scenarioContent = document.getElementById('game-scenario-content');
        const finalScoreDisplay = document.getElementById('game-final-score');

        const btnStart = document.getElementById('btn-start');
        const btnLegitimo = document.getElementById('btn-legitimo');
        const btnPhishing = document.getElementById('btn-phishing');
        const btnRestart = document.getElementById('btn-restart');
        const btnNextRound = document.getElementById('btn-next-round');
        
        const feedbackModal = document.getElementById('game-feedback-modal');
        const feedbackTitle = document.getElementById('feedback-title');
        const feedbackExplanation = document.getElementById('feedback-explanation');

        // --- Configuración del Juego ---
        const ROUND_TIME = 15; // 15 segundos por ronda
        let score = 0;
        let currentRound = 0;
        let timerId = null;
        let timeLeft = 0;

        // --- Base de Datos de Escenarios (¡CON LOGOS SVG EMBUTIDOS!) ---
        const scenarios = [
            {
                type: 'email',
                isPhishing: true,
                content: {
                    // Logo Falso de Amazon "A-Prime"
                    logoUrl: "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Crect width='100' height='100' rx='10' fill='%23232f3e'/%3E%3Cpath d='M30 70 L50 30 L70 70' stroke='%23f90' stroke-width='10' fill='none'/%3E%3Cpath d='M40 70 Q50 80 60 70' stroke='%23f90' stroke-width='5' fill='none'/%3E%3C/svg%3E",
                    from: "Servicio al Cliente <servicio@amzn-prime.co>",
                    subject: "Problema con su pedido #112-45890-12345",
                    body: "Estimado cliente,<br><br>No hemos podido confirmar la dirección de envío de su último pedido. Esto puede causar un retraso indefinido.<br><br>Por favor, actualice su información de inmediato para evitar la cancelación.<br><br><a>Haga clic aquí para verificar su cuenta</a>"
                },
                explanation: "¡PHISHING! El remitente no es de Amazon. Fíjate en el dominio: <strong>'amzn-prime.co'</strong>. Amazon siempre usa 'amazon.com' o 'amazon.es'. Además, crean un sentido de urgencia."
            },
            {
                type: 'login',
                isPhishing: true,
                content: {
                    url: "https://instagram.seguridad-total.com/login",
                    // Logo Falso de Instagram
                    logoUrl: "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Cdefs%3E%3CradialGradient id='g' cx='0.5' cy='0.5' r='0.5'%3E%3Cstop stop-color='%23f09433' offset='0'/%3E%3Cstop stop-color='%23e6683c' offset='0.25'/%3E%3Cstop stop-color='%23dc2743' offset='0.5'/%3E%3Cstop stop-color='%23cc2366' offset='0.75'/%3E%3Cstop stop-color='%23bc1888' offset='1'/%3E%3C/radialGradient%3E%3C/defs%3E%3Crect width='90' height='90' x='5' y='5' rx='25' fill='url(%23g)'/%3E%3Ccircle cx='50' cy='50' r='25' stroke='white' stroke-width='8' fill='none'/%3E%3Ccircle cx='70' cy='30' r='6' fill='white'/%3E%3C/svg%3E",
                },
                explanation: "¡PHISHING! La URL es la clave. El dominio real es 'instagram.com', no <strong>'instagram.seguridad-total.com'</strong>. Es un sitio falso diseñado para robar tu contraseña."
            },
            {
                type: 'whatsapp',
                isPhishing: true,
                content: {
                    // Logo Falso de Banco
                    logoUrl: "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Crect width='100' height='100' rx='50' fill='%23075e54'/%3E%3Cpath d='M50 20 L80 40 V50 H20 V40 Z M25 55 H35 V80 H25 Z M45 55 H55 V80 H45 Z M65 55 H75 V80 H65 Z M15 80 H85 V90 H15 Z' fill='white'/%3E%3C/svg%3E",
                    sender: "Tu Banco",
                    message: "Hemos detectado actividad sospechosa en su cuenta. Para su seguridad, ha sido bloqueada temporalmente. Por favor, verifique su identidad en el siguiente enlace: <a>https://bit.ly/banco-seguro-123</a>"
                },
                explanation: "¡PHISHING! Tu banco NUNCA te contactará por WhatsApp para un problema de seguridad. Además, usan un acortador de URL (<strong>bit.ly</strong>) para ocultar el verdadero sitio web malicioso."
            },
            {
                type: 'email',
                isPhishing: false,
                content: {
                    // ¡TU LOGO DE INSTATECNO!
                    logoUrl: 'https://i.imgur.com/G4Qh60X.png', 
                    from: "Soporte InstaTecno <noreply@instatecno.net>",
                    subject: "Confirmación de restablecimiento de contraseña",
                    body: "Hola,<br><br>Hemos recibido una solicitud para restablecer la contraseña de tu cuenta en <strong>instatecno.net</strong>.<br><br>Si has sido tú, haz clic en el siguiente enlace. Si no has sido tú, puedes ignorar este mensaje de forma segura.<br><br><a>https://instatecno.net/reset/token=xyz123</a>"
                },
                explanation: "¡LEGÍTIMO! Este email es seguro. El logo es el tuyo, y tanto el remitente como el enlace apuntan al dominio real <strong>'instatecno.net'</strong>. Además, te da la opción de 'ignorar el mensaje', no te presiona."
            },
            {
                type: 'login',
                isPhishing: true,
                content: {
                    url: "https://accounts.g00gle.com/ServiceLogin",
                    // Logo Falso de Google "G00gle"
                    logoUrl: "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Cpath d='M50 20 A30 30 0 1 1 45 79.9' stroke='%234285F4' stroke-width='10' fill='none'/%3E%3Cpath d='M45 50 H70' stroke='%2334A853' stroke-width='10'/%3E%3Cpath d='M50 20 A30 30 0 0 1 55 20.1' stroke='%23FBBC05' stroke-width='10' fill='none'/%3E%3Cpath d='M55 20.1 A30 30 0 0 1 79.9 45' stroke='%23EA4335' stroke-width='10' fill='none'/%3E%3C/svg%3E",
                },
                explanation: "¡PHISHING! Un truco clásico. Han reemplazado las 'o' con ceros (<strong>'g00gle.com'</strong>). Siempre revisa la ortografía de la URL y fíjate en el logo, que es genérico y no el oficial."
            },
            {
                type: 'email',
                isPhishing: true,
                content: {
                    // Logo Falso de Microsoft (ventanas)
                    logoUrl: "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Crect x='10' y='10' width='40' height='40' fill='%23F25022'/%3E%3Crect x='50' y='10' width='40' height='40' fill='%237FBA00'/%3E%3Crect x='10' y='50' width='40' height='40' fill='%2300A4EF'/%3E%3Crect x='50' y='50' width='40' height='40' fill='%23FFB900'/%3E%3C/svg%3E",
                    from: "Equipo de Cuentas Microsoft <soporte@microsft-office.com>",
                    subject: "ALERTA: Su cuenta será suspendida",
                    body: "Estimado Usuario,<br><br>Su cuenta de Microsoft ha violado nuestros términos de servicio. Su cuenta y sus archivos se eliminarán permanentemente en <strong>48 horas</strong> si no verifica su propiedad.<br><br><a>Haga clic aquí para evitar la suspensión</a>"
                },
                explanation: "¡PHISHING! Fíjate en 3 cosas: 1. El remitente <strong>'microsft-office.com'</strong> (falta una 'o'). 2. El saludo genérico 'Estimado Usuario'. 3. La amenaza y la urgencia ('se eliminarán en 48 horas')."
            }
        ];
        
        const TOTAL_ROUNDS = scenarios.length;

        // --- Función para construir el HTML del escenario ---
        function buildScenario(data) {
            let html = '';
            switch(data.type) {
                case 'email':
                    html = `
                        <div class="email-scenario">
                            <div class="email-header">
                                <img decoding="async" src="${data.content.logoUrl}" alt="Logo" class="email-logo">
                                <div class="email-header-info">
                                    <h3>${data.content.subject}</h3>
                                    <p><span>De:</span> ${data.content.from}</p>
                                </div>
                            </div>
                            <div class="email-body">
                                <p>${data.content.body}</p>
                            </div>
                        </div>
                    `;
                    break;
                case 'login':
                    html = `
                        <div class="login-scenario-wrapper">
                            <div class="fake-browser-bar">
                                <span>${data.content.url}</span>
                            </div>
                            <div class="login-scenario">
                                <img decoding="async" src="${data.content.logoUrl}" alt="Logo" class="login-logo-img">
                                <input type="text" class="login-input" placeholder="Nombre de usuario">
                                <input type="password" class="login-input" placeholder="Contraseña">
                                <button class="login-btn">Iniciar Sesión</button>
                            </div>
                        </div>
                    `;
                    break;
                case 'whatsapp':
                    html = `
                        <div class="whatsapp-scenario">
                            <div class="whatsapp-header">
                                <img decoding="async" src="${data.content.logoUrl}" alt="Logo" class="whatsapp-sender-logo">
                                ${data.content.sender}
                            </div>
                            <div class="whatsapp-body">
                                <div class="bubble left">
                                    <p>${data.content.message}</p>
                                </div>
                            </div>
                        </div>
                    `;
                    break;
            }
            scenarioContent.innerHTML = html;
        }

        // --- Función para Iniciar el Temporizador ---
        function startTimer() {
            timeLeft = ROUND_TIME;
            timerBar.style.width = '100%';
            timerBar.style.backgroundColor = 'var(--color-primario-instatecno)';
            
            clearInterval(timerId); // Limpia cualquier timer anterior
            
            timerId = setInterval(() => {
                timeLeft--;
                let perc = (timeLeft / ROUND_TIME) * 100;
                timerBar.style.width = `${perc}%`;
                
                if (perc < 40) {
                    timerBar.style.backgroundColor = 'var(--color-error)';
                }
                
                if (timeLeft <= 0) {
                    clearInterval(timerId);
                    checkAnswer(null); // Timeout
                }
            }, 1000);
        }

        // --- Función para Comprobar la Respuesta ---
        function checkAnswer(userChoice) {
            clearInterval(timerId); // Detiene el timer
            
            const scenario = scenarios[currentRound];
            const isCorrect = (userChoice === !scenario.isPhishing);
            
            feedbackExplanation.innerHTML = scenario.explanation;
            
            if (userChoice === null) { // Si se acabó el tiempo
                feedbackTitle.textContent = "¡Tiempo Agotado!";
                feedbackTitle.className = 'incorrect';
            } else if (isCorrect) {
                feedbackTitle.textContent = "¡Correcto!";
                feedbackTitle.className = 'correct';
                score++;
            } else {
                feedbackTitle.textContent = "¡Incorrecto!";
                feedbackTitle.className = 'incorrect';
            }
            
            feedbackModal.style.display = 'flex';
        }

        // --- Función para Cargar la Siguiente Ronda ---
        function nextRound() {
            feedbackModal.style.display = 'none';
            currentRound++;
            
            if (currentRound >= TOTAL_ROUNDS) {
                endGame();
            } else {
                loadRound();
            }
        }

        // --- Función para Cargar una Ronda ---
        function loadRound() {
            scoreDisplay.textContent = `Puntos: ${score}`;
            roundDisplay.textContent = `Ronda: ${currentRound + 1} / ${TOTAL_ROUNDS}`;
            
            buildScenario(scenarios[currentRound]);
            startTimer();
        }

        // --- Función para Iniciar el Juego ---
        function startGame() {
            score = 0;
            currentRound = 0;
            startScreen.style.display = 'none';
            endScreen.style.display = 'none';
            playScreen.style.display = 'block';
            loadRound();
        }

        // --- Función para Terminar el Juego ---
        function endGame() {
            playScreen.style.display = 'none';
            endScreen.style.display = 'block';
            finalScoreDisplay.textContent = `${score} / ${TOTAL_ROUNDS}`;
        }
        
        // --- Asignar Event Listeners ---
        btnStart.addEventListener('click', startGame);
        btnRestart.addEventListener('click', startGame);
        btnNextRound.addEventListener('click', nextRound);
        
        btnLegitimo.addEventListener('click', () => checkAnswer(true));
        btnPhishing.addEventListener('click', () => checkAnswer(false));

    });
    </script>

</body>
</html>



<p></p>
<p>La entrada <a href="https://instatecno.net/minijuegos-aprendizaje/reto-de-phishing">El Código Completo: Reto de Phishing</a> se publicó primero en <a href="https://instatecno.net">InstaTecno</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://instatecno.net/minijuegos-aprendizaje/reto-de-phishing/feed</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
		<item>
		<title>Desafío de Terminal (Juego de Comandos)</title>
		<link>https://instatecno.net/minijuegos-aprendizaje/simulador-de-cmd</link>
					<comments>https://instatecno.net/minijuegos-aprendizaje/simulador-de-cmd#respond</comments>
		
		<dc:creator><![CDATA[David Sanchez]]></dc:creator>
		<pubDate>Sun, 16 Nov 2025 18:48:25 +0000</pubDate>
				<category><![CDATA[Minijuegos]]></category>
		<guid isPermaLink="false">https://instatecno.net/?p=890</guid>

					<description><![CDATA[<p>Cuando te pida Username:, escribe: instatecno (y pulsa Enter) Cuando te pida Password:, escribe: tecnoPRO123 (y pulsa Enter. ¡Respeta las [&#8230;]</p>
<p>La entrada <a href="https://instatecno.net/minijuegos-aprendizaje/simulador-de-cmd">Desafío de Terminal (Juego de Comandos)</a> se publicó primero en <a href="https://instatecno.net">InstaTecno</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>Cuando te pida <code>Username:</code>, escribe: <strong>instatecno</strong> (y pulsa Enter)</p>



<p>Cuando te pida <code>Password:</code>, escribe: <strong>tecnoPRO123</strong> (y pulsa Enter. ¡Respeta las mayúsculas!)</p>



<!DOCTYPE html>
<html lang="es">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Instatecno: Simulador de Misión</title>

<style>
    /* --- VARIABLES DE MARCA (Tus colores) --- */
    :root {
        --color-primario-instatecno: #00A8E8;
        --color-secundario-instatecno: #95C11F;
        --color-terminal-bg: #2d3436;
        --color-terminal-text: #ecf0f1;
        --color-boot-text: #bdc3c7; /* Texto de arranque */
        --color-error: #e74c3c;
        --font-mono: 'Consolas', 'Courier New', monospace;
    }

    /* --- CONTENEDOR PRINCIPAL DEL JUEGO --- */
    .terminal-container {
        font-family: var(--font-mono);
        background-color: var(--color-terminal-bg);
        border: 1px solid #000;
        border-radius: 8px;
        box-shadow: 0 10px 30px rgba(0, 0, 0, 0.3);
        width: 100%;
        max-width: 800px; /* Más ancho para más texto */
        margin: 2rem auto;
        overflow: hidden;
    }

    /* --- BARRA DE TÍTULO DE LA VENTANA --- */
    .terminal-title-bar {
        background: #4a4a4a;
        color: var(--color-terminal-text);
        padding: 10px 15px;
        font-weight: 700;
        font-family: 'Segoe UI', Roboto, sans-serif;
        font-size: 0.9em;
        border-bottom: 1px solid #000;
    }
    .terminal-title-bar span {
        color: var(--color-primario-instatecno);
        font-weight: bold;
    }

    /* --- ÁREA DE SALIDA (LOG) --- */
    #terminal-output {
        height: 450px;
        overflow-y: scroll;
        padding: 15px;
        box-sizing: border-box;
        color: var(--color-terminal-text);
        font-size: 0.95em;
        line-height: 1.6;
        white-space: pre-wrap; /* Mantiene los saltos de línea */
        word-break: break-all;
    }
    
    /* Clases para los mensajes */
    #terminal-output .log-boot { color: var(--color-boot-text); }
    #terminal-output .log-guide { color: var(--color-primario-instatecno); font-weight: bold; }
    #terminal-output .log-success { color: var(--color-secundario-instatecno); font-weight: bold; }
    #terminal-output .log-error { color: var(--color-error); font-weight: bold; }
    #terminal-output .log-command { color: #bdc3c7; }
    #terminal-output .log-explanation { 
        color: #f1c40f; /* Amarillo para explicaciones */
        background: rgba(44, 62, 80, 0.5);
        padding: 5px;
        border-left: 3px solid #f1c40f;
    }
    #terminal-output .log-prompt { color: var(--color-terminal-text); }


    /* --- LÍNEA DE ENTRADA (Input) --- */
    .terminal-input-line {
        display: flex;
        background-color: rgba(0, 0, 0, 0.2);
        padding: 10px 15px;
        border-top: 1px solid #4a4a4a;
    }
    
    #terminal-prompt {
        color: var(--color-terminal-text);
        font-weight: bold;
        margin-right: 8px;
        white-space: nowrap; /* Evita que el prompt se rompa */
    }
    
    #terminal-input {
        background: transparent;
        border: none;
        outline: none;
        color: var(--color-terminal-text);
        font-family: var(--font-mono);
        font-size: 1em;
        flex-grow: 1; /* Ocupa el espacio restante */
        caret-color: var(--color-terminal-text); /* Color del cursor parpadeante */
    }
</style>
</head>
<body>

    <div class="terminal-container" id="game-terminal">
        <div class="terminal-title-bar">
            <span>Instatecno.net</span> :: Simulador de Misión
        </div>
        
        <div id="terminal-output"></div>
        
        <div class="terminal-input-line">
            <span id="terminal-prompt">></span>
            <input type="text" id="terminal-input" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false">
        </div>
    </div>

    <script>
    document.addEventListener('DOMContentLoaded', () => {
        
        // --- DOM Elements ---
        const terminalContainer = document.getElementById('game-terminal');
        const output = document.getElementById('terminal-output');
        const input = document.getElementById('terminal-input');
        const prompt = document.getElementById('terminal-prompt');

        // --- Game State ---
        let gameState = {
            phase: 'booting', // booting, login_user, login_pass, mission1, mission2_briefing, mission2_ssh_pass, mission2_server
            level_m1: 0,
            level_m2: 0,
            username: '',
            currentPrompt: 'C:\\User\\InstaTecno>'
        };
        
        // --- Misión 1: Eliminar Virus (Windows) ---
        const mission1_levels = [
            {
                instruction: "[ASISTENTE]: Bienvenido, Técnico. Tenemos un problema. Se ha detectado un archivo sospechoso en este sistema. Tu misión es encontrarlo y eliminarlo.\n\nPrimero, veamos qué archivos hay en tu carpeta actual. Escribe: ls",
                command: "ls",
                success: "Documentos/\nDescargas/\nSistema/\nnotas.txt\nsospechoso.exe",
                explanation: "¡Buen trabajo! `ls` (list) es el comando para 'listar' el contenido de un directorio. Como puedes ver, ahí está... 'sospechoso.exe'."
            },
            {
                instruction: "[ASISTENTE]: No podemos eliminarlo desde aquí. Parece estar 'anclado' al directorio del sistema.\nDebemos movernos a la carpeta 'Sistema'. Escribe: cd Sistema",
                command: "cd Sistema",
                success: "Directorio cambiado a 'Sistema'.",
                newPrompt: "C:\\User\\InstaTecno\\Sistema>",
                explanation: "`cd` (change directory) es el comando para moverte entre carpetas. Acabas de 'entrar' en la carpeta 'Sistema'."
            },
            {
                instruction: "[ASISTENTE]: Estamos dentro. Antes de borrar el archivo, debemos quitarle los permisos de 'solo lectura' que lo protegen.\nEscribe: chmod -r sospechoso.exe",
                command: "chmod -r sospechoso.exe",
                success: "Permisos de 'sospechoso.exe' actualizados. (Protección de escritura eliminada)",
                explanation: "`chmod` (change mode) se usa para cambiar los permisos de un archivo. El flag '-r' le ha quitado la protección de 'solo lectura'."
            },
            {
                instruction: "[ASISTENTE]: ¡Perfecto! El archivo es vulnerable. Es la hora de la verdad.\nEscribe `rm sospechoso.exe` para eliminarlo.",
                command: "rm sospechoso.exe",
                success: "Archivo 'sospechoso.exe' eliminado.",
                explanation: "`rm` (remove) es el comando para borrar archivos. Es muy potente, ¡así que siempre hay que usarlo con cuidado!"
            }
        ];
        
        // --- Misión 2: Parchear Web (Linux Server) ---
        const mission2_levels = [
            {
                instruction: "[ASISTENTE]: Estoy dentro. Esta es la raíz del servidor. La web está en '/var/www/html'.\nNavega hasta la carpeta de minijuegos. Escribe: cd /var/www/html/minijuegos",
                command: "cd /var/www/html/minijuegos",
                success: "Directorio cambiado a '/var/www/html/minijuegos'.",
                newPrompt: "admin@instatecno:/var/www/html/minijuegos$",
                explanation: "¡Genial! Acabas de usar una ruta absoluta. En Linux, todo empieza desde la raíz '/'."
            },
            {
                instruction: "[ASISTENTE]: OK, lista el contenido para ver qué minijuegos tenemos.",
                command: "ls",
                success: "ensamblador/\npuzzle_tecno/\nterminal_quest/",
                explanation: "`ls` funciona igual aquí. ¡Ahí está! El bug está en la carpeta 'ensamblador'."
            },
            {
                instruction: "[ASISTENTE]: Entra en esa carpeta.\nEscribe: cd ensamblador",
                command: "cd ensamblador",
                success: "Directorio cambiado a '/var/www/html/minijuegos/ensamblador'.",
                newPrompt: "admin@instatecno:/.../ensamblador$",
                explanation: "Estamos en el directorio del juego."
            },
            {
                instruction: "[ASISTENTE]: Sube un parche de emergencia. Vamos a ver los archivos y sus detalles.\nEscribe `ls -l` (es L minúscula, no 1).",
                command: "ls -l",
                success: "-rw-r--r-- 1 admin admin 15720 Oct 28 10:30 ensamblador.js\n-rw-r--r-- 1 admin admin  15990 Oct 28 11:05 ensamblador.v2.js.patch\n-rw-r--r-- 1 admin admin   2048 Oct 28 09:15 index.html",
                explanation: "`ls -l` (list long) te da una lista detallada, con permisos, propietario y tamaño. 'ensamblador.js' es el archivo roto, y 'ensamblador.v2.js.patch' es el parche."
            },
            {
                instruction: "[ASISTENTE]: ¡Ahí está! El parche está listo. Solo tenemos que reemplazar el archivo viejo (roto) por el nuevo (parche).\nEscribe: mv ensamblador.v2.js.patch ensamblador.js",
                command: "mv ensamblador.v2.js.patch ensamblador.js",
                success: "¡Hecho! Archivo renombrado. El parche está aplicado.",
                explanation: "`mv` (move) se usa para mover o renombrar archivos. Acabas de 'renombrar' el parche para que ocupe el lugar del archivo roto. ¡Has arreglado el bug!"
            },
            {
                instruction: "[ASISTENTE]: ¡Misión cumplida! El minijuego vuelve a funcionar. Salgamos del servidor.\nEscribe: exit",
                command: "exit",
                success: "Conexión con instatecno.net cerrada.",
                newPrompt: "C:\\User\\InstaTecno\\Sistema>", // Vuelve al prompt de Windows
                explanation: "`exit` cierra la sesión actual. Has vuelto a tu terminal local."
            }
        ];
        
        // --- Credenciales de Login ---
        const LOGIN_USER = "instatecno";
        const LOGIN_PASS = "tecnoPRO123";
        
        // ==========================================================
        //  ¡AQUÍ ESTÁ EL CAMBIO!
        //  Ambas contraseñas son ahora iguales.
        // ==========================================================
        const SERVER_PASS = "tecnoPRO123";

        // --- Función para imprimir en la terminal ---
        function printToTerminal(message, className = '') {
            const p = document.createElement('p');
            // Reemplaza \n con <br> para saltos de línea si es necesario
            p.innerHTML = message.replace(/\n/g, '<br>');
            if (className) {
                p.className = className;
            }
            output.appendChild(p);
            // Auto-scroll al final
            output.scrollTop = output.scrollHeight;
        }
        
        // --- Función para imprimir línea a línea (Boot y Explicaciones) ---
        async function typeLines(lines, className, delay = 50) {
            for (const line of lines) {
                printToTerminal(line, className);
                // Pausa entre líneas
                await new Promise(res => setTimeout(res, delay));
            }
        }

        // --- FASE 1: Secuencia de Arranque ---
        async function bootSequence() {
            input.disabled = true;
            prompt.style.display = 'none';
            
            const bootLines = [
                "Iniciando InstaTecno OS v1.3...",
                "RAM Check: 32768MB [OK]",
                "CPU: Intel Core i9 @ 3.6GHz [OK]",
                "Verificando integridad del sistema... [OK]",
                "Cargando kernel... [OK]",
                "Montando discos... [OK]",
                "Iniciando servicios de red... [OK]",
                "Sistema listo.",
                "\nBienvenido al terminal seguro de InstaTecno.",
                "Se requiere autenticación."
            ];
            
            await typeLines(bootLines, 'log-boot', 100);
            startLogin();
        }
        
        // --- FASE 2: Inicio de Login ---
        function startLogin() {
            prompt.style.display = 'block';
            gameState.phase = 'login_user';
            prompt.textContent = "Username:";
            input.type = 'text';
            input.disabled = false; // Asegurarse de que esté activado
            input.focus();
        }

        // --- FASE 3: Inicio de Misión 1 ---
        async function startMission1() {
            gameState.phase = 'mission1';
            gameState.level_m1 = 0;
            prompt.textContent = gameState.currentPrompt;
            await typeLines(["\nAutenticación correcta. Acceso concedido.", "Cargando Asistente de Misión..."], 'log-success', 100);
            
            input.disabled = false;
            displayNextTask();
        }
        
        // --- FASE 4: Inicio de Misión 2 (Briefing) ---
        async function startMission2Briefing() {
            gameState.phase = 'mission2_briefing';
            await typeLines([
                "\n[ASISTENTE]: ¡Buen trabajo con ese virus! Pero no hay descanso.",
                "Acaba de entrar un ticket de prioridad ALTA.",
                "SITIO: instatecno.net",
                "PROBLEMA: El nuevo 'Minijuego de Ensamblaje' tiene un bug y está caido.",
                "TAREA: Debes conectarte al servidor y 'parchear' el archivo .js.",
                "\nVamos a conectarnos al servidor web. Escribe el comando de conexión:\nssh admin@instatecno.net"
            ], 'log-guide', 100);
            
            input.disabled = false;
            input.focus();
        }
        
        // --- FASE 5: Inicio de Misión 2 (En Servidor) ---
        async function startServerMission() {
            gameState.phase = 'mission2_server';
            gameState.level_m2 = 0;
            gameState.currentPrompt = "admin@instatecno:~ $"; // Prompt de Linux
            prompt.textContent = gameState.currentPrompt;
            
            await typeLines(["\n¡Conexión establecida! Bienvenido al servidor de instatecno.net."], 'log-success', 100);
            
            input.disabled = false;
            displayNextTask();
        }

        // --- Mostrar Siguiente Tarea (para ambas misiones) ---
        function displayNextTask() {
            if (gameState.phase === 'mission1') {
                if (gameState.level_m1 >= mission1_levels.length) {
                    // --- Fin de Misión 1 -> Inicia Misión 2 ---
                    input.disabled = true;
                    startMission2Briefing();
                } else {
                    const level = mission1_levels[gameState.level_m1];
                    printToTerminal("\n" + level.instruction, 'log-guide');
                    input.focus();
                }
            } 
            else if (gameState.phase === 'mission2_server') {
                 if (gameState.level_m2 >= mission2_levels.length) {
                    // --- Fin del Juego ---
                    printToTerminal("\n¡TODAS LAS MISIONES COMPLETAS!", 'log-success');
                    printToTerminal("Has limpiado el PC y arreglado el bug de instatecno.net.", 'log-success');
                    printToTerminal("¡Eres una leyenda, técnico!", 'log-guide');
                    input.disabled = true; // Desactiva el input
                    prompt.style.display = 'none';
                } else {
                    const level = mission2_levels[gameState.level_m2];
                    printToTerminal("\n" + level.instruction, 'log-guide');
                    input.focus();
                }
            }
        }
        
        // --- Manejador de Input Principal (cuando el usuario pulsa Enter) ---
        async function handleInput(e) {
            if (e.key !== 'Enter') return;
            
            const userInput = input.value.trim();
            if (userInput === "") return;
            
            // Oculta el input temporalmente (para modo password)
            if (gameState.phase === 'login_pass' || gameState.phase === 'mission2_ssh_pass') {
                printToTerminal(prompt.textContent + " " + "********", 'log-command');
            } else {
                printToTerminal(prompt.textContent + " " + userInput, 'log-command');
            }
            
            input.value = ''; // Limpia el input

            // --- Lógica de Fases ---
            switch (gameState.phase) {
                
                // --- FASE LOGIN (Usuario) ---
                case 'login_user':
                    gameState.username = userInput;
                    prompt.textContent = "Password:";
                    input.type = 'password';
                    gameState.phase = 'login_pass';
                    break;
                
                // --- FASE LOGIN (Contraseña) ---
                case 'login_pass':
                    input.type = 'text'; // Vuelve a modo texto
                    if (gameState.username.toLowerCase() === LOGIN_USER.toLowerCase() && userInput === LOGIN_PASS) {
                        input.disabled = true; // Desactiva MIENTRAS carga la misión
                        await startMission1();
                    } else {
                        printToTerminal("\nAcceso Denegado. Credenciales incorrectas.", 'log-error');
                        await new Promise(res => setTimeout(res, 500));
                        startLogin(); // Reinicia el login
                    }
                    break;
                
                // --- FASE MISIÓN 1 ---
                case 'mission1':
                    const level1 = mission1_levels[gameState.level_m1];
                    if (userInput.toLowerCase() === 'clear') {
                        output.innerHTML = '';
                        printToTerminal("Pantalla limpiada.", 'log-success');
                        displayNextTask();
                        break;
                    }
                    if (userInput.toLowerCase() === level1.command.toLowerCase()) {
                        printToTerminal(level1.success, 'log-success');
                        await new Promise(res => setTimeout(res, 500));
                        printToTerminal(level1.explanation, 'log-explanation');
                        if (level1.newPrompt) {
                            gameState.currentPrompt = level1.newPrompt;
                            prompt.textContent = gameState.currentPrompt;
                        }
                        gameState.level_m1++;
                        displayNextTask();
                    } else {
                        printToTerminal(`'${userInput}' no es el comando esperado. Revisa la instrucción.`, 'log-error');
                    }
                    break;
                
                // --- FASE MISIÓN 2 (Briefing) ---
                case 'mission2_briefing':
                    if (userInput.toLowerCase() === 'ssh admin@instatecno.net') {
                        gameState.phase = 'mission2_ssh_pass';
                        prompt.textContent = "Password de 'admin@instatecno.net':";
                        input.type = 'password';
                    } else {
                        printToTerminal("Comando incorrecto. Debes conectarte al servidor.", 'log-error');
                    }
                    break;
                    
                // --- FASE MISIÓN 2 (Password Servidor) ---
                case 'mission2_ssh_pass':
                    input.type = 'text';
                    if (userInput === SERVER_PASS) {
                        input.disabled = true;
                        await startServerMission();
                    } else {
                        printToTerminal("\nAcceso Denegado. Contraseña del servidor incorrecta.", 'log-error');
                        await new Promise(res => setTimeout(res, 500));
                        // Vuelve al briefing para reintentar la conexión
                        input.disabled = true;
                        startMission2Briefing();
                    }
                    break;
                    
                // --- FASE MISIÓN 2 (En Servidor) ---
                case 'mission2_server':
                    const level2 = mission2_levels[gameState.level_m2];
                    if (userInput.toLowerCase() === 'clear') {
                        output.innerHTML = '';
                        printToTerminal("Pantalla limpiada.", 'log-success');
                        displayNextTask();
                        break;
                    }
                    
                    // Comprobación de comando
                    if (userInput.toLowerCase() === level2.command.toLowerCase()) {
                        printToTerminal(level2.success, 'log-success');
                        await new Promise(res => setTimeout(res, 500));
                        printToTerminal(level2.explanation, 'log-explanation');
                        
                        if (level2.newPrompt) {
                            gameState.currentPrompt = level2.newPrompt;
                            prompt.textContent = gameState.currentPrompt;
                        }
                        
                        // Si el comando es 'exit', vuelve a la misión 1 (ya completada)
                        if(level2.command === 'exit') {
                            gameState.phase = 'mission1';
                        }
                        
                        gameState.level_m2++;
                        displayNextTask(); // Llama a la siguiente tarea
                    } else {
                        printToTerminal(`'${userInput}' no es el comando esperado. Revisa la instrucción.`, 'log-error');
                    }
                    break;
            }
        }
        
        // --- Event Listeners ---
        
        // Enfoca el input cuando se hace clic en cualquier parte de la terminal
        terminalContainer.addEventListener('click', () => {
            if (!input.disabled) {
                input.focus();
            }
        });

        // Escucha la tecla Enter en el input
        input.addEventListener('keydown', handleInput);

        // --- Inicia el juego con la secuencia de arranque ---
        bootSequence();
    });
    </script>

</body>
</html>



<p>Ahora que sabes practica haciendo lo que quieras en esta terminal tanto de Windows y de Linux</p>



<p> </p>



<style>
    /* Estilos encapsulados para no romper tu tema de WordPress */
    #wp-terminal-wrapper {
        --bg-color: #0c0c0c;
        --text-color: #0f0;
        --prompt-color: #00ff00;
        --dir-color: #5555ff;
        --cmd-color: #ffffff;
        --error-color: #ff3333;
        --font-main: 'Courier New', Courier, monospace;
        
        background-color: var(--bg-color);
        color: var(--text-color);
        font-family: var(--font-main);
        font-size: 15px;
        /* Altura fija para que se vea bien dentro del post */
        height: 500px; 
        width: 100%;
        overflow-y: auto;
        overflow-x: hidden;
        padding: 20px;
        box-sizing: border-box;
        border: 2px solid #333;
        border-radius: 5px;
        position: relative;
        text-align: left;
        line-height: 1.4;
    }

    #wp-terminal-wrapper .output-line {
        margin-bottom: 4px;
        white-space: pre-wrap;
        word-break: break-all;
    }

    #wp-terminal-wrapper .prompt-line {
        display: flex;
        align-items: center;
        margin-top: 10px;
    }

    #wp-terminal-wrapper .prompt-text {
        color: var(--prompt-color);
        margin-right: 8px;
        font-weight: bold;
        white-space: nowrap;
    }

    /* Input invisible pero funcional */
    #wp-terminal-wrapper input.cmd-input {
        background: transparent !important;
        border: none !important;
        box-shadow: none !important;
        color: var(--cmd-color) !important;
        font-family: var(--font-main) !important;
        font-size: 15px !important;
        flex-grow: 1;
        outline: none !important;
        padding: 0 !important;
        margin: 0 !important;
        height: auto !important;
    }

    /* Colores de sintaxis */
    #wp-terminal-wrapper .is-dir { color: var(--dir-color); font-weight: bold; }
    #wp-terminal-wrapper .is-file { color: var(--text-color); }
    #wp-terminal-wrapper .error-msg { color: var(--error-color); }

    /* Scrollbar estilo hacker */
    #wp-terminal-wrapper::-webkit-scrollbar { width: 10px; }
    #wp-terminal-wrapper::-webkit-scrollbar-track { background: #111; }
    #wp-terminal-wrapper::-webkit-scrollbar-thumb { background: #333; border-radius: 4px; }
</style>

<div id="wp-terminal-wrapper">
    <div class="output-line">Universal Web Shell v2.0 (WP Edition)</div>
    <div class="output-line">Escribe &#8216;help&#8217; para ver comandos.</div>
    <div class="output-line">&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;</div>
    <div id="wp-term-history"></div>
    
    <div class="prompt-line">
        <span id="wp-term-prompt" class="prompt-text">root@web:~$</span>
        <input type="text" class="cmd-input" id="wp-cmd-input" autocomplete="off" spellcheck="false">
    </div>
</div>

<script>
(function() {
    // --- SISTEMA DE ARCHIVOS VIRTUAL ---
    const fileSystem = {
        root: {
            type: 'dir',
            children: {
                'home': {
                    type: 'dir',
                    children: {
                        'visitante': {
                            type: 'dir',
                            children: {
                                'notas.txt': { type: 'file', content: 'Gracias por visitar mi web.' }
                            }
                        }
                    }
                },
                'proyectos': { type: 'dir', children: {} },
                'readme.txt': { type: 'file', content: 'Terminal Interactiva en WordPress.' }
            }
        }
    };

    // --- VARIABLES DE ESTADO ---
    let currentPath = []; 
    let currentDir = fileSystem.root; 
    let commandHistory = [];
    let historyIndex = -1;

    // --- REFERENCIAS AL DOM ---
    const wrapper = document.getElementById('wp-terminal-wrapper');
    const input = document.getElementById('wp-cmd-input');
    const historyDiv = document.getElementById('wp-term-history');
    const promptSpan = document.getElementById('wp-term-prompt');

    if (!wrapper || !input) return; // Seguridad por si el DOM no carga

    // --- FUNCIONES DE UTILIDAD ---
    function updatePrompt() {
        const pathStr = '/' + currentPath.join('/');
        promptSpan.innerText = `root@web:${pathStr}$`;
    }

    function print(text, className = '') {
        const div = document.createElement('div');
        div.className = 'output-line ' + className;
        // Reemplazar saltos de línea para HTML
        div.innerHTML = text.replace(/\n/g, '<br>');
        historyDiv.appendChild(div);
        wrapper.scrollTop = wrapper.scrollHeight;
    }

    function getDirFromPath(pathArray) {
        let dir = fileSystem.root;
        for (const part of pathArray) {
            if (dir.children && dir.children[part] && dir.children[part].type === 'dir') {
                dir = dir.children[part];
            } else {
                return null;
            }
        }
        return dir;
    }

    // --- COMANDOS ---
    const commands = {
        'help': () => {
            print("COMANDOS:");
            print("  ls, dir, cd [carpeta], pwd");
            print("  cat [archivo], touch [archivo], rm [archivo]");
            print("  mkdir [nombre], clear, echo [texto]");
        },
        'clear': () => historyDiv.innerHTML = '',
        'cls': () => historyDiv.innerHTML = '',
        'ls': listDir,
        'dir': listDir,
        'pwd': () => print('/' + currentPath.join('/')),
        'cd': (args) => {
            if (!args[0]) return;
            if (args[0] === '..') {
                if (currentPath.length > 0) {
                    currentPath.pop();
                    currentDir = getDirFromPath(currentPath);
                    updatePrompt();
                }
                return;
            }
            if (args[0] === '/') {
                currentPath = [];
                currentDir = fileSystem.root;
                updatePrompt();
                return;
            }
            const target = args[0];
            if (currentDir.children[target] && currentDir.children[target].type === 'dir') {
                currentPath.push(target);
                currentDir = currentDir.children[target];
                updatePrompt();
            } else {
                print(`cd: ${target}: No existe`, 'error-msg');
            }
        },
        'touch': (args) => {
            if(!args[0]) return print("Falta nombre", 'error-msg');
            if(currentDir.children[args[0]]) return print("Ya existe", 'error-msg');
            currentDir.children[args[0]] = { type: 'file', content: '' };
            print(`Creado: ${args[0]}`);
        },
        'mkdir': (args) => {
            if(!args[0]) return print("Falta nombre", 'error-msg');
            if(currentDir.children[args[0]]) return print("Ya existe", 'error-msg');
            currentDir.children[args[0]] = { type: 'dir', children: {} };
            print(`Directorio creado: ${args[0]}`);
        },
        'cat': (args) => {
            if(!args[0]) return print("Falta archivo", 'error-msg');
            const item = currentDir.children[args[0]];
            if(!item) return print("No existe", 'error-msg');
            if(item.type === 'dir') return print("Es un directorio", 'error-msg');
            print(item.content);
        },
        'rm': (args) => {
            if(!args[0]) return print("Falta nombre", 'error-msg');
            if(!currentDir.children[args[0]]) return print("No existe", 'error-msg');
            delete currentDir.children[args[0]];
            print("Eliminado.");
        },
        'echo': (args) => print(args.join(' '))
    };

    function listDir() {
        const contents = Object.keys(currentDir.children);
        if (contents.length === 0) {
            print("(Vacío)");
            return;
        }
        let outputHtml = '';
        contents.forEach(name => {
            const item = currentDir.children[name];
            const style = item.type === 'dir' ? 'is-dir' : 'is-file';
            const suffix = item.type === 'dir' ? '/' : '';
            outputHtml += `<span class="${style}">${name}${suffix}</span>  `;
        });
        print(outputHtml);
    }

    // --- EVENTOS ---
    input.addEventListener('keydown', function(e) {
        if (e.key === 'Enter') {
            const rawInput = this.value.trim();
            if (rawInput) {
                commandHistory.push(rawInput);
                historyIndex = commandHistory.length;
                print(`${promptSpan.innerText} ${rawInput}`);
                
                const parts = rawInput.split(' ');
                const cmd = parts[0].toLowerCase();
                const args = parts.slice(1);

                if (commands[cmd]) {
                    commands[cmd](args);
                } else {
                    print(`Comando desconocido: ${cmd}`, 'error-msg');
                }
            } else {
                print(promptSpan.innerText);
            }
            this.value = '';
            wrapper.scrollTop = wrapper.scrollHeight;
        } else if (e.key === 'ArrowUp') {
            e.preventDefault();
            if (historyIndex > 0) {
                historyIndex--;
                this.value = commandHistory[historyIndex];
            }
        } else if (e.key === 'ArrowDown') {
            e.preventDefault();
            if (historyIndex < commandHistory.length - 1) {
                historyIndex++;
                this.value = commandHistory[historyIndex];
            } else {
                historyIndex = commandHistory.length;
                this.value = '';
            }
        }
    });

    // Mantener foco en el input al hacer clic en la terminal
    wrapper.addEventListener('click', () => {
        input.focus();
    });

    // Iniciar
    updatePrompt();

})(); // Fin del encapsulamiento
</script>



<p></p>
<p>La entrada <a href="https://instatecno.net/minijuegos-aprendizaje/simulador-de-cmd">Desafío de Terminal (Juego de Comandos)</a> se publicó primero en <a href="https://instatecno.net">InstaTecno</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://instatecno.net/minijuegos-aprendizaje/simulador-de-cmd/feed</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>

<!--
Performance optimized by W3 Total Cache. Learn more: https://www.boldgrid.com/w3-total-cache/?utm_source=w3tc&utm_medium=footer_comment&utm_campaign=free_plugin

Almacenamiento en caché de páginas con Disk: Enhanced 
Minified using Disk

Served from: instatecno.net @ 2026-05-17 14:37:41 by W3 Total Cache
-->