Files
JGA-2026/index.html
T
Hermes AI Bot c3fbe892cc Hotel-Highlight + Route + Nachbarn + Restaurants + PWA + Theme-Toggle (index.html)
**Hotel präsenter auf Karten:**
- Größerer Hotel-Marker (56px vs 38px)
- Goldener pulsierender Glow (CSS-Animation hotelPulse)
- Permanentes Label 'Hotel Uno · Basis' unter dem Pin
- Auto-Open Popup nach 1.5s mit goldenem Banner
- Filter-Toggle (Hotel immer sichtbar, Action/Fun/Sight ausblendbar)

**Feature 7 - Route zwischen Locations:**
- OSRM Public API für echte Auto-Routen
- Schnell-Routen vom Hotel (3 nächste Locations)
- 'Zurück zum Hotel' Button in jedem Location-Popup
- Fallback auf Haversine-Luftlinie wenn API down

**Feature 8 - Was ist in der Nähe:**
- Nachbarn <3km Luftlinie in jedem Popup

**Feature 14 - Restaurant-Tipps:**
- Geo-Cluster-basierte Restaurant-Empfehlungen pro Location
- 14 handgepflegte Tipps (€€, Cuisine, Beschreibung)

**Feature 20 - PWA:**
- manifest.json + sw.js (cache-first für eigene Files)
- Theme-Color, Apple-Meta, SW-Registrierung in allen 5 HTML-Dateien

**Feature 21 - Dark/Light Mode Toggle:**
- CSS-Variablen-System + 🌙/☀️ Toggle-Button
- localStorage-Persistenz (nur index.html, andere Seiten folgen)

**Bugfixes:**
- Enigma-URL auf User-Sublink korrigiert (alle 3 Map-Dateien)
- tourenplan-mit-tram.html Locations-Sync mit tourenplan.html
  (Endorfin/KartPlanet hatten komplett andere Preise+Koordinaten+URLs)
2026-06-27 08:32:48 +00:00

