Feature 18: Trinkspiel-Seite + Theme-Toggle finalisiert

Neu:
- trinkspiel.html: 5 Spiele-Modi (Kings, Ride the Bus, Ring of Fire,
  Ich hab noch nie, Wahrheit/Pflicht) mit 3D-Karten-Flip-Animation,
  Spieler-Tracker, König-Becher-Meter, Regel-Tracker, Statistik,
  History. localStorage-Persistenz (jga-players-v2, jga-rules-v2).
- countdown.html: Live-Countdown auf 25.07.2026 (Feature 24).

Update:
- index.html: Countdown-Card in Planungs-Tools Sektion.
- sw.js: trinkspiel.html + countdown.html gecacht, Cache v1->v2.
- packliste.html + tourenplan.html + tourenplan-mit-tram.html:
  Theme-Toggle Finalisierung + Favicon-Fixes.

Nicht verlinkt auf index.html — User-Review vor Freigabe.
This commit is contained in:
Hermes AI Bot
2026-06-27 09:03:35 +00:00
parent 5932c19ac5
commit 897f5f80a0
7 changed files with 1843 additions and 41 deletions
+89 -19
View File
@@ -4,43 +4,95 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>JGA Prag Packliste</title>
<link rel="icon" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'>
<link rel="manifest" href="manifest.json">
<meta name="theme-color" content="#3b82f6">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
<meta name="apple-mobile-web-app-title" content="JGA Prag">
<meta name="mobile-web-app-capable" content="yes"><text y='.9em' font-size='90'>🧭</text></svg>">
<meta name="mobile-web-app-capable" content="yes">
<script>
(function() {
const saved = localStorage.getItem('jga-theme');
document.documentElement.setAttribute('data-theme', saved || 'dark');
})();
</script>
<link rel="icon" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><text y='.9em' font-size='90'>🧭</text></svg>">
<style>
/* ====== Theme-Variablen ====== */
:root, [data-theme="dark"] {
--bg: #1c1c1f;
--card-bg: #26262a;
--card-border: #353539;
--text: #e8e8ea;
--text-muted: #999;
--text-strong: #fff;
--accent: #3b82f6;
--accent-text: #60a5fa;
--progress-bg: #2a2a2d;
}
[data-theme="light"] {
--bg: #f5f5f7;
--card-bg: #ffffff;
--card-border: #e0e0e3;
--text: #1a1a1a;
--text-muted: #666;
--text-strong: #000;
--accent: #2563eb;
--accent-text: #2563eb;
--progress-bg: #e0e0e3;
}
* { box-sizing: border-box; }
html, body {
margin: 0; padding: 0;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
background: #1c1c1f;
color: #e8e8ea;
background: var(--bg);
color: var(--text);
min-height: 100vh;
transition: background 0.3s, color 0.3s;
}
.container { max-width: 900px; margin: 0 auto; padding: 40px 24px; }
h1 {
font-size: 38px;
margin: 0 0 8px 0;
color: #fff;
color: var(--text-strong);
font-weight: 700;
}
.subtitle { color: #999; margin-bottom: 32px; font-size: 16px; }
.subtitle { color: var(--text-muted); margin-bottom: 32px; font-size: 16px; }
.back-link {
display: inline-block;
margin-bottom: 24px;
color: #60a5fa;
color: var(--accent-text);
text-decoration: none;
font-size: 14px;
}
.back-link:hover { text-decoration: underline; }
/* Theme-Toggle Button */
.theme-toggle {
position: fixed;
top: 16px;
right: 16px;
width: 44px; height: 44px;
border-radius: 50%;
background: var(--card-bg);
border: 1px solid var(--card-border);
color: var(--text);
font-size: 20px;
cursor: pointer;
z-index: 100;
box-shadow: 0 2px 8px rgba(0,0,0,0.15);
transition: all 0.2s;
display: flex; align-items: center; justify-content: center;
}
.theme-toggle:hover {
transform: rotate(15deg) scale(1.1);
border-color: var(--accent);
}
.category {
background: #26262a;
border: 1px solid #353539;
background: var(--card-bg);
border: 1px solid var(--card-border);
border-radius: 12px;
padding: 20px 24px;
margin-bottom: 16px;
@@ -48,7 +100,7 @@
.category h2 {
margin: 0 0 16px 0;
font-size: 20px;
color: #fff;
color: var(--text-strong);
display: flex;
align-items: center;
gap: 8px;
@@ -62,18 +114,19 @@
.checklist { list-style: none; padding: 0; margin: 0; }
.checklist li {
padding: 8px 0;
border-bottom: 1px solid #2a2a2d;
border-bottom: 1px solid var(--card-border);
display: flex;
align-items: flex-start;
gap: 10px;
font-size: 15px;
color: var(--text);
}
.checklist li:last-child { border-bottom: none; }
.checklist input[type="checkbox"] {
appearance: none;
width: 18px;
height: 18px;
border: 2px solid #3b82f6;
border: 2px solid var(--accent);
border-radius: 4px;
flex-shrink: 0;
margin-top: 2px;
@@ -82,8 +135,8 @@
background: transparent;
}
.checklist input[type="checkbox"]:checked {
background: #3b82f6;
border-color: #3b82f6;
background: var(--accent);
border-color: var(--accent);
}
.checklist input[type="checkbox"]:checked::after {
content: "✓";
@@ -96,17 +149,17 @@
}
.checklist li.checked span {
text-decoration: line-through;
color: #666;
color: var(--text-muted);
}
.checklist li small {
display: block;
color: #888;
color: var(--text-muted);
font-size: 12px;
margin-top: 2px;
}
.progress-bar {
background: #2a2a2d;
background: var(--progress-bg);
height: 8px;
border-radius: 4px;
overflow: hidden;
@@ -114,13 +167,13 @@
}
.progress-bar .fill {
height: 100%;
background: #3b82f6;
background: var(--accent);
width: 0%;
transition: width 0.3s ease;
}
.progress-text {
text-align: center;
color: #aaa;
color: var(--text-muted);
font-size: 13px;
margin-bottom: 24px;
}
@@ -136,6 +189,7 @@
</style>
</head>
<body>
<button class="theme-toggle" id="theme-toggle" aria-label="Theme wechseln" title="Light/Dark Mode">🌙</button>
<div class="container">
<a href="index.html" class="back-link">← Zurück zur Übersicht</a>
@@ -280,6 +334,22 @@
updateProgress();
});
// Theme-Toggle
const themeBtn = document.getElementById('theme-toggle');
function updateThemeIcon() {
const cur = document.documentElement.getAttribute('data-theme') || 'dark';
themeBtn.textContent = cur === 'dark' ? '☀️' : '🌙';
themeBtn.title = cur === 'dark' ? 'Light Mode aktivieren' : 'Dark Mode aktivieren';
}
updateThemeIcon();
themeBtn.addEventListener('click', () => {
const cur = document.documentElement.getAttribute('data-theme') || 'dark';
const next = cur === 'dark' ? 'light' : 'dark';
document.documentElement.setAttribute('data-theme', next);
localStorage.setItem('jga-theme', next);
updateThemeIcon();
});
updateProgress();
</script>
<script>