feat: build the Russian responsive web interface

This commit is contained in:
2026-08-29 21:11:36 +03:00
parent 03b283f892
commit e77d9d62c7
8 changed files with 409 additions and 74 deletions
+42 -6
View File
@@ -3,17 +3,53 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#08233d">
<title>Морской бой — ESP32</title>
<link rel="stylesheet" href="/styles.css">
</head>
<body>
<main>
<h1>Морской бой</h1>
<p>ESP32-C6: проверка Wi-Fi, LittleFS и HTTP.</p>
<section aria-live="polite">
<h2>Состояние устройства</h2>
<dl id="health">Загрузка…</dl>
<main class="app-shell">
<header class="app-header">
<div><p class="eyebrow">ESP32-C6 · локальная игра</p><h1>Морской бой</h1></div>
<p id="connection-status" class="connection-status" role="status">Подключение…</p>
</header>
<p id="notice" class="notice" aria-live="polite" hidden></p>
<section id="screen-connect" class="screen" aria-labelledby="connect-title">
<h2 id="connect-title">Подключение к игре</h2>
<p>Введите имя, чтобы занять место игрока или наблюдать за партией.</p>
<form id="join-form" class="stack-form">
<label for="display-name">Ваше имя</label>
<input id="display-name" name="name" type="text" maxlength="80" autocomplete="name" required>
<div class="button-row"><button id="join-player" type="submit">Играть</button><button id="join-spectator" type="button" class="secondary">Наблюдать</button></div>
</form>
<p id="availability" class="muted">Проверяем доступные места…</p>
</section>
<section id="screen-lobby" class="screen" aria-labelledby="lobby-title" hidden>
<h2 id="lobby-title">Лобби</h2><p id="lobby-description"></p>
<div id="mode-controls" class="panel" hidden>
<h3>Режим игры</h3>
<div class="button-row"><button type="button" data-mode="human" class="mode-button">Два игрока</button><button type="button" data-mode="bot" class="mode-button">Против ESP32</button></div>
<button id="start-game" type="button">Начать игру</button>
</div>
<p id="lobby-help" class="muted"></p>
</section>
<section id="screen-game" class="screen" aria-labelledby="game-title" hidden>
<div class="screen-heading"><div><h2 id="game-title">Поле боя</h2><p id="turn-status" class="turn-status"></p></div><p id="wins" class="score" aria-label="Победы"></p></div>
<div id="board-tabs" class="board-tabs" role="tablist" aria-label="Выбор поля"></div>
<div id="boards" class="boards"></div>
<div id="shot-controls" class="shot-controls" hidden><p id="target-status" class="muted">Выберите клетку на поле соперника.</p><button id="fire-button" type="button" disabled>Огонь</button><button id="cancel-target" type="button" class="secondary" disabled>Отменить</button></div>
<button id="abort-game" type="button" class="text-button" hidden>Отменить партию</button>
</section>
<section id="screen-result" class="screen" aria-labelledby="result-title" hidden>
<h2 id="result-title">Партия завершена</h2><p id="result-description"></p>
<div id="result-boards" class="boards result-boards"></div><button id="rematch-button" type="button">Сыграть ещё</button>
</section>
<section id="screen-reconnecting" class="screen reconnecting" aria-labelledby="reconnecting-title" hidden><h2 id="reconnecting-title">Восстанавливаем связь</h2><p>Состояние игры обновляется через HTTP. WebSocket подключится автоматически.</p></section>
<section id="screen-error" class="screen error-screen" aria-labelledby="error-title" hidden><h2 id="error-title">Не удалось продолжить</h2><p id="error-description"></p><button id="retry-button" type="button">Повторить</button></section>
</main>
<script src="/app.js" defer></script>
</body>