<!DOCTYPE html>
<html lang="en" data-theme="hashed">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta name="csrf-token" content="{{ csrf_token() }}">
    <meta name="user-id" content="{{ session.username|default('anonymous', true) }}">
    <title>{% block title %}Deep Research System{% endblock %}</title>
    <link rel="icon" type="image/png" href="/static/favicon.png">

    <!-- FOUC Prevention: Apply theme before any rendering -->
    <!-- Theme list is auto-detected from themes.css by ThemeHelper -->
    <script>
        (function() {
            // Auto-detected from CSS - no need to manually update this list
            var validThemes = {{ get_themes_json()|safe }};
            // Store theme metadata for JavaScript (used by theme.js)
            window.LDR_THEME_METADATA = {{ get_theme_metadata()|safe }};

            var userId = {{ session.username|default("anonymous", true)|tojson }};
            var storageKey = 'ldr-theme-' + userId;
            var theme = localStorage.getItem(storageKey) || 'system';
            // Validate theme
            if (validThemes.indexOf(theme) === -1) {
                theme = 'hashed';
            }
            var effectiveTheme = theme;
            if (theme === 'system') {
                effectiveTheme = window.matchMedia('(prefers-color-scheme: dark)').matches ? 'hashed' : 'sepia';
            }
            document.documentElement.setAttribute('data-theme', effectiveTheme);
        })();
    </script>

    <!-- Vite HMR for development -->
    {{ vite_hmr() }}

    <!-- SafeLogger must load before app.js which uses it at init -->
    <script src="/static/js/security/safe-logger.js"></script>
    <!-- Load all vendor dependencies and styles through Vite -->
    {{ vite_asset('js/app.js') }}

    <!-- Keep local styles that aren't bundled by Vite -->
    <!-- Note: styles.css is already bundled via app.js import; do not add a duplicate link -->
    <link rel="stylesheet" href="/static/css/help-system.css">
    <link rel="stylesheet" href="/static/css/mobile-navigation.css">
    <link rel="stylesheet" href="/static/css/mobile-responsive.css">

    <!-- Theme overrides must load AFTER base styles to take precedence -->
    <link rel="stylesheet" href="/static/css/themes.css">

    <!--
        Egress-scope visual cues
        ========================
        Inline (not in styles.css) because styles.css is bundled by Vite —
        editing the source doesn't take effect without a rebuild, and these
        cues need to ship with the next reload. body[data-scope=…] is
        server-rendered by base.html below from the user's saved
        policy.egress_scope; JS on the research form updates it live when
        the dropdown changes (see static/js/components/research.js).

        Palette:
          BOTH         → no left-border accent (default state, no extra cue)
          PUBLIC_ONLY  → blue #3b82f6 (informational "public sources only")
          PRIVATE_ONLY → teal #14a37f (privacy mode)
          STRICT       → violet #8b5cf6 (locked to a single engine)
        Risk ordering (data exfil): BOTH > PUBLIC_ONLY > STRICT/PRIVATE_ONLY.
        BOTH is the riskiest because it permits local engines AND a cloud
        LLM in the same run — local-data-to-cloud leakage happens through
        the LLM call, not the search egress itself. PUBLIC_ONLY blocks
        local engines so local data never enters the pipeline; that
        active choice is informational (blue), not a deeper warning.
        The "Public search egress enabled" banner does the actual nag.
        Red intentionally avoided.
    -->
    <style>
        .ldr-card.ldr-research-card,
        #chat-page,
        .ldr-chat-container {
            transition: border-left-color 0.2s ease, background-color 0.2s ease;
            border-left: 5px solid transparent;
        }
        #query,
        #chat-input {
            transition: border-color 0.2s ease, box-shadow 0.2s ease;
        }
        /* BOTH (default) has NO body[data-scope] rule — the
           transparent left border above stays, the textarea uses its
           default border, and the warning banner does the nagging. */
        body[data-scope="public_only"] .ldr-card.ldr-research-card,
        body[data-scope="public_only"] #chat-page,
        body[data-scope="public_only"] .ldr-chat-container {
            border-left-color: #3b82f6;
            background-color: rgba(59, 130, 246, 0.03);
        }
        body[data-scope="public_only"] #query,
        body[data-scope="public_only"] #chat-input {
            border-color: #3b82f6;
            box-shadow: 0 0 0 1px rgba(59, 130, 246, 0.22);
        }
        body[data-scope="private_only"] .ldr-card.ldr-research-card,
        body[data-scope="private_only"] #chat-page,
        body[data-scope="private_only"] .ldr-chat-container {
            border-left-color: #14a37f;
            background-color: rgba(20, 163, 127, 0.03);
        }
        body[data-scope="private_only"] #query,
        body[data-scope="private_only"] #chat-input {
            border-color: #14a37f;
            box-shadow: 0 0 0 1px rgba(20, 163, 127, 0.25);
        }
        body[data-scope="strict"] .ldr-card.ldr-research-card,
        body[data-scope="strict"] #chat-page,
        body[data-scope="strict"] .ldr-chat-container {
            border-left-color: #8b5cf6;
            background-color: rgba(139, 92, 246, 0.035);
        }
        body[data-scope="strict"] #query,
        body[data-scope="strict"] #chat-input {
            border-color: #8b5cf6;
            box-shadow: 0 0 0 1px rgba(139, 92, 246, 0.25);
        }
    </style>

    <!-- Force hide sidebar on mobile with inline CSS for highest priority -->
    <style>
        @media (max-width: 767px) {
            /* Absolutely hide the desktop sidebar on mobile */
            .ldr-sidebar:not(.active),
            aside.ldr-sidebar:not(.active),
            .ldr-app-container > aside {
                display: none !important;
                visibility: hidden !important;
                width: 0 !important;
                height: 0 !important;
                position: absolute !important;
                left: -9999px !important;
            }

            /* Ensure app container doesn't use flex on mobile */
            .ldr-app-container {
                display: block !important;
            }

            /* Main content takes full width */
            .ldr-main-content {
                margin-left: 0 !important;
                width: 100% !important;
                max-width: 100vw !important;
                box-sizing: border-box !important;
                overflow-x: hidden !important;
            }

            /* Top bar must not overflow viewport */
            .ldr-top-bar {
                max-width: 100vw !important;
                box-sizing: border-box !important;
            }
        }
    </style>

    {% block extra_head %}{% endblock %}
