Files
Hermes AI Bot 4e1691ac37 fix(cache): auto-reload bei SW-Update statt confirm-Prompt
Bei neuem Service Worker wird die Seite automatisch neu geladen.
Kein Popup mehr für die User.
2026-06-27 13:08:41 +00:00

912 lines
30 KiB
HTML
Raw Permalink 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 Die letzte Reise vor dem Altar</title>
<link rel="manifest" href="manifest.json">
<meta name="theme-color" content="#d4a017">
<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 theme = saved || '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 — JGA-Farben: Bordeaux (Akzent), Gold (Highlights), tiefes Schwarz
============================================================ */
:root, [data-theme="dark"] {
--bg: #0e0c0f;
--bg-2: #18141a;
--bg-3: #221a23;
--card-bg: #1d1822;
--card-bg-hover: #261e2c;
--card-border: #2d2532;
--card-border-hover: #4a3a55;
--text: #f1ebe4;
--text-strong: #fff8e7;
--text-muted: #a89e93;
--text-dim: #756d65;
--accent: #d4a017; /* Royal Gold */
--accent-bright: #f6c544;
--accent-dim: #8a6914;
--bordeaux: #8b1538; /* Bordeaux / Burgund */
--bordeaux-bright: #b81e4a;
--success: #2dd36f;
--danger: #eb445a;
--shadow: 0 4px 20px rgba(0,0,0,0.4);
--shadow-strong: 0 12px 40px rgba(0,0,0,0.55);
--glow-gold: 0 0 24px rgba(212,160,23,0.35);
--glow-bordeaux: 0 0 24px rgba(139,21,56,0.35);
/* Kategorie-Farben */
--cat-base: #f6c544; /* Gold — Hotel/Base */
--cat-action: #ef4444; /* Rot — Action */
--cat-fun: #a855f7; /* Lila — Fun/Games */
--cat-nacht: #6366f1; /* Indigo — Nachtleben */
--cat-stadt: #14b8a6; /* Teal — Sightseeing */
}
[data-theme="light"] {
--bg: #fdf8f0; /* Cremig warm */
--bg-2: #f5ecdc;
--bg-3: #ebe0cc;
--card-bg: #ffffff;
--card-bg-hover: #fdf8f0;
--card-border: #e8dcc6;
--card-border-hover: #d4a017;
--text: #2a1f1a;
--text-strong: #1a0e0a;
--text-muted: #6b5d4f;
--text-dim: #968879;
--accent: #b8860b;
--accent-bright: #d4a017;
--accent-dim: #8a6914;
--bordeaux: #8b1538;
--bordeaux-bright: #a0122f;
--success: #1e8e3e;
--danger: #c5223a;
--shadow: 0 4px 20px rgba(101, 67, 33, 0.12);
--shadow-strong: 0 12px 40px rgba(101, 67, 33, 0.18);
--glow-gold: 0 0 24px rgba(212,160,23,0.25);
--glow-bordeaux: 0 0 24px rgba(139,21,56,0.2);
--cat-base: #b8860b;
--cat-action: #dc2626;
--cat-fun: #9333ea;
--cat-nacht: #4f46e5;
--cat-stadt: #0d9488;
}
* { box-sizing: border-box; }
html, body {
margin: 0; padding: 0;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
background: var(--bg);
color: var(--text);
min-height: 100vh;
overflow-x: hidden;
transition: background 0.4s, color 0.4s;
}
/* ===== Animierter Hintergrund ===== */
body::before {
content: '';
position: fixed;
inset: 0;
background:
radial-gradient(circle at 20% 10%, rgba(212,160,23,0.12), transparent 40%),
radial-gradient(circle at 80% 30%, rgba(139,21,56,0.10), transparent 50%),
radial-gradient(circle at 40% 90%, rgba(168,85,247,0.08), transparent 45%);
pointer-events: none;
z-index: -1;
animation: bgPulse 18s ease-in-out infinite;
}
@keyframes bgPulse {
0%, 100% { opacity: 1; }
50% { opacity: 0.6; }
}
/* Emoji in Originalfarbe */
.emoji {
font-family: "Apple Color Emoji", "Segoe UI Emoji", "Noto Color Emoji", emoji;
}
/* ===== Container ===== */
.container {
max-width: 1400px;
margin: 0 auto;
padding: 32px 24px 80px;
}
/* ===== Theme-Toggle ===== */
.theme-toggle {
position: fixed;
top: 20px; right: 20px;
width: 48px; height: 48px;
border-radius: 50%;
background: var(--card-bg);
border: 2px solid var(--accent);
color: var(--accent-bright);
font-size: 22px;
cursor: pointer;
z-index: 100;
box-shadow: var(--shadow);
transition: all 0.3s;
display: flex; align-items: center; justify-content: center;
}
.theme-toggle:hover {
transform: rotate(20deg) scale(1.1);
box-shadow: var(--glow-gold);
}
/* ============================================================
HERO
============================================================ */
.hero {
text-align: center;
padding: 48px 16px 56px;
margin-bottom: 40px;
position: relative;
border-radius: 24px;
background:
linear-gradient(135deg, rgba(139,21,56,0.25) 0%, rgba(212,160,23,0.15) 50%, rgba(139,21,56,0.25) 100%),
var(--bg-2);
border: 1px solid var(--card-border);
overflow: hidden;
}
.hero::before {
content: '';
position: absolute;
inset: 0;
background: repeating-linear-gradient(
45deg,
transparent 0px,
transparent 20px,
rgba(212,160,23,0.03) 20px,
rgba(212,160,23,0.03) 21px
);
pointer-events: none;
}
.hero-crown {
font-size: 48px;
margin-bottom: 8px;
display: block;
filter: drop-shadow(0 4px 12px rgba(212,160,23,0.5));
animation: bobUp 3s ease-in-out infinite;
}
@keyframes bobUp {
0%, 100% { transform: translateY(0) rotate(-5deg); }
50% { transform: translateY(-8px) rotate(5deg); }
}
.hero h1 {
font-size: clamp(40px, 7vw, 72px);
margin: 0 0 8px 0;
font-weight: 900;
letter-spacing: -1px;
background: linear-gradient(135deg, var(--accent-bright) 0%, #fff8e7 50%, var(--bordeaux-bright) 100%);
-webkit-background-clip: text;
background-clip: text;
-webkit-text-fill-color: transparent;
text-shadow: 0 0 40px rgba(212,160,23,0.3);
line-height: 1;
}
[data-theme="light"] .hero h1 {
background: linear-gradient(135deg, var(--bordeaux) 0%, #4a0e1a 100%);
-webkit-background-clip: text;
background-clip: text;
-webkit-text-fill-color: transparent;
text-shadow: none;
}
.hero .sub {
font-size: clamp(16px, 2.2vw, 22px);
color: var(--text-strong);
margin: 0 0 4px 0;
font-weight: 600;
letter-spacing: 0.5px;
}
.hero .where {
font-size: clamp(18px, 2.5vw, 26px);
color: var(--accent-bright);
margin: 8px 0 16px;
font-weight: 700;
}
[data-theme="light"] .hero .where {
color: var(--bordeaux);
}
.hero-meta {
display: inline-flex;
flex-wrap: wrap;
gap: 8px;
justify-content: center;
margin-top: 8px;
}
.hero-chip {
background: rgba(212,160,23,0.12);
color: var(--accent-bright);
padding: 6px 14px;
border-radius: 999px;
font-size: 13px;
font-weight: 600;
border: 1px solid rgba(212,160,23,0.35);
}
.hero-chip.hotel {
background: rgba(246,197,68,0.18);
border-color: var(--accent-bright);
}
/* ===== Section-Title ===== */
.section {
margin-bottom: 56px;
}
.section-title {
display: flex;
align-items: center;
gap: 12px;
font-size: clamp(20px, 3vw, 28px);
margin: 0 0 20px;
font-weight: 800;
letter-spacing: -0.3px;
}
.section-title .bar {
flex: 1;
height: 2px;
background: linear-gradient(90deg, var(--accent) 0%, transparent 100%);
border-radius: 1px;
}
[data-theme="light"] .section-title .bar {
background: linear-gradient(90deg, var(--accent) 0%, var(--bg-3) 80%);
opacity: 0.7;
}
.section-subtitle {
color: var(--text-muted);
font-size: 14px;
margin: -10px 0 20px 36px;
}
/* ============================================================
INFO BAR — Trip-Übersicht (kompakt)
============================================================ */
.trip-info {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
gap: 12px;
margin-bottom: 40px;
}
.trip-pill {
background: var(--card-bg);
border: 1px solid var(--card-border);
border-radius: 14px;
padding: 14px 16px;
display: flex;
align-items: center;
gap: 12px;
transition: all 0.2s;
}
.trip-pill:hover { transform: translateY(-2px); border-color: var(--accent); }
.trip-pill .icon { font-size: 24px; }
.trip-pill .text { flex: 1; }
.trip-pill .label { font-size: 11px; color: var(--text-muted); text-transform: uppercase; letter-spacing: 1px; }
.trip-pill .value { font-size: 15px; color: var(--text-strong); font-weight: 700; margin-top: 2px; }
/* ============================================================
HAUPT-CARDS — groß, mit Akzentfarbe links
============================================================ */
.cards-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
gap: 18px;
}
.big-card {
background: var(--card-bg);
border: 1px solid var(--card-border);
border-radius: 16px;
padding: 0;
overflow: hidden;
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
position: relative;
display: flex;
flex-direction: column;
text-decoration: none;
color: var(--text);
cursor: pointer;
}
.big-card::before {
content: '';
position: absolute;
top: 0; left: 0; right: 0;
height: 4px;
background: var(--card-color, var(--accent));
box-shadow: 0 0 16px var(--card-color, var(--accent));
opacity: 0.7;
}
.big-card:hover {
transform: translateY(-4px);
background: var(--card-bg-hover);
border-color: var(--card-color, var(--accent));
box-shadow: 0 12px 32px rgba(0,0,0,0.3), 0 0 0 1px var(--card-color, var(--accent));
}
.big-card .body { padding: 22px 22px 18px; flex: 1; }
.big-card .top {
display: flex;
align-items: center;
gap: 14px;
margin-bottom: 14px;
}
.big-card .icon-wrap {
width: 56px; height: 56px;
border-radius: 14px;
background: linear-gradient(135deg, var(--card-color, var(--accent)) 0%, color-mix(in srgb, var(--card-color, var(--accent)) 60%, black) 100%);
display: flex;
align-items: center;
justify-content: center;
font-size: 30px;
flex-shrink: 0;
box-shadow: 0 6px 20px rgba(0,0,0,0.3);
}
.big-card h3 {
margin: 0;
font-size: 20px;
color: var(--text-strong);
font-weight: 800;
letter-spacing: -0.2px;
}
.big-card .tag {
font-size: 11px;
text-transform: uppercase;
letter-spacing: 1.2px;
color: var(--card-color, var(--accent));
font-weight: 700;
margin-top: 2px;
}
.big-card .desc {
color: var(--text-muted);
font-size: 14px;
line-height: 1.55;
margin: 0;
}
.big-card .cta {
padding: 14px 22px;
border-top: 1px solid var(--card-border);
background: rgba(0,0,0,0.15);
display: flex;
align-items: center;
justify-content: space-between;
font-weight: 700;
font-size: 14px;
color: var(--card-color, var(--accent));
transition: all 0.3s;
}
[data-theme="light"] .big-card .cta { background: rgba(0,0,0,0.03); }
.big-card:hover .cta {
background: var(--card-color, var(--accent));
color: #fff;
}
.big-card .cta .arrow {
font-size: 18px;
transition: transform 0.3s;
}
.big-card:hover .cta .arrow { transform: translateX(4px); }
/* ============================================================
LOCATION CARDS (kompakter, mit Kategorie-Farbe)
============================================================ */
.loc-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
gap: 14px;
}
.loc-card {
background: var(--card-bg);
border: 1px solid var(--card-border);
border-left: 4px solid var(--cat-color, var(--cat-action));
border-radius: 12px;
padding: 16px 18px;
transition: all 0.25s;
text-decoration: none;
color: var(--text);
display: block;
position: relative;
overflow: hidden;
}
.loc-card::after {
content: '';
position: absolute;
top: 0; right: 0;
width: 80px; height: 80px;
background: radial-gradient(circle, var(--cat-color, var(--cat-action)) 0%, transparent 70%);
opacity: 0.08;
border-radius: 50%;
transform: translate(30px, -30px);
}
.loc-card:hover {
transform: translateX(3px);
background: var(--card-bg-hover);
border-color: var(--cat-color);
border-left-color: var(--cat-color);
box-shadow: 0 6px 20px rgba(0,0,0,0.25);
}
.loc-card .head {
display: flex;
align-items: center;
gap: 10px;
margin-bottom: 8px;
}
.loc-card .emoji { font-size: 28px; }
.loc-card h4 {
margin: 0;
font-size: 16px;
font-weight: 700;
color: var(--text-strong);
}
.loc-card .meta {
font-size: 11px;
color: var(--cat-color);
text-transform: uppercase;
letter-spacing: 1px;
font-weight: 800;
margin-top: 1px;
}
[data-theme="light"] .loc-card .meta {
/* Dunklere Variante der Akzentfarbe für besseren Kontrast auf hellem Card-Hintergrund */
color: color-mix(in srgb, var(--cat-color) 80%, #1a0e0a);
}
.loc-card .addr {
font-size: 13px;
color: var(--text-muted);
line-height: 1.5;
margin: 0;
}
.loc-card .price {
display: inline-block;
margin-top: 8px;
background: var(--cat-color);
color: #fff;
padding: 3px 10px;
border-radius: 999px;
font-size: 12px;
font-weight: 700;
}
/* ============================================================
KATEGORIE-LABELS (für Location-Sektionen)
============================================================ */
.cat-legend {
display: flex;
gap: 14px;
flex-wrap: wrap;
margin-bottom: 18px;
font-size: 12px;
color: var(--text-muted);
}
.cat-legend span {
display: inline-flex;
align-items: center;
gap: 6px;
}
.cat-legend .dot {
width: 10px; height: 10px; border-radius: 50%;
}
/* ============================================================
FOOTER
============================================================ */
footer {
text-align: center;
padding: 32px 16px;
color: var(--text-dim);
font-size: 13px;
border-top: 1px solid var(--card-border);
margin-top: 56px;
}
footer a {
color: var(--accent);
text-decoration: none;
font-weight: 600;
}
footer a:hover { text-decoration: underline; }
/* ============================================================
CONFETTI (klein, beim Card-Klick)
============================================================ */
.confetti {
position: fixed;
width: 8px;
height: 8px;
pointer-events: none;
z-index: 1000;
border-radius: 2px;
}
/* ============================================================
RESPONSIVE
============================================================ */
@media (max-width: 600px) {
.container { padding: 20px 16px 60px; }
.hero { padding: 36px 16px 40px; }
.theme-toggle { top: 14px; right: 14px; width: 42px; height: 42px; font-size: 18px; }
.big-card .icon-wrap { width: 48px; height: 48px; font-size: 26px; }
.big-card h3 { font-size: 18px; }
.cards-grid { grid-template-columns: 1fr; }
.loc-grid { grid-template-columns: 1fr; }
}
</style>
</head>
<body>
<button class="theme-toggle" id="theme-toggle" aria-label="Theme wechseln" title="Light/Dark Mode">🌙</button>
<div class="container">
<!-- ===== HERO ===== -->
<section class="hero">
<span class="hero-crown">👑</span>
<h1>JGA Prag 2026</h1>
<p class="where emoji">🍺 Die letzte Reise vor dem Altar 🍺</p>
<p class="sub">25.26. Juli · 8 Jungs · Eine Mission</p>
<div class="hero-meta">
<span class="hero-chip emoji">📅 25.07.2026</span>
<span class="hero-chip emoji">👥 8 Pers.</span>
<span class="hero-chip hotel emoji">🏨 Hotel Uno Prague</span>
</div>
</section>
<!-- ===== TRIP-ÜBERSICHT (Quick-Info kompakt) ===== -->
<section class="trip-info">
<div class="trip-pill">
<span class="icon emoji">📅</span>
<div class="text">
<div class="label">Datum</div>
<div class="value">25.26. Juli</div>
</div>
</div>
<div class="trip-pill">
<span class="icon emoji">👥</span>
<div class="text">
<div class="label">Gruppe</div>
<div class="value">8 Jungs</div>
</div>
</div>
<div class="trip-pill">
<span class="icon emoji">🏨</span>
<div class="text">
<div class="label">Basis</div>
<div class="value">Hotel Uno Prague</div>
</div>
</div>
<div class="trip-pill">
<span class="icon emoji">🚋</span>
<div class="text">
<div class="label">Tram</div>
<div class="value">Na Hroudě · 3 Min</div>
</div>
</div>
</section>
<!-- ===== QUICK-ACCESS: Karten + Tools in einer Section ===== -->
<section class="section">
<h2 class="section-title"><span class="emoji"></span><span>Quick-Access</span><span class="bar"></span></h2>
<p class="section-subtitle">Die wichtigsten Tools für unterwegs — ein Klick weg</p>
<div class="cards-grid">
<!-- Karten -->
<a href="tourenplan.html" class="big-card" style="--card-color:#f6c544;" data-confetti>
<div class="body">
<div class="top">
<div class="icon-wrap emoji">🗺️</div>
<div>
<h3>Tourenplan</h3>
<div class="tag">Karte · Basis</div>
</div>
</div>
<p class="desc">Alle 11 Locations auf einer Karte. Emoji-Marker, Preise, Adressen — direkt im Popup.</p>
</div>
<div class="cta"><span>Karte öffnen</span><span class="arrow"></span></div>
</a>
<a href="tourenplan-mit-tram.html" class="big-card" style="--card-color:#6366f1;" data-confetti>
<div class="body">
<div class="top">
<div class="icon-wrap emoji">🚋</div>
<div>
<h3>Tourenplan + Tram</h3>
<div class="tag">Karte · ÖPNV</div>
</div>
</div>
<p class="desc">Erweitert um 7 Tram-Linien + 3 Metro-Linien + 15 Haltestellen. Mit Ticket-Info.</p>
</div>
<div class="cta"><span>Karte öffnen</span><span class="arrow"></span></div>
</a>
<!-- Tools -->
<a href="wetter.html" class="big-card" style="--card-color:#14b8a6;" data-confetti>
<div class="body">
<div class="top">
<div class="icon-wrap emoji">🌤️</div>
<div>
<h3>Wetter-Vorschau</h3>
<div class="tag">Planung</div>
</div>
</div>
<p class="desc">Historische Mittelwerte + Live-Wetterlinks + Packliste-Tipps für Prag im Juli.</p>
</div>
<div class="cta"><span>Wetter öffnen</span><span class="arrow"></span></div>
</a>
<a href="packliste.html" class="big-card" style="--card-color:#f97316;" data-confetti>
<div class="body">
<div class="top">
<div class="icon-wrap emoji">🎒</div>
<div>
<h3>Packliste</h3>
<div class="tag">Checkliste</div>
</div>
</div>
<p class="desc">Interaktive Checkliste mit Fortschrittsbalken. Speichert automatisch im Browser.</p>
</div>
<div class="cta"><span>Packliste öffnen</span><span class="arrow"></span></div>
</a>
<a href="countdown.html" class="big-card" style="--card-color:#d4a017;" data-confetti>
<div class="body">
<div class="top">
<div class="icon-wrap emoji">⏱️</div>
<div>
<h3>JGA-Countdown</h3>
<div class="tag">Live</div>
</div>
</div>
<p class="desc">Countdown bis zum großen Tag. Share-Button für Social Media, Vorbereitungs-Fortschritt.</p>
</div>
<div class="cta"><span>Countdown öffnen</span><span class="arrow"></span></div>
</a>
</div>
</section>
<!-- ===== HOTEL / BASIS ===== -->
<section class="section">
<h2 class="section-title"><span class="emoji">🏨</span><span>Unsere Basis</span><span class="bar"></span></h2>
<a href="https://www.unoprague.cz" target="_blank" rel="noopener" class="loc-card" style="--cat-color:var(--cat-base);">
<div class="head">
<span class="emoji">🏨</span>
<div>
<h4>Hotel Uno Prague</h4>
<div class="meta">Übernachtung</div>
</div>
</div>
<p class="addr">Štěchovická 2296/2a, Praha 10 Strašnice</p>
<span class="price">🔗 Website öffnen</span>
</a>
</section>
<!-- ===== DIE 10 LOCATIONS ===== -->
<section class="section">
<h2 class="section-title"><span class="emoji">🎯</span><span>Die 10 Locations</span><span class="bar"></span></h2>
<div class="cat-legend">
<span><span class="dot" style="background:var(--cat-action);"></span> Action</span>
<span><span class="dot" style="background:var(--cat-fun);"></span> Fun &amp; Games</span>
<span><span class="dot" style="background:var(--cat-nacht);"></span> Nachtleben</span>
<span><span class="dot" style="background:var(--cat-stadt);"></span> Sightseeing</span>
</div>
<div class="loc-grid">
<a href="https://endorfin.cz/en/escape-games/" target="_blank" rel="noopener" class="loc-card" style="--cat-color:var(--cat-fun);">
<div class="head">
<span class="emoji">🔐</span>
<div>
<h4>Endorfin Escape Games</h4>
<div class="meta">Fun · 2 Teams</div>
</div>
</div>
<p class="addr">Petrohradská 216/3, Praha 10</p>
<span class="price">ca. 20 € p.P./1h</span>
</a>
<a href="https://kartplanet.cz/en/" target="_blank" rel="noopener" class="loc-card" style="--cat-color:var(--cat-action);">
<div class="head">
<span class="emoji">🏎️</span>
<div>
<h4>KartPlanet Praha</h4>
<div class="meta">Action · Indoor</div>
</div>
</div>
<p class="addr">Mezitraťová, Praha 9 Hrdlořezy</p>
<span class="price">ca. 15 € p.P./10min</span>
</a>
<a href="https://levelsprague.com/de/minigolf/" target="_blank" rel="noopener" class="loc-card" style="--cat-color:var(--cat-fun);">
<div class="head">
<span class="emoji"></span>
<div>
<h4>Level Prague Minigolf</h4>
<div class="meta">Fun · Indoor</div>
</div>
</div>
<p class="addr">Národní 63/26, Praha 1 (im Máj)</p>
<span class="price">ca. 25 € p.P./1h</span>
</a>
<a href="https://www.ovcin.cz/" target="_blank" rel="noopener" class="loc-card" style="--cat-color:var(--cat-fun);">
<div class="head">
<span class="emoji">🎳</span>
<div>
<h4>Bowling Ovčín</h4>
<div class="meta">Fun · Restaurant</div>
</div>
</div>
<p class="addr">Záběhlická 82, Praha 10 Záběhlice</p>
<span class="price">ca. 6 € p.P./2h</span>
</a>
<a href="https://www.mysteriumtours.com/de/prag/prager-geister-tour/" target="_blank" rel="noopener" class="loc-card" style="--cat-color:var(--cat-stadt);">
<div class="head">
<span class="emoji">👻</span>
<div>
<h4>Mysterium Geister-Tour</h4>
<div class="meta">Sightseeing · Abend</div>
</div>
</div>
<p class="addr">Treffpunkt: Cartier, Pařížská / Altstädter Ring</p>
<span class="price">ca. 20 € p.P./2h</span>
</a>
<a href="https://www.pragueranger.cz/de/" target="_blank" rel="noopener" class="loc-card" style="--cat-color:var(--cat-action);">
<div class="head">
<span class="emoji">🎯</span>
<div>
<h4>Prague Ranger</h4>
<div class="meta">Action · Outdoor</div>
</div>
</div>
<p class="addr">Shuttle ab Lublaňská 1729/23, Praha 2</p>
<span class="price">ca. 100-200 € p.P./3-4h</span>
</a>
<a href="https://beerboatsprague.com/de/Prague-Beer-Boat-Tour" target="_blank" rel="noopener" class="loc-card" style="--cat-color:var(--cat-nacht);">
<div class="head">
<span class="emoji"></span>
<div>
<h4>Beer Boat Prague</h4>
<div class="meta">Nachtleben · Treta</div>
</div>
</div>
<p class="addr">Start: Štefánikův most</p>
<span class="price">ca. 45 € p.P./1h · Bier inkl.</span>
</a>
<a href="https://www.paintballgame.cz/" target="_blank" rel="noopener" class="loc-card" style="--cat-color:var(--cat-action);">
<div class="head">
<span class="emoji">🎨</span>
<div>
<h4>Paintball Game Praha</h4>
<div class="meta">Action · Outdoor</div>
</div>
</div>
<p class="addr">Pod Císařkou, Praha 5 Buďánka</p>
<span class="price">ca. 24 € p.P./1h · Reball</span>
</a>
<a href="https://www.funarena.cz/en/activities/axe-throwing" target="_blank" rel="noopener" class="loc-card" style="--cat-color:var(--cat-action);">
<div class="head">
<span class="emoji">🪓</span>
<div>
<h4>FunArena Axtwerfen</h4>
<div class="meta">Action · Indoor</div>
</div>
</div>
<p class="addr">Bělehradská, Praha 4 Nusle (10 Min von Metro C)</p>
<span class="price">ca. 16 € p.P./1h</span>
</a>
<a href="https://mercurialaser.cz/en/pankrac/" target="_blank" rel="noopener" class="loc-card" style="--cat-color:var(--cat-action);">
<div class="head">
<span class="emoji">🔫</span>
<div>
<h4>Mercuria Laser Game Pankrác</h4>
<div class="meta">Action · Indoor</div>
</div>
</div>
<p class="addr">Budějovická 409/1a, Praha 4 (unter Bauhaus)</p>
<span class="price">ca. 7 € p.P./20min</span>
</a>
<a href="https://enigma.swallnet.com/index.php/odkaz-mistra-hvezdare-en/" target="_blank" rel="noopener" class="loc-card" style="--cat-color:var(--cat-stadt);">
<div class="head">
<span class="emoji">🔍</span>
<div>
<h4>Enigma Outdoor Adventure</h4>
<div class="meta">Sightseeing · App-Spiel</div>
</div>
</div>
<p class="addr">Stadtweit · Mobile-App Mystery</p>
<span class="price">ca. 5 € p.P./1-2h</span>
</a>
</div>
</section>
<footer>
<p>Stand: <span id="build-date"></span></p>
<p style="margin-top:8px;">
<a href="https://pid.cz/en/" target="_blank" rel="noopener">🚋 Prag ÖPNV (PID) — Fahrpläne &amp; 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();
});
/* ===== Confetti bei Card-Klicks (nur Quick-Access) ===== */
const CONFETTI_COLORS = ['#f6c544', '#d4a017', '#8b1538', '#b81e4a', '#ec4899', '#a855f7', '#14b8a6'];
document.querySelectorAll('[data-confetti]').forEach(card => {
card.addEventListener('click', (e) => {
const rect = card.getBoundingClientRect();
const cx = rect.left + rect.width / 2;
const cy = rect.top + rect.height / 2;
for (let i = 0; i < 14; i++) {
const c = document.createElement('div');
c.className = 'confetti';
c.style.left = cx + 'px';
c.style.top = cy + 'px';
c.style.background = CONFETTI_COLORS[Math.floor(Math.random() * CONFETTI_COLORS.length)];
document.body.appendChild(c);
const angle = (Math.PI * 2 * i) / 14 + Math.random() * 0.5;
const velocity = 80 + Math.random() * 100;
const dx = Math.cos(angle) * velocity;
const dy = Math.sin(angle) * velocity - 60;
const rot = (Math.random() - 0.5) * 720;
c.animate([
{ transform: `translate(0,0) rotate(0deg)`, opacity: 1 },
{ transform: `translate(${dx}px, ${dy + 200}px) rotate(${rot}deg)`, opacity: 0 }
], { duration: 900 + Math.random() * 300, easing: 'cubic-bezier(0.25, 0.46, 0.45, 0.94)' });
setTimeout(() => c.remove(), 1300);
}
});
});
// PWA Service Worker — Network-First Strategie (Updates kommen sofort durch)
if ('serviceWorker' in navigator) {
window.addEventListener('load', () => {
navigator.serviceWorker.register('./sw.js')
.then(reg => {
console.log('[PWA] SW registered:', reg.scope);
reg.addEventListener('updatefound', () => {
const newSw = reg.installing;
if (!newSw) return;
newSw.addEventListener('statechange', () => {
if (newSw.state === 'activated' && navigator.serviceWorker.controller) {
console.log('[PWA] Neue Version aktiviert — lade automatisch neu');
window.location.reload();
}
});
});
})
.catch(err => console.warn('[PWA] SW registration failed:', err));
});
}
</script>
</body>
</html>