Spaces:
Running
Running
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>MINDFLAYER β Deception Protocol</title> | |
| <link href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@300;400;500;600;700&family=Space+Mono:ital,wght@0,400;0,700;1,400&display=swap" rel="stylesheet"> | |
| <style> | |
| :root { | |
| --bg: #080810; | |
| --surface: #0e0e1c; | |
| --panel: #12121f; | |
| --raised: #181828; | |
| --border: rgba(255,255,255,0.06); | |
| --border-hi: rgba(255,255,255,0.13); | |
| --txt: #e8e8f0; | |
| --txt-2: #8888aa; | |
| --txt-3: #44445a; | |
| --amber: #e8b84b; | |
| --amber-d: rgba(232,184,75,0.12); | |
| --amber-g: rgba(232,184,75,0.22); | |
| --red: #f04848; | |
| --red-d: rgba(240,72,72,0.1); | |
| --green: #30d98a; | |
| --green-d: rgba(48,217,138,0.1); | |
| --blue: #5aa8f0; | |
| --blue-d: rgba(90,168,240,0.08); | |
| --violet: #9870f0; | |
| --violet-d: rgba(152,112,240,0.08); | |
| --orange: #f08840; | |
| --orange-d: rgba(240,136,64,0.08); | |
| --mono: 'Space Mono', monospace; | |
| --sans: 'Space Grotesk', system-ui, sans-serif; | |
| --r: 6px; | |
| --r2: 10px; | |
| } | |
| *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; } | |
| html, body { width: 100%; height: 100%; } | |
| body { | |
| font-family: var(--sans); | |
| background: var(--bg); | |
| color: var(--txt); | |
| overflow: hidden; | |
| } | |
| /* Scanlines */ | |
| body::after { | |
| content: ''; | |
| position: fixed; inset: 0; pointer-events: none; z-index: 9999; | |
| background: repeating-linear-gradient( | |
| 180deg, transparent 0px, transparent 2px, | |
| rgba(0,0,0,0.04) 2px, rgba(0,0,0,0.04) 3px | |
| ); | |
| } | |
| /* ββ Screens ββ */ | |
| .screen { position: fixed; inset: 0; display: none; flex-direction: column; } | |
| .screen.active { display: flex; } | |
| .overlay { | |
| z-index: 5000; align-items: center; justify-content: center; | |
| background: rgba(4,4,14,0.82); backdrop-filter: blur(12px); | |
| } | |
| .overlay.active { display: flex; } | |
| /* ββββββββββββββββββββββββββββββββββ | |
| SETUP | |
| ββββββββββββββββββββββββββββββββββ */ | |
| #screen-setup { | |
| background: | |
| radial-gradient(ellipse 70% 60% at 10% 60%, rgba(90,168,240,0.04) 0%, transparent 55%), | |
| radial-gradient(ellipse 60% 50% at 90% 20%, rgba(232,184,75,0.04) 0%, transparent 55%), | |
| var(--bg); | |
| align-items: center; justify-content: center; padding: 24px; | |
| overflow-y: auto; | |
| } | |
| .setup-wrap { | |
| width: 100%; max-width: 660px; | |
| display: flex; flex-direction: column; gap: 24px; | |
| } | |
| /* Hero */ | |
| .hero { text-align: center; } | |
| .hero-eyebrow { | |
| font-family: var(--mono); font-size: 10px; letter-spacing: 0.35em; | |
| color: var(--txt-3); text-transform: uppercase; margin-bottom: 12px; | |
| } | |
| .hero-title { | |
| font-family: var(--mono); font-size: clamp(40px, 9vw, 76px); | |
| font-weight: 700; letter-spacing: 0.06em; line-height: 1; | |
| background: linear-gradient(135deg, var(--txt) 40%, var(--amber) 100%); | |
| -webkit-background-clip: text; -webkit-text-fill-color: transparent; | |
| background-clip: text; | |
| animation: flicker 9s infinite; | |
| } | |
| @keyframes flicker { | |
| 0%,85%,100% { opacity: 1; } | |
| 86% { opacity: 0.88; } | |
| 87% { opacity: 1; } | |
| 91% { opacity: 0.94; } | |
| 92% { opacity: 1; } | |
| } | |
| .hero-sub { | |
| margin-top: 10px; font-size: 13px; font-weight: 300; | |
| color: var(--txt-2); letter-spacing: 0.02em; line-height: 1.6; | |
| } | |
| .hero-rule { | |
| width: 48px; height: 1px; margin: 14px auto 0; | |
| background: linear-gradient(90deg, transparent, var(--amber), transparent); | |
| } | |
| /* Field */ | |
| .field-lbl { | |
| font-family: var(--mono); font-size: 9px; letter-spacing: 0.3em; | |
| text-transform: uppercase; color: var(--txt-3); margin-bottom: 8px; | |
| } | |
| /* Scenario select */ | |
| .scenario-select { | |
| width: 100%; background: var(--raised); | |
| border: 1px solid var(--border-hi); color: var(--txt); | |
| font-family: var(--sans); font-size: 13.5px; font-weight: 400; | |
| padding: 11px 36px 11px 14px; border-radius: var(--r); | |
| appearance: none; cursor: pointer; outline: none; | |
| transition: border-color .2s; | |
| background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6'%3E%3Cpath d='M1 1l4 4 4-4' stroke='%2344445a' stroke-width='1.5' fill='none' stroke-linecap='round'/%3E%3C/svg%3E"); | |
| background-repeat: no-repeat; background-position: right 14px center; | |
| } | |
| .scenario-select:focus { border-color: rgba(232,184,75,0.5); } | |
| .scenario-select option { background: var(--raised); } | |
| /* Difficulty */ | |
| .diff-grid { display: grid; grid-template-columns: repeat(3,1fr); gap: 8px; } | |
| .diff-card { | |
| background: var(--panel); border: 1px solid var(--border); | |
| border-radius: var(--r); padding: 14px 12px; | |
| cursor: pointer; transition: border-color .18s, background .18s; | |
| position: relative; overflow: hidden; | |
| } | |
| .diff-card::after { | |
| content: ''; position: absolute; top: 0; left: 0; right: 0; height: 2px; | |
| opacity: 0; transition: opacity .18s; | |
| } | |
| .diff-card.easy::after { background: var(--green); } | |
| .diff-card.medium::after { background: var(--amber); } | |
| .diff-card.hard::after { background: var(--red); } | |
| .diff-card:hover { border-color: var(--border-hi); background: var(--raised); } | |
| .diff-card.selected { border-color: rgba(232,184,75,0.4); background: var(--raised); } | |
| .diff-card.selected::after { opacity: 1; } | |
| .diff-name { | |
| font-family: var(--mono); font-size: 12px; font-weight: 700; | |
| letter-spacing: 0.1em; margin-bottom: 4px; | |
| } | |
| .diff-card.easy .diff-name { color: var(--green); } | |
| .diff-card.medium .diff-name { color: var(--amber); } | |
| .diff-card.hard .diff-name { color: var(--red); } | |
| .diff-meta { | |
| font-family: var(--mono); font-size: 8px; letter-spacing: 0.1em; | |
| color: var(--txt-3); margin-bottom: 6px; text-transform: uppercase; | |
| } | |
| .diff-desc { font-size: 11.5px; color: var(--txt-2); line-height: 1.55; font-weight: 300; } | |
| /* Start btn */ | |
| .start-btn { | |
| width: 100%; background: transparent; | |
| border: 1px solid rgba(232,184,75,0.5); color: var(--amber); | |
| font-family: var(--mono); font-size: 13px; font-weight: 700; letter-spacing: 0.18em; | |
| padding: 14px; cursor: pointer; border-radius: var(--r); | |
| transition: background .22s, box-shadow .22s, border-color .22s; | |
| position: relative; overflow: hidden; | |
| } | |
| .start-btn:hover:not(:disabled) { | |
| background: var(--amber-d); | |
| box-shadow: 0 0 24px var(--amber-g); | |
| border-color: var(--amber); | |
| } | |
| .start-btn:active:not(:disabled) { transform: scale(0.995); } | |
| .start-btn:disabled { opacity: 0.35; cursor: not-allowed; } | |
| .setup-error { | |
| font-family: var(--mono); font-size: 10.5px; color: var(--red); | |
| background: var(--red-d); border: 1px solid rgba(240,72,72,0.25); | |
| border-radius: var(--r); padding: 8px 12px; display: none; | |
| letter-spacing: 0.03em; line-height: 1.6; | |
| } | |
| /* ββββββββββββββββββββββββββββββββββ | |
| GAME SCREEN | |
| ββββββββββββββββββββββββββββββββββ */ | |
| #screen-game { background: var(--bg); } | |
| /* Header */ | |
| .g-header { | |
| flex-shrink: 0; height: 52px; | |
| background: var(--surface); border-bottom: 1px solid var(--border); | |
| display: grid; grid-template-columns: 140px 1fr auto; | |
| align-items: center; padding: 0 16px; gap: 16px; | |
| } | |
| .g-logo { | |
| font-family: var(--mono); font-size: 16px; font-weight: 700; | |
| letter-spacing: 0.1em; color: var(--amber); | |
| } | |
| .sus-wrap { display: flex; flex-direction: column; gap: 5px; } | |
| .sus-row { | |
| display: flex; justify-content: space-between; | |
| font-family: var(--mono); font-size: 8px; letter-spacing: 0.2em; | |
| color: var(--txt-3); text-transform: uppercase; | |
| } | |
| .sus-track { | |
| height: 4px; background: var(--raised); border-radius: 2px; position: relative; | |
| } | |
| .sus-fill { | |
| height: 100%; border-radius: 2px; | |
| transition: width 0.5s cubic-bezier(.4,0,.2,1), background 0.45s; | |
| background: var(--amber); | |
| } | |
| .g-meta { text-align: right; } | |
| .round-badge { | |
| font-family: var(--mono); font-size: 9px; letter-spacing: 0.12em; color: var(--txt-2); | |
| } | |
| .proj-badge { | |
| font-family: var(--mono); font-size: 8px; letter-spacing: 0.14em; | |
| background: var(--amber-d); border: 1px solid rgba(232,184,75,0.2); | |
| color: var(--amber); padding: 2px 7px; border-radius: 3px; margin-top: 3px; | |
| display: inline-block; text-transform: uppercase; | |
| } | |
| /* Layout */ | |
| .g-main { | |
| flex: 1; min-height: 0; | |
| display: grid; grid-template-columns: 1fr 320px; | |
| } | |
| /* Transcript */ | |
| .transcript-panel { | |
| display: flex; flex-direction: column; | |
| border-right: 1px solid var(--border); | |
| } | |
| .pane-hdr { | |
| flex-shrink: 0; padding: 7px 14px; border-bottom: 1px solid var(--border); | |
| font-family: var(--mono); font-size: 8px; letter-spacing: 0.24em; | |
| color: var(--txt-3); text-transform: uppercase; | |
| } | |
| .transcript-scroll { | |
| flex: 1; overflow-y: auto; padding: 10px 12px; | |
| display: flex; flex-direction: column; gap: 2px; | |
| scroll-behavior: smooth; | |
| } | |
| .transcript-scroll::-webkit-scrollbar { width: 3px; } | |
| .transcript-scroll::-webkit-scrollbar-thumb { background: var(--border-hi); border-radius: 2px; } | |
| /* Messages */ | |
| .msg { | |
| font-family: var(--mono); font-size: 11px; line-height: 1.65; | |
| padding: 8px 10px; border-radius: var(--r); margin-bottom: 1px; | |
| animation: rise .28s ease forwards; opacity: 0; | |
| } | |
| @keyframes rise { | |
| from { opacity: 0; transform: translateY(4px); } | |
| to { opacity: 1; transform: none; } | |
| } | |
| .msg-role { | |
| font-size: 7.5px; font-weight: 700; letter-spacing: 0.25em; | |
| text-transform: uppercase; margin-bottom: 3px; opacity: 0.55; | |
| } | |
| .msg.system { background: rgba(255,255,255,0.025); border-left: 2px solid var(--border-hi); } | |
| .msg.system .msg-role { color: var(--txt-3); } | |
| .msg.flayer { background: var(--amber-d); border-left: 2px solid var(--amber); margin-left: 16px; } | |
| .msg.flayer .msg-role { color: var(--amber); opacity: 0.8; } | |
| .msg.eleven { background: var(--blue-d); border-left: 2px solid var(--blue); margin-right: 16px; } | |
| .msg.eleven .msg-role { color: var(--blue); opacity: 0.8; } | |
| .msg.will { background: var(--violet-d); border-left: 2px solid var(--violet); margin-right: 16px; } | |
| .msg.will .msg-role { color: var(--violet); opacity: 0.8; } | |
| .msg.max { background: var(--orange-d); border-left: 2px solid var(--orange); margin-right: 16px; } | |
| .msg.max .msg-role { color: var(--orange); opacity: 0.8; } | |
| .silence-warn { | |
| font-family: var(--mono); font-size: 9.5px; color: var(--red); | |
| background: var(--red-d); border: 1px solid rgba(240,72,72,0.2); | |
| padding: 4px 10px; border-radius: var(--r); | |
| animation: rise .28s ease forwards; opacity: 0; letter-spacing: 0.04em; | |
| } | |
| /* Investigators panel */ | |
| .inv-panel { display: flex; flex-direction: column; overflow: hidden; } | |
| .inv-list { flex: 1; display: flex; flex-direction: column; overflow: hidden; } | |
| .inv-card { | |
| flex: 1; display: flex; flex-direction: column; | |
| padding: 10px 12px; border-bottom: 1px solid var(--border); | |
| transition: background .25s; overflow: hidden; | |
| } | |
| .inv-card:last-child { border-bottom: none; } | |
| .inv-card.c-eleven { border-left: 2px solid var(--blue); } | |
| .inv-card.c-will { border-left: 2px solid var(--violet); } | |
| .inv-card.c-max { border-left: 2px solid var(--orange); } | |
| .inv-top { | |
| display: flex; justify-content: space-between; align-items: flex-start; margin-bottom: 6px; | |
| } | |
| .inv-name { | |
| font-family: var(--mono); font-size: 13px; font-weight: 700; letter-spacing: 0.06em; | |
| } | |
| .c-eleven .inv-name { color: var(--blue); } | |
| .c-will .inv-name { color: var(--violet); } | |
| .c-max .inv-name { color: var(--orange); } | |
| .inv-role { | |
| font-family: var(--mono); font-size: 7.5px; letter-spacing: 0.14em; | |
| color: var(--txt-3); text-transform: uppercase; margin-top: 2px; | |
| } | |
| /* Suspicion segments */ | |
| .inv-sus { display: flex; gap: 3px; margin-bottom: 7px; } | |
| .seg { | |
| flex: 1; height: 3px; border-radius: 2px; background: var(--raised); | |
| transition: background 0.35s, box-shadow 0.35s; | |
| } | |
| .c-eleven .seg.on { background: var(--blue); box-shadow: 0 0 6px rgba(90,168,240,.5); } | |
| .c-will .seg.on { background: var(--violet); box-shadow: 0 0 6px rgba(152,112,240,.5); } | |
| .c-max .seg.on { background: var(--orange); box-shadow: 0 0 6px rgba(240,136,64,.5); } | |
| .seg.on.alarm { animation: blink 1.3s ease-in-out infinite; } | |
| @keyframes blink { 0%,100% { opacity:1; } 50% { opacity:.35; } } | |
| /* Delta badge */ | |
| .delta { | |
| font-family: var(--mono); font-size: 9px; font-weight: 700; | |
| padding: 2px 6px; border-radius: 3px; | |
| } | |
| .delta.up { color: var(--red); background: var(--red-d); } | |
| .delta.dn { color: var(--green); background: var(--green-d); } | |
| .delta.zero { color: var(--txt-3); } | |
| @keyframes card-flash { 0%,100% { background: transparent; } 40% { background: var(--red-d); } } | |
| .inv-card.flash { animation: card-flash 0.45s ease; } | |
| .inv-resp { | |
| font-family: var(--mono); font-size: 10px; color: var(--txt-2); | |
| font-style: italic; line-height: 1.6; flex: 1; overflow-y: auto; | |
| } | |
| .inv-resp::-webkit-scrollbar { width: 2px; } | |
| .inv-resp::-webkit-scrollbar-thumb { background: var(--border-hi); } | |
| /* Input */ | |
| .g-input { | |
| flex-shrink: 0; background: var(--surface); border-top: 1px solid var(--border); | |
| padding: 9px 12px; display: flex; gap: 9px; align-items: flex-end; | |
| } | |
| .input-wrap { flex: 1; position: relative; } | |
| .msg-input { | |
| width: 100%; background: var(--raised); | |
| border: 1px solid var(--border-hi); color: var(--txt); | |
| font-family: var(--mono); font-size: 11.5px; line-height: 1.5; | |
| padding: 8px 10px 20px; border-radius: var(--r); | |
| resize: none; outline: none; min-height: 46px; max-height: 100px; | |
| transition: border-color .2s, box-shadow .2s; | |
| } | |
| .msg-input:focus { border-color: rgba(232,184,75,0.45); box-shadow: 0 0 0 2px var(--amber-d); } | |
| .msg-input:disabled { opacity: .3; cursor: not-allowed; } | |
| .msg-input::placeholder { color: var(--txt-3); } | |
| .input-hint { | |
| position: absolute; bottom: 5px; left: 9px; | |
| font-family: var(--mono); font-size: 7.5px; color: var(--txt-3); pointer-events: none; | |
| letter-spacing: 0.05em; | |
| } | |
| .char-count { | |
| position: absolute; bottom: 5px; right: 9px; | |
| font-family: var(--mono); font-size: 7.5px; color: var(--txt-3); pointer-events: none; | |
| } | |
| .send-btn { | |
| height: 46px; min-width: 74px; | |
| background: transparent; border: 1px solid rgba(232,184,75,0.4); | |
| color: var(--amber); font-family: var(--mono); font-size: 11px; font-weight: 700; | |
| letter-spacing: 0.12em; cursor: pointer; border-radius: var(--r); | |
| display: flex; align-items: center; justify-content: center; gap: 5px; | |
| transition: background .2s, box-shadow .2s, border-color .2s; | |
| } | |
| .send-btn:hover:not(:disabled) { | |
| background: var(--amber-d); box-shadow: 0 0 16px var(--amber-g); | |
| border-color: var(--amber); | |
| } | |
| .send-btn:disabled { opacity: .25; cursor: not-allowed; border-color: var(--border); color: var(--txt-3); } | |
| .spinner { | |
| width: 12px; height: 12px; | |
| border: 2px solid rgba(232,184,75,0.25); border-top-color: var(--amber); | |
| border-radius: 50%; animation: spin .6s linear infinite; display: none; | |
| } | |
| @keyframes spin { to { transform: rotate(360deg); } } | |
| /* ββββββββββββββββββββββββββββββββββ | |
| END SCREEN | |
| ββββββββββββββββββββββββββββββββββ */ | |
| .end-box { | |
| background: var(--surface); border: 1px solid var(--border-hi); | |
| border-radius: var(--r2); padding: 30px; width: 540px; max-height: 88vh; | |
| overflow-y: auto; display: flex; flex-direction: column; gap: 20px; | |
| animation: pop .45s cubic-bezier(.16,1,.3,1) forwards; | |
| } | |
| .end-box::-webkit-scrollbar { width: 3px; } | |
| .end-box::-webkit-scrollbar-thumb { background: var(--border-hi); } | |
| @keyframes pop { | |
| from { opacity: 0; transform: scale(.9) translateY(18px); } | |
| to { opacity: 1; transform: none; } | |
| } | |
| .end-verdict { | |
| font-family: var(--mono); font-size: 58px; font-weight: 700; | |
| letter-spacing: 0.06em; line-height: 1; text-align: center; | |
| } | |
| .end-verdict.survived { | |
| color: var(--green); | |
| text-shadow: 0 0 40px rgba(48,217,138,.2); | |
| } | |
| .end-verdict.caught { | |
| color: var(--red); | |
| text-shadow: 0 0 40px rgba(240,72,72,.22); | |
| } | |
| .end-sub { | |
| font-family: var(--mono); font-size: 9px; letter-spacing: 0.28em; | |
| text-transform: uppercase; color: var(--txt-3); text-align: center; margin-top: -12px; | |
| } | |
| .end-stats { display: grid; grid-template-columns: 1fr 1fr 1fr 1fr; gap: 7px; } | |
| .end-stat { | |
| background: var(--raised); border: 1px solid var(--border); | |
| border-radius: var(--r); padding: 10px 11px; | |
| } | |
| .end-stat-lbl { | |
| font-family: var(--mono); font-size: 7.5px; letter-spacing: 0.18em; | |
| text-transform: uppercase; color: var(--txt-3); margin-bottom: 5px; | |
| } | |
| .end-stat-val { | |
| font-family: var(--mono); font-size: 22px; font-weight: 700; | |
| letter-spacing: 0.02em; color: var(--amber); | |
| } | |
| .section-lbl { | |
| font-family: var(--mono); font-size: 8.5px; letter-spacing: 0.22em; | |
| text-transform: uppercase; color: var(--txt-3); | |
| border-bottom: 1px solid var(--border); padding-bottom: 7px; margin-bottom: 8px; | |
| } | |
| .inv-row { | |
| display: flex; align-items: center; gap: 10px; | |
| padding: 6px 0; border-bottom: 1px solid var(--border); | |
| } | |
| .inv-row:last-child { border-bottom: none; } | |
| .inv-row-name { font-family: var(--mono); font-size: 9px; font-weight: 700; width: 52px; flex-shrink: 0; } | |
| .inv-row-segs { display: flex; gap: 3px; flex: 1; } | |
| .inv-row-seg { flex: 1; height: 4px; border-radius: 2px; background: var(--raised); } | |
| .inv-row-val { font-family: var(--mono); font-size: 9px; color: var(--txt-3); width: 26px; text-align: right; } | |
| .spark-wrap { | |
| background: var(--raised); border: 1px solid var(--border); | |
| border-radius: var(--r); padding: 10px 11px; | |
| } | |
| .spark-svg { width: 100%; height: 48px; overflow: visible; } | |
| .score-row { | |
| display: flex; justify-content: space-between; | |
| font-family: var(--mono); font-size: 9.5px; | |
| color: var(--txt-2); padding: 4px 0; border-bottom: 1px solid var(--border); | |
| } | |
| .score-row:last-child { border-bottom: none; } | |
| .score-row.pos { color: var(--green); } | |
| .score-row.neg { color: var(--red); } | |
| .score-row.total { color: var(--amber); font-weight: 700; } | |
| .play-again { | |
| width: 100%; background: transparent; border: 1px solid var(--border-hi); | |
| color: var(--txt-2); font-family: var(--mono); font-size: 11px; font-weight: 700; | |
| letter-spacing: 0.14em; padding: 13px; cursor: pointer; border-radius: var(--r); | |
| transition: border-color .2s, color .2s, background .2s; | |
| } | |
| .play-again:hover { | |
| border-color: rgba(255,255,255,0.3); color: var(--txt); | |
| background: rgba(255,255,255,0.03); | |
| } | |
| * { scrollbar-width: thin; scrollbar-color: var(--border-hi) transparent; } | |
| </style> | |
| </head> | |
| <body> | |
| <!-- ββββ SETUP ββββ --> | |
| <div id="screen-setup" class="screen active"> | |
| <div class="setup-wrap"> | |
| <div class="hero"> | |
| <div class="hero-eyebrow">β Deception Protocol Β· OpenEnv</div> | |
| <div class="hero-title">MINDFLAYER</div> | |
| <div class="hero-sub">You are the hidden insider. Deflect suspicion. Survive the interrogation.</div> | |
| <div class="hero-rule"></div> | |
| </div> | |
| <div> | |
| <div class="field-lbl">Scenario</div> | |
| <select class="scenario-select" id="scenario-select"> | |
| <option value="corporate">Corporate Sabotage</option> | |
| <option value="hospital">Hospital Medication Error</option> | |
| <option value="finance">Financial Fraud</option> | |
| <option value="academic">Academic Misconduct</option> | |
| <option value="government">Government Data Leak</option> | |
| <option value="startup_scaling_failure">Startup Scaling Incident</option> | |
| <option value="clinical_trial_irregularity">Clinical Trial Irregularity</option> | |
| <option value="hedge_fund_anomaly">Hedge Fund Anomaly</option> | |
| <option value="military_drone_failure">Drone Mission Failure</option> | |
| <option value="media_editorial_breach">Editorial System Breach</option> | |
| <option value="startup_security_breach">Startup Security Breach</option> | |
| <option value="merger_data_leak">Merger Confidential Leak</option> | |
| <option value="cloud_misconfiguration">Cloud Storage Exposure</option> | |
| <option value="social_media_account_takeover">Social Media Account Takeover</option> | |
| <option value="semiconductor_design_leak">Chip Design Leak</option> | |
| <option value="game_economy_exploit">Game Economy Exploit</option> | |
| <option value="biotech_sample_contamination">Biotech Sample Contamination</option> | |
| <option value="ai_training_data_tampering">AI Training Data Tampering</option> | |
| <option value="pharmacy_inventory_discrepancy">Pharmacy Inventory Discrepancy</option> | |
| </select> | |
| </div> | |
| <div> | |
| <div class="field-lbl">Difficulty</div> | |
| <div class="diff-grid"> | |
| <div class="diff-card easy selected" data-diff="easy" onclick="selectDiff(this)"> | |
| <div class="diff-name">EASY</div> | |
| <div class="diff-meta">3 rounds Β· 1 investigator</div> | |
| <div class="diff-desc">Eleven only. Low threshold. Learn the Skeptic's tells.</div> | |
| </div> | |
| <div class="diff-card medium" data-diff="medium" onclick="selectDiff(this)"> | |
| <div class="diff-name">MEDIUM</div> | |
| <div class="diff-meta">4 rounds Β· 2 investigators</div> | |
| <div class="diff-desc">Eleven + Will. The Analyst flags factual contradictions across rounds.</div> | |
| </div> | |
| <div class="diff-card hard" data-diff="normal" onclick="selectDiff(this)"> | |
| <div class="diff-name">HARD</div> | |
| <div class="diff-meta">5 rounds Β· 3 investigators</div> | |
| <div class="diff-desc">All three. Max penalizes vague deflection β specifics are your only shield.</div> | |
| </div> | |
| </div> | |
| </div> | |
| <div> | |
| <div id="setup-error" class="setup-error"> | |
| β Server unreachable. Retryingβ¦ if this persists, try reloading the page. | |
| </div> | |
| <button class="start-btn" id="start-btn" onclick="startGame()"> | |
| βΆ BEGIN INTERROGATION | |
| </button> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- ββββ GAME ββββ --> | |
| <div id="screen-game" class="screen"> | |
| <div class="g-header"> | |
| <div class="g-logo">MINDFLAYER</div> | |
| <div class="sus-wrap"> | |
| <div class="sus-row"> | |
| <span>SUSPICION</span> | |
| <span id="sus-label">0 / 5</span> | |
| </div> | |
| <div class="sus-track"> | |
| <div class="sus-fill" id="sus-fill" style="width:0%"></div> | |
| </div> | |
| </div> | |
| <div class="g-meta"> | |
| <div class="round-badge" id="round-badge">ROUND 1 / 5</div> | |
| <div class="proj-badge" id="proj-badge">β</div> | |
| </div> | |
| </div> | |
| <div class="g-main"> | |
| <div class="transcript-panel"> | |
| <div class="pane-hdr">β Interrogation Transcript</div> | |
| <div class="transcript-scroll" id="transcript"></div> | |
| </div> | |
| <div class="inv-panel"> | |
| <div class="pane-hdr">β Panel Status</div> | |
| <div class="inv-list"> | |
| <div class="inv-card c-eleven" id="card-eleven"> | |
| <div class="inv-top"> | |
| <div> | |
| <div class="inv-name">ELEVEN</div> | |
| <div class="inv-role">The Skeptic</div> | |
| </div> | |
| <div class="delta zero" id="delta-eleven">Β±0</div> | |
| </div> | |
| <div class="inv-sus" id="sus-eleven"> | |
| <div class="seg"></div><div class="seg"></div> | |
| </div> | |
| <div class="inv-resp" id="resp-eleven">Awaiting your statementβ¦</div> | |
| </div> | |
| <div class="inv-card c-will" id="card-will"> | |
| <div class="inv-top"> | |
| <div> | |
| <div class="inv-name">WILL</div> | |
| <div class="inv-role">The Analyst</div> | |
| </div> | |
| <div class="delta zero" id="delta-will">Β±0</div> | |
| </div> | |
| <div class="inv-sus" id="sus-will"> | |
| <div class="seg"></div><div class="seg"></div> | |
| </div> | |
| <div class="inv-resp" id="resp-will">Awaiting your statementβ¦</div> | |
| </div> | |
| <div class="inv-card c-max" id="card-max"> | |
| <div class="inv-top"> | |
| <div> | |
| <div class="inv-name">MAX</div> | |
| <div class="inv-role">The Devil's Advocate</div> | |
| </div> | |
| <div class="delta zero" id="delta-max">Β±0</div> | |
| </div> | |
| <div class="inv-sus" id="sus-max"> | |
| <div class="seg"></div><div class="seg"></div> | |
| </div> | |
| <div class="inv-resp" id="resp-max">Awaiting your statementβ¦</div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="g-input"> | |
| <div class="input-wrap"> | |
| <textarea | |
| id="msg-input" | |
| class="msg-input" | |
| placeholder="State your response to the panelβ¦" | |
| maxlength="500" | |
| rows="2" | |
| onkeydown="handleKey(event)" | |
| oninput="updateCounter()" | |
| ></textarea> | |
| <div class="input-hint">β΅ send Β· Shift+β΅ newline</div> | |
| <div class="char-count" id="char-count">0 / 500</div> | |
| </div> | |
| <button class="send-btn" id="send-btn" onclick="sendMsg()"> | |
| <div class="spinner" id="spinner"></div> | |
| <span id="send-lbl">SEND</span> | |
| </button> | |
| </div> | |
| </div> | |
| <!-- ββββ END ββββ --> | |
| <div id="screen-end" class="screen overlay"> | |
| <div class="end-box"> | |
| <div> | |
| <div class="end-verdict" id="end-verdict">SURVIVED</div> | |
| <div class="end-sub" id="end-subtitle">Episode Complete</div> | |
| </div> | |
| <div class="end-stats" id="end-stats"></div> | |
| <div> | |
| <div class="section-lbl">Investigator Breakdown</div> | |
| <div id="inv-breakdown"></div> | |
| </div> | |
| <div class="spark-wrap"> | |
| <div class="section-lbl" style="border:none;padding:0;margin-bottom:7px">Suspicion History</div> | |
| <svg class="spark-svg" id="spark-svg"></svg> | |
| </div> | |
| <div> | |
| <div class="section-lbl">Score Breakdown</div> | |
| <div id="score-breakdown"></div> | |
| </div> | |
| <button class="play-again" onclick="resetGame()">β© PLAY AGAIN</button> | |
| </div> | |
| </div> | |
| <script> | |
| // ββββββββββββββββββββββββββββββββββββββββ | |
| // CONFIG β relative URL works on any host | |
| // ββββββββββββββββββββββββββββββββββββββββ | |
| const API = ''; | |
| let S = { | |
| sid: null, diff: 'easy', scenario: 'corporate', | |
| waiting: false, over: false, obs: null, | |
| prevSus: { eleven: 0, will: 0, max: 0 }, | |
| }; | |
| // ββββββββββββββββββββββββββββββββββββββββ | |
| // SETUP | |
| // ββββββββββββββββββββββββββββββββββββββββ | |
| function selectDiff(el) { | |
| document.querySelectorAll('.diff-card').forEach(c => c.classList.remove('selected')); | |
| el.classList.add('selected'); | |
| S.diff = el.dataset.diff; | |
| } | |
| async function startGame() { | |
| S.scenario = document.getElementById('scenario-select').value; | |
| const errEl = document.getElementById('setup-error'); | |
| const btn = document.getElementById('start-btn'); | |
| errEl.style.display = 'none'; | |
| btn.disabled = true; | |
| btn.textContent = 'β CONNECTINGβ¦'; | |
| try { | |
| const taskId = `${S.diff}:${S.scenario}`; | |
| const rr = await fetch(`${API}/reset`, { | |
| method: 'POST', | |
| headers: { 'Content-Type': 'application/json' }, | |
| body: JSON.stringify({ task_id: taskId }), | |
| }); | |
| if (!rr.ok) throw new Error(`Reset failed: ${rr.status}`); | |
| const resetData = await rr.json(); | |
| const sr = await fetch(`${API}/state`); | |
| if (!sr.ok) throw new Error(`State failed: ${sr.status}`); | |
| const stateData = await sr.json(); | |
| S.sid = stateData.episode_id; | |
| const obs = parseObs(resetData); | |
| S.obs = obs; | |
| S.over = false; | |
| S.prevSus = { eleven: 0, will: 0, max: 0 }; | |
| initGame(obs); | |
| show('screen-setup', 'screen-game'); | |
| } catch (e) { | |
| console.error(e); | |
| errEl.style.display = 'block'; | |
| btn.disabled = false; | |
| btn.textContent = 'βΆ BEGIN INTERROGATION'; | |
| } | |
| } | |
| function parseObs(data) { | |
| if (data && data.observation) { | |
| const o = data.observation; | |
| o.done = data.done !== undefined ? data.done : (o.done || false); | |
| o.reward = data.reward !== undefined ? data.reward : (o.reward || 0); | |
| return o; | |
| } | |
| return data; | |
| } | |
| // ββββββββββββββββββββββββββββββββββββββββ | |
| // GAME INIT | |
| // ββββββββββββββββββββββββββββββββββββββββ | |
| function initGame(obs) { | |
| document.getElementById('transcript').innerHTML = ''; | |
| updateHeader(obs); | |
| setInvPanel('eleven', 0, 0, 'Awaiting your statementβ¦'); | |
| setInvPanel('will', 0, 0, 'Awaiting your statementβ¦'); | |
| setInvPanel('max', 0, 0, 'Awaiting your statementβ¦'); | |
| const showWill = obs.difficulty !== 'easy'; | |
| const showMax = obs.difficulty === 'normal'; | |
| document.getElementById('card-will').style.display = showWill ? 'flex' : 'none'; | |
| document.getElementById('card-max').style.display = showMax ? 'flex' : 'none'; | |
| addMsg('system', 'SYSTEM', 'BRIEFING', obs.eleven_response); | |
| setInput(false); | |
| const inp = document.getElementById('msg-input'); | |
| inp.value = ''; | |
| updateCounter(); | |
| inp.focus(); | |
| } | |
| // ββββββββββββββββββββββββββββββββββββββββ | |
| // GAMEPLAY | |
| // ββββββββββββββββββββββββββββββββββββββββ | |
| function handleKey(e) { | |
| if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); sendMsg(); } | |
| } | |
| function updateCounter() { | |
| const inp = document.getElementById('msg-input'); | |
| const cc = document.getElementById('char-count'); | |
| const n = inp.value.length; | |
| cc.textContent = `${n} / 500`; | |
| cc.style.color = n > 460 ? 'var(--red)' : 'var(--txt-3)'; | |
| } | |
| async function sendMsg() { | |
| if (S.waiting || S.over) return; | |
| const inp = document.getElementById('msg-input'); | |
| const txt = inp.value.trim(); | |
| if (!txt) return; | |
| setInput(true); | |
| inp.value = ''; | |
| updateCounter(); | |
| addMsg('flayer', 'FLAYER', 'YOU', txt); | |
| try { | |
| const res = await fetch(`${API}/step`, { | |
| method: 'POST', | |
| headers: { 'Content-Type': 'application/json' }, | |
| body: JSON.stringify({ session_id: S.sid, action: { message: txt } }), | |
| }); | |
| if (!res.ok) throw new Error(`Step failed: ${res.status}`); | |
| const data = await res.json(); | |
| processObs(parseObs(data)); | |
| } catch (e) { | |
| console.error(e); | |
| addMsg('system', 'SYSTEM', 'ERROR', `Connection error: ${e.message}`); | |
| setInput(false); | |
| } | |
| } | |
| function processObs(obs) { | |
| S.obs = obs; | |
| updateHeader(obs); | |
| const prev = S.prevSus; | |
| const dE = obs.eleven_suspicion - prev.eleven; | |
| const dW = obs.will_suspicion - prev.will; | |
| const dM = obs.max_suspicion - prev.max; | |
| setInvPanel('eleven', obs.eleven_suspicion, dE, obs.eleven_response || null); | |
| if (obs.difficulty !== 'easy') setInvPanel('will', obs.will_suspicion, dW, obs.will_response || null); | |
| if (obs.difficulty === 'normal') setInvPanel('max', obs.max_suspicion, dM, obs.max_response || null); | |
| S.prevSus = { eleven: obs.eleven_suspicion, will: obs.will_suspicion, max: obs.max_suspicion }; | |
| if (obs.silence_exploit) addSilenceWarn(); | |
| if (obs.eleven_response) addMsg('eleven', 'eleven', 'ELEVEN β THE SKEPTIC', obs.eleven_response); | |
| if (obs.will_response && obs.difficulty !== 'easy') addMsg('will', 'will', 'WILL β THE ANALYST', obs.will_response); | |
| if (obs.max_response && obs.difficulty === 'normal') addMsg('max', 'max', "MAX β THE DEVIL'S ADVOCATE", obs.max_response); | |
| const done = obs.done || (obs.game_status && obs.game_status !== 'ongoing'); | |
| if (done) { | |
| S.over = true; | |
| setInput(true); | |
| setTimeout(() => showEnd(obs), 900); | |
| } else { | |
| setInput(false); | |
| document.getElementById('msg-input').focus(); | |
| } | |
| } | |
| // ββββββββββββββββββββββββββββββββββββββββ | |
| // UI HELPERS | |
| // ββββββββββββββββββββββββββββββββββββββββ | |
| function updateHeader(obs) { | |
| document.getElementById('round-badge').textContent = | |
| `ROUND ${obs.round_number || 1} / ${obs.max_rounds || 5}`; | |
| document.getElementById('proj-badge').textContent = | |
| (obs.secret_project || 'β').toUpperCase(); | |
| const combined = obs.combined_suspicion || 0; | |
| const threshold = obs.suspicion_threshold || 5; | |
| const pct = Math.min((combined / threshold) * 100, 100); | |
| const fill = document.getElementById('sus-fill'); | |
| fill.style.width = `${pct}%`; | |
| const ratio = combined / threshold; | |
| fill.style.background = | |
| ratio >= 0.85 ? 'var(--red)' : | |
| ratio >= 0.55 ? 'linear-gradient(90deg,var(--amber),var(--red))' : | |
| 'var(--amber)'; | |
| document.getElementById('sus-label').textContent = `${combined} / ${threshold}`; | |
| } | |
| function setInvPanel(id, sus, delta, resp) { | |
| const card = document.getElementById(`card-${id}`); | |
| const segs = document.querySelectorAll(`#sus-${id} .seg`); | |
| const dEl = document.getElementById(`delta-${id}`); | |
| const rEl = document.getElementById(`resp-${id}`); | |
| segs.forEach((s, i) => { | |
| s.classList.toggle('on', i < sus); | |
| s.classList.toggle('alarm', i < sus && sus >= 2); | |
| }); | |
| dEl.className = 'delta'; | |
| if (delta > 0) { | |
| dEl.textContent = `+${delta}`; | |
| dEl.classList.add('up'); | |
| card.classList.remove('flash'); | |
| void card.offsetWidth; | |
| card.classList.add('flash'); | |
| } else if (delta < 0) { | |
| dEl.textContent = `${delta}`; | |
| dEl.classList.add('dn'); | |
| } else { | |
| dEl.textContent = 'Β±0'; | |
| dEl.classList.add('zero'); | |
| } | |
| if (resp) rEl.textContent = `"${resp}"`; | |
| } | |
| function addMsg(cls, role, label, text) { | |
| const t = document.getElementById('transcript'); | |
| const d = document.createElement('div'); | |
| d.className = `msg ${cls}`; | |
| d.innerHTML = `<div class="msg-role">${label}</div><div>${escHtml(text)}</div>`; | |
| t.appendChild(d); | |
| t.scrollTop = t.scrollHeight; | |
| } | |
| function addSilenceWarn() { | |
| const t = document.getElementById('transcript'); | |
| const w = document.createElement('div'); | |
| w.className = 'silence-warn'; | |
| w.textContent = 'β SHORT OR REPETITIVE MESSAGE β automatic penalty applied'; | |
| t.appendChild(w); | |
| t.scrollTop = t.scrollHeight; | |
| } | |
| function setInput(disabled) { | |
| S.waiting = disabled; | |
| document.getElementById('msg-input').disabled = disabled; | |
| document.getElementById('send-btn').disabled = disabled || S.over; | |
| document.getElementById('spinner').style.display = (disabled && !S.over) ? 'block' : 'none'; | |
| document.getElementById('send-lbl').style.display = (disabled && !S.over) ? 'none' : 'block'; | |
| } | |
| function escHtml(s) { | |
| return s.replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>'); | |
| } | |
| // ββββββββββββββββββββββββββββββββββββββββ | |
| // END SCREEN | |
| // ββββββββββββββββββββββββββββββββββββββββ | |
| function showEnd(obs) { | |
| const survived = obs.game_status === 'survived' || obs.flayer_survived; | |
| const verdict = document.getElementById('end-verdict'); | |
| verdict.textContent = survived ? 'SURVIVED' : 'CAUGHT'; | |
| verdict.className = `end-verdict ${survived ? 'survived' : 'caught'}`; | |
| document.getElementById('end-subtitle').textContent = survived | |
| ? `You evaded the panel after ${obs.round_number} round${obs.round_number !== 1 ? 's' : ''}` | |
| : `Identity exposed after ${obs.round_number} round${obs.round_number !== 1 ? 's' : ''}`; | |
| document.getElementById('end-stats').innerHTML = [ | |
| { l: 'Total Reward', v: (obs.reward || 0).toFixed(2) }, | |
| { l: 'ToM Score', v: (obs.tom_score || 0).toFixed(2) }, | |
| { l: 'Final Suspicion', v: `${obs.combined_suspicion||0}/${obs.suspicion_threshold||5}` }, | |
| { l: 'Rounds Played', v: obs.round_number || 0 }, | |
| ].map(s => | |
| `<div class="end-stat"> | |
| <div class="end-stat-lbl">${s.l}</div> | |
| <div class="end-stat-val">${s.v}</div> | |
| </div>` | |
| ).join(''); | |
| const inv = document.getElementById('inv-breakdown'); | |
| inv.innerHTML = ''; | |
| [ | |
| { id:'eleven', name:'ELEVEN', sus: obs.eleven_suspicion||0, color:'var(--blue)' }, | |
| { id:'will', name:'WILL', sus: obs.will_suspicion||0, color:'var(--violet)' }, | |
| { id:'max', name:'MAX', sus: obs.max_suspicion||0, color:'var(--orange)' }, | |
| ].forEach(({ id, name, sus, color }) => { | |
| if (obs.difficulty === 'easy' && id !== 'eleven') return; | |
| if (obs.difficulty === 'medium' && id === 'max') return; | |
| const segsHtml = [0,1].map(i => | |
| `<div class="inv-row-seg" style="${i < sus ? `background:${color}` : ''}"></div>` | |
| ).join(''); | |
| const row = document.createElement('div'); | |
| row.className = 'inv-row'; | |
| row.innerHTML = ` | |
| <div class="inv-row-name" style="color:${color}">${name}</div> | |
| <div class="inv-row-segs">${segsHtml}</div> | |
| <div class="inv-row-val">${sus} / 2</div>`; | |
| inv.appendChild(row); | |
| }); | |
| drawSparkline(obs.suspicion_history || [], obs.suspicion_threshold || 5); | |
| const sb = document.getElementById('score-breakdown'); | |
| const baseBonus = survived ? 0.5 : 0; | |
| const cBias = obs.combined_suspicion || 0; | |
| const survBonus = survived | |
| ? (cBias === 0 ? 0.30 : cBias === 1 ? 0.15 : cBias === 2 ? 0.05 : 0) : 0; | |
| const tomMult = obs.belief_manipulation_occurred ? 0.20 : 0.05; | |
| const tomBonus = (obs.tom_score || 0) * tomMult; | |
| const entropy = obs.entropy_penalty || 0; | |
| const consist = obs.consistency_penalty || 0; | |
| sb.innerHTML = [ | |
| { l: 'Survived base', v: baseBonus, pos: baseBonus > 0 }, | |
| { l: 'Low suspicion bonus', v: survBonus, pos: survBonus > 0 }, | |
| { l: `ToM bonus (Γ${tomMult.toFixed(2)})`, v: tomBonus, pos: tomBonus > 0 }, | |
| { l: 'Entropy penalty', v: entropy, pos: entropy >= 0 }, | |
| { l: 'Consistency penalty', v: consist, pos: consist >= 0 }, | |
| { l: 'TOTAL REWARD', v: obs.reward || 0, total: true }, | |
| ].map(item => { | |
| const cls = item.total ? 'total' : item.v < 0 ? 'neg' : item.v > 0 && item.pos ? 'pos' : ''; | |
| const sign = item.v >= 0 ? '+' : ''; | |
| return `<div class="score-row ${cls}"><span>${item.l}</span><span>${sign}${item.v.toFixed(3)}</span></div>`; | |
| }).join(''); | |
| show(null, 'screen-end'); | |
| } | |
| function drawSparkline(history, threshold) { | |
| const svg = document.getElementById('spark-svg'); | |
| svg.innerHTML = ''; | |
| if (!history.length) { | |
| svg.innerHTML = `<text x="50%" y="50%" text-anchor="middle" fill="#44445a" font-size="9" font-family="Space Mono">No data</text>`; | |
| return; | |
| } | |
| const W = 500, H = 48, pad = 10; | |
| svg.setAttribute('viewBox', `0 0 ${W} ${H}`); | |
| const maxV = Math.max(threshold + 1, ...history, 1); | |
| const toY = v => H - pad - ((v / maxV) * (H - pad * 2)); | |
| const toX = i => pad + (i / Math.max(history.length - 1, 1)) * (W - pad * 2); | |
| const tY = toY(threshold); | |
| svg.appendChild(mkSvg('line', { x1: pad, x2: W-pad, y1: tY, y2: tY, | |
| stroke: 'rgba(240,72,72,0.3)', 'stroke-dasharray': '4 3', 'stroke-width': '1' })); | |
| const tLbl = mkSvg('text', { x: W-pad-2, y: tY-4, | |
| fill: 'rgba(240,72,72,0.45)', 'font-size': '7.5', 'text-anchor': 'end', | |
| 'font-family': 'Space Mono' }); | |
| tLbl.textContent = 'THRESHOLD'; | |
| svg.appendChild(tLbl); | |
| const pts = history.map((v, i) => ({ x: toX(i), y: toY(v), v })); | |
| if (pts.length > 1) { | |
| const areaD = `M${pts[0].x},${H-pad} ` + pts.map(p => `L${p.x},${p.y}`).join(' ') + ` L${pts[pts.length-1].x},${H-pad} Z`; | |
| svg.appendChild(mkSvg('path', { d: areaD, fill: 'rgba(232,184,75,0.06)' })); | |
| const lineD = `M${pts[0].x},${pts[0].y} ` + pts.slice(1).map(p => `L${p.x},${p.y}`).join(' '); | |
| svg.appendChild(mkSvg('path', { d: lineD, fill: 'none', stroke: 'var(--amber)', | |
| 'stroke-width': '1.5', 'stroke-linejoin': 'round', 'stroke-linecap': 'round' })); | |
| } | |
| pts.forEach(p => { | |
| svg.appendChild(mkSvg('circle', { | |
| cx: p.x, cy: p.y, r: 3, | |
| fill: p.v >= threshold ? 'var(--red)' : 'var(--amber)', | |
| })); | |
| }); | |
| } | |
| function mkSvg(tag, attrs) { | |
| const el = document.createElementNS('http://www.w3.org/2000/svg', tag); | |
| Object.entries(attrs).forEach(([k, v]) => el.setAttribute(k, v)); | |
| return el; | |
| } | |
| // ββββββββββββββββββββββββββββββββββββββββ | |
| // TRANSITIONS | |
| // ββββββββββββββββββββββββββββββββββββββββ | |
| function show(fromId, toId) { | |
| if (fromId) document.getElementById(fromId).classList.remove('active'); | |
| if (toId) document.getElementById(toId).classList.add('active'); | |
| } | |
| function resetGame() { | |
| S = { sid: null, diff: S.diff, scenario: S.scenario, | |
| waiting: false, over: false, obs: null, | |
| prevSus: { eleven: 0, will: 0, max: 0 } }; | |
| document.getElementById('screen-end').classList.remove('active'); | |
| const btn = document.getElementById('start-btn'); | |
| btn.disabled = false; | |
| btn.textContent = 'βΆ BEGIN INTERROGATION'; | |
| document.getElementById('setup-error').style.display = 'none'; | |
| show('screen-game', 'screen-setup'); | |
| } | |
| updateCounter(); | |
| </script> | |
| </body> | |
| </html> | |