2026-03-30 13:32:55 +02:00
|
|
|
|
<!DOCTYPE html>
|
|
|
|
|
|
<html lang="de">
|
|
|
|
|
|
<head>
|
|
|
|
|
|
<meta charset="UTF-8">
|
|
|
|
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
|
|
|
|
<title>HELLDIVERS 2 – Stratagem Trainer</title>
|
|
|
|
|
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|
|
|
|
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
|
|
|
|
|
<link href="https://fonts.googleapis.com/css2?family=Exo+2:wght@400;600;700&family=Rajdhani:wght@600;700&family=Share+Tech+Mono&display=swap" rel="stylesheet">
|
|
|
|
|
|
<link rel="stylesheet" href="styles.css">
|
|
|
|
|
|
</head>
|
|
|
|
|
|
<body>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- ── Navigation ─────────────────────────────────────────────── -->
|
|
|
|
|
|
<nav id="main-nav" class="hidden">
|
|
|
|
|
|
<div class="nav-brand">
|
|
|
|
|
|
<span class="nav-logo">⚡</span>
|
|
|
|
|
|
<span>HELLDIVERS 2</span>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="nav-links">
|
|
|
|
|
|
<button class="nav-btn" data-view="dashboard">Dashboard</button>
|
|
|
|
|
|
<button class="nav-btn" data-view="practice">Training</button>
|
|
|
|
|
|
<button class="nav-btn" data-view="lobby">1v1</button>
|
|
|
|
|
|
<button class="nav-btn" data-view="leaderboard">Highscores</button>
|
|
|
|
|
|
<button class="nav-btn nav-btn-admin hidden" id="nav-admin" data-view="admin">Admin</button>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="nav-user">
|
|
|
|
|
|
<span class="nav-username" id="nav-username"></span>
|
2026-03-30 16:47:10 +02:00
|
|
|
|
<button class="btn btn-muted btn-sm" id="btn-logout">Logout</button>
|
2026-03-30 13:32:55 +02:00
|
|
|
|
</div>
|
|
|
|
|
|
</nav>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- Incoming challenge badge (shown anywhere) -->
|
|
|
|
|
|
<div id="challenge-badge" class="challenge-badge hidden"></div>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- ── LOGIN ─────────────────────────────────────────────────── -->
|
|
|
|
|
|
<div id="view-login" class="view view-centered">
|
|
|
|
|
|
<div class="login-box">
|
|
|
|
|
|
<div class="login-header">
|
|
|
|
|
|
<div class="login-logo">⚡</div>
|
|
|
|
|
|
<h1>HELLDIVERS 2</h1>
|
|
|
|
|
|
<p class="login-sub">STRATAGEM TRAINER — SUPER EARTH AUTHORIZED</p>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<form id="login-form" class="login-form" autocomplete="off">
|
|
|
|
|
|
<div class="field">
|
|
|
|
|
|
<label for="login-username">Helldiver ID</label>
|
|
|
|
|
|
<input id="login-username" type="text" placeholder="Username" autocomplete="username" required>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="field">
|
|
|
|
|
|
<label for="login-password">Access Code</label>
|
|
|
|
|
|
<input id="login-password" type="password" placeholder="Password" autocomplete="current-password" required>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<p id="login-error" class="error hidden"></p>
|
|
|
|
|
|
<button type="submit" class="btn btn-accent btn-full">AUTHENTICATE</button>
|
|
|
|
|
|
</form>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- ── CHANGE PASSWORD ───────────────────────────────────────── -->
|
|
|
|
|
|
<div id="view-change-password" class="view view-centered hidden">
|
|
|
|
|
|
<div class="login-box">
|
|
|
|
|
|
<div class="login-header">
|
|
|
|
|
|
<h2>CHANGE ACCESS CODE</h2>
|
|
|
|
|
|
<p class="login-sub">Temporary password must be changed before proceeding</p>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<form id="change-password-form" class="login-form">
|
|
|
|
|
|
<div class="field">
|
|
|
|
|
|
<label for="cp-old">Current Password</label>
|
|
|
|
|
|
<input id="cp-old" type="password" required autocomplete="current-password">
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="field">
|
|
|
|
|
|
<label for="cp-new">New Password (min 8 chars)</label>
|
|
|
|
|
|
<input id="cp-new" type="password" required minlength="8" autocomplete="new-password">
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="field">
|
|
|
|
|
|
<label for="cp-confirm">Confirm New Password</label>
|
|
|
|
|
|
<input id="cp-confirm" type="password" required autocomplete="new-password">
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<p id="cp-error" class="error hidden"></p>
|
|
|
|
|
|
<button type="submit" class="btn btn-accent btn-full">SET NEW PASSWORD</button>
|
|
|
|
|
|
</form>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- ── DASHBOARD ─────────────────────────────────────────────── -->
|
|
|
|
|
|
<div id="view-dashboard" class="view hidden">
|
|
|
|
|
|
<div class="page-header">
|
|
|
|
|
|
<h2 class="page-title">COMMAND CENTER</h2>
|
|
|
|
|
|
<p class="page-sub">Welcome back, Helldiver. For Super Earth.</p>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div class="dashboard-grid">
|
|
|
|
|
|
<!-- Stats card -->
|
|
|
|
|
|
<div class="card">
|
|
|
|
|
|
<h3 class="card-title">YOUR STATS</h3>
|
|
|
|
|
|
<div class="stat-grid">
|
|
|
|
|
|
<div class="stat-item">
|
|
|
|
|
|
<div class="stat-value" id="dash-total-score">—</div>
|
|
|
|
|
|
<div class="stat-label">Total Score</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="stat-item">
|
|
|
|
|
|
<div class="stat-value accent" id="dash-rank">—</div>
|
|
|
|
|
|
<div class="stat-label">Global Rank</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="stat-item">
|
|
|
|
|
|
<div class="stat-value" id="dash-sessions">—</div>
|
|
|
|
|
|
<div class="stat-label">Sessions</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="stat-item">
|
|
|
|
|
|
<div class="stat-value" id="dash-win-rate">—</div>
|
|
|
|
|
|
<div class="stat-label">Match Win Rate</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- Daily challenge card -->
|
|
|
|
|
|
<div class="card card-accent">
|
|
|
|
|
|
<h3 class="card-title">⚡ DAILY CHALLENGE</h3>
|
|
|
|
|
|
<div class="daily-stratagem">
|
|
|
|
|
|
<div class="daily-name" id="dash-daily-name">—</div>
|
|
|
|
|
|
<div class="daily-category" id="dash-daily-category"></div>
|
|
|
|
|
|
<div class="daily-best">
|
|
|
|
|
|
Best time: <span id="dash-daily-best">—</span>
|
|
|
|
|
|
</div>
|
2026-03-30 16:47:10 +02:00
|
|
|
|
<button class="btn btn-accent" id="btn-daily-challenge">Practice this stratagem</button>
|
2026-03-30 13:32:55 +02:00
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- Online users card -->
|
|
|
|
|
|
<div class="card">
|
|
|
|
|
|
<h3 class="card-title">ONLINE HELLDIVERS</h3>
|
|
|
|
|
|
<div id="dash-online" class="online-list">
|
|
|
|
|
|
<span class="muted">Loading...</span>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- Recent sessions card -->
|
|
|
|
|
|
<div class="card">
|
|
|
|
|
|
<h3 class="card-title">RECENT SESSIONS</h3>
|
|
|
|
|
|
<table class="data-table">
|
|
|
|
|
|
<thead>
|
|
|
|
|
|
<tr><th>Stratagem</th><th>Score</th><th>Time</th></tr>
|
|
|
|
|
|
</thead>
|
|
|
|
|
|
<tbody id="dash-recent">
|
|
|
|
|
|
<tr><td colspan="3" class="muted">No sessions yet</td></tr>
|
|
|
|
|
|
</tbody>
|
|
|
|
|
|
</table>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- ── PRACTICE ───────────────────────────────────────────────── -->
|
|
|
|
|
|
<div id="view-practice" class="view hidden">
|
|
|
|
|
|
<div class="page-header">
|
|
|
|
|
|
<h2 class="page-title">TRAINING PROTOCOL</h2>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- Category filters -->
|
|
|
|
|
|
<div class="category-row" id="practice-categories"></div>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- Idle (start screen) -->
|
|
|
|
|
|
<div id="practice-idle" class="practice-idle">
|
|
|
|
|
|
<div class="idle-hint">Select categories above, then start training</div>
|
2026-03-30 16:47:10 +02:00
|
|
|
|
<button class="btn btn-accent btn-lg" id="btn-start-practice">⚡ START TRAINING</button>
|
2026-03-30 13:32:55 +02:00
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- Active training -->
|
|
|
|
|
|
<div id="practice-active" class="practice-active hidden">
|
|
|
|
|
|
<div class="stratagem-display card">
|
|
|
|
|
|
<div class="stratagem-category" id="practice-category"></div>
|
|
|
|
|
|
<div class="stratagem-name" id="practice-name"></div>
|
|
|
|
|
|
<div class="arrow-sequence" id="practice-sequence"></div>
|
|
|
|
|
|
<div class="practice-hint">Use Arrow Keys or D-Pad</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div class="practice-hud">
|
|
|
|
|
|
<div class="hud-item">
|
|
|
|
|
|
<div class="hud-label">TIME</div>
|
|
|
|
|
|
<div class="timer" id="practice-timer">30</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="hud-item">
|
|
|
|
|
|
<div class="hud-label">SCORE</div>
|
|
|
|
|
|
<div class="hud-value" id="practice-score">0</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="hud-item">
|
|
|
|
|
|
<div class="hud-label">STREAK</div>
|
|
|
|
|
|
<div class="hud-value accent" id="practice-streak">0</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- D-Pad (mobile) -->
|
2026-03-30 16:47:10 +02:00
|
|
|
|
<div class="dpad" id="practice-dpad">
|
2026-03-30 13:32:55 +02:00
|
|
|
|
<div class="dpad-row">
|
2026-03-30 16:47:10 +02:00
|
|
|
|
<button class="dpad-btn dpad-up" data-dir="up">↑</button>
|
2026-03-30 13:32:55 +02:00
|
|
|
|
</div>
|
|
|
|
|
|
<div class="dpad-row">
|
2026-03-30 16:47:10 +02:00
|
|
|
|
<button class="dpad-btn dpad-left" data-dir="left">←</button>
|
2026-03-30 13:32:55 +02:00
|
|
|
|
<div class="dpad-center"></div>
|
2026-03-30 16:47:10 +02:00
|
|
|
|
<button class="dpad-btn dpad-right" data-dir="right">→</button>
|
2026-03-30 13:32:55 +02:00
|
|
|
|
</div>
|
|
|
|
|
|
<div class="dpad-row">
|
2026-03-30 16:47:10 +02:00
|
|
|
|
<button class="dpad-btn dpad-down" data-dir="down">↓</button>
|
2026-03-30 13:32:55 +02:00
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
2026-03-30 16:47:10 +02:00
|
|
|
|
<button class="btn btn-muted" id="btn-stop-practice">Stop Training</button>
|
2026-03-30 13:32:55 +02:00
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- ── LOBBY ──────────────────────────────────────────────────── -->
|
|
|
|
|
|
<div id="view-lobby" class="view hidden">
|
|
|
|
|
|
<div class="page-header">
|
|
|
|
|
|
<h2 class="page-title">1v1 ARENA</h2>
|
|
|
|
|
|
<p class="page-sub">Challenge a fellow Helldiver to a stratagem duel</p>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div class="lobby-layout">
|
|
|
|
|
|
<div class="card">
|
|
|
|
|
|
<h3 class="card-title">ONLINE HELLDIVERS</h3>
|
|
|
|
|
|
<div id="lobby-players" class="player-list">
|
|
|
|
|
|
<p class="muted">Loading...</p>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div id="lobby-challenges" class="challenge-list"></div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- ── MATCH ──────────────────────────────────────────────────── -->
|
|
|
|
|
|
<div id="view-match" class="view hidden">
|
|
|
|
|
|
<div class="match-header">
|
|
|
|
|
|
<div class="match-status-text" id="match-status">Waiting...</div>
|
|
|
|
|
|
<div class="match-category" id="match-category"></div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div class="match-scoreboard">
|
|
|
|
|
|
<div class="match-player me">
|
|
|
|
|
|
<div class="match-player-name" id="match-me-name"></div>
|
|
|
|
|
|
<div class="match-wins" id="match-me-wins">0</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="match-vs">VS</div>
|
|
|
|
|
|
<div class="match-player opp">
|
|
|
|
|
|
<div class="match-player-name" id="match-opp-name"></div>
|
|
|
|
|
|
<div class="match-wins" id="match-opp-wins">0</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- Round area -->
|
|
|
|
|
|
<div id="match-round-area" class="match-round-area hidden">
|
|
|
|
|
|
<div class="match-sequences">
|
|
|
|
|
|
<div class="match-seq-col">
|
|
|
|
|
|
<div class="match-seq-label">YOU</div>
|
|
|
|
|
|
<div class="arrow-sequence" id="match-me-sequence"></div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="match-seq-col">
|
|
|
|
|
|
<div class="match-seq-label">OPPONENT</div>
|
|
|
|
|
|
<div class="arrow-sequence" id="match-opp-sequence"></div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<!-- D-Pad (mobile) -->
|
2026-03-30 16:47:10 +02:00
|
|
|
|
<div class="dpad" id="match-dpad">
|
2026-03-30 13:32:55 +02:00
|
|
|
|
<div class="dpad-row">
|
2026-03-30 16:47:10 +02:00
|
|
|
|
<button class="dpad-btn dpad-up" data-dir="up">↑</button>
|
2026-03-30 13:32:55 +02:00
|
|
|
|
</div>
|
|
|
|
|
|
<div class="dpad-row">
|
2026-03-30 16:47:10 +02:00
|
|
|
|
<button class="dpad-btn dpad-left" data-dir="left">←</button>
|
2026-03-30 13:32:55 +02:00
|
|
|
|
<div class="dpad-center"></div>
|
2026-03-30 16:47:10 +02:00
|
|
|
|
<button class="dpad-btn dpad-right" data-dir="right">→</button>
|
2026-03-30 13:32:55 +02:00
|
|
|
|
</div>
|
|
|
|
|
|
<div class="dpad-row">
|
2026-03-30 16:47:10 +02:00
|
|
|
|
<button class="dpad-btn dpad-down" data-dir="down">↓</button>
|
2026-03-30 13:32:55 +02:00
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div class="match-actions">
|
2026-03-30 16:47:10 +02:00
|
|
|
|
<button class="btn btn-accent hidden" id="match-ready-btn">READY</button>
|
|
|
|
|
|
<button class="btn btn-muted btn-sm" id="btn-leave-match">Leave Match</button>
|
2026-03-30 13:32:55 +02:00
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- ── LEADERBOARD ────────────────────────────────────────────── -->
|
|
|
|
|
|
<div id="view-leaderboard" class="view hidden">
|
|
|
|
|
|
<div class="page-header">
|
|
|
|
|
|
<h2 class="page-title">HALL OF HEROES</h2>
|
|
|
|
|
|
<p class="page-sub">Top Helldivers ranked by total practice score</p>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div class="card">
|
|
|
|
|
|
<table class="data-table leaderboard-table">
|
|
|
|
|
|
<thead>
|
|
|
|
|
|
<tr>
|
|
|
|
|
|
<th>#</th>
|
|
|
|
|
|
<th>Helldiver</th>
|
|
|
|
|
|
<th>Total Score</th>
|
|
|
|
|
|
<th>Sessions</th>
|
|
|
|
|
|
<th>Match W/Total</th>
|
|
|
|
|
|
</tr>
|
|
|
|
|
|
</thead>
|
|
|
|
|
|
<tbody id="leaderboard-table-body">
|
|
|
|
|
|
<tr><td colspan="5" class="muted">Loading...</td></tr>
|
|
|
|
|
|
</tbody>
|
|
|
|
|
|
</table>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- ── ADMIN ──────────────────────────────────────────────────── -->
|
|
|
|
|
|
<div id="view-admin" class="view hidden">
|
|
|
|
|
|
<div class="page-header">
|
|
|
|
|
|
<h2 class="page-title">ADMIN PANEL</h2>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div class="admin-layout">
|
|
|
|
|
|
<!-- Create user -->
|
|
|
|
|
|
<div class="card">
|
|
|
|
|
|
<h3 class="card-title">CREATE HELLDIVER</h3>
|
|
|
|
|
|
<div class="field">
|
|
|
|
|
|
<label for="new-username">Username</label>
|
|
|
|
|
|
<input id="new-username" type="text" placeholder="helldiver_name" pattern="[a-zA-Z0-9_-]{2,32}">
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="field">
|
|
|
|
|
|
<label for="new-role">Role</label>
|
|
|
|
|
|
<select id="new-role">
|
|
|
|
|
|
<option value="user">User</option>
|
|
|
|
|
|
<option value="admin">Admin</option>
|
|
|
|
|
|
</select>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<p id="admin-error" class="error hidden"></p>
|
2026-03-30 16:47:10 +02:00
|
|
|
|
<button class="btn btn-accent" id="btn-create-user">Create User</button>
|
2026-03-30 13:32:55 +02:00
|
|
|
|
<div id="new-pw-display" class="pw-display hidden"></div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- User list -->
|
|
|
|
|
|
<div class="card">
|
|
|
|
|
|
<h3 class="card-title">ACTIVE HELLDIVERS</h3>
|
|
|
|
|
|
<div id="admin-users" class="admin-user-list">Loading...</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- Toast notifications -->
|
|
|
|
|
|
<div id="toast-container"></div>
|
|
|
|
|
|
|
|
|
|
|
|
<script src="app.js"></script>
|
|
|
|
|
|
</body>
|
|
|
|
|
|
</html>
|