</head>
<body data-scope="{{ egress_scope or 'both' }}">
    <!-- Skip to content link for keyboard/screen reader users -->
    <a href="#main-content" class="ldr-skip-link">Skip to main content</a>

    <div class="ldr-app-container">
        <!-- Sidebar -->
        {% include 'components/sidebar.html' %}

        <!-- Main Content -->
        <main id="main-content" class="ldr-main-content">
            {% if session.username %}
            <div class="ldr-top-bar">
                <div class="ldr-top-bar-left">
                    <!-- Theme dropdown selector -->
                    <div class="ldr-theme-selector">
                        <i aria-hidden="true" class="fas fa-palette ldr-theme-icon"></i>
                        <select id="theme-dropdown" class="ldr-theme-dropdown"
                                title="Select theme" aria-label="Select color theme">
                            <!-- Options populated by theme.js -->
                        </select>
                    </div>
                </div>
                <div class="ldr-top-bar-right">
                    <div class="ldr-user-menu">
                        <span class="ldr-user-info">
                            <i aria-hidden="true" class="fas fa-user"></i> {{ session.username }}
                        </span>
                        <form action="{{ url_for('auth.logout') }}" method="POST" class="ldr-logout-form" id="logout-form" style="display: inline;">
                            <input type="hidden" name="csrf_token" value="{{ csrf_token() }}"/>
                            <a href="#" class="ldr-logout-btn" onclick="event.preventDefault(); document.getElementById('logout-form').submit(); return false;">
                                <i aria-hidden="true" class="fas fa-sign-out-alt"></i> Logout
                            </a>
                        </form>
                    </div>
                </div>
            </div>
            {% endif %}

            {% block content %}{% endblock %}

            <!-- Collapsible Log Panel is included in specific pages -->
        </main>
    </div>

    <!-- Mobile Tab Bar -->
    {# Mobile navigation now handled dynamically by mobile-navigation.js #}
    {# {% include 'components/mobile_nav.html' %} #}

    <!-- Common Templates -->
    {% block templates %}{% endblock %}

    <!-- Scripts -->

    <!-- Backend constants injected from Python (single source of truth) -->
    <!-- Source: src/local_deep_research/constants.py::ResearchStatus -->
    <!-- Injected by: src/local_deep_research/web/app_factory.py (inject_frontend_constants) -->
    <!-- Consumed by: src/local_deep_research/web/static/js/config/constants.js (ResearchStates helpers) -->
    <!-- Must remain a bare <script> (no defer) so window.* is set before defer-ed scripts run. -->
    <script>
        window.RESEARCH_STATUS = Object.freeze({{ research_status_enum | tojson }});
        window.RESEARCH_TERMINAL_STATES = Object.freeze(new Set({{ research_terminal_states | tojson }}));
        window.LDR_LOG_LIMITS = Object.freeze({{ log_limits | tojson }});
    </script>

    <!-- Constants and URL Configuration -->
    <script defer src="/static/js/config/constants.js"></script>
    <script defer src="/static/js/config/urls.js"></script>

    <!-- Logo click handler -->
    <script>
        document.addEventListener('DOMContentLoaded', function() {
            const logoLink = document.getElementById('logo-link');
            if (logoLink) {
                logoLink.addEventListener('click', function() {
                    window.location.href = '/';
                });
            }
        });
    </script>

    <!-- All vendor libraries are now loaded through Vite in the <head> section -->

    <!-- Core JS
         IMPORTANT: ui.js defines the global `escapeHtmlFallback` constant.
         All subsequent scripts can reference it directly. Do NOT redeclare
         escapeHtmlFallback at top-level in any other script — it will cause
         a SyntaxError and crash the page. See the comment in ui.js. -->
    <script defer src="/static/js/services/theme.js"></script>
    <script defer src="/static/js/services/formatting.js"></script>
    <script defer src="/static/js/services/ui.js"></script>
    <script defer src="/static/js/services/api.js"></script>
    <script defer src="/static/js/services/socket.js"></script>
    <script defer src="/static/js/services/keyboard.js"></script>
    <script defer src="/static/js/services/help.js"></script>

    <!-- Security Utilities -->
    <script defer src="/static/js/security/xss-protection.js"></script>

    <!-- Form Utilities -->
    <script defer src="/static/js/utils/form-validation.js"></script>
    <script defer src="/static/js/utils/sse-completion.js"></script>
    <script defer src="/static/js/utils/value-helpers.js"></script>
    <script defer src="/static/js/utils/provider-options.js"></script>
    <script defer src="/static/js/utils/alert-helpers.js"></script>
    <script defer src="/static/js/utils/format-bytes.js"></script>

    <!-- Shared Components -->
    <script defer src="/static/js/utils/log-helpers.js"></script>
    <script defer src="/static/js/components/logpanel.js"></script>

    <!-- Page-specific Components -->
    {% block component_scripts %}{% endblock %}

    <!-- Page-specific JS -->
    {% block page_scripts %}{% endblock %}

    <script>
        // Configure marked to not use eval
        if (typeof marked !== 'undefined') {
            marked.setOptions({
                headerIds: false,
                mangle: false,
                smartypants: false
            });
        }

        // Configure html2canvas to avoid using eval if possible
        if (typeof html2canvas !== 'undefined') {
            window.html2canvas_noSandbox = true;
        }
    </script>

    <script defer src="/static/js/components/settings_sync.js"></script>

    <!-- Mobile Navigation -->
    <script defer src="/static/js/security/url-validator.js"></script>
    <script defer src="/static/js/security/safe-fetch.js"></script>
    <script defer src="/static/js/mobile-navigation.js"></script>
</body>
</html>