466 lines
14 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="de">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>JGA Prag 2026 Übersicht</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">
<script>
// Theme-Toggle: localStorage > System-Preference > Dark
(function() {
const saved = localStorage.getItem('jga-theme');
const sysDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
const theme = saved || (sysDark ? 'dark' : 'dark'); // Default Dark
document.documentElement.setAttribute('data-theme', theme);
})();
</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-dim: #666;
--accent: #3b82f6;
--accent-hover: #2563eb;
--info-bg: #26262a;
--info-label: #888;
--footer-border: #2a2a2d;
--footer-text: #666;
}
[data-theme="light"] {
--bg: #f5f5f7;
--card-bg: #ffffff;
--card-border: #e0e0e3;
--text: #1a1a1a;
--text-muted: #555;
--text-dim: #888;
--accent: #2563eb;
--accent-hover: #1d4ed8;
--info-bg: #ffffff;
--info-label: #6b6b6b;
--footer-border: #e0e0e3;
--footer-text: #888;
}
* { box-sizing: border-box; }
html, body {
margin: 0; padding: 0;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", sans-serif;
background: var(--bg);
color: var(--text);
min-height: 100vh;
transition: background 0.3s, color 0.3s;
}
.container {
max-width: 1400px;
margin: 0 auto;
padding: 40px 24px;
}
header {
text-align: center;
margin-bottom: 48px;
}
h1 {
font-size: 42px;
margin: 0 0 12px 0;
color: var(--text);
font-weight: 700;
}
.subtitle {
font-size: 18px;
color: var(--text-muted);
margin: 0;
}
.badge {
display: inline-block;
background: rgba(59, 130, 246, 0.15);
color: var(--accent);
padding: 4px 12px;
border-radius: 12px;
font-size: 13px;
margin-top: 12px;
border: 1px solid rgba(59, 130, 246, 0.3);
}
/* 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);
}
/* Emoji global in Original-Farbe */
.card-icon, h1, .badge, .info-item .label {
font-family: "Apple Color Emoji", "Segoe UI Emoji", "Noto Color Emoji", "Segoe UI Symbol", emoji, sans-serif;
}
/* Karten-Grid */
.cards {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
gap: 20px;
margin-bottom: 48px;
}
.card {
background: var(--card-bg);
border: 1px solid var(--card-border);
border-radius: 12px;
padding: 28px;
transition: all 0.3s ease;
display: flex;
flex-direction: column;
}
.card:hover {
transform: translateY(-2px);
border-color: var(--accent);
}
.card-icon {
font-size: 48px;
margin-bottom: 16px;
line-height: 1;
}
.card h2 {
margin: 0 0 8px 0;
font-size: 20px;
color: var(--text);
font-weight: 600;
}
.card .description {
color: var(--text-muted);
font-size: 14px;
line-height: 1.6;
margin: 0 0 16px 0;
flex: 1;
}
.card .open-btn {
display: inline-block;
padding: 10px 20px;
background: var(--accent);
color: #fff;
text-decoration: none;
border-radius: 6px;
font-weight: 500;
text-align: center;
transition: background 0.2s;
}
.card .open-btn:hover {
background: var(--accent-hover);
}
/* Section Header */
.section-title {
font-size: 22px;
margin: 48px 0 24px 0;
color: var(--text);
font-weight: 600;
}
/* Info-Block */
.info-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
gap: 16px;
margin-bottom: 32px;
}
.info-item {
background: var(--info-bg);
border-left: 3px solid var(--accent);
padding: 16px;
border-radius: 4px;
}
.info-item .label {
font-size: 12px;
color: var(--info-label);
text-transform: uppercase;
letter-spacing: 1px;
margin-bottom: 4px;
}
.info-item .value {
font-size: 16px;
color: var(--text);
font-weight: 600;
}
/* Quick Links */
.quick-links {
display: flex;
flex-wrap: wrap;
gap: 10px;
margin-bottom: 32px;
}
.quick-links a {
display: inline-flex;
align-items: center;
gap: 6px;
padding: 8px 14px;
background: #26262a;
color: #e8e8ea;
text-decoration: none;
border-radius: 6px;
font-size: 14px;
border: 1px solid #353539;
transition: all 0.2s;
}
.quick-links a:hover {
background: #2d2d31;
border-color: #3b82f6;
}
footer {
text-align: center;
padding: 32px 0 16px 0;
color: var(--footer-text);
font-size: 12px;
border-top: 1px solid var(--footer-border);
margin-top: 48px;
}
footer a {
color: var(--accent) !important;
}
@media (max-width: 600px) {
h1 { font-size: 32px; }
.container { padding: 24px 16px; }
.card-icon { font-size: 40px; }
}
</style>
</head>
<body>
<div class="container">
<button class="theme-toggle" id="theme-toggle" aria-label="Theme wechseln" title="Light/Dark Mode">🌙</button>
<header>
<h1>🧭 JGA Prag 2026</h1>
<p class="subtitle">Interaktive Karten, Wetter-Vorschau & Packliste für den Junggesellenabschied</p>
<div class="badge">📅 25.26. Juli 2026 · 👥 8 Personen · 🏨 Hotel Uno Prague</div>
</header>
<!-- Trip Overview -->
<div class="section-title">Trip-Übersicht</div>
<div class="info-grid">
<div class="info-item">
<div class="label">📅 Datum</div>
<div class="value">25.26. Juli 2026</div>
</div>
<div class="info-item">
<div class="label">👥 Gruppe</div>
<div class="value">8 Personen</div>
</div>
<div class="info-item">
<div class="label">🏨 Hotel</div>
<div class="value">Hotel Uno Prague</div>
</div>
<div class="info-item">
<div class="label">🚋 Tram</div>
<div class="value">Na Hroudě (3 Min Fußweg)</div>
</div>
</div>
<!-- Karten -->
<div class="section-title">🗺️ Interaktive Karten</div>
<div class="cards">
<div class="card">
<div class="card-icon">🗺️</div>
<h2>Tourenplan</h2>
<p class="description">
Basis-Karte mit allen 11 Locations (Hotel + 10 Attraktionen).
Emoji-Marker, Popups mit Adressen und Preisen, Dark Mode.
</p>
<a href="tourenplan.html" class="open-btn">Karte öffnen →</a>
</div>
<div class="card">
<div class="card-icon">🚋</div>
<h2>Tourenplan + Tram & Metro</h2>
<p class="description">
Erweiterte Version mit 7 Tram-Linien + 3 Metro-Linien (A/B/C) + 15 Haltestellen.
Mit 🎫 Ticket-Button für ÖPNV-Preise & Gruppenkauf.
</p>
<a href="tourenplan-mit-tram.html" class="open-btn">Karte öffnen →</a>
</div>
</div>
<!-- Planungs-Tools -->
<div class="section-title">🧰 Planungs-Tools</div>
<div class="cards">
<div class="card">
<div class="card-icon">🌤️</div>
<h2>Wetter-Vorschau</h2>
<p class="description">
Historische Mittelwerte + Live-Links zu Wetterdiensten.
Packliste-Tipps und Schlechtwetter-Alternativen inklusive.
</p>
<a href="wetter.html" class="open-btn">Wetter öffnen →</a>
</div>
<div class="card">
<div class="card-icon">🎒</div>
<h2>Packliste</h2>
<p class="description">
Interaktive Checkliste mit Fortschrittsbalken. Speichert dein Häkchen
automatisch im Browser. Druckbar als PDF.
</p>
<a href="packliste.html" class="open-btn">Packliste öffnen →</a>
</div>
</div>
<!-- Locations Übersicht -->
<div class="section-title">🏨 Unsere Basis</div>
<div class="cards">
<div class="card">
<div class="card-icon">🏨</div>
<h2>Hotel Uno Prague</h2>
<p class="description">Štěchovická 2296/2a, Praha 10 Strašnice. Unsere Basis.</p>
<a href="https://www.unoprague.cz" target="_blank" rel="noopener" class="open-btn">🔗 Website öffnen</a>
</div>
</div>
<div class="section-title">📍 Die 10 Locations</div>
<div class="cards">
<div class="card">
<div class="card-icon">🔐</div>
<h2>Endorfin Escape Games</h2>
<p class="description">Petrohradská 216/3, Praha 10. 5 Räume, max. 5 Pers/Raum → 2 Teams.</p>
<a href="https://endorfin.cz/en/escape-games/" target="_blank" rel="noopener" class="open-btn">🔗 Website öffnen</a>
</div>
<div class="card">
<div class="card-icon">🏎️</div>
<h2>KartPlanet Praha</h2>
<p class="description">Mezitraťová, Praha 9 Hrdlořezy. Indoor Go-Kart.</p>
<a href="https://kartplanet.cz/en/" target="_blank" rel="noopener" class="open-btn">🔗 Website öffnen</a>
</div>
<div class="card">
<div class="card-icon"></div>
<h2>Level Prague Minigolf</h2>
<p class="description">Národní 63/26, Praha 1 (im Máj House of Fun). Indoor.</p>
<a href="https://levelsprague.com/de/minigolf/" target="_blank" rel="noopener" class="open-btn">🔗 Website öffnen</a>
</div>
<div class="card">
<div class="card-icon">🎳</div>
<h2>Bowling Ovčín</h2>
<p class="description">Záběhlická 82, Praha 10 Záběhlice. Bowling + Billard + Restaurant.</p>
<a href="https://www.ovcin.cz/" target="_blank" rel="noopener" class="open-btn">🔗 Website öffnen</a>
</div>
<div class="card">
<div class="card-icon">👻</div>
<h2>Mysterium Geister-Tour</h2>
<p class="description">Treffpunkt: Cartier, Ecke Pařížská / Altstädter Ring. Start 19:45 / 20:00 / 20:15.</p>
<a href="https://www.mysteriumtours.com/de/prag/prager-geister-tour/" target="_blank" rel="noopener" class="open-btn">🔗 Website öffnen</a>
</div>
<div class="card">
<div class="card-icon">🎯</div>
<h2>Prague Ranger</h2>
<p class="description">Shuttle-Pickup Lublaňská 1729/23, Praha 2. Outdoor-Schießstand.</p>
<a href="https://www.pragueranger.cz/de/" target="_blank" rel="noopener" class="open-btn">🔗 Website öffnen</a>
</div>
<div class="card">
<div class="card-icon"></div>
<h2>Beer Boat Prague</h2>
<p class="description">Start: Štefánikův most. Tretboot-Biertour mit privatem Kapitän.</p>
<a href="https://beerboatsprague.com/de/Prague-Beer-Boat-Tour" target="_blank" rel="noopener" class="open-btn">🔗 Website öffnen</a>
</div>
<div class="card">
<div class="card-icon">🎨</div>
<h2>Paintball Game Praha</h2>
<p class="description">Pod Císařkou, Praha 5 Buďánka. Reball (kein Schmerz).</p>
<a href="https://www.paintballgame.cz/" target="_blank" rel="noopener" class="open-btn">🔗 Website öffnen</a>
</div>
<div class="card">
<div class="card-icon">🔫</div>
<h2>Mercuria Laser Game Pankrác</h2>
<p class="description">Budějovická 409/1a, Praha 4 (unter Bauhaus, neben Penny).</p>
<a href="https://mercurialaser.cz/en/pankrac/" target="_blank" rel="noopener" class="open-btn">🔗 Website öffnen</a>
</div>
<div class="card">
<div class="card-icon">🔍</div>
<h2>Enigma Outdoor Adventure</h2>
<p class="description">Stadtweites Mobile-App Mystery-Spiel. Kein fester Treffpunkt.</p>
<a href="https://enigma.swallnet.com/index.php/odkaz-mistra-hvezdare-en/" target="_blank" rel="noopener" class="open-btn">🔗 Website öffnen</a>
</div>
</div>
<footer>
<p>Stand: <span id="build-date"></span></p>
<p style="margin-top:8px;"><a href="https://pid.cz/en/" target="_blank" rel="noopener" style="color:#60a5fa;text-decoration:none;">🚋 Prag ÖPNV (PID) — Fahrpläne & Tickets</a></p>
</footer>
</div>
<script>
document.getElementById('build-date').textContent = new Date().toLocaleDateString('de-DE', { year: 'numeric', month: 'long', day: 'numeric' });
// 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();
});
</script>
<script>
// PWA Service Worker registrieren
if ('serviceWorker' in navigator) {
window.addEventListener('load', () => {
navigator.serviceWorker.register('./sw.js')
.then(reg => console.log('[PWA] SW registered:', reg.scope))
.catch(err => console.warn('[PWA] SW registration failed:', err));
});
}
</script>
</body>
</html>