185 lines
204 KiB
HTML
Executable File
185 lines
204 KiB
HTML
Executable File
<!DOCTYPE html>
|
||
<html lang="de">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<title>Kantine Wrapper Installer (v1.4.0)</title>
|
||
<style>
|
||
body { font-family: 'Inter', sans-serif; max-width: 600px; margin: 40px auto; padding: 20px; background: #1a1a2e; color: #eee; }
|
||
h1 { color: #029AA8; } /* Knapp Teal */
|
||
.instructions { background: #16213e; padding: 20px; border-radius: 12px; margin: 20px 0; }
|
||
.instructions ol li { margin: 10px 0; }
|
||
a.bookmarklet { display: inline-block; background: #029AA8; color: white; padding: 12px 24px; border-radius: 8px; text-decoration: none; font-weight: 600; font-size: 18px; cursor: grab; }
|
||
a.bookmarklet:hover { background: #006269; }
|
||
code { background: #0f3460; padding: 2px 6px; border-radius: 4px; }
|
||
|
||
/* Collapsible Changelog */
|
||
details.styled-details { background: rgba(0,0,0,0.2); border-radius: 8px; overflow: hidden; }
|
||
summary.styled-summary { padding: 15px; cursor: pointer; font-weight: bold; list-style: none; display: flex; justify-content: space-between; align-items: center; user-select: none; }
|
||
summary.styled-summary:hover { background: rgba(255,255,255,0.05); }
|
||
summary.styled-summary::-webkit-details-marker { display: none; }
|
||
summary.styled-summary::after { content: '▼'; font-size: 0.8em; transition: transform 0.2s; }
|
||
details.styled-details[open] summary.styled-summary::after { transform: rotate(180deg); transition: transform 0.2s; }
|
||
.changelog-container { padding: 0 15px 15px 15px; border-top: 1px solid rgba(255,255,255,0.05); }
|
||
</style>
|
||
</head>
|
||
<body>
|
||
<div style="text-align: center; margin-bottom: 30px;">
|
||
<h1 style="margin-bottom: 5px;">🍽️ Kantine Wrapper <span style="font-size:0.5em; opacity:0.6; font-weight:400; vertical-align:middle; margin-left:10px;">v1.4.0</span></h1>
|
||
<p style="font-size: 1.2rem; color: #a0aec0; margin-top: 0; font-style: italic;">"Mahlzeit! Jetzt bessa einfach."</p>
|
||
</div>
|
||
|
||
<!-- 1. BUTTON (Top Priority) -->
|
||
<div class="card" style="text-align: center; border: 2px solid #029AA8;">
|
||
<p style="margin-bottom:15px; font-weight:bold;">👇 Diesen Button in die Lesezeichen-Leiste ziehen:</p>
|
||
<p><a class="bookmarklet" id="bookmarklet-link" href="#" onclick="event.preventDefault(); return false;" title="Nicht klicken! Ziehe mich in deine Lesezeichen-Leiste.">⏳ Wird generiert...</a></p>
|
||
</div>
|
||
|
||
<!-- 2. INSTRUCTIONS -->
|
||
<div class="card">
|
||
<h2>So funktioniert's</h2>
|
||
<ol>
|
||
<li>Ziehe den Button oben in deine <strong>Lesezeichen-Leiste</strong> (Drag & Drop)</li>
|
||
<li>Navigiere zu <a href="https://web.bessa.app/knapp-kantine" style="color:#029AA8">web.bessa.app/knapp-kantine</a></li>
|
||
<li>Klicke auf das Lesezeichen <code>Kantine v1.4.0</code></li>
|
||
</ol>
|
||
</div>
|
||
|
||
<!-- 3. FEATURES -->
|
||
<div class="card">
|
||
<h2>✨ Features</h2>
|
||
<ul>
|
||
<li>📅 <strong>Wochenübersicht:</strong> Die ganze Woche auf einen Blick.</li>
|
||
<li>⏳ <strong>Order Countdown:</strong> Roter Alarm 1h vor Bestellschluss.</li>
|
||
<li>🌟 <strong>Smart Highlights:</strong> Markiere deine Favoriten (z.B. "Schnitzel").</li>
|
||
<li>💰 <strong>Kostenkontrolle:</strong> Automatische Berechnung der Wochensumme.</li>
|
||
<li>🔑 <strong>Auto-Login:</strong> Nutzt deine bestehende Session.</li>
|
||
<li>🏷️ <strong>Badges & Status:</strong> Menü-Codes (M1, M2) und Bestellstatus direkt sichtbar.</li>
|
||
</ul>
|
||
|
||
<div style="margin-top: 30px; padding: 15px; background: rgba(233, 69, 96, 0.1); border: 1px solid rgba(233, 69, 96, 0.3); border-radius: 8px; font-size: 0.85em; color: #ddd;">
|
||
<strong>⚠️ Haftungsausschluss:</strong><br>
|
||
Die Verwendung dieses Bookmarklets erfolgt auf eigene Verantwortung. Der Entwickler übernimmt keine Haftung für Schäden, Datenverlust oder ungewollte Bestellungen, die durch die Nutzung dieser Software entstehen.
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 4. CHANGELOG (Bottom) -->
|
||
<div class="card">
|
||
<details class="styled-details">
|
||
<summary class="styled-summary">Changelog & Version History</summary>
|
||
<div class="changelog-container">
|
||
<h3>v1.4.0 (2026-02-22)</h3>
|
||
<ul>
|
||
<li>**Feature**: Bestellhistorie per Knopfdruck abrufbar. Übersichtliche Darstellung, gruppiert nach Monaten und Kalenderwochen, inklusive Stornos. 📜✨</li>
|
||
</ul>
|
||
<h3>v1.3.2 (2026-02-19)</h3>
|
||
<ul>
|
||
<li>**Fix**: Falsche Anzahl an Highlight-Menüs im "Nächste Woche"-Badge korrigiert (zählte alle Menüs statt nur Highlights). 🐛</li>
|
||
</ul>
|
||
<h3>v1.3.1 (2026-02-17)</h3>
|
||
<ul>
|
||
<li>**Feature**: Smart Cache – API-Refresh beim Start wird übersprungen wenn Daten für die aktuelle KW vorhanden und Cache < 1h alt ist. ⚡</li>
|
||
</ul>
|
||
<h3>v1.3.0 (2026-02-16)</h3>
|
||
<ul>
|
||
<li>**Feature**: GitHub Release Management 📦</li>
|
||
- Version-Menü: Klick auf Versionsnummer zeigt alle verfügbaren Versionen
|
||
- Dev-Mode Toggle: Zwischen Releases (stabil) und Tags (dev) wechseln
|
||
- Downgrade-Support: Jede Version hat einen eigenen Installer-Link
|
||
- Update-Check nutzt jetzt die GitHub API statt `version.txt`
|
||
- GitHub PAT für höheres API-Rate-Limit (5000/h)
|
||
- SemVer-Check: Update-Icon nur bei wirklich neuerer Version
|
||
|
||
<h3>v1.2.9 (2026-02-16)</h3>
|
||
|
||
<h3>v1.2.8 (2026-02-16)</h3>
|
||
<ul>
|
||
<li>**Debug**: Weiteres Logging (Fetch-Status, Start-Log) zur Fehlersuche. 🔎</li>
|
||
</ul>
|
||
<h3>v1.2.7 (2026-02-16)</h3>
|
||
<ul>
|
||
<li>**Debug**: Verbose Logging für Update-Check eingebaut. 🐞</li>
|
||
</ul>
|
||
<h3>v1.2.6 (2026-02-16)</h3>
|
||
<ul>
|
||
<li>**Test**: Version Bump zum Testen der Live-Update-Erkennung. 🧪</li>
|
||
</ul>
|
||
<h3>v1.2.5 (2026-02-16)</h3>
|
||
<ul>
|
||
<li>**Refactor**: Update-Erkennung komplett überarbeitet (stündlicher Check, diskretes 🆕 Icon im Header, kein Banner mehr). 🔄</li>
|
||
<li>**Cleanup**: Ungenutzter CSS-Code und Netzwerk-Traffic reduziert. 🧹</li>
|
||
<li>**Fix**: Highlight-Logik stabilisiert (keine falschen Matches bei leeren Tags). 🏷️</li>
|
||
</ul>
|
||
<h3>v1.2.4 (2026-02-16)</h3>
|
||
<ul>
|
||
<li>**Feature**: Gefundene Highlights werden jetzt direkt im Menü als Badge angezeigt. 🏷️</li>
|
||
</ul>
|
||
<h3>v1.2.3 (2026-02-16)</h3>
|
||
<ul>
|
||
<li>**Fix**: Update-Icon ist jetzt klickbar und führt direkt zum Installer. 🔗</li>
|
||
<li>**Dev**: Unit-Tests für Update-Logik im Build integriert. 🛡️</li>
|
||
</ul>
|
||
<h3>v1.2.2 (2026-02-16)</h3>
|
||
<ul>
|
||
<li>**UX**: Installer-Changelog jetzt einklappbar für mehr Übersicht. 📂</li>
|
||
</ul>
|
||
<h3>v1.2.1 (2026-02-16)</h3>
|
||
<ul>
|
||
<li>**Fix**: Smart Highlights werden jetzt korrekt auf Menü-Items angewendet (`checkHighlight` in `createDayCard`). 🌟</li>
|
||
<li>**Feature**: Mock-Daten (`mock-data.js`) für Standalone-Tests eingebaut. 🧪</li>
|
||
<li>**Style**: Highlight-Glow mit blauer Puls-Animation (`blue-pulse`) überarbeitet. 💎</li>
|
||
<li>**Style**: Tag-Badges konsistent mit Badge-System gestaltet. 🏷️</li>
|
||
<li>**Style**: "Hinzufügen"-Button (`#btn-add-tag`) als Primary-Button gestylt. 🎨</li>
|
||
<li>**Style**: Modal-Body Padding und Input-Font korrigiert. 🔧</li>
|
||
<li>**Docs**: README Projektstruktur mit Tabelle für `dist/`-Artefakte ergänzt. 📖</li>
|
||
</ul>
|
||
<h3>v1.2.0 (2026-02-16)</h3>
|
||
<ul>
|
||
<li>**Feature**: Bessere UX im Installer (Button oben, Log unten, Features aktualisiert). 💅</li>
|
||
<li>**Tech**: Build-Tests hinzugefügt. 🧪</li>
|
||
<li>**Fix**: Encoding-Probleme final behoben (dank Python Buildlogic). 🐍</li>
|
||
</ul>
|
||
<h3>v1.1.2 (2026-02-16)</h3>
|
||
<ul>
|
||
<li>**Fix**: Encoding-Problem beim Bookmarklet behoben (URL Malformed Error). 🔗</li>
|
||
</ul>
|
||
<h3>v1.1.1 (2026-02-16)</h3>
|
||
<ul>
|
||
<li>**Fix**: Kritischer Fehler behoben, der das Laden des Wrappers verhinderte. 🐛</li>
|
||
</ul>
|
||
<h3>v1.1.0 (2026-02-16)</h3>
|
||
<ul>
|
||
<li>**Feature: Bestell-Countdown**: Zeigt 1 Stunde vor Bestellschluss einen roten Countdown an. ⏳</li>
|
||
<li>**Feature: Smart Highlights**: Markiere deine Lieblingsspeisen (z.B. "Schnitzel", "Vegetarisch"), damit sie leuchten. 🌟</li>
|
||
<li>**Feature: Changelog**: Diese Übersicht der Änderungen. 📜</li>
|
||
<li>**Verbesserung**: Live-Check der Version beim Update.</li>
|
||
</ul>
|
||
<h3>v1.0.3 (2026-02-13)</h3>
|
||
<ul>
|
||
<li>**Fix**: Update-Link öffnet nun den Installer direkt als Webseite (via htmlpreview).</li>
|
||
</ul>
|
||
<h3>v1.0.2 (2026-02-13)</h3>
|
||
<ul>
|
||
<li>**Sync**: Version mit GitHub synchronisiert.</li>
|
||
</ul>
|
||
<h3>v1.0.1 (2026-02-12)</h3>
|
||
<ul>
|
||
<li>**UI**: Besseres Design für "Nächste Woche" (Badges).</li>
|
||
<li>**Core**: Grundlegende Funktionen (Bestellen, Guthaben, Token-Store).</li>
|
||
|
||
</div>
|
||
</details>
|
||
</div>
|
||
|
||
<div style="text-align: center; margin-top: 40px; color: #5c6b7f; font-size: 0.8rem;">
|
||
<p>Powered by <strong>Kaufi-Kitchen</strong> 👨🍳</p>
|
||
</div>
|
||
|
||
|
||
<script>
|
||
document.getElementById('bookmarklet-link').href =
|
||
"javascript:(function()%7Bvar%20s=document.createElement(%27style%27);s.textContent=%27:root%20%7B%20%20%20/%2A%20Premium%20Slate/Gray-Blue%20Palette%20-%20Light%20Mode%20%2A/%20%20%20--bg-body:%20%23f1f5f9;%20%20%20/%2A%20Slate%20100%20%2A/%20%20%20--bg-card:%20%23ffffff;%20%20%20--text-primary:%20%23334155;%20%20%20/%2A%20Slate%20700%20%2A/%20%20%20--text-secondary:%20%2364748b;%20%20%20--accent-color:%20%230f172a;%20%20%20/%2A%20Slate%20900%20(High%20contrast)%20%2A/%20%20%20--border-color:%20%23cbd5e1;%20%20%20/%2A%20Slate%20300%20%2A/%20%20%20--banner-bg:%20%23e2e8f0;%20%20%20--banner-text:%20%231e293b;%20%20%20--success-color:%20%23059669;%20%20%20--error-color:%20%23dc2626;%20%20%20--card-shadow:%200%204px%206px%20-1px%20rgb(0%200%200%20/%200.05),%200%202px%204px%20-2px%20rgb(0%200%200%20/%200.05);%20%20%20--header-bg:%20rgba(255,%20255,%20255,%200.9);%20%20%20--header-border:%201px%20solid%20rgba(203,%20213,%20225,%200.6);%20%7D%20%5Bdata-theme=%5C%22dark%5C%22%5D%20%7B%20%20%20/%2A%20Premium%20Slate/Gray-Blue%20Palette%20-%20Dark%20Mode%20%2A/%20%20%20--bg-body:%20%231e293b;%20%20%20/%2A%20Deep%20Slate%20Gray%20(Requested)%20%2A/%20%20%20--bg-card:%20%23334155;%20%20%20/%2A%20Slate%20700%20%2A/%20%20%20--text-primary:%20%23f8fafc;%20%20%20/%2A%20Slate%2050%20%2A/%20%20%20--text-secondary:%20%23cbd5e1;%20%20%20/%2A%20Slate%20300%20%2A/%20%20%20--accent-color:%20%2360a5fa;%20%20%20/%2A%20Blue%20400%20%2A/%20%20%20--border-color:%20%23475569;%20%20%20/%2A%20Slate%20600%20%2A/%20%20%20--banner-bg:%20%23475569;%20%20%20--banner-text:%20%23e2e8f0;%20%20%20--header-bg:%20rgba(30,%2041,%2059,%200.9);%20%20%20--header-border:%201px%20solid%20rgba(71,%2085,%20105,%200.6);%20%20%20--card-shadow:%200%2010px%2015px%20-3px%20rgb(0%200%200%20/%200.4);%20%7D%20%2A%20%7B%20%20%20box-sizing:%20border-box;%20%20%20margin:%200;%20%20%20padding:%200;%20%7D%20body%20%7B%20%20%20font-family:%20%5C%27Inter%5C%27,%20system-ui,%20-apple-system,%20sans-serif;%20%20%20background-color:%20var(--bg-body);%20%20%20color:%20var(--text-primary);%20%20%20transition:%20background-color%200.3s%20ease,%20color%200.3s%20ease;%20%20%20line-height:%201.5;%20%20%20-webkit-font-smoothing:%20antialiased;%20%7D%20/%2A%20Fix%20scrolling%20bug:%20Reset%20html/body%20styles%20from%20host%20page%20%2A/%20html,%20body%20%7B%20%20%20height:%20auto%20!important;%20%20%20min-height:%20100%25%20!important;%20%20%20overflow-y:%20auto%20!important;%20%20%20overflow-x:%20hidden%20!important;%20%20%20position:%20static%20!important;%20%20%20margin:%200%20!important;%20%20%20padding:%200%20!important;%20%7D%20/%2A%20Header%20%2A/%20.app-header%20%7B%20%20%20position:%20sticky;%20%20%20top:%200;%20%20%20z-index:%20100;%20%20%20backdrop-filter:%20blur(12px);%20%20%20background-color:%20var(--header-bg);%20%20%20border-bottom:%20var(--header-border);%20%20%20padding:%201rem%200;%20%7D%20.header-content%20%7B%20%20%20width:%20100%25;%20%20%20/%2A%20Full%20width%20%2A/%20%20%20padding:%200%202rem;%20%20%20/%2A%20Comfortable%20padding%20%2A/%20%20%20display:%20grid;%20%20%20grid-template-columns:%201fr%20auto%201fr;%20%20%20align-items:%20center;%20%20%20gap:%201rem;%20%7D%20.brand%20%7B%20%20%20display:%20flex;%20%20%20align-items:%20center;%20%20%20gap:%200.75rem;%20%7D%20.brand-text%20%7B%20%20%20display:%20flex;%20%20%20flex-direction:%20column;%20%7D%20.brand%20h1%20%7B%20%20%20font-size:%201.25rem;%20%20%20font-weight:%20700;%20%20%20letter-spacing:%20-0.025em;%20%20%20margin-bottom:%200;%20%7D%20.subtitle%20%7B%20%20%20font-size:%200.85rem;%20%20%20color:%20var(--text-secondary);%20%20%20font-weight:%20400;%20%20%20margin-left:%202px;%20%7D%20.logo-icon%20%7B%20%20%20font-size:%201.5rem;%20%20%20color:%20var(--accent-color);%20%7D%20/%2A%20Controls%20%2A/%20.controls%20%7B%20%20%20display:%20flex;%20%20%20align-items:%20center;%20%20%20gap:%201.5rem;%20%20%20justify-self:%20end;%20%7D%20/%2A%20Header%20Week%20Info%20(centered)%20%2A/%20.header-week-info%20%7B%20%20%20text-align:%20center;%20%20%20line-height:%201.3;%20%7D%20.header-center-wrapper%20%7B%20%20%20display:%20flex;%20%20%20flex-direction:%20row;%20%20%20align-items:%20center;%20%20%20gap:%201.5rem;%20%20%20justify-content:%20center;%20%7D%20%20.header-week-title%20%7B%20%20%20font-size:%201.1rem;%20%20%20font-weight:%20600;%20%20%20color:%20var(--text-primary);%20%7D%20.header-week-subtitle%20%7B%20%20%20font-size:%200.85rem;%20%20%20color:%20var(--text-secondary);%20%7D%20.nav-group%20%7B%20%20%20display:%20flex;%20%20%20background-color:%20var(--bg-card);%20%20%20border:%201px%20solid%20var(--border-color);%20%20%20padding:%200.25rem;%20%20%20border-radius:%208px;%20%7D%20.nav-btn%20%7B%20%20%20background:%20none;%20%20%20border:%20none;%20%20%20padding:%200.5rem%201rem;%20%20%20font-size:%200.875rem;%20%20%20font-weight:%20500;%20%20%20color:%20var(--text-secondary);%20%20%20cursor:%20pointer;%20%20%20border-radius:%206px;%20%20%20transition:%20all%200.2s;%20%20%20display:%20flex;%20%20%20align-items:%20center;%20%20%20gap:%200.5rem;%20%7D%20.nav-btn:hover%20%7B%20%20%20color:%20var(--text-primary);%20%20%20background-color:%20rgba(100,%20116,%20139,%200.1);%20%7D%20.nav-btn.active%20%7B%20%20%20background-color:%20var(--accent-color);%20%20%20color:%20white;%20%7D%20/%2A%20Badge%20for%20nav%20buttons%20(day%20count%20indicator)%20%2A/%20.nav-badge%20%7B%20%20%20background-color:%20var(--error-color);%20%20%20color:%20white;%20%20%20font-size:%200.75rem;%20%20%20font-weight:%20600;%20%20%20padding:%200%206px;%20%20%20border-radius:%2010px;%20%20%20min-width:%2018px;%20%20%20height:%2018px;%20%20%20display:%20inline-flex;%20%20%20align-items:%20center;%20%20%20justify-content:%20center;%20%20%20margin-left:%208px;%20%20%20gap:%203px;%20%20%20line-height:%201;%20%7D%20.nav-badge%20.orderable%20%7B%20%20%20color:%20%23fff;%20%20%20font-weight:%20800;%20%7D%20.nav-badge%20.separator%20%7B%20%20%20opacity:%200.6;%20%20%20font-weight:%20400;%20%7D%20.nav-badge%20.total%20%7B%20%20%20opacity:%200.8;%20%20%20font-weight:%20400;%20%7D%20.nav-btn.active%20.nav-badge%20%7B%20%20%20background:%20rgba(255,%20255,%20255,%200.3);%20%7D%20/%2A%20Primary%20style%20for%20Login%20Button%20to%20match%20header%20%2A/%20%23btn-login-open%20%7B%20%20%20background-color:%20var(--accent-color);%20%20%20color:%20white;%20%20%20padding:%200.5rem%201.25rem;%20%20%20border-radius:%208px;%20%20%20font-weight:%20600;%20%20%20letter-spacing:%200.025em;%20%20%20box-shadow:%200%202px%204px%20rgba(0,%200,%200,%200.1);%20%7D%20%23btn-login-open:hover%20%7B%20%20%20background-color:%20%23334155;%20%20%20/%2A%20Slightly%20lighter%20than%20slate-900%20%2A/%20%20%20transform:%20translateY(-1px);%20%20%20box-shadow:%200%204px%206px%20rgba(0,%200,%200,%200.1);%20%7D%20/%2A%20User%20Badge%20Button%20(Login)%20%2A/%20.user-badge-btn%20%7B%20%20%20display:%20flex;%20%20%20align-items:%20center;%20%20%20gap:%208px;%20%20%20padding:%206px%2012px;%20%20%20background:%20var(--bg-card);%20%20%20border:%201px%20solid%20var(--border-color);%20%20%20border-radius:%2020px;%20%20%20font-size:%200.9rem;%20%20%20font-weight:%20500;%20%20%20color:%20var(--text-primary);%20%20%20cursor:%20pointer;%20%20%20transition:%20all%200.2s;%20%7D%20.user-badge-btn:hover%20%7B%20%20%20background:%20rgba(100,%20116,%20139,%200.1);%20%20%20border-color:%20var(--accent-color);%20%7D%20.user-badge-btn%20.material-icons-round%20%7B%20%20%20font-size:%201.25rem;%20%20%20color:%20var(--accent-color);%20%7D%20.icon-btn%20%7B%20%20%20background:%20none;%20%20%20border:%20none;%20%20%20color:%20var(--text-primary);%20%20%20cursor:%20pointer;%20%20%20padding:%200.5rem;%20%20%20border-radius:%2050%25;%20%20%20transition:%20background-color%200.2s;%20%20%20display:%20flex;%20%20%20align-items:%20center;%20%20%20justify-content:%20center;%20%7D%20.icon-btn:hover%20%7B%20%20%20background-color:%20rgba(100,%20116,%20139,%200.1);%20%7D%20/%2A%20Refresh%20button%20animation%20%2A/%20%23btn-refresh.refreshing%20.material-icons-round%20%7B%20%20%20animation:%20rotate%201s%20linear%20infinite;%20%7D%20%40keyframes%20rotate%20%7B%20%20%20from%20%7B%20%20%20%20%20transform:%20rotate(0deg);%20%20%20%7D%20%20%20to%20%7B%20%20%20%20%20transform:%20rotate(360deg);%20%20%20%7D%20%7D%20/%2A%20Progress%20Modal%20%2A/%20.progress-container%20%7B%20%20%20margin-bottom:%201.5rem;%20%7D%20.progress-bar%20%7B%20%20%20width:%20100%25;%20%20%20height:%208px;%20%20%20background-color:%20var(--border-color);%20%20%20border-radius:%204px;%20%20%20overflow:%20hidden;%20%20%20margin-bottom:%200.75rem;%20%7D%20.progress-fill%20%7B%20%20%20height:%20100%25;%20%20%20background:%20linear-gradient(90deg,%20var(--accent-color)%200%25,%20%2360a5fa%20100%25);%20%20%20width:%200%25;%20%20%20transition:%20width%200.3s%20ease;%20%20%20border-radius:%204px;%20%7D%20.progress-percent%20%7B%20%20%20text-align:%20center;%20%20%20font-size:%201.5rem;%20%20%20font-weight:%20700;%20%20%20color:%20var(--text-primary);%20%20%20margin-bottom:%200.5rem;%20%7D%20.progress-message%20%7B%20%20%20text-align:%20center;%20%20%20color:%20var(--text-secondary);%20%20%20font-size:%200.9rem;%20%20%20font-weight:%20500;%20%7D%20.weekly-cost%20%7B%20%20%20background-color:%20rgba(59,%20130,%20246,%200.1);%20%20%20/%2A%20Blue%20tint%20%2A/%20%20%20color:%20var(--accent-color);%20%20%20padding:%200.4rem%200.8rem;%20%20%20border-radius:%208px;%20%20%20font-weight:%20600;%20%20%20font-size:%200.9rem;%20%20%20display:%20flex;%20%20%20align-items:%20center;%20%20%20gap:%200.5rem;%20%20%20border:%201px%20solid%20rgba(59,%20130,%20246,%200.2);%20%7D%20.weekly-cost%20.material-icons-round%20%7B%20%20%20font-size:%2018px;%20%7D%20/%2A%20Container%20%2A/%20.container%20%7B%20%20%20width:%20100%25;%20%20%20/%2A%20Full%20width%20%2A/%20%20%20margin:%202rem%20auto;%20%20%20padding:%200%202rem;%20%20%20min-height:%2080vh;%20%7D%20/%2A%20Banner%20%2A/%20.banner%20%7B%20%20%20background-color:%20var(--banner-bg);%20%20%20color:%20var(--banner-text);%20%20%20padding:%200.75rem%201rem;%20%20%20border-radius:%208px;%20%20%20display:%20flex;%20%20%20align-items:%20center;%20%20%20gap:%200.5rem;%20%20%20margin-bottom:%202rem;%20%20%20font-size:%200.875rem;%20%20%20font-weight:%20500;%20%20%20border:%201px%20solid%20var(--border-color);%20%20%20max-width:%20fit-content;%20%7D%20/%2A%20User%20Badge%20%2A/%20.user-badge%20%7B%20%20%20display:%20flex;%20%20%20align-items:%20center;%20%20%20gap:%208px;%20%20%20padding:%206px%2012px;%20%20%20background:%20var(--bg-card);%20%20%20/%2A%20Changed%20from%20--surface%20%2A/%20%20%20border:%201px%20solid%20var(--border-color);%20%20%20/%2A%20Changed%20from%20--border%20%2A/%20%20%20border-radius:%2020px;%20%20%20font-size:%200.9rem;%20%20%20font-weight:%20500;%20%7D%20.icon-btn-small%20%7B%20%20%20background:%20none;%20%20%20border:%20none;%20%20%20padding:%204px;%20%20%20cursor:%20pointer;%20%20%20color:%20var(--text-secondary);%20%20%20/%2A%20Changed%20from%20--text-muted%20%2A/%20%20%20display:%20flex;%20%20%20align-items:%20center;%20%20%20justify-content:%20center;%20%20%20border-radius:%2050%25;%20%20%20transition:%20all%200.2s;%20%7D%20.icon-btn-small:hover%20%7B%20%20%20color:%20var(--error-color);%20%20%20/%2A%20Changed%20from%20--danger%20%2A/%20%20%20background:%20rgba(239,%2068,%2068,%200.1);%20%7D%20/%2A%20Modal%20%2A/%20.modal%20%7B%20%20%20position:%20fixed;%20%20%20top:%200;%20%20%20left:%200;%20%20%20width:%20100%25;%20%20%20height:%20100%25;%20%20%20background:%20rgba(0,%200,%200,%200.5);%20%20%20backdrop-filter:%20blur(4px);%20%20%20display:%20flex;%20%20%20align-items:%20center;%20%20%20justify-content:%20center;%20%20%20z-index:%201000;%20%20%20transition:%20all%200.3s;%20%7D%20.modal.hidden%20%7B%20%20%20opacity:%200;%20%20%20pointer-events:%20none;%20%7D%20.modal-content%20%7B%20%20%20background:%20var(--bg-card);%20%20%20width:%2090%25;%20%20%20max-width:%20400px;%20%20%20border-radius:%2016px;%20%20%20box-shadow:%200%2020px%2025px%20-5px%20rgba(0,%200,%200,%200.1),%200%2010px%2010px%20-5px%20rgba(0,%200,%200,%200.04);%20%20%20overflow:%20hidden;%20%20%20animation:%20modalSlide%200.3s%20ease-out;%20%7D%20/%2A%20History%20Modal%20specific%20%2A/%20.history-modal-content%20%7B%20%20%20max-width:%20600px;%20%20%20max-height:%2085vh;%20%20%20display:%20flex;%20%20%20flex-direction:%20column;%20%7D%20.history-modal-content%20.modal-body%20%7B%20%20%20overflow-y:%20auto;%20%20%20padding:%200;%20/%2A%20Padding%20is%20handled%20by%20inner%20elements%20%2A/%20%7D%20/%2A%20History%20Styles%20%2A/%20.history-month-group%20%7B%20%20%20margin-bottom:%2024px;%20%7D%20.history-month-header%20%7B%20%20%20position:%20sticky;%20%20%20top:%200;%20%20%20background:%20var(--bg-card);%20%20%20padding:%2012px%2020px;%20%20%20margin:%200;%20%20%20font-size:%201.1rem;%20%20%20font-weight:%20700;%20%20%20color:%20var(--text-primary);%20%20%20border-bottom:%201px%20solid%20var(--border-color);%20%20%20border-top:%201px%20solid%20var(--border-color);%20%20%20z-index:%2010;%20%7D%20.history-month-group:first-child%20.history-month-header%20%7B%20%20%20border-top:%20none;%20%7D%20.history-week-group%20%7B%20%20%20padding:%2016px%2020px%208px;%20%7D%20.history-week-header%20%7B%20%20%20display:%20flex;%20%20%20justify-content:%20space-between;%20%20%20align-items:%20center;%20%20%20font-size:%200.95rem;%20%20%20font-weight:%20600;%20%20%20color:%20var(--text-secondary);%20%20%20margin-bottom:%2012px;%20%7D%20.history-week-summary%20%7B%20%20%20font-size:%200.85rem;%20%20%20font-weight:%20500;%20%20%20background:%20rgba(100,%20116,%20139,%200.1);%20%20%20padding:%204px%2010px;%20%20%20border-radius:%2012px;%20%7D%20.history-items%20%7B%20%20%20display:%20flex;%20%20%20flex-direction:%20column;%20%20%20gap:%208px;%20%7D%20.history-item%20%7B%20%20%20display:%20grid;%20%20%20grid-template-columns:%2050px%201fr%20auto;%20%20%20align-items:%20center;%20%20%20gap:%2012px;%20%20%20padding:%2010px%2012px;%20%20%20background:%20var(--bg-body);%20%20%20border-radius:%208px;%20%20%20border:%201px%20solid%20var(--border-color);%20%7D%20.history-item-date%20%7B%20%20%20font-size:%200.85rem;%20%20%20color:%20var(--text-secondary);%20%20%20font-weight:%20500;%20%7D%20.history-item-details%20%7B%20%20%20display:%20flex;%20%20%20flex-direction:%20column;%20%20%20gap:%204px;%20%7D%20.history-item-name%20%7B%20%20%20font-size:%200.95rem;%20%20%20font-weight:%20500;%20%20%20color:%20var(--text-primary);%20%7D%20.history-item-price%20%7B%20%20%20font-weight:%20600;%20%20%20color:%20var(--text-primary);%20%7D%20.history-item-name-cancelled%20%7B%20%20%20text-decoration:%20line-through;%20%20%20color:%20var(--text-secondary);%20%7D%20.history-item-price-cancelled%20%7B%20%20%20text-decoration:%20line-through;%20%20%20color:%20var(--text-secondary);%20%7D%20%40keyframes%20modalSlide%20%7B%20%20%20from%20%7B%20%20%20%20%20transform:%20translateY(20px);%20%20%20%20%20opacity:%200;%20%20%20%7D%20%20%20to%20%7B%20%20%20%20%20transform:%20translateY(0);%20%20%20%20%20opacity:%201;%20%20%20%7D%20%7D%20.modal-header%20%7B%20%20%20display:%20flex;%20%20%20align-items:%20center;%20%20%20justify-content:%20space-between;%20%20%20padding:%2020px;%20%20%20border-bottom:%201px%20solid%20var(--border-color);%20%7D%20.modal-header%20h2%20%7B%20%20%20margin:%200;%20%20%20font-size:%201.25rem;%20%7D%20.modal-body%20%7B%20%20%20padding:%2020px;%20%7D%20%23login-form%20%7B%20%20%20padding:%2020px;%20%7D%20.form-group%20%7B%20%20%20margin-bottom:%2020px;%20%7D%20.form-group%20label%20%7B%20%20%20display:%20block;%20%20%20margin-bottom:%206px;%20%20%20font-weight:%20500;%20%20%20font-size:%200.9rem;%20%7D%20.form-group%20input%20%7B%20%20%20width:%20100%25;%20%20%20padding:%2010px%2012px;%20%20%20border:%201px%20solid%20var(--border-color);%20%20%20/%2A%20Changed%20from%20--border%20%2A/%20%20%20border-radius:%208px;%20%20%20background:%20var(--bg-body);%20%20%20/%2A%20Changed%20from%20--bg%20%2A/%20%20%20color:%20var(--text-primary);%20%20%20/%2A%20Changed%20from%20--text%20%2A/%20%20%20font-family:%20inherit;%20%20%20transition:%20border-color%200.2s;%20%7D%20.form-group%20input:focus%20%7B%20%20%20outline:%20none;%20%20%20border-color:%20var(--accent-color);%20%20%20/%2A%20Changed%20from%20--primary%20%2A/%20%7D%20.help-text%20%7B%20%20%20display:%20block;%20%20%20margin-top:%204px;%20%20%20color:%20var(--text-secondary);%20%20%20/%2A%20Changed%20from%20--text-muted%20%2A/%20%20%20font-size:%200.75rem;%20%7D%20.error-msg%20%7B%20%20%20margin-bottom:%2016px;%20%20%20padding:%2010px;%20%20%20background:%20rgba(239,%2068,%2068,%200.1);%20%20%20color:%20var(--error-color);%20%20%20/%2A%20Changed%20from%20--danger%20%2A/%20%20%20border-radius:%208px;%20%20%20font-size:%200.85rem;%20%20%20text-align:%20center;%20%7D%20.modal-actions%20%7B%20%20%20margin-top:%2024px;%20%7D%20.btn-primary.wide%20%7B%20%20%20width:%20100%25;%20%20%20justify-content:%20center;%20%7D%20.hidden%20%7B%20%20%20display:%20none%20!important;%20%7D%20/%2A%20Menu%20Grid%20%2A/%20.menu-grid%20%7B%20%20%20display:%20grid;%20%20%20gap:%202rem;%20%7D%20.week-section%20%7B%20%20%20margin-bottom:%203rem;%20%7D%20.week-header%20%7B%20%20%20margin-bottom:%201.5rem;%20%20%20border-bottom:%201px%20solid%20var(--border-color);%20%20%20padding-bottom:%201rem;%20%20%20text-align:%20center;%20%7D%20.week-title%20%7B%20%20%20font-size:%201.75rem;%20%20%20font-weight:%20700;%20%20%20color:%20var(--text-primary);%20%7D%20.week-range%20%7B%20%20%20color:%20var(--text-secondary);%20%20%20font-size:%200.9rem;%20%20%20margin-top:%200.25rem;%20%7D%20.days-grid%20%7B%20%20%20display:%20grid;%20%20%20grid-template-columns:%20repeat(auto-fit,%20minmax(180px,%201fr));%20%20%20gap:%200.75rem;%20%7D%20/%2A%20Card%20%2A/%20.menu-card%20%7B%20%20%20background-color:%20var(--bg-card);%20%20%20border-radius:%2012px;%20%20%20border:%201px%20solid%20var(--border-color);%20%20%20box-shadow:%20var(--card-shadow);%20%20%20overflow:%20hidden;%20%20%20transition:%20transform%200.2s%20ease,%20box-shadow%200.2s%20ease;%20%20%20display:%20flex;%20%20%20flex-direction:%20column;%20%7D%20/%2A%20Past%20Day%20Styling%20-%20Target%20specific%20elements%20so%20ordered%20items%20can%20remain%20visible%20%2A/%20.menu-card.past-day%20.card-header,%20.menu-card.past-day%20.menu-item:not(.ordered)%20%7B%20%20%20opacity:%200.6;%20%20%20filter:%20grayscale(0.8);%20%20%20transition:%20opacity%200.3s,%20filter%200.3s;%20%7D%20.menu-card.past-day:hover%20.card-header,%20.menu-card.past-day:hover%20.menu-item:not(.ordered)%20%7B%20%20%20opacity:%200.8;%20%20%20filter:%20grayscale(0.4);%20%7D%20/%2A%20Enhancements%20for%20ordered%20items%20%2A/%20.menu-card.past-day%20.menu-item.ordered%20%7B%20%20%20/%2A%20No%20opacity/filter%20here%20-%20fully%20visible%20%2A/%20%20%20background:%20var(--bg-card);%20%20%20box-shadow:%200%204px%2012px%20rgba(0,%200,%200,%200.15);%20%20%20border:%201px%20solid%20var(--accent-color);%20%20%20border-radius:%208px;%20%20%20padding:%201rem;%20%20%20margin:%200%20-1rem%201.5rem%20-1rem;%20%20%20position:%20relative;%20%20%20z-index:%2010;%20%7D%20.menu-item.today-ordered%20%7B%20%20%20border:%202px%20solid%20var(--accent-color);%20%20%20box-shadow:%200%200%2020px%20rgba(96,%20165,%20250,%200.4);%20%20%20border-radius:%208px;%20%20%20padding:%201rem;%20%20%20margin:%200%20-1rem%201.5rem%20-1rem;%20%20%20background:%20var(--bg-card);%20%20%20position:%20relative;%20%20%20z-index:%205;%20%20%20animation:%20pulse-glow%203s%20infinite;%20%7D%20%40keyframes%20pulse-glow%20%7B%20%20%200%25%20%7B%20%20%20%20%20box-shadow:%200%200%2015px%20rgba(96,%20165,%20250,%200.3);%20%20%20%7D%20%20%2050%25%20%7B%20%20%20%20%20box-shadow:%200%200%2025px%20rgba(96,%20165,%20250,%200.6);%20%20%20%7D%20%20%20100%25%20%7B%20%20%20%20%20box-shadow:%200%200%2015px%20rgba(96,%20165,%20250,%200.3);%20%20%20%7D%20%7D%20%20.menu-card:hover%20%7B%20%20%20transform:%20translateY(-2px);%20%20%20box-shadow:%200%2020px%2025px%20-5px%20rgb(0%200%200%20/%200.1),%200%208px%2010px%20-6px%20rgb(0%200%200%20/%200.1);%20%7D%20.card-header%20%7B%20%20%20padding:%201rem%201.25rem;%20%20%20border-bottom:%201px%20solid%20var(--border-color);%20%20%20display:%20flex;%20%20%20justify-content:%20space-between;%20%20%20align-items:%20baseline;%20%20%20background-color:%20rgba(100,%20116,%20139,%200.05);%20%7D%20.day-name%20%7B%20%20%20font-size:%201.125rem;%20%20%20font-weight:%20600;%20%7D%20.day-date%20%7B%20%20%20font-size:%200.875rem;%20%20%20color:%20var(--text-secondary);%20%7D%20.card-body%20%7B%20%20%20padding:%201.25rem;%20%20%20display:%20grid;%20%20%20grid-template-rows:%20auto;%20%20%20/%2A%20Each%20menu%20item%20gets%20its%20own%20row%20%2A/%20%20%20align-content:%20start;%20%7D%20.empty-state%20%7B%20%20%20color:%20var(--text-secondary);%20%20%20font-style:%20italic;%20%20%20text-align:%20center;%20%20%20padding:%201rem;%20%7D%20/%2A%20Menu%20Items%20%2A/%20.menu-item%20%7B%20%20%20margin-bottom:%201.5rem;%20%20%20padding-bottom:%201.5rem;%20%20%20border-bottom:%201px%20solid%20var(--border-color);%20%7D%20.menu-item:last-child%20%7B%20%20%20margin-bottom:%200;%20%20%20padding-bottom:%200;%20%20%20border-bottom:%20none;%20%7D%20.item-header%20%7B%20%20%20display:%20flex;%20%20%20justify-content:%20space-between;%20%20%20align-items:%20flex-start;%20%20%20margin-bottom:%200.5rem;%20%20%20gap:%201rem;%20%7D%20.item-name%20%7B%20%20%20font-weight:%20600;%20%20%20color:%20var(--text-primary);%20%20%20font-size:%201rem;%20%7D%20.item-price%20%7B%20%20%20font-weight:%20700;%20%20%20color:%20var(--accent-color);%20%20%20white-space:%20nowrap;%20%7D%20.item-desc%20%7B%20%20%20font-size:%200.875rem;%20%20%20color:%20var(--text-secondary);%20%20%20line-height:%201.6;%20%20%20margin-bottom:%200.75rem;%20%7D%20.badges%20%7B%20%20%20display:%20flex;%20%20%20gap:%200.5rem;%20%20%20margin-left:%20auto;%20%7D%20.item-status-row%20%7B%20%20%20display:%20flex;%20%20%20align-items:%20center;%20%20%20gap:%200.5rem;%20%20%20margin-bottom:%200.75rem;%20%7D%20.badge%20%7B%20%20%20display:%20inline-flex;%20%20%20align-items:%20center;%20%20%20justify-content:%20center;%20%20%20height:%2024px;%20%20%20font-size:%200.75rem;%20%20%20padding:%200%2010px;%20%20%20border-radius:%204px;%20%20%20font-weight:%20600;%20%20%20text-transform:%20uppercase;%20%20%20letter-spacing:%200.05em;%20%20%20line-height:%20normal;%20%20%20white-space:%20nowrap;%20%7D%20.badge.available%20%7B%20%20%20background-color:%20rgba(16,%20185,%20129,%200.1);%20%20%20/%2A%20Emerald%20500%20/%2010%25%20%2A/%20%20%20color:%20var(--success-color);%20%20%20border:%201px%20solid%20rgba(16,%20185,%20129,%200.2);%20%7D%20.badge.sold-out%20%7B%20%20%20background-color:%20rgba(239,%2068,%2068,%200.1);%20%20%20/%2A%20Red%20500%20/%2010%25%20%2A/%20%20%20color:%20var(--error-color);%20%20%20border:%201px%20solid%20rgba(239,%2068,%2068,%200.2);%20%7D%20.badge.ordered%20%7B%20%20%20background-color:%20rgba(139,%2092,%20246,%200.1);%20%20%20/%2A%20Violet%20500%20/%2010%25%20%2A/%20%20%20color:%20%238b5cf6;%20%20%20border:%201px%20solid%20rgba(139,%2092,%20246,%200.2);%20%20%20gap:%204px;%20%7D%20.badge.ordered%20.material-icons-round%20%7B%20%20%20font-size:%201rem;%20%7D%20/%2A%20Loading%20%2A/%20.loading-state%20%7B%20%20%20text-align:%20center;%20%20%20padding:%204rem;%20%20%20color:%20var(--text-secondary);%20%7D%20.spinner%20%7B%20%20%20width:%2040px;%20%20%20height:%2040px;%20%20%20border:%203px%20solid%20var(--border-color);%20%20%20border-top-color:%20var(--accent-color);%20%20%20border-radius:%2050%25;%20%20%20margin:%200%20auto%201rem;%20%20%20animation:%20spin%201s%20linear%20infinite;%20%7D%20%40keyframes%20spin%20%7B%20%20%20to%20%7B%20%20%20%20%20transform:%20rotate(360deg);%20%20%20%7D%20%7D%20/%2A%20Footer%20%2A/%20.app-footer%20%7B%20%20%20text-align:%20center;%20%20%20padding:%202rem;%20%20%20color:%20var(--text-secondary);%20%20%20font-size:%200.875rem;%20%20%20border-top:%201px%20solid%20var(--border-color);%20%20%20margin-top:%20auto;%20%7D%20/%2A%20===%20Order%20/%20Cancel%20Buttons%20(inline%20in%20status%20row)%20===%20%2A/%20.btn-order%20%7B%20%20%20display:%20inline-flex;%20%20%20align-items:%20center;%20%20%20gap:%204px;%20%20%20padding:%204px%2010px;%20%20%20border:%20none;%20%20%20border-radius:%206px;%20%20%20background:%20var(--success-color);%20%20%20color:%20white;%20%20%20font-size:%200.75rem;%20%20%20font-weight:%20600;%20%20%20cursor:%20pointer;%20%20%20transition:%20all%200.2s%20ease;%20%20%20font-family:%20inherit;%20%7D%20.btn-order%20.material-icons-round%20%7B%20%20%20font-size:%2016px;%20%7D%20.btn-order:hover:not(:disabled)%20%7B%20%20%20filter:%20brightness(1.15);%20%20%20transform:%20translateY(-1px);%20%7D%20.btn-order:disabled%20%7B%20%20%20opacity:%200.5;%20%20%20cursor:%20not-allowed;%20%7D%20.btn-order.loading%20%7B%20%20%20pointer-events:%20none;%20%20%20opacity:%200.6;%20%7D%20.btn-order-compact%20%7B%20%20%20padding:%202px%204px;%20%20%20gap:%200;%20%7D%20.btn-order-compact%20.material-icons-round%20%7B%20%20%20font-size:%2016px;%20%7D%20.btn-cancel%20%7B%20%20%20display:%20inline-flex;%20%20%20align-items:%20center;%20%20%20justify-content:%20center;%20%20%20padding:%204px%206px;%20%20%20border:%20none;%20%20%20border-radius:%206px;%20%20%20background:%20var(--error-color);%20%20%20color:%20white;%20%20%20font-size:%200.75rem;%20%20%20cursor:%20pointer;%20%20%20transition:%20all%200.2s%20ease;%20%20%20font-family:%20inherit;%20%7D%20.btn-cancel%20.material-icons-round%20%7B%20%20%20font-size:%2016px;%20%7D%20.btn-cancel:hover:not(:disabled)%20%7B%20%20%20filter:%20brightness(1.15);%20%20%20transform:%20translateY(-1px);%20%7D%20.btn-cancel:disabled%20%7B%20%20%20opacity:%200.5;%20%20%20cursor:%20not-allowed;%20%7D%20/%2A%20Past%20days:%20hide%20action%20buttons%20%2A/%20.past-day%20.item-actions%20%7B%20%20%20display:%20none;%20%7D%20/%2A%20Order%20count%20badge%20(for%20multi-orders)%20%2A/%20.order-count-badge%20%7B%20%20%20display:%20inline-flex;%20%20%20align-items:%20center;%20%20%20justify-content:%20center;%20%20%20background:%20rgba(255,%20255,%20255,%200.3);%20%20%20color:%20white;%20%20%20font-size:%200.65rem;%20%20%20font-weight:%20700;%20%20%20min-width:%2016px;%20%20%20height:%2016px;%20%20%20padding:%200%204px;%20%20%20border-radius:%208px;%20%20%20margin-left:%204px;%20%20%20line-height:%201;%20%7D%20/%2A%20===%20Toast%20Notifications%20===%20%2A/%20%23toast-container%20%7B%20%20%20position:%20fixed;%20%20%20bottom:%2020px;%20%20%20right:%2020px;%20%20%20z-index:%2010000;%20%20%20display:%20flex;%20%20%20flex-direction:%20column;%20%20%20gap:%208px;%20%20%20pointer-events:%20none;%20%7D%20.toast%20%7B%20%20%20display:%20flex;%20%20%20align-items:%20center;%20%20%20gap:%208px;%20%20%20padding:%2010px%2016px;%20%20%20border-radius:%208px;%20%20%20font-size:%200.85rem;%20%20%20font-weight:%20500;%20%20%20font-family:%20%5C%27Inter%5C%27,%20sans-serif;%20%20%20color:%20white;%20%20%20backdrop-filter:%20blur(10px);%20%20%20box-shadow:%200%204px%2012px%20rgba(0,%200,%200,%200.3);%20%20%20pointer-events:%20auto;%20%20%20transform:%20translateX(120%25);%20%20%20opacity:%200;%20%20%20transition:%20transform%200.3s%20ease,%20opacity%200.3s%20ease;%20%7D%20.toast.show%20%7B%20%20%20transform:%20translateX(0);%20%20%20opacity:%201;%20%7D%20.toast%20.material-icons-round%20%7B%20%20%20font-size:%2018px;%20%7D%20.toast-success%20%7B%20%20%20background:%20rgba(5,%20150,%20105,%200.95);%20%7D%20.toast-error%20%7B%20%20%20background:%20rgba(220,%2038,%2038,%200.95);%20%7D%20.toast-info%20%7B%20%20%20background:%20rgba(59,%20130,%20246,%200.95);%20%7D%20/%2A%20===%20Mobile%20Responsiveness%20===%20%2A/%20%40media%20(max-width:%20600px)%20%7B%20%20%20.header-content%20%7B%20%20%20%20%20flex-direction:%20column;%20%20%20%20%20gap:%201rem;%20%20%20%20%20padding:%200.75rem;%20%20%20%7D%20%20%20.week-nav%20%7B%20%20%20%20%20width:%20100%25;%20%20%20%20%20justify-content:%20center;%20%20%20%7D%20%20%20.nav-pills%20%7B%20%20%20%20%20width:%20100%25;%20%20%20%20%20justify-content:%20space-between;%20%20%20%7D%20%20%20.nav-btn%20%7B%20%20%20%20%20flex:%201;%20%20%20%20%20justify-content:%20center;%20%20%20%20%20padding:%200.5rem;%20%20%20%20%20font-size:%200.85rem;%20%20%20%7D%20%20%20.days-grid%20%7B%20%20%20%20%20grid-template-columns:%201fr;%20%20%20%20%20/%2A%20Force%20single%20column%20%2A/%20%20%20%7D%20%20%20.main-content%20%7B%20%20%20%20%20padding:%201rem;%20%20%20%7D%20%20%20.week-title%20%7B%20%20%20%20%20font-size:%201.5rem;%20%20%20%7D%20%20%20/%2A%20Adjust%20toast%20position%20for%20mobile%20%2A/%20%20%20.toast-container%20%7B%20%20%20%20%20bottom:%201rem;%20%20%20%20%20right:%201rem;%20%20%20%20%20left:%201rem;%20%20%20%20%20/%2A%20Center%20on%20mobile%20%2A/%20%20%20%20%20width:%20auto;%20%20%20%7D%20%20%20.menu-card%20%7B%20%20%20%20%20margin-bottom:%201rem;%20%20%20%7D%20%7D%20/%2A%20===%20Flagging%20%26%20Notification%20Styles%20===%20%2A/%20.btn-flag%20%7B%20%20%20display:%20inline-flex;%20%20%20align-items:%20center;%20%20%20justify-content:%20center;%20%20%20background:%20transparent;%20%20%20border:%201px%20solid%20var(--text-secondary);%20%20%20color:%20var(--text-secondary);%20%20%20border-radius:%206px;%20%20%20padding:%204px;%20%20%20cursor:%20pointer;%20%20%20transition:%20all%200.2s;%20%20%20margin-right:%200.5rem;%20%20%20width:%2028px;%20%20%20height:%2028px;%20%7D%20.btn-flag:hover%20%7B%20%20%20background:%20rgba(234,%20179,%208,%200.1);%20%20%20/%2A%20Yellow-500%20/%2010%25%20%2A/%20%20%20color:%20%23eab308;%20%20%20border-color:%20%23eab308;%20%7D%20.btn-flag.active%20%7B%20%20%20background:%20rgba(234,%20179,%208,%200.1);%20%20%20color:%20%23eab308;%20%20%20border-color:%20%23eab308;%20%7D%20.btn-flag%20.material-icons-round%20%7B%20%20%20font-size:%201.1rem;%20%7D%20/%2A%20Flagged%20%26%20Sold%20Out%20(Yellow%20Glow)%20%2A/%20.menu-item.flagged-sold-out%20%7B%20%20%20border:%201px%20solid%20%23eab308;%20%20%20box-shadow:%200%200%2010px%20rgba(234,%20179,%208,%200.2);%20%20%20border-radius:%208px;%20%20%20padding:%201rem;%20%20%20margin:%200%20-1rem%201.5rem%20-1rem;%20%20%20background:%20var(--bg-card);%20%20%20position:%20relative;%20%20%20z-index:%205;%20%20%20animation:%20yellow-pulse%203s%20infinite;%20%7D%20%40keyframes%20yellow-pulse%20%7B%20%20%200%25%20%7B%20%20%20%20%20box-shadow:%200%200%208px%20rgba(234,%20179,%208,%200.2);%20%20%20%7D%20%20%2050%25%20%7B%20%20%20%20%20box-shadow:%200%200%2016px%20rgba(234,%20179,%208,%200.5);%20%20%20%7D%20%20%20100%25%20%7B%20%20%20%20%20box-shadow:%200%200%208px%20rgba(234,%20179,%208,%200.2);%20%20%20%7D%20%7D%20/%2A%20Flagged%20%26%20Available%20(Green%20Glow)%20%2A/%20.menu-item.flagged-available%20%7B%20%20%20border:%202px%20solid%20var(--success-color);%20%20%20box-shadow:%200%200%2015px%20rgba(16,%20185,%20129,%200.3);%20%20%20border-radius:%208px;%20%20%20padding:%201rem;%20%20%20margin:%200%20-1rem%201.5rem%20-1rem;%20%20%20background:%20var(--bg-card);%20%20%20position:%20relative;%20%20%20z-index:%205;%20%20%20animation:%20green-pulse%203s%20infinite;%20%7D%20%40keyframes%20green-pulse%20%7B%20%20%200%25%20%7B%20%20%20%20%20box-shadow:%200%200%2010px%20rgba(16,%20185,%20129,%200.3);%20%20%20%7D%20%20%2050%25%20%7B%20%20%20%20%20box-shadow:%200%200%2020px%20rgba(16,%20185,%20129,%200.6);%20%20%20%7D%20%20%20100%25%20%7B%20%20%20%20%20box-shadow:%200%200%2010px%20rgba(16,%20185,%20129,%200.3);%20%20%20%7D%20%7D%20/%2A%20Day%20Header%20Badges%20%2A/%20.day-header-left%20%7B%20%20%20display:%20flex;%20%20%20align-items:%20center;%20%20%20gap:%200.75rem;%20%7D%20.menu-code-badge%20%7B%20%20%20font-size:%200.75rem;%20%20%20font-weight:%20700;%20%20%20color:%20%238b5cf6;%20%20%20/%2A%20Violet%20500%20%2A/%20%20%20background-color:%20rgba(139,%2092,%20246,%200.15);%20%20%20border:%201px%20solid%20rgba(139,%2092,%20246,%200.3);%20%20%20padding:%202px%206px;%20%20%20border-radius:%206px;%20%20%20line-height:%20normal;%20%20%20display:%20inline-block;%20%7D%20/%2A%20Detailed%20Badge%20Colors%20%2A/%20.nav-badge.badge-violet%20%7B%20%20%20background-color:%20%238b5cf6;%20%7D%20.nav-badge.badge-green%20%7B%20%20%20background-color:%20var(--success-color);%20%7D%20.nav-badge.badge-red%20%7B%20%20%20background-color:%20var(--error-color);%20%7D%20.nav-badge.badge-blue%20%7B%20%20%20background-color:%20var(--accent-color);%20%7D%20/%2A%20Day%20Header%20Status%20Colors%20(User%20Request)%20%2A/%20.card-header.header-violet%20%7B%20%20%20background-color:%20rgba(139,%2092,%20246,%200.15);%20%20%20border-bottom:%202px%20solid%20%238b5cf6;%20%7D%20.card-header.header-green%20%7B%20%20%20background-color:%20rgba(16,%20185,%20129,%200.15);%20%20%20border-bottom:%202px%20solid%20var(--success-color);%20%7D%20.card-header.header-red%20%7B%20%20%20background-color:%20rgba(239,%2068,%2068,%200.15);%20%20%20border-bottom:%202px%20solid%20var(--error-color);%20%7D%20.card-header.header-violet%20.day-name,%20.card-header.header-green%20.day-name,%20.card-header.header-red%20.day-name%20%7B%20%20%20font-weight:%20700;%20%20%20color:%20var(--text-primary);%20%20%20/%2A%20Ensure%20text%20remains%20standard%20color%20%2A/%20%7D%20/%2A%20Update%20Icon%20%2A/%20.update-icon%20%7B%20%20%20display:%20inline-flex;%20%20%20align-items:%20center;%20%20%20justify-content:%20center;%20%20%20margin-left:%208px;%20%20%20background-color:%20rgba(16,%20185,%20129,%200.2);%20%20%20/%2A%20Green%20tint%20%2A/%20%20%20color:%20var(--success-color);%20%20%20border-radius:%2050%25;%20%20%20width:%2024px;%20%20%20height:%2024px;%20%20%20cursor:%20pointer;%20%20%20font-size:%2014px;%20%20%20transition:%20all%200.2s;%20%20%20text-decoration:%20none;%20%20%20animation:%20pulse%202s%20infinite;%20%7D%20.update-icon:hover%20%7B%20%20%20background-color:%20var(--success-color);%20%20%20color:%20white;%20%20%20transform:%20scale(1.1);%20%7D%20%40keyframes%20pulse%20%7B%20%20%200%25%20%7B%20%20%20%20%20box-shadow:%200%200%200%200%20rgba(16,%20185,%20129,%200.4);%20%20%20%7D%20%20%2070%25%20%7B%20%20%20%20%20box-shadow:%200%200%200%206px%20rgba(16,%20185,%20129,%200);%20%20%20%7D%20%20%20100%25%20%7B%20%20%20%20%20box-shadow:%200%200%200%200%20rgba(16,%20185,%20129,%200);%20%20%20%7D%20%7D%20/%2A%20Order%20Countdown%20%2A/%20%23order-countdown%20%7B%20%20%20background:%20rgba(255,%20255,%20255,%200.1);%20%20%20padding:%200.25rem%200.75rem;%20%20%20border-radius:%2099px;%20%20%20font-size:%200.85rem;%20%20%20display:%20flex;%20%20%20align-items:%20center;%20%20%20gap:%200.5rem;%20%20%20white-space:%20nowrap;%20%20%20border:%201px%20solid%20var(--border-color);%20%7D%20%23order-countdown%20span%20%7B%20%20%20opacity:%200.7;%20%20%20font-size:%200.75rem;%20%20%20text-transform:%20uppercase;%20%20%20letter-spacing:%200.5px;%20%7D%20%23order-countdown.urgent%20%7B%20%20%20background:%20rgba(239,%2068,%2068,%200.2);%20%20%20border-color:%20rgba(239,%2068,%2068,%200.5);%20%20%20color:%20%23ef4444;%20%20%20animation:%20pulse-red%202s%20infinite;%20%7D%20%40keyframes%20pulse-red%20%7B%20%20%200%25%20%7B%20%20%20%20%20box-shadow:%200%200%200%200%20rgba(239,%2068,%2068,%200.4);%20%20%20%7D%20%20%2070%25%20%7B%20%20%20%20%20box-shadow:%200%200%200%206px%20rgba(239,%2068,%2068,%200);%20%20%20%7D%20%20%20100%25%20%7B%20%20%20%20%20box-shadow:%200%200%200%200%20rgba(239,%2068,%2068,%200);%20%20%20%7D%20%7D%20/%2A%20Smart%20Highlights%20(Blue%20Glow%20-%20matches%20today-ordered/flagged%20pattern)%20%2A/%20.menu-item.highlight-glow%20%7B%20%20%20border:%202px%20solid%20rgba(59,%20130,%20246,%200.7);%20%20%20box-shadow:%200%200%2020px%20rgba(59,%20130,%20246,%200.4);%20%20%20border-radius:%208px;%20%20%20padding:%201rem;%20%20%20margin:%200%20-1rem%201.5rem%20-1rem;%20%20%20background:%20var(--bg-card);%20%20%20position:%20relative;%20%20%20z-index:%205;%20%20%20animation:%20blue-pulse%203s%20infinite;%20%7D%20%40keyframes%20blue-pulse%20%7B%20%20%200%25%20%7B%20%20%20%20%20box-shadow:%200%200%2015px%20rgba(59,%20130,%20246,%200.3);%20%20%20%7D%20%20%2050%25%20%7B%20%20%20%20%20box-shadow:%200%200%2025px%20rgba(59,%20130,%20246,%200.6);%20%20%20%7D%20%20%20100%25%20%7B%20%20%20%20%20box-shadow:%200%200%2015px%20rgba(59,%20130,%20246,%200.3);%20%20%20%7D%20%7D%20/%2A%20Nav%20Badge%20with%20Count%20%2A/%20.nav-badge.has-highlights%20%7B%20%20%20background-color:%20var(--bg-card);%20%20%20/%2A%20Neutral%20background%20%2A/%20%20%20color:%20var(--text-primary);%20%20%20border:%201px%20solid%20var(--border-color);%20%20%20padding:%202px%206px;%20%7D%20.nav-badge%20.highlight-count%20%7B%20%20%20color:%20%233b82f6;%20%20%20/%2A%20Blue%20500%20%2A/%20%20%20font-weight:%20700;%20%20%20margin-left:%204px;%20%7D%20/%2A%20Tag%20Management%20Modal%20%2A/%20%23tags-list%20%7B%20%20%20display:%20flex;%20%20%20flex-wrap:%20wrap;%20%20%20gap:%200.5rem;%20%20%20margin-top:%201rem;%20%20%20min-height:%2050px;%20%7D%20/%2A%20Tag%20badges%20styled%20consistently%20with%20.badge%20(verf%C3%BCgbar/ausverkauft)%20%2A/%20.tag-badge%20%7B%20%20%20display:%20inline-flex;%20%20%20align-items:%20center;%20%20%20justify-content:%20center;%20%20%20height:%2024px;%20%20%20font-size:%200.75rem;%20%20%20padding:%200%2010px;%20%20%20border-radius:%204px;%20%20%20font-weight:%20600;%20%20%20text-transform:%20uppercase;%20%20%20letter-spacing:%200.05em;%20%20%20line-height:%20normal;%20%20%20white-space:%20nowrap;%20%20%20background-color:%20rgba(59,%20130,%20246,%200.1);%20%20%20color:%20%233b82f6;%20%20%20border:%201px%20solid%20rgba(59,%20130,%20246,%200.2);%20%20%20gap:%204px;%20%7D%20.tag-remove%20%7B%20%20%20cursor:%20pointer;%20%20%20opacity:%200.7;%20%20%20font-size:%201.1em;%20%20%20line-height:%201;%20%20%20transition:%20all%200.2s;%20%7D%20.tag-remove:hover%20%7B%20%20%20opacity:%201;%20%20%20color:%20%23ef4444;%20%7D%20.input-group%20%7B%20%20%20display:%20flex;%20%20%20gap:%200.5rem;%20%7D%20.input-group%20input%20%7B%20%20%20flex:%201;%20%20%20padding:%200.75rem;%20%20%20background:%20var(--bg-body);%20%20%20border:%201px%20solid%20var(--border-color);%20%20%20color:%20var(--text-primary);%20%20%20border-radius:%208px;%20%20%20font-family:%20inherit;%20%7D%20/%2A%20Add%20tag%20button%20-%20styled%20like%20.btn-order%20with%20nav-btn.active%20color%20%2A/%20%23btn-add-tag%20%7B%20%20%20display:%20inline-flex;%20%20%20align-items:%20center;%20%20%20gap:%204px;%20%20%20padding:%200.5rem%201rem;%20%20%20border:%20none;%20%20%20border-radius:%206px;%20%20%20background:%20var(--accent-color);%20%20%20color:%20white;%20%20%20font-size:%200.8rem;%20%20%20font-weight:%20600;%20%20%20cursor:%20pointer;%20%20%20transition:%20all%200.2s%20ease;%20%20%20font-family:%20inherit;%20%20%20white-space:%20nowrap;%20%7D%20%23btn-add-tag:hover%20%7B%20%20%20filter:%20brightness(1.15);%20%20%20transform:%20translateY(-1px);%20%7D%20%20.matched-tags%20%7B%20%20%20display:%20flex;%20%20%20flex-wrap:%20wrap;%20%20%20gap:%206px;%20%20%20margin-bottom:%208px;%20%20%20/%2A%20Space%20between%20tags%20and%20title%20%2A/%20%20%20margin-top:%20-5px;%20%20%20/%2A%20Pull%20closer%20to%20header%20%2A/%20%7D%20.tag-badge-small%20%7B%20%20%20display:%20inline-flex;%20%20%20align-items:%20center;%20%20%20font-size:%200.7rem;%20%20%20padding:%202px%208px;%20%20%20border-radius:%204px;%20%20%20background:%20rgba(59,%20130,%20246,%200.15);%20%20%20color:%20%2360a5fa;%20%20%20border:%201px%20solid%20rgba(59,%20130,%20246,%200.3);%20%20%20font-weight:%20600;%20%20%20text-transform:%20uppercase;%20%20%20letter-spacing:%200.05em;%20%7D%20%5Bdata-theme=%5C%22light%5C%22%5D%20.tag-badge-small%20%7B%20%20%20background:%20rgba(37,%2099,%20235,%200.1);%20%20%20color:%20%232563eb;%20%20%20border:%201px%20solid%20rgba(37,%2099,%20235,%200.2);%20%7D%20%20/%2A%20Installer%20Changelog%20%2A/%20.changelog-container%20ul%20%7B%20%20%20padding-left:%201.5rem;%20%20%20margin:%200.5rem%200;%20%7D%20.changelog-container%20li%20%7B%20%20%20margin-bottom:%200.4rem;%20%20%20line-height:%201.5;%20%7D%20.changelog-container%20h3%20%7B%20%20%20margin-top:%201.5rem;%20%20%20margin-bottom:%200.5rem;%20%20%20font-size:%201.1em;%20%20%20color:%20var(--accent-color);%20%7D%20/%2A%20===%20Version%20Menu%20===%20%2A/%20.version-tag%20%7B%20%20%20cursor:%20pointer;%20%20%20transition:%20opacity%200.2s%20ease,%20text-decoration%200.2s%20ease;%20%7D%20.version-tag:hover%20%7B%20%20%20opacity:%201%20!important;%20%20%20text-decoration:%20underline;%20%7D%20.version-list%20%7B%20%20%20list-style:%20none;%20%20%20padding:%200;%20%20%20max-height:%20350px;%20%20%20overflow-y:%20auto;%20%20%20margin:%200;%20%7D%20.version-item%20%7B%20%20%20display:%20flex;%20%20%20justify-content:%20space-between;%20%20%20align-items:%20center;%20%20%20padding:%2010px%2014px;%20%20%20border-radius:%208px;%20%20%20margin-bottom:%204px;%20%20%20transition:%20background%200.2s;%20%7D%20.version-item:hover%20%7B%20%20%20background:%20rgba(100,%20116,%20139,%200.08);%20%7D%20.version-item.current%20%7B%20%20%20background:%20rgba(2,%20154,%20168,%200.1);%20%20%20border:%201px%20solid%20rgba(2,%20154,%20168,%200.25);%20%7D%20%5Bdata-theme=%5C%22dark%5C%22%5D%20.version-item:hover%20%7B%20%20%20background:%20rgba(255,%20255,%20255,%200.05);%20%7D%20%5Bdata-theme=%5C%22dark%5C%22%5D%20.version-item.current%20%7B%20%20%20background:%20rgba(96,%20165,%20250,%200.12);%20%20%20border:%201px%20solid%20rgba(96,%20165,%20250,%200.25);%20%7D%20.version-info%20%7B%20%20%20display:%20flex;%20%20%20align-items:%20center;%20%20%20gap:%2010px;%20%7D%20.badge-current%20%7B%20%20%20font-size:%200.75rem;%20%20%20font-weight:%20600;%20%20%20color:%20var(--success-color);%20%20%20padding:%202px%208px;%20%20%20border-radius:%204px;%20%20%20background:%20rgba(5,%20150,%20105,%200.1);%20%7D%20.badge-new%20%7B%20%20%20font-size:%200.75rem;%20%20%20font-weight:%20600;%20%20%20color:%20%23029aa8;%20%20%20padding:%202px%208px;%20%20%20border-radius:%204px;%20%20%20background:%20rgba(2,%20154,%20168,%200.1);%20%7D%20%5Bdata-theme=%5C%22dark%5C%22%5D%20.badge-new%20%7B%20%20%20color:%20%2360a5fa;%20%20%20background:%20rgba(96,%20165,%20250,%200.12);%20%7D%20.install-link%20%7B%20%20%20font-size:%200.8rem;%20%20%20font-weight:%20500;%20%20%20padding:%204px%2012px;%20%20%20border-radius:%206px;%20%20%20background:%20rgba(2,%20154,%20168,%200.1);%20%20%20color:%20%23029aa8;%20%20%20text-decoration:%20none;%20%20%20border:%201px%20solid%20rgba(2,%20154,%20168,%200.25);%20%20%20transition:%20all%200.2s;%20%20%20white-space:%20nowrap;%20%7D%20.install-link:hover%20%7B%20%20%20background:%20rgba(2,%20154,%20168,%200.2);%20%20%20border-color:%20rgba(2,%20154,%20168,%200.4);%20%7D%20%5Bdata-theme=%5C%22dark%5C%22%5D%20.install-link%20%7B%20%20%20color:%20%2360a5fa;%20%20%20background:%20rgba(96,%20165,%20250,%200.12);%20%20%20border:%201px%20solid%20rgba(96,%20165,%20250,%200.25);%20%7D%20%5Bdata-theme=%5C%22dark%5C%22%5D%20.install-link:hover%20%7B%20%20%20background:%20rgba(96,%20165,%20250,%200.2);%20%20%20border-color:%20rgba(96,%20165,%20250,%200.4);%20%7D%20.dev-toggle%20%7B%20%20%20padding:%2010px%2014px;%20%20%20border-radius:%208px;%20%20%20background:%20rgba(100,%20116,%20139,%200.05);%20%20%20border:%201px%20solid%20var(--border-color);%20%7D%20.dev-toggle%20input%5Btype=%5C%22checkbox%5C%22%5D%20%7B%20%20%20accent-color:%20%23029aa8;%20%20%20width:%2016px;%20%20%20height:%2016px;%20%7D%20%5Bdata-theme=%5C%22dark%5C%22%5D%20.dev-toggle%20input%5Btype=%5C%22checkbox%5C%22%5D%20%7B%20%20%20accent-color:%20%2360a5fa;%20%7D%27;document.head.appendChild(s);/%2A%2A%0A%20%2A%20Kantine%20Wrapper%20%E2%80%93%20Client-Only%20Bookmarklet%0A%20%2A%20Replaces%20Bessa%20page%20content%20with%20enhanced%20weekly%20menu%20view.%0A%20%2A%20All%20API%20calls%20go%20directly%20to%20api.bessa.app%20(same%20origin).%0A%20%2A%20Data%20stored%20in%20localStorage%20(flags,%20theme,%20auth).%0A%20%2A/%0A(function%20()%20%7B%0A%20%20%20%20%27use%20strict%27;%0A%0A%20%20%20%20//%20Prevent%20double%20injection%0A%20%20%20%20if%20(window.__KANTINE_LOADED)%20return;%0A%20%20%20%20window.__KANTINE_LOADED%20=%20true;%0A%0A%20%20%20%20//%20===%20Constants%20===%0A%20%20%20%20const%20API_BASE%20=%20%27https://api.bessa.app/v1%27;%0A%20%20%20%20const%20GUEST_TOKEN%20=%20%27c3418725e95a9f90e3645cbc846b4d67c7c66131%27;%0A%20%20%20%20const%20CLIENT_VERSION%20=%20%271.7.0_prod/2026-01-26%27;%0A%20%20%20%20const%20VENUE_ID%20=%20591;%0A%20%20%20%20const%20MENU_ID%20=%207;%0A%20%20%20%20const%20POLL_INTERVAL_MS%20=%205%20%2A%2060%20%2A%201000;%20//%205%20minutes%0A%0A%20%20%20%20//%20===%20GitHub%20Release%20Management%20===%0A%20%20%20%20const%20GITHUB_REPO%20=%20%27TauNeutrino/kantine-overview%27;%0A%20%20%20%20const%20GITHUB_API%20=%20%60https://api.github.com/repos/%24%7BGITHUB_REPO%7D%60;%0A%20%20%20%20const%20INSTALLER_BASE%20=%20%60https://htmlpreview.github.io/%3Fhttps://github.com/%24%7BGITHUB_REPO%7D/blob%60;%0A%0A%20%20%20%20//%20===%20State%20===%0A%20%20%20%20let%20allWeeks%20=%20%5B%5D;%0A%20%20%20%20let%20currentWeekNumber%20=%20getISOWeek(new%20Date());%0A%20%20%20%20let%20currentYear%20=%20new%20Date().getFullYear();%0A%20%20%20%20let%20displayMode%20=%20%27this-week%27;%0A%20%20%20%20let%20authToken%20=%20sessionStorage.getItem(%27kantine_authToken%27);%0A%20%20%20%20let%20currentUser%20=%20sessionStorage.getItem(%27kantine_currentUser%27);%0A%20%20%20%20let%20orderMap%20=%20new%20Map();%0A%20%20%20%20let%20userFlags%20=%20new%20Set(JSON.parse(localStorage.getItem(%27kantine_flags%27)%20%7C%7C%20%27%5B%5D%27));%0A%20%20%20%20let%20pollIntervalId%20=%20null;%0A%0A%20%20%20%20//%20===%20API%20Helpers%20===%0A%20%20%20%20function%20apiHeaders(token)%20%7B%0A%20%20%20%20%20%20%20%20return%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%27Authorization%27:%20%60Token%20%24%7Btoken%20%7C%7C%20GUEST_TOKEN%7D%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20%27Accept%27:%20%27application/json%27,%0A%20%20%20%20%20%20%20%20%20%20%20%20%27Content-Type%27:%20%27application/json%27,%0A%20%20%20%20%20%20%20%20%20%20%20%20%27X-Client-Version%27:%20CLIENT_VERSION%0A%20%20%20%20%20%20%20%20%7D;%0A%20%20%20%20%7D%0A%0A%20%20%20%20//%20===%20Inject%20UI%20===%0A%20%20%20%20function%20injectUI()%20%7B%0A%20%20%20%20%20%20%20%20//%20Replace%20entire%20page%20content%0A%20%20%20%20%20%20%20%20document.title%20=%20%27Kantine%20Weekly%20Menu%27;%0A%0A%20%20%20%20%20%20%20%20//%20Inject%20Google%20Fonts%20if%20not%20already%20present%0A%20%20%20%20%20%20%20%20if%20(!document.querySelector(%27link%5Bhref%2A=%22fonts.googleapis.com/css2%3Ffamily=Inter%22%5D%27))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20fontLink%20=%20document.createElement(%27link%27);%0A%20%20%20%20%20%20%20%20%20%20%20%20fontLink.rel%20=%20%27stylesheet%27;%0A%20%20%20%20%20%20%20%20%20%20%20%20fontLink.href%20=%20%27https://fonts.googleapis.com/css2%3Ffamily=Inter:wght%40300;400;500;600;700%26display=swap%27;%0A%20%20%20%20%20%20%20%20%20%20%20%20document.head.appendChild(fontLink);%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20if%20(!document.querySelector(%27link%5Bhref%2A=%22Material+Icons+Round%22%5D%27))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20iconLink%20=%20document.createElement(%27link%27);%0A%20%20%20%20%20%20%20%20%20%20%20%20iconLink.rel%20=%20%27stylesheet%27;%0A%20%20%20%20%20%20%20%20%20%20%20%20iconLink.href%20=%20%27https://fonts.googleapis.com/icon%3Ffamily=Material+Icons+Round%27;%0A%20%20%20%20%20%20%20%20%20%20%20%20document.head.appendChild(iconLink);%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20document.body.innerHTML%20=%20%60%0A%20%20%20%20%20%20%20%20%3Cdiv%20id=%22kantine-wrapper%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cheader%20class=%22app-header%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cdiv%20class=%22header-content%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cdiv%20class=%22brand%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cspan%20class=%22material-icons-round%20logo-icon%22%3Erestaurant_menu%3C/span%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cdiv%20class=%22header-left%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Ch1%3EKantinen%20%C3%9Cbersicht%20%3Csmall%20class=%22version-tag%22%20style=%22font-size:%200.6em;%20opacity:%200.7;%20font-weight:%20400;%20cursor:%20pointer;%22%20title=%22Klick%20f%C3%BCr%20Versionsmen%C3%BC%22%3Ev1.4.0%3C/small%3E%3C/h1%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cdiv%20id=%22last-updated-subtitle%22%20class=%22subtitle%22%3E%3C/div%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C/div%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C/div%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cdiv%20class=%22header-center-wrapper%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cdiv%20id=%22header-week-info%22%20class=%22header-week-info%22%3E%3C/div%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cdiv%20id=%22weekly-cost-display%22%20class=%22weekly-cost%20hidden%22%3E%3C/div%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C/div%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cdiv%20class=%22controls%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cbutton%20id=%22btn-refresh%22%20class=%22icon-btn%22%20aria-label=%22Men%C3%BCdaten%20aktualisieren%22%20title=%22Men%C3%BCdaten%20neu%20laden%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cspan%20class=%22material-icons-round%22%3Erefresh%3C/span%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C/button%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cbutton%20id=%22btn-history%22%20class=%22icon-btn%22%20aria-label=%22Bestellhistorie%22%20title=%22Bestellhistorie%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cspan%20class=%22material-icons-round%22%3Ereceipt_long%3C/span%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C/button%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cbutton%20id=%22btn-highlights%22%20class=%22icon-btn%22%20aria-label=%22Pers%C3%B6nliche%20Highlights%20verwalten%22%20title=%22Pers%C3%B6nliche%20Highlights%20verwalten%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cspan%20class=%22material-icons-round%22%3Elabel%3C/span%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C/button%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cdiv%20class=%22nav-group%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cbutton%20id=%22btn-this-week%22%20class=%22nav-btn%20active%22%3EDiese%20Woche%3C/button%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cbutton%20id=%22btn-next-week%22%20class=%22nav-btn%22%3EN%C3%A4chste%20Woche%3C/button%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C/div%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cbutton%20id=%22theme-toggle%22%20class=%22icon-btn%22%20aria-label=%22Toggle%20Theme%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cspan%20class=%22material-icons-round%20theme-icon%22%3Elight_mode%3C/span%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C/button%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cbutton%20id=%22btn-login-open%22%20class=%22user-badge-btn%20icon-btn-small%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cspan%20class=%22material-icons-round%22%3Elogin%3C/span%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cspan%3EAnmelden%3C/span%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C/button%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cdiv%20id=%22user-info%22%20class=%22user-badge%20hidden%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cspan%20class=%22material-icons-round%22%3Eperson%3C/span%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cspan%20id=%22user-id-display%22%3E%3C/span%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cbutton%20id=%22btn-logout%22%20class=%22icon-btn-small%22%20aria-label=%22Logout%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cspan%20class=%22material-icons-round%22%3Elogout%3C/span%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C/button%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C/div%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C/div%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C/div%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C/header%3E%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cdiv%20id=%22login-modal%22%20class=%22modal%20hidden%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cdiv%20class=%22modal-content%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cdiv%20class=%22modal-header%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Ch2%3ELogin%3C/h2%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cbutton%20id=%22btn-login-close%22%20class=%22icon-btn%22%20aria-label=%22Close%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cspan%20class=%22material-icons-round%22%3Eclose%3C/span%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C/button%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C/div%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cform%20id=%22login-form%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cdiv%20class=%22form-group%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Clabel%20for=%22employee-id%22%3EMitarbeiternummer%3C/label%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cinput%20type=%22text%22%20id=%22employee-id%22%20name=%22employee-id%22%20placeholder=%22z.B.%202041%22%20required%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Csmall%20class=%22help-text%22%3EDeine%20offizielle%20Knapp%20Mitarbeiternummer.%3C/small%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C/div%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cdiv%20class=%22form-group%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Clabel%20for=%22password%22%3EPasswort%3C/label%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cinput%20type=%22password%22%20id=%22password%22%20name=%22password%22%20placeholder=%22Bessa%20Passwort%22%20required%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Csmall%20class=%22help-text%22%3EDas%20Passwort%20f%C3%BCr%20deinen%20Bessa%20Account.%3C/small%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C/div%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cdiv%20id=%22login-error%22%20class=%22error-msg%20hidden%22%3E%3C/div%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cdiv%20class=%22modal-actions%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cbutton%20type=%22submit%22%20class=%22btn-primary%20wide%22%3EEinloggen%3C/button%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C/div%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C/form%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C/div%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C/div%3E%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cdiv%20id=%22progress-modal%22%20class=%22modal%20hidden%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cdiv%20class=%22modal-content%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cdiv%20class=%22modal-header%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Ch2%3EMen%C3%BCdaten%20aktualisieren%3C/h2%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C/div%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cdiv%20class=%22modal-body%22%20style=%22padding:%2020px;%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cdiv%20class=%22progress-container%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cdiv%20class=%22progress-bar%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cdiv%20id=%22progress-fill%22%20class=%22progress-fill%22%3E%3C/div%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C/div%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cdiv%20id=%22progress-percent%22%20class=%22progress-percent%22%3E0%25%3C/div%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C/div%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cp%20id=%22progress-message%22%20class=%22progress-message%22%3EInitialisierung...%3C/p%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C/div%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C/div%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C/div%3E%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cdiv%20id=%22highlights-modal%22%20class=%22modal%20hidden%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cdiv%20class=%22modal-content%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cdiv%20class=%22modal-header%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Ch2%3EMeine%20Highlights%3C/h2%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cbutton%20id=%22btn-highlights-close%22%20class=%22icon-btn%22%20aria-label=%22Close%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cspan%20class=%22material-icons-round%22%3Eclose%3C/span%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C/button%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C/div%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cdiv%20class=%22modal-body%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cp%20style=%22margin-bottom:%201rem;%20color:%20var(--text-secondary);%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20Markiere%20Men%C3%BCs%20automatisch,%20wenn%20sie%20diese%20Schlagw%C3%B6rter%20enthalten.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C/p%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cdiv%20class=%22input-group%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cinput%20type=%22text%22%20id=%22tag-input%22%20placeholder=%22z.B.%20Schnitzel,%20Vegetarisch...%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cbutton%20id=%22btn-add-tag%22%20class=%22btn-primary%22%3EHinzuf%C3%BCgen%3C/button%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C/div%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cdiv%20id=%22tags-list%22%3E%3C/div%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C/div%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C/div%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C/div%3E%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cdiv%20id=%22history-modal%22%20class=%22modal%20hidden%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cdiv%20class=%22modal-content%20history-modal-content%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cdiv%20class=%22modal-header%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Ch2%3EBestellhistorie%3C/h2%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cbutton%20id=%22btn-history-close%22%20class=%22icon-btn%22%20aria-label=%22Close%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cspan%20class=%22material-icons-round%22%3Eclose%3C/span%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C/button%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C/div%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cdiv%20class=%22modal-body%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cdiv%20id=%22history-loading%22%20class=%22hidden%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cp%20id=%22history-progress-text%22%20style=%22text-align:%20center;%20margin-bottom:%201rem;%20color:%20var(--text-secondary);%22%3ELade%20Historie...%3C/p%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cdiv%20class=%22progress-container%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cdiv%20class=%22progress-bar%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cdiv%20id=%22history-progress-fill%22%20class=%22progress-fill%22%3E%3C/div%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C/div%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C/div%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C/div%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cdiv%20id=%22history-content%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C!--%20Dynamically%20populated%20--%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C/div%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C/div%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C/div%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C/div%3E%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cdiv%20id=%22version-modal%22%20class=%22modal%20hidden%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cdiv%20class=%22modal-content%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cdiv%20class=%22modal-header%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Ch2%3E%F0%9F%93%A6%20Versionen%3C/h2%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cbutton%20id=%22btn-version-close%22%20class=%22icon-btn%22%20aria-label=%22Close%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cspan%20class=%22material-icons-round%22%3Eclose%3C/span%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C/button%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C/div%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cdiv%20class=%22modal-body%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cdiv%20style=%22margin-bottom:%201rem;%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cstrong%3EAktuell:%3C/strong%3E%20%3Cspan%20id=%22version-current%22%3Ev1.4.0%3C/span%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C/div%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cdiv%20class=%22dev-toggle%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Clabel%20style=%22display:flex;align-items:center;gap:8px;cursor:pointer;%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cinput%20type=%22checkbox%22%20id=%22dev-mode-toggle%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cspan%3EDev-Mode%20(alle%20Tags%20anzeigen)%3C/span%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C/label%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C/div%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cdiv%20id=%22version-list-container%22%20style=%22margin-top:1rem;%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cp%20style=%22color:var(--text-secondary);%22%3ELade%20Versionen...%3C/p%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C/div%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C/div%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C/div%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C/div%3E%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cmain%20class=%22container%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cdiv%20id=%22last-updated-banner%22%20class=%22banner%20hidden%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cspan%20class=%22material-icons-round%22%3Eupdate%3C/span%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cspan%20id=%22last-updated-text%22%3EGerade%20aktualisiert%3C/span%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C/div%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cdiv%20id=%22loading%22%20class=%22loading-state%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cdiv%20class=%22spinner%22%3E%3C/div%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cp%3ELade%20Men%C3%BCdaten...%3C/p%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C/div%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cdiv%20id=%22menu-container%22%20class=%22menu-grid%22%3E%3C/div%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C/main%3E%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cfooter%20class=%22app-footer%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cp%3EBessa%20Knapp-Kantine%20Wrapper%20%26bull;%20%3Cspan%20id=%22current-year%22%3E%24%7Bnew%20Date().getFullYear()%7D%3C/span%3E%3C/p%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C/footer%3E%0A%20%20%20%20%20%20%20%20%3C/div%3E%60;%0A%20%20%20%20%7D%0A%0A%20%20%20%20//%20===%20Bind%20Events%20===%0A%20%20%20%20function%20bindEvents()%20%7B%0A%20%20%20%20%20%20%20%20const%20btnThisWeek%20=%20document.getElementById(%27btn-this-week%27);%0A%20%20%20%20%20%20%20%20const%20btnNextWeek%20=%20document.getElementById(%27btn-next-week%27);%0A%20%20%20%20%20%20%20%20const%20btnRefresh%20=%20document.getElementById(%27btn-refresh%27);%0A%20%20%20%20%20%20%20%20const%20themeToggle%20=%20document.getElementById(%27theme-toggle%27);%0A%20%20%20%20%20%20%20%20const%20btnLoginOpen%20=%20document.getElementById(%27btn-login-open%27);%0A%20%20%20%20%20%20%20%20const%20btnLoginClose%20=%20document.getElementById(%27btn-login-close%27);%0A%20%20%20%20%20%20%20%20const%20btnLogout%20=%20document.getElementById(%27btn-logout%27);%0A%20%20%20%20%20%20%20%20const%20loginForm%20=%20document.getElementById(%27login-form%27);%0A%20%20%20%20%20%20%20%20const%20loginModal%20=%20document.getElementById(%27login-modal%27);%0A%0A%20%20%20%20%20%20%20%20//%20Highlights%20Modal%0A%20%20%20%20%20%20%20%20const%20btnHighlights%20=%20document.getElementById(%27btn-highlights%27);%0A%20%20%20%20%20%20%20%20const%20highlightsModal%20=%20document.getElementById(%27highlights-modal%27);%0A%20%20%20%20%20%20%20%20const%20btnHighlightsClose%20=%20document.getElementById(%27btn-highlights-close%27);%0A%20%20%20%20%20%20%20%20const%20btnAddTag%20=%20document.getElementById(%27btn-add-tag%27);%0A%20%20%20%20%20%20%20%20const%20tagInput%20=%20document.getElementById(%27tag-input%27);%0A%0A%20%20%20%20%20%20%20%20//%20History%20Modal%0A%20%20%20%20%20%20%20%20const%20btnHistory%20=%20document.getElementById(%27btn-history%27);%0A%20%20%20%20%20%20%20%20const%20historyModal%20=%20document.getElementById(%27history-modal%27);%0A%20%20%20%20%20%20%20%20const%20btnHistoryClose%20=%20document.getElementById(%27btn-history-close%27);%0A%0A%20%20%20%20%20%20%20%20btnHistory.addEventListener(%27click%27,%20()%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!authToken)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20loginModal.classList.remove(%27hidden%27);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20historyModal.classList.remove(%27hidden%27);%0A%20%20%20%20%20%20%20%20%20%20%20%20fetchFullOrderHistory();%0A%20%20%20%20%20%20%20%20%7D);%0A%0A%20%20%20%20%20%20%20%20btnHistoryClose.addEventListener(%27click%27,%20()%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20historyModal.classList.add(%27hidden%27);%0A%20%20%20%20%20%20%20%20%7D);%0A%0A%20%20%20%20%20%20%20%20window.addEventListener(%27click%27,%20(e)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(e.target%20===%20historyModal)%20historyModal.classList.add(%27hidden%27);%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(e.target%20===%20highlightsModal)%20highlightsModal.classList.add(%27hidden%27);%0A%20%20%20%20%20%20%20%20%7D);%0A%0A%20%20%20%20%20%20%20%20//%20Version%20Menu%0A%20%20%20%20%20%20%20%20const%20versionTag%20=%20document.querySelector(%27.version-tag%27);%0A%20%20%20%20%20%20%20%20const%20versionModal%20=%20document.getElementById(%27version-modal%27);%0A%20%20%20%20%20%20%20%20const%20btnVersionClose%20=%20document.getElementById(%27btn-version-close%27);%0A%0A%20%20%20%20%20%20%20%20if%20(versionTag)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20versionTag.addEventListener(%27click%27,%20(e)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20e.preventDefault();%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20e.stopPropagation();%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20openVersionMenu();%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20if%20(btnVersionClose)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20btnVersionClose.addEventListener(%27click%27,%20()%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20versionModal.classList.add(%27hidden%27);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20window.addEventListener(%27click%27,%20(e)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(e.target%20===%20versionModal)%20versionModal.classList.add(%27hidden%27);%0A%20%20%20%20%20%20%20%20%7D);%0A%0A%20%20%20%20%20%20%20%20btnAddTag.addEventListener(%27click%27,%20()%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20tag%20=%20tagInput.value;%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(addHighlightTag(tag))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20tagInput.value%20=%20%27%27;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20renderTagsList();%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D);%0A%0A%20%20%20%20%20%20%20%20tagInput.addEventListener(%27keypress%27,%20(e)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(e.key%20===%20%27Enter%27)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20btnAddTag.click();%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D);%0A%0A%20%20%20%20%20%20%20%20//%20Theme%0A%20%20%20%20%20%20%20%20const%20savedTheme%20=%20localStorage.getItem(%27theme%27);%0A%20%20%20%20%20%20%20%20const%20prefersDark%20=%20window.matchMedia(%27(prefers-color-scheme:%20dark)%27).matches;%0A%20%20%20%20%20%20%20%20const%20themeIcon%20=%20themeToggle.querySelector(%27.theme-icon%27);%0A%0A%20%20%20%20%20%20%20%20if%20(savedTheme%20===%20%27dark%27%20%7C%7C%20(!savedTheme%20%26%26%20prefersDark))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20document.documentElement.setAttribute(%27data-theme%27,%20%27dark%27);%0A%20%20%20%20%20%20%20%20%20%20%20%20themeIcon.textContent%20=%20%27dark_mode%27;%0A%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20document.documentElement.setAttribute(%27data-theme%27,%20%27light%27);%0A%20%20%20%20%20%20%20%20%20%20%20%20themeIcon.textContent%20=%20%27light_mode%27;%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20themeToggle.addEventListener(%27click%27,%20()%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20current%20=%20document.documentElement.getAttribute(%27data-theme%27);%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20next%20=%20current%20===%20%27dark%27%20%3F%20%27light%27%20:%20%27dark%27;%0A%20%20%20%20%20%20%20%20%20%20%20%20document.documentElement.setAttribute(%27data-theme%27,%20next);%0A%20%20%20%20%20%20%20%20%20%20%20%20localStorage.setItem(%27theme%27,%20next);%0A%20%20%20%20%20%20%20%20%20%20%20%20themeIcon.textContent%20=%20next%20===%20%27dark%27%20%3F%20%27dark_mode%27%20:%20%27light_mode%27;%0A%20%20%20%20%20%20%20%20%7D);%0A%0A%20%20%20%20%20%20%20%20//%20Navigation%0A%20%20%20%20%20%20%20%20btnThisWeek.addEventListener(%27click%27,%20()%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(displayMode%20!==%20%27this-week%27)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20displayMode%20=%20%27this-week%27;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20btnThisWeek.classList.add(%27active%27);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20btnNextWeek.classList.remove(%27active%27);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20renderVisibleWeeks();%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D);%0A%0A%20%20%20%20%20%20%20%20btnNextWeek.addEventListener(%27click%27,%20()%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(displayMode%20!==%20%27next-week%27)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20displayMode%20=%20%27next-week%27;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20btnNextWeek.classList.add(%27active%27);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20btnThisWeek.classList.remove(%27active%27);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20renderVisibleWeeks();%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D);%0A%0A%20%20%20%20%20%20%20%20//%20Refresh%20%E2%80%93%20fetch%20fresh%20data%20from%20Bessa%20API%0A%20%20%20%20%20%20%20%20btnRefresh.addEventListener(%27click%27,%20()%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!authToken)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20loginModal.classList.remove(%27hidden%27);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20loadMenuDataFromAPI();%0A%20%20%20%20%20%20%20%20%7D);%0A%0A%20%20%20%20%20%20%20%20//%20Login%20Modal%0A%20%20%20%20%20%20%20%20btnLoginOpen.addEventListener(%27click%27,%20()%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20loginModal.classList.remove(%27hidden%27);%0A%20%20%20%20%20%20%20%20%20%20%20%20document.getElementById(%27login-error%27).classList.add(%27hidden%27);%0A%20%20%20%20%20%20%20%20%20%20%20%20loginForm.reset();%0A%20%20%20%20%20%20%20%20%7D);%0A%0A%20%20%20%20%20%20%20%20btnLoginClose.addEventListener(%27click%27,%20()%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20loginModal.classList.add(%27hidden%27);%0A%20%20%20%20%20%20%20%20%7D);%0A%0A%20%20%20%20%20%20%20%20window.addEventListener(%27click%27,%20(e)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(e.target%20===%20loginModal)%20loginModal.classList.add(%27hidden%27);%0A%20%20%20%20%20%20%20%20%7D);%0A%0A%20%20%20%20%20%20%20%20//%20Login%20Form%20Submit%0A%20%20%20%20%20%20%20%20loginForm.addEventListener(%27submit%27,%20async%20(e)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20e.preventDefault();%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20employeeId%20=%20document.getElementById(%27employee-id%27).value.trim();%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20password%20=%20document.getElementById(%27password%27).value;%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20loginError%20=%20document.getElementById(%27login-error%27);%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20submitBtn%20=%20loginForm.querySelector(%27button%5Btype=%22submit%22%5D%27);%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20originalText%20=%20submitBtn.textContent;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20submitBtn.disabled%20=%20true;%0A%20%20%20%20%20%20%20%20%20%20%20%20submitBtn.textContent%20=%20%27Wird%20eingeloggt...%27;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20try%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20email%20=%20%60knapp-%24%7BemployeeId%7D%40bessa.app%60;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20response%20=%20await%20fetch(%60%24%7BAPI_BASE%7D/auth/login/%60,%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20method:%20%27POST%27,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20headers:%20apiHeaders(GUEST_TOKEN),%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20body:%20JSON.stringify(%7B%20email,%20password%20%7D)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20data%20=%20await%20response.json();%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(response.ok)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20authToken%20=%20data.key;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20currentUser%20=%20employeeId;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20sessionStorage.setItem(%27kantine_authToken%27,%20data.key);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20sessionStorage.setItem(%27kantine_currentUser%27,%20employeeId);%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20Fetch%20user%20name%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20try%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20userResp%20=%20await%20fetch(%60%24%7BAPI_BASE%7D/auth/user/%60,%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20headers:%20apiHeaders(authToken)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(userResp.ok)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20userData%20=%20await%20userResp.json();%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(userData.first_name)%20sessionStorage.setItem(%27kantine_firstName%27,%20userData.first_name);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(userData.last_name)%20sessionStorage.setItem(%27kantine_lastName%27,%20userData.last_name);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%20catch%20(err)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20console.error(%27Failed%20to%20fetch%20user%20info:%27,%20err);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20updateAuthUI();%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20loginModal.classList.add(%27hidden%27);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20fetchOrders();%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20loginForm.reset();%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20startPolling();%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20Reload%20menu%20data%20with%20auth%20for%20full%20details%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20loadMenuDataFromAPI();%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20loginError.textContent%20=%20data.non_field_errors%3F.%5B0%5D%20%7C%7C%20data.error%20%7C%7C%20%27Login%20fehlgeschlagen%27;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20loginError.classList.remove(%27hidden%27);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%20catch%20(error)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20console.error(%27Login%20error:%27,%20error);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20loginError.textContent%20=%20%27Ein%20Fehler%20ist%20aufgetreten%27;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20loginError.classList.remove(%27hidden%27);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%20finally%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20submitBtn.disabled%20=%20false;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20submitBtn.textContent%20=%20originalText;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D);%0A%0A%20%20%20%20%20%20%20%20//%20Logout%0A%20%20%20%20%20%20%20%20btnLogout.addEventListener(%27click%27,%20()%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20sessionStorage.removeItem(%27kantine_authToken%27);%0A%20%20%20%20%20%20%20%20%20%20%20%20sessionStorage.removeItem(%27kantine_currentUser%27);%0A%20%20%20%20%20%20%20%20%20%20%20%20sessionStorage.removeItem(%27kantine_firstName%27);%0A%20%20%20%20%20%20%20%20%20%20%20%20sessionStorage.removeItem(%27kantine_lastName%27);%0A%20%20%20%20%20%20%20%20%20%20%20%20authToken%20=%20null;%0A%20%20%20%20%20%20%20%20%20%20%20%20currentUser%20=%20null;%0A%20%20%20%20%20%20%20%20%20%20%20%20orderMap%20=%20new%20Map();%0A%20%20%20%20%20%20%20%20%20%20%20%20stopPolling();%0A%20%20%20%20%20%20%20%20%20%20%20%20updateAuthUI();%0A%20%20%20%20%20%20%20%20%20%20%20%20renderVisibleWeeks();%0A%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%7D%0A%0A%20%20%20%20//%20===%20Auth%20UI%20===%0A%20%20%20%20function%20updateAuthUI()%20%7B%0A%20%20%20%20%20%20%20%20//%20Try%20to%20recover%20session%20from%20Bessa%27s%20storage%20if%20not%20already%20logged%20in%0A%20%20%20%20%20%20%20%20if%20(!authToken)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20try%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20akita%20=%20localStorage.getItem(%27AkitaStores%27);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(akita)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20parsed%20=%20JSON.parse(akita);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(parsed.auth%20%26%26%20parsed.auth.token)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20console.log(%27Found%20existing%20Bessa%20session!%27);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20authToken%20=%20parsed.auth.token;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20sessionStorage.setItem(%27kantine_authToken%27,%20authToken);%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(parsed.auth.user)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20currentUser%20=%20parsed.auth.user.id%20%7C%7C%20%27unknown%27;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20sessionStorage.setItem(%27kantine_currentUser%27,%20currentUser);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(parsed.auth.user.firstName)%20sessionStorage.setItem(%27kantine_firstName%27,%20parsed.auth.user.firstName);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(parsed.auth.user.lastName)%20sessionStorage.setItem(%27kantine_lastName%27,%20parsed.auth.user.lastName);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%20catch%20(e)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20console.warn(%27Failed%20to%20parse%20AkitaStores:%27,%20e);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20authToken%20=%20sessionStorage.getItem(%27kantine_authToken%27);%0A%20%20%20%20%20%20%20%20currentUser%20=%20sessionStorage.getItem(%27kantine_currentUser%27);%0A%20%20%20%20%20%20%20%20const%20firstName%20=%20sessionStorage.getItem(%27kantine_firstName%27);%0A%20%20%20%20%20%20%20%20const%20btnLoginOpen%20=%20document.getElementById(%27btn-login-open%27);%0A%20%20%20%20%20%20%20%20const%20userInfo%20=%20document.getElementById(%27user-info%27);%0A%20%20%20%20%20%20%20%20const%20userIdDisplay%20=%20document.getElementById(%27user-id-display%27);%0A%0A%20%20%20%20%20%20%20%20if%20(authToken)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20btnLoginOpen.classList.add(%27hidden%27);%0A%20%20%20%20%20%20%20%20%20%20%20%20userInfo.classList.remove(%27hidden%27);%0A%20%20%20%20%20%20%20%20%20%20%20%20userIdDisplay.textContent%20=%20firstName%20%7C%7C%20(currentUser%20%3F%20%60User%20%24%7BcurrentUser%7D%60%20:%20%27Angemeldet%27);%0A%20%20%20%20%20%20%20%20%20%20%20%20fetchOrders();%20//%20Always%20fetch%20fresh%20orders%20on%20auth%20update%0A%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20btnLoginOpen.classList.remove(%27hidden%27);%0A%20%20%20%20%20%20%20%20%20%20%20%20userInfo.classList.add(%27hidden%27);%0A%20%20%20%20%20%20%20%20%20%20%20%20userIdDisplay.textContent%20=%20%27%27;%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20renderVisibleWeeks();%0A%20%20%20%20%7D%0A%0A%20%20%20%20//%20===%20Fetch%20Orders%20from%20Bessa%20===%0A%20%20%20%20async%20function%20fetchOrders()%20%7B%0A%20%20%20%20%20%20%20%20if%20(!authToken)%20return;%0A%20%20%20%20%20%20%20%20try%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20Use%20user/orders%20endpoint%20for%20reliable%20history%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20response%20=%20await%20fetch(%60%24%7BAPI_BASE%7D/user/orders/%3Fvenue=%24%7BVENUE_ID%7D%26ordering=-created%26limit=50%60,%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20headers:%20apiHeaders(authToken)%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20data%20=%20await%20response.json();%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(response.ok)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20orderMap%20=%20new%20Map();%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20results%20=%20data.results%20%7C%7C%20%5B%5D;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20for%20(const%20order%20of%20results)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20Filter%20out%20cancelled%20orders%20(State%209)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20Accepting%20State%201%20(Created%3F),%205%20(Placed%3F),%208%20(Completed)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20TODO:%20Verify%20exact%20states.%20Subagent%20saw%205=Active,%208=Completed,%209=Cancelled.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(order.order_state%20===%209)%20continue;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20Extract%20date%20properly%20(it%20comes%20as%20ISO%20string)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20orderDate%20=%20order.date.split(%27T%27)%5B0%5D;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20for%20(const%20item%20of%20(order.items%20%7C%7C%20%5B%5D))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20key%20=%20%60%24%7BorderDate%7D_%24%7Bitem.article%7D%60;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(!orderMap.has(key))%20orderMap.set(key,%20%5B%5D);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20orderMap.get(key).push(order.id);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20console.log(%60Fetched%20%24%7Bresults.length%7D%20orders,%20mapped%20active%20ones.%60);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20renderVisibleWeeks();%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%20catch%20(error)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20console.error(%27Error%20fetching%20orders:%27,%20error);%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20//%20===%20History%20Modal%20Flow%20===%0A%20%20%20%20let%20fullOrderHistoryCache%20=%20null;%0A%0A%20%20%20%20async%20function%20fetchFullOrderHistory()%20%7B%0A%20%20%20%20%20%20%20%20const%20historyLoading%20=%20document.getElementById(%27history-loading%27);%0A%20%20%20%20%20%20%20%20const%20historyContent%20=%20document.getElementById(%27history-content%27);%0A%20%20%20%20%20%20%20%20const%20progressFill%20=%20document.getElementById(%27history-progress-fill%27);%0A%20%20%20%20%20%20%20%20const%20progressText%20=%20document.getElementById(%27history-progress-text%27);%0A%0A%20%20%20%20%20%20%20%20if%20(fullOrderHistoryCache)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20renderHistory(fullOrderHistoryCache);%0A%20%20%20%20%20%20%20%20%20%20%20%20return;%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20if%20(!authToken)%20return;%0A%0A%20%20%20%20%20%20%20%20historyContent.innerHTML%20=%20%27%27;%0A%20%20%20%20%20%20%20%20historyLoading.classList.remove(%27hidden%27);%0A%20%20%20%20%20%20%20%20progressFill.style.width%20=%20%270%25%27;%0A%20%20%20%20%20%20%20%20progressText.textContent%20=%20%27Lade%20Bestellhistorie...%27;%0A%0A%20%20%20%20%20%20%20%20let%20nextUrl%20=%20%60%24%7BAPI_BASE%7D/user/orders/%3Fvenue=%24%7BVENUE_ID%7D%26ordering=-created%26limit=50%60;%0A%20%20%20%20%20%20%20%20let%20allOrders%20=%20%5B%5D;%0A%20%20%20%20%20%20%20%20let%20totalCount%20=%200;%0A%0A%20%20%20%20%20%20%20%20try%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20while%20(nextUrl)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20response%20=%20await%20fetch(nextUrl,%20%7B%20headers:%20apiHeaders(authToken)%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(!response.ok)%20throw%20new%20Error(%60Fetch%20failed:%20%24%7Bresponse.status%7D%60);%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20data%20=%20await%20response.json();%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(data.count%20%26%26%20totalCount%20===%200)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20totalCount%20=%20data.count;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20allOrders%20=%20allOrders.concat(data.results%20%7C%7C%20%5B%5D);%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20Update%20progress%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(totalCount%20%3E%200)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20pct%20=%20Math.round((allOrders.length%20/%20totalCount)%20%2A%20100);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20progressFill.style.width%20=%20%60%24%7Bpct%7D%25%60;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20progressText.textContent%20=%20%60Lade%20Bestellung%20%24%7BallOrders.length%7D%20von%20%24%7BtotalCount%7D...%60;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20progressText.textContent%20=%20%60Lade%20Bestellung%20%24%7BallOrders.length%7D...%60;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20nextUrl%20=%20data.next;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20fullOrderHistoryCache%20=%20allOrders;%0A%20%20%20%20%20%20%20%20%20%20%20%20renderHistory(fullOrderHistoryCache);%0A%0A%20%20%20%20%20%20%20%20%7D%20catch%20(error)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20console.error(%27Error%20fetching%20full%20history:%27,%20error);%0A%20%20%20%20%20%20%20%20%20%20%20%20historyContent.innerHTML%20=%20%60%3Cp%20style=%22color:var(--error-color);text-align:center;%22%3EFehler%20beim%20Laden%20der%20Historie.%3C/p%3E%60;%0A%20%20%20%20%20%20%20%20%7D%20finally%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20historyLoading.classList.add(%27hidden%27);%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20function%20renderHistory(orders)%20%7B%0A%20%20%20%20%20%20%20%20const%20content%20=%20document.getElementById(%27history-content%27);%0A%20%20%20%20%20%20%20%20if%20(!orders%20%7C%7C%20orders.length%20===%200)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20content.innerHTML%20=%20%27%3Cp%20style=%22text-align:center;color:var(--text-secondary);padding:20px;%22%3EKeine%20Bestellungen%20gefunden.%3C/p%3E%27;%0A%20%20%20%20%20%20%20%20%20%20%20%20return;%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20//%20Group%20by%20Month%20-%3E%20Week%20Number%20(KW)%0A%20%20%20%20%20%20%20%20const%20groups%20=%20%7B%7D;%0A%0A%20%20%20%20%20%20%20%20orders.forEach(order%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20d%20=%20new%20Date(order.date);%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20y%20=%20d.getFullYear();%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20m%20=%20d.getMonth();%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20monthKey%20=%20%60%24%7By%7D-%24%7Bm.toString().padStart(2,%20%270%27)%7D%60;%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20monthName%20=%20d.toLocaleString(%27de-AT%27,%20%7B%20month:%20%27long%27,%20year:%20%27numeric%27%20%7D);%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20kw%20=%20getISOWeek(d);%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!groups%5BmonthKey%5D)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20groups%5BmonthKey%5D%20=%20%7B%20name:%20monthName,%20year:%20y,%20monthIndex:%20m,%20weeks:%20%7B%7D%20%7D;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!groups%5BmonthKey%5D.weeks%5Bkw%5D)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20groups%5BmonthKey%5D.weeks%5Bkw%5D%20=%20%7B%20label:%20%60KW%20%24%7Bkw%7D%60,%20items:%20%5B%5D,%20count:%200,%20total:%200%20%7D;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20items%20=%20order.items%20%7C%7C%20%5B%5D;%0A%20%20%20%20%20%20%20%20%20%20%20%20items.forEach(item%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20groups%5BmonthKey%5D.weeks%5Bkw%5D.items.push(%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20date:%20order.date,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20name:%20item.name%20%7C%7C%20%27Men%C3%BC%27,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20price:%20parseFloat(item.price%20%7C%7C%20order.total%20%7C%7C%200),%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20state:%20order.order_state%20//%209%20is%20cancelled%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(order.order_state%20!==%209)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20groups%5BmonthKey%5D.weeks%5Bkw%5D.count++;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20groups%5BmonthKey%5D.weeks%5Bkw%5D.total%20+=%20parseFloat(item.price%20%7C%7C%20order.total%20%7C%7C%200);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%7D);%0A%0A%20%20%20%20%20%20%20%20//%20Generate%20HTML%20%0A%20%20%20%20%20%20%20%20const%20sortedMonths%20=%20Object.keys(groups).sort((a,%20b)%20=%3E%20b.localeCompare(a));%0A%20%20%20%20%20%20%20%20let%20html%20=%20%27%27;%0A%0A%20%20%20%20%20%20%20%20sortedMonths.forEach(mKey%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20monthGroup%20=%20groups%5BmKey%5D;%0A%20%20%20%20%20%20%20%20%20%20%20%20html%20+=%20%60%3Cdiv%20class=%22history-month-group%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Ch3%20class=%22history-month-header%22%3E%24%7BmonthGroup.name%7D%3C/h3%3E%60;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20sortedKWs%20=%20Object.keys(monthGroup.weeks).sort((a,%20b)%20=%3E%20parseInt(b)%20-%20parseInt(a));%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20sortedKWs.forEach(kw%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20week%20=%20monthGroup.weeks%5Bkw%5D;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20html%20+=%20%60%3Cdiv%20class=%22history-week-group%22%20style=%22padding:%2010px%2020px;%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cdiv%20class=%22history-week-header%22%20style=%22display:flex;%20justify-content:space-between;%20margin-bottom:%208px;%20color:%20var(--text-secondary);%20font-size:%200.95rem;%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cstrong%3E%24%7Bweek.label%7D%3C/strong%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cspan%3E%24%7Bweek.count%7D%20Bestellungen%20%26bull;%20%3Cstrong%3E%E2%82%AC%24%7Bweek.total.toFixed(2)%7D%3C/strong%3E%3C/span%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C/div%3E%60;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20week.items.forEach(item%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20isCancelled%20=%20item.state%20===%209;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20dateObj%20=%20new%20Date(item.date);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20dayStr%20=%20dateObj.toLocaleDateString(%27de-AT%27,%20%7B%20weekday:%20%27short%27,%20day:%20%272-digit%27,%20month:%20%272-digit%27%20%7D);%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20html%20+=%20%60%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cdiv%20class=%22history-item%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cdiv%20style=%22font-size:%200.85rem;%20color:%20var(--text-secondary);%22%3E%24%7BdayStr%7D%3C/div%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cdiv%20class=%22history-item-name%20%24%7BisCancelled%20%3F%20%27history-item-name-cancelled%27%20:%20%27%27%7D%22%3E%24%7BescapeHtml(item.name)%7D%3C/div%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cdiv%20class=%22history-item-price%20%24%7BisCancelled%20%3F%20%27history-item-price-cancelled%27%20:%20%27%27%7D%22%3E%E2%82%AC%24%7Bitem.price.toFixed(2)%7D%3C/div%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C/div%3E%60;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20html%20+=%20%60%3C/div%3E%60;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20html%20+=%20%60%3C/div%3E%60;%0A%20%20%20%20%20%20%20%20%7D);%0A%0A%20%20%20%20%20%20%20%20content.innerHTML%20=%20html;%0A%20%20%20%20%7D%0A%0A%20%20%20%20//%20===%20Place%20Order%20===%0A%20%20%20%20async%20function%20placeOrder(date,%20articleId,%20name,%20price,%20description)%20%7B%0A%20%20%20%20%20%20%20%20if%20(!authToken)%20return;%0A%20%20%20%20%20%20%20%20try%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20Get%20user%20data%20for%20customer%20object%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20userResp%20=%20await%20fetch(%60%24%7BAPI_BASE%7D/auth/user/%60,%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20headers:%20apiHeaders(authToken)%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!userResp.ok)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20showToast(%27Fehler:%20Benutzerdaten%20konnten%20nicht%20geladen%20werden%27,%20%27error%27);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20userData%20=%20await%20userResp.json();%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20now%20=%20new%20Date().toISOString();%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20orderPayload%20=%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20uuid:%20crypto.randomUUID(),%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20created:%20now,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20updated:%20now,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20order_type:%207,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20items:%20%5B%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20article:%20articleId,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20course_group:%20null,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20modifiers:%20%5B%5D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20uuid:%20crypto.randomUUID(),%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20name:%20name,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20description:%20description%20%7C%7C%20%27%27,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20price:%20String(parseFloat(price)),%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20amount:%201,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20vat:%20%2710.00%27,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20comment:%20%27%27%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%5D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20table:%20null,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20total:%20parseFloat(price),%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20tip:%200,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20currency:%20%27EUR%27,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20venue:%20VENUE_ID,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20states:%20%5B%5D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20order_state:%201,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20date:%20%60%24%7Bdate%7DT10:00:00.000Z%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20payment_method:%20%27payroll%27,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20customer:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20first_name:%20userData.first_name,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20last_name:%20userData.last_name,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20email:%20userData.email,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20newsletter:%20false%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20preorder:%20false,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20delivery_fee:%200,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20cash_box_table_name:%20null,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20take_away:%20false%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20response%20=%20await%20fetch(%60%24%7BAPI_BASE%7D/user/orders/%60,%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20method:%20%27POST%27,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20headers:%20apiHeaders(authToken),%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20body:%20JSON.stringify(orderPayload)%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(response.ok%20%7C%7C%20response.status%20===%20201)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20showToast(%60Bestellt:%20%24%7Bname%7D%60,%20%27success%27);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20await%20fetchOrders();%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20data%20=%20await%20response.json();%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20showToast(%60Fehler:%20%24%7Bdata.detail%20%7C%7C%20data.non_field_errors%3F.%5B0%5D%20%7C%7C%20%27Bestellung%20fehlgeschlagen%27%7D%60,%20%27error%27);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%20catch%20(error)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20console.error(%27Order%20error:%27,%20error);%0A%20%20%20%20%20%20%20%20%20%20%20%20showToast(%27Netzwerkfehler%20bei%20Bestellung%27,%20%27error%27);%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20//%20===%20Cancel%20Order%20===%0A%20%20%20%20async%20function%20cancelOrder(date,%20articleId,%20name)%20%7B%0A%20%20%20%20%20%20%20%20if%20(!authToken)%20return;%0A%20%20%20%20%20%20%20%20const%20key%20=%20%60%24%7Bdate%7D_%24%7BarticleId%7D%60;%0A%20%20%20%20%20%20%20%20const%20orderIds%20=%20orderMap.get(key);%0A%20%20%20%20%20%20%20%20if%20(!orderIds%20%7C%7C%20orderIds.length%20===%200)%20return;%0A%0A%20%20%20%20%20%20%20%20//%20LIFO:%20cancel%20most%20recent%0A%20%20%20%20%20%20%20%20const%20orderId%20=%20orderIds%5BorderIds.length%20-%201%5D;%0A%20%20%20%20%20%20%20%20try%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20response%20=%20await%20fetch(%60%24%7BAPI_BASE%7D/user/orders/%24%7BorderId%7D/cancel/%60,%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20method:%20%27PATCH%27,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20headers:%20apiHeaders(authToken),%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20body:%20JSON.stringify(%7B%7D)%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(response.ok)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20showToast(%60Storniert:%20%24%7Bname%7D%60,%20%27success%27);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20await%20fetchOrders();%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20data%20=%20await%20response.json();%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20showToast(%60Fehler:%20%24%7Bdata.detail%20%7C%7C%20%27Stornierung%20fehlgeschlagen%27%7D%60,%20%27error%27);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%20catch%20(error)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20console.error(%27Cancel%20error:%27,%20error);%0A%20%20%20%20%20%20%20%20%20%20%20%20showToast(%27Netzwerkfehler%20bei%20Stornierung%27,%20%27error%27);%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20//%20===%20Flag%20Management%20(localStorage)%20===%0A%20%20%20%20function%20saveFlags()%20%7B%0A%20%20%20%20%20%20%20%20localStorage.setItem(%27kantine_flags%27,%20JSON.stringify(%5B...userFlags%5D));%0A%20%20%20%20%7D%0A%0A%20%20%20%20function%20toggleFlag(date,%20articleId,%20name,%20cutoff)%20%7B%0A%20%20%20%20%20%20%20%20const%20id%20=%20%60%24%7Bdate%7D_%24%7BarticleId%7D%60;%0A%20%20%20%20%20%20%20%20if%20(userFlags.has(id))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20userFlags.delete(id);%0A%20%20%20%20%20%20%20%20%20%20%20%20showToast(%60Flag%20entfernt%20f%C3%BCr%20%24%7Bname%7D%60,%20%27success%27);%0A%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20userFlags.add(id);%0A%20%20%20%20%20%20%20%20%20%20%20%20showToast(%60Benachrichtigung%20aktiviert%20f%C3%BCr%20%24%7Bname%7D%60,%20%27success%27);%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(Notification.permission%20===%20%27default%27)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20Notification.requestPermission();%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20saveFlags();%0A%20%20%20%20%20%20%20%20renderVisibleWeeks();%0A%20%20%20%20%7D%0A%0A%20%20%20%20//%20FR-019:%20Auto-remove%20flags%20whose%20cutoff%20has%20passed%0A%20%20%20%20function%20cleanupExpiredFlags()%20%7B%0A%20%20%20%20%20%20%20%20const%20now%20=%20new%20Date();%0A%20%20%20%20%20%20%20%20let%20changed%20=%20false;%0A%20%20%20%20%20%20%20%20for%20(const%20flagId%20of%20%5B...userFlags%5D)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20%5Bdate%5D%20=%20flagId.split(%27_%27);%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20cutoff%20=%20new%20Date(date);%0A%20%20%20%20%20%20%20%20%20%20%20%20cutoff.setHours(10,%200,%200,%200);%20//%20Standard%20cutoff%2010:00%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(now%20%3E=%20cutoff)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20userFlags.delete(flagId);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20changed%20=%20true;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20if%20(changed)%20saveFlags();%0A%20%20%20%20%7D%0A%0A%20%20%20%20//%20===%20Polling%20(Client-Side)%20===%0A%20%20%20%20function%20startPolling()%20%7B%0A%20%20%20%20%20%20%20%20if%20(pollIntervalId)%20return;%0A%20%20%20%20%20%20%20%20if%20(!authToken)%20return;%0A%20%20%20%20%20%20%20%20pollIntervalId%20=%20setInterval(()%20=%3E%20pollFlaggedItems(),%20POLL_INTERVAL_MS);%0A%20%20%20%20%20%20%20%20console.log(%27Polling%20started%20(every%205%20min)%27);%0A%20%20%20%20%7D%0A%0A%20%20%20%20function%20stopPolling()%20%7B%0A%20%20%20%20%20%20%20%20if%20(pollIntervalId)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20clearInterval(pollIntervalId);%0A%20%20%20%20%20%20%20%20%20%20%20%20pollIntervalId%20=%20null;%0A%20%20%20%20%20%20%20%20%20%20%20%20console.log(%27Polling%20stopped%27);%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20async%20function%20pollFlaggedItems()%20%7B%0A%20%20%20%20%20%20%20%20if%20(userFlags.size%20===%200%20%7C%7C%20!authToken)%20return;%0A%20%20%20%20%20%20%20%20console.log(%60Polling%20%24%7BuserFlags.size%7D%20flagged%20items...%60);%0A%0A%20%20%20%20%20%20%20%20for%20(const%20flagId%20of%20userFlags)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20%5Bdate,%20articleIdStr%5D%20=%20flagId.split(%27_%27);%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20articleId%20=%20parseInt(articleIdStr);%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20try%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20response%20=%20await%20fetch(%60%24%7BAPI_BASE%7D/venues/%24%7BVENUE_ID%7D/menu/%24%7BMENU_ID%7D/%24%7Bdate%7D/%60,%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20headers:%20apiHeaders(authToken)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(!response.ok)%20continue;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20data%20=%20await%20response.json();%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20groups%20=%20data.results%20%7C%7C%20%5B%5D;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20let%20foundItem%20=%20null;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20for%20(const%20group%20of%20groups)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(group.items)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20foundItem%20=%20group.items.find(i%20=%3E%20i.id%20===%20articleId%20%7C%7C%20i.article%20===%20articleId);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(foundItem)%20break;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(foundItem)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20isAvailable%20=%20(foundItem.amount_tracking%20===%20false)%20%7C%7C%20(parseInt(foundItem.available_amount)%20%3E%200);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(isAvailable)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20itemName%20=%20foundItem.name%20%7C%7C%20%27Unbekannt%27;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20showToast(%60%24%7BitemName%7D%20ist%20jetzt%20verf%C3%BCgbar!%60,%20%27success%27);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(Notification.permission%20===%20%27granted%27)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20new%20Notification(%27Kantine%20Wrapper%27,%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20body:%20%60%24%7BitemName%7D%20ist%20jetzt%20verf%C3%BCgbar!%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20icon:%20%27%F0%9F%8D%BD%EF%B8%8F%27%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20Refresh%20menu%20data%20to%20update%20UI%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20loadMenuDataFromAPI();%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%20catch%20(err)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20console.error(%60Poll%20error%20for%20%24%7BflagId%7D:%60,%20err);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20Small%20delay%20between%20checks%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20await%20new%20Promise(r%20=%3E%20setTimeout(r,%20200));%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20//%20===%20Highlight%20Management%20===%0A%20%20%20%20let%20highlightTags%20=%20JSON.parse(localStorage.getItem(%27kantine_highlightTags%27)%20%7C%7C%20%27%5B%5D%27);%0A%0A%20%20%20%20function%20saveHighlightTags()%20%7B%0A%20%20%20%20%20%20%20%20localStorage.setItem(%27kantine_highlightTags%27,%20JSON.stringify(highlightTags));%0A%20%20%20%20%20%20%20%20renderVisibleWeeks();%20//%20Refresh%20UI%20to%20apply%20changes%0A%20%20%20%20%20%20%20%20updateNextWeekBadge();%0A%20%20%20%20%7D%0A%0A%20%20%20%20function%20addHighlightTag(tag)%20%7B%0A%20%20%20%20%20%20%20%20tag%20=%20tag.trim().toLowerCase();%0A%20%20%20%20%20%20%20%20if%20(tag%20%26%26%20!highlightTags.includes(tag))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20highlightTags.push(tag);%0A%20%20%20%20%20%20%20%20%20%20%20%20saveHighlightTags();%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20true;%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20return%20false;%0A%20%20%20%20%7D%0A%0A%20%20%20%20function%20removeHighlightTag(tag)%20%7B%0A%20%20%20%20%20%20%20%20highlightTags%20=%20highlightTags.filter(t%20=%3E%20t%20!==%20tag);%0A%20%20%20%20%20%20%20%20saveHighlightTags();%0A%20%20%20%20%7D%0A%0A%20%20%20%20function%20renderTagsList()%20%7B%0A%20%20%20%20%20%20%20%20const%20list%20=%20document.getElementById(%27tags-list%27);%0A%20%20%20%20%20%20%20%20list.innerHTML%20=%20%27%27;%0A%20%20%20%20%20%20%20%20highlightTags.forEach(tag%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20badge%20=%20document.createElement(%27span%27);%0A%20%20%20%20%20%20%20%20%20%20%20%20badge.className%20=%20%27tag-badge%27;%0A%20%20%20%20%20%20%20%20%20%20%20%20badge.innerHTML%20=%20%60%24%7Btag%7D%20%3Cspan%20class=%22tag-remove%22%20data-tag=%22%24%7Btag%7D%22%3E%26times;%3C/span%3E%60;%0A%20%20%20%20%20%20%20%20%20%20%20%20list.appendChild(badge);%0A%20%20%20%20%20%20%20%20%7D);%0A%0A%20%20%20%20%20%20%20%20//%20Bind%20remove%20events%0A%20%20%20%20%20%20%20%20list.querySelectorAll(%27.tag-remove%27).forEach(btn%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20btn.addEventListener(%27click%27,%20(e)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20removeHighlightTag(e.target.dataset.tag);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20renderTagsList();%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%7D%0A%0A%20%20%20%20function%20checkHighlight(text)%20%7B%0A%20%20%20%20%20%20%20%20if%20(!text)%20return%20%5B%5D;%0A%20%20%20%20%20%20%20%20text%20=%20text.toLowerCase();%0A%20%20%20%20%20%20%20%20return%20highlightTags.filter(tag%20=%3E%20text.includes(tag));%0A%20%20%20%20%7D%0A%0A%20%20%20%20//%20===%20Local%20Menu%20Cache%20(localStorage)%20===%0A%20%20%20%20const%20CACHE_KEY%20=%20%27kantine_menuCache%27;%0A%20%20%20%20const%20CACHE_TS_KEY%20=%20%27kantine_menuCacheTs%27;%0A%0A%20%20%20%20function%20saveMenuCache()%20%7B%0A%20%20%20%20%20%20%20%20try%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20localStorage.setItem(CACHE_KEY,%20JSON.stringify(allWeeks));%0A%20%20%20%20%20%20%20%20%20%20%20%20localStorage.setItem(CACHE_TS_KEY,%20new%20Date().toISOString());%0A%20%20%20%20%20%20%20%20%7D%20catch%20(e)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20console.warn(%27Failed%20to%20cache%20menu%20data:%27,%20e);%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20function%20loadMenuCache()%20%7B%0A%20%20%20%20%20%20%20%20try%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20cached%20=%20localStorage.getItem(CACHE_KEY);%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20cachedTs%20=%20localStorage.getItem(CACHE_TS_KEY);%0A%20%20%20%20%20%20%20%20%20%20%20%20console.log(%60%5BCache%5D%20localStorage:%20key=%24%7B!!cached%7D%20(%24%7Bcached%20%3F%20cached.length%20:%200%7D%20chars),%20ts=%24%7BcachedTs%7D%60);%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(cached)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20allWeeks%20=%20JSON.parse(cached);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20currentWeekNumber%20=%20getISOWeek(new%20Date());%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20currentYear%20=%20new%20Date().getFullYear();%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20console.log(%60%5BCache%5D%20Parsed%20%24%7BallWeeks.length%7D%20weeks:%60,%20allWeeks.map(w%20=%3E%20%60KW%24%7Bw.weekNumber%7D/%24%7Bw.year%7D%20(%24%7B(w.days%20%7C%7C%20%5B%5D).length%7D%20days)%60));%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20renderVisibleWeeks();%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20updateNextWeekBadge();%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(cachedTs)%20updateLastUpdatedTime(cachedTs);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20console.log(%27Loaded%20menu%20from%20cache%27);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20true;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%20catch%20(e)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20console.warn(%27Failed%20to%20load%20cached%20menu:%27,%20e);%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20return%20false;%0A%20%20%20%20%7D%0A%0A%20%20%20%20//%20FR-024:%20Check%20if%20cache%20is%20fresh%20enough%20to%20skip%20API%20refresh%0A%20%20%20%20function%20isCacheFresh()%20%7B%0A%20%20%20%20%20%20%20%20const%20cachedTs%20=%20localStorage.getItem(CACHE_TS_KEY);%0A%20%20%20%20%20%20%20%20if%20(!cachedTs)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20console.log(%27%5BCache%5D%20No%20timestamp%20found%27);%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20false;%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20//%20Condition%201:%20Cache%20%3C%201%20hour%20old%0A%20%20%20%20%20%20%20%20const%20ageMs%20=%20Date.now()%20-%20new%20Date(cachedTs).getTime();%0A%20%20%20%20%20%20%20%20const%20ageMin%20=%20Math.round(ageMs%20/%2060000);%0A%20%20%20%20%20%20%20%20if%20(ageMs%20%3E%2060%20%2A%2060%20%2A%201000)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20console.log(%60%5BCache%5D%20Stale:%20%24%7BageMin%7Dmin%20old%20(max%2060)%60);%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20false;%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20//%20Condition%202:%20Data%20for%20current%20week%20exists%0A%20%20%20%20%20%20%20%20const%20thisWeek%20=%20getISOWeek(new%20Date());%0A%20%20%20%20%20%20%20%20const%20thisYear%20=%20getWeekYear(new%20Date());%0A%20%20%20%20%20%20%20%20const%20hasCurrentWeek%20=%20allWeeks.some(w%20=%3E%20w.weekNumber%20===%20thisWeek%20%26%26%20w.year%20===%20thisYear%20%26%26%20w.days%20%26%26%20w.days.length%20%3E%200);%0A%0A%20%20%20%20%20%20%20%20console.log(%60%5BCache%5D%20Age:%20%24%7BageMin%7Dmin,%20looking%20for%20KW%24%7BthisWeek%7D/%24%7BthisYear%7D,%20found:%20%24%7BhasCurrentWeek%7D%60);%0A%20%20%20%20%20%20%20%20return%20hasCurrentWeek;%0A%20%20%20%20%7D%0A%0A%20%20%20%20//%20===%20Menu%20Data%20Fetching%20(Direct%20from%20Bessa%20API)%20===%0A%20%20%20%20async%20function%20loadMenuDataFromAPI()%20%7B%0A%20%20%20%20%20%20%20%20const%20loading%20=%20document.getElementById(%27loading%27);%0A%20%20%20%20%20%20%20%20const%20progressModal%20=%20document.getElementById(%27progress-modal%27);%0A%20%20%20%20%20%20%20%20const%20progressFill%20=%20document.getElementById(%27progress-fill%27);%0A%20%20%20%20%20%20%20%20const%20progressPercent%20=%20document.getElementById(%27progress-percent%27);%0A%20%20%20%20%20%20%20%20const%20progressMessage%20=%20document.getElementById(%27progress-message%27);%0A%0A%20%20%20%20%20%20%20%20loading.classList.remove(%27hidden%27);%0A%0A%20%20%20%20%20%20%20%20const%20token%20=%20authToken%20%7C%7C%20GUEST_TOKEN;%0A%0A%20%20%20%20%20%20%20%20try%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20Show%20progress%20modal%0A%20%20%20%20%20%20%20%20%20%20%20%20progressModal.classList.remove(%27hidden%27);%0A%20%20%20%20%20%20%20%20%20%20%20%20progressMessage.textContent%20=%20%27Hole%20verf%C3%BCgbare%20Daten...%27;%0A%20%20%20%20%20%20%20%20%20%20%20%20progressFill.style.width%20=%20%270%25%27;%0A%20%20%20%20%20%20%20%20%20%20%20%20progressPercent.textContent%20=%20%270%25%27;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20//%201.%20Fetch%20available%20dates%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20datesResponse%20=%20await%20fetch(%60%24%7BAPI_BASE%7D/venues/%24%7BVENUE_ID%7D/menu/dates/%60,%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20headers:%20apiHeaders(token)%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!datesResponse.ok)%20throw%20new%20Error(%60Failed%20to%20fetch%20dates:%20%24%7BdatesResponse.status%7D%60);%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20datesData%20=%20await%20datesResponse.json();%0A%20%20%20%20%20%20%20%20%20%20%20%20let%20availableDates%20=%20datesData.results%20%7C%7C%20%5B%5D;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20Filter%20%E2%80%93%20last%207%20days%20+%20future,%20limit%2030%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20cutoff%20=%20new%20Date();%0A%20%20%20%20%20%20%20%20%20%20%20%20cutoff.setDate(cutoff.getDate()%20-%207);%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20cutoffStr%20=%20cutoff.toISOString().split(%27T%27)%5B0%5D;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20availableDates%20=%20availableDates%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20.filter(d%20=%3E%20d.date%20%3E=%20cutoffStr)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20.sort((a,%20b)%20=%3E%20a.date.localeCompare(b.date))%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20.slice(0,%2030);%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20totalDates%20=%20availableDates.length;%0A%20%20%20%20%20%20%20%20%20%20%20%20progressMessage.textContent%20=%20%60%24%7BtotalDates%7D%20Tage%20gefunden.%20Lade%20Details...%60;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20//%202.%20Fetch%20details%20for%20each%20date%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20allDays%20=%20%5B%5D;%0A%20%20%20%20%20%20%20%20%20%20%20%20let%20completed%20=%200;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20for%20(const%20dateObj%20of%20availableDates)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20dateStr%20=%20dateObj.date;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20pct%20=%20Math.round(((completed%20+%201)%20/%20totalDates)%20%2A%20100);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20progressFill.style.width%20=%20%60%24%7Bpct%7D%25%60;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20progressPercent.textContent%20=%20%60%24%7Bpct%7D%25%60;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20progressMessage.textContent%20=%20%60Lade%20Men%C3%BC%20f%C3%BCr%20%24%7BdateStr%7D...%60;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20try%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20detailResp%20=%20await%20fetch(%60%24%7BAPI_BASE%7D/venues/%24%7BVENUE_ID%7D/menu/%24%7BMENU_ID%7D/%24%7BdateStr%7D/%60,%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20headers:%20apiHeaders(token)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(detailResp.ok)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20detailData%20=%20await%20detailResp.json();%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20Debug:%20log%20raw%20API%20response%20for%20first%20date%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(completed%20===%200)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20console.log(%27%5BKantine%20Debug%5D%20Raw%20API%20response%20for%27,%20dateStr,%20%27:%27,%20JSON.stringify(detailData).substring(0,%202000));%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20menuGroups%20=%20detailData.results%20%7C%7C%20%5B%5D;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20let%20dayItems%20=%20%5B%5D;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20for%20(const%20group%20of%20menuGroups)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(group.items%20%26%26%20Array.isArray(group.items))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20dayItems%20=%20dayItems.concat(group.items);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(dayItems.length%20%3E%200)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20Debug:%20log%20first%20item%20structure%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(completed%20===%200)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20console.log(%27%5BKantine%20Debug%5D%20First%20item%20keys:%27,%20Object.keys(dayItems%5B0%5D));%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20console.log(%27%5BKantine%20Debug%5D%20First%20item:%27,%20JSON.stringify(dayItems%5B0%5D).substring(0,%20500));%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20allDays.push(%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20date:%20dateStr,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20menu_items:%20dayItems,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20orders:%20dateObj.orders%20%7C%7C%20%5B%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%20catch%20(err)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20console.error(%60Failed%20to%20fetch%20details%20for%20%24%7BdateStr%7D:%60,%20err);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20completed++;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20Small%20delay%20to%20avoid%20rate%20limiting%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20await%20new%20Promise(r%20=%3E%20setTimeout(r,%20100));%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20//%203.%20Group%20by%20ISO%20week%20(Merge%20with%20existing%20to%20preserve%20past%20days)%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20weeksMap%20=%20new%20Map();%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20Hydrate%20from%20existing%20cache%20(preserve%20past%20data)%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(allWeeks%20%26%26%20allWeeks.length%20%3E%200)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20allWeeks.forEach(w%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20key%20=%20%60%24%7Bw.year%7D-%24%7Bw.weekNumber%7D%60;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20try%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20weeksMap.set(key,%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20year:%20w.year,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20weekNumber:%20w.weekNumber,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20days:%20w.days%20%3F%20w.days.map(d%20=%3E%20(%7B%20...d,%20items:%20d.items%20%3F%20%5B...d.items%5D%20:%20%5B%5D%20%7D))%20:%20%5B%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%20catch%20(e)%20%7B%20console.warn(%27Error%20hydrating%20week:%27,%20e);%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20for%20(const%20day%20of%20allDays)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20d%20=%20new%20Date(day.date);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20weekNum%20=%20getISOWeek(d);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20year%20=%20getWeekYear(d);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20key%20=%20%60%24%7Byear%7D-%24%7BweekNum%7D%60;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(!weeksMap.has(key))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20weeksMap.set(key,%20%7B%20year,%20weekNumber:%20weekNum,%20days:%20%5B%5D%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20weekObj%20=%20weeksMap.get(key);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20weekday%20=%20d.toLocaleDateString(%27en-US%27,%20%7B%20weekday:%20%27long%27%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20orderCutoffDate%20=%20new%20Date(day.date);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20orderCutoffDate.setHours(10,%200,%200,%200);%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20newDayObj%20=%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20date:%20day.date,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20weekday:%20weekday,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20orderCutoff:%20orderCutoffDate.toISOString(),%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20items:%20day.menu_items.map(item%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20isUnlimited%20=%20item.amount_tracking%20===%20false;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20hasStock%20=%20parseInt(item.available_amount)%20%3E%200;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20id:%20%60%24%7Bday.date%7D_%24%7Bitem.id%7D%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20articleId:%20item.id,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20name:%20item.name%20%7C%7C%20%27Unknown%27,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20description:%20item.description%20%7C%7C%20%27%27,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20price:%20parseFloat(item.price)%20%7C%7C%200,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20available:%20isUnlimited%20%7C%7C%20hasStock,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20availableAmount:%20parseInt(item.available_amount)%20%7C%7C%200,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20amountTracking:%20item.amount_tracking%20!==%20false%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20Merge:%20Overwrite%20if%20exists,%20push%20if%20new%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20existingIndex%20=%20weekObj.days.findIndex(existing%20=%3E%20existing.date%20===%20day.date);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(existingIndex%20%3E=%200)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20weekObj.days%5BexistingIndex%5D%20=%20newDayObj;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20weekObj.days.push(newDayObj);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20Sort%20weeks%20and%20days%0A%20%20%20%20%20%20%20%20%20%20%20%20allWeeks%20=%20Array.from(weeksMap.values()).sort((a,%20b)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(a.year%20!==%20b.year)%20return%20a.year%20-%20b.year;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20a.weekNumber%20-%20b.weekNumber;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20allWeeks.forEach(w%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(w.days)%20w.days.sort((a,%20b)%20=%3E%20a.date.localeCompare(b.date));%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20Save%20to%20localStorage%20cache%0A%20%20%20%20%20%20%20%20%20%20%20%20saveMenuCache();%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20Update%20timestamp%0A%20%20%20%20%20%20%20%20%20%20%20%20updateLastUpdatedTime(new%20Date().toISOString());%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20currentWeekNumber%20=%20getISOWeek(new%20Date());%0A%20%20%20%20%20%20%20%20%20%20%20%20currentYear%20=%20new%20Date().getFullYear();%0A%0A%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20updateAuthUI();%20//%20This%20will%20trigger%20fetchOrders%20if%20logged%20in%0A%20%20%20%20%20%20%20%20%20%20%20%20renderVisibleWeeks();%0A%20%20%20%20%20%20%20%20%20%20%20%20updateNextWeekBadge();%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20progressMessage.textContent%20=%20%27Fertig!%27;%0A%20%20%20%20%20%20%20%20%20%20%20%20setTimeout(()%20=%3E%20progressModal.classList.add(%27hidden%27),%20500);%0A%0A%20%20%20%20%20%20%20%20%7D%20catch%20(error)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20console.error(%27Error%20fetching%20menu:%27,%20error);%0A%20%20%20%20%20%20%20%20%20%20%20%20progressModal.classList.add(%27hidden%27);%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20showErrorModal(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%27Keine%20Verbindung%27,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%60Die%20Men%C3%BCdaten%20konnten%20nicht%20geladen%20werden.%20M%C3%B6glicherweise%20besteht%20keine%20Verbindung%20zur%20API%20oder%20zur%20Bessa-Webseite.%3Cbr%3E%3Cbr%3E%3Csmall%20style=%22color:var(--text-secondary)%22%3E%24%7Berror.message%7D%3C/small%3E%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%27Zur%20Original-Seite%27,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%27https://web.bessa.app/knapp-kantine%27%0A%20%20%20%20%20%20%20%20%20%20%20%20);%0A%20%20%20%20%20%20%20%20%7D%20finally%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20loading.classList.add(%27hidden%27);%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20//%20===%20Last%20Updated%20Display%20===%0A%20%20%20%20let%20lastUpdatedTimestamp%20=%20null;%0A%20%20%20%20let%20lastUpdatedIntervalId%20=%20null;%0A%0A%20%20%20%20function%20updateLastUpdatedTime(isoTimestamp)%20%7B%0A%20%20%20%20%20%20%20%20const%20subtitle%20=%20document.getElementById(%27last-updated-subtitle%27);%0A%20%20%20%20%20%20%20%20if%20(!isoTimestamp)%20return;%0A%20%20%20%20%20%20%20%20lastUpdatedTimestamp%20=%20isoTimestamp;%0A%20%20%20%20%20%20%20%20try%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20date%20=%20new%20Date(isoTimestamp);%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20timeStr%20=%20date.toLocaleTimeString(%27de-DE%27,%20%7B%20hour:%20%272-digit%27,%20minute:%20%272-digit%27%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20dateStr%20=%20date.toLocaleDateString(%27de-DE%27,%20%7B%20day:%20%272-digit%27,%20month:%20%272-digit%27%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20ago%20=%20getRelativeTime(date);%0A%20%20%20%20%20%20%20%20%20%20%20%20subtitle.textContent%20=%20%60Aktualisiert:%20%24%7BdateStr%7D%20%24%7BtimeStr%7D%20(%24%7Bago%7D)%60;%0A%20%20%20%20%20%20%20%20%7D%20catch%20(e)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20subtitle.textContent%20=%20%27%27;%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20//%20Auto-refresh%20relative%20time%20every%20minute%0A%20%20%20%20%20%20%20%20if%20(!lastUpdatedIntervalId)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20lastUpdatedIntervalId%20=%20setInterval(()%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(lastUpdatedTimestamp)%20updateLastUpdatedTime(lastUpdatedTimestamp);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D,%2060%20%2A%201000);%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20function%20getRelativeTime(date)%20%7B%0A%20%20%20%20%20%20%20%20const%20diffMs%20=%20Date.now()%20-%20date.getTime();%0A%20%20%20%20%20%20%20%20const%20diffMin%20=%20Math.floor(diffMs%20/%2060000);%0A%20%20%20%20%20%20%20%20if%20(diffMin%20%3C%201)%20return%20%27gerade%20eben%27;%0A%20%20%20%20%20%20%20%20if%20(diffMin%20===%201)%20return%20%27vor%201%20min.%27;%0A%20%20%20%20%20%20%20%20if%20(diffMin%20%3C%2060)%20return%20%60vor%20%24%7BdiffMin%7D%20min.%60;%0A%20%20%20%20%20%20%20%20const%20diffH%20=%20Math.floor(diffMin%20/%2060);%0A%20%20%20%20%20%20%20%20if%20(diffH%20===%201)%20return%20%27vor%201%20Std.%27;%0A%20%20%20%20%20%20%20%20return%20%60vor%20%24%7BdiffH%7D%20Std.%60;%0A%20%20%20%20%7D%0A%0A%20%20%20%20//%20===%20Toast%20Notification%20===%0A%20%20%20%20function%20showToast(message,%20type%20=%20%27info%27)%20%7B%0A%20%20%20%20%20%20%20%20let%20container%20=%20document.getElementById(%27toast-container%27);%0A%20%20%20%20%20%20%20%20if%20(!container)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20container%20=%20document.createElement(%27div%27);%0A%20%20%20%20%20%20%20%20%20%20%20%20container.id%20=%20%27toast-container%27;%0A%20%20%20%20%20%20%20%20%20%20%20%20document.body.appendChild(container);%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20const%20toast%20=%20document.createElement(%27div%27);%0A%20%20%20%20%20%20%20%20toast.className%20=%20%60toast%20toast-%24%7Btype%7D%60;%0A%20%20%20%20%20%20%20%20const%20icon%20=%20type%20===%20%27success%27%20%3F%20%27check_circle%27%20:%20type%20===%20%27error%27%20%3F%20%27error%27%20:%20%27info%27;%0A%20%20%20%20%20%20%20%20toast.innerHTML%20=%20%60%3Cspan%20class=%22material-icons-round%22%3E%24%7Bicon%7D%3C/span%3E%3Cspan%3E%24%7Bmessage%7D%3C/span%3E%60;%0A%20%20%20%20%20%20%20%20container.appendChild(toast);%0A%20%20%20%20%20%20%20%20requestAnimationFrame(()%20=%3E%20toast.classList.add(%27show%27));%0A%20%20%20%20%20%20%20%20setTimeout(()%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20toast.classList.remove(%27show%27);%0A%20%20%20%20%20%20%20%20%20%20%20%20setTimeout(()%20=%3E%20toast.remove(),%20300);%0A%20%20%20%20%20%20%20%20%7D,%203000);%0A%20%20%20%20%7D%0A%0A%20%20%20%20//%20===%20Next%20Week%20Badge%20===%0A%20%20%20%20function%20updateNextWeekBadge()%20%7B%0A%20%20%20%20%20%20%20%20const%20btnNextWeek%20=%20document.getElementById(%27btn-next-week%27);%0A%20%20%20%20%20%20%20%20let%20nextWeek%20=%20currentWeekNumber%20+%201;%0A%20%20%20%20%20%20%20%20let%20nextYear%20=%20currentYear;%0A%20%20%20%20%20%20%20%20if%20(nextWeek%20%3E%2052)%20%7B%20nextWeek%20=%201;%20nextYear++;%20%7D%0A%0A%20%20%20%20%20%20%20%20const%20nextWeekData%20=%20allWeeks.find(w%20=%3E%20w.weekNumber%20===%20nextWeek%20%26%26%20w.year%20===%20nextYear);%0A%20%20%20%20%20%20%20%20let%20totalDataCount%20=%200;%0A%20%20%20%20%20%20%20%20let%20orderableCount%20=%200;%0A%20%20%20%20%20%20%20%20let%20daysWithOrders%20=%200;%0A%20%20%20%20%20%20%20%20let%20daysWithOrderableAndNoOrder%20=%200;%0A%0A%20%20%20%20%20%20%20%20if%20(nextWeekData%20%26%26%20nextWeekData.days)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20nextWeekData.days.forEach(day%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(day.items%20%26%26%20day.items.length%20%3E%200)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20totalDataCount++;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20isOrderable%20=%20day.items.some(item%20=%3E%20item.available);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(isOrderable)%20orderableCount++;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20let%20hasOrder%20=%20false;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20day.items.forEach(item%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20articleId%20=%20item.articleId%20%7C%7C%20parseInt(item.id.split(%27_%27)%5B1%5D);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20key%20=%20%60%24%7Bday.date%7D_%24%7BarticleId%7D%60;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(orderMap.has(key)%20%26%26%20orderMap.get(key).length%20%3E%200)%20hasOrder%20=%20true;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(hasOrder)%20daysWithOrders++;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(isOrderable%20%26%26%20!hasOrder)%20daysWithOrderableAndNoOrder++;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20let%20badge%20=%20btnNextWeek.querySelector(%27.nav-badge%27);%0A%20%20%20%20%20%20%20%20if%20(totalDataCount%20%3E%200)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!badge)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20badge%20=%20document.createElement(%27span%27);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20badge.className%20=%20%27nav-badge%27;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20btnNextWeek.appendChild(badge);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20Format:%20(%20Ordered%20/%20Orderable%20/%20Total%20)%0A%20%20%20%20%20%20%20%20%20%20%20%20badge.title%20=%20%60%24%7BdaysWithOrders%7D%20bestellt%20/%20%24%7BorderableCount%7D%20bestellbar%20/%20%24%7BtotalDataCount%7D%20gesamt%60;%0A%20%20%20%20%20%20%20%20%20%20%20%20badge.innerHTML%20=%20%60%3Cspan%20class=%22ordered%22%3E%24%7BdaysWithOrders%7D%3C/span%3E%3Cspan%20class=%22separator%22%3E/%3C/span%3E%3Cspan%20class=%22orderable%22%3E%24%7BorderableCount%7D%3C/span%3E%3Cspan%20class=%22separator%22%3E/%3C/span%3E%3Cspan%20class=%22total%22%3E%24%7BtotalDataCount%7D%3C/span%3E%60;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20Color%20Logic%0A%20%20%20%20%20%20%20%20%20%20%20%20badge.classList.remove(%27badge-violet%27,%20%27badge-green%27,%20%27badge-red%27,%20%27badge-blue%27);%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20Refined%20Logic%20(v1.7.4):%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20Violet:%20If%20we%20have%20orders%20AND%20there%20are%20no%20DAYS%20left%20that%20are%20orderable%20but%20un-ordered.%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20(i.e.%20%22I%20have%20ordered%20everything%20I%20can%22)%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(daysWithOrders%20%3E%200%20%26%26%20daysWithOrderableAndNoOrder%20===%200)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20badge.classList.add(%27badge-violet%27);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20if%20(daysWithOrderableAndNoOrder%20%3E%200)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20badge.classList.add(%27badge-green%27);%20//%20Orderable%20days%20exist%20without%20order%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20if%20(orderableCount%20===%200)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20badge.classList.add(%27badge-red%27);%20//%20No%20orderable%20days%20at%20all%20%26%20no%20orders%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20badge.classList.add(%27badge-blue%27);%20//%20Default%20/%20partial%20state%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20Advanced%20Feature:%20Highlight%20Count%0A%20%20%20%20%20%20%20%20%20%20%20%20let%20highlightCount%20=%200;%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(nextWeekData%20%26%26%20nextWeekData.days)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20nextWeekData.days.forEach(day%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20day.items.forEach(item%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20nameMatches%20=%20checkHighlight(item.name);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20descMatches%20=%20checkHighlight(item.description);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(nameMatches.length%20%3E%200%20%7C%7C%20descMatches.length%20%3E%200)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20highlightCount++;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(highlightCount%20%3E%200)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20Append%20blue%20count%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20badge.innerHTML%20+=%20%60%3Cspan%20class=%22highlight-count%22%20title=%22%24%7BhighlightCount%7D%20Highlight%20Men%C3%BCs%22%3E(%24%7BhighlightCount%7D)%3C/span%3E%60;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20badge.title%20+=%20%60%20%E2%80%A2%20%24%7BhighlightCount%7D%20Highlights%20gefunden%60;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20badge.classList.add(%27has-highlights%27);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%7D%20else%20if%20(badge)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20badge.remove();%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20//%20===%20Weekly%20Cost%20===%0A%20%20%20%20function%20updateWeeklyCost(days)%20%7B%0A%20%20%20%20%20%20%20%20let%20totalCost%20=%200;%0A%20%20%20%20%20%20%20%20if%20(days%20%26%26%20days.length%20%3E%200)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20days.forEach(day%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(day.items)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20day.items.forEach(item%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20articleId%20=%20item.articleId%20%7C%7C%20parseInt(item.id.split(%27_%27)%5B1%5D);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20key%20=%20%60%24%7Bday.date%7D_%24%7BarticleId%7D%60;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20orders%20=%20orderMap.get(key)%20%7C%7C%20%5B%5D;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(orders.length%20%3E%200)%20totalCost%20+=%20item.price%20%2A%20orders.length;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20const%20costDisplay%20=%20document.getElementById(%27weekly-cost-display%27);%0A%20%20%20%20%20%20%20%20if%20(totalCost%20%3E%200)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20costDisplay.innerHTML%20=%20%60%3Cspan%20class=%22material-icons-round%22%3Eshopping_bag%3C/span%3E%20%3Cspan%3EGesamt:%20%24%7BtotalCost.toFixed(2).replace(%27.%27,%20%27,%27)%7D%20%E2%82%AC%3C/span%3E%60;%0A%20%20%20%20%20%20%20%20%20%20%20%20costDisplay.classList.remove(%27hidden%27);%0A%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20costDisplay.classList.add(%27hidden%27);%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20//%20===%20Render%20Weeks%20===%0A%20%20%20%20function%20renderVisibleWeeks()%20%7B%0A%20%20%20%20%20%20%20%20const%20menuContainer%20=%20document.getElementById(%27menu-container%27);%0A%20%20%20%20%20%20%20%20if%20(!menuContainer)%20return;%0A%20%20%20%20%20%20%20%20menuContainer.innerHTML%20=%20%27%27;%0A%0A%20%20%20%20%20%20%20%20let%20targetWeek%20=%20currentWeekNumber;%0A%20%20%20%20%20%20%20%20let%20targetYear%20=%20currentYear;%0A%0A%20%20%20%20%20%20%20%20if%20(displayMode%20===%20%27next-week%27)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20targetWeek++;%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(targetWeek%20%3E%2052)%20%7B%20targetWeek%20=%201;%20targetYear++;%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20//%20Flatten%20%26%20filter%20by%20week%20+%20year%0A%20%20%20%20%20%20%20%20const%20allDays%20=%20allWeeks.flatMap(w%20=%3E%20w.days%20%7C%7C%20%5B%5D);%0A%20%20%20%20%20%20%20%20const%20daysInTargetWeek%20=%20allDays.filter(day%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20d%20=%20new%20Date(day.date);%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20getISOWeek(d)%20===%20targetWeek%20%26%26%20getWeekYear(d)%20===%20targetYear;%0A%20%20%20%20%20%20%20%20%7D);%0A%0A%20%20%20%20%20%20%20%20if%20(daysInTargetWeek.length%20===%200)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20menuContainer.innerHTML%20=%20%60%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cdiv%20class=%22empty-state%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cp%3EKeine%20Men%C3%BCdaten%20f%C3%BCr%20KW%20%24%7BtargetWeek%7D%20(%24%7BtargetYear%7D)%20verf%C3%BCgbar.%3C/p%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Csmall%3EVersuchen%20Sie%20eine%20andere%20Woche%20oder%20schauen%20Sie%20sp%C3%A4ter%20vorbei.%3C/small%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C/div%3E%60;%0A%20%20%20%20%20%20%20%20%20%20%20%20document.getElementById(%27weekly-cost-display%27).classList.add(%27hidden%27);%0A%20%20%20%20%20%20%20%20%20%20%20%20return;%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20updateWeeklyCost(daysInTargetWeek);%0A%0A%20%20%20%20%20%20%20%20//%20Update%20header%0A%20%20%20%20%20%20%20%20const%20headerWeekInfo%20=%20document.getElementById(%27header-week-info%27);%0A%20%20%20%20%20%20%20%20const%20weekTitle%20=%20displayMode%20===%20%27this-week%27%20%3F%20%27Diese%20Woche%27%20:%20%27N%C3%A4chste%20Woche%27;%0A%20%20%20%20%20%20%20%20headerWeekInfo.innerHTML%20=%20%60%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cdiv%20class=%22header-week-title%22%3E%24%7BweekTitle%7D%3C/div%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cdiv%20class=%22header-week-subtitle%22%3EWeek%20%24%7BtargetWeek%7D%20%E2%80%A2%20%24%7BtargetYear%7D%3C/div%3E%60;%0A%0A%20%20%20%20%20%20%20%20const%20grid%20=%20document.createElement(%27div%27);%0A%20%20%20%20%20%20%20%20grid.className%20=%20%27days-grid%27;%0A%0A%20%20%20%20%20%20%20%20daysInTargetWeek.sort((a,%20b)%20=%3E%20a.date.localeCompare(b.date));%0A%0A%20%20%20%20%20%20%20%20//%20Filter%20weekends%0A%20%20%20%20%20%20%20%20const%20workingDays%20=%20daysInTargetWeek.filter(d%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20date%20=%20new%20Date(d.date);%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20day%20=%20date.getDay();%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20day%20!==%200%20%26%26%20day%20!==%206;%0A%20%20%20%20%20%20%20%20%7D);%0A%0A%20%20%20%20%20%20%20%20workingDays.forEach(day%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20card%20=%20createDayCard(day);%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(card)%20grid.appendChild(card);%0A%20%20%20%20%20%20%20%20%7D);%0A%0A%20%20%20%20%20%20%20%20menuContainer.appendChild(grid);%0A%20%20%20%20%20%20%20%20setTimeout(()%20=%3E%20syncMenuItemHeights(grid),%200);%0A%20%20%20%20%7D%0A%0A%20%20%20%20//%20===%20Sync%20Item%20Heights%20===%0A%20%20%20%20function%20syncMenuItemHeights(grid)%20%7B%0A%20%20%20%20%20%20%20%20const%20cards%20=%20grid.querySelectorAll(%27.menu-card%27);%0A%20%20%20%20%20%20%20%20if%20(cards.length%20===%200)%20return;%0A%20%20%20%20%20%20%20%20let%20maxItems%20=%200;%0A%20%20%20%20%20%20%20%20cards.forEach(card%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20maxItems%20=%20Math.max(maxItems,%20card.querySelectorAll(%27.menu-item%27).length);%0A%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20for%20(let%20i%20=%200;%20i%20%3C%20maxItems;%20i++)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20let%20maxHeight%20=%200;%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20itemsAtPos%20=%20%5B%5D;%0A%20%20%20%20%20%20%20%20%20%20%20%20cards.forEach(card%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20items%20=%20card.querySelectorAll(%27.menu-item%27);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(items%5Bi%5D)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20items%5Bi%5D.style.height%20=%20%27auto%27;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20maxHeight%20=%20Math.max(maxHeight,%20items%5Bi%5D.offsetHeight);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20itemsAtPos.push(items%5Bi%5D);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20itemsAtPos.forEach(item%20=%3E%20%7B%20item.style.height%20=%20%60%24%7BmaxHeight%7Dpx%60;%20%7D);%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20//%20===%20Create%20Day%20Card%20===%0A%20%20%20%20function%20createDayCard(day)%20%7B%0A%20%20%20%20%20%20%20%20if%20(!day.items%20%7C%7C%20day.items.length%20===%200)%20return%20null;%0A%0A%20%20%20%20%20%20%20%20const%20card%20=%20document.createElement(%27div%27);%0A%20%20%20%20%20%20%20%20card.className%20=%20%27menu-card%27;%0A%0A%20%20%20%20%20%20%20%20const%20now%20=%20new%20Date();%0A%20%20%20%20%20%20%20%20const%20cardDate%20=%20new%20Date(day.date);%0A%0A%20%20%20%20%20%20%20%20let%20isPastCutoff%20=%20false;%0A%20%20%20%20%20%20%20%20if%20(day.orderCutoff)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20isPastCutoff%20=%20now%20%3E=%20new%20Date(day.orderCutoff);%0A%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20today%20=%20new%20Date();%0A%20%20%20%20%20%20%20%20%20%20%20%20today.setHours(0,%200,%200,%200);%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20cd%20=%20new%20Date(day.date);%0A%20%20%20%20%20%20%20%20%20%20%20%20cd.setHours(0,%200,%200,%200);%0A%20%20%20%20%20%20%20%20%20%20%20%20isPastCutoff%20=%20cd%20%3C%20today;%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20if%20(isPastCutoff)%20card.classList.add(%27past-day%27);%0A%0A%20%20%20%20%20%20%20%20//%20Collect%20ordered%20menu%20codes%0A%20%20%20%20%20%20%20%20const%20menuBadges%20=%20%5B%5D;%0A%20%20%20%20%20%20%20%20if%20(day.items)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20day.items.forEach(item%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20articleId%20=%20item.articleId%20%7C%7C%20parseInt(item.id.split(%27_%27)%5B1%5D);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20orderKey%20=%20%60%24%7Bday.date%7D_%24%7BarticleId%7D%60;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20orders%20=%20orderMap.get(orderKey)%20%7C%7C%20%5B%5D;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20count%20=%20orders.length;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(count%20%3E%200)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20Regex%20for%20M1,%20M2,%20M1F%20etc.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20match%20=%20item.name.match(/(%5BM%5D%5B1-9%5D%5BFf%5D%3F)/);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(match)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20let%20code%20=%20match%5B1%5D;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(count%20%3E%201)%20code%20+=%20%27+%27;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20menuBadges.push(code);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20//%20Header%0A%20%20%20%20%20%20%20%20const%20header%20=%20document.createElement(%27div%27);%0A%20%20%20%20%20%20%20%20header.className%20=%20%27card-header%27;%0A%20%20%20%20%20%20%20%20const%20dateStr%20=%20cardDate.toLocaleDateString(%27de-DE%27,%20%7B%20day:%20%272-digit%27,%20month:%20%272-digit%27%20%7D);%0A%0A%20%20%20%20%20%20%20%20const%20badgesHtml%20=%20menuBadges.map(code%20=%3E%20%60%3Cspan%20class=%22menu-code-badge%22%3E%24%7Bcode%7D%3C/span%3E%60).join(%27%27);%0A%0A%20%20%20%20%20%20%20%20//%20Determine%20Day%20Status%20for%20Header%20Color%0A%20%20%20%20%20%20%20%20//%20Violet:%20Has%20Order%0A%20%20%20%20%20%20%20%20//%20Green:%20No%20Order%20but%20Orderable%0A%20%20%20%20%20%20%20%20//%20Red:%20No%20Order%20and%20Not%20Orderable%20(Locked/Sold%20Out)%0A%20%20%20%20%20%20%20%20let%20headerClass%20=%20%27%27;%0A%20%20%20%20%20%20%20%20const%20hasAnyOrder%20=%20day.items%20%26%26%20day.items.some(item%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20articleId%20=%20item.articleId%20%7C%7C%20parseInt(item.id.split(%27_%27)%5B1%5D);%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20key%20=%20%60%24%7Bday.date%7D_%24%7BarticleId%7D%60;%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20orderMap.has(key)%20%26%26%20orderMap.get(key).length%20%3E%200;%0A%20%20%20%20%20%20%20%20%7D);%0A%0A%20%20%20%20%20%20%20%20const%20hasOrderable%20=%20day.items%20%26%26%20day.items.some(item%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20Use%20pre-calculated%20available%20flag%20from%20loadMenuDataFromAPI%20calculation%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20item.available;%0A%20%20%20%20%20%20%20%20%7D);%0A%0A%20%20%20%20%20%20%20%20if%20(hasAnyOrder)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20headerClass%20=%20%27header-violet%27;%0A%20%20%20%20%20%20%20%20%7D%20else%20if%20(hasOrderable%20%26%26%20!isPastCutoff)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20headerClass%20=%20%27header-green%27;%0A%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20Red%20if%20not%20orderable%20(or%20past%20cutoff)%0A%20%20%20%20%20%20%20%20%20%20%20%20headerClass%20=%20%27header-red%27;%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20if%20(headerClass)%20header.classList.add(headerClass);%0A%0A%20%20%20%20%20%20%20%20header.innerHTML%20=%20%60%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cdiv%20class=%22day-header-left%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cspan%20class=%22day-name%22%3E%24%7BtranslateDay(day.weekday)%7D%3C/span%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cdiv%20class=%22day-badges%22%3E%24%7BbadgesHtml%7D%3C/div%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C/div%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cspan%20class=%22day-date%22%3E%24%7BdateStr%7D%3C/span%3E%60;%0A%20%20%20%20%20%20%20%20card.appendChild(header);%0A%0A%20%20%20%20%20%20%20%20//%20Body%0A%20%20%20%20%20%20%20%20const%20body%20=%20document.createElement(%27div%27);%0A%20%20%20%20%20%20%20%20body.className%20=%20%27card-body%27;%0A%0A%20%20%20%20%20%20%20%20const%20todayDateStr%20=%20new%20Date().toISOString().split(%27T%27)%5B0%5D;%0A%20%20%20%20%20%20%20%20const%20isToday%20=%20day.date%20===%20todayDateStr;%0A%0A%20%20%20%20%20%20%20%20const%20sortedItems%20=%20%5B...day.items%5D.sort((a,%20b)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(isToday)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20aId%20=%20a.articleId%20%7C%7C%20parseInt(a.id.split(%27_%27)%5B1%5D);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20bId%20=%20b.articleId%20%7C%7C%20parseInt(b.id.split(%27_%27)%5B1%5D);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20aOrdered%20=%20orderMap.has(%60%24%7Bday.date%7D_%24%7BaId%7D%60);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20bOrdered%20=%20orderMap.has(%60%24%7Bday.date%7D_%24%7BbId%7D%60);%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(aOrdered%20%26%26%20!bOrdered)%20return%20-1;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(!aOrdered%20%26%26%20bOrdered)%20return%201;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20a.name.localeCompare(b.name);%0A%20%20%20%20%20%20%20%20%7D);%0A%0A%20%20%20%20%20%20%20%20sortedItems.forEach(item%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20itemEl%20=%20document.createElement(%27div%27);%0A%20%20%20%20%20%20%20%20%20%20%20%20itemEl.className%20=%20%27menu-item%27;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20articleId%20=%20item.articleId%20%7C%7C%20parseInt(item.id.split(%27_%27)%5B1%5D);%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20orderKey%20=%20%60%24%7Bday.date%7D_%24%7BarticleId%7D%60;%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20orderIds%20=%20orderMap.get(orderKey)%20%7C%7C%20%5B%5D;%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20orderCount%20=%20orderIds.length;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20Status%20badge%0A%20%20%20%20%20%20%20%20%20%20%20%20let%20statusBadge%20=%20%27%27;%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(item.available)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20statusBadge%20=%20item.amountTracking%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3F%20%60%3Cspan%20class=%22badge%20available%22%3EVerf%C3%BCgbar%20(%24%7Bitem.availableAmount%7D)%3C/span%3E%60%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20:%20%60%3Cspan%20class=%22badge%20available%22%3EVerf%C3%BCgbar%3C/span%3E%60;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20statusBadge%20=%20%60%3Cspan%20class=%22badge%20sold-out%22%3EAusverkauft%3C/span%3E%60;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20Order%20badge%0A%20%20%20%20%20%20%20%20%20%20%20%20let%20orderedBadge%20=%20%27%27;%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(orderCount%20%3E%200)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20countBadge%20=%20orderCount%20%3E%201%20%3F%20%60%3Cspan%20class=%22order-count-badge%22%3E%24%7BorderCount%7D%3C/span%3E%60%20:%20%27%27;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20orderedBadge%20=%20%60%3Cspan%20class=%22badge%20ordered%22%3E%3Cspan%20class=%22material-icons-round%22%3Echeck_circle%3C/span%3E%20Bestellt%24%7BcountBadge%7D%3C/span%3E%60;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20itemEl.classList.add(%27ordered%27);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(new%20Date(day.date).toDateString()%20===%20now.toDateString())%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20itemEl.classList.add(%27today-ordered%27);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20Flagged%20styles%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20flagId%20=%20%60%24%7Bday.date%7D_%24%7BarticleId%7D%60;%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20isFlagged%20=%20userFlags.has(flagId);%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(isFlagged)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20itemEl.classList.add(item.available%20%3F%20%27flagged-available%27%20:%20%27flagged-sold-out%27);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20Highlight%20matching%20menu%20items%20based%20on%20user%20tags%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20matchedTags%20=%20%5B...new%20Set(%5B...checkHighlight(item.name),%20...checkHighlight(item.description)%5D)%5D;%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(matchedTags.length%20%3E%200)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20itemEl.classList.add(%27highlight-glow%27);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20Action%20buttons%0A%20%20%20%20%20%20%20%20%20%20%20%20let%20orderButton%20=%20%27%27;%0A%20%20%20%20%20%20%20%20%20%20%20%20let%20cancelButton%20=%20%27%27;%0A%20%20%20%20%20%20%20%20%20%20%20%20let%20flagButton%20=%20%27%27;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(authToken%20%26%26%20!isPastCutoff)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20Flag%20button%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20flagIcon%20=%20isFlagged%20%3F%20%27notifications_active%27%20:%20%27notifications_none%27;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20flagClass%20=%20isFlagged%20%3F%20%27btn-flag%20active%27%20:%20%27btn-flag%27;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20flagTitle%20=%20isFlagged%20%3F%20%27Benachrichtigung%20deaktivieren%27%20:%20%27Benachrichtigen%20wenn%20verf%C3%BCgbar%27;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(!item.available%20%7C%7C%20isFlagged)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20flagButton%20=%20%60%3Cbutton%20class=%22%24%7BflagClass%7D%22%20data-date=%22%24%7Bday.date%7D%22%20data-article=%22%24%7BarticleId%7D%22%20data-name=%22%24%7BescapeHtml(item.name)%7D%22%20data-cutoff=%22%24%7Bday.orderCutoff%7D%22%20title=%22%24%7BflagTitle%7D%22%3E%3Cspan%20class=%22material-icons-round%22%3E%24%7BflagIcon%7D%3C/span%3E%3C/button%3E%60;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20Order%20button%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(item.available)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(orderCount%20%3E%200)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20orderButton%20=%20%60%3Cbutton%20class=%22btn-order%20btn-order-compact%22%20data-date=%22%24%7Bday.date%7D%22%20data-article=%22%24%7BarticleId%7D%22%20data-name=%22%24%7BescapeHtml(item.name)%7D%22%20data-price=%22%24%7Bitem.price%7D%22%20data-desc=%22%24%7BescapeHtml(item.description%20%7C%7C%20%27%27)%7D%22%20title=%22%24%7BescapeHtml(item.name)%7D%20nochmal%20bestellen%22%3E%3Cspan%20class=%22material-icons-round%22%3Eadd%3C/span%3E%3C/button%3E%60;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20orderButton%20=%20%60%3Cbutton%20class=%22btn-order%22%20data-date=%22%24%7Bday.date%7D%22%20data-article=%22%24%7BarticleId%7D%22%20data-name=%22%24%7BescapeHtml(item.name)%7D%22%20data-price=%22%24%7Bitem.price%7D%22%20data-desc=%22%24%7BescapeHtml(item.description%20%7C%7C%20%27%27)%7D%22%20title=%22%24%7BescapeHtml(item.name)%7D%20bestellen%22%3E%3Cspan%20class=%22material-icons-round%22%3Eadd_shopping_cart%3C/span%3E%20Bestellen%3C/button%3E%60;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20Cancel%20button%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(orderCount%20%3E%200)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20cancelIcon%20=%20orderCount%20===%201%20%3F%20%27close%27%20:%20%27remove%27;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20cancelTitle%20=%20orderCount%20===%201%20%3F%20%27Bestellung%20stornieren%27%20:%20%27Eine%20Bestellung%20stornieren%27;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20cancelButton%20=%20%60%3Cbutton%20class=%22btn-cancel%22%20data-date=%22%24%7Bday.date%7D%22%20data-article=%22%24%7BarticleId%7D%22%20data-name=%22%24%7BescapeHtml(item.name)%7D%22%20title=%22%24%7BcancelTitle%7D%22%3E%3Cspan%20class=%22material-icons-round%22%3E%24%7BcancelIcon%7D%3C/span%3E%3C/button%3E%60;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20Build%20matched-tags%20HTML%20(only%20if%20tags%20found)%0A%20%20%20%20%20%20%20%20%20%20%20%20let%20tagsHtml%20=%20%27%27;%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(matchedTags.length%20%3E%200)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20badges%20=%20matchedTags.map(t%20=%3E%20%60%3Cspan%20class=%22tag-badge-small%22%3E%3Cspan%20class=%22material-icons-round%22%20style=%22font-size:10px;margin-right:2px%22%3Estar%3C/span%3E%24%7BescapeHtml(t)%7D%3C/span%3E%60).join(%27%27);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20tagsHtml%20=%20%60%3Cdiv%20class=%22matched-tags%22%3E%24%7Bbadges%7D%3C/div%3E%60;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20itemEl.innerHTML%20=%20%60%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cdiv%20class=%22item-header%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cspan%20class=%22item-name%22%3E%24%7BescapeHtml(item.name)%7D%3C/span%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cspan%20class=%22item-price%22%3E%24%7Bitem.price.toFixed(2)%7D%20%E2%82%AC%3C/span%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C/div%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cdiv%20class=%22item-status-row%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%24%7BorderedBadge%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%24%7BcancelButton%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%24%7BorderButton%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%24%7BflagButton%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cdiv%20class=%22badges%22%3E%24%7BstatusBadge%7D%3C/div%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C/div%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%24%7BtagsHtml%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cp%20class=%22item-desc%22%3E%24%7BescapeHtml(item.description)%7D%3C/p%3E%60;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20Event:%20Order%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20orderBtn%20=%20itemEl.querySelector(%27.btn-order%27);%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(orderBtn)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20orderBtn.addEventListener(%27click%27,%20(e)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20e.stopPropagation();%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20btn%20=%20e.currentTarget;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20btn.disabled%20=%20true;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20btn.classList.add(%27loading%27);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20placeOrder(btn.dataset.date,%20parseInt(btn.dataset.article),%20btn.dataset.name,%20parseFloat(btn.dataset.price),%20btn.dataset.desc%20%7C%7C%20%27%27)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20.finally(()%20=%3E%20%7B%20btn.disabled%20=%20false;%20btn.classList.remove(%27loading%27);%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20Event:%20Cancel%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20cancelBtn%20=%20itemEl.querySelector(%27.btn-cancel%27);%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(cancelBtn)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20cancelBtn.addEventListener(%27click%27,%20(e)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20e.stopPropagation();%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20btn%20=%20e.currentTarget;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20btn.disabled%20=%20true;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20cancelOrder(btn.dataset.date,%20parseInt(btn.dataset.article),%20btn.dataset.name)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20.finally(()%20=%3E%20%7B%20btn.disabled%20=%20false;%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20Event:%20Flag%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20flagBtn%20=%20itemEl.querySelector(%27.btn-flag%27);%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(flagBtn)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20flagBtn.addEventListener(%27click%27,%20(e)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20e.stopPropagation();%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20btn%20=%20e.currentTarget;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20toggleFlag(btn.dataset.date,%20parseInt(btn.dataset.article),%20btn.dataset.name,%20btn.dataset.cutoff);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20body.appendChild(itemEl);%0A%20%20%20%20%20%20%20%20%7D);%0A%0A%20%20%20%20%20%20%20%20card.appendChild(body);%0A%20%20%20%20%20%20%20%20return%20card;%0A%20%20%20%20%7D%0A%0A%20%20%20%20//%20===%20GitHub%20Release%20Management%20===%0A%0A%20%20%20%20//%20Semver%20comparison:%20returns%20true%20if%20remote%20%3E%20local%0A%20%20%20%20function%20isNewer(remote,%20local)%20%7B%0A%20%20%20%20%20%20%20%20if%20(!remote%20%7C%7C%20!local)%20return%20false;%0A%20%20%20%20%20%20%20%20const%20r%20=%20remote.replace(/%5Ev/,%20%27%27).split(%27.%27).map(Number);%0A%20%20%20%20%20%20%20%20const%20l%20=%20local.replace(/%5Ev/,%20%27%27).split(%27.%27).map(Number);%0A%20%20%20%20%20%20%20%20for%20(let%20i%20=%200;%20i%20%3C%20Math.max(r.length,%20l.length);%20i++)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20((r%5Bi%5D%20%7C%7C%200)%20%3E%20(l%5Bi%5D%20%7C%7C%200))%20return%20true;%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20((r%5Bi%5D%20%7C%7C%200)%20%3C%20(l%5Bi%5D%20%7C%7C%200))%20return%20false;%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20return%20false;%0A%20%20%20%20%7D%0A%0A%20%20%20%20//%20GitHub%20API%20headers%0A%20%20%20%20function%20githubHeaders()%20%7B%0A%20%20%20%20%20%20%20%20return%20%7B%20%27Accept%27:%20%27application/vnd.github.v3+json%27%20%7D;%0A%20%20%20%20%7D%0A%0A%20%20%20%20//%20Fetch%20versions%20from%20GitHub%20(releases%20or%20tags)%0A%20%20%20%20async%20function%20fetchVersions(devMode)%20%7B%0A%20%20%20%20%20%20%20%20const%20endpoint%20=%20devMode%0A%20%20%20%20%20%20%20%20%20%20%20%20%3F%20%60%24%7BGITHUB_API%7D/tags%3Fper_page=20%60%0A%20%20%20%20%20%20%20%20%20%20%20%20:%20%60%24%7BGITHUB_API%7D/releases%3Fper_page=20%60;%0A%0A%20%20%20%20%20%20%20%20const%20resp%20=%20await%20fetch(endpoint,%20%7B%20headers:%20githubHeaders()%20%7D);%0A%20%20%20%20%20%20%20%20if%20(!resp.ok)%20throw%20new%20Error(%60GitHub%20API%20%24%7Bresp.status%7D%60);%0A%20%20%20%20%20%20%20%20const%20data%20=%20await%20resp.json();%0A%0A%20%20%20%20%20%20%20%20//%20Normalize%20to%20common%20format:%20%7B%20tag,%20name,%20url,%20body%20%7D%0A%20%20%20%20%20%20%20%20return%20data.map(item%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20tag%20=%20devMode%20%3F%20item.name%20:%20item.tag_name;%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20tag,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20name:%20devMode%20%3F%20tag%20:%20(item.name%20%7C%7C%20tag),%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20url:%20%60%24%7BINSTALLER_BASE%7D/%24%7Btag%7D/dist/install.html%60,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20body:%20item.body%20%7C%7C%20%27%27%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D;%0A%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%7D%0A%0A%20%20%20%20//%20Periodic%20update%20check%20(runs%20on%20init%20+%20every%20hour)%0A%20%20%20%20async%20function%20checkForUpdates()%20%7B%0A%20%20%20%20%20%20%20%20const%20currentVersion%20=%20%27v1.4.0%27;%0A%20%20%20%20%20%20%20%20const%20devMode%20=%20localStorage.getItem(%27kantine_dev_mode%27)%20===%20%27true%27;%0A%0A%20%20%20%20%20%20%20%20try%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20versions%20=%20await%20fetchVersions(devMode);%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!versions.length)%20return;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20Cache%20for%20version%20menu%0A%20%20%20%20%20%20%20%20%20%20%20%20localStorage.setItem(%27kantine_version_cache%27,%20JSON.stringify(%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20timestamp:%20Date.now(),%20devMode,%20versions%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D));%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20latest%20=%20versions%5B0%5D.tag;%0A%20%20%20%20%20%20%20%20%20%20%20%20console.log(%60%5BKantine%5D%20Version%20Check:%20Local%20%5B%24%7BcurrentVersion%7D%5D%20vs%20Latest%20%5B%24%7Blatest%7D%5D%20(%24%7BdevMode%20%3F%20%27dev%27%20:%20%27stable%27%7D)%60);%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!isNewer(latest,%20currentVersion))%20return;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20console.log(%60%5BKantine%5D%20Update%20verf%C3%BCgbar:%20%24%7Blatest%7D%60);%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20Show%20%F0%9F%86%95%20icon%20in%20header%20(only%20once)%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20headerTitle%20=%20document.querySelector(%27.header-left%20h1%27);%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(headerTitle%20%26%26%20!headerTitle.querySelector(%27.update-icon%27))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20icon%20=%20document.createElement(%27a%27);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20icon.className%20=%20%27update-icon%27;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20icon.href%20=%20versions%5B0%5D.url;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20icon.target%20=%20%27_blank%27;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20icon.innerHTML%20=%20%27%F0%9F%86%95%27;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20icon.title%20=%20%60Update:%20%24%7Blatest%7D%20%E2%80%94%20Klick%20zum%20Installieren%60;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20icon.style.cssText%20=%20%27margin-left:8px;font-size:1em;text-decoration:none;cursor:pointer;vertical-align:middle;%27;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20headerTitle.appendChild(icon);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%20catch%20(e)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20console.warn(%27%5BKantine%5D%20Version%20check%20failed:%27,%20e);%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20//%20Open%20Version%20Menu%20modal%0A%20%20%20%20function%20openVersionMenu()%20%7B%0A%20%20%20%20%20%20%20%20const%20modal%20=%20document.getElementById(%27version-modal%27);%0A%20%20%20%20%20%20%20%20const%20container%20=%20document.getElementById(%27version-list-container%27);%0A%20%20%20%20%20%20%20%20const%20devToggle%20=%20document.getElementById(%27dev-mode-toggle%27);%0A%20%20%20%20%20%20%20%20const%20currentVersion%20=%20%27v1.4.0%27;%0A%0A%20%20%20%20%20%20%20%20if%20(!modal)%20return;%0A%20%20%20%20%20%20%20%20modal.classList.remove(%27hidden%27);%0A%0A%20%20%20%20%20%20%20%20//%20Set%20current%20version%20display%0A%20%20%20%20%20%20%20%20const%20cur%20=%20document.getElementById(%27version-current%27);%0A%20%20%20%20%20%20%20%20if%20(cur)%20cur.textContent%20=%20currentVersion;%0A%0A%20%20%20%20%20%20%20%20//%20Init%20dev%20toggle%0A%20%20%20%20%20%20%20%20const%20devMode%20=%20localStorage.getItem(%27kantine_dev_mode%27)%20===%20%27true%27;%0A%20%20%20%20%20%20%20%20devToggle.checked%20=%20devMode;%0A%0A%20%20%20%20%20%20%20%20//%20Load%20versions%20(from%20cache%20or%20fresh)%0A%20%20%20%20%20%20%20%20async%20function%20loadVersions(forceRefresh)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20dm%20=%20devToggle.checked;%0A%20%20%20%20%20%20%20%20%20%20%20%20container.innerHTML%20=%20%27%3Cp%20style=%22color:var(--text-secondary);%22%3ELade%20Versionen...%3C/p%3E%27;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20try%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20let%20versions;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20cached%20=%20JSON.parse(localStorage.getItem(%27kantine_version_cache%27)%20%7C%7C%20%27null%27);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(!forceRefresh%20%26%26%20cached%20%26%26%20cached.devMode%20===%20dm%20%26%26%20(Date.now()%20-%20cached.timestamp%20%3C%203600000))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20versions%20=%20cached.versions;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20versions%20=%20await%20fetchVersions(dm);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20localStorage.setItem(%27kantine_version_cache%27,%20JSON.stringify(%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20timestamp:%20Date.now(),%20devMode:%20dm,%20versions%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D));%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(!versions.length)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20container.innerHTML%20=%20%27%3Cp%20style=%22color:var(--text-secondary);%22%3EKeine%20Versionen%20gefunden.%3C/p%3E%27;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20container.innerHTML%20=%20%27%3Cul%20class=%22version-list%22%3E%3C/ul%3E%27;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20list%20=%20container.querySelector(%27.version-list%27);%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20versions.forEach(v%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20isCurrent%20=%20v.tag%20===%20currentVersion;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20isNew%20=%20isNewer(v.tag,%20currentVersion);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20li%20=%20document.createElement(%27li%27);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20li.className%20=%20%27version-item%27%20+%20(isCurrent%20%3F%20%27%20current%27%20:%20%27%27);%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20let%20badge%20=%20%27%27;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(isCurrent)%20badge%20=%20%27%3Cspan%20class=%22badge-current%22%3E%E2%9C%93%20Installiert%3C/span%3E%27;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20else%20if%20(isNew)%20badge%20=%20%27%3Cspan%20class=%22badge-new%22%3E%E2%AC%86%20Neu!%3C/span%3E%27;%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20let%20action%20=%20%27%27;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(!isCurrent)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20action%20=%20%60%3Ca%20href=%22%24%7Bv.url%7D%22%20target=%22_blank%22%20class=%22install-link%22%20title=%22%24%7Bv.tag%7D%20installieren%22%3EInstallieren%3C/a%3E%60;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20li.innerHTML%20=%20%60%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cdiv%20class=%22version-info%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cstrong%3E%24%7Bv.tag%7D%3C/strong%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%24%7Bbadge%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C/div%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%24%7Baction%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%60;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20list.appendChild(li);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%20catch%20(e)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20container.innerHTML%20=%20%60%3Cp%20style=%22color:%23e94560;%22%3EFehler:%20%24%7Be.message%7D%3C/p%3E%60;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20loadVersions(false);%0A%0A%20%20%20%20%20%20%20%20//%20Dev%20toggle%20handler%0A%20%20%20%20%20%20%20%20devToggle.onchange%20=%20()%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20localStorage.setItem(%27kantine_dev_mode%27,%20devToggle.checked);%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20Clear%20cache%20to%20force%20refresh%20when%20mode%20changes%0A%20%20%20%20%20%20%20%20%20%20%20%20localStorage.removeItem(%27kantine_version_cache%27);%0A%20%20%20%20%20%20%20%20%20%20%20%20loadVersions(true);%0A%20%20%20%20%20%20%20%20%7D;%0A%20%20%20%20%7D%0A%0A%20%20%20%20//%20===%20Order%20Countdown%20===%0A%20%20%20%20function%20updateCountdown()%20%7B%0A%20%20%20%20%20%20%20%20const%20now%20=%20new%20Date();%0A%20%20%20%20%20%20%20%20const%20currentDay%20=%20now.getDay();%0A%20%20%20%20%20%20%20%20//%20Skip%20weekends%20(0=Sun,%206=Sat)%0A%20%20%20%20%20%20%20%20if%20(currentDay%20===%200%20%7C%7C%20currentDay%20===%206)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20removeCountdown();%0A%20%20%20%20%20%20%20%20%20%20%20%20return;%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20const%20todayStr%20=%20now.toISOString().split(%27T%27)%5B0%5D;%0A%0A%20%20%20%20%20%20%20%20//%201.%20Check%20if%20we%20already%20ordered%20for%20today%0A%20%20%20%20%20%20%20%20let%20hasOrder%20=%20false;%0A%20%20%20%20%20%20%20%20//%20Optimization:%20Check%20orderMap%20for%20today%27s%20date%0A%20%20%20%20%20%20%20%20//%20Keys%20are%20%22YYYY-MM-DD_ArticleID%22%0A%20%20%20%20%20%20%20%20for%20(const%20key%20of%20orderMap.keys())%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(key.startsWith(todayStr))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20hasOrder%20=%20true;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20break;%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20if%20(hasOrder)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20removeCountdown();%0A%20%20%20%20%20%20%20%20%20%20%20%20return;%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20//%202.%20Calculate%20time%20to%20cutoff%20(10:00%20AM)%0A%20%20%20%20%20%20%20%20const%20cutoff%20=%20new%20Date();%0A%20%20%20%20%20%20%20%20cutoff.setHours(10,%200,%200,%200);%0A%0A%20%20%20%20%20%20%20%20const%20diff%20=%20cutoff%20-%20now;%0A%0A%20%20%20%20%20%20%20%20//%20If%20passed%20cutoff%20or%20more%20than%203%20hours%20away%20(e.g.%2007:00),%20maybe%20don%27t%20show%3F%0A%20%20%20%20%20%20%20%20//%20User%20req:%20%22heute%20noch%20keine%20bestellung...%20countdown%20erscheinen%22%0A%20%20%20%20%20%20%20%20//%20Let%27s%20show%20it%20if%20within%20valid%20order%20window%20(e.g.%2000:00%20-%2010:00)%0A%0A%20%20%20%20%20%20%20%20if%20(diff%20%3C=%200)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20removeCountdown();%0A%20%20%20%20%20%20%20%20%20%20%20%20return;%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20//%203.%20Render%20Countdown%0A%20%20%20%20%20%20%20%20const%20diffHrs%20=%20Math.floor(diff%20/%203600000);%0A%20%20%20%20%20%20%20%20const%20diffMins%20=%20Math.floor((diff%20%25%203600000)%20/%2060000);%0A%0A%20%20%20%20%20%20%20%20const%20headerCenter%20=%20document.querySelector(%27.header-center-wrapper%27);%0A%20%20%20%20%20%20%20%20if%20(!headerCenter)%20return;%0A%0A%20%20%20%20%20%20%20%20let%20countdownEl%20=%20document.getElementById(%27order-countdown%27);%0A%20%20%20%20%20%20%20%20if%20(!countdownEl)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20countdownEl%20=%20document.createElement(%27div%27);%0A%20%20%20%20%20%20%20%20%20%20%20%20countdownEl.id%20=%20%27order-countdown%27;%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20Insert%20before%20cost%20display%20or%20append%0A%20%20%20%20%20%20%20%20%20%20%20%20headerCenter.insertBefore(countdownEl,%20headerCenter.firstChild);%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20countdownEl.innerHTML%20=%20%60%3Cspan%3EBestellschluss:%3C/span%3E%20%3Cstrong%3E%24%7BdiffHrs%7Dh%20%24%7BdiffMins%7Dm%3C/strong%3E%60;%0A%0A%20%20%20%20%20%20%20%20//%20Red%20Alert%20if%20%3C%201%20hour%0A%20%20%20%20%20%20%20%20if%20(diff%20%3C%203600000)%20%7B%20//%201%20hour%0A%20%20%20%20%20%20%20%20%20%20%20%20countdownEl.classList.add(%27urgent%27);%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20Notification%20logic%20(One%20time)%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20notifiedKey%20=%20%60kantine_notified_%24%7BtodayStr%7D%60;%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!sessionStorage.getItem(notifiedKey))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(Notification.permission%20===%20%27granted%27)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20new%20Notification(%27Kantine:%20Bestellschluss%20naht!%27,%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20body:%20%27Du%20hast%20heute%20noch%20nichts%20bestellt.%20Nur%20noch%201%20Stunde!%27,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20icon:%20%27%E2%8F%B3%27%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20if%20(Notification.permission%20===%20%27default%27)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20Notification.requestPermission();%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20sessionStorage.setItem(notifiedKey,%20%27true%27);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20countdownEl.classList.remove(%27urgent%27);%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20function%20removeCountdown()%20%7B%0A%20%20%20%20%20%20%20%20const%20el%20=%20document.getElementById(%27order-countdown%27);%0A%20%20%20%20%20%20%20%20if%20(el)%20el.remove();%0A%20%20%20%20%7D%0A%0A%20%20%20%20//%20Update%20countdown%20every%20minute%0A%20%20%20%20setInterval(updateCountdown,%2060000);%0A%20%20%20%20//%20Also%20update%20on%20load%0A%20%20%20%20setTimeout(updateCountdown,%201000);%0A%0A%20%20%20%20//%20===%20Helpers%20===%20%0A%20%20%20%20function%20getISOWeek(date)%20%7B%0A%20%20%20%20%20%20%20%20const%20d%20=%20new%20Date(Date.UTC(date.getFullYear(),%20date.getMonth(),%20date.getDate()));%0A%20%20%20%20%20%20%20%20const%20dayNum%20=%20d.getUTCDay()%20%7C%7C%207;%0A%20%20%20%20%20%20%20%20d.setUTCDate(d.getUTCDate()%20+%204%20-%20dayNum);%0A%20%20%20%20%20%20%20%20const%20yearStart%20=%20new%20Date(Date.UTC(d.getUTCFullYear(),%200,%201));%0A%20%20%20%20%20%20%20%20return%20Math.ceil(((d%20-%20yearStart)%20/%2086400000%20+%201)%20/%207);%0A%20%20%20%20%7D%0A%0A%20%20%20%20function%20getWeekYear(d)%20%7B%0A%20%20%20%20%20%20%20%20const%20date%20=%20new%20Date(d.getTime());%0A%20%20%20%20%20%20%20%20date.setDate(date.getDate()%20+%203%20-%20(date.getDay()%20+%206)%20%25%207);%0A%20%20%20%20%20%20%20%20return%20date.getFullYear();%0A%20%20%20%20%7D%0A%0A%0A%20%20%20%20function%20translateDay(englishDay)%20%7B%0A%20%20%20%20%20%20%20%20const%20map%20=%20%7B%20Monday:%20%27Montag%27,%20Tuesday:%20%27Dienstag%27,%20Wednesday:%20%27Mittwoch%27,%20Thursday:%20%27Donnerstag%27,%20Friday:%20%27Freitag%27,%20Saturday:%20%27Samstag%27,%20Sunday:%20%27Sonntag%27%20%7D;%0A%20%20%20%20%20%20%20%20return%20map%5BenglishDay%5D%20%7C%7C%20englishDay;%0A%20%20%20%20%7D%0A%0A%20%20%20%20function%20escapeHtml(text)%20%7B%0A%20%20%20%20%20%20%20%20const%20div%20=%20document.createElement(%27div%27);%0A%20%20%20%20%20%20%20%20div.textContent%20=%20text%20%7C%7C%20%27%27;%0A%20%20%20%20%20%20%20%20return%20div.innerHTML;%0A%20%20%20%20%7D%0A%0A%20%20%20%20//%20===%20Bootstrap%20===%0A%20%20%20%20injectUI();%0A%20%20%20%20bindEvents();%0A%20%20%20%20updateAuthUI();%0A%20%20%20%20cleanupExpiredFlags();%0A%0A%20%20%20%20//%20Load%20cached%20data%20first%20for%20instant%20UI,%20refresh%20only%20if%20stale%20(FR-024)%0A%20%20%20%20const%20hadCache%20=%20loadMenuCache();%0A%20%20%20%20if%20(hadCache)%20%7B%0A%20%20%20%20%20%20%20%20document.getElementById(%27loading%27).classList.add(%27hidden%27);%0A%20%20%20%20%20%20%20%20if%20(!isCacheFresh())%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20console.log(%27Cache%20stale%20or%20incomplete%20%E2%80%93%20refreshing%20from%20API%27);%0A%20%20%20%20%20%20%20%20%20%20%20%20loadMenuDataFromAPI();%0A%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20console.log(%27Cache%20fresh%20%26%20complete%20%E2%80%93%20skipping%20API%20refresh%27);%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20loadMenuDataFromAPI();%0A%20%20%20%20%7D%0A%0A%20%20%20%20//%20Auto-start%20polling%20if%20already%20logged%20in%0A%20%20%20%20if%20(authToken)%20%7B%0A%20%20%20%20%20%20%20%20startPolling();%0A%20%20%20%20%7D%0A%0A%20%20%20%20//%20Check%20for%20updates%20(now%20+%20every%20hour)%0A%20%20%20%20checkForUpdates();%0A%20%20%20%20setInterval(checkForUpdates,%2060%20%2A%2060%20%2A%201000);%0A%0A%20%20%20%20console.log(%27Kantine%20Wrapper%20loaded%20%E2%9C%85%27);%0A%7D)();%0A%0A//%20===%20Error%20Modal%20===%0Afunction%20showErrorModal(title,%20htmlContent,%20btnText,%20url)%20%7B%0A%20%20%20%20const%20modalId%20=%20%27error-modal%27;%0A%20%20%20%20let%20modal%20=%20document.getElementById(modalId);%0A%20%20%20%20if%20(modal)%20modal.remove();%0A%0A%20%20%20%20modal%20=%20document.createElement(%27div%27);%0A%20%20%20%20modal.id%20=%20modalId;%0A%20%20%20%20modal.className%20=%20%27modal%20hidden%27;%0A%20%20%20%20modal.innerHTML%20=%20%60%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cdiv%20class=%22modal-content%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cdiv%20class=%22modal-header%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Ch2%20style=%22color:%20var(--error-color);%20display:%20flex;%20align-items:%20center;%20gap:%2010px;%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cspan%20class=%22material-icons-round%22%3Esignal_wifi_off%3C/span%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%24%7Btitle%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C/h2%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C/div%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cdiv%20style=%22padding:%2020px;%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cp%20style=%22margin-bottom:%2015px;%20color:%20var(--text-primary);%22%3E%24%7BhtmlContent%7D%3C/p%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cdiv%20style=%22margin-top:%2020px;%20display:%20flex;%20justify-content:%20center;%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cbutton%20id=%22btn-error-redirect%22%20style=%22%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20background-color:%20var(--accent-color);%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20color:%20white;%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20padding:%2012px%2024px;%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20border-radius:%208px;%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20border:%20none;%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20font-weight:%20600;%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20cursor:%20pointer;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20display:%20flex;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20align-items:%20center;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20gap:%208px;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20width:%20100%25;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20justify-content:%20center;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20transition:%20transform%200.1s;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%24%7BbtnText%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cspan%20class=%22material-icons-round%22%3Eopen_in_new%3C/span%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C/button%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C/div%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C/div%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C/div%3E%0A%20%20%20%20%20%20%20%20%60;%0A%20%20%20%20document.body.appendChild(modal);%0A%0A%20%20%20%20document.getElementById(%27btn-error-redirect%27).addEventListener(%27click%27,%20()%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20window.location.href%20=%20url;%0A%20%20%20%20%7D);%0A%0A%20%20%20%20requestAnimationFrame(()%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20modal.classList.remove(%27hidden%27);%0A%20%20%20%20%7D);%0A%7D%0A%7D)();";
|
||
document.getElementById('bookmarklet-link').textContent = 'Kantine v1.4.0';
|
||
</script>
|
||
</body>
|
||
</html>
|