Lade Men\u00fcdaten...
\\njavascript:(function(){ if(window.__KANTINE_LOADED){alert('Kantine Wrapper already loaded!');return;} var s=document.createElement('style');s.textContent=':root { /* Premium Slate/Gray-Blue Palette - Light Mode */ --bg-body: #f1f5f9; /* Slate 100 */ --bg-card: #ffffff; --text-primary: #334155; /* Slate 700 */ --text-secondary: #64748b; --accent-color: #0f172a; /* Slate 900 (High contrast) */ --border-color: #cbd5e1; /* Slate 300 */ --banner-bg: #e2e8f0; --banner-text: #1e293b; --success-color: #059669; --error-color: #dc2626; --card-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.05), 0 2px 4px -2px rgb(0 0 0 / 0.05); --header-bg: rgba(255, 255, 255, 0.9); --header-border: 1px solid rgba(203, 213, 225, 0.6); } [data-theme="dark"] { /* Premium Slate/Gray-Blue Palette - Dark Mode */ --bg-body: #1e293b; /* Deep Slate Gray (Requested) */ --bg-card: #334155; /* Slate 700 */ --text-primary: #f8fafc; /* Slate 50 */ --text-secondary: #cbd5e1; /* Slate 300 */ --accent-color: #60a5fa; /* Blue 400 */ --border-color: #475569; /* Slate 600 */ --banner-bg: #475569; --banner-text: #e2e8f0; --header-bg: rgba(30, 41, 59, 0.9); --header-border: 1px solid rgba(71, 85, 105, 0.6); --card-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.4); } * { box-sizing: border-box; margin: 0; padding: 0; } body { font-family: \'Inter\', system-ui, -apple-system, sans-serif; background-color: var(--bg-body); color: var(--text-primary); transition: background-color 0.3s ease, color 0.3s ease; line-height: 1.5; -webkit-font-smoothing: antialiased; } /* Fix scrolling bug: Reset html/body styles from host page */ /* IMPORTANT: html must NOT have overflow set, or it creates a scroll container that breaks position: sticky */ html { height: auto !important; min-height: 100% !important; overflow: visible !important; position: static !important; margin: 0 !important; padding: 0 !important; } body { height: auto !important; min-height: 100% !important; overflow-x: clip !important; /* clip prevents horizontal overflow without breaking sticky */ overflow-y: visible !important; position: static !important; margin: 0 !important; padding: 0 !important; } /* Header */ .app-header { flex-shrink: 0; z-index: 100; backdrop-filter: blur(12px); background-color: var(--header-bg); border-bottom: var(--header-border); padding: 1rem 0; } .header-content { width: 100%; /* Full width */ padding: 0 2rem; /* Comfortable padding */ display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; gap: 1rem; } .brand { display: flex; align-items: center; gap: 0.75rem; } .brand-text { display: flex; flex-direction: column; } .brand h1 { font-size: 1.25rem; font-weight: 700; letter-spacing: -0.025em; margin-bottom: 0; } .subtitle { font-size: 0.85rem; color: var(--text-secondary); font-weight: 400; margin-left: 2px; } .logo-icon { font-size: 1.5rem; color: var(--accent-color); } /* Controls */ .controls { display: flex; align-items: center; gap: 1.5rem; justify-self: end; } /* Header Week Info (centered) */ .header-week-info { text-align: center; line-height: 1.3; } .header-center-wrapper { display: flex; flex-direction: row; align-items: center; gap: 1.5rem; justify-content: center; } .header-week-title { font-size: 1.1rem; font-weight: 600; color: var(--text-primary); } .header-week-subtitle { font-size: 0.85rem; color: var(--text-secondary); } /* Language Toggle (FR-100) */ .lang-toggle { display: inline-flex; gap: 0; border-radius: 6px; overflow: hidden; border: 1px solid var(--border-color); background: var(--bg-card); } .lang-btn { padding: 3px 10px; font-size: 0.7rem; font-weight: 600; letter-spacing: 0.03em; background: transparent; color: var(--text-secondary); border: none; cursor: pointer; transition: all 0.2s; } .lang-btn:hover { color: var(--text-primary); background: rgba(100, 116, 139, 0.1); } .lang-btn.active { background: var(--accent-color); color: white; } .nav-group { display: flex; background-color: var(--bg-card); border: 1px solid var(--border-color); padding: 0.25rem; border-radius: 8px; } .nav-btn { background: none; border: none; padding: 0.5rem 1rem; font-size: 0.875rem; font-weight: 500; color: var(--text-secondary); cursor: pointer; border-radius: 6px; transition: all 0.2s; display: flex; align-items: center; gap: 0.5rem; } .nav-btn:hover { color: var(--text-primary); background-color: rgba(100, 116, 139, 0.1); } .nav-btn.active { background-color: var(--accent-color); color: white; } /* Notification state for Next Week */ .nav-btn.new-week-available { animation: goldPulse 2s infinite; border-color: #f59e0b; color: var(--accent-color); } .nav-btn.new-week-available.active { color: white; } @keyframes goldPulse { 0% { box-shadow: 0 0 0 0 rgba(245, 158, 11, 0.7); } 70% { box-shadow: 0 0 0 10px rgba(245, 158, 11, 0); } 100% { box-shadow: 0 0 0 0 rgba(245, 158, 11, 0); } } /* Badge for nav buttons (day count indicator) */ .nav-badge { background-color: var(--error-color); color: white; font-size: 0.75rem; font-weight: 600; padding: 0 6px; border-radius: 10px; min-width: 18px; height: 18px; display: inline-flex; align-items: center; justify-content: center; margin-left: 8px; gap: 3px; line-height: 1; } .nav-badge .orderable { color: #fff; font-weight: 800; } .nav-badge .separator { opacity: 0.6; font-weight: 400; } .nav-badge .total { opacity: 0.8; font-weight: 400; } .nav-btn.active .nav-badge { background: rgba(255, 255, 255, 0.3); } /* Primary style for Login Button to match header */ #btn-login-open { background-color: var(--accent-color); color: white; padding: 0.5rem 1.25rem; border-radius: 8px; font-weight: 600; letter-spacing: 0.025em; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); } #btn-login-open:hover { background-color: #334155; /* Slightly lighter than slate-900 */ transform: translateY(-1px); box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); } /* User Badge Button (Login) */ .user-badge-btn { display: flex; align-items: center; gap: 8px; padding: 6px 12px; background: var(--bg-card); border: 1px solid var(--border-color); border-radius: 20px; font-size: 0.9rem; font-weight: 500; color: var(--text-primary); cursor: pointer; transition: all 0.2s; } .user-badge-btn:hover { background: rgba(100, 116, 139, 0.1); border-color: var(--accent-color); } .user-badge-btn .material-icons-round { font-size: 1.25rem; color: var(--accent-color); } .icon-btn { background: none; border: none; color: var(--text-primary); cursor: pointer; padding: 0.5rem; border-radius: 50%; transition: background-color 0.2s; display: flex; align-items: center; justify-content: center; } .icon-btn:hover { background-color: rgba(100, 116, 139, 0.1); } /* Refresh button animation */ #btn-refresh.refreshing .material-icons-round, #alarm-bell.refreshing .material-icons-round { animation: rotate 1s linear infinite; } @keyframes rotate { from { transform: rotate(0deg); } to { transform: rotate(360deg); } } /* Progress Modal */ .progress-container { margin-bottom: 1.5rem; } .progress-bar { width: 100%; height: 8px; background-color: var(--border-color); border-radius: 4px; overflow: hidden; margin-bottom: 0.75rem; } .progress-fill { height: 100%; background: linear-gradient(90deg, var(--accent-color) 0%, #60a5fa 100%); width: 0%; transition: width 0.3s ease; border-radius: 4px; } .progress-percent { text-align: center; font-size: 1.5rem; font-weight: 700; color: var(--text-primary); margin-bottom: 0.5rem; } .progress-message { text-align: center; color: var(--text-secondary); font-size: 0.9rem; font-weight: 500; } .weekly-cost { background-color: rgba(59, 130, 246, 0.1); /* Blue tint */ color: var(--accent-color); padding: 0.4rem 0.8rem; border-radius: 8px; font-weight: 600; font-size: 0.9rem; display: flex; align-items: center; gap: 0.5rem; border: 1px solid rgba(59, 130, 246, 0.2); } .weekly-cost .material-icons-round { font-size: 18px; } /* Container - flex column, full width so child scrollbar is at edge */ .container { flex: 1; width: 100%; overflow: hidden; padding: 0 0 0 0; /* Only top padding, no horizontal so child fills width */ display: flex; flex-direction: column; } /* Add horizontal padding to direct children of container to maintain layout */ .container>*:not(.menu-grid) { padding-left: 2rem; padding-right: 2rem; } /* Banner */ .banner { background-color: var(--banner-bg); color: var(--banner-text); padding: 0.75rem 1rem; border-radius: 8px; display: flex; align-items: center; gap: 0.5rem; margin-bottom: 2rem; font-size: 0.875rem; font-weight: 500; border: 1px solid var(--border-color); max-width: fit-content; } /* User Badge */ .user-badge { display: flex; align-items: center; gap: 8px; padding: 6px 12px; background: var(--bg-card); /* Changed from --surface */ border: 1px solid var(--border-color); /* Changed from --border */ border-radius: 20px; font-size: 0.9rem; font-weight: 500; } .icon-btn-small { background: none; border: none; padding: 4px; cursor: pointer; color: var(--text-secondary); /* Changed from --text-muted */ display: flex; align-items: center; justify-content: center; border-radius: 50%; transition: all 0.2s; } .icon-btn-small:hover { color: var(--error-color); /* Changed from --danger */ background: rgba(239, 68, 68, 0.1); } /* Modal */ .modal { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0, 0, 0, 0.5); backdrop-filter: blur(4px); display: flex; align-items: center; justify-content: center; z-index: 1000; transition: all 0.3s; } .modal.hidden { opacity: 0; pointer-events: none; } .modal-content { background: var(--bg-card); width: 90%; max-width: 400px; border-radius: 16px; box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04); overflow: hidden; animation: modalSlide 0.3s ease-out; } /* History Modal specific */ .history-modal-content { max-width: 600px; max-height: 85vh; display: flex; flex-direction: column; } .history-modal-content .modal-body { overflow-y: auto; padding: 0; /* Padding is handled by inner elements */ } /* History Styles */ .history-year-group { margin-bottom: 16px; } .history-year-header { background: var(--bg-card); padding: 12px 20px; margin: 0; font-size: 1.2rem; font-weight: 700; color: var(--text-primary); border-bottom: 2px solid var(--border-color); position: sticky; top: 0; z-index: 12; } .history-month-group { border-bottom: 1px solid var(--border-color); } .history-month-header { display: flex; justify-content: space-between; align-items: center; padding: 14px 20px; margin: 0; font-size: 1.05rem; font-weight: 600; color: var(--text-primary); background: var(--bg-body); cursor: pointer; transition: background 0.2s; } .history-month-header:hover { background: var(--border-color); /* Slight hover effect */ } .history-month-summary { display: flex; align-items: center; gap: 12px; font-size: 0.95rem; color: var(--text-secondary); } .history-month-content { display: none; /* Collapsed by default */ background: var(--bg-card); } .history-month-group.open .history-month-content { display: block; /* Expanded when open class is present */ } .history-month-group.open .history-month-header .material-icons-round { transform: rotate(180deg); } .history-month-header .material-icons-round { transition: transform 0.3s; font-size: 20px; } .history-week-group { padding: 12px 20px; border-bottom: 1px dashed var(--border-color); } .history-week-group:last-child { border-bottom: none; } .history-week-header { display: flex; justify-content: space-between; align-items: center; font-size: 0.9rem; font-weight: 600; color: var(--text-secondary); margin-bottom: 10px; } .history-week-summary { font-size: 0.85rem; font-weight: 500; background: rgba(100, 116, 139, 0.1); padding: 4px 10px; border-radius: 12px; } .history-items { display: flex; flex-direction: column; gap: 8px; } .history-item { display: grid; grid-template-columns: 50px 1fr auto; align-items: center; gap: 12px; padding: 10px 12px; background: var(--bg-body); border-radius: 8px; border: 1px solid var(--border-color); } .history-item-date { font-size: 0.85rem; color: var(--text-secondary); font-weight: 500; } .history-item-details { display: flex; flex-direction: column; gap: 4px; } .history-item-name { font-size: 0.95rem; font-weight: 500; color: var(--text-primary); } .history-item-price { font-weight: 600; color: var(--text-primary); } .history-item-status { font-size: 0.8rem; font-weight: 600; color: var(--text-primary); text-transform: uppercase; letter-spacing: 0.5px; } .history-item-cancelled { opacity: 0.5; filter: grayscale(1); } .history-item-price-cancelled { text-decoration: line-through; color: var(--text-secondary); } @keyframes modalSlide { from { transform: translateY(20px); opacity: 0; } to { transform: translateY(0); opacity: 1; } } .modal-header { display: flex; align-items: center; justify-content: space-between; padding: 20px; border-bottom: 1px solid var(--border-color); } .modal-header h2 { margin: 0; font-size: 1.25rem; } .modal-body { padding: 20px; } #login-form { padding: 20px; } .form-group { margin-bottom: 20px; } .form-group label { display: block; margin-bottom: 6px; font-weight: 500; font-size: 0.9rem; } .form-group input { width: 100%; padding: 10px 12px; border: 1px solid var(--border-color); /* Changed from --border */ border-radius: 8px; background: var(--bg-body); /* Changed from --bg */ color: var(--text-primary); /* Changed from --text */ font-family: inherit; transition: border-color 0.2s; } .form-group input:focus { outline: none; border-color: var(--accent-color); /* Changed from --primary */ } .help-text { display: block; margin-top: 4px; color: var(--text-secondary); /* Changed from --text-muted */ font-size: 0.75rem; } .error-msg { margin-bottom: 16px; padding: 10px; background: rgba(239, 68, 68, 0.1); color: var(--error-color); /* Changed from --danger */ border-radius: 8px; font-size: 0.85rem; text-align: center; } .modal-actions { margin-top: 24px; } .btn-primary.wide { width: 100%; justify-content: center; } .hidden { display: none !important; } /* Menu Grid Container */ .menu-grid { display: flex; flex-direction: column; flex: 1; overflow: hidden; gap: 1rem; } .week-section { margin-bottom: 2rem; } .week-header { margin-bottom: 1.5rem; border-bottom: 1px solid var(--border-color); padding-bottom: 1rem; text-align: center; } .week-title { font-size: 1.75rem; font-weight: 700; color: var(--text-primary); } .week-range { color: var(--text-secondary); font-size: 0.9rem; margin-top: 0.25rem; } /* Full-viewport layout: header + scrollable content + footer */ #kantine-wrapper { display: flex; flex-direction: column; height: 100vh; height: 100dvh; /* Dynamic viewport height for mobile browsers */ overflow: hidden; } .days-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 0.75rem; flex: 1; overflow-y: auto; /* This is the scroll container at the window edge */ align-content: start; padding: 0 2rem 2rem 2rem; } /* Card */ .menu-card { background-color: var(--bg-card); border-radius: 12px; border: 1px solid var(--border-color); box-shadow: var(--card-shadow); overflow: clip; /* Clips scrolling content behind sticky header */ transition: box-shadow 0.2s ease; display: flex; flex-direction: column; } /* Past Day Styling - Target specific elements so ordered items can remain visible AND preserve sticky context */ /* We MUST apply filter/opacity to children, not the parent .menu-card, or else position: sticky breaks */ /* Header keeps fully opaque background to hide scrolling items, only grayscales */ .menu-card.past-day .card-header { filter: grayscale(0.8); transition: filter 0.3s; } /* Items become semi-transparent */ .menu-card.past-day .menu-item:not(.ordered) { opacity: 0.6; filter: grayscale(0.8); transition: opacity 0.3s, filter 0.3s; } .menu-card.past-day:hover .card-header { filter: grayscale(0.4); } .menu-card.past-day:hover .menu-item:not(.ordered) { opacity: 0.8; filter: grayscale(0.4); } /* Past ordered items get no special frame or shadow, but remain visually distinct by staying fully opaque (via the :not(.ordered) selector above) */ .menu-item.today-ordered { border: 2px solid #8b5cf6; box-shadow: 0 0 30px rgba(139, 92, 246, 0.6); border-radius: 8px; padding: 1rem; margin: 0 -1rem 1.5rem -1rem; background: var(--bg-card); position: relative; z-index: 5; animation: pulse-glow-strong 3s infinite; } @keyframes pulse-glow-strong { 0% { box-shadow: 0 0 20px rgba(139, 92, 246, 0.4); } 50% { box-shadow: 0 0 40px rgba(139, 92, 246, 0.8); } 100% { box-shadow: 0 0 20px rgba(139, 92, 246, 0.4); } } .menu-card:hover { box-shadow: 0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1); } .card-header { padding: 1rem 1.25rem; border-bottom: 1px solid var(--border-color); display: flex; justify-content: space-between; align-items: baseline; background-color: var(--bg-card); /* Removed border-radius: 12px 12px 0 0; .menu-card\'s overflow: clip will round the corners initially. When sticky at the top, it will be square and perfectly hide scrolling content! */ /* Sticky within .container scroll area */ position: sticky; top: 0; z-index: 90; } .card-body { padding: 1.25rem; display: grid; grid-template-rows: auto; align-content: start; } .day-name { font-size: 1.125rem; font-weight: 600; } .day-date { font-size: 0.875rem; color: var(--text-secondary); } .empty-state { color: var(--text-secondary); font-style: italic; text-align: center; padding: 1rem; } /* Menu Items */ .menu-item { margin-bottom: 1.5rem; padding-bottom: 1.5rem; border-bottom: 1px solid var(--border-color); } .menu-item:last-child { margin-bottom: 0; padding-bottom: 0; border-bottom: none; } .item-header { display: flex; justify-content: space-between; align-items: flex-start; margin-bottom: 0.5rem; gap: 1rem; } .item-name { font-weight: 600; color: var(--text-primary); font-size: 1rem; } .item-price { font-weight: 700; color: var(--accent-color); white-space: nowrap; } .item-desc { font-size: 0.875rem; color: var(--text-secondary); line-height: 1.6; margin-bottom: 0.75rem; white-space: pre-wrap; } .badges { display: flex; gap: 0.5rem; margin-left: auto; } .item-status-row { display: flex; align-items: center; gap: 0.5rem; margin-bottom: 0.75rem; } .badge { display: inline-flex; align-items: center; justify-content: center; height: 24px; font-size: 0.75rem; padding: 0 10px; border-radius: 4px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.05em; line-height: normal; white-space: nowrap; } .badge.available { background-color: rgba(16, 185, 129, 0.1); /* Emerald 500 / 10% */ color: var(--success-color); border: 1px solid rgba(16, 185, 129, 0.2); } .badge.sold-out { background-color: rgba(239, 68, 68, 0.1); /* Red 500 / 10% */ color: var(--error-color); border: 1px solid rgba(239, 68, 68, 0.2); } .badge.ordered { background-color: rgba(139, 92, 246, 0.1); /* Violet 500 / 10% */ color: #8b5cf6; border: 1px solid rgba(139, 92, 246, 0.2); gap: 4px; } .badge.ordered .material-icons-round { font-size: 1rem; } /* Loading */ .loading-state { text-align: center; padding: 4rem; color: var(--text-secondary); } .spinner { width: 40px; height: 40px; border: 3px solid var(--border-color); border-top-color: var(--accent-color); border-radius: 50%; margin: 0 auto 1rem; animation: spin 1s linear infinite; } @keyframes spin { to { transform: rotate(360deg); } } /* Footer */ .app-footer { flex-shrink: 0; text-align: center; padding: 0.4rem 2rem; color: var(--text-secondary); font-size: 0.8rem; border-top: 1px solid var(--border-color); } /* === Order / Cancel Buttons (inline in status row) === */ .btn-order { display: inline-flex; align-items: center; gap: 4px; padding: 4px 10px; border: none; border-radius: 6px; background: var(--success-color); color: white; font-size: 0.75rem; font-weight: 600; cursor: pointer; transition: all 0.2s ease; font-family: inherit; } .btn-order .material-icons-round { font-size: 16px; } .btn-order:hover:not(:disabled) { filter: brightness(1.15); transform: translateY(-1px); } .btn-order:disabled { opacity: 0.5; cursor: not-allowed; } .btn-order.loading { pointer-events: none; opacity: 0.6; } .btn-order-compact { padding: 2px 4px; gap: 0; } .btn-order-compact .material-icons-round { font-size: 16px; } .btn-cancel { display: inline-flex; align-items: center; justify-content: center; padding: 4px 6px; border: none; border-radius: 6px; background: var(--error-color); color: white; font-size: 0.75rem; cursor: pointer; transition: all 0.2s ease; font-family: inherit; } .btn-cancel .material-icons-round { font-size: 16px; } .btn-cancel:hover:not(:disabled) { filter: brightness(1.15); transform: translateY(-1px); } .btn-cancel:disabled { opacity: 0.5; cursor: not-allowed; } /* Past days: hide action buttons */ .past-day .item-actions { display: none; } /* Order count badge (for multi-orders) */ .order-count-badge { display: inline-flex; align-items: center; justify-content: center; background: rgba(255, 255, 255, 0.3); color: white; font-size: 0.65rem; font-weight: 700; min-width: 16px; height: 16px; padding: 0 4px; border-radius: 8px; margin-left: 4px; line-height: 1; } /* === Toast Notifications === */ #toast-container { position: fixed; bottom: 20px; right: 20px; z-index: 10000; display: flex; flex-direction: column; gap: 8px; pointer-events: none; } .toast { display: flex; align-items: center; gap: 8px; padding: 10px 16px; border-radius: 8px; font-size: 0.85rem; font-weight: 500; font-family: \'Inter\', sans-serif; color: white; backdrop-filter: blur(10px); box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3); pointer-events: auto; transform: translateX(120%); opacity: 0; transition: transform 0.3s ease, opacity 0.3s ease; } .toast.show { transform: translateX(0); opacity: 1; } .toast .material-icons-round { font-size: 18px; } .toast-success { background: rgba(5, 150, 105, 0.95); } .toast-error { background: rgba(220, 38, 38, 0.95); } .toast-info { background: rgba(59, 130, 246, 0.95); } /* === Mobile Responsiveness === */ @media (max-width: 600px) { .header-content { flex-direction: column; gap: 1rem; padding: 0.75rem; } .week-nav { width: 100%; justify-content: center; } .nav-pills { width: 100%; justify-content: space-between; } .nav-btn { flex: 1; justify-content: center; padding: 0.5rem; font-size: 0.85rem; } .days-grid { grid-template-columns: 1fr; /* Force single column */ } .main-content { padding: 1rem; } .week-title { font-size: 1.5rem; } /* Adjust toast position for mobile */ .toast-container { bottom: 1rem; right: 1rem; left: 1rem; /* Center on mobile */ width: auto; } .menu-card { margin-bottom: 1rem; } } /* === Flagging & Notification Styles === */ .btn-flag { display: inline-flex; align-items: center; justify-content: center; background: transparent; border: 1px solid var(--text-secondary); color: var(--text-secondary); border-radius: 6px; padding: 4px; cursor: pointer; transition: all 0.2s; margin-right: 0.5rem; width: 28px; height: 28px; } .btn-flag:hover { background: rgba(234, 179, 8, 0.1); /* Yellow-500 / 10% */ color: #eab308; border-color: #eab308; } .btn-flag.active { background: rgba(234, 179, 8, 0.1); color: #eab308; border-color: #eab308; } .btn-flag .material-icons-round { font-size: 1.1rem; } /* Flagged & Sold Out (Yellow Glow) */ .menu-item.flagged-sold-out { border: 1px solid #eab308; box-shadow: 0 0 10px rgba(234, 179, 8, 0.2); border-radius: 8px; padding: 1rem; margin: 0 -1rem 1.5rem -1rem; background: var(--bg-card); position: relative; z-index: 5; animation: yellow-pulse 3s infinite; } @keyframes yellow-pulse { 0% { box-shadow: 0 0 8px rgba(234, 179, 8, 0.2); } 50% { box-shadow: 0 0 16px rgba(234, 179, 8, 0.5); } 100% { box-shadow: 0 0 8px rgba(234, 179, 8, 0.2); } } /* Flagged & Available (Green Glow) */ .menu-item.flagged-available { border: 2px solid var(--success-color); box-shadow: 0 0 15px rgba(16, 185, 129, 0.3); border-radius: 8px; padding: 1rem; margin: 0 -1rem 1.5rem -1rem; background: var(--bg-card); position: relative; z-index: 5; animation: green-pulse 3s infinite; } @keyframes green-pulse { 0% { box-shadow: 0 0 10px rgba(16, 185, 129, 0.3); } 50% { box-shadow: 0 0 20px rgba(16, 185, 129, 0.6); } 100% { box-shadow: 0 0 10px rgba(16, 185, 129, 0.3); } } /* Day Header Badges */ .day-header-left { display: flex; align-items: center; gap: 0.75rem; } .menu-code-badge { font-size: 0.75rem; font-weight: 700; color: #8b5cf6; /* Violet 500 */ background-color: rgba(139, 92, 246, 0.15); border: 1px solid rgba(139, 92, 246, 0.3); padding: 2px 6px; border-radius: 6px; line-height: normal; display: inline-block; } /* Detailed Badge Colors */ .nav-badge.badge-violet { background-color: #8b5cf6; } .nav-badge.badge-green { background-color: var(--success-color); } .nav-badge.badge-red { background-color: var(--error-color); } .nav-badge.badge-blue { background-color: var(--accent-color); } /* Day Header Status Colors (User Request) */ .card-header.header-violet { background-color: var(--bg-card); background-image: linear-gradient(rgba(139, 92, 246, 0.15), rgba(139, 92, 246, 0.15)); border-bottom: 2px solid #8b5cf6; } .card-header.header-green { background-color: var(--bg-card); background-image: linear-gradient(rgba(16, 185, 129, 0.15), rgba(16, 185, 129, 0.15)); border-bottom: 2px solid var(--success-color); } .card-header.header-red { background-color: var(--bg-card); background-image: linear-gradient(rgba(239, 68, 68, 0.15), rgba(239, 68, 68, 0.15)); border-bottom: 2px solid var(--error-color); } .card-header.header-violet .day-name, .card-header.header-green .day-name, .card-header.header-red .day-name { font-weight: 700; color: var(--text-primary); /* Ensure text remains standard color */ } /* Update Icon */ .update-icon { display: inline-flex; align-items: center; justify-content: center; margin-left: 8px; background-color: rgba(16, 185, 129, 0.2); /* Green tint */ color: var(--success-color); border-radius: 50%; width: 24px; height: 24px; cursor: pointer; font-size: 14px; transition: all 0.2s; text-decoration: none; animation: pulse 2s infinite; } .update-icon:hover { background-color: var(--success-color); color: white; transform: scale(1.1); } @keyframes pulse { 0% { box-shadow: 0 0 0 0 rgba(16, 185, 129, 0.4); } 70% { box-shadow: 0 0 0 6px rgba(16, 185, 129, 0); } 100% { box-shadow: 0 0 0 0 rgba(16, 185, 129, 0); } } /* Order Countdown */ #order-countdown { background: rgba(255, 255, 255, 0.1); padding: 0.25rem 0.75rem; border-radius: 99px; font-size: 0.85rem; display: flex; align-items: center; gap: 0.5rem; white-space: nowrap; border: 1px solid var(--border-color); } #order-countdown span { opacity: 0.7; font-size: 0.75rem; text-transform: uppercase; letter-spacing: 0.5px; } #order-countdown.urgent { background: rgba(239, 68, 68, 0.2); border-color: rgba(239, 68, 68, 0.5); color: #ef4444; animation: pulse-red 2s infinite; } @keyframes pulse-red { 0% { box-shadow: 0 0 0 0 rgba(239, 68, 68, 0.4); } 70% { box-shadow: 0 0 0 6px rgba(239, 68, 68, 0); } 100% { box-shadow: 0 0 0 0 rgba(239, 68, 68, 0); } } /* Smart Highlights (Blue Glow - matches today-ordered/flagged pattern) */ .menu-item.highlight-glow { border: 2px solid rgba(59, 130, 246, 0.7); box-shadow: 0 0 20px rgba(59, 130, 246, 0.4); border-radius: 8px; padding: 1rem; margin: 0 -1rem 1.5rem -1rem; background: var(--bg-card); position: relative; z-index: 5; animation: blue-pulse 3s infinite; } @keyframes blue-pulse { 0% { box-shadow: 0 0 15px rgba(59, 130, 246, 0.3); } 50% { box-shadow: 0 0 25px rgba(59, 130, 246, 0.6); } 100% { box-shadow: 0 0 15px rgba(59, 130, 246, 0.3); } } /* Nav Badge with Count */ .nav-badge.has-highlights { background-color: var(--bg-card); /* Neutral background */ color: var(--text-primary); border: 1px solid var(--border-color); padding: 2px 6px; } .nav-badge .highlight-count { color: #3b82f6; /* Blue 500 */ font-weight: 700; margin-left: 4px; } /* Tag Management Modal */ #tags-list { display: flex; flex-wrap: wrap; gap: 0.5rem; margin-top: 1rem; min-height: 50px; } /* Tag badges styled consistently with .badge (verfügbar/ausverkauft) */ .tag-badge { display: inline-flex; align-items: center; justify-content: center; height: 24px; font-size: 0.75rem; padding: 0 10px; border-radius: 4px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.05em; line-height: normal; white-space: nowrap; background-color: rgba(59, 130, 246, 0.1); color: #3b82f6; border: 1px solid rgba(59, 130, 246, 0.2); gap: 4px; } .tag-remove { cursor: pointer; opacity: 0.7; font-size: 1.1em; line-height: 1; transition: all 0.2s; } .tag-remove:hover { opacity: 1; color: #ef4444; } .input-group { display: flex; gap: 0.5rem; } .input-group input { flex: 1; padding: 0.75rem; background: var(--bg-body); border: 1px solid var(--border-color); color: var(--text-primary); border-radius: 8px; font-family: inherit; } /* Add tag button - styled like .btn-order with nav-btn.active color */ #btn-add-tag { display: inline-flex; align-items: center; gap: 4px; padding: 0.5rem 1rem; border: none; border-radius: 6px; background: var(--accent-color); color: white; font-size: 0.8rem; font-weight: 600; cursor: pointer; transition: all 0.2s ease; font-family: inherit; white-space: nowrap; } #btn-add-tag:hover { filter: brightness(1.15); transform: translateY(-1px); } .matched-tags { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 8px; /* Space between tags and title */ margin-top: -5px; /* Pull closer to header */ } .tag-badge-small { display: inline-flex; align-items: center; font-size: 0.7rem; padding: 2px 8px; border-radius: 4px; background: rgba(59, 130, 246, 0.15); color: #60a5fa; border: 1px solid rgba(59, 130, 246, 0.3); font-weight: 600; text-transform: uppercase; letter-spacing: 0.05em; } [data-theme="light"] .tag-badge-small { background: rgba(37, 99, 235, 0.1); color: #2563eb; border: 1px solid rgba(37, 99, 235, 0.2); } /* Installer Changelog */ .changelog-container ul { padding-left: 1.5rem; margin: 0.5rem 0; } .changelog-container li { margin-bottom: 0.4rem; line-height: 1.5; } .changelog-container h3 { margin-top: 1.5rem; margin-bottom: 0.5rem; font-size: 1.1em; color: var(--accent-color); } /* === Version Menu === */ .version-tag { cursor: pointer; transition: opacity 0.2s ease, text-decoration 0.2s ease; } .version-tag:hover { opacity: 1 !important; text-decoration: underline; } .version-list { list-style: none; padding: 0; margin: 0; } .version-item { display: flex; justify-content: space-between; align-items: center; padding: 10px 14px; border-radius: 8px; margin-bottom: 4px; transition: background 0.2s; } .version-item:hover { background: rgba(100, 116, 139, 0.08); } .version-item.current { background: rgba(2, 154, 168, 0.1); border: 1px solid rgba(2, 154, 168, 0.25); } [data-theme="dark"] .version-item:hover { background: rgba(255, 255, 255, 0.05); } [data-theme="dark"] .version-item.current { background: rgba(96, 165, 250, 0.12); border: 1px solid rgba(96, 165, 250, 0.25); } .version-info { display: flex; align-items: center; gap: 10px; } .badge-current { font-size: 0.75rem; font-weight: 600; color: var(--success-color); padding: 2px 8px; border-radius: 4px; background: rgba(5, 150, 105, 0.1); } .badge-new { font-size: 0.75rem; font-weight: 600; color: #029aa8; padding: 2px 8px; border-radius: 4px; background: rgba(2, 154, 168, 0.1); } [data-theme="dark"] .badge-new { color: #60a5fa; background: rgba(96, 165, 250, 0.12); } .install-link { font-size: 0.8rem; font-weight: 500; padding: 4px 12px; border-radius: 6px; background: rgba(2, 154, 168, 0.1); color: #029aa8; text-decoration: none; border: 1px solid rgba(2, 154, 168, 0.25); transition: all 0.2s; white-space: nowrap; } .install-link:hover { background: rgba(2, 154, 168, 0.2); border-color: rgba(2, 154, 168, 0.4); } [data-theme="dark"] .install-link { color: #60a5fa; background: rgba(96, 165, 250, 0.12); border: 1px solid rgba(96, 165, 250, 0.25); } [data-theme="dark"] .install-link:hover { background: rgba(96, 165, 250, 0.2); border-color: rgba(96, 165, 250, 0.4); } .dev-toggle { padding: 10px 14px; border-radius: 8px; background: rgba(100, 116, 139, 0.05); border: 1px solid var(--border-color); } .dev-toggle input[type="checkbox"] { accent-color: #029aa8; width: 16px; height: 16px; } [data-theme="dark"] .dev-toggle input[type="checkbox"] { accent-color: #60a5fa; } ';document.head.appendChild(s); // Inject JS logic var sc=document.createElement('script'); sc.textContent="(()=>{\"use strict\";var e={367(e,t,n){n.d(t,{A0:()=>f,Aq:()=>m,BM:()=>L,Et:()=>w,Gb:()=>d,H:()=>y,KG:()=>D,N4:()=>h,P0:()=>T,PQ:()=>v,VL:()=>x,Y1:()=>E,g8:()=>b,i_:()=>c,m9:()=>O,oL:()=>A,wH:()=>g});var a=n(901),s=n(413),o=n(521),i=n(672),r=n(842);let l=null;function c(){if(!a.gX)try{const e=localStorage.getItem(\"AkitaStores\");if(e){const t=JSON.parse(e);t.auth&&t.auth.token&&((0,a.O5)(t.auth.token),localStorage.setItem(\"kantine_authToken\",t.auth.token),t.auth.user&&((0,a.lt)(t.auth.user.id||\"unknown\"),localStorage.setItem(\"kantine_currentUser\",t.auth.user.id||\"unknown\"),t.auth.user.firstName&&localStorage.setItem(\"kantine_firstName\",t.auth.user.firstName),t.auth.user.lastName&&localStorage.setItem(\"kantine_lastName\",t.auth.user.lastName)))}}catch(e){console.warn(\"Failed to parse AkitaStores:\",e)}(0,a.O5)(localStorage.getItem(\"kantine_authToken\")),(0,a.lt)(localStorage.getItem(\"kantine_currentUser\"));const e=localStorage.getItem(\"kantine_firstName\"),t=document.getElementById(\"btn-login-open\"),n=document.getElementById(\"user-info\"),s=document.getElementById(\"user-id-display\");a.gX?(t.classList.add(\"hidden\"),n.classList.remove(\"hidden\"),s.textContent=e||(a.Ny?`User ${a.Ny}`:\"Angemeldet\"),d()):(t.classList.remove(\"hidden\"),n.classList.add(\"hidden\"),s.textContent=\"\"),(0,r.OR)()}async function d(){if(a.gX)try{const e=await fetch(`${o.tE}/user/orders/?venue=${o.eW}&ordering=-created&limit=50`,{headers:(0,i.H)(a.gX)}),t=await e.json();if(e.ok){const e=new Map,n=t.results||[];for(const t of n){if(9===t.order_state)continue;const n=t.date.split(\"T\")[0];for(const a of t.items||[]){const s=`${n}_${a.article}`;e.has(s)||e.set(s,[]),e.get(s).push(t.id)}}(0,a.di)(e),(0,r.OR)(),(0,r.gJ)()}}catch(e){console.error(\"Error fetching orders:\",e)}}async function m(){const e=document.getElementById(\"history-loading\"),t=document.getElementById(\"history-content\"),n=document.getElementById(\"history-progress-fill\"),s=document.getElementById(\"history-progress-text\");let r=[];if(l)r=l;else{const e=localStorage.getItem(\"kantine_history_cache\");if(e)try{r=JSON.parse(e),l=r}catch(e){console.warn(\"History cache parse error\",e)}}if(r.length>0&&u(r),!a.gX)return;0===r.length&&(t.innerHTML=\"\",e.classList.remove(\"hidden\")),n.style.width=\"0%\",s.textContent=r.length>0?\"Suche nach neuen Bestellungen...\":\"Lade Bestellhistorie...\",r.length>0&&e.classList.remove(\"hidden\");let c=r.length>0?`${o.tE}/user/orders/?venue=${o.eW}&ordering=-created&limit=5`:`${o.tE}/user/orders/?venue=${o.eW}&ordering=-created&limit=50`,d=[],m=0,g=0===r.length,h=!1;try{for(;c&&!h;){const e=await fetch(c,{headers:(0,i.H)(a.gX)});if(!e.ok)throw new Error(`Fetch failed: ${e.status}`);const t=await e.json();t.count&&0===m&&(m=t.count);const o=t.results||[];for(const e of o){const t=r.findIndex(t=>t.id===e.id);if(!g&&-1!==t){const n=r[t];if(n.updated===e.updated&&n.order_state===e.order_state){h=!0;break}}d.push(e)}if(!h&&g)if(m>0){const e=Math.round(d.length/m*100);n.style.width=`${e}%`,s.textContent=`Lade Bestellung ${d.length} von ${m}...`}else s.textContent=`Lade Bestellung ${d.length}...`;else h||(s.textContent=`${d.length} neue/ge\u00e4nderte Bestellungen gefunden...`);c=h?null:t.next}if(d.length>0){const e=new Map(r.map(e=>[e.id,e]));for(const t of d)e.set(t.id,t);const t=Array.from(e.values());t.sort((e,t)=>new Date(t.created)-new Date(e.created)),l=t;try{localStorage.setItem(\"kantine_history_cache\",JSON.stringify(t))}catch(e){console.warn(\"History cache write error\",e)}u(l)}}catch(e){console.error(\"Error in history sync:\",e),0===r.length?t.innerHTML='
Fehler beim Laden der Historie.
':T(\"Hintergrund-Synchronisation fehlgeschlagen\",\"error\")}finally{e.classList.add(\"hidden\")}}function u(e){const t=document.getElementById(\"history-content\");if(!e||0===e.length)return void(t.innerHTML='Keine Bestellungen gefunden.
');const n={};e.forEach(e=>{const t=new Date(e.date),a=t.getFullYear(),o=t.getMonth(),i=`${a}-${o.toString().padStart(2,\"0\")}`,r=t.toLocaleString(\"de-AT\",{month:\"long\"}),l=(0,s.sn)(t);n[a]||(n[a]={year:a,months:{}}),n[a].months[i]||(n[a].months[i]={name:r,year:a,monthIndex:o,count:0,total:0,weeks:{}}),n[a].months[i].weeks[l]||(n[a].months[i].weeks[l]={label:`KW ${l}`,items:[],count:0,total:0});(e.items||[]).forEach(t=>{const s=parseFloat(t.price||e.total||0);n[a].months[i].weeks[l].items.push({date:e.date,name:t.name||\"Men\u00fc\",price:s,state:e.order_state}),9!==e.order_state&&(n[a].months[i].weeks[l].count++,n[a].months[i].weeks[l].total+=s,n[a].months[i].count++,n[a].months[i].total+=s)})});const a=Object.keys(n).sort((e,t)=>t-e);let o=\"\";a.forEach(e=>{const t=n[e];o+=`{const t=e.date;let n=null;try{const a=await fetch(`${o.tE}/venues/${o.eW}/menu/${o.YU}/${t}/`,{headers:(0,i.H)(u)});if(a.ok){const s=(await a.json()).results||[];let o=[];for(const e of s)e.items&&Array.isArray(e.items)&&(o=o.concat(e.items));o.length>0&&(n={date:t,menu_items:o,orders:e.orders||[]})}}catch(e){console.error(`Failed to fetch details for ${t}:`,e)}finally{v++;const e=Math.round(v/p*100);l.style.width=`${e}%`,d.textContent=`${e}%`,m.textContent=`Lade Men\u00fc f\u00fcr ${t}...`}return n}));for(const e of a)e&&f.push(e)}const b=new Map;a.p_&&a.p_.length>0&&a.p_.forEach(e=>{const t=`${e.year}-${e.weekNumber}`;try{b.set(t,{year:e.year,weekNumber:e.weekNumber,days:e.days?e.days.map(e=>({...e,items:e.items?[...e.items]:[]})):[]})}catch(e){console.warn(\"Error hydrating week:\",e)}});for(const e of f){const t=new Date(e.date),n=(0,s.sn)(t),a=(0,s.Ao)(t),o=`${a}-${n}`;b.has(o)||b.set(o,{year:a,weekNumber:n,days:[]});const i=b.get(o),r=t.toLocaleDateString(\"en-US\",{weekday:\"long\"}),l=new Date(e.date);l.setHours(10,0,0,0);const c={date:e.date,weekday:r,orderCutoff:l.toISOString(),items:e.menu_items.map(t=>{const n=!1===t.amount_tracking,a=parseInt(t.available_amount)>0;return{id:`${e.date}_${t.id}`,articleId:t.id,name:t.name||\"Unknown\",description:t.description||\"\",price:parseFloat(t.price)||0,available:n||a,availableAmount:parseInt(t.available_amount)||0,amountTracking:!1!==t.amount_tracking}})},d=i.days.findIndex(t=>t.date===e.date);d>=0?i.days[d]=c:i.days.push(c)}const w=Array.from(b.values()).sort((e,t)=>e.year!==t.year?e.year-t.year:e.weekNumber-t.weekNumber);w.forEach(e=>{e.days&&e.days.sort((e,t)=>e.date.localeCompare(t.date))}),(0,a.tn)(w),S(),N((new Date).toISOString()),(0,a.Xt)((0,s.sn)(new Date)),(0,a.pK)((new Date).getFullYear()),c(),(0,r.OR)(),(0,r.gJ)(),(0,r.Mb)(),m.textContent=\"Fertig!\",setTimeout(()=>t.classList.add(\"hidden\"),500)}catch(e){console.error(\"Error fetching menu:\",e),t.classList.add(\"hidden\"),Promise.resolve().then(n.bind(n,842)).then(t=>{t.showErrorModal(\"Keine Verbindung\",`Die Men\u00fcdaten konnten nicht geladen werden. M\u00f6glicherweise besteht keine Verbindung zur API oder zur Bessa-Webseite.
${(0,s.ZD)(e.message)}`,\"Zur Original-Seite\",\"https://web.bessa.app/knapp-kantine\")})}finally{e.classList.add(\"hidden\")}}let C=null,M=null;function N(e){const t=document.getElementById(\"last-updated-subtitle\");if(e){C=e,localStorage.setItem(\"kantine_last_updated\",e),localStorage.setItem(\"kantine_last_checked\",e);try{const n=new Date(e),a=n.toLocaleTimeString(\"de-DE\",{hour:\"2-digit\",minute:\"2-digit\"}),o=n.toLocaleDateString(\"de-DE\",{day:\"2-digit\",month:\"2-digit\"}),i=(0,s.gs)(n);t.textContent=`Aktualisiert: ${o} ${a} (${i})`}catch(e){t.textContent=\"\"}M||(M=setInterval(()=>{C&&(N(C),(0,r.Mb)())},6e4))}}function T(e,t=\"info\"){let n=document.getElementById(\"toast-container\");n||(n=document.createElement(\"div\"),n.id=\"toast-container\",document.body.appendChild(n));const a=document.createElement(\"div\");a.className=`toast toast-${t}`;const o=\"success\"===t?\"check_circle\":\"error\"===t?\"error\":\"info\";a.innerHTML=`${(0,s.ZD)(e)}`,n.appendChild(a),requestAnimationFrame(()=>a.classList.add(\"show\")),setTimeout(()=>{a.classList.remove(\"show\"),setTimeout(()=>a.remove(),300)},3e3)}},672(e,t,n){n.d(t,{H:()=>s,O:()=>o});var a=n(521);function s(e){return{Authorization:`Token ${e||a.f9}`,Accept:\"application/json\",\"Content-Type\":\"application/json\",\"X-Client-Version\":a.fZ}}function o(){return{Accept:\"application/vnd.github.v3+json\"}}},521(e,t,n){n.d(t,{YU:()=>r,d_:()=>m,eW:()=>i,f9:()=>s,fZ:()=>o,fv:()=>l,pe:()=>d,tE:()=>a});const a=\"https://api.bessa.app/v1\",s=\"c3418725e95a9f90e3645cbc846b4d67c7c66131\",o=\"v1.6.11\",i=591,r=7,l=3e5,c=\"TauNeutrino/kantine-overview\",d=`https://api.github.com/repos/${c}`,m=`https://htmlpreview.github.io/?https://github.com/${c}/blob`},901(e,t,n){n.d(t,{BT:()=>o,BY:()=>m,K8:()=>u,Kl:()=>g,L:()=>d,Ny:()=>c,O5:()=>b,UD:()=>E,Xt:()=>f,cc:()=>A,di:()=>k,gX:()=>l,iw:()=>L,lt:()=>w,pK:()=>v,p_:()=>s,qo:()=>y,sw:()=>r,tn:()=>p,vW:()=>i,yz:()=>h});var a=n(413);let s=[],o=(0,a.sn)(new Date),i=(new Date).getFullYear(),r=\"this-week\",l=localStorage.getItem(\"kantine_authToken\"),c=localStorage.getItem(\"kantine_currentUser\"),d=new Map,m=new Set(JSON.parse(localStorage.getItem(\"kantine_flags\")||\"[]\")),u=null,g=localStorage.getItem(\"kantine_lang\")||\"de\",h=JSON.parse(localStorage.getItem(\"kantine_highlightTags\")||\"[]\");function p(e){s=e}function f(e){o=e}function v(e){i=e}function y(e){r=e}function b(e){l=e}function w(e){c=e}function k(e){d=e}function A(e){u=e}function E(e){g=e}function L(e){h=e}},842(e,t,n){n.d(t,{Gk:()=>u,Mb:()=>f,OR:()=>c,Ux:()=>m,gJ:()=>l,showErrorModal:()=>p});var a=n(901),s=n(413),o=n(521),i=n(672),r=n(367);function l(){const e=document.getElementById(\"btn-next-week\");let t=a.BT+1,n=a.vW;t>52&&(t=1,n++);const s=a.p_.find(e=>e.weekNumber===t&&e.year===n);let o=0,i=0,l=0,c=0;s&&s.days&&s.days.forEach(e=>{if(e.items&&e.items.length>0){o++;const t=e.items.some(e=>e.available);t&&i++;let n=!1;e.items.forEach(t=>{const s=t.articleId||parseInt(t.id.split(\"_\")[1]),o=`${e.date}_${s}`;a.L.has(o)&&a.L.get(o).length>0&&(n=!0)}),n&&l++,t&&!n&&c++}});let d=e.querySelector(\".nav-badge\");if(o>0){d||(d=document.createElement(\"span\"),d.className=\"nav-badge\",e.appendChild(d)),d.title=`${l} bestellt / ${i} bestellbar / ${o} gesamt`,d.innerHTML=`${l}/${i}/${o}`,d.classList.remove(\"badge-violet\",\"badge-green\",\"badge-red\",\"badge-blue\"),l>0&&0===c?d.classList.add(\"badge-violet\"):c>0?d.classList.add(\"badge-green\"):0===i?d.classList.add(\"badge-red\"):d.classList.add(\"badge-blue\");let a=0;if(s&&s.days&&s.days.forEach(e=>{e.items.forEach(e=>{const t=(0,r.BM)(e.name),n=(0,r.BM)(e.description);(t.length>0||n.length>0)&&a++})}),a>0&&(d.insertAdjacentHTML(\"beforeend\",`(${a})`),d.title+=` \u2022 ${a} Highlights gefunden`,d.classList.add(\"has-highlights\")),0===l){e.classList.add(\"new-week-available\");const a=`kantine_notified_nextweek_${n}_${t}`;localStorage.getItem(a)||(localStorage.setItem(a,\"true\"),(0,r.P0)(\"Neue Men\u00fcdaten f\u00fcr n\u00e4chste Woche verf\u00fcgbar!\",\"info\"))}else e.classList.remove(\"new-week-available\")}else d&&d.remove()}function c(){const e=document.getElementById(\"menu-container\");if(!e)return;e.innerHTML=\"\";let t=a.BT,n=a.vW;\"next-week\"===a.sw&&(t++,t>52&&(t=1,n++));const o=a.p_.flatMap(e=>e.days||[]).filter(e=>{const a=new Date(e.date);return(0,s.sn)(a)===t&&(0,s.Ao)(a)===n});if(0===o.length)return e.innerHTML=`\\n
Keine Men\u00fcdaten f\u00fcr KW ${t} (${n}) verf\u00fcgbar.
\\n Versuchen Sie eine andere Woche oder schauen Sie sp\u00e4ter vorbei.\\n${(0,s.ZD)((0,s.PC)(t.description))}
`;const k=o.querySelector(\".btn-order\");k&&k.addEventListener(\"click\",e=>{e.stopPropagation();const t=e.currentTarget;t.disabled=!0,t.classList.add(\"loading\"),(0,r.wH)(t.dataset.date,parseInt(t.dataset.article),t.dataset.name,parseFloat(t.dataset.price),t.dataset.desc||\"\").finally(()=>{t.disabled=!1,t.classList.remove(\"loading\")})});const A=o.querySelector(\".btn-cancel\");A&&A.addEventListener(\"click\",e=>{e.stopPropagation();const t=e.currentTarget;t.disabled=!0,(0,r.N4)(t.dataset.date,parseInt(t.dataset.article),t.dataset.name).finally(()=>{t.disabled=!1})});const E=o.querySelector(\".btn-flag\");E&&E.addEventListener(\"click\",e=>{e.stopPropagation();const t=e.currentTarget;(0,r.PQ)(t.dataset.date,parseInt(t.dataset.article),t.dataset.name,t.dataset.cutoff)}),p.appendChild(o)}),t.appendChild(p),t}(e);t&&c.appendChild(t)}),e.appendChild(c),setTimeout(()=>function(e){const t=e.querySelectorAll(\".menu-card\");if(0===t.length)return;let n=0;t.forEach(e=>{n=Math.max(n,e.querySelectorAll(\".menu-item\").length)});for(let e=0;eKeine Versionen gefunden.
');t.innerHTML='Lade Versionen...
';try{const e=localStorage.getItem(\"kantine_version_cache\");let t=null;if(e)try{t=JSON.parse(e)}catch(e){}t&&t.devMode===o&&t.versions&&i(t.versions);const n=await d(o),a=JSON.stringify(n);a!==(t?JSON.stringify(t.versions):\"\")&&(localStorage.setItem(\"kantine_version_cache\",JSON.stringify({timestamp:Date.now(),devMode:o,versions:n})),i(n))}catch(e){t.innerHTML=`Fehler: ${(0,s.ZD)(e.message)}
`}}n.checked=i,r(),n.onchange=()=>{localStorage.setItem(\"kantine_dev_mode\",n.checked),localStorage.removeItem(\"kantine_version_cache\"),r()}}function g(){if(!a.gX||!a.Ny)return void h();const e=new Date,t=e.getDay();if(0===t||6===t)return void h();const n=e.toISOString().split(\"T\")[0];let s=!1;for(const e of a.L.keys())if(e.startsWith(n)){s=!0;break}if(s)return void h();const o=new Date;o.setHours(10,0,0,0);const i=o-e;if(i<=0)return void h();const r=Math.floor(i/36e5),l=Math.floor(i%36e5/6e4),c=document.querySelector(\".header-center-wrapper\");if(!c)return;let d=document.getElementById(\"order-countdown\");if(d||(d=document.createElement(\"div\"),d.id=\"order-countdown\",c.insertBefore(d,c.firstChild)),d.innerHTML=`Bestellschluss: ${r}h ${l}m`,i<36e5){d.classList.add(\"urgent\");const e=`kantine_notified_${n}`;localStorage.getItem(e)||(\"granted\"===Notification.permission?new Notification(\"Kantine: Bestellschluss naht!\",{body:\"Du hast heute noch nichts bestellt. Nur noch 1 Stunde!\",icon:\"\u23f3\"}):\"default\"===Notification.permission&&Notification.requestPermission(),localStorage.setItem(e,\"true\"))}else d.classList.remove(\"urgent\")}function h(){const e=document.getElementById(\"order-countdown\");e&&e.remove()}function p(e,t,n,a){const o=\"error-modal\";let i=document.getElementById(o);i&&i.remove(),i=document.createElement(\"div\"),i.id=o,i.className=\"modal hidden\",i.innerHTML=`\\n \\n `,document.body.appendChild(i),document.getElementById(\"btn-error-redirect\").addEventListener(\"click\",()=>{window.location.href=a}),requestAnimationFrame(()=>{i.classList.remove(\"hidden\")})}function f(){const e=document.getElementById(\"alarm-bell\"),t=document.getElementById(\"alarm-bell-icon\");if(!e||!t)return;if(0===a.BY.size)return e.classList.add(\"hidden\"),e.style.display=\"none\",t.style.color=\"var(--text-secondary)\",void(t.style.textShadow=\"none\");e.classList.remove(\"hidden\"),e.style.display=\"inline-flex\";let n=!1;for(const e of a.p_)if(e.days){for(const t of e.days)if(t.items){for(const e of t.items)if(e.available&&a.BY.has(e.id)){n=!0;break}if(n)break}if(n)break}const o=localStorage.getItem(\"kantine_last_checked\"),i=localStorage.getItem(\"kantine_flagged_items_last_checked\");let r=0;o&&(r=Math.max(r,new Date(o).getTime())),i&&(r=Math.max(r,new Date(i).getTime()));let l=\"gerade eben\";if(0===r){const e=(new Date).toISOString();localStorage.setItem(\"kantine_last_checked\",e),r=new Date(e).getTime()}l=(0,s.gs)(new Date(r)),e.title=`Zuletzt gepr\u00fcft: ${l}`,n?(t.style.color=\"#10b981\",t.style.textShadow=\"0 0 10px rgba(16, 185, 129, 0.4)\"):(t.style.color=\"#f59e0b\",t.style.textShadow=\"0 0 10px rgba(245, 158, 11, 0.4)\")}setInterval(g,6e4),setTimeout(g,1e3)},413(e,t,n){n.d(t,{Ao:()=>o,FS:()=>i,PC:()=>u,U4:()=>l,ZD:()=>r,gs:()=>c,sn:()=>s});var a=n(901);function s(e){const t=new Date(Date.UTC(e.getFullYear(),e.getMonth(),e.getDate())),n=t.getUTCDay()||7;t.setUTCDate(t.getUTCDate()+4-n);const a=new Date(Date.UTC(t.getUTCFullYear(),0,1));return Math.ceil(((t-a)/864e5+1)/7)}function o(e){const t=new Date(e.getTime());return t.setDate(t.getDate()+3-(t.getDay()+6)%7),t.getFullYear()}function i(e){return{Monday:\"Montag\",Tuesday:\"Dienstag\",Wednesday:\"Mittwoch\",Thursday:\"Donnerstag\",Friday:\"Freitag\",Saturday:\"Samstag\",Sunday:\"Sonntag\"}[e]||e}function r(e){const t=document.createElement(\"div\");return t.textContent=e||\"\",t.innerHTML}function l(e,t){if(!e||!t)return!1;const n=e.replace(/^v/,\"\").split(\".\").map(Number),a=t.replace(/^v/,\"\").split(\".\").map(Number);for(let e=0;eLade Men\u00fcdaten...
\\n