144 lines
6.5 KiB
HTML
144 lines
6.5 KiB
HTML
<!doctype html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<meta name="viewport" content="width=device-width,initial-scale=1">
|
|
<title>Station Master — replays</title>
|
|
<style>
|
|
:root{--bg:#12151a;--fg:#e6e9ee;--dim:#8b94a3;--line:#2c333d;--panel:#1a1f26}
|
|
*{box-sizing:border-box}
|
|
body{margin:0;background:var(--bg);color:var(--fg);
|
|
font:14px/1.5 ui-monospace,SFMono-Regular,Menlo,Consolas,monospace}
|
|
a{color:#5aa9e6}
|
|
header{background:var(--panel);border-bottom:1px solid var(--line);padding:10px 16px;
|
|
display:flex;gap:18px;align-items:baseline;flex-wrap:wrap;position:sticky;top:0;z-index:5}
|
|
header b{font-size:16px}
|
|
.home{color:inherit;text-decoration:none;border-bottom:1px dotted #5f6b7a}
|
|
.home:hover{color:#5aa9e6}
|
|
.build{margin-left:auto;font-size:11px;opacity:.7}
|
|
main{padding:18px;max-width:1300px;margin:0 auto}
|
|
h2{font-size:12px;text-transform:uppercase;letter-spacing:.09em;color:var(--dim);margin:0 0 8px}
|
|
section{background:var(--panel);border:1px solid var(--line);border-radius:8px;padding:14px 16px;margin-bottom:14px}
|
|
.dim{color:var(--dim)}
|
|
.sm{font-size:11px}
|
|
button{background:#2a3038;color:var(--fg);border:1px solid var(--line);border-radius:5px;
|
|
padding:6px 11px;margin:2px 4px 2px 0;cursor:pointer;font:inherit;font-size:13px;text-align:left}
|
|
button:hover{background:#39424e;border-color:#4d6fa8}
|
|
button.entry{display:block;width:100%;margin-bottom:6px}
|
|
#perr{color:#e58080;min-height:18px;font-size:12px}
|
|
input[type=file]{font:inherit;font-size:12px;color:var(--dim)}
|
|
/* viewer */
|
|
#viewer{display:none}
|
|
.vbar{display:flex;gap:6px;align-items:center;flex-wrap:wrap;margin-bottom:10px}
|
|
.vgrid{display:grid;grid-template-columns:minmax(0,1fr) 380px;gap:14px;align-items:start}
|
|
@media(max-width:1100px){.vgrid{grid-template-columns:1fr}}
|
|
.scroll{overflow-x:auto}
|
|
#vlog{max-height:420px;overflow:auto;font-size:12px}
|
|
.line{padding:1px 0}
|
|
/* Auto-hide, matching the playable page and the standalone replay. Folded leaves a summary rather
|
|
than nothing, because a panel that disappears reads as broken instead of folded away. */
|
|
button.ghost{background:#222831;border:1px solid #4a5361;color:#c6ccd6;font-size:11px;
|
|
padding:2px 9px;margin-left:10px;text-transform:none;letter-spacing:0;vertical-align:middle}
|
|
button.ghost:hover{border-color:#4d6fa8;color:#fff}
|
|
#vdistrict.folded .scroll{display:none}
|
|
#vdistrict.folded #vdistrictsummary{display:block;padding:2px 0}
|
|
#vdistrictsummary{display:none}
|
|
.line.now{background:rgba(90,169,230,.10)}
|
|
.t-good{color:#8fd6a0}.t-bad{color:#e58080}.t-clock{color:#9fb6d8;font-weight:600}.t-quiet{color:var(--dim)}
|
|
select{background:#2a3038;color:var(--fg);border:1px solid var(--line);border-radius:5px;padding:5px;font:inherit;font-size:12px}
|
|
input[type=range]{flex:1;min-width:180px}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
|
|
<header>
|
|
<b><a class="home" href="./index.html">Station Master</a></b>
|
|
<span class="dim">replays</span>
|
|
<span class="build">build __BUILD__</span>
|
|
</header>
|
|
|
|
<main>
|
|
<div id="picker">
|
|
<section>
|
|
<h2>Saved on this site</h2>
|
|
<div id="hosted"><p class="dim">loading…</p></div>
|
|
</section>
|
|
|
|
<section>
|
|
<h2>Open a save file</h2>
|
|
<p class="dim">A Station Master save is a small <code>.json</code> file — a seed and the list of
|
|
moves made. That is enough to rebuild the whole game, so a replay can be emailed like a text file.
|
|
Save one from inside a game with <b>Save replay</b>.</p>
|
|
<input type="file" id="file" accept=".json,application/json">
|
|
<div id="perr"></div>
|
|
</section>
|
|
</div>
|
|
|
|
<div id="viewer">
|
|
<section>
|
|
<div class="vbar">
|
|
<button id="vclose">← all replays</button>
|
|
<b id="vtitle">—</b>
|
|
<span class="dim" id="vnote"></span>
|
|
</div>
|
|
<div class="vbar">
|
|
<button id="vfirst">⏮ start</button>
|
|
<button id="vback">◀ step</button>
|
|
<button id="vplay">▶ play</button>
|
|
<button id="vfwd">step ▶</button>
|
|
<button id="vstage">next Stage ⏭</button>
|
|
<button id="vlast">end ⏭</button>
|
|
<select id="vspeed">
|
|
<option value="3000">extra slow</option>
|
|
<option value="1200">slow</option>
|
|
<option value="700" selected>normal</option>
|
|
<option value="280">fast</option>
|
|
<option value="90">very fast</option>
|
|
</select>
|
|
<button id="vsound">🔇 muted</button>
|
|
<input type="range" id="vscrub" min="0" max="0" value="0">
|
|
<span class="dim" id="vpos">0 / 0</span>
|
|
</div>
|
|
<!-- The same turn chart the live game shows, from the same renderer — where you are in the
|
|
Day should look identical whether you are playing or watching. -->
|
|
<div id="turnchart"></div>
|
|
<div class="vbar">
|
|
<span>Revenue <b id="vrev">0</b></span>
|
|
<span class="dim">← → to step, space to play</span>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- SAME PANELS, SAME ORDER as the playable page. A replay is the game being watched rather
|
|
than played, so the only things it drops are the ones that ask you to act. It used to show
|
|
three panels against the play page's eight: no facilities, no blockers, no cards, no yards,
|
|
so a replay could not answer "why is nothing moving?" — the question a replay exists for. -->
|
|
<div class="vgrid">
|
|
<div>
|
|
<section><h2>The Division — west to east</h2><div class="scroll" id="vdivision"></div></section>
|
|
<section id="vdistrict"><h2>Office Area <button id="vdistricttoggle" class="ghost">auto-hide: on</button></h2>
|
|
<div id="vdistrictsummary" class="dim"></div>
|
|
<div class="scroll" id="vgrid"></div></section>
|
|
<section><h2>What happened</h2><div id="vlog"></div></section>
|
|
</div>
|
|
<div>
|
|
<section><h2>Cards Available</h2>
|
|
<h3>Cards in Hand</h3><div id="vhand" class="cardrow">—</div>
|
|
<h3>Department Decks (top card face up)</h3><div id="vdepts" class="cardrow ref">—</div>
|
|
</section>
|
|
<section><h2>The Yards</h2>
|
|
<h3>Division Yard <span class="dim" id="vdivtot"></span></h3>
|
|
<div id="vdivyard" class="yard"></div>
|
|
<h3>Classification Yard <span class="dim" id="vclstot"></span></h3>
|
|
<div id="vclsyard" class="yard"></div>
|
|
</section>
|
|
<section><h2>Blocked — why nothing is moving</h2><ul class="blocked" id="vblocked"></ul></section>
|
|
<section><h2>Facilities</h2><div id="vfacs"></div></section>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</main>
|
|
|
|
<script type="module" src="./web/replays.js"></script>
|
|
</body>
|
|
</html>
|