Files
kantine2ical/templates/index.html
2026-02-23 12:47:21 +01:00

383 lines
10 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>Speiseplan Kantine BHZ Kiel-Wik iCal-Abo</title>
<meta name="description" content="Aktueller Speiseplan der Kantine im Behördenzentrum Kiel-Wik als iCal-Abo und übersichtliche Kacheln für kommende Tage.">
<meta name="author" content="Markus F.J. Busche">
<meta name="robots" content="index,follow">
<link rel="canonical" href="{{ base_url }}/">
<meta property="og:locale" content="de_DE">
<meta property="og:type" content="website">
<meta property="og:title" content="Speiseplan Kantine BHZ Kiel-Wik iCal-Abo">
<meta property="og:description" content="Aktueller Speiseplan der Kantine im Behördenzentrum Kiel-Wik als abonnierbarer Kalender und als übersichtliche Kachelansicht für kommende Tage.">
<meta property="og:url" content="{{ base_url }}/">
<link rel="icon" href="{{ url_for('static', filename='favicon.png') }}" type="image/png">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=DM+Sans:ital,opsz,wght@0,9..40,400;0,9..40,500;0,9..40,600;0,9..40,700&display=swap" rel="stylesheet">
<script defer data-domain="kantine.elpatron.me" src="https://plausible.elpatron.me/js/script.js"></script>
<style>
:root {
--bg: #0f1419;
--surface: #1a2332;
--text: #e6edf3;
--text-muted: #8b949e;
--accent: #58a6ff;
--accent-soft: rgba(88, 166, 255, 0.15);
--border: #30363d;
--success: #3fb950;
--radius: 12px;
--font: 'DM Sans', -apple-system, BlinkMacSystemFont, sans-serif;
}
* {
box-sizing: border-box;
}
body {
margin: 0;
font-family: var(--font);
background: var(--bg);
color: var(--text);
line-height: 1.6;
min-height: 100vh;
}
.wrap {
max-width: 640px;
margin: 0 auto;
padding: 2rem 1.25rem;
}
header {
margin-bottom: 2.5rem;
}
h1 {
font-size: clamp(1.5rem, 4vw, 1.75rem);
font-weight: 700;
margin: 0 0 0.5rem;
letter-spacing: -0.02em;
}
.subtitle {
color: var(--text-muted);
font-size: 0.95rem;
margin: 0;
}
.last-refresh {
color: var(--text-muted);
font-size: 0.875rem;
margin: 0.5rem 0 0;
}
.card {
background: var(--surface);
border: 1px solid var(--border);
border-radius: var(--radius);
padding: 1.25rem 1.5rem;
margin-bottom: 1.5rem;
}
.card h2 {
font-size: 1.1rem;
font-weight: 600;
margin: 0 0 0.75rem;
display: flex;
align-items: center;
gap: 0.5rem;
}
.card h2 .num {
display: inline-flex;
align-items: center;
justify-content: center;
width: 1.5rem;
height: 1.5rem;
background: var(--accent-soft);
color: var(--accent);
border-radius: 6px;
font-size: 0.85rem;
}
.url-box {
display: flex;
flex-wrap: wrap;
gap: 0.5rem;
align-items: center;
background: var(--bg);
border: 1px solid var(--border);
border-radius: 8px;
padding: 0.75rem 1rem;
margin-bottom: 1rem;
}
.url-box input {
flex: 1;
min-width: 0;
background: none;
border: none;
color: var(--text);
font-family: ui-monospace, monospace;
font-size: 0.85rem;
}
.url-box input:focus {
outline: none;
}
.btn {
display: inline-flex;
align-items: center;
gap: 0.4rem;
padding: 0.5rem 1rem;
font-size: 0.9rem;
font-weight: 500;
font-family: var(--font);
border-radius: 8px;
border: none;
cursor: pointer;
background: var(--accent);
color: #fff;
white-space: nowrap;
}
.btn:hover {
filter: brightness(1.1);
}
.btn:active {
transform: scale(0.98);
}
.btn.copy-done {
background: var(--success);
}
ol.steps {
margin: 0;
padding-left: 1.25rem;
color: var(--text-muted);
font-size: 0.95rem;
}
ol.steps li {
margin-bottom: 0.5rem;
}
ol.steps li strong {
color: var(--text);
}
.provider-grid {
display: grid;
gap: 1rem;
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
}
.provider {
background: var(--bg);
border: 1px solid var(--border);
border-radius: 8px;
padding: 1rem;
}
.provider strong {
display: block;
margin-bottom: 0.35rem;
font-size: 0.95rem;
}
.provider p {
margin: 0;
font-size: 0.85rem;
color: var(--text-muted);
}
footer {
margin-top: 2.5rem;
padding-top: 1.5rem;
border-top: 1px solid var(--border);
font-size: 0.85rem;
color: var(--text-muted);
}
footer p {
margin: 0 0 0.5rem;
}
footer p:last-child {
margin-bottom: 0;
}
.footer-credit {
margin-top: 0.75rem;
}
footer a {
color: var(--accent);
text-decoration: none;
}
footer a:hover {
text-decoration: underline;
}
.speiseplan-section {
margin-bottom: 2.5rem;
}
.speiseplan-section h2 {
font-size: 1.1rem;
font-weight: 600;
margin: 0 0 1rem;
}
.speiseplan-grid {
display: grid;
gap: 1rem;
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
}
.day-tile {
background: var(--surface);
border: 1px solid var(--border);
border-radius: var(--radius);
padding: 1.25rem 1.5rem;
}
.day-tile h3 {
font-size: 1rem;
font-weight: 600;
margin: 0 0 0.75rem;
color: var(--accent);
}
.day-tile .dishes {
font-size: 0.9rem;
color: var(--text-muted);
line-height: 1.5;
}
.day-tile .dishes div {
margin-bottom: 0.35rem;
}
.day-tile .dishes div:last-child {
margin-bottom: 0;
}
.speiseplan-empty {
color: var(--text-muted);
font-size: 0.95rem;
margin: 0;
}
</style>
</head>
<body>
<div class="wrap">
<header>
<h1>Speiseplan Kantine BHZ Kiel-Wik</h1>
<p class="subtitle">Inoffizieller Kalender für die Kantine im Behördenzentrum Kiel Wik. iCal-Abo für Ihren Kalender täglich aktualisiert, alle Tagesgerichte (I.V.) um 12:00 Uhr.</p>
{% if last_refresh_str %}
<p class="last-refresh">Zuletzt aktualisiert: {{ last_refresh_str }}</p>
{% else %}
<p class="last-refresh">Speisepläne wurden noch nicht aktualisiert.</p>
{% endif %}
</header>
<section class="speiseplan-section">
<h2>Speiseplan (zukünftige Tage)</h2>
{% if upcoming_days %}
<div class="speiseplan-grid">
{% for date_str, dishes in upcoming_days %}
<article class="day-tile">
<h3>{{ date_str }}</h3>
<div class="dishes">
{% for dish in dishes %}
<div>{{ dish }}</div>
{% endfor %}
</div>
</article>
{% endfor %}
</div>
{% else %}
<p class="speiseplan-empty">Es liegen derzeit (noch) keine neuen Speisepläne vor.</p>
{% endif %}
</section>
<section class="card">
<h2><span class="num">1</span> Abo-URL kopieren</h2>
<p style="margin: 0 0 1rem; font-size: 0.95rem; color: var(--text-muted);">Diese URL in Ihrem Kalender als „Abonnement“ oder „Von URL hinzufügen“ eintragen:</p>
<div class="url-box">
<input type="text" id="ical-url" value="{{ calendar_url }}" readonly aria-label="iCal-URL">
<button type="button" class="btn" id="copy-btn" aria-label="URL kopieren">Kopieren</button>
</div>
</section>
<section class="card">
<h2><span class="num">2</span> Google Kalender</h2>
<ol class="steps">
<li><strong><a href="https://calendar.google.com" target="_blank" rel="noopener">calendar.google.com</a></strong> öffnen</li>
<li>Rechts neben „Meine Kalender“ auf <strong>+</strong> klicken → <strong>Von URL</strong></li>
<li>Die obige Abo-URL einfügen und <strong>Kalender hinzufügen</strong> wählen</li>
<li>Der Speiseplan erscheint als eigener Kalender und wird automatisch aktualisiert</li>
</ol>
</section>
<section class="card">
<h2><span class="num">3</span> Andere Kalender-Apps</h2>
<div class="provider-grid">
<div class="provider">
<strong>Outlook (Web)</strong>
<p>Kalender → Einstellungen → Kalender hinzufügen → Abonnement; Abo-URL einfügen.</p>
</div>
<div class="provider">
<strong>Apple Kalender</strong>
<p>Kalender → Ablage → Neues Kalender-Abonnement; Abo-URL einfügen.</p>
</div>
<div class="provider">
<strong>Thunderbird</strong>
<p>Kalender → Neuer Kalender → Im Netzwerk; Abo-URL einfügen.</p>
</div>
<div class="provider">
<strong>Android / iOS</strong>
<p>In den Einstellungen der Kalender-App „Kalender hinzufügen“ / „Abo per URL“; Abo-URL einfügen.</p>
</div>
</div>
</section>
<footer>
<p>Quelle: <a href="http://kantine-bhz.de" target="_blank" rel="noopener">kantine-bhz.de</a>. Der Speiseplan wird einmal täglich aktualisiert. Direkter Kalender-Download: <a href="{{ calendar_url }}">calendar.ics</a>.</p>
<p class="footer-credit">No tracking, no cookies. Made as a hobby project in 2026 by <a href="mailto:elpatron@mailbox.org">Markus F.J. Busche</a>.</p>
</footer>
</div>
<script>
(function() {
var input = document.getElementById('ical-url');
var btn = document.getElementById('copy-btn');
if (!input || !btn) return;
btn.addEventListener('click', function() {
input.select();
input.setSelectionRange(0, 99999);
try {
navigator.clipboard.writeText(input.value);
btn.textContent = 'Kopiert';
btn.classList.add('copy-done');
setTimeout(function() {
btn.textContent = 'Kopieren';
btn.classList.remove('copy-done');
}, 2000);
} catch (e) {
btn.textContent = 'Bitte manuell kopieren';
}
});
})();
</script>
</body>
</html>