mirror of
https://github.com/tiennm99/caro.git
synced 2026-05-20 20:23:43 +00:00
172 lines
6.9 KiB
HTML
172 lines
6.9 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8" />
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
<title>Gomoku</title>
|
|
<style>
|
|
* { margin: 0; padding: 0; box-sizing: border-box; }
|
|
body {
|
|
background: #1a1a2e;
|
|
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
|
color: #eee;
|
|
overflow: hidden;
|
|
width: 100vw;
|
|
height: 100vh;
|
|
display: flex;
|
|
justify-content: center;
|
|
align-items: center;
|
|
}
|
|
#game-container {
|
|
position: relative;
|
|
width: 800px;
|
|
height: 800px;
|
|
max-width: 100vw;
|
|
max-height: 100vh;
|
|
}
|
|
#game-container canvas { display: block; }
|
|
#ui-overlay {
|
|
position: absolute;
|
|
top: 0; left: 0;
|
|
width: 100%;
|
|
height: 100%;
|
|
pointer-events: none;
|
|
z-index: 10;
|
|
}
|
|
/* Menu panels etc. are direct children and should capture clicks.
|
|
Exception: .game-hud is a full-canvas wrapper that must stay click-through
|
|
so Phaser still receives pointer events on the board. Its interactive
|
|
children (.hud-top, .hud-side, .hud-bottom) re-enable pointer-events below. */
|
|
#ui-overlay > *:not(.game-hud) { pointer-events: auto; }
|
|
|
|
/* Menu panels */
|
|
.menu-panel {
|
|
position: absolute; top: 50%; left: 50%;
|
|
transform: translate(-50%, -50%);
|
|
background: #16213e; border-radius: 16px; padding: 40px;
|
|
min-width: 320px; text-align: center;
|
|
box-shadow: 0 8px 32px rgba(0,0,0,0.5);
|
|
display: flex; flex-direction: column; gap: 12px; align-items: center;
|
|
}
|
|
.menu-panel.wide { min-width: 480px; }
|
|
.menu-title { font-size: 28px; color: #e94560; margin-bottom: 4px; }
|
|
.menu-subtitle { font-size: 14px; color: #888; margin-bottom: 8px; }
|
|
.accent { color: #e94560; font-weight: bold; }
|
|
|
|
/* Buttons */
|
|
.menu-btn {
|
|
padding: 12px 28px; border: none; border-radius: 8px;
|
|
font-size: 15px; cursor: pointer; transition: all 0.15s;
|
|
font-family: inherit; color: #eee; width: 100%; max-width: 260px;
|
|
}
|
|
.menu-btn.primary { background: #e94560; }
|
|
.menu-btn.primary:hover { background: #d63851; }
|
|
.menu-btn.secondary { background: transparent; border: 1px solid #e94560; color: #e94560; }
|
|
.menu-btn.secondary:hover { background: rgba(233,69,96,0.1); }
|
|
.menu-btn.ghost { background: transparent; color: #888; font-size: 13px; }
|
|
.menu-btn.ghost:hover { color: #eee; }
|
|
.menu-btn.danger { background: #c0392b; }
|
|
.menu-btn.danger:hover { background: #a93226; }
|
|
.menu-btn.small { padding: 6px 14px; font-size: 13px; width: auto; max-width: none; }
|
|
|
|
/* Input */
|
|
.menu-input {
|
|
width: 100%; max-width: 260px; padding: 12px 16px;
|
|
background: #0f3460; border: 1px solid #333; border-radius: 8px;
|
|
color: #eee; font-size: 15px; outline: none; font-family: inherit;
|
|
}
|
|
.menu-input:focus { border-color: #e94560; box-shadow: 0 0 0 2px rgba(233,69,96,0.2); }
|
|
|
|
/* Room table */
|
|
.room-table { width: 100%; border-collapse: collapse; margin: 8px 0; font-size: 13px; }
|
|
.room-table th { color: #888; text-align: left; padding: 6px 8px; border-bottom: 1px solid #333; }
|
|
.room-table td { padding: 8px; border-bottom: 1px solid #222; }
|
|
.empty-state { color: #666; padding: 24px; text-align: center; }
|
|
.menu-row { display: flex; gap: 8px; justify-content: center; }
|
|
|
|
/* Spinner */
|
|
.spinner {
|
|
width: 36px; height: 36px; border: 3px solid #333;
|
|
border-top-color: #e94560; border-radius: 50%;
|
|
animation: spin 0.8s linear infinite; margin: 12px auto;
|
|
}
|
|
@keyframes spin { to { transform: rotate(360deg); } }
|
|
|
|
/* Game HUD */
|
|
.game-hud { position: absolute; top: 0; left: 0; width: 100%; height: 100%; pointer-events: none; }
|
|
.game-hud > * { pointer-events: auto; }
|
|
.hud-top {
|
|
position: absolute; top: 4px; left: 50%; transform: translateX(-50%);
|
|
display: flex; gap: 12px; align-items: center;
|
|
background: rgba(22,33,62,0.9); border-radius: 8px; padding: 4px 16px;
|
|
}
|
|
.player-panel { display: flex; align-items: center; gap: 6px; font-size: 13px; }
|
|
.stone-dot { width: 14px; height: 14px; border-radius: 50%; display: inline-block; }
|
|
.stone-dot.black { background: #222; border: 1px solid #555; }
|
|
.stone-dot.white { background: #f5f5f5; border: 1px solid #999; }
|
|
.turn-dot {
|
|
width: 8px; height: 8px; border-radius: 50%;
|
|
background: #333; transition: background 0.2s;
|
|
}
|
|
.turn-dot.active { background: #4ecca3; box-shadow: 0 0 6px #4ecca3; }
|
|
.hud-vs { color: #555; font-size: 12px; font-weight: bold; }
|
|
|
|
/* Move history sidebar */
|
|
.hud-side {
|
|
position: absolute; top: 50px; right: 4px;
|
|
background: rgba(22,33,62,0.85); border-radius: 8px;
|
|
width: 100px; max-height: 360px; padding: 6px; overflow: hidden;
|
|
}
|
|
.hud-side-title { font-size: 11px; color: #888; text-align: center; margin-bottom: 4px; }
|
|
.move-list { max-height: 320px; overflow-y: auto; font-size: 11px; }
|
|
.move-entry { padding: 2px 4px; border-bottom: 1px solid rgba(255,255,255,0.05); }
|
|
.move-entry.black { color: #ccc; }
|
|
.move-entry.white { color: #aaa; }
|
|
|
|
/* Bottom controls */
|
|
.hud-bottom {
|
|
position: absolute; bottom: 4px; left: 50%; transform: translateX(-50%);
|
|
display: flex; gap: 8px;
|
|
}
|
|
|
|
/* Game over overlay */
|
|
.game-over-overlay {
|
|
position: absolute; top: 0; left: 0; width: 100%; height: 100%;
|
|
background: rgba(0,0,0,0.6); display: flex; justify-content: center; align-items: center;
|
|
z-index: 20; animation: fadeIn 0.3s;
|
|
}
|
|
.game-over-card {
|
|
background: #16213e; border-radius: 16px; padding: 40px;
|
|
text-align: center; min-width: 300px;
|
|
}
|
|
.result-text { font-size: 42px; font-weight: bold; margin-bottom: 8px; }
|
|
.result-text.win { color: #4ecca3; }
|
|
.result-text.lose { color: #e94560; }
|
|
.result-text.draw { color: #f0c040; }
|
|
.winner-name { color: #888; font-size: 14px; margin-bottom: 20px; }
|
|
.game-over-buttons { display: flex; flex-direction: column; gap: 10px; align-items: center; margin-top: 16px; }
|
|
@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }
|
|
|
|
/* Toast notifications */
|
|
#toast-container {
|
|
position: fixed; bottom: 20px; right: 20px;
|
|
display: flex; flex-direction: column; gap: 8px; z-index: 100;
|
|
}
|
|
.toast {
|
|
padding: 10px 20px; border-radius: 8px; font-size: 13px;
|
|
color: #fff; animation: slideIn 0.3s; min-width: 200px;
|
|
}
|
|
.toast-error { background: #c0392b; }
|
|
.toast-info { background: #2980b9; }
|
|
.toast-success { background: #27ae60; }
|
|
.toast-exit { opacity: 0; transition: opacity 0.3s; }
|
|
@keyframes slideIn { from { transform: translateX(100%); opacity: 0; } to { transform: translateX(0); opacity: 1; } }
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div id="game-container"></div>
|
|
<div id="ui-overlay"></div>
|
|
<script type="module" src="/src/main.js"></script>
|
|
</body>
|
|
</html>
|