{"id":1645,"date":"2026-05-13T23:37:00","date_gmt":"2026-05-14T04:37:00","guid":{"rendered":"https:\/\/masterwok.co\/?page_id=1645"},"modified":"2026-05-13T23:43:43","modified_gmt":"2026-05-14T04:43:43","slug":"juego-master-wok","status":"publish","type":"page","link":"https:\/\/masterwok.co\/index.php\/juego-master-wok\/","title":{"rendered":"Juego Master"},"content":{"rendered":"\t\t<div data-elementor-type=\"wp-page\" data-elementor-id=\"1645\" class=\"elementor elementor-1645\">\n\t\t\t\t<div class=\"elementor-element elementor-element-042bc48 e-flex e-con-boxed e-con e-parent\" data-id=\"042bc48\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-55f57e5 elementor-widget elementor-widget-html\" data-id=\"55f57e5\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<!DOCTYPE html>\r\n<html lang=\"es\">\r\n<head>\r\n  <meta charset=\"UTF-8\" \/>\r\n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" \/>\r\n  <title>Reto Master Wok - P\u00e1jaro Volador<\/title>\r\n  <style>\r\n    * { box-sizing: border-box; margin: 0; padding: 0; font-family: Arial, Helvetica, sans-serif; }\r\n\r\n    body {\r\n      min-height: 100vh;\r\n      background: radial-gradient(circle at top, #202020, #060606 68%);\r\n      color: #fff;\r\n      padding: 18px;\r\n    }\r\n\r\n    .app { max-width: 1240px; margin: auto; }\r\n\r\n    .header {\r\n      display: flex;\r\n      justify-content: space-between;\r\n      align-items: center;\r\n      gap: 18px;\r\n      flex-wrap: wrap;\r\n      margin-bottom: 20px;\r\n    }\r\n\r\n    .brand { display: flex; align-items: center; gap: 14px; }\r\n\r\n    .logo {\r\n      width: 58px;\r\n      height: 58px;\r\n      border-radius: 18px;\r\n      background: linear-gradient(135deg, #ffce00, #ff4d00);\r\n      display: grid;\r\n      place-items: center;\r\n      font-weight: 900;\r\n      color: #111;\r\n      font-size: 25px;\r\n      box-shadow: 0 12px 35px rgba(255, 100, 0, .3);\r\n    }\r\n\r\n    h1 { font-size: 27px; line-height: 1.1; }\r\n    .brand p { color: #cfcfcf; margin-top: 4px; }\r\n\r\n    .badge {\r\n      background: rgba(255,255,255,.08);\r\n      border: 1px solid rgba(255,255,255,.13);\r\n      padding: 12px 16px;\r\n      border-radius: 999px;\r\n      color: #ffce00;\r\n      font-weight: 800;\r\n    }\r\n\r\n    .grid {\r\n      display: grid;\r\n      grid-template-columns: 1.25fr .75fr;\r\n      gap: 18px;\r\n    }\r\n\r\n    .card {\r\n      background: rgba(255,255,255,.075);\r\n      border: 1px solid rgba(255,255,255,.12);\r\n      border-radius: 26px;\r\n      padding: 20px;\r\n      box-shadow: 0 18px 45px rgba(0,0,0,.35);\r\n      backdrop-filter: blur(10px);\r\n    }\r\n\r\n    .top-section {\r\n      display: grid;\r\n      grid-template-columns: 1fr 250px;\r\n      gap: 18px;\r\n      align-items: stretch;\r\n    }\r\n\r\n    .intro h2 {\r\n      font-size: 36px;\r\n      line-height: 1.08;\r\n      margin-bottom: 12px;\r\n    }\r\n\r\n    .intro h2 span { color: #ffce00; }\r\n    .intro p { color: #d7d7d7; line-height: 1.55; margin-bottom: 14px; }\r\n\r\n    input, select, textarea {\r\n      width: 100%;\r\n      border: 1px solid rgba(255,255,255,.15);\r\n      background: rgba(0,0,0,.34);\r\n      color: #fff;\r\n      padding: 12px 13px;\r\n      border-radius: 14px;\r\n      font-size: 14px;\r\n      outline: none;\r\n    }\r\n\r\n    input::placeholder, textarea::placeholder { color: #9c9c9c; }\r\n\r\n    button {\r\n      border: none;\r\n      background: linear-gradient(135deg, #ffce00, #ff6a00);\r\n      color: #111;\r\n      font-weight: 900;\r\n      padding: 12px 15px;\r\n      border-radius: 14px;\r\n      cursor: pointer;\r\n      font-size: 14px;\r\n      box-shadow: 0 12px 24px rgba(255, 112, 0, .25);\r\n    }\r\n\r\n    button.secondary {\r\n      background: rgba(255,255,255,.1);\r\n      color: #fff;\r\n      border: 1px solid rgba(255,255,255,.12);\r\n      box-shadow: none;\r\n    }\r\n\r\n    button.danger {\r\n      background: rgba(255, 60, 60, .18);\r\n      color: #fff;\r\n      border: 1px solid rgba(255, 60, 60, .35);\r\n      box-shadow: none;\r\n    }\r\n\r\n    .form { display: grid; gap: 10px; max-width: 430px; }\r\n\r\n    .scanner-panel {\r\n      margin-top: 12px;\r\n      max-width: 430px;\r\n      display: grid;\r\n      gap: 10px;\r\n      background: rgba(0,0,0,.25);\r\n      border: 1px solid rgba(255,255,255,.12);\r\n      border-radius: 18px;\r\n      padding: 12px;\r\n    }\r\n\r\n    .scanner-head {\r\n      display: flex;\r\n      justify-content: space-between;\r\n      align-items: center;\r\n      gap: 10px;\r\n    }\r\n\r\n    .small-btn { padding: 8px 10px; font-size: 12px; border-radius: 11px; }\r\n\r\n    #cameraPreview {\r\n      width: 100%;\r\n      height: 210px;\r\n      background: #111;\r\n      border-radius: 16px;\r\n      object-fit: cover;\r\n      border: 1px solid rgba(255,255,255,.12);\r\n    }\r\n\r\n    .manual-code-row {\r\n      display: grid;\r\n      grid-template-columns: 1fr auto;\r\n      gap: 8px;\r\n    }\r\n\r\n    .prize-card {\r\n      background: linear-gradient(180deg, rgba(255,206,0,.16), rgba(255,92,0,.08));\r\n      border: 1px solid rgba(255,206,0,.25);\r\n      border-radius: 24px;\r\n      padding: 15px;\r\n      text-align: center;\r\n    }\r\n\r\n    .prize-card img {\r\n      width: 100%;\r\n      height: 145px;\r\n      object-fit: cover;\r\n      border-radius: 19px;\r\n      margin-bottom: 12px;\r\n      background: #222;\r\n    }\r\n\r\n    .prize-card small { color: #ffce00; font-weight: 900; letter-spacing: .08em; }\r\n    .prize-card h3 { margin-top: 6px; font-size: 22px; }\r\n    .prize-card p { color: #ddd; font-size: 13px; margin-top: 7px; line-height: 1.35; }\r\n\r\n    .game-wrap { margin-top: 18px; }\r\n\r\n    .game-header {\r\n      display: flex;\r\n      justify-content: space-between;\r\n      align-items: center;\r\n      gap: 10px;\r\n      flex-wrap: wrap;\r\n      margin-bottom: 12px;\r\n    }\r\n\r\n    .game-stats { display: flex; gap: 10px; flex-wrap: wrap; }\r\n\r\n    .pill {\r\n      background: rgba(0,0,0,.28);\r\n      border: 1px solid rgba(255,255,255,.1);\r\n      border-radius: 999px;\r\n      padding: 9px 12px;\r\n      color: #ffce00;\r\n      font-weight: 800;\r\n      font-size: 14px;\r\n    }\r\n\r\n    canvas {\r\n      width: 100%;\r\n      height: 430px;\r\n      display: block;\r\n      background: linear-gradient(180deg, #70cfff 0%, #c6f2ff 55%, #6ed36a 100%);\r\n      border-radius: 24px;\r\n      border: 1px solid rgba(255,255,255,.16);\r\n      cursor: pointer;\r\n      touch-action: manipulation;\r\n    }\r\n\r\n    .game-controls { display: flex; gap: 10px; flex-wrap: wrap; margin-top: 12px; }\r\n    .side { display: grid; gap: 18px; }\r\n    .ranking h3, .admin h3 { font-size: 22px; margin-bottom: 14px; }\r\n    .rank-list { display: grid; gap: 9px; }\r\n\r\n    .rank-item {\r\n      display: grid;\r\n      grid-template-columns: 38px 1fr auto;\r\n      align-items: center;\r\n      gap: 10px;\r\n      background: rgba(0,0,0,.25);\r\n      border: 1px solid rgba(255,255,255,.08);\r\n      padding: 12px;\r\n      border-radius: 17px;\r\n    }\r\n\r\n    .position {\r\n      width: 38px;\r\n      height: 38px;\r\n      border-radius: 14px;\r\n      display: grid;\r\n      place-items: center;\r\n      background: rgba(255,206,0,.14);\r\n      color: #ffce00;\r\n      font-weight: 900;\r\n    }\r\n\r\n    .rank-item strong { display: block; margin-bottom: 3px; }\r\n    .rank-item span { color: #bdbdbd; font-size: 12px; }\r\n    .score { color: #ffce00; font-weight: 900; }\r\n\r\n    .admin-login {\r\n      display: grid;\r\n      grid-template-columns: 1fr 1fr auto;\r\n      gap: 8px;\r\n      align-items: center;\r\n    }\r\n\r\n    .admin-login input { padding: 10px 11px; font-size: 13px; }\r\n    .admin-login button { padding: 10px 12px; font-size: 13px; }\r\n\r\n    .admin-panel { display: grid; gap: 14px; }\r\n\r\n    .admin-tabs {\r\n      display: flex;\r\n      gap: 8px;\r\n      flex-wrap: wrap;\r\n      margin-bottom: 2px;\r\n    }\r\n\r\n    .admin-tab {\r\n      background: rgba(255,255,255,.08);\r\n      border: 1px solid rgba(255,255,255,.12);\r\n      color: #fff;\r\n      box-shadow: none;\r\n      padding: 9px 11px;\r\n      font-size: 13px;\r\n    }\r\n\r\n    .admin-tab.active { background: linear-gradient(135deg, #ffce00, #ff6a00); color: #111; }\r\n    .admin-section { display: none; gap: 10px; }\r\n    .admin-section.active { display: grid; }\r\n    .admin-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }\r\n    .admin-actions { display: flex; flex-wrap: wrap; gap: 9px; margin-top: 2px; }\r\n\r\n    .mini-stats {\r\n      display: grid;\r\n      grid-template-columns: repeat(3, 1fr);\r\n      gap: 9px;\r\n      margin-top: 8px;\r\n    }\r\n\r\n    .stat {\r\n      background: rgba(0,0,0,.25);\r\n      border: 1px solid rgba(255,255,255,.08);\r\n      border-radius: 17px;\r\n      padding: 12px;\r\n      text-align: center;\r\n    }\r\n\r\n    .stat strong { display: block; color: #ffce00; font-size: 22px; }\r\n    .stat span { color: #bdbdbd; font-size: 12px; }\r\n    .toast { min-height: 22px; margin-top: 9px; color: #ffce00; font-weight: 800; }\r\n    .hidden { display: none !important; }\r\n    .small-note { color: #d3d3d3; font-size: 13px; line-height: 1.45; margin-top: 8px; }\r\n\r\n    .prize-options {\r\n      display: grid;\r\n      grid-template-columns: repeat(3, 1fr);\r\n      gap: 9px;\r\n    }\r\n\r\n    .prize-option {\r\n      background: rgba(0,0,0,.24);\r\n      border: 1px solid rgba(255,255,255,.1);\r\n      border-radius: 16px;\r\n      overflow: hidden;\r\n      cursor: pointer;\r\n      transition: transform .15s, border-color .15s;\r\n    }\r\n\r\n    .prize-option:hover { transform: translateY(-2px); border-color: rgba(255,206,0,.6); }\r\n    .prize-option.selected { border-color: #ffce00; box-shadow: 0 0 0 2px rgba(255,206,0,.18); }\r\n\r\n    .prize-option img {\r\n      width: 100%;\r\n      height: 70px;\r\n      object-fit: cover;\r\n      display: block;\r\n    }\r\n\r\n    .prize-option span {\r\n      display: block;\r\n      padding: 8px;\r\n      font-size: 12px;\r\n      font-weight: 800;\r\n      text-align: center;\r\n    }\r\n\r\n    .qr-preview-box {\r\n      background: rgba(0,0,0,.22);\r\n      border: 1px solid rgba(255,255,255,.1);\r\n      border-radius: 18px;\r\n      padding: 12px;\r\n      max-height: 370px;\r\n      overflow: auto;\r\n    }\r\n\r\n    .qr-grid {\r\n      display: grid;\r\n      grid-template-columns: repeat(4, 1fr);\r\n      gap: 10px;\r\n    }\r\n\r\n    .qr-card {\r\n      background: #fff;\r\n      color: #111;\r\n      border-radius: 12px;\r\n      padding: 8px;\r\n      text-align: center;\r\n      min-height: 118px;\r\n      display: grid;\r\n      place-items: center;\r\n      gap: 5px;\r\n      page-break-inside: avoid;\r\n    }\r\n\r\n    .qr-code {\r\n      width: 62px;\r\n      height: 62px;\r\n      background: #fff;\r\n      display: grid;\r\n      grid-template-columns: repeat(7, 1fr);\r\n      grid-template-rows: repeat(7, 1fr);\r\n      gap: 2px;\r\n      padding: 3px;\r\n      border: 2px solid #111;\r\n    }\r\n\r\n    .qr-cell { background: transparent; }\r\n    .qr-cell.black { background: #111; }\r\n    .qr-card strong { font-size: 10px; }\r\n    .qr-card small { font-size: 8px; color: #333; }\r\n\r\n    .employee-table {\r\n      width: 100%;\r\n      border-collapse: collapse;\r\n      font-size: 13px;\r\n      overflow: hidden;\r\n      border-radius: 14px;\r\n    }\r\n\r\n    .employee-table th, .employee-table td {\r\n      border-bottom: 1px solid rgba(255,255,255,.08);\r\n      padding: 9px;\r\n      text-align: left;\r\n    }\r\n\r\n    .employee-table th { color: #ffce00; background: rgba(0,0,0,.22); }\r\n\r\n    @media print {\r\n      body { background: #fff; color: #111; padding: 0; }\r\n      body * { visibility: hidden; }\r\n      #qrPrintArea, #qrPrintArea * { visibility: visible; }\r\n      #qrPrintArea {\r\n        position: absolute;\r\n        left: 0;\r\n        top: 0;\r\n        width: 100%;\r\n        background: #fff;\r\n        color: #111;\r\n        padding: 18px;\r\n      }\r\n      .qr-grid { grid-template-columns: repeat(4, 1fr); gap: 12px; }\r\n      .qr-preview-box { max-height: none; overflow: visible; border: none; }\r\n      .qr-card { border: 1px solid #111; }\r\n    }\r\n\r\n    @media (max-width: 980px) {\r\n      .grid, .top-section { grid-template-columns: 1fr; }\r\n      .intro h2 { font-size: 31px; }\r\n      canvas { height: 360px; }\r\n      .admin-grid, .mini-stats, .admin-login, .prize-options { grid-template-columns: 1fr; }\r\n      .qr-grid { grid-template-columns: repeat(2, 1fr); }\r\n    }\r\n  <\/style>\r\n<\/head>\r\n<body>\r\n  <div class=\"app\">\r\n    <header class=\"header\">\r\n      <div class=\"brand\">\r\n        <div class=\"logo\">MW<\/div>\r\n        <div>\r\n          <h1>Reto Master Wok<\/h1>\r\n          <p>P\u00e1jaro volador con QR de una sola jugada<\/p>\r\n        <\/div>\r\n      <\/div>\r\n      <div class=\"badge\">Campa\u00f1a activa: Mayo 2026<\/div>\r\n    <\/header>\r\n\r\n    <main class=\"grid\">\r\n      <section class=\"card\">\r\n        <div class=\"top-section\">\r\n          <div class=\"intro\">\r\n            <h2>Vuela, esquiva obst\u00e1culos y gana el <span>premio del mes<\/span>.<\/h2>\r\n            <p>\r\n              El empleado escanea un QR, ingresa su c\u00e9dula y juega una sola vez.\r\n              Cada clic hace subir el p\u00e1jaro; si no hace clic, la gravedad lo baja.\r\n            <\/p>\r\n            <div class=\"form\">\r\n              <input id=\"cedula\" type=\"text\" placeholder=\"N\u00famero de c\u00e9dula del empleado\" \/>\r\n              <button onclick=\"startQRFlow()\">Iniciar juego \/ escanear QR<\/button>\r\n            <\/div>\r\n\r\n            <div id=\"scannerPanel\" class=\"scanner-panel hidden\">\r\n              <div class=\"scanner-head\">\r\n                <strong>Validar c\u00f3digo de juego<\/strong>\r\n                <button class=\"secondary small-btn\" onclick=\"closeCameraScanner()\">Cerrar<\/button>\r\n              <\/div>\r\n              <video id=\"cameraPreview\" autoplay playsinline><\/video>\r\n              <p class=\"small-note\">Se abre la c\u00e1mara para escanear el QR. Si no funciona, escribe el c\u00f3digo manual del cup\u00f3n.<\/p>\r\n              <div class=\"manual-code-row\">\r\n                <input id=\"manualCode\" type=\"text\" placeholder=\"C\u00f3digo manual o c\u00f3digo QR\" \/>\r\n                <button onclick=\"activateManualCode()\">Validar c\u00f3digo<\/button>\r\n              <\/div>\r\n              <button class=\"secondary\" onclick=\"simulateQRScan()\">Demo: simular QR escaneado<\/button>\r\n            <\/div>\r\n            <div id=\"loginMsg\" class=\"toast\"><\/div>\r\n          <\/div>\r\n\r\n          <aside class=\"prize-card\">\r\n            <img decoding=\"async\" id=\"prizeImage\" src=\"https:\/\/images.unsplash.com\/photo-1485965120184-e220f721d03e?auto=format&fit=crop&w=900&q=80\" alt=\"Premio del mes\" \/>\r\n            <small>PREMIO DEL MES<\/small>\r\n            <h3 id=\"prizeName\">Bicicleta<\/h3>\r\n            <p id=\"prizeDesc\">Para el empleado con mayor puntaje acumulado del mes.<\/p>\r\n          <\/aside>\r\n        <\/div>\r\n\r\n        <div class=\"game-wrap\">\r\n          <div class=\"game-header\">\r\n            <h3>Juego: P\u00e1jaro Master Wok<\/h3>\r\n            <div class=\"game-stats\">\r\n              <div class=\"pill\">Puntaje: <span id=\"currentScore\">0<\/span><\/div>\r\n              <div class=\"pill\">Nivel: <span id=\"currentLevel\">1<\/span><\/div>\r\n              <div class=\"pill\">Velocidad: <span id=\"currentSpeed\">1.0x<\/span><\/div>\r\n            <\/div>\r\n          <\/div>\r\n\r\n          <canvas id=\"gameCanvas\" width=\"900\" height=\"430\"><\/canvas>\r\n\r\n          <div class=\"game-controls\">\r\n            <button onclick=\"startGame()\">Iniciar partida<\/button>\r\n            <button class=\"secondary\" onclick=\"birdJump()\">Clic \/ subir<\/button>\r\n            <button class=\"secondary\" onclick=\"resetGameOnly()\">Reiniciar demo<\/button>\r\n          <\/div>\r\n          <p class=\"small-note\">En celular se juega tocando la pantalla. En computador se juega con clic o barra espaciadora.<\/p>\r\n          <div id=\"gameMsg\" class=\"toast\"><\/div>\r\n        <\/div>\r\n      <\/section>\r\n\r\n      <aside class=\"side\">\r\n        <section class=\"card ranking\">\r\n          <h3>\ud83c\udfc6 Top 5 del mes<\/h3>\r\n          <div class=\"rank-list\" id=\"rankingList\"><\/div>\r\n        <\/section>\r\n\r\n        <section class=\"card admin\">\r\n          <h3>Administrador<\/h3>\r\n\r\n          <div id=\"adminLogin\" class=\"admin-login\">\r\n            <input id=\"adminUser\" type=\"text\" value=\"administrador\" placeholder=\"Usuario\" \/>\r\n            <input id=\"adminPass\" type=\"password\" value=\"administrador\" placeholder=\"Contrase\u00f1a\" \/>\r\n            <button onclick=\"adminLogin()\">Entrar<\/button>\r\n          <\/div>\r\n\r\n          <div id=\"adminPanel\" class=\"admin-panel hidden\">\r\n            <div class=\"admin-tabs\">\r\n              <button class=\"admin-tab active\" onclick=\"showAdminTab('dashboard', this)\">Resumen<\/button>\r\n              <button class=\"admin-tab\" onclick=\"showAdminTab('premio', this)\">Premio<\/button>\r\n              <button class=\"admin-tab\" onclick=\"showAdminTab('qr', this)\">QR<\/button>\r\n              <button class=\"admin-tab\" onclick=\"showAdminTab('empleados', this)\">Empleados<\/button>\r\n              <button class=\"admin-tab\" onclick=\"showAdminTab('seguridad', this)\">Clave<\/button>\r\n            <\/div>\r\n\r\n            <div id=\"admin-dashboard\" class=\"admin-section active\">\r\n              <div class=\"mini-stats\">\r\n                <div class=\"stat\"><strong id=\"qrGenerated\">0<\/strong><span>QR + c\u00f3digos<\/span><\/div>\r\n                <div class=\"stat\"><strong id=\"qrUsed\">0<\/strong><span>QR usados<\/span><\/div>\r\n                <div class=\"stat\"><strong id=\"qrAvailable\">0<\/strong><span>QR disponibles<\/span><\/div>\r\n              <\/div>\r\n              <p class=\"small-note\">Desde aqu\u00ed puedes cambiar el premio, generar c\u00f3digos QR imprimibles, administrar empleados y reiniciar la campa\u00f1a mensual.<\/p>\r\n              <div class=\"admin-actions\">\r\n                <button class=\"secondary\" onclick=\"resetScores()\">Reiniciar ranking mensual<\/button>\r\n                <button class=\"danger\" onclick=\"adminLogout()\">Salir del administrador<\/button>\r\n              <\/div>\r\n            <\/div>\r\n\r\n            <div id=\"admin-premio\" class=\"admin-section\">\r\n              <label>Escoger premio predeterminado<\/label>\r\n              <div class=\"prize-options\" id=\"prizeOptions\"><\/div>\r\n\r\n              <div class=\"admin-grid\">\r\n                <input id=\"adminPrizeName\" type=\"text\" value=\"Bicicleta\" placeholder=\"Nombre del premio\" \/>\r\n                <input id=\"adminPrizeDesc\" type=\"text\" value=\"Para el empleado con mayor puntaje acumulado del mes.\" placeholder=\"Descripci\u00f3n del premio\" \/>\r\n              <\/div>\r\n              <input id=\"adminPrizeImage\" type=\"text\" value=\"https:\/\/images.unsplash.com\/photo-1485965120184-e220f721d03e?auto=format&fit=crop&w=900&q=80\" placeholder=\"URL de imagen del premio\" \/>\r\n              <input id=\"adminPrizeUpload\" type=\"file\" accept=\"image\/*\" onchange=\"uploadPrizeImage(event)\" \/>\r\n              <div class=\"admin-actions\">\r\n                <button onclick=\"updatePrize()\">Actualizar premio<\/button>\r\n              <\/div>\r\n              <p class=\"small-note\">Puedes escoger una imagen predeterminada, pegar una URL o subir una imagen desde tu computador.<\/p>\r\n            <\/div>\r\n\r\n            <div id=\"admin-qr\" class=\"admin-section\">\r\n              <div class=\"admin-grid\">\r\n                <select id=\"qrAmount\">\r\n                  <option value=\"20\">Generar 20 QR<\/option>\r\n                  <option value=\"50\">Generar 50 QR<\/option>\r\n                  <option value=\"100\">Generar 100 QR<\/option>\r\n                  <option value=\"200\" selected>Generar 200 QR<\/option>\r\n                  <option value=\"500\">Generar 500 QR<\/option>\r\n                <\/select>\r\n                <input id=\"campaignCode\" type=\"text\" value=\"MAY-2026\" placeholder=\"C\u00f3digo de campa\u00f1a\" \/>\r\n              <\/div>\r\n              <div class=\"admin-actions\">\r\n                <button onclick=\"generateQR()\">Generar c\u00f3digos QR<\/button>\r\n                <button class=\"secondary\" onclick=\"printQR()\">Descargar \/ guardar PDF<\/button>\r\n                <button class=\"secondary\" onclick=\"downloadQRCSV()\">Descargar listado CSV<\/button>\r\n              <\/div>\r\n              <p class=\"small-note\">Cada cup\u00f3n trae QR + c\u00f3digo de validaci\u00f3n manual. Para PDF: presiona \u201cDescargar \/ guardar PDF\u201d y en la ventana de impresi\u00f3n elige \u201cGuardar como PDF\u201d.<\/p>\r\n              <div id=\"qrPrintArea\" class=\"qr-preview-box\">\r\n                <div style=\"color:#111;background:#fff;padding:10px;border-radius:12px;margin-bottom:10px;text-align:center;\">\r\n                  <strong>Reto Master Wok<\/strong><br>\r\n                  <small>Escanea el QR o escribe el c\u00f3digo manual. Cada cup\u00f3n sirve para una sola jugada.<\/small>\r\n                <\/div>\r\n                <div id=\"qrList\" class=\"qr-grid\"><\/div>\r\n              <\/div>\r\n            <\/div>\r\n\r\n            <div id=\"admin-empleados\" class=\"admin-section\">\r\n              <div class=\"admin-grid\">\r\n                <input id=\"employeeName\" type=\"text\" placeholder=\"Nombre empleado\" \/>\r\n                <input id=\"employeeCedula\" type=\"text\" placeholder=\"C\u00e9dula\" \/>\r\n                <input id=\"employeeRestaurant\" type=\"text\" placeholder=\"Restaurante\" \/>\r\n                <button onclick=\"addEmployee()\">Agregar empleado<\/button>\r\n                <button class=\"danger\" onclick=\"clearEmployees()\">Borrar empleados<\/button>\r\n              <\/div>\r\n              <table class=\"employee-table\">\r\n                <thead><tr><th>Nombre<\/th><th>C\u00e9dula<\/th><th>Restaurante<\/th><\/tr><\/thead>\r\n                <tbody id=\"employeeTableBody\"><\/tbody>\r\n              <\/table>\r\n            <\/div>\r\n\r\n            <div id=\"admin-seguridad\" class=\"admin-section\">\r\n              <div class=\"admin-grid\">\r\n                <input id=\"newAdminUser\" type=\"text\" value=\"administrador\" placeholder=\"Nuevo usuario admin\" \/>\r\n                <input id=\"newAdminPass\" type=\"password\" value=\"administrador\" placeholder=\"Nueva contrase\u00f1a admin\" \/>\r\n              <\/div>\r\n              <div class=\"admin-actions\">\r\n                <button onclick=\"changeAdminCredentials()\">Cambiar usuario y contrase\u00f1a<\/button>\r\n              <\/div>\r\n              <p class=\"small-note\">Demo: el cambio funciona mientras la p\u00e1gina est\u00e9 abierta. En la versi\u00f3n real se guardar\u00eda en base de datos con contrase\u00f1a encriptada.<\/p>\r\n            <\/div>\r\n          <\/div>\r\n          <div id=\"adminMsg\" class=\"toast\"><\/div>\r\n        <\/section>\r\n      <\/aside>\r\n    <\/main>\r\n  <\/div>\r\n\r\n  <script>\r\n    let adminCredentials = { user: 'administrador', pass: 'administrador' };\r\n    let employeeAccessApproved = false;\r\n    let currentEmployeeCedula = '';\r\n    let currentQR = '';\r\n    let qrCodes = [];\r\n    let cameraStream = null;\r\n\r\n    const defaultPrizes = [\r\n      {\r\n        name: 'Bicicleta',\r\n        desc: 'Premio para el empleado con mayor puntaje del mes.',\r\n        image: 'https:\/\/images.unsplash.com\/photo-1485965120184-e220f721d03e?auto=format&fit=crop&w=900&q=80'\r\n      },\r\n      {\r\n        name: 'Nevera',\r\n        desc: 'Premio especial para el ganador mensual.',\r\n        image: 'https:\/\/images.unsplash.com\/photo-1584568694244-14fbdf83bd30?auto=format&fit=crop&w=900&q=80'\r\n      },\r\n      {\r\n        name: 'Microondas',\r\n        desc: 'Premio mensual para reconocer el esfuerzo del equipo.',\r\n        image: 'https:\/\/images.unsplash.com\/photo-1585659722983-3a675dabf23d?auto=format&fit=crop&w=900&q=80'\r\n      },\r\n      {\r\n        name: 'Ventilador',\r\n        desc: 'Premio pr\u00e1ctico para el ganador de la campa\u00f1a.',\r\n        image: 'https:\/\/images.unsplash.com\/photo-1626806819282-2c1dc01a5e0c?auto=format&fit=crop&w=900&q=80'\r\n      },\r\n      {\r\n        name: 'Viaje',\r\n        desc: 'Experiencia especial para el mejor puntaje del mes.',\r\n        image: 'https:\/\/images.unsplash.com\/photo-1507525428034-b723cf961d3e?auto=format&fit=crop&w=900&q=80'\r\n      },\r\n      {\r\n        name: 'Bono en efectivo',\r\n        desc: 'Bono mensual para el empleado ganador.',\r\n        image: 'https:\/\/images.unsplash.com\/photo-1579621970795-87facc2f976d?auto=format&fit=crop&w=900&q=80'\r\n      }\r\n    ];\r\n\r\n    let employees = JSON.parse(localStorage.getItem('mw_employees') || '[]');\r\n\r\n    let ranking = [\r\n      { name: 'Andrea', restaurant: 'Armenia', score: 8450 },\r\n      { name: 'Daniela', restaurant: 'Calarc\u00e1', score: 7980 },\r\n      { name: '\u00c1ngela', restaurant: 'Quimbaya', score: 7600 },\r\n      { name: 'Viviana', restaurant: 'La Tebaida', score: 7300 },\r\n      { name: 'Juan', restaurant: 'Circasia', score: 6950 }\r\n    ];\r\n\r\n    function renderRanking() {\r\n      const list = document.getElementById('rankingList');\r\n      ranking.sort((a, b) => b.score - a.score);\r\n      const top = ranking.slice(0, 5);\r\n      if (!top.length) {\r\n        list.innerHTML = '<p class=\"small-note\">Ranking vac\u00edo para la nueva campa\u00f1a.<\/p>';\r\n        return;\r\n      }\r\n      list.innerHTML = top.map((player, index) => `\r\n        <div class=\"rank-item\">\r\n          <div class=\"position\">${index + 1}<\/div>\r\n          <div>\r\n            <strong>${player.name}<\/strong>\r\n            <span>${player.restaurant}<\/span>\r\n          <\/div>\r\n          <div class=\"score\">${player.score.toLocaleString('es-CO')}<\/div>\r\n        <\/div>\r\n      `).join('');\r\n    }\r\n\r\n    function renderPrizeOptions() {\r\n      const container = document.getElementById('prizeOptions');\r\n      container.innerHTML = defaultPrizes.map((prize, index) => `\r\n        <div class=\"prize-option ${index === 0 ? 'selected' : ''}\" onclick=\"selectDefaultPrize(${index}, this)\">\r\n          <img decoding=\"async\" src=\"${prize.image}\" alt=\"${prize.name}\" \/>\r\n          <span>${prize.name}<\/span>\r\n        <\/div>\r\n      `).join('');\r\n    }\r\n\r\n    function selectDefaultPrize(index, element) {\r\n      const prize = defaultPrizes[index];\r\n      document.querySelectorAll('.prize-option').forEach(item => item.classList.remove('selected'));\r\n      element.classList.add('selected');\r\n      document.getElementById('adminPrizeName').value = prize.name;\r\n      document.getElementById('adminPrizeDesc').value = prize.desc;\r\n      document.getElementById('adminPrizeImage').value = prize.image;\r\n      updatePrize();\r\n    }\r\n\r\n    function uploadPrizeImage(event) {\r\n      const file = event.target.files[0];\r\n      if (!file) return;\r\n      const reader = new FileReader();\r\n      reader.onload = function(e) {\r\n        document.getElementById('adminPrizeImage').value = e.target.result;\r\n        document.getElementById('prizeImage').src = e.target.result;\r\n        document.getElementById('adminMsg').textContent = 'Imagen subida. Ahora puedes cambiar el nombre y guardar el premio.';\r\n      };\r\n      reader.readAsDataURL(file);\r\n    }\r\n\r\n    function updatePrize() {\r\n      const name = document.getElementById('adminPrizeName').value.trim() || 'Premio del mes';\r\n      const image = document.getElementById('adminPrizeImage').value.trim();\r\n      const desc = document.getElementById('adminPrizeDesc').value.trim() || 'Para el empleado con mayor puntaje acumulado del mes.';\r\n      document.getElementById('prizeName').textContent = name;\r\n      if (image) document.getElementById('prizeImage').src = image;\r\n      document.getElementById('prizeDesc').textContent = desc;\r\n      document.getElementById('adminMsg').textContent = 'Premio actualizado correctamente.';\r\n    }\r\n\r\n    function renderEmployees() {\r\n      const body = document.getElementById('employeeTableBody');\r\n      if (!employees.length) {\r\n        body.innerHTML = '<tr><td colspan=\"3\">No hay empleados registrados. Agr\u00e9galos desde cero.<\/td><\/tr>';\r\n        return;\r\n      }\r\n      body.innerHTML = employees.map(emp => `\r\n        <tr><td>${emp.name}<\/td><td>${emp.cedula}<\/td><td>${emp.restaurant}<\/td><\/tr>\r\n      `).join('');\r\n    }\r\n\r\n    function clearEmployees() {\r\n      employees = [];\r\n      localStorage.removeItem('mw_employees');\r\n      renderEmployees();\r\n      document.getElementById('adminMsg').textContent = 'Base de empleados borrada. Ya puedes agregarlos desde cero.';\r\n    }\r\n\r\n    function addEmployee() {\r\n      const name = document.getElementById('employeeName').value.trim();\r\n      const cedula = document.getElementById('employeeCedula').value.trim();\r\n      const restaurant = document.getElementById('employeeRestaurant').value.trim();\r\n      if (!name || !cedula || !restaurant) {\r\n        document.getElementById('adminMsg').textContent = 'Completa nombre, c\u00e9dula y restaurante.';\r\n        return;\r\n      }\r\n      const exists = employees.some(emp => emp.cedula === cedula);\r\n      if (exists) {\r\n        document.getElementById('adminMsg').textContent = 'Esa c\u00e9dula ya est\u00e1 registrada.';\r\n        return;\r\n      }\r\n      employees.push({ name, cedula, restaurant });\r\n      localStorage.setItem('mw_employees', JSON.stringify(employees));\r\n      renderEmployees();\r\n      document.getElementById('employeeName').value = '';\r\n      document.getElementById('employeeCedula').value = '';\r\n      document.getElementById('employeeRestaurant').value = '';\r\n      document.getElementById('adminMsg').textContent = 'Empleado agregado y guardado correctamente.';\r\n    }\r\n\r\n    async function startQRFlow() {\r\n      const cedula = document.getElementById('cedula').value.trim();\r\n      const msg = document.getElementById('loginMsg');\r\n      employeeAccessApproved = false;\r\n\r\n      if (!cedula) {\r\n        msg.textContent = 'Primero escribe la c\u00e9dula del empleado.';\r\n        return;\r\n      }\r\n\r\n      const employee = employees.find(emp => emp.cedula === cedula);\r\n      if (!employee) {\r\n        msg.textContent = 'Esta c\u00e9dula no est\u00e1 registrada. Agr\u00e9gala primero desde el administrador.';\r\n        return;\r\n      }\r\n\r\n      currentEmployeeCedula = cedula;\r\n      document.getElementById('scannerPanel').classList.remove('hidden');\r\n      msg.textContent = `Empleado encontrado: ${employee.name}. Ahora escanea el QR o escribe el c\u00f3digo manual.`;\r\n      await openCameraScanner();\r\n    }\r\n\r\n    async function openCameraScanner() {\r\n      const video = document.getElementById('cameraPreview');\r\n      const msg = document.getElementById('loginMsg');\r\n      try {\r\n        if (cameraStream) closeCameraScanner(false);\r\n        cameraStream = await navigator.mediaDevices.getUserMedia({ video: { facingMode: 'environment' } });\r\n        video.srcObject = cameraStream;\r\n        msg.textContent = 'C\u00e1mara abierta. Escanea el QR o usa el c\u00f3digo manual.';\r\n      } catch (error) {\r\n        msg.textContent = 'No se pudo abrir la c\u00e1mara. Puedes escribir el c\u00f3digo manual del cup\u00f3n.';\r\n      }\r\n    }\r\n\r\n    function closeCameraScanner(showMessage = true) {\r\n      if (cameraStream) {\r\n        cameraStream.getTracks().forEach(track => track.stop());\r\n        cameraStream = null;\r\n      }\r\n      const video = document.getElementById('cameraPreview');\r\n      if (video) video.srcObject = null;\r\n      document.getElementById('scannerPanel').classList.add('hidden');\r\n      if (showMessage) document.getElementById('loginMsg').textContent = 'Esc\u00e1ner cerrado.';\r\n    }\r\n\r\n    function simulateQRScan() {\r\n      if (!qrCodes.length) generateQR();\r\n      const firstAvailable = qrCodes.find(item => !item.used);\r\n      if (!firstAvailable) {\r\n        document.getElementById('loginMsg').textContent = 'No hay QR disponibles. Genera nuevos c\u00f3digos desde administrador.';\r\n        return;\r\n      }\r\n      validateEmployeeAndQRCode(firstAvailable.code);\r\n    }\r\n\r\n    function activateManualCode() {\r\n      const manualCode = document.getElementById('manualCode').value.trim();\r\n      if (!manualCode) {\r\n        document.getElementById('loginMsg').textContent = 'Escribe el c\u00f3digo manual o c\u00f3digo QR.';\r\n        return;\r\n      }\r\n      validateEmployeeAndQRCode(manualCode);\r\n    }\r\n\r\n    function validateEmployeeAndQRCode(codeInput) {\r\n      const code = codeInput.trim().toUpperCase();\r\n      const employee = employees.find(emp => emp.cedula === currentEmployeeCedula);\r\n      const qrItem = qrCodes.find(item => item.code.toUpperCase() === code || item.validation.toUpperCase() === code);\r\n      const msg = document.getElementById('loginMsg');\r\n\r\n      if (!employee) {\r\n        msg.textContent = 'Empleado no encontrado. Vuelve a escribir la c\u00e9dula.';\r\n        employeeAccessApproved = false;\r\n        return;\r\n      }\r\n\r\n      if (!qrCodes.length) {\r\n        msg.textContent = 'No hay QR generados. Entra al administrador y genera c\u00f3digos primero.';\r\n        employeeAccessApproved = false;\r\n        return;\r\n      }\r\n\r\n      if (!qrItem) {\r\n        msg.textContent = 'C\u00f3digo no v\u00e1lido para esta campa\u00f1a.';\r\n        employeeAccessApproved = false;\r\n        return;\r\n      }\r\n\r\n      if (qrItem.used) {\r\n        msg.textContent = `Ese c\u00f3digo ya fue usado${qrItem.usedBy ? ' por ' + qrItem.usedBy : ''}. Cada QR sirve para una sola partida.`;\r\n        employeeAccessApproved = false;\r\n        return;\r\n      }\r\n\r\n      employeeAccessApproved = true;\r\n      currentQR = qrItem.code;\r\n      document.getElementById('manualCode').value = qrItem.validation;\r\n      closeCameraScanner(false);\r\n      msg.textContent = `QR validado para ${employee.name}. Ahora s\u00ed puedes iniciar la partida.`;\r\n    }\r\n\r\n    function adminLogin() {\r\n      const user = document.getElementById('adminUser').value.trim();\r\n      const pass = document.getElementById('adminPass').value.trim();\r\n      const msg = document.getElementById('adminMsg');\r\n\r\n      if (user === adminCredentials.user && pass === adminCredentials.pass) {\r\n        document.getElementById('adminLogin').classList.add('hidden');\r\n        document.getElementById('adminPanel').classList.remove('hidden');\r\n        msg.textContent = 'Administrador conectado correctamente.';\r\n      } else {\r\n        msg.textContent = 'Usuario o contrase\u00f1a incorrectos.';\r\n      }\r\n    }\r\n\r\n    function adminLogout() {\r\n      document.getElementById('adminPanel').classList.add('hidden');\r\n      document.getElementById('adminLogin').classList.remove('hidden');\r\n      document.getElementById('adminMsg').textContent = 'Sesi\u00f3n de administrador cerrada.';\r\n    }\r\n\r\n    function showAdminTab(tab, button) {\r\n      document.querySelectorAll('.admin-section').forEach(section => section.classList.remove('active'));\r\n      document.querySelectorAll('.admin-tab').forEach(btn => btn.classList.remove('active'));\r\n      document.getElementById('admin-' + tab).classList.add('active');\r\n      button.classList.add('active');\r\n    }\r\n\r\n    function changeAdminCredentials() {\r\n      const newUser = document.getElementById('newAdminUser').value.trim();\r\n      const newPass = document.getElementById('newAdminPass').value.trim();\r\n      if (!newUser || !newPass) {\r\n        document.getElementById('adminMsg').textContent = 'Debes escribir nuevo usuario y nueva contrase\u00f1a.';\r\n        return;\r\n      }\r\n      adminCredentials = { user: newUser, pass: newPass };\r\n      document.getElementById('adminUser').value = newUser;\r\n      document.getElementById('adminPass').value = newPass;\r\n      document.getElementById('adminMsg').textContent = 'Usuario y contrase\u00f1a cambiados en esta demo.';\r\n    }\r\n\r\n    function makeDemoQRPattern(seed) {\r\n      let html = '';\r\n      for (let i = 0; i < 49; i++) {\r\n        const isCorner = (i < 14 && i % 7 < 2) || (i < 14 && i % 7 > 4) || (i > 34 && i % 7 < 2);\r\n        const black = isCorner || ((i * seed + seed) % 5 === 0) || ((i + seed) % 7 === 0);\r\n        html += `<div class=\"qr-cell ${black ? 'black' : ''}\"><\/div>`;\r\n      }\r\n      return html;\r\n    }\r\n\r\n    function generateValidationCode(index, usedCodes) {\r\n      const letters = 'ABCDEFGHJKLMNPQRSTUVWXYZ23456789';\r\n      let attempts = 0;\r\n\r\n      while (attempts < 200) {\r\n        let code = '';\r\n        const randomPart = Math.floor(Math.random() * 9999999) + Date.now() + index + attempts;\r\n        let seed = index * 7919 + randomPart;\r\n\r\n        for (let i = 0; i < 6; i++) {\r\n          seed = (seed * 9301 + 49297) % 233280;\r\n          code += letters[seed % letters.length];\r\n        }\r\n\r\n        if (!usedCodes.has(code)) {\r\n          usedCodes.add(code);\r\n          return code;\r\n        }\r\n\r\n        attempts++;\r\n      }\r\n\r\n      const fallback = 'MW' + String(index).padStart(4, '0') + String(Date.now()).slice(-2);\r\n      usedCodes.add(fallback);\r\n      return fallback;\r\n    }\r\n\r\n    function generateQR() {\r\n      const amount = Number(document.getElementById('qrAmount').value);\r\n      const campaign = document.getElementById('campaignCode').value.trim() || 'MAY-2026';\r\n      qrCodes = [];\r\n      const usedManualCodes = new Set();\r\n      const usedQRCodes = new Set();\r\n\r\n      for (let i = 1; i <= amount; i++) {\r\n        let code = `MW-${campaign}-${String(i).padStart(4, '0')}`;\r\n        while (usedQRCodes.has(code)) {\r\n          code = `MW-${campaign}-${String(i).padStart(4, '0')}-${Math.floor(Math.random() * 999)}`;\r\n        }\r\n        usedQRCodes.add(code);\r\n\r\n        const validation = generateValidationCode(i, usedManualCodes);\r\n        qrCodes.push({ code, validation, used: false, usedBy: null, usedAt: null });\r\n      }\r\n\r\n      document.getElementById('qrGenerated').textContent = amount;\r\n      document.getElementById('qrUsed').textContent = 0;\r\n      document.getElementById('qrAvailable').textContent = amount;\r\n      renderQRList();\r\n      document.getElementById('manualCode').value = qrCodes[0]?.validation || '';\r\n      document.getElementById('adminMsg').textContent = `Se generaron ${amount} c\u00f3digos \u00fanicos. Cada QR y cada c\u00f3digo manual sirven solo para una partida.`;\r\n    }\r\n\r\n    function renderQRList() {\r\n      const list = document.getElementById('qrList');\r\n      list.innerHTML = qrCodes.map((item, index) => `\r\n        <div class=\"qr-card\">\r\n          <div class=\"qr-code\">${makeDemoQRPattern(index + 3)}<\/div>\r\n          <strong>${item.code}<\/strong>\r\n          <small>C\u00f3digo manual: <b>${item.validation}<\/b><\/small>\r\n          <small>${item.used ? 'USADO' : '1 jugada disponible'} \u00b7 Reto Master Wok<\/small>\r\n        <\/div>\r\n      `).join('');\r\n    }\r\n\r\n    function printQR() {\r\n      if (!qrCodes.length) generateQR();\r\n      document.getElementById('adminMsg').textContent = 'Se abri\u00f3 la ventana de impresi\u00f3n. Elige \u201cGuardar como PDF\u201d para descargarlo.';\r\n      setTimeout(() => window.print(), 200);\r\n    }\r\n\r\n    function downloadQRCSV() {\r\n      if (!qrCodes.length) generateQR();\r\n      const rows = ['codigo_qr,codigo_manual,estado,usado_por,fecha_uso', ...qrCodes.map(qr => `${qr.code},${qr.validation},${qr.used ? 'usado' : 'disponible'},${qr.usedBy || ''},${qr.usedAt || ''}`)];\r\n      const blob = new Blob([rows.join('\\n')], { type: 'text\/csv;charset=utf-8;' });\r\n      const url = URL.createObjectURL(blob);\r\n      const a = document.createElement('a');\r\n      a.href = url;\r\n      a.download = 'codigos_qr_master_wok.csv';\r\n      a.click();\r\n      URL.revokeObjectURL(url);\r\n      document.getElementById('adminMsg').textContent = 'Listado CSV descargado.';\r\n    }\r\n\r\n    function resetScores() {\r\n      ranking = [];\r\n      renderRanking();\r\n      document.getElementById('adminMsg').textContent = 'Ranking mensual reiniciado. En la versi\u00f3n real se conservar\u00eda historial anterior.';\r\n    }\r\n\r\n    \/\/ Juego tipo p\u00e1jaro volador\r\n    const canvas = document.getElementById('gameCanvas');\r\n    const ctx = canvas.getContext('2d');\r\n    let gameRunning = false;\r\n    let gameOver = false;\r\n    let animationId;\r\n\r\n    let bird = { x: 150, y: 210, radius: 18, velocity: 0 };\r\n    let gravity = 0.48;\r\n    let jumpPower = -8.2;\r\n    let pipes = [];\r\n    let frame = 0;\r\n    let score = 0;\r\n    let level = 1;\r\n    let speed = 2.7;\r\n    let pipeGap = 150;\r\n    let pipeWidth = 74;\r\n\r\n    function resetGameState() {\r\n      bird = { x: 150, y: 210, radius: 18, velocity: 0 };\r\n      pipes = [];\r\n      frame = 0;\r\n      score = 0;\r\n      level = 1;\r\n      speed = 2.7;\r\n      pipeGap = 150;\r\n      gameRunning = false;\r\n      gameOver = false;\r\n      updateGameStats();\r\n      drawGame();\r\n    }\r\n\r\n    function startGame() {\r\n      if (!employeeAccessApproved) {\r\n        document.getElementById('gameMsg').textContent = 'Primero valida la c\u00e9dula y escanea el QR o escribe el c\u00f3digo manual.';\r\n        startQRFlow();\r\n        return;\r\n      }\r\n      cancelAnimationFrame(animationId);\r\n      resetGameState();\r\n      gameRunning = true;\r\n      document.getElementById('gameMsg').textContent = 'Partida iniciada. Haz clic para subir.';\r\n      loop();\r\n    }\r\n\r\n    function resetGameOnly() {\r\n      cancelAnimationFrame(animationId);\r\n      resetGameState();\r\n      document.getElementById('gameMsg').textContent = 'Demo reiniciada.';\r\n    }\r\n\r\n    function birdJump() {\r\n      if (!gameRunning || gameOver) return;\r\n      bird.velocity = jumpPower;\r\n    }\r\n\r\n    function createPipe() {\r\n      const margin = 55;\r\n      const minTop = margin;\r\n      const maxTop = canvas.height - pipeGap - margin;\r\n      const topHeight = Math.floor(Math.random() * (maxTop - minTop + 1)) + minTop;\r\n      pipes.push({ x: canvas.width + 20, topHeight, passed: false });\r\n    }\r\n\r\n    function updateDifficulty() {\r\n      level = Math.floor(score \/ 5) + 1;\r\n      speed = 2.7 + (level - 1) * 0.35;\r\n      pipeGap = Math.max(98, 150 - (level - 1) * 6);\r\n      updateGameStats();\r\n    }\r\n\r\n    function updateGameStats() {\r\n      document.getElementById('currentScore').textContent = score;\r\n      document.getElementById('currentLevel').textContent = level;\r\n      document.getElementById('currentSpeed').textContent = (speed \/ 2.7).toFixed(1) + 'x';\r\n    }\r\n\r\n    function updateGame() {\r\n      frame++;\r\n      bird.velocity += gravity;\r\n      bird.y += bird.velocity;\r\n\r\n      const pipeInterval = Math.max(72, 112 - level * 4);\r\n      if (frame % pipeInterval === 0) createPipe();\r\n\r\n      pipes.forEach(pipe => {\r\n        pipe.x -= speed;\r\n        if (!pipe.passed && pipe.x + pipeWidth < bird.x) {\r\n          pipe.passed = true;\r\n          score++;\r\n          updateDifficulty();\r\n        }\r\n      });\r\n\r\n      pipes = pipes.filter(pipe => pipe.x + pipeWidth > -20);\r\n\r\n      if (bird.y - bird.radius < 0 || bird.y + bird.radius > canvas.height) endGame();\r\n\r\n      pipes.forEach(pipe => {\r\n        const bottomY = pipe.topHeight + pipeGap;\r\n        const birdLeft = bird.x - bird.radius;\r\n        const birdRight = bird.x + bird.radius;\r\n        const birdTop = bird.y - bird.radius;\r\n        const birdBottom = bird.y + bird.radius;\r\n        const pipeLeft = pipe.x;\r\n        const pipeRight = pipe.x + pipeWidth;\r\n        const insidePipeX = birdRight > pipeLeft && birdLeft < pipeRight;\r\n        const hitTopPipe = birdTop < pipe.topHeight;\r\n        const hitBottomPipe = birdBottom > bottomY;\r\n        if (insidePipeX && (hitTopPipe || hitBottomPipe)) endGame();\r\n      });\r\n    }\r\n\r\n    function drawGame() {\r\n      ctx.clearRect(0, 0, canvas.width, canvas.height);\r\n      const sky = ctx.createLinearGradient(0, 0, 0, canvas.height);\r\n      sky.addColorStop(0, '#69cfff');\r\n      sky.addColorStop(.62, '#d7f8ff');\r\n      sky.addColorStop(1, '#6bd86c');\r\n      ctx.fillStyle = sky;\r\n      ctx.fillRect(0, 0, canvas.width, canvas.height);\r\n      ctx.fillStyle = 'rgba(255,255,255,.65)';\r\n      drawCloud(90, 70); drawCloud(430, 95); drawCloud(720, 62);\r\n      pipes.forEach(pipe => {\r\n        drawPipe(pipe.x, 0, pipeWidth, pipe.topHeight, true);\r\n        drawPipe(pipe.x, pipe.topHeight + pipeGap, pipeWidth, canvas.height - (pipe.topHeight + pipeGap), false);\r\n      });\r\n      ctx.fillStyle = '#3ba64b';\r\n      ctx.fillRect(0, canvas.height - 18, canvas.width, 18);\r\n      ctx.save();\r\n      ctx.translate(bird.x, bird.y);\r\n      ctx.rotate(Math.max(-0.55, Math.min(0.75, bird.velocity \/ 12)));\r\n      ctx.fillStyle = '#ffce00';\r\n      ctx.beginPath(); ctx.arc(0, 0, bird.radius, 0, Math.PI * 2); ctx.fill();\r\n      ctx.fillStyle = '#ff6a00';\r\n      ctx.beginPath(); ctx.moveTo(15, -3); ctx.lineTo(32, 5); ctx.lineTo(15, 12); ctx.closePath(); ctx.fill();\r\n      ctx.fillStyle = '#111';\r\n      ctx.beginPath(); ctx.arc(7, -7, 3, 0, Math.PI * 2); ctx.fill();\r\n      ctx.fillStyle = 'rgba(255,255,255,.8)';\r\n      ctx.beginPath(); ctx.ellipse(-8, 6, 10, 6, -0.5, 0, Math.PI * 2); ctx.fill();\r\n      ctx.restore();\r\n      if (!gameRunning && !gameOver) drawCenterText('Valida c\u00e9dula y QR, luego inicia', 'Clic \/ toque para subir durante el juego');\r\n      if (gameOver) drawCenterText('Partida terminada', 'Puntaje guardado: ' + score);\r\n    }\r\n\r\n    function drawPipe(x, y, w, h, top) {\r\n      const grad = ctx.createLinearGradient(x, 0, x + w, 0);\r\n      grad.addColorStop(0, '#118a33'); grad.addColorStop(.5, '#35d654'); grad.addColorStop(1, '#0b6f28');\r\n      ctx.fillStyle = grad; ctx.fillRect(x, y, w, h);\r\n      ctx.fillStyle = '#0a5d23';\r\n      if (top) ctx.fillRect(x - 8, h - 20, w + 16, 20);\r\n      else ctx.fillRect(x - 8, y, w + 16, 20);\r\n    }\r\n\r\n    function drawCloud(x, y) {\r\n      ctx.beginPath();\r\n      ctx.arc(x, y, 20, 0, Math.PI * 2);\r\n      ctx.arc(x + 24, y - 12, 24, 0, Math.PI * 2);\r\n      ctx.arc(x + 52, y, 20, 0, Math.PI * 2);\r\n      ctx.fill();\r\n    }\r\n\r\n    function drawCenterText(title, subtitle) {\r\n      ctx.fillStyle = 'rgba(0,0,0,.52)';\r\n      ctx.fillRect(0, canvas.height \/ 2 - 58, canvas.width, 116);\r\n      ctx.textAlign = 'center';\r\n      ctx.fillStyle = '#fff';\r\n      ctx.font = 'bold 32px Arial';\r\n      ctx.fillText(title, canvas.width \/ 2, canvas.height \/ 2 - 8);\r\n      ctx.fillStyle = '#ffce00';\r\n      ctx.font = 'bold 18px Arial';\r\n      ctx.fillText(subtitle, canvas.width \/ 2, canvas.height \/ 2 + 28);\r\n    }\r\n\r\n    function loop() {\r\n      if (!gameRunning) return;\r\n      updateGame();\r\n      drawGame();\r\n      if (!gameOver) animationId = requestAnimationFrame(loop);\r\n    }\r\n\r\n    function endGame() {\r\n      if (gameOver) return;\r\n      gameOver = true;\r\n      gameRunning = false;\r\n      cancelAnimationFrame(animationId);\r\n      drawGame();\r\n      const finalScore = score * 100 + Math.max(0, level - 1) * 50;\r\n      const employee = employees.find(emp => emp.cedula === currentEmployeeCedula);\r\n      ranking.push({\r\n        name: employee ? employee.name : 'Empleado ' + currentEmployeeCedula.slice(-4),\r\n        restaurant: employee ? employee.restaurant : 'Master Wok',\r\n        score: finalScore\r\n      });\r\n      renderRanking();\r\n\r\n      const qrItem = qrCodes.find(item => item.code === currentQR);\r\n      if (qrItem) {\r\n        const employee = employees.find(emp => emp.cedula === currentEmployeeCedula);\r\n        qrItem.used = true;\r\n        qrItem.usedBy = employee ? employee.name : currentEmployeeCedula;\r\n        qrItem.usedAt = new Date().toLocaleString('es-CO');\r\n      }\r\n      const used = qrCodes.filter(qr => qr.used).length;\r\n      const available = Math.max(0, qrCodes.length - used);\r\n      document.getElementById('qrUsed').textContent = used;\r\n      document.getElementById('qrAvailable').textContent = available;\r\n      renderQRList();\r\n\r\n      document.getElementById('gameMsg').textContent = `QR ${currentQR || 'demo'} usado. Puntaje final guardado: ${finalScore.toLocaleString('es-CO')}`;\r\n      employeeAccessApproved = false;\r\n    }\r\n\r\n    canvas.addEventListener('click', birdJump);\r\n    canvas.addEventListener('touchstart', function(e) { e.preventDefault(); birdJump(); }, { passive: false });\r\n    document.addEventListener('keydown', function(e) {\r\n      if (e.code === 'Space') { e.preventDefault(); birdJump(); }\r\n    });\r\n\r\n    renderRanking();\r\n    renderPrizeOptions();\r\n    renderEmployees();\r\n    resetGameState();\r\n    generateQR();\r\n  <\/script>\r\n<\/body>\r\n<\/html>\r\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t","protected":false},"excerpt":{"rendered":"<p>&nbsp; &nbsp; MW Reto Master Wok P\u00e1jaro volador con QR de una sola jugada Campa\u00f1a activa: Mayo 2026 &nbsp; Vuela, esquiva obst\u00e1culos y gana el premio del mes. El empleado escanea un QR, ingresa su c\u00e9dula y juega una sola vez. Cada clic hace subir el p\u00e1jaro; si no hace clic, la gravedad lo baja. [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"_joinchat":[],"footnotes":""},"class_list":["post-1645","page","type-page","status-publish","hentry"],"blocksy_meta":[],"_links":{"self":[{"href":"https:\/\/masterwok.co\/index.php\/wp-json\/wp\/v2\/pages\/1645","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/masterwok.co\/index.php\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/masterwok.co\/index.php\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/masterwok.co\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/masterwok.co\/index.php\/wp-json\/wp\/v2\/comments?post=1645"}],"version-history":[{"count":5,"href":"https:\/\/masterwok.co\/index.php\/wp-json\/wp\/v2\/pages\/1645\/revisions"}],"predecessor-version":[{"id":1649,"href":"https:\/\/masterwok.co\/index.php\/wp-json\/wp\/v2\/pages\/1645\/revisions\/1649"}],"wp:attachment":[{"href":"https:\/\/masterwok.co\/index.php\/wp-json\/wp\/v2\/media?parent=1645"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}