Szabo Ivan c168da359e implement complete frontend:
- add lobby, game, leaderboard, results pages
- add scripts: storage, lobby, game, drawing, scoring, countries
- add styles: main, lobby, game
- unify header/footer across all pages
- show lobby name in lobby view
- remove clear board from leaderboard
2026-05-05 13:01:14 +02:00

357 lines
9.6 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="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>GeoDraw — Results</title>
<link rel="stylesheet" href="styles/main.css" />
<style>
.results-page {
min-height: calc(100vh - var(--hh));
display: grid;
place-items: center;
padding: 60px 0;
}
.results-inner {
width: 100%;
max-width: 680px;
display: grid;
gap: 24px;
}
.results-header {
text-align: center;
}
.results-emoji {
font-size: 3.5rem;
margin-bottom: 16px;
display: block;
animation: popIn .5s cubic-bezier(.34,1.56,.64,1) both;
}
@keyframes popIn {
from { transform: scale(0); opacity: 0; }
to { transform: scale(1); opacity: 1; }
}
.results-title {
font-family: 'Syne', sans-serif;
font-weight: 800;
font-size: clamp(2rem, 5vw, 3.4rem);
letter-spacing: -.03em;
line-height: 1.05;
margin-bottom: 8px;
}
.results-player {
font-size: 1rem;
color: var(--ink-soft);
}
.results-player strong { color: var(--ink); }
/* Total score */
.score-total-card {
background: linear-gradient(135deg, var(--sea) 0%, #159fd4 50%, var(--leaf) 100%);
border-radius: var(--r-xl);
padding: 36px 40px;
text-align: center;
color: var(--white);
box-shadow: 0 16px 40px rgba(26,127,196,.3);
animation: slideUp .5s .1s cubic-bezier(.34,1.56,.64,1) both;
}
@keyframes slideUp {
from { transform: translateY(30px); opacity: 0; }
to { transform: translateY(0); opacity: 1; }
}
.score-total-label {
font-size: .78rem;
font-weight: 700;
letter-spacing: .1em;
text-transform: uppercase;
opacity: .78;
margin-bottom: 8px;
}
.score-total-num {
font-family: 'Syne', sans-serif;
font-weight: 800;
font-size: clamp(4rem, 10vw, 6rem);
line-height: 1;
letter-spacing: -.04em;
}
.score-total-max {
font-size: 1.4rem;
opacity: .6;
font-weight: 400;
}
.score-grade {
display: inline-block;
margin-top: 12px;
padding: 4px 18px;
border-radius: 999px;
background: rgba(255,255,255,.22);
font-family: 'Syne', sans-serif;
font-weight: 800;
font-size: 1.1rem;
letter-spacing: .04em;
}
/* Round breakdown */
.rounds-card {
background: var(--white);
border: 1px solid var(--line);
border-radius: var(--r-xl);
padding: 28px 32px;
box-shadow: var(--shadow-sm);
animation: slideUp .5s .2s cubic-bezier(.34,1.56,.64,1) both;
}
.rounds-card-title {
font-family: 'Syne', sans-serif;
font-weight: 700;
font-size: 1rem;
letter-spacing: -.01em;
margin-bottom: 20px;
color: var(--ink-soft);
}
.round-rows { display: grid; gap: 14px; }
.round-row {
display: grid;
grid-template-columns: auto 1fr auto;
align-items: center;
gap: 16px;
}
.round-row__label {
font-size: .82rem;
font-weight: 600;
color: var(--ink-soft);
white-space: nowrap;
}
.round-row__bar-wrap {
height: 8px;
background: var(--cream);
border-radius: 999px;
overflow: hidden;
}
.round-row__bar {
height: 100%;
border-radius: 999px;
background: linear-gradient(90deg, var(--sea), var(--leaf));
transition: width .8s cubic-bezier(.34,1.56,.64,1);
}
.round-row__score {
font-family: 'Syne', sans-serif;
font-weight: 800;
font-size: .9rem;
color: var(--sea);
min-width: 36px;
text-align: right;
}
/* Country list */
.countries-row {
display: flex;
flex-wrap: wrap;
gap: 8px;
margin-top: 8px;
}
.country-tag {
padding: 5px 12px;
border-radius: 999px;
background: var(--sea-dim);
color: var(--sea);
font-size: .8rem;
font-weight: 600;
}
/* Actions */
.results-actions {
display: flex;
gap: 12px;
flex-wrap: wrap;
animation: slideUp .5s .3s cubic-bezier(.34,1.56,.64,1) both;
}
.results-actions .btn { flex: 1 1 180px; }
@media (max-width: 600px) {
.results-page { padding: 40px 0; }
.score-total-card { padding: 28px 24px; }
.rounds-card { padding: 22px 20px; }
.results-actions .btn { flex-basis: 100%; }
}
@media (max-width: 360px) {
.score-total-num { font-size: 3.4rem; }
}
</style>
</head>
<body>
<div class="wrap">
<header class="header">
<div class="container header__inner">
<a href="index.html" class="logo">
<div class="logo__mark">
<svg viewBox="0 0 24 24" fill="none">
<circle cx="12" cy="12" r="9" stroke="white" stroke-width="1.6"/>
<path d="M3 12 Q8 8 12 12 Q16 16 21 12" stroke="white" stroke-width="1.4" fill="none"/>
<path d="M12 3 Q14 8 12 12 Q10 16 12 21" stroke="white" stroke-width="1.4" fill="none"/>
</svg>
</div>
<span class="logo__text">GeoDraw</span>
</a>
<nav class="nav">
<a href="index.html" class="nav__link">Home</a>
<a href="leaderboard.html" class="nav__link">Leaderboard</a>
<a href="lobby.html" class="nav__cta">Play again →</a>
</nav>
</div>
</header>
<main>
<div class="container results-page">
<div class="results-inner">
<div class="results-header">
<span class="results-emoji" id="results-emoji">🌍</span>
<h1 class="results-title" id="results-title">Game over!</h1>
<p class="results-player">Played by <strong id="results-player">—</strong></p>
</div>
<div class="score-total-card">
<p class="score-total-label">Total Score</p>
<div class="score-total-num">
<span id="total-score">0</span><span class="score-total-max"> / 300</span>
</div>
<span class="score-grade" id="total-grade">—</span>
</div>
<div class="rounds-card">
<p class="rounds-card-title">Round breakdown</p>
<div class="round-rows" id="round-rows">
<!-- filled by JS -->
</div>
<div class="countries-row" id="countries-row"></div>
</div>
<div class="results-actions">
<a href="lobby.html" class="btn btn--primary">
Play Again →
</a>
<a href="leaderboard.html" class="btn btn--ghost">
🏆 Leaderboard
</a>
</div>
</div>
</div>
</main>
<footer class="footer">
<div class="container footer__inner">
<div>
<a href="index.html" class="footer__brand">GeoDraw</a>
<p class="footer__sub">© 2026 · Browser geography game</p>
</div>
<div class="footer__center">
<p class="footer__label">Follow us</p>
<div class="socials">
<a href="#" class="social" aria-label="Facebook">f</a>
<a href="#" class="social" aria-label="YouTube">▶</a>
<a href="#" class="social" aria-label="LinkedIn">in</a>
<a href="#" class="social" aria-label="X">𝕏</a>
</div>
</div>
<div class="footer__right">
<a href="#" class="footer__link">Impressum</a>
<a href="#" class="footer__link">Datenschutz</a>
</div>
</div>
</footer>
</div>
<script src="scripts/storage.js"></script>
<script src="scripts/scoring.js"></script>
<script>
document.addEventListener("DOMContentLoaded", () => {
const state = Storage.getGameState();
const name = Storage.getPlayerName();
document.getElementById("results-player").textContent = name;
if (!state) {
document.getElementById("results-title").textContent = "No game found.";
document.getElementById("total-score").textContent = "—";
return;
}
const { scores, totalScore, countries } = state;
// Emoji + title based on score
const avg = totalScore / 3;
let emoji = "🌍", title = "Not bad!";
if (avg >= 85) { emoji = "🔥"; title = "Incredible!"; }
else if (avg >= 70) { emoji = "🎉"; title = "Well done!"; }
else if (avg >= 50) { emoji = "👏"; title = "Good effort!"; }
else { emoji = "😅"; title = "Keep practising!"; }
document.getElementById("results-emoji").textContent = emoji;
document.getElementById("results-title").textContent = title;
document.getElementById("total-score").textContent = totalScore;
// Grade
const grade = Scoring.getGrade(avg);
const gradeEl = document.getElementById("total-grade");
gradeEl.textContent = `Grade ${grade.label}`;
// Round rows
const rowsContainer = document.getElementById("round-rows");
(scores || []).forEach((s, i) => {
const row = document.createElement("div");
row.className = "round-row";
row.innerHTML = `
<span class="round-row__label">Round ${i + 1}</span>
<div class="round-row__bar-wrap">
<div class="round-row__bar" style="width:0%" data-target="${s}"></div>
</div>
<span class="round-row__score">${s}%</span>
`;
rowsContainer.appendChild(row);
});
// Animate bars
requestAnimationFrame(() => {
document.querySelectorAll(".round-row__bar").forEach(bar => {
bar.style.width = bar.dataset.target + "%";
});
});
// Country tags
const tagsContainer = document.getElementById("countries-row");
(countries || []).forEach(c => {
const tag = document.createElement("span");
tag.className = "country-tag";
tag.textContent = c;
tagsContainer.appendChild(tag);
});
});
</script>
</body>
</html>