<!--
Copyright (C) 2026 Stefy Lanza <stefy@nexlab.net>

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <https://www.gnu.org/licenses/>.
-->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>{% block title %}AISBF Dashboard{% endblock %}</title>
    <link rel="icon" type="image/png" href="{{ url_for(request, '/favicon.ico') }}">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
    <style>
        /* ── Theme: dark (default) ── */
        :root {
            --bg-page:       #1a1a2e;
            --bg-panel:      #16213e;
            --bg-input:      #1a1a2e;
            --bg-accent:     #0f3460;
            --color-text:    #e0e0e0;
            --color-muted:   #a0a0a0;
            --color-subtle:  #666;
            --color-primary: #e94560;
            --color-primary-hover: #c73e54;
            --color-secondary: #0f3460;
            --color-secondary-hover: #1a4a7a;
            --color-border:  #0f3460;
            --color-link:    #60a5fa;
            --color-link-hover: #93c5fd;
            --shadow:        rgba(0,0,0,0.3);
            --shadow-lg:     rgba(0,0,0,0.4);
            --alert-success-bg: #1a3a2e; --alert-success-fg: #4ade80; --alert-success-border: #22c55e;
            --alert-error-bg:   #3a1a1a; --alert-error-fg:   #f87171; --alert-error-border:   #ef4444;
            --alert-info-bg:    #1a2a3a; --alert-info-fg:    #60a5fa; --alert-info-border:    #3b82f6;
            --th-bg: #0f3460;
        }

        /* ── Theme: light ── */
        [data-theme="light"] {
            --bg-page:       #f0f2f5;
            --bg-panel:      #ffffff;
            --bg-input:      #f8f9fa;
            --bg-accent:     #e8edf5;
            --color-text:    #1a1a2e;
            --color-muted:   #555;
            --color-subtle:  #888;
            --color-primary: #d63251;
            --color-primary-hover: #b02844;
            --color-secondary: #dde3ee;
            --color-secondary-hover: #c5cfe0;
            --color-border:  #c8d0e0;
            --color-link:    #2563eb;
            --color-link-hover: #1d4ed8;
            --shadow:        rgba(0,0,0,0.08);
            --shadow-lg:     rgba(0,0,0,0.12);
            --alert-success-bg: #ecfdf5; --alert-success-fg: #166534; --alert-success-border: #86efac;
            --alert-error-bg:   #fef2f2; --alert-error-fg:   #991b1b; --alert-error-border:   #fca5a5;
            --alert-info-bg:    #eff6ff; --alert-info-fg:    #1e40af; --alert-info-border:    #93c5fd;
            --th-bg: #e8edf5;
            --btn-danger-bg: #c0392b; --btn-danger-fg: #ffffff; --btn-danger-hover: #96281b;
            --btn-warning-bg: #d68910; --btn-warning-fg: #ffffff; --btn-warning-hover: #b7770d;
        }

        /* ── Theme: trans (transgender flag colors) ── */
        /* Flag: light blue #55CDFC, pink #F7A8B8, white #FFFFFF */
        [data-theme="trans"] {
            --bg-page:       #d0eef8;
            --bg-panel:      #eef8fd;
            --bg-input:      #e0f4fb;
            --bg-accent:     #55cdfc;
            --color-text:    #0d2a38;
            --color-muted:   #2a5a70;
            --color-subtle:  #4a8a9a;
            --color-primary: #d4547a;
            --color-primary-hover: #b83a60;
            --color-secondary: #f7a8b8;
            --color-secondary-hover: #f08098;
            --color-border:  #55cdfc;
            --color-link:    #0a6a95;
            --color-link-hover: #084f70;
            --shadow:        rgba(85,205,252,0.25);
            --shadow-lg:     rgba(85,205,252,0.4);
            --alert-success-bg: #cceefa; --alert-success-fg: #0a3a50; --alert-success-border: #55cdfc;
            --alert-error-bg:   #fde0ea; --alert-error-fg:   #7a1030; --alert-error-border:   #f7a8b8;
            --alert-info-bg:    #cceefa; --alert-info-fg:    #0a3a50; --alert-info-border:    #55cdfc;
            --th-bg: #a8e4f8;
            --btn-danger-bg: #c0392b; --btn-danger-fg: #ffffff; --btn-danger-hover: #96281b;
            --btn-warning-bg: #d68910; --btn-warning-fg: #ffffff; --btn-warning-hover: #b7770d;
        }

        /* ── Theme: freepal (Palestinian flag colors) ── */
        /* Flag: black #000000, white #FFFFFF, green #009736, red #EE2A35 */
        [data-theme="freepal"] {
            --bg-page:       #0a1a0a;
            --bg-panel:      #0f2a0f;
            --bg-input:      #0d200d;
            --bg-accent:     #1a4a1a;
            --color-text:    #e8f5e8;
            --color-muted:   #90c890;
            --color-subtle:  #5a9a5a;
            --color-primary: #ee2a35;
            --color-primary-hover: #c41f28;
            --color-secondary: #1a4a1a;
            --color-secondary-hover: #245a24;
            --color-border:  #009736;
            --color-link:    #4ade80;
            --color-link-hover: #22c55e;
            --shadow:        rgba(0,0,0,0.4);
            --shadow-lg:     rgba(0,0,0,0.6);
            --alert-success-bg: #0f2a0f; --alert-success-fg: #4ade80; --alert-success-border: #009736;
            --alert-error-bg:   #2a0a0a; --alert-error-fg:   #f87171; --alert-error-border:   #ee2a35;
            --alert-info-bg:    #0a0a0a; --alert-info-fg:    #e8f5e8; --alert-info-border:    #444444;
            --th-bg: #1a4a1a;
            --btn-danger-bg: #ee2a35; --btn-danger-fg: #ffffff; --btn-danger-hover: #c41f28;
            --btn-warning-bg: #d68910; --btn-warning-fg: #ffffff; --btn-warning-hover: #b7770d;
        }

        * { margin: 0; padding: 0; box-sizing: border-box; }
        body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif; background: var(--bg-page); color: var(--color-text); }
        .container { max-width: 1452px; margin: 0 auto; padding: 20px; }
        .container-wide { max-width: min(1680px, calc(100vw - 32px)); }
        .header { background: var(--bg-panel); color: var(--color-text); padding: 20px 0; margin-bottom: 30px; border-bottom: 2px solid var(--color-border); }
        .header .container { display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 10px; }
        .header h1 { font-size: 24px; font-weight: 600; }
        .header-actions { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }
        .nav { background: var(--bg-panel); padding: 15px; border-radius: 8px; margin-bottom: 20px; box-shadow: 0 2px 4px var(--shadow); display: flex; flex-wrap: wrap; gap: 10px; }
        .nav a { color: var(--color-muted); text-decoration: none; padding: 8px 12px; border-radius: 4px; flex-shrink: 0; }
        .nav a:hover { background: var(--bg-accent); color: var(--color-text); }
        .nav a.active { background: var(--color-primary); color: white; }
        .content { background: var(--bg-panel); padding: 30px; border-radius: 8px; box-shadow: 0 2px 4px var(--shadow); }
        .content-wide { padding: 0; background: transparent; box-shadow: none; }
        .form-group { margin-bottom: 20px; }
        .form-group label { display: block; margin-bottom: 5px; font-weight: 500; color: var(--color-text); }
        .form-group input, .form-group textarea, .form-group select { width: 100%; padding: 10px; border: 1px solid var(--color-border); border-radius: 4px; font-size: 14px; background: var(--bg-input); color: var(--color-text); }
        .form-group textarea { min-height: 200px; font-family: 'Courier New', monospace; }
        .btn { padding: 10px 20px; background: var(--color-primary); color: white; border: none; border-radius: 4px; cursor: pointer; font-size: 14px; text-decoration: none; display: inline-block; margin-left: 10px; }
        .btn:hover { background: var(--color-primary-hover); }
        .btn-secondary { background: var(--color-secondary); color: var(--color-text); }
        .btn-secondary:hover { background: var(--color-secondary-hover); }
        .btn-danger { background: var(--btn-danger-bg, #e74c3c); color: var(--btn-danger-fg, white); }
        .btn-danger:hover { background: var(--btn-danger-hover, #c0392b); }
        .btn-warning { background: var(--btn-warning-bg, #f39c12); color: var(--btn-warning-fg, white); }
        .btn-warning:hover { background: var(--btn-warning-hover, #e67e22); }
        .alert { padding: 15px; border-radius: 4px; margin-bottom: 20px; }
        .alert-success { background: var(--alert-success-bg); color: var(--alert-success-fg); border: 1px solid var(--alert-success-border); }
        .alert-error { background: var(--alert-error-bg); color: var(--alert-error-fg); border: 1px solid var(--alert-error-border); }
        .alert-info { background: var(--alert-info-bg); color: var(--alert-info-fg); border: 1px solid var(--alert-info-border); }
        table { width: 100%; border-collapse: collapse; margin-top: 20px; }
        th, td { padding: 12px; text-align: left; border-bottom: 1px solid var(--color-border); color: var(--color-text); }
        th { background: var(--th-bg); font-weight: 600; color: var(--color-text); }
        .code { background: var(--bg-accent); padding: 15px; border-radius: 4px; font-family: 'Courier New', monospace; font-size: 13px; overflow-x: auto; color: var(--color-text); }
        .nav .account-menu { position: relative; margin-left: auto; }
        .nav .account-trigger { display: flex; align-items: center; gap: 8px; padding: 6px 12px; border-radius: 4px; cursor: pointer; color: var(--color-muted); }
        .nav .account-trigger:hover { background: var(--bg-accent); color: var(--color-text); }
        .nav .account-trigger img { width: 24px; height: 24px; border-radius: 50%; vertical-align: middle; }
        .nav .account-dropdown { position: absolute; top: 100%; right: 0; background: var(--bg-panel); border-radius: 8px; min-width: 200px; box-shadow: 0 4px 12px var(--shadow-lg); margin-top: 8px; display: none; z-index: 100; border: 1px solid var(--color-border); }
        .nav .account-dropdown.active { display: block; }
        .nav .account-dropdown a { display: block; padding: 12px 16px; color: var(--color-muted); text-decoration: none; border-radius: 0; }
        .nav .account-dropdown a:first-child { border-radius: 8px 8px 0 0; }
        .nav .account-dropdown a:last-child { border-radius: 0 0 8px 8px; }
        .nav .account-dropdown a:hover { background: var(--bg-accent); color: var(--color-text); }

        /* Notification bell */
        .notif-bell { position: relative; display: flex; align-items: center; padding: 6px 10px; border-radius: 4px; cursor: pointer; color: var(--color-muted); user-select: none; }
        .notif-bell:hover { background: var(--bg-accent); color: var(--color-text); }
        .notif-badge { position: absolute; top: 2px; right: 2px; background: var(--color-primary); color: #fff; border-radius: 50%; font-size: 10px; font-weight: 700; min-width: 16px; height: 16px; line-height: 16px; text-align: center; padding: 0 3px; display: none; }
        .notif-dropdown { position: absolute; top: 100%; right: 0; background: var(--bg-panel); border: 1px solid var(--color-border); border-radius: 8px; min-width: 320px; max-width: 360px; box-shadow: 0 4px 12px var(--shadow-lg); margin-top: 8px; z-index: 200; display: none; }
        .notif-dropdown.active { display: block; }
        .notif-header { display: flex; justify-content: space-between; align-items: center; padding: 12px 16px; border-bottom: 1px solid var(--color-border); }
        .notif-header span { font-weight: 600; color: var(--color-text); font-size: 13px; }
        .notif-header button { background: none; border: none; color: var(--color-link); font-size: 12px; cursor: pointer; padding: 0; }
        .notif-header button:hover { color: var(--color-link-hover); }
        .notif-list { max-height: 340px; overflow-y: auto; }
        .notif-item { padding: 12px 16px; border-bottom: 1px solid var(--color-border); cursor: pointer; transition: background .15s; display: flex; gap: 10px; align-items: flex-start; }
        .notif-item:hover { background: var(--bg-accent); }
        .notif-item.unread { border-left: 3px solid var(--color-primary); }
        .notif-item.read { border-left: 3px solid transparent; opacity: .75; }
        .notif-item-body { flex: 1; min-width: 0; }
        .notif-item-title { font-size: 13px; font-weight: 600; color: var(--color-text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
        .notif-item-msg { font-size: 12px; color: var(--color-muted); margin-top: 3px; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
        .notif-item-time { font-size: 11px; color: var(--color-subtle); margin-top: 4px; }
        .notif-item-del { color: var(--color-subtle); font-size: 14px; padding: 2px 6px; border-radius: 3px; flex-shrink: 0; }
        .notif-item-del:hover { color: #f87171; background: rgba(239,68,68,.15); }
        .notif-empty { padding: 24px 16px; text-align: center; color: var(--color-subtle); font-size: 13px; }
        .notif-footer { padding: 10px 16px; border-top: 1px solid var(--color-border); text-align: center; }
        .notif-footer a { color: var(--color-link); font-size: 12px; text-decoration: none; }
        .notif-footer a:hover { color: var(--color-link-hover); }

        /* ── Language switcher ── */
        .lang-switcher { position: relative; display: flex; align-items: center; }
        .lang-trigger { display: flex; align-items: center; gap: 5px; padding: 4px 8px; border-radius: 4px; cursor: pointer; color: var(--color-muted); font-size: 13px; background: none; border: 1px solid var(--color-border); }
        .lang-trigger:hover { background: var(--bg-accent); color: var(--color-text); }
        .lang-dropdown { position: absolute; top: 100%; right: 0; background: var(--bg-panel); border: 1px solid var(--color-border); border-radius: 8px; min-width: 200px; max-height: 320px; overflow-y: auto; box-shadow: 0 4px 12px var(--shadow-lg); margin-top: 6px; z-index: 200; display: none; }
        .lang-dropdown.active { display: block; }
        .lang-option { display: block; padding: 8px 14px; color: var(--color-muted); text-decoration: none; font-size: 13px; cursor: pointer; border: none; background: none; width: 100%; text-align: left; }
        .lang-option:hover { background: var(--bg-accent); color: var(--color-text); }
        .lang-option.active { color: var(--color-primary); font-weight: 600; }
        .lang-option .lang-code { font-size: 11px; color: var(--color-subtle); margin-left: 4px; }

        /* ── Theme switcher ── */
        .theme-switcher { display: flex; align-items: center; gap: 5px; }
        .theme-btn { width: 22px; height: 22px; border-radius: 50%; border: 2px solid rgba(255,255,255,0.25); cursor: pointer; transition: border-color .2s, transform .2s; flex-shrink: 0; padding: 0; }
        .theme-btn:hover { transform: scale(1.2); border-color: rgba(255,255,255,0.6); }
        .theme-btn.active { border-color: white; box-shadow: 0 0 0 1px rgba(0,0,0,0.3); }
        [data-theme="light"] .theme-btn { border-color: rgba(0,0,0,0.2); }
        [data-theme="light"] .theme-btn:hover { border-color: rgba(0,0,0,0.5); }
        [data-theme="light"] .theme-btn.active { border-color: #333; box-shadow: 0 0 0 1px rgba(255,255,255,0.5); }
        .theme-btn[data-t="dark"]     { background: linear-gradient(135deg, #1a1a2e 50%, #e94560 50%); }
        .theme-btn[data-t="light"]    { background: linear-gradient(135deg, #f0f2f5 50%, #d63251 50%); }
        .theme-btn[data-t="trans"]    { background: linear-gradient(to bottom, #55cdfc 33%, #f7a8b8 33% 66%, #ffffff 66%); }
        .theme-btn[data-t="freepal"] { background: linear-gradient(to bottom, #000000 33%, #ffffff 33% 66%, #009736 66%); }
        
        /* Rainbow Upgrade Button */
        .upgrade-button {
            font-weight: 700 !important;
            padding: 8px 16px !important;
            border-radius: 6px !important;
            background: linear-gradient(120deg, #ff0080, #ff8c00, #40e0d0, #9370db, #ff0080) !important;
            background-size: 400% 400% !important;
            animation: rainbow-gradient 3s ease infinite !important;
            color: white !important;
            text-shadow: 0 1px 2px rgba(0,0,0,0.3) !important;
            box-shadow: 0 0 12px rgba(255, 0, 128, 0.5) !important;
            margin-left: 4px !important;
            transition: transform 0.2s ease, box-shadow 0.2s ease !important;
        }
        
        .upgrade-button:hover {
            transform: scale(1.05) !important;
            box-shadow: 0 0 20px rgba(255, 0, 128, 0.7) !important;
        }
        
        @keyframes rainbow-gradient {
            0% { background-position: 0% 50%; }
            50% { background-position: 100% 50%; }
            100% { background-position: 0% 50%; }
        }
        
        .rainbow-text {
            background: linear-gradient(90deg, #ff0000, #ff7f00, #ffff00, #00ff00, #0000ff, #4b0082, #9400d3);
            background-size: 400% 400%;
            animation: rainbow-text 2s linear infinite;
            -webkit-background-clip: text;
            background-clip: text;
            color: transparent !important;
            font-weight: 800 !important;
        }
        
        @keyframes rainbow-text {
            0% { background-position: 0% center; }
            100% { background-position: 400% center; }
        }

        /* ── Mobile responsive ── */
        @media (max-width: 768px) {
            .container { padding: 8px; }
            .header { padding: 12px 0; margin-bottom: 12px; }
            .header h1 { font-size: 18px; }
            .header-actions { margin-top: 6px; }
            .header-actions .btn { padding: 6px 10px; font-size: 12px; margin-left: 0; }
            .nav { padding: 8px; gap: 6px; }
            .nav a { padding: 6px 8px; font-size: 13px; }
            .content { padding: 14px; }
            table { display: block; overflow-x: auto; -webkit-overflow-scrolling: touch; }
            th, td { padding: 8px 10px; font-size: 13px; white-space: nowrap; }
            .btn { padding: 8px 12px; font-size: 13px; }
            .form-group input, .form-group textarea, .form-group select { font-size: 16px; /* prevent iOS zoom */ }
            .notif-dropdown { min-width: 280px; max-width: calc(100vw - 16px); right: -60px; }
            .account-dropdown { min-width: 160px; }
            .donate-modal-content, .ui-modal-box { width: 96%; padding: 18px; }
            /* Collapse any 2-column inline-style grids */
            [style*="grid-template-columns: 1fr 1fr"],
            [style*="grid-template-columns: repeat(auto-fit, minmax(4"] {
                grid-template-columns: 1fr !important;
            }
        }
        @media (max-width: 480px) {
            .header-actions .btn { font-size: 11px; padding: 5px 8px; }
            .nav a { font-size: 12px; padding: 5px 7px; }
            .content { padding: 10px; }
        }
    </style>
    <script>
        /* Apply saved theme and language immediately to avoid flash */
        (function() {
            var user = '{{ request.session.username|default("__guest__") }}';
            var t = localStorage.getItem('aisbf_theme_' + user) || 'dark';
            if (t !== 'dark') document.documentElement.setAttribute('data-theme', t);
            var l = localStorage.getItem('aisbf_lang_' + user);
            if (l && l !== 'en') document.documentElement.setAttribute('lang', l);
        })();
    </script>
    <script>
        /*
         * Copyright (C) 2026 Stefy Lanza <stefy@nexlab.net>
         *
         * This program is free software: you can redistribute it and/or modify
         * it under the terms of the GNU General Public License as published by
         * the Free Software Foundation, either version 3 of the License, or
         * (at your option) any later version.
         *
         * This program is distributed in the hope that it will be useful,
         * but WITHOUT ANY WARRANTY; without even the implied warranty of
         * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
         * GNU General Public License for more details.
         *
         * You should have received a copy of the GNU General Public License
         * along with this program.  If not, see <https://www.gnu.org/licenses/>.
         */
        function toggleAccountMenu() {
            const dropdown = document.getElementById('account-dropdown');
            dropdown.classList.toggle('active');
        }
        
        // Theme switcher
        (function() {
            var user = '{{ request.session.username|default("__guest__") }}';
            var key = 'aisbf_theme_' + user;
            function applyTheme(t) {
                if (t === 'dark') document.documentElement.removeAttribute('data-theme');
                else document.documentElement.setAttribute('data-theme', t);
                document.querySelectorAll('.theme-btn').forEach(function(b) {
                    b.classList.toggle('active', b.dataset.t === t);
                });
            }
            window.setTheme = function(t) {
                localStorage.setItem(key, t);
                applyTheme(t);
            };
            // Sync buttons on load
            document.addEventListener('DOMContentLoaded', function() {
                var saved = localStorage.getItem(key) || 'dark';
                applyTheme(saved);
            });
        })();

        // Language switcher
        (function() {
            function buildLangDropdown() {
                var dd = document.getElementById('lang-dropdown');
                if (!dd || !window.i18n) return;
                var langs = window.i18n.getAvailableLanguages();
                var current = window.i18n.getCurrentLanguage();
                dd.innerHTML = Object.entries(langs).map(function(entry) {
                    var code = entry[0], name = entry[1];
                    return '<button class="lang-option lang-btn' + (code === current ? ' active' : '') + '" data-lang="' + code + '" onclick="selectLanguage(\'' + code + '\')">' +
                        name + '<span class="lang-code">' + code.toUpperCase() + '</span></button>';
                }).join('');
                var codeEl = document.getElementById('current-lang-code');
                if (codeEl) codeEl.textContent = current.toUpperCase();
            }

            window.selectLanguage = function(lang) {
                window.i18n.setLanguage(lang).then(function() {
                    // Reload page to apply server-side translations
                    window.location.reload();
                });
            };

            window.toggleLangDropdown = function(e) {
                e.stopPropagation();
                var dd = document.getElementById('lang-dropdown');
                if (!dd.innerHTML) buildLangDropdown();
                dd.classList.toggle('active');
            };

            document.addEventListener('DOMContentLoaded', function() {
                // Rebuild after i18n initializes (fires i18n:ready when language is loaded)
                document.addEventListener('i18n:ready', buildLangDropdown);
            });

            document.addEventListener('click', function(e) {
                var sw = document.querySelector('.lang-switcher');
                if (sw && !sw.contains(e.target)) {
                    var dd = document.getElementById('lang-dropdown');
                    if (dd) dd.classList.remove('active');
                }
            });
        })();
        
        // Close account dropdown when clicking outside
        document.addEventListener('click', function(event) {
            const dropdown = document.getElementById('account-dropdown');
            if (!dropdown) return;
            const accountMenu = dropdown.closest('.account-menu');
            if (accountMenu && !accountMenu.contains(event.target)) {
                dropdown.classList.remove('active');
            }
        });
        
        function restartServer() {
            showConfirm('Are you sure you want to restart the server? This will disconnect all active connections.', 'Restart Server', '🔄', 'warn').then(ok => {
                if (!ok) return;
                fetch('{{ url_for(request, "/dashboard/restart") }}', {
                    method: 'POST',
                    headers: {'Content-Type': 'application/json'}
                })
                .then(response => response.json())
                .then(data => {
                    showAlert(data.message + ' The page will reload in 5 seconds.', 'Restarting');
                    setTimeout(() => window.location.reload(), 5000);
                })
                .catch(error => {
                    showAlert('Error restarting server: ' + error, 'Error', '❌', 'danger');
                });
            });
        }
        
        // Snake Game Easter Egg
        (function() {
            var keyHistory = [];
            var lastKeyTime = 0;
            var timeout = 10000; // 10 seconds window
            var sequence = ['ArrowUp', 'ArrowDown', 'ArrowUp'];
            var currentIndex = 0;
            
            document.addEventListener('keydown', function(e) {
                // Don't activate easter egg when typing in input fields
                var activeElement = document.activeElement;
                if (activeElement && (activeElement.tagName === 'INPUT' || activeElement.tagName === 'TEXTAREA' || activeElement.tagName === 'SELECT')) {
                    return;
                }
                
                var now = Date.now();
                
                // Reset if too much time passed
                if (now - lastKeyTime > timeout) {
                    keyHistory = [];
                    currentIndex = 0;
                }
                lastKeyTime = now;
                
                // Only track ArrowUp and ArrowDown
                if (e.key === 'ArrowUp' || e.key === 'ArrowDown') {
                    keyHistory.push(e.key);
                    
                    // Check if current sequence matches target
                    if (keyHistory[currentIndex] === sequence[currentIndex]) {
                        currentIndex++;
                        if (currentIndex === sequence.length) {
                            // Sequence complete! Open the game
                            openSnakeGame();
                            keyHistory = [];
                            currentIndex = 0;
                        }
                    } else {
                        // Wrong key, reset
                        keyHistory = [];
                        currentIndex = 0;
                    }
                }
            });
            
            function openSnakeGame() {
                var gameHtml = `
                <!DOCTYPE html>
                <html>
                <head>
                    <title>Snake Game - AISBF Easter Egg</title>
                    <style>
                        @import url('https://fonts.googleapis.com/css2?family=Press+Start+2P&display=swap');
                        * { box-sizing: border-box; margin: 0; padding: 0; }
                        html, body {
                            width: 100%; height: 100%;
                            background: #09080a;
                            font-family: 'Press Start 2P', cursive;
                            overflow: hidden;
                            display: flex;
                            justify-content: center;
                            align-items: center;
                        }
                        #game-container {
                            position: relative;
                            display: flex;
                            flex-direction: column;
                            align-items: center;
                        }
                        #start-screen {
                            position: absolute;
                            background: #120d18;
                            padding: 30px;
                            border: 5px solid #0d0a12;
                            box-shadow: 0 50px 50px -30px rgba(0,0,0,0.3);
                            text-align: center;
                            z-index: 10;
                            border-radius: 10px;
                        }
                        #start-screen h1 {
                            color: #ff76ff;
                            font-size: 24px;
                            margin-bottom: 20px;
                            text-shadow: 0 0 10px #ff76ff;
                        }
                        #start-screen .difficulty {
                            margin: 20px 0;
                        }
                        #start-screen .difficulty button {
                            background: #0d0a12;
                            border: 2px solid #3e3f43;
                            color: #e9eaee;
                            padding: 10px 15px;
                            margin: 5px;
                            cursor: pointer;
                            font-family: 'Press Start 2P', cursive;
                            font-size: 10px;
                        }
                        #start-screen .difficulty button:hover,
                        #start-screen .difficulty button.active {
                            border-color: #ff76ff;
                            color: #ff76ff;
                        }
                        #start-screen .play-btn {
                            background: #ff76ff;
                            border: none;
                            color: #0d0a12;
                            padding: 15px 30px;
                            font-family: 'Press Start 2P', cursive;
                            font-size: 14px;
                            cursor: pointer;
                            margin-top: 20px;
                        }
                        #start-screen .play-btn:hover {
                            background: #ff5acc;
                        }
                        #gameover-screen {
                            position: absolute;
                            background: #120d18;
                            padding: 30px;
                            border: 5px solid #0d0a12;
                            box-shadow: 0 50px 50px -30px rgba(0,0,0,0.3);
                            text-align: center;
                            z-index: 10;
                            border-radius: 10px;
                        }
                        #gameover-screen h2 {
                            color: #ff76ff;
                            font-size: 20px;
                            margin-bottom: 15px;
                            text-shadow: 0 0 10px #ff76ff;
                        }
                        #gameover-screen p {
                            color: #e9eaee;
                            font-size: 12px;
                            margin-bottom: 20px;
                        }
                        #gameover-screen .play-btn {
                            background: #ff76ff;
                            border: none;
                            color: #0d0a12;
                            padding: 15px 30px;
                            font-family: 'Press Start 2P', cursive;
                            font-size: 14px;
                            cursor: pointer;
                            margin-top: 10px;
                        }
                        #gameover-screen .play-btn:hover {
                            background: #ff5acc;
                        }
                        canvas {
                            background: #09080a;
                            border: 2px solid #3e3f43;
                        }
                        #score {
                            position: fixed;
                            top: 20px;
                            right: 20px;
                            color: #ff76ff;
                            font-size: 30px;
                            display: none;
                        }
                        .hidden { display: none !important; }
                    </style>
                </head>
                <body>
                    <div id="score">0</div>
                    <div id="game-container">
                        <div id="start-screen">
                            <h1>🐍 AISBF Snake 🐍</h1>
                            <div class="difficulty">
                                <button data-speed="150" class="active">Easy</button>
                                <button data-speed="100">Medium</button>
                                <button data-speed="50">Hard</button>
                            </div>
                            <button class="play-btn" onclick="startGame()">Play</button>
                        </div>
                        <canvas id="game-canvas"></canvas>
                        <div id="gameover-screen" class="hidden">
                            <h2>🐍 Game Over 🐍</h2>
                            <p id="gameover-score"></p>
                            <button class="play-btn" onclick="playAgain()">Play Again</button>
                        </div>
                    </div>
                    <script>
                        const canvas = document.getElementById('game-canvas');
                        const ctx = canvas.getContext('2d');
                        const startScreen = document.getElementById('start-screen');
                        const gameoverScreen = document.getElementById('gameover-screen');
                        const scoreDisplay = document.getElementById('score');
                        
                        // Set canvas size
                        canvas.width = 600;
                        canvas.height = 400;
                        
                        let snake = [];
                        let food = {};
                        let direction = 'right';
                        let nextDirection = 'right';
                        let gameLoop = null;
                        let score = 0;
                        let speed = 150;
                        
                        // Difficulty buttons
                        document.querySelectorAll('.difficulty button').forEach(btn => {
                            btn.addEventListener('click', function() {
                                document.querySelectorAll('.difficulty button').forEach(b => b.classList.remove('active'));
                                this.classList.add('active');
                                speed = parseInt(this.dataset.speed);
                            });
                        });
                        
                        function initGame() {
                            snake = [
                                {x: 300, y: 200},
                                {x: 280, y: 200},
                                {x: 260, y: 200}
                            ];
                            direction = 'right';
                            nextDirection = 'right';
                            score = 0;
                            scoreDisplay.textContent = score;
                            placeFood();
                        }
                        
                        function placeFood() {
                            food = {
                                x: Math.floor(Math.random() * (canvas.width / 20)) * 20,
                                y: Math.floor(Math.random() * (canvas.height / 20)) * 20
                            };
                        }
                        
                        function startGame() {
                            startScreen.classList.add('hidden');
                            scoreDisplay.style.display = 'block';
                            initGame();
                            if (gameLoop) clearInterval(gameLoop);
                            gameLoop = setInterval(update, speed);
                        }
                        
                        function update() {
                            direction = nextDirection;
                            
                            const head = {x: snake[0].x, y: snake[0].y};
                            
                            switch(direction) {
                                case 'up': head.y -= 20; break;
                                case 'down': head.y += 20; break;
                                case 'left': head.x -= 20; break;
                                case 'right': head.x += 20; break;
                            }
                            
                            // Check wall collision
                            if (head.x < 0 || head.x >= canvas.width || head.y < 0 || head.y >= canvas.height) {
                                gameOver();
                                return;
                            }
                            
                            // Check self collision
                            for (let i = 0; i < snake.length; i++) {
                                if (head.x === snake[i].x && head.y === snake[i].y) {
                                    gameOver();
                                    return;
                                }
                            }
                            
                            snake.unshift(head);
                            
                            // Check food collision
                            if (head.x === food.x && head.y === food.y) {
                                score += 10;
                                scoreDisplay.textContent = score;
                                placeFood();
                            } else {
                                snake.pop();
                            }
                            
                            draw();
                        }
                        
                        function draw() {
                            // Clear canvas
                            ctx.fillStyle = '#09080a';
                            ctx.fillRect(0, 0, canvas.width, canvas.height);
                            
                            // Draw snake
                            ctx.fillStyle = '#fac020';
                            snake.forEach((segment, i) => {
                                ctx.fillStyle = i === 0 ? '#ffd700' : '#fac020';
                                ctx.fillRect(segment.x + 1, segment.y + 1, 18, 18);
                            });
                            
                            // Draw food
                            ctx.fillStyle = '#ee6b71';
                            ctx.beginPath();
                            ctx.arc(food.x + 10, food.y + 10, 8, 0, Math.PI * 2);
                            ctx.fill();
                        }
                        
                        function gameOver() {
                            clearInterval(gameLoop);
                            document.getElementById('gameover-score').textContent = 'Score: ' + score;
                            gameoverScreen.classList.remove('hidden');
                            scoreDisplay.style.display = 'none';
                        }

                        function playAgain() {
                            gameoverScreen.classList.add('hidden');
                            startScreen.classList.remove('hidden');
                        }
                        
                        // Keyboard controls
                        document.addEventListener('keydown', function(e) {
                            switch(e.key) {
                                case 'ArrowUp':
                                    if (direction !== 'down') nextDirection = 'up';
                                    e.preventDefault();
                                    break;
                                case 'ArrowDown':
                                    if (direction !== 'up') nextDirection = 'down';
                                    e.preventDefault();
                                    break;
                                case 'ArrowLeft':
                                    if (direction !== 'right') nextDirection = 'left';
                                    e.preventDefault();
                                    break;
                                case 'ArrowRight':
                                    if (direction !== 'left') nextDirection = 'right';
                                    e.preventDefault();
                                    break;
                            }
                        });
                        
                        // Initial draw
                        draw();
                    <\/script>
                </body>
                </html>
                `;
                
                var gameWindow = window.open('', 'SnakeGame', 'width=650,height=500');
                gameWindow.document.write(gameHtml);
                gameWindow.document.close();
                gameWindow.focus();
            }
        })();
    </script>
    {% block extra_css %}{% endblock %}
    <script src="{{ url_for(request, '/dashboard/static/i18n.js') }}"></script>
</head>
<body data-username="{{ request.session.username|default('__guest__') }}">
    <div class="header">
        <div class="container">
            <h1>AISBF Dashboard <span style="font-size: 0.8em; font-weight: normal; opacity: 0.7;">v{{ __version__ }}</span></h1>
            {% if request.session.logged_in %}
            <div class="header-actions">
                {% if is_aisbf_cloud %}
                <button onclick="openContactModal()" class="btn btn-secondary" data-i18n="header.help">Help</button>
                {% endif %}
                <a href="{{ url_for(request, '/dashboard/docs') }}" class="btn btn-secondary" data-i18n="header.docs">Docs</a>
                <a href="{{ url_for(request, '/dashboard/about') }}" class="btn btn-secondary" data-i18n="header.about">About</a>
                <a href="{{ url_for(request, '/dashboard/license') }}" class="btn btn-secondary" data-i18n="header.license">License</a>
                {% if request.session.role == 'admin' %}
                <button onclick="restartServer()" class="btn btn-warning" data-i18n="header.restart_server">Restart Server</button>
                {% endif %}
                <div class="theme-switcher" title="Color theme">
                    <button class="theme-btn" data-t="dark"    onclick="setTheme('dark')"    title="Dark theme"></button>
                    <button class="theme-btn" data-t="light"   onclick="setTheme('light')"   title="Light theme"></button>
                    <button class="theme-btn" data-t="trans"   onclick="setTheme('trans')"   title="Trans theme"></button>
                    <button class="theme-btn" data-t="freepal" onclick="setTheme('freepal')" title="Free Palestine theme"></button>
                </div>
                <div class="lang-switcher">
                    <button class="lang-trigger" onclick="toggleLangDropdown(event)" title="Language">
                        <i class="fas fa-language"></i>
                        <span id="current-lang-code">EN</span>
                    </button>
                    <div class="lang-dropdown" id="lang-dropdown"></div>
                </div>
                <a href="{{ url_for(request, '/dashboard/logout') }}" class="btn btn-secondary" data-i18n="header.logout">Logout</a>
            </div>
            {% endif %}
        </div>
    </div>

    {% if request.session.impersonating_as %}
    <div style="background: #7c3aed; color: #fff; text-align: center; padding: 8px 16px; font-size: 14px;">
        <strong>⚠ Impersonating:</strong> {{ request.session.username }}
        &nbsp;—&nbsp;
        <a href="{{ url_for(request, '/dashboard/logout') }}" style="color: #fff; text-decoration: underline;">Stop impersonating (return to admin)</a>
    </div>
    {% endif %}

    {% if request.session.logged_in and show_upgrade_banner %}
    <div class="upgrade-banner">
        <div class="container">
            <div class="d-flex align-items-center justify-content-between py-2">
                <div>
                    <i class="fas fa-rocket me-2"></i>
                    <span>Want higher limits? <strong>Upgrade your plan</strong> for more requests and features!</span>
                </div>
                <a href="{{ url_for(request, '/dashboard/pricing') }}" class="btn btn-sm btn-light">
                    View Pricing Plans <i class="fas fa-arrow-right ms-1"></i>
                </a>
            </div>
        </div>
    </div>
    {% endif %}

    {% if request.session.logged_in %}
    <div class="container">
        <div class="nav">
            <a href="{{ url_for(request, '/dashboard') }}" {% if request.path == '/dashboard' %}class="active"{% endif %} data-i18n="nav.overview">Overview</a>
            <a href="{{ url_for(request, '/dashboard/providers') }}" {% if '/providers' in request.path %}class="active"{% endif %} data-i18n="nav.providers">Providers</a>
            <a href="{{ url_for(request, '/dashboard/rotations') }}" {% if '/rotations' in request.path %}class="active"{% endif %} data-i18n="nav.rotations">Rotations</a>
            <a href="{{ url_for(request, '/dashboard/autoselect') }}" {% if '/autoselect' in request.path %}class="active"{% endif %} data-i18n="nav.autoselect">Autoselect</a>
            <a href="{{ url_for(request, '/dashboard/studio') }}" {% if '/studio' in request.path %}class="active"{% endif %} data-i18n="nav.studio">Studio</a>
            {% if request.state.market_enabled is not defined or request.state.market_enabled %}
            <a href="{{ url_for(request, '/dashboard/market') }}" {% if '/market' in request.path and '/admin/market' not in request.path %}class="active"{% endif %}>Market</a>
            {% endif %}
            <a href="{{ url_for(request, '/dashboard/prompts') }}" {% if '/prompts' in request.path %}class="active"{% endif %} data-i18n="nav.prompts">Prompts</a>
            <a href="{{ url_for(request, '/dashboard/analytics') }}" {% if '/analytics' in request.path %}class="active"{% endif %} data-i18n="nav.analytics">Analytics</a>
            {% if request.session.user_id %}
            <a href="{{ url_for(request, '/dashboard/user/tokens') }}" {% if '/user/tokens' in request.path %}class="active"{% endif %} data-i18n="nav.api_tokens">API Tokens</a>
            <a href="{{ url_for(request, '/dashboard/wallet') }}" {% if '/wallet' in request.path %}class="active"{% endif %} data-i18n="nav.wallet">Wallet</a>
            <a href="{{ url_for(request, '/dashboard/usage') }}" {% if '/usage' in request.path %}class="active"{% endif %} data-i18n="nav.usage">Usage</a>
            {% endif %}
            {% if request.session.role == 'admin' %}
            <a href="{{ url_for(request, '/dashboard/users') }}" {% if '/users' in request.path %}class="active"{% endif %} data-i18n="nav.users">Users</a>
            <a href="{{ url_for(request, '/dashboard/settings') }}" {% if '/settings' in request.path %}class="active"{% endif %} data-i18n="nav.settings">Settings</a>
            <a href="{{ url_for(request, '/dashboard/admin/tiers') }}" {% if '/admin/tiers' in request.path %}class="active"{% endif %} data-i18n="nav.tiers">Tiers</a>
            <a href="{{ url_for(request, '/dashboard/admin/payment-settings') }}" {% if '/admin/payment-settings' in request.path %}class="active"{% endif %} data-i18n="nav.payment_settings">Payment Settings</a>
            {% endif %}
            {% if show_upgrade_button %}
            <a href="{{ url_for(request, '/dashboard/pricing') }}" class="upgrade-button rainbow-text">✨ Upgrade! ✨</a>
            {% endif %}
            {% if request.session.user_id %}
            <!-- Notification Bell -->
            <div class="notif-menu-wrap" id="notif-menu" style="position:relative; display:flex; align-items:center; margin-left:0;">
                <div class="notif-bell" id="notif-bell" onclick="toggleNotifDropdown(event)" title="Notifications">
                    <i class="fas fa-bell"></i>
                    <span class="notif-badge" id="notif-badge"></span>
                </div>
                <div class="notif-dropdown" id="notif-dropdown">
                    <div class="notif-header">
                        <span data-i18n="notifications.title">Notifications</span>
                        <button onclick="markAllNotifRead(event)" data-i18n="notifications.mark_all_read">Mark all as read</button>
                    </div>
                    <div class="notif-list" id="notif-list">
                        <div class="notif-empty" data-i18n="common.loading">Loading…</div>
                    </div>
                    <div class="notif-footer">
                        <a href="#" onclick="loadNotifications(); return false;" data-i18n="notifications.refresh">Refresh</a>
                    </div>
                </div>
            </div>
            <div class="account-menu">
                <div class="account-trigger" onclick="toggleAccountMenu()">
                    <img src="{{ '/dashboard/profile-pic' if request.session.has_profile_pic else 'https://www.gravatar.com/avatar/' ~ (request.session.email|md5 if request.session.email else '') ~ '?s=48&d=identicon' }}" alt="User avatar">
                    <span data-i18n="nav.account">Account</span>
                </div>
                <div class="account-dropdown" id="account-dropdown">
                    {% if request.session.user_id %}
                    {% if request.session.user_id %}
                     <a href="{{ url_for(request, '/dashboard/profile') }}" data-i18n="account_menu.edit_profile">Edit Profile</a>
                     <a href="{{ url_for(request, '/dashboard/user/tokens') }}" data-i18n="account_menu.api_tokens">API Tokens</a>
                     <a href="{{ url_for(request, '/dashboard/cache-settings') }}" data-i18n="account_menu.cache_settings">Cache Settings</a>
                     <a href="{{ url_for(request, '/dashboard/subscription') }}" data-i18n="account_menu.subscription">Subscription</a>
                     <a href="{{ url_for(request, '/dashboard/wallet') }}" data-i18n="account_menu.wallet">Wallet</a>
                     <a href="{{ url_for(request, '/dashboard/billing') }}" data-i18n="account_menu.billing">Billing</a>
                     <a href="{{ url_for(request, '/dashboard/usage') }}" data-i18n="account_menu.usage_quotas">Usage &amp; Quotas</a>
                     <a href="{{ url_for(request, '/dashboard/change-password') }}" data-i18n="account_menu.change_password">Change Password</a>
                    {% endif %}
                    {% endif %}
                </div>
            </div>
            {% endif %}
        </div>
    </div>
    {% endif %}
    
    <!-- Shared collapsible sub-panel helper (used by providers/rotations/autoselect config forms).
         Defined before the content block so page scripts can call subPanel() during initial render. -->
    <style>
    .sub-panel {
        border: 1px solid var(--color-border);
        border-radius: 4px;
        margin-bottom: 12px;
        background: var(--bg-page);
        overflow: hidden;
    }
    .sub-panel-header {
        padding: 10px 12px;
        cursor: pointer;
        user-select: none;
        display: flex;
        align-items: center;
        gap: 8px;
        background: var(--bg-accent);
        font-weight: 600;
        font-size: 14px;
        color: var(--color-text);
    }
    .sub-panel-header:hover { filter: brightness(1.08); }
    .sub-panel-header .sp-chevron { font-size: 12px; width: 14px; display: inline-block; color: var(--color-muted); }
    .sub-panel-header .sp-title { flex: 1; }
    .sub-panel-header .sp-badge { font-weight: 400; font-size: 12px; color: var(--color-muted); }
    .sub-panel-body { padding: 14px 12px; border-top: 1px solid var(--color-border); }
    .sub-panel.sp-nested { background: var(--bg-panel); }
    </style>
    <script>
    (function(){
        // Tracks which sub-panels are open, keyed by a stable string. State
        // survives re-renders of a detail form so panels don't snap shut when
        // an unrelated field re-renders the list, and is persisted to
        // sessionStorage so open/close state is remembered while navigating
        // between dashboard pages within the same browser session.
        const _SP_STORE = 'aisbf_open_subpanels';
        function _spLoad() {
            try { return new Set(JSON.parse(sessionStorage.getItem(_SP_STORE) || '[]')); }
            catch (e) { return new Set(); }
        }
        function _spSave() {
            try { sessionStorage.setItem(_SP_STORE, JSON.stringify([...window._openSubPanels])); }
            catch (e) { /* sessionStorage unavailable — keep in-memory only */ }
        }
        window._openSubPanels = window._openSubPanels || _spLoad();

        function _spEsc(s) {
            return String(s).replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;').replace(/"/g,'&quot;').replace(/'/g,'&#39;');
        }

        // Build a collapsible sub-panel. `key` must be unique per logical panel.
        // opts: {badge, nested, open} — `open:true` makes it default-expanded the
        // first time it is seen (afterwards user state in _openSubPanels wins).
        window.subPanel = function(key, title, innerHtml, opts) {
            opts = opts || {};
            if (opts.open && !window._openSubPanels.has('__seen__' + key)) {
                window._openSubPanels.add('__seen__' + key);
                window._openSubPanels.add(key);
                _spSave();
            }
            const isOpen = window._openSubPanels.has(key);
            const safe = _spEsc(key);
            const chev = isOpen ? '▼' : '▶';
            const disp = isOpen ? 'block' : 'none';
            const badge = opts.badge ? `<span class="sp-badge">${opts.badge}</span>` : '';
            const nestedCls = opts.nested ? ' sp-nested' : '';
            return `
              <div class="sub-panel${nestedCls}">
                <div class="sub-panel-header" onclick="toggleSubPanel('${safe}', this)">
                  <span class="sp-chevron">${chev}</span>
                  <span class="sp-title">${title}</span>
                  ${badge}
                </div>
                <div class="sub-panel-body" style="display:${disp};">${innerHtml}</div>
              </div>`;
        };

        window.toggleSubPanel = function(key, headerEl) {
            const body = headerEl.parentElement.querySelector('.sub-panel-body');
            if (!body) return;
            const willOpen = !window._openSubPanels.has(key);
            if (willOpen) window._openSubPanels.add(key); else window._openSubPanels.delete(key);
            _spSave();
            body.style.display = willOpen ? 'block' : 'none';
            const chev = headerEl.querySelector('.sp-chevron');
            if (chev) chev.textContent = willOpen ? '▼' : '▶';
        };
    })();
    </script>

    <div class="container{% if studio_body_mode == 'wide' %} container-wide{% endif %}">
        <div class="content{% if studio_body_mode == 'wide' %} content-wide{% endif %}">
            {% block content %}{% endblock %}
        </div>
    </div>
    
    <style>
        .footer {
            margin-top: 40px;
            padding: 20px 0;
            text-align: center;
            border-top: 1px solid var(--color-border);
            background: var(--bg-panel);
        }
        
        .donate-btn {
            background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
            color: white;
            border: none;
            padding: 12px 24px;
            border-radius: 8px;
            font-size: 14px;
            font-weight: 600;
            cursor: pointer;
            transition: transform 0.2s, box-shadow 0.2s;
        }
        
        .donate-btn:hover {
            transform: scale(1.05);
            box-shadow: 0 4px 15px rgba(245, 87, 108, 0.4);
        }
        
        /* ── Shared modal backdrop ── */
        .donate-modal, .ui-modal-backdrop {
            display: none;
            position: fixed;
            top: 0; left: 0;
            width: 100%; height: 100%;
            background: rgba(0,0,0,0.7);
            z-index: 1000;
            align-items: center;
            justify-content: center;
        }
        .donate-modal.active, .ui-modal-backdrop.active { display: flex; }

        .donate-modal-content, .ui-modal-box {
            background: var(--bg-panel);
            padding: 30px;
            border-radius: 12px;
            max-width: 500px;
            width: 90%;
            max-height: 90vh;
            overflow-y: auto;
            border: 1px solid var(--color-border);
        }
        
        .donate-modal-header, .ui-modal-header {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-bottom: 20px;
        }
        
        .donate-modal-header h3, .ui-modal-header h3 {
            color: var(--color-primary);
            margin: 0;
        }
        
        .close-modal {
            background: none;
            border: none;
            color: var(--color-muted);
            font-size: 24px;
            cursor: pointer;
        }

        /* ── ui-modal specific ── */
        .ui-modal-body { color: var(--color-text); line-height: 1.5; margin-bottom: 20px; }
        .ui-modal-input {
            width: 100%; padding: 10px;
            border: 1px solid var(--color-border); border-radius: 4px;
            font-size: 14px; background: var(--bg-input); color: var(--color-text);
            margin-top: 10px;
        }
        .ui-modal-footer { display: flex; gap: 10px; justify-content: flex-end; }
        .ui-modal-icon { font-size: 2em; margin-bottom: 10px; display: block; text-align: center; }
        .ui-modal-icon.warn { color: #f39c12; }
        .ui-modal-icon.info { color: #3b82f6; }
        .ui-modal-icon.danger { color: #e74c3c; }
        
        .crypto-address {
            background: var(--bg-accent);
            padding: 12px;
            border-radius: 6px;
            margin: 10px 0;
            font-family: 'Courier New', monospace;
            font-size: 13px;
            word-break: break-all;
            cursor: pointer;
            user-select: all;
            color: var(--color-text);
        }
        
        .crypto-label {
            font-weight: 600;
            margin-top: 15px;
            color: var(--color-text);
        }
        
        .donate-message {
            margin: 20px 0;
            color: var(--color-muted);
            line-height: 1.5;
        }
    </style>
    
    <footer class="footer">
        <div class="container">
            <div style="display: flex; justify-content: center; gap: 15px; align-items: center; flex-wrap: wrap;">
                <button class="donate-btn" onclick="openDonateModal()">
                    <i class="fas fa-heart"></i> <span data-i18n="footer.support_development">Support AISBF Development</span>
                </button>
                
                {% if is_aisbf_cloud %}
                <a href="https://aisbf.cloud/privacy.html" target="_blank" class="btn btn-secondary" style="font-size: 13px; padding: 8px 16px;" data-i18n="footer.privacy_policy">
                    Privacy Policy
                </a>
                <a href="https://aisbf.cloud/tos.html" target="_blank" class="btn btn-secondary" style="font-size: 13px; padding: 8px 16px;" data-i18n="footer.terms_of_service">
                    Terms of Service
                </a>
                <button class="btn btn-secondary" onclick="openContactModal()" style="font-size: 13px; padding: 8px 16px;">
                    <i class="fas fa-envelope"></i> <span data-i18n="footer.contact">Contact</span>
                </button>
                {% endif %}
            </div>
        </div>
    </footer>
    
    <div class="donate-modal" id="donateModal">
        <div class="donate-modal-content">
            <div class="donate-modal-header">
                <h3>Support AISBF</h3>
                <button class="close-modal" onclick="closeDonateModal()">&times;</button>
            </div>
            
            <div class="donate-message">
                <strong>Thank you</strong> for considering a donation. Your support helps maintain AISBF as completely open source and free software.
            </div>
            
            <div class="crypto-label">
                <i class="fab fa-bitcoin"></i> Bitcoin (BTC)
            </div>
            <div class="crypto-address" onclick="copyToClipboard(this)">
                bc1qcpt2uutqkz4456j5r78rjm3gwq03h5fpwmcc5u
            </div>
            
            <div class="crypto-label">
                <i class="fab fa-ethereum"></i> Ethereum (ETH), USDC, USDT (ERC20, Mainnet)
            </div>
            <div class="crypto-address" onclick="copyToClipboard(this)">
                0xdA6dAb526515b5cb556d20269207D43fcc760E51
            </div>
            
            <div style="margin-top: 20px; color: #a0a0a0; font-size: 12px;">
                Click any address to copy it to your clipboard
            </div>
        </div>
    </div>
    
    <!-- Welcome Modal (AISBF Cloud only) -->
    {% if is_aisbf_cloud and not welcome_shown %}
    <div class="donate-modal active" id="welcomeModal">
        <div class="donate-modal-content">
            <div class="donate-modal-header">
                <h3>Welcome to AISBF!</h3>
                <button class="close-modal" onclick="closeWelcomeModal()">&times;</button>
            </div>
            
            <div style="margin: 20px 0;">
                <p style="margin-bottom: 15px;">
                    <strong>Thank you</strong> for being an early adopter! We're currently in heavy development phase.
                </p>
                <p style="margin-bottom: 15px;">
                    You may encounter bugs, service interruptions, or changes during this period.
                </p>
                <p style="margin-bottom: 20px;">
                    Your feedback helps us make AISBF better. Please don't hesitate to reach out!
                </p>
                
                <div style="background: #0f3460; padding: 15px; border-radius: 6px; margin-bottom: 15px;">
                    <p style="margin: 5px 0;"><i class="fab fa-telegram"></i> Telegram: <a href="https://t.me/StefySpora" target="_blank" style="color: #60a5fa;">@StefySpora</a></p>
                    <p style="margin: 5px 0;"><i class="fab fa-reddit"></i> Reddit: <a href="https://reddit.com/u/sporastefy" target="_blank" style="color: #60a5fa;">u/sporastefy</a></p>
                </div>
                
                <div style="display: flex; gap: 10px; margin-top: 20px;">
                    <button class="btn" onclick="openContactModal()">
                        <i class="fas fa-envelope"></i> Send Feedback
                    </button>
                    <button class="btn btn-secondary" onclick="closeWelcomeModal()">
                        Got it!
                    </button>
                </div>
            </div>
        </div>
    </div>
    {% endif %}
    
    <!-- Contact Modal -->
    <div class="donate-modal" id="contactModal">
        <div class="donate-modal-content" style="max-width: 600px;">
            <div class="donate-modal-header">
                <h3>Contact Us</h3>
                <button class="close-modal" onclick="closeContactModal()">&times;</button>
            </div>
            
            <form id="contactForm" onsubmit="submitContactForm(event)">
                {% if not request.session.logged_in %}
                <div class="form-group">
                    <label>Your Email <span style="color: var(--color-error);">*</span></label>
                    <input type="email" id="contactEmail" required placeholder="your@email.com" style="width: 100%;">
                </div>
                {% endif %}
                <div class="form-group">
                    <label>Type</label>
                    <select id="contactType" required>
                        <option value="">Select type...</option>
                        <option value="bug">Bug Report</option>
                        <option value="feature">Feature Request</option>
                        <option value="feedback">Feedback</option>
                        <option value="question">Question</option>
                        <option value="help">Help</option>
                    </select>
                </div>
                
                <div class="form-group">
                    <label>Title</label>
                    <input type="text" id="contactTitle" required placeholder="Brief summary of your message">
                </div>
                
                <div class="form-group">
                    <label>Message</label>
                    <textarea id="contactMessage" required rows="6" placeholder="Describe your issue, request, or feedback in detail..."></textarea>
                </div>
                
                <div style="display: flex; gap: 10px; margin-top: 20px;">
                    <button type="submit" class="btn" id="contactSubmitBtn">
                        <i class="fas fa-paper-plane"></i> Send Message
                    </button>
                    <button type="button" class="btn btn-secondary" onclick="closeContactModal()">
                        Cancel
                    </button>
                </div>
                
                <div id="contactStatus" style="margin-top: 15px;"></div>
            </form>
        </div>
    </div>
    
    <script>
        function openDonateModal() {
            document.getElementById('donateModal').classList.add('active');
        }
        
        function closeDonateModal() {
            document.getElementById('donateModal').classList.remove('active');
        }
        
        function closeWelcomeModal() {
            document.getElementById('welcomeModal').classList.remove('active');
            // Mark welcome modal as shown on server
            fetch('/dashboard/welcome-shown', {
                method: 'POST',
                headers: {'Content-Type': 'application/json'},
                credentials: 'same-origin'
            }).catch(err => console.log('Could not mark welcome as shown:', err));
        }
        
        function openContactModal() {
            document.getElementById('contactModal').classList.add('active');
            if (document.getElementById('welcomeModal')) {
                closeWelcomeModal();
            }
        }
        
        function closeContactModal() {
            document.getElementById('contactModal').classList.remove('active');
            document.getElementById('contactForm').reset();
            document.getElementById('contactStatus').textContent = '';
        }
        
        function submitContactForm(event) {
            event.preventDefault();
            
            const btn = document.getElementById('contactSubmitBtn');
            const status = document.getElementById('contactStatus');
            
            btn.disabled = true;
            btn.textContent = 'Sending...';
            status.textContent = '';
            
            const emailEl = document.getElementById('contactEmail');
            const payload = {
                type: document.getElementById('contactType').value,
                title: document.getElementById('contactTitle').value,
                message: document.getElementById('contactMessage').value
            };
            if (emailEl) payload.email = emailEl.value;

            fetch('/dashboard/contact', {
                method: 'POST',
                headers: {'Content-Type': 'application/json'},
                body: JSON.stringify(payload)
            })
            .then(response => response.json())
            .then(data => {
                if (data.success) {
                    status.innerHTML = '<div class="alert alert-success">Message sent successfully! Thank you for your feedback.</div>';
                    setTimeout(() => closeContactModal(), 2000);
                } else {
                    status.innerHTML = '<div class="alert alert-error">Error: ' + (data.error || 'Failed to send message') + '</div>';
                }
            })
            .catch(err => {
                status.innerHTML = '<div class="alert alert-error">Network error. Please try again later.</div>';
            })
            .finally(() => {
                btn.disabled = false;
                btn.innerHTML = '<i class="fas fa-paper-plane"></i> Send Message';
            });
        }
        
        function copyToClipboard(element) {
            const text = element.textContent.trim();
            navigator.clipboard.writeText(text).then(() => {
                const original = element.textContent;
                element.textContent = 'Copied!';
                setTimeout(() => {
                    element.textContent = original;
                }, 1500);
            }).catch(err => {
                // Fallback for browsers that don't support clipboard API
                const textarea = document.createElement('textarea');
                textarea.value = text;
                textarea.style.position = 'fixed';
                textarea.style.opacity = '0';
                document.body.appendChild(textarea);
                textarea.select();
                try {
                    document.execCommand('copy');
                    const original = element.textContent;
                    element.textContent = 'Copied!';
                    setTimeout(() => {
                        element.textContent = original;
                    }, 1500);
                } catch (e) {
                    console.error('Failed to copy:', e);
                }
                document.body.removeChild(textarea);
            });
        }
        
        // Close modals when clicking outside
        const donateModal = document.getElementById('donateModal');
        if (donateModal) {
            donateModal.addEventListener('click', function(e) {
                if (e.target === this) {
                    closeDonateModal();
                }
            });
        }
        
        const welcomeModal = document.getElementById('welcomeModal');
        if (welcomeModal) {
            welcomeModal.addEventListener('click', function(e) {
                if (e.target === this) {
                    closeWelcomeModal();
                }
            });
        }
        
        const contactModal = document.getElementById('contactModal');
        if (contactModal) {
            contactModal.addEventListener('click', function(e) {
                if (e.target === this) {
                    closeContactModal();
                }
            });
        }
    </script>
    
    <!-- Global UI Modal System -->
    <div class="ui-modal-backdrop" id="uiModal">
        <div class="ui-modal-box" style="max-width:420px;">
            <div class="ui-modal-header">
                <h3 id="uiModalTitle">Notice</h3>
                <button class="close-modal" id="uiModalClose">&times;</button>
            </div>
            <div class="ui-modal-body">
                <span id="uiModalIcon" class="ui-modal-icon" style="display:none;"></span>
                <div id="uiModalMsg"></div>
                <input class="ui-modal-input" id="uiModalInput" type="text" style="display:none;" placeholder="">
            </div>
            <div class="ui-modal-footer" id="uiModalFooter"></div>
        </div>
    </div>
    <script>
    (function(){
        const backdrop = document.getElementById('uiModal');
        const titleEl  = document.getElementById('uiModalTitle');
        const iconEl   = document.getElementById('uiModalIcon');
        const msgEl    = document.getElementById('uiModalMsg');
        const inputEl  = document.getElementById('uiModalInput');
        const footerEl = document.getElementById('uiModalFooter');
        const closeBtn = document.getElementById('uiModalClose');
        let _resolve = null;

        function open(opts) {
            titleEl.textContent = opts.title || 'Notice';
            if (opts.html) msgEl.innerHTML = opts.message || '';
            else msgEl.textContent = opts.message || '';
            if (opts.icon) { iconEl.className = 'ui-modal-icon ' + (opts.iconClass||'info'); iconEl.textContent = opts.icon; iconEl.style.display='block'; }
            else { iconEl.style.display='none'; }
            inputEl.style.display = opts.prompt ? 'block' : 'none';
            inputEl.value = opts.defaultValue || '';
            inputEl.placeholder = opts.placeholder || '';
            footerEl.innerHTML = '';
            (opts.buttons||[]).forEach(b => {
                const btn = document.createElement('button');
                btn.textContent = b.label;
                btn.className = 'btn ' + (b.cls||'btn-secondary');
                btn.onclick = () => { close(); _resolve(b.value); };
                footerEl.appendChild(btn);
            });
            backdrop.classList.add('active');
            if (opts.prompt) setTimeout(()=>inputEl.focus(),50);
        }

        function close() { backdrop.classList.remove('active'); }

        closeBtn.onclick = () => { close(); if(_resolve) _resolve(null); };
        backdrop.addEventListener('click', e => { if(e.target===backdrop){ close(); if(_resolve) _resolve(null); } });

        window.showAlert = function(message, title, icon, iconClass) {
            return new Promise(res => {
                _resolve = res;
                open({ title: title||'Notice', message, icon: icon||'ℹ️', iconClass: iconClass||'info',
                    buttons: [{label:'OK', value:true, cls:'btn'}] });
            });
        };
        window.showConfirm = function(message, title, icon, iconClass, html) {
            return new Promise(res => {
                _resolve = res;
                open({ title: title||'Confirm', message, html, icon: icon||'⚠️', iconClass: iconClass||'warn',
                    buttons: [
                        {label:'Cancel', value:false, cls:'btn-secondary'},
                        {label:'Confirm', value:true, cls:'btn'}
                    ] });
            });
        };
        window.showDangerConfirm = function(message, title) {
            return new Promise(res => {
                _resolve = res;
                open({ title: title||'Warning', message, icon:'🗑️', iconClass:'danger',
                    buttons: [
                        {label:'Cancel', value:false, cls:'btn-secondary'},
                        {label:'Delete', value:true, cls:'btn btn-danger'}
                    ] });
            });
        };
        window.showConfirm = function(message, title, confirmLabel, confirmCls) {
            return new Promise(res => {
                _resolve = res;
                open({ title: title||'Confirm', message, icon:'❓', iconClass:'',
                    buttons: [
                        {label:'Cancel', value:false, cls:'btn-secondary'},
                        {label: confirmLabel||'OK', value:true, cls:'btn ' + (confirmCls||'')}
                    ] });
            });
        };
        window.showPrompt = function(message, defaultValue, placeholder, title) {
            return new Promise(res => {
                _resolve = v => res(v === null ? null : inputEl.value || null);
                open({ title: title||'Input', message, prompt:true, defaultValue, placeholder,
                    buttons: [
                        {label:'Cancel', value:null, cls:'btn-secondary'},
                        {label:'OK', value:true, cls:'btn'}
                    ] });
                // OK button needs to read input value
                const okBtn = footerEl.lastChild;
                okBtn.onclick = () => { const v = inputEl.value.trim(); close(); res(v||null); };
            });
        };
    })();
    </script>

    {% block extra_js %}{% endblock %}

    {% if request.session.user_id %}
    <script>
    (function() {
        let _notifData = [];
        let _pollInterval = null;

        function fmtTime(ts) {
            if (!ts) return '';
            const d = new Date(ts.replace(' ', 'T') + 'Z');
            const now = new Date();
            const diff = Math.floor((now - d) / 1000);
            if (diff < 60) return 'just now';
            if (diff < 3600) return Math.floor(diff/60) + 'm ago';
            if (diff < 86400) return Math.floor(diff/3600) + 'h ago';
            return Math.floor(diff/86400) + 'd ago';
        }

        function renderNotifications(items) {
            const list = document.getElementById('notif-list');
            if (!items.length) {
                list.innerHTML = '<div class="notif-empty"><i class="fas fa-check-circle" style="color:#4ade80;"></i> No notifications</div>';
                return;
            }
            list.innerHTML = items.map(n => `
                <div class="notif-item ${n.is_read ? 'read' : 'unread'}" data-id="${n.id}" onclick="readNotif(${n.id}, this)">
                    <div class="notif-item-body">
                        <div class="notif-item-title">${escHtml(n.title)}</div>
                        <div class="notif-item-msg">${escHtml(n.message)}</div>
                        <div class="notif-item-time">${fmtTime(n.created_at)}</div>
                    </div>
                    <span class="notif-item-del" title="Delete" onclick="delNotif(event, ${n.id})"><i class="fas fa-times"></i></span>
                </div>
            `).join('');
        }

        function escHtml(s) {
            return String(s).replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;').replace(/"/g,'&quot;');
        }

        function updateBadge(count) {
            const badge = document.getElementById('notif-badge');
            if (!badge) return;
            if (count > 0) {
                badge.textContent = count > 99 ? '99+' : count;
                badge.style.display = 'block';
            } else {
                badge.style.display = 'none';
            }
        }

        window.loadNotifications = async function() {
            try {
                const r = await fetch('/dashboard/api/notifications');
                const data = await r.json();
                _notifData = data.notifications || [];
                renderNotifications(_notifData);
                updateBadge(_notifData.filter(n => !n.is_read).length);
            } catch(e) {}
        };

        window.toggleNotifDropdown = function(e) {
            e.stopPropagation();
            const dd = document.getElementById('notif-dropdown');
            const isOpen = dd.classList.contains('active');
            // Close account dropdown if open
            document.getElementById('account-dropdown')?.classList.remove('active');
            dd.classList.toggle('active');
            if (!isOpen) loadNotifications();
        };

        window.readNotif = async function(id, el) {
            if (!el.classList.contains('unread')) return;
            el.classList.replace('unread', 'read');
            try {
                await fetch('/dashboard/api/notifications/' + id + '/read', {method:'POST'});
                const unread = document.querySelectorAll('.notif-item.unread').length;
                updateBadge(unread);
            } catch(e) {}
        };

        window.delNotif = async function(e, id) {
            e.stopPropagation();
            const item = document.querySelector('.notif-item[data-id="' + id + '"]');
            if (item) item.remove();
            try {
                await fetch('/dashboard/api/notifications/' + id, {method:'DELETE'});
                const remaining = document.querySelectorAll('.notif-item').length;
                if (!remaining) renderNotifications([]);
                const unread = document.querySelectorAll('.notif-item.unread').length;
                updateBadge(unread);
            } catch(e) {}
        };

        window.markAllNotifRead = async function(e) {
            e.stopPropagation();
            document.querySelectorAll('.notif-item.unread').forEach(el => el.classList.replace('unread', 'read'));
            updateBadge(0);
            try { await fetch('/dashboard/api/notifications/read-all', {method:'POST'}); } catch(e) {}
        };

        // Close notification dropdown when clicking outside
        document.addEventListener('click', function(ev) {
            const menu = document.getElementById('notif-menu');
            const dd = document.getElementById('notif-dropdown');
            if (menu && dd && !menu.contains(ev.target)) {
                dd.classList.remove('active');
            }
        });

        // Poll unread count every 60 seconds
        async function pollCount() {
            try {
                const r = await fetch('/dashboard/api/notifications/count');
                const data = await r.json();
                updateBadge(data.count || 0);
            } catch(e) {}
        }

        pollCount();
        _pollInterval = setInterval(pollCount, 60000);
    })();
    </script>
    {% endif %}
</body>
</html>
