2PlayerGame/chapter3/public/index.html
2026-07-23 17:03:26 +03:00

225 lines
15 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="uk">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Невпізнаний — детектив на двох, розділ 3</title>
<style>
:root {
--night:#0b0d12; --panel:#12151c; --panel2:#1a1f29; --line:#262c38;
--txt:#cfd6df; --dim:#7d8794; --acc:#e8b04b; --red:#c94f4f; --green:#5aa870; --blue:#5b8dbf;
--paper:#e9ddc0; --paper2:#dcCfae; --ink:#282218; --inkdim:#6f6450; --paperline:#c3b28b;
--amber:#ffb454; --amberdim:#8a6a34; --crt:#0e0903;
--noise:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='140' height='140'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='2'/><feColorMatrix values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 .05 0'/></filter><rect width='140' height='140' filter='url(%23n)'/></svg>");
}
* { box-sizing:border-box; margin:0; }
html { accent-color:var(--acc); }
body { background:var(--night); color:var(--txt); font:15px/1.45 Georgia, 'Times New Roman', serif; height:100vh; overflow:hidden; }
button { font:inherit; color:var(--txt); background:var(--panel2); border:1px solid var(--line); border-radius:4px; padding:6px 12px; cursor:pointer; }
button:hover { border-color:var(--acc); }
button.primary { background:var(--acc); color:#14100a; font-weight:bold; }
button.danger { background:var(--red); color:#fff; }
button:disabled { opacity:.5; cursor:default; }
input, select, textarea { font:inherit; color:var(--txt); background:#0d1116; border:1px solid var(--line); border-radius:4px; padding:6px 10px; }
input:focus, textarea:focus { outline:none; border-color:var(--acc); }
h3 { font-size:15px; color:var(--acc); margin-bottom:6px; letter-spacing:.4px; }
.dim { color:var(--dim); } .small { font-size:12.5px; }
ul { padding-left:18px; } li { margin:4px 0; }
/* ---------- Лобі: дощова ніч ---------- */
#lobby { position:fixed; inset:0; display:flex; align-items:center; justify-content:center; z-index:50; overflow:hidden;
background:
radial-gradient(ellipse at 20% 110%, rgba(232,176,75,.10), transparent 45%),
radial-gradient(ellipse at 85% 105%, rgba(91,141,191,.09), transparent 40%),
linear-gradient(180deg, #05070c 0%, #0a0e16 55%, #11141c 100%); }
#lobby::before { content:''; position:absolute; inset:-60px; pointer-events:none; opacity:.5;
background:repeating-linear-gradient(103deg, transparent 0 16px, rgba(175,195,220,.05) 16px 17px);
animation:rainfall 0.9s linear infinite; }
@keyframes rainfall { to { transform:translate(-34px, 120px); } }
#lobby::after { content:''; position:absolute; left:0; right:0; bottom:0; height:26%; pointer-events:none; opacity:.9;
background:
linear-gradient(0deg, #04060a 30%, transparent),
repeating-linear-gradient(90deg, transparent 0 46px, rgba(20,26,36,.9) 46px 118px, transparent 118px 150px); }
#lobby .card { position:relative; z-index:2; background:rgba(16,19,27,.94); border:1px solid var(--line); border-radius:10px;
padding:36px 40px; width:460px; box-shadow:0 30px 80px rgba(0,0,0,.7), inset 0 0 60px rgba(0,0,0,.35); }
#lobby h1 { font-size:34px; color:var(--txt); letter-spacing:8px; margin-bottom:2px;
text-shadow:0 0 22px rgba(201,79,79,.5), 0 2px 0 #000; }
#lobby h1::after { content:'СПРАВУ ВІДКРИТО'; display:block; font-size:10px; letter-spacing:4px; color:var(--red);
border:1px solid var(--red); width:max-content; padding:2px 8px; margin-top:8px; transform:rotate(-2deg); opacity:.85; }
#lobby .row { margin:16px 0; display:flex; gap:8px; }
#lobby input { flex:1; text-transform:uppercase; letter-spacing:2px; }
.rolebtn { flex:1; padding:12px; text-align:left; transition:transform .12s; }
.rolebtn:hover { transform:translateY(-2px); }
.rolebtn b { display:block; color:var(--acc); }
.rolebtn[data-role="analyst"] b { color:var(--amber); font-family:'Courier New', monospace; letter-spacing:1px; }
/* ---------- Каркас ---------- */
#app { display:none; height:100vh; flex-direction:column; }
#app.on { display:flex; }
header { display:flex; align-items:center; gap:14px; padding:8px 14px; background:linear-gradient(180deg, #171b24, #121620);
border-bottom:1px solid var(--line); box-shadow:0 4px 16px rgba(0,0,0,.4); }
header .title { color:var(--txt); font-weight:bold; font-size:16px; letter-spacing:4px; text-shadow:0 0 14px rgba(201,79,79,.4); }
.badge { font-size:12px; border:1px solid var(--line); border-radius:2px; padding:2px 9px; color:var(--dim); letter-spacing:.5px; }
.badge.on { color:var(--green); border-color:var(--green); }
#main { flex:1; display:flex; min-height:0; }
#stage { flex:1; min-width:0; display:flex; flex-direction:column; padding:12px; gap:8px; overflow:auto; }
#side { width:400px; border-left:1px solid #1c130c; display:flex; flex-direction:column; min-height:0;
background:linear-gradient(160deg, #33261a, #2a1f14 60%, #241a10); background-blend-mode:multiply; }
#side::before { content:''; position:absolute; } /* резерв */
/* ---------- Дошка: корок і папір ---------- */
.tabs { display:flex; border-bottom:2px solid rgba(0,0,0,.35); background:rgba(0,0,0,.18); }
.tabs button { flex:1; border:none; border-radius:0; background:none; padding:9px 4px; color:#b7a284; border-bottom:2px solid transparent; letter-spacing:1px; }
.tabs button.on { color:var(--paper); border-bottom-color:var(--acc); text-shadow:0 1px 0 #000; }
.tabbody { flex:1; overflow-y:auto; padding:12px 12px 20px; background-image:var(--noise); }
.tabbody > .dim { color:#c9b596; text-shadow:0 1px 0 rgba(0,0,0,.5); }
#side .card { position:relative; background:var(--paper); background-image:var(--noise); color:var(--ink);
border:1px solid var(--paperline); border-radius:2px; padding:14px 11px 9px; margin:0 0 12px;
box-shadow:0 4px 10px rgba(0,0,0,.55); }
#side .card:nth-child(odd) { transform:rotate(.5deg); }
#side .card:nth-child(3n) { transform:rotate(-.6deg); }
#side .card::before { content:''; position:absolute; top:-5px; left:50%; width:11px; height:11px; margin-left:-6px;
border-radius:50%; background:radial-gradient(circle at 35% 30%, #ff9a8a, #a72a1e 65%); box-shadow:0 2px 3px rgba(0,0,0,.6); }
#side .card .dim, #side .card .small.dim { color:var(--inkdim); }
#side .card b { color:#1d1812; }
#side .card input { background:transparent; border:none; border-bottom:1px dashed #a5946e; border-radius:0; color:var(--ink); padding:3px 2px; }
#side .card input::placeholder { color:#a5946e; }
#side button { background:#d9cba6; color:var(--ink); border:1px solid #b3a077; }
#side button:hover { border-color:#7a1f1f; }
#side .tag { font-size:10.5px; background:transparent; border:1px solid #b3a077; color:var(--inkdim); border-radius:2px; padding:0 5px; }
.card .t { display:flex; gap:6px; align-items:baseline; }
.card .t b { flex:1; }
.mk { display:flex; gap:4px; margin-top:6px; }
.mk button { padding:1px 8px; font-size:12px; }
.mk button.on { border-color:#7a1f1f; color:#7a1f1f; font-weight:bold; }
#side .card.cross { opacity:.55; }
#side .card.cross::after { content:'✗'; position:absolute; inset:0; display:flex; align-items:center; justify-content:center;
font-size:64px; color:rgba(167,42,30,.35); transform:rotate(-14deg); pointer-events:none; }
#side .card.cross b { text-decoration:line-through; }
#side .card.tick { border-color:#4d7a44; box-shadow:0 4px 10px rgba(0,0,0,.55), inset 0 0 0 2px rgba(77,122,68,.35); }
.pinbtn { background:none; border:none; opacity:.45; font-size:15px; padding:0 4px; }
.pinbtn.on { opacity:1; filter:drop-shadow(0 0 4px rgba(232,176,75,.8)); }
/* ---------- Сцена: польовий ---------- */
#cv { width:100%; border:1px solid #1c222c; border-radius:10px; background:#0a0e12; display:block;
box-shadow:0 0 0 1px #04060a, 0 14px 44px rgba(0,0,0,.6); }
#fieldhint { color:#8fa6bd; font-size:13px; min-height:18px; font-family:'Courier New', monospace; letter-spacing:.4px;
text-shadow:0 0 8px rgba(120,160,210,.35); }
#fieldhint::before { content:'▸ '; color:var(--acc); }
/* ---------- Сцена: аналітик = CRT-термінал ---------- */
.role-analyst #stage { position:relative; margin:10px; border-radius:10px; background:var(--crt);
border:1px solid #33230d; box-shadow:inset 0 0 140px rgba(255,170,60,.07), 0 12px 40px rgba(0,0,0,.6);
color:var(--amber); font-family:'Courier New', monospace; animation:crtflicker 7s infinite; }
.role-analyst #stage::after { content:''; position:fixed; pointer-events:none; z-index:5; inset:0;
background:repeating-linear-gradient(0deg, rgba(0,0,0,.14) 0 1px, transparent 1px 3px); mix-blend-mode:multiply; }
@keyframes crtflicker { 0%,94%,100% { opacity:1; } 95% { opacity:.96; } 96% { opacity:1; } 98% { opacity:.985; } }
.role-analyst #stage h3, .role-analyst #stage .syshead { color:var(--amber); text-shadow:0 0 8px rgba(255,180,84,.5); }
.role-analyst #stage .dim { color:var(--amberdim); }
.role-analyst #stage button { background:transparent; color:var(--amber); border:1px solid var(--amberdim); border-radius:2px; font-family:inherit; }
.role-analyst #stage button:hover:not(:disabled) { border-color:var(--amber); box-shadow:0 0 10px rgba(255,180,84,.25); }
.role-analyst #stage button.primary { background:rgba(255,180,84,.16); color:var(--amber); font-weight:bold; }
.role-analyst #stage input, .role-analyst #stage select, .role-analyst #stage textarea {
background:#080502; color:var(--amber); border:1px solid #3a2a10; font-family:inherit; border-radius:2px; }
.role-analyst #stage .card { background:#120b03; border:1px dashed #45330f; border-radius:2px; padding:9px 11px; margin-bottom:8px; }
.role-analyst #stage .card.tick { border-color:var(--green); border-style:solid; }
.role-analyst #stage table th { color:var(--amberdim); }
.role-analyst #stage th, .role-analyst #stage td { border-bottom:1px solid #33240c; }
.role-analyst #stage tr.rowlink:hover td { background:rgba(255,180,84,.07); }
.role-analyst #cv { filter:sepia(.35) hue-rotate(-22deg) saturate(1.5) contrast(1.05); border-color:#33230d; }
.role-analyst #stage details summary { cursor:pointer; color:var(--amberdim); }
.atabs { display:flex; gap:6px; flex-wrap:wrap; }
.atabs button.on { border-color:var(--amber) !important; color:var(--amber); box-shadow:0 0 10px rgba(255,180,84,.3); }
.apanel { display:none; } .apanel.on { display:block; }
table { width:100%; border-collapse:collapse; font-size:13.5px; }
th, td { text-align:left; padding:4px 8px; border-bottom:1px solid var(--line); }
th { color:var(--dim); font-weight:normal; }
tr.rowlink { cursor:pointer; } tr.rowlink:hover td { background:var(--panel2); }
tr.cross td { opacity:.45; text-decoration:line-through; }
tr.tick td { color:var(--green); }
tr.hl td { background:rgba(232,176,75,.1); }
.filters { display:flex; gap:8px; flex-wrap:wrap; margin:8px 0; align-items:center; }
.filters select, .filters input { width:130px; }
.syshead { color:var(--dim); text-transform:uppercase; font-size:12px; letter-spacing:2px; margin:14px 0 6px; }
.syshead::before { content:'— '; opacity:.5; }
/* ---------- Модалки: паперовий протокол ---------- */
.modal { position:fixed; inset:0; background:rgba(2,4,8,.72); display:flex; align-items:center; justify-content:center; z-index:40;
backdrop-filter:blur(2px); }
.modal > div { background:var(--paper); background-image:var(--noise); color:var(--ink);
border:1px solid #b6a67e; border-radius:3px; padding:22px 24px; width:min(600px, 94vw); max-height:88vh; overflow-y:auto;
box-shadow:0 30px 90px rgba(0,0,0,.8), inset 0 0 0 6px rgba(0,0,0,.03); font-family:Georgia, serif; }
.modal h3 { color:#7a1f1f; border-bottom:2px solid rgba(122,31,31,.5); padding-bottom:5px; margin-bottom:10px;
text-transform:uppercase; letter-spacing:1.5px; font-size:14px; }
.modal .dim, .modal .small.dim { color:var(--inkdim); }
.modal .syshead { color:#7a1f1f; opacity:.8; }
.modal button { background:#d9cba6; color:var(--ink); border:1px solid #b3a077; border-radius:2px; }
.modal button:hover { border-color:#7a1f1f; }
.modal button.primary { background:#7a1f1f; color:var(--paper); }
.modal button.danger { background:#7a1f1f; color:var(--paper); letter-spacing:1px; }
.modal input, .modal select, .modal textarea { background:rgba(255,255,255,.5); color:var(--ink); border:1px solid #b3a077; border-radius:2px; }
.modal th, .modal td { border-bottom:1px solid #cbbd9b; }
.modal th { color:var(--inkdim); }
.modal .tag { border:1px solid #b3a077; color:var(--inkdim); background:transparent; }
.modal .card { background:rgba(255,255,255,.35); border:1px solid #c3b28b; border-radius:2px; padding:9px 11px; margin-bottom:8px; }
.modal label { color:var(--ink); }
.grid { display:grid; grid-template-columns:repeat(auto-fill,minmax(110px,1fr)); gap:8px; margin-top:8px; }
/* ---------- Тости: телеграма ---------- */
#toasts { position:fixed; bottom:18px; left:50%; transform:translateX(-50%); display:flex; flex-direction:column; gap:6px; z-index:60; }
.toast { background:var(--paper); background-image:var(--noise); color:var(--ink); border-top:3px double #7a1f1f; border-bottom:3px double #7a1f1f;
padding:8px 18px; animation:fade 4s forwards; box-shadow:0 8px 24px rgba(0,0,0,.6); font-size:14px; }
@keyframes fade { 0%,80% { opacity:1 } 100% { opacity:0 } }
/* ---------- Фінал ---------- */
#endscreen p { margin:10px 0; }
#endscreen h3 { display:inline-block; transform:rotate(-2deg); border:3px solid #7a1f1f; padding:6px 14px;
font-size:20px; letter-spacing:3px; box-shadow:none; }
</style>
</head>
<body>
<div id="lobby">
<div class="card">
<h1>НЕВПІЗНАНИЙ</h1>
<div class="dim" style="margin-top:10px">Детектив на двох • розділ 3 • кожна справа — нова</div>
<div class="row"><input id="code" maxlength="24" placeholder="КОД СЕСІЇ (він же — справа)"></div>
<div class="row">
<button class="rolebtn" data-role="field"><b>Польовий детектив</b><span class="small dim">район, обшуки, допити</span></button>
<button class="rolebtn" data-role="analyst"><b>&gt; АНАЛІТИК_</b><span class="small dim">бази, камери, лабораторія</span></button>
</div>
<div class="dim small">Той самий код — та сама справа і її збереження. Новий код — цілком нова справа.</div>
</div>
</div>
<div id="app">
<header>
<span class="title">НЕВПІЗНАНИЙ</span>
<span class="badge" id="b-session"></span>
<span class="badge" id="b-field">поле</span>
<span class="badge" id="b-analyst">аналітик</span>
<span style="flex:1"></span>
<button id="sndbtn" class="small" title="звук">🔊</button>
<button id="introbtn" class="small">Справа</button>
<button id="accusebtn" class="danger">ЗВИНУВАЧЕННЯ</button>
</header>
<div id="main">
<div id="stage"></div>
<div id="side">
<div class="tabs" id="sidetabs">
<button data-tab="ev" class="on">Докази</button>
<button data-tab="notes">Нотатки</button>
</div>
<div class="tabbody" id="sidebody"></div>
</div>
</div>
</div>
<div id="toasts"></div>
<script src="sound.js"></script>
<script src="client.js"></script>
<script src="field.js"></script>
<script src="analyst.js"></script>
</body>
</html>