<!DOCTYPE html>
<html lang="en" data-theme="light" data-bs-theme="light">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">
    <title>{% block title %}mc-webui{% endblock %}</title>

    <!-- Favicon -->
    <link rel="apple-touch-icon" sizes="180x180" href="{{ url_for('static', filename='images/apple-touch-icon.png') }}">
    <link rel="icon" type="image/png" sizes="32x32" href="{{ url_for('static', filename='images/favicon-32x32.png') }}">
    <link rel="icon" type="image/png" sizes="16x16" href="{{ url_for('static', filename='images/favicon-16x16.png') }}">
    <link rel="manifest" href="{{ url_for('static', filename='manifest.json') }}">
    <link rel="shortcut icon" href="{{ url_for('static', filename='favicon.ico') }}">

    <!-- Theme: apply saved preference before CSS loads to prevent flash -->
    <script>
        (function() {
            var t = localStorage.getItem('mc-webui-theme') || 'light';
            document.documentElement.setAttribute('data-theme', t);
            document.documentElement.setAttribute('data-bs-theme', t);
        })();
    </script>

    <!-- Sidebar breakpoint: apply saved preference before CSS loads to prevent layout flash -->
    <script>
        (function() {
            try {
                var stored = parseInt(localStorage.getItem('mc-webui-sidebar-breakpoint'), 10);
                var bp = (isNaN(stored) || stored < 600 || stored > 2000) ? 992 : stored;
                if (window.innerWidth >= bp) {
                    document.documentElement.classList.add('layout-wide');
                }
            } catch (e) {}
        })();
    </script>

    <!-- Bootstrap 5 CSS (local) -->
    <link href="{{ url_for('static', filename='vendor/bootstrap/css/bootstrap.min.css') }}" rel="stylesheet">
    <!-- Bootstrap Icons (local) -->
    <link rel="stylesheet" href="{{ url_for('static', filename='vendor/bootstrap-icons/bootstrap-icons.css') }}">

    <!-- Leaflet CSS -->
    <link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css"
          integrity="sha256-p4NxAoJBhIIN+hmNHrzRCf9tD/miZyoHS5obTRR9BMY="
          crossorigin="" />

    <!-- Custom CSS -->
    <link rel="stylesheet" href="{{ url_for('static', filename='css/style.css') }}">
    <!-- Theme CSS (light/dark mode) -->
    <link rel="stylesheet" href="{{ url_for('static', filename='css/theme.css') }}">

    {% block extra_head %}{% endblock %}
</head>
<body>
    <!-- Navbar -->
    <nav class="navbar navbar-dark bg-primary">
        <div class="container-fluid">
            <span class="navbar-brand mb-0 h1">
                <i class="bi bi-broadcast"></i> mc-webui
                {% if device_name %}
                <small class="text-white-50 d-none d-sm-inline">- {{ device_name }}</small>
                {% endif %}
                {% if transport_type == 'ble' %}
                <span class="badge bg-info ms-1 d-none d-sm-inline" title="Bluetooth Low Energy">BLE</span>
                {% elif transport_type == 'tcp' %}
                <span class="badge bg-warning text-dark ms-1 d-none d-sm-inline" title="TCP connection">TCP</span>
                {% endif %}
            </span>
            <div class="d-flex align-items-center gap-2">
                <div id="notificationBell" class="btn btn-outline-light position-relative navbar-touch-btn" style="cursor: pointer;" onclick="markAllChannelsRead()" title="Mark all as read">
                    <i class="bi bi-bell"></i>
                </div>
                <div class="position-relative channel-mobile-selector" id="channelSelectorWrapper" style="min-width: 80px; max-width: 140px;">
                    <input type="text"
                           id="channelSelectorInput"
                           class="form-control form-select navbar-touch-select"
                           placeholder="Public"
                           autocomplete="off"
                           title="Select channel"
                           style="cursor: pointer;">
                    <div id="channelSelectorDropdown" class="channel-selector-dropdown" style="display: none;"></div>
                </div>
                <button class="btn btn-outline-light navbar-touch-btn" data-bs-toggle="offcanvas" data-bs-target="#mainMenu" title="Menu">
                    <i class="bi bi-list"></i>
                </button>
            </div>
        </div>
    </nav>

    <!-- Offcanvas Menu -->
    <div class="offcanvas offcanvas-end" tabindex="-1" id="mainMenu">
        <div class="offcanvas-header">
            <h5 class="offcanvas-title"><i class="bi bi-menu-button-wide"></i> Menu</h5>
            <button type="button" class="btn-close" data-bs-dismiss="offcanvas"></button>
        </div>
        <div class="px-3 pb-2 text-muted small border-bottom">
            <div class="d-flex align-items-center justify-content-between">
                <span id="versionDisplay">
                    <i class="bi bi-tag"></i> <span id="versionText">{{ version }}</span>
                    <span class="badge bg-secondary ms-1" id="branchBadge">{{ git_branch }}</span>
                </span>
                <button id="checkUpdateBtn" class="btn btn-sm btn-outline-secondary py-0 px-1" title="Check for updates">
                    <i class="bi bi-arrow-repeat" id="checkUpdateIcon"></i>
                </button>
            </div>
            <div id="updateLinkContainer" class="d-none mt-1"></div>
        </div>
        <div class="offcanvas-body">
            <div class="list-group list-group-flush">
                <!-- Messages -->
                <button id="menu-filter" class="list-group-item list-group-item-action d-flex align-items-center gap-3 d-none" type="button">
                    <i class="bi bi-funnel" style="font-size: 1.5rem;"></i>
                    <div class="flex-grow-1">
                        <div>Filter messages</div>
                        <small class="d-block text-muted">Filter current chat</small>
                    </div>
                </button>
                <button id="menu-search" class="list-group-item list-group-item-action d-flex align-items-center gap-3 d-none" type="button"
                        data-bs-toggle="modal" data-bs-target="#searchModal" data-bs-dismiss="offcanvas">
                    <i class="bi bi-search" style="font-size: 1.5rem;"></i>
                    <div class="flex-grow-1">
                        <div>Search messages</div>
                        <small class="d-block text-muted">Search all messages</small>
                    </div>
                </button>
                <button id="menu-dm" class="list-group-item list-group-item-action d-flex align-items-center gap-3 d-none" type="button"
                        data-bs-toggle="modal" data-bs-target="#dmModal" data-bs-dismiss="offcanvas">
                    <i class="bi bi-envelope-fill" style="font-size: 1.5rem;"></i>
                    <div class="flex-grow-1">
                        <div class="d-flex justify-content-between align-items-center">
                            <span>Direct Messages</span>
                            <span class="badge rounded-pill bg-danger d-none menu-badge-dm">0</span>
                        </div>
                        <small class="d-block text-muted">Private conversations</small>
                    </div>
                </button>
                <button id="menu-contacts" class="list-group-item list-group-item-action d-flex align-items-center gap-3 d-none" type="button"
                        data-bs-toggle="modal" data-bs-target="#contactsModal" data-bs-dismiss="offcanvas">
                    <i class="bi bi-person-lines-fill" style="font-size: 1.5rem;"></i>
                    <div class="flex-grow-1">
                        <div class="d-flex justify-content-between align-items-center">
                            <span>Contact Management</span>
                            <span class="badge rounded-pill bg-warning d-none menu-badge-contacts">0</span>
                        </div>
                        <small class="d-block text-muted">Manage known contacts</small>
                    </div>
                </button>
                <button class="list-group-item list-group-item-action d-flex align-items-center gap-3" data-bs-toggle="modal" data-bs-target="#channelsModal" data-bs-dismiss="offcanvas">
                    <i class="bi bi-broadcast-pin" style="font-size: 1.5rem;"></i>
                    <span>Manage Channels</span>
                </button>
                <div class="list-group-item">
                    <div class="d-flex align-items-center gap-3 mb-2">
                        <i class="bi bi-calendar3" style="font-size: 1.5rem;"></i>
                        <label for="dateSelector" class="form-label mb-0">Message History</label>
                    </div>
                    <select id="dateSelector" class="form-select" title="Select date">
                        <option value="">Today (Live)</option>
                        <!-- Archive dates loaded dynamically via JavaScript -->
                    </select>
                </div>

                <!-- Network -->
                <div class="list-group-item py-2 mt-2">
                    <small class="text-muted fw-bold text-uppercase">Network</small>
                </div>
                <button class="list-group-item list-group-item-action d-flex align-items-center gap-3" id="advertBtn" title="Send single advertisement (recommended for normal operation)">
                    <i class="bi bi-megaphone" style="font-size: 1.5rem;"></i>
                    <div>
                        <span>Send Advert</span>
                        <small class="d-block text-muted">Announce presence (normal)</small>
                    </div>
                </button>
                <button class="list-group-item list-group-item-action d-flex align-items-center gap-3 text-warning" id="floodadvBtn" title="Flood advertisement - use sparingly! High airtime usage.">
                    <i class="bi bi-broadcast" style="font-size: 1.5rem;"></i>
                    <div>
                        <span>Flood Advert</span>
                        <small class="d-block text-muted">Network recovery only!</small>
                    </div>
                </button>

                <!-- Tools -->
                <div class="list-group-item py-2 mt-2">
                    <small class="text-muted fw-bold text-uppercase">Tools</small>
                </div>
                <button class="list-group-item list-group-item-action d-flex align-items-center gap-3"
                        id="mapBtn" title="Show all contacts with GPS on map">
                    <i class="bi bi-map" style="font-size: 1.5rem;"></i>
                    <div>
                        <span>Map</span>
                        <small class="d-block text-muted">All contacts with GPS</small>
                    </div>
                </button>
                <button id="consoleBtn" class="list-group-item list-group-item-action d-flex align-items-center gap-3" data-bs-toggle="modal" data-bs-target="#consoleModal" data-bs-dismiss="offcanvas">
                    <i class="bi bi-terminal" style="font-size: 1.5rem;"></i>
                    <div>
                        <span>Console</span>
                        <small class="d-block text-muted">Direct meshcli commands</small>
                    </div>
                </button>

                <!-- System -->
                <div class="list-group-item py-2 mt-2">
                    <small class="text-muted fw-bold text-uppercase">System</small>
                </div>
                <button id="deviceInfoBtn" class="list-group-item list-group-item-action d-flex align-items-center gap-3" data-bs-toggle="modal" data-bs-target="#deviceInfoModal" data-bs-dismiss="offcanvas">
                    <i class="bi bi-cpu" style="font-size: 1.5rem;"></i>
                    <span>Device Info</span>
                </button>
                <button id="logsBtn" class="list-group-item list-group-item-action d-flex align-items-center gap-3" data-bs-toggle="modal" data-bs-target="#logsModal" data-bs-dismiss="offcanvas">
                    <i class="bi bi-journal-text" style="font-size: 1.5rem;"></i>
                    <div>
                        <span>System Log</span>
                        <small class="d-block text-muted">Real-time application logs</small>
                    </div>
                </button>
                <button id="menu-settings" class="list-group-item list-group-item-action d-flex align-items-center gap-3 d-none" data-bs-toggle="modal" data-bs-target="#settingsModal" data-bs-dismiss="offcanvas">
                    <i class="bi bi-gear" style="font-size: 1.5rem;"></i>
                    <div>
                        <span>Settings</span>
                        <small class="d-block text-muted">Application settings</small>
                    </div>
                </button>
                <button class="list-group-item list-group-item-action d-flex align-items-center gap-3" data-bs-toggle="modal" data-bs-target="#backupModal" data-bs-dismiss="offcanvas">
                    <i class="bi bi-database-down" style="font-size: 1.5rem;"></i>
                    <div>
                        <span>Backup</span>
                        <small class="d-block text-muted">Database backup & restore</small>
                    </div>
                </button>
            </div>
        </div>
    </div>

    <!-- Main Content -->
    <main>
        {% block content %}{% endblock %}
    </main>

    <!-- Channels Management Modal -->
    <div class="modal fade" id="channelsModal" tabindex="-1">
        <div class="modal-dialog modal-lg">
            <div class="modal-content">
                <div class="modal-header">
                    <h5 class="modal-title"><i class="bi bi-broadcast-pin"></i> Manage Channels</h5>
                    <button type="button" class="btn-close" data-bs-dismiss="modal"></button>
                </div>
                <div class="modal-body">
                    <!-- Channel List -->
                    <h6>Your Channels</h6>
                    <div id="channelsList" class="list-group mb-3">
                        <div class="text-center text-muted py-3">
                            <div class="spinner-border spinner-border-sm"></div> Loading...
                        </div>
                    </div>

                    <!-- Actions -->
                    <div class="btn-group w-100 mb-3" role="group">
                        <button type="button" class="btn btn-primary" data-bs-toggle="collapse" data-bs-target="#addChannelForm">
                            <i class="bi bi-plus-circle"></i> Add New Channel
                        </button>
                        <button type="button" class="btn btn-success" data-bs-toggle="collapse" data-bs-target="#joinChannelForm">
                            <i class="bi bi-box-arrow-in-right"></i> Join Existing
                        </button>
                    </div>

                    <!-- Add Channel Form (collapsed) -->
                    <div class="collapse" id="addChannelForm">
                        <div class="card card-body mb-3">
                            <h6>Create New Channel</h6>
                            <form id="createChannelForm">
                                <div class="mb-2">
                                    <label for="newChannelName" class="form-label">Channel Name</label>
                                    <input type="text" class="form-control" id="newChannelName"
                                           placeholder="e.g., Malopolska"
                                           pattern="[a-zA-Z0-9_\-]+"
                                           required>
                                    <small class="text-muted">Only letters, numbers, _ and -</small>
                                </div>
                                <button type="submit" class="btn btn-primary">
                                    <i class="bi bi-plus-circle"></i> Create & Auto-generate Key
                                </button>
                            </form>
                        </div>
                    </div>

                    <!-- Join Channel Form (collapsed) -->
                    <div class="collapse" id="joinChannelForm">
                        <div class="card card-body mb-3">
                            <h6>Join Existing Channel</h6>
                            <form id="joinChannelFormSubmit">
                                <div class="mb-2">
                                    <label for="joinChannelName" class="form-label">Channel Name</label>
                                    <input type="text" class="form-control" id="joinChannelName" required>
                                </div>
                                <div class="mb-2">
                                    <label for="joinChannelKey" class="form-label">Channel Key (32 hex chars) <small class="text-muted">- optional for channels starting with #</small></label>
                                    <input type="text" class="form-control" id="joinChannelKey"
                                           placeholder="485af7e164459d280d8818d9c99fb30d (leave empty for # channels)"
                                           pattern="[a-fA-F0-9]{32}"
                                           maxlength="32">
                                </div>
                                <div class="d-flex gap-2">
                                    <button type="submit" class="btn btn-success">
                                        <i class="bi bi-box-arrow-in-right"></i> Join Channel
                                    </button>
                                    <button type="button" class="btn btn-secondary" id="scanQRBtn">
                                        <i class="bi bi-qr-code-scan"></i> Scan QR Code
                                    </button>
                                </div>
                            </form>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>

    <!-- Set Channel Region Scope Modal -->
    <div class="modal fade" id="regionPickerModal" tabindex="-1">
        <div class="modal-dialog modal-dialog-centered">
            <div class="modal-content">
                <div class="modal-header">
                    <h5 class="modal-title">
                        <i class="bi bi-pin-map"></i>
                        Set Region Scope for <span id="regionPickerChannelName" class="fw-bold"></span>
                    </h5>
                    <button type="button" class="btn-close" data-bs-dismiss="modal"></button>
                </div>
                <div class="modal-body">
                    <div class="alert alert-info py-2 small mb-3">
                        <i class="bi bi-info-circle"></i> Only repeaters allowing the selected region will forward messages from this channel.
                    </div>
                    <div id="regionPickerList" class="list-group mb-0"></div>
                </div>
                <div class="modal-footer py-2">
                    <button type="button" class="btn btn-secondary btn-sm" data-bs-dismiss="modal">Cancel</button>
                    <button type="button" class="btn btn-primary btn-sm" id="regionPickerSaveBtn">Save</button>
                </div>
            </div>
        </div>
    </div>

    <!-- Share Channel Modal -->
    <div class="modal fade" id="shareChannelModal" tabindex="-1">
        <div class="modal-dialog">
            <div class="modal-content">
                <div class="modal-header">
                    <h5 class="modal-title"><i class="bi bi-share"></i> Share Channel</h5>
                    <button type="button" class="btn-close" data-bs-dismiss="modal"></button>
                </div>
                <div class="modal-body">
                    <h6 id="shareChannelName"></h6>

                    <!-- QR Code -->
                    <div class="text-center mb-3">
                        <img id="shareChannelQR" src="" alt="QR Code" class="img-fluid" style="max-width: 300px;">
                    </div>

                    <!-- Channel Details -->
                    <div class="mb-3">
                        <label class="form-label fw-bold">Channel Key:</label>
                        <div class="input-group">
                            <input type="text" class="form-control font-monospace" id="shareChannelKey" readonly>
                            <button class="btn btn-outline-secondary" type="button" onclick="copyChannelKey()">
                                <i class="bi bi-clipboard"></i> Copy
                            </button>
                        </div>
                    </div>

                    <div class="alert alert-info small">
                        <i class="bi bi-info-circle"></i>
                        Share this QR code or key with others to let them join this channel.
                    </div>
                </div>
            </div>
        </div>
    </div>

    <!-- Device Info Modal -->
    <div class="modal fade" id="deviceInfoModal" tabindex="-1">
        <div class="modal-dialog">
            <div class="modal-content">
                <div class="modal-header">
                    <h5 class="modal-title"><i class="bi bi-cpu"></i> Device</h5>
                    <button type="button" class="btn-close" data-bs-dismiss="modal"></button>
                </div>
                <div class="modal-body">
                    <ul class="nav nav-tabs mb-3" role="tablist">
                        <li class="nav-item" role="presentation">
                            <button class="nav-link active" data-bs-toggle="tab" data-bs-target="#tabDeviceInfo" type="button">Info</button>
                        </li>
                        <li class="nav-item" role="presentation">
                            <button class="nav-link" data-bs-toggle="tab" data-bs-target="#tabDeviceStats" type="button" id="statsTabBtn">Stats</button>
                        </li>
                        <li class="nav-item" role="presentation">
                            <button class="nav-link" data-bs-toggle="tab" data-bs-target="#tabDeviceShare" type="button" id="shareTabBtn">Share</button>
                        </li>
                    </ul>
                    <div class="tab-content">
                        <div class="tab-pane fade show active" id="tabDeviceInfo">
                            <div id="deviceInfoContent">
                                <div class="text-center py-3">
                                    <div class="spinner-border spinner-border-sm"></div> Loading...
                                </div>
                            </div>
                        </div>
                        <div class="tab-pane fade" id="tabDeviceStats">
                            <div id="deviceStatsContent">
                                <div class="text-center py-3 text-muted">
                                    Click to load stats
                                </div>
                            </div>
                        </div>
                        <div class="tab-pane fade" id="tabDeviceShare">
                            <div id="deviceShareContent">
                                <div class="text-center py-3 text-muted">
                                    Click to generate share code
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>

    <!-- Settings Modal -->
    <div class="modal fade" id="settingsModal" tabindex="-1">
        <div class="modal-dialog">
            <div class="modal-content">
                <div class="modal-header">
                    <h5 class="modal-title"><i class="bi bi-gear"></i> Settings</h5>
                    <button type="button" class="btn-close" data-bs-dismiss="modal"></button>
                </div>
                <div class="modal-body">
                    <ul class="nav nav-tabs mb-3" role="tablist">
                        <li class="nav-item" role="presentation">
                            <button class="nav-link active" data-bs-toggle="tab" data-bs-target="#tabSettingsDevice" type="button">Device</button>
                        </li>
                        <li class="nav-item" role="presentation">
                            <button class="nav-link" data-bs-toggle="tab" data-bs-target="#tabSettingsMessages" type="button">Messages</button>
                        </li>
                        <li class="nav-item" role="presentation">
                            <button class="nav-link" data-bs-toggle="tab" data-bs-target="#tabSettingsChat" type="button">Group Chat</button>
                        </li>
                        <li class="nav-item" role="presentation">
                            <button class="nav-link" data-bs-toggle="tab" data-bs-target="#tabSettingsInterface" type="button">Interface</button>
                        </li>
                        <li class="nav-item" role="presentation">
                            <button class="nav-link" data-bs-toggle="tab" data-bs-target="#tabSettingsAppearance" type="button">Appearance</button>
                        </li>
                        <li class="nav-item" role="presentation">
                            <button class="nav-link" data-bs-toggle="tab" data-bs-target="#tabSettingsContacts" type="button">Contacts</button>
                        </li>
                        <li class="nav-item" role="presentation">
                            <button class="nav-link" data-bs-toggle="tab" data-bs-target="#tabSettingsRegions" type="button">Regions</button>
                        </li>
                        <li class="nav-item" role="presentation">
                            <button class="nav-link" data-bs-toggle="tab" data-bs-target="#tabSettingsAnalyzer" type="button">Analyzer</button>
                        </li>
                        <li class="nav-item" role="presentation">
                            <button class="nav-link" data-bs-toggle="tab" data-bs-target="#tabSettingsNotifications" type="button">Notifications</button>
                        </li>
                    </ul>
                    <div class="tab-content">
                        <!-- Device Settings Tab -->
                        <div class="tab-pane fade show active" id="tabSettingsDevice">
                            <ul class="nav nav-pills nav-fill mb-3" role="tablist">
                                <li class="nav-item" role="presentation">
                                    <button class="nav-link active py-1 px-2" data-bs-toggle="pill"
                                            data-bs-target="#tabDevicePublicInfo" type="button">Public Info</button>
                                </li>
                                <li class="nav-item" role="presentation">
                                    <button class="nav-link py-1 px-2" data-bs-toggle="pill"
                                            data-bs-target="#tabDeviceRadio" type="button">Radio Settings</button>
                                </li>
                            </ul>
                            <div class="tab-content">
                                <!-- Public Info sub-tab -->
                                <div class="tab-pane fade show active" id="tabDevicePublicInfo">
                                    <form id="devicePublicInfoForm">
                                        <table class="table table-sm table-borderless mb-3 align-middle">
                                            <tbody>
                                                <tr>
                                                    <td class="ps-0">Name</td>
                                                    <td class="pe-0"><input type="text" class="form-control form-control-sm"
                                                        id="settDeviceName" maxlength="32" placeholder="Device name"></td>
                                                </tr>
                                                <tr>
                                                    <td class="ps-0">Latitude</td>
                                                    <td class="pe-0">
                                                        <div class="input-group input-group-sm">
                                                            <input type="number" class="form-control form-control-sm"
                                                                id="settDeviceLat" step="0.000001" min="-90" max="90" placeholder="0.000000">
                                                            <button type="button" class="btn btn-outline-secondary" id="settDevicePickMapBtn"
                                                                title="Pick from map"><i class="bi bi-geo-alt"></i></button>
                                                        </div>
                                                    </td>
                                                </tr>
                                                <tr>
                                                    <td class="ps-0">Longitude</td>
                                                    <td class="pe-0"><input type="number" class="form-control form-control-sm"
                                                        id="settDeviceLon" step="0.000001" min="-180" max="180" placeholder="0.000000"></td>
                                                </tr>
                                                <tr>
                                                    <td class="ps-0">Share position in advert
                                                        <span class="badge rounded-pill text-muted" data-bs-toggle="tooltip"
                                                            title="Include GPS coordinates in device advertisement"><i class="bi bi-info-circle"></i></span>
                                                    </td>
                                                    <td class="pe-0">
                                                        <div class="form-check form-switch mb-0">
                                                            <input class="form-check-input" type="checkbox" id="settDeviceAdvertLoc">
                                                        </div>
                                                    </td>
                                                </tr>
                                                <tr>
                                                    <td class="ps-0">Path hash mode
                                                        <span class="badge rounded-pill text-muted" data-bs-toggle="tooltip"
                                                            title="Bytes per hop in routing paths. 1B = shortest path, more collisions; 3B = longest, fewest collisions."><i class="bi bi-info-circle"></i></span>
                                                    </td>
                                                    <td class="pe-0">
                                                        <select class="form-select form-select-sm" id="settDevicePathHashMode">
                                                            <option value="0">1 byte (default)</option>
                                                            <option value="1">2 bytes</option>
                                                            <option value="2">3 bytes</option>
                                                        </select>
                                                    </td>
                                                </tr>
                                            </tbody>
                                        </table>
                                        <div class="d-flex gap-2">
                                            <button type="submit" class="btn btn-primary btn-sm">Save</button>
                                        </div>
                                    </form>
                                </div>
                                <!-- Radio Settings sub-tab -->
                                <div class="tab-pane fade" id="tabDeviceRadio">
                                    <form id="deviceRadioForm">
                                        <table class="table table-sm table-borderless mb-3 align-middle">
                                            <tbody>
                                                <tr>
                                                    <td class="ps-0" colspan="2">
                                                        <select class="form-select form-select-sm" id="settRadioPreset">
                                                            <option value="">Load preset...</option>
                                                        </select>
                                                    </td>
                                                </tr>
                                                <tr>
                                                    <td class="ps-0">Frequency (MHz)</td>
                                                    <td class="pe-0" style="width:7rem"><input type="number" class="form-control form-control-sm"
                                                        id="settRadioFreq" step="0.001" min="100" max="1000"></td>
                                                </tr>
                                                <tr>
                                                    <td class="ps-0">Bandwidth (kHz)</td>
                                                    <td class="pe-0">
                                                        <select class="form-select form-select-sm" id="settRadioBw" style="width:7rem">
                                                            <option value="7.8">7.8</option>
                                                            <option value="10.4">10.4</option>
                                                            <option value="15.6">15.6</option>
                                                            <option value="20.8">20.8</option>
                                                            <option value="31.25">31.25</option>
                                                            <option value="41.7">41.7</option>
                                                            <option value="62.5">62.5</option>
                                                            <option value="125">125</option>
                                                            <option value="250">250</option>
                                                            <option value="500">500</option>
                                                        </select>
                                                    </td>
                                                </tr>
                                                <tr>
                                                    <td class="ps-0">Spreading Factor</td>
                                                    <td class="pe-0" style="width:7rem"><input type="number" class="form-control form-control-sm"
                                                        id="settRadioSf" min="5" max="12"></td>
                                                </tr>
                                                <tr>
                                                    <td class="ps-0">Coding Rate</td>
                                                    <td class="pe-0" style="width:7rem"><input type="number" class="form-control form-control-sm"
                                                        id="settRadioCr" min="5" max="8"></td>
                                                </tr>
                                                <tr>
                                                    <td class="ps-0">TX Power (dBm)</td>
                                                    <td class="pe-0" style="width:7rem"><input type="number" class="form-control form-control-sm"
                                                        id="settRadioTxPower" min="0" max="30"></td>
                                                </tr>
                                            </tbody>
                                        </table>
                                        <div class="d-flex gap-2">
                                            <button type="submit" class="btn btn-primary btn-sm">Save</button>
                                        </div>
                                    </form>
                                </div>
                            </div>
                        </div>
                        <div class="tab-pane fade" id="tabSettingsMessages">
                            <div id="settingsMessagesContent">
                                <form id="dmRetrySettingsForm">
                                    <p class="text-muted small mb-3">Retries are counted after the initial send, e.g. 3 retries = 4 total attempts.</p>
                                    <h6 class="text-muted mb-2">When path is known (DIRECT)</h6>
                                    <table class="table table-sm table-borderless mb-3 align-middle">
                                        <tbody>
                                            <tr>
                                                <td class="ps-0">Direct retries <span class="badge rounded-pill text-muted" data-bs-toggle="tooltip" title="Attempts via known path before switching to flood"><i class="bi bi-info-circle"></i></span></td>
                                                <td class="pe-0" style="width:5rem"><input type="number" class="form-control form-control-sm" id="settDirectMaxRetries" min="0" max="20" value="3"></td>
                                            </tr>
                                            <tr>
                                                <td class="ps-0">Flood retries <span class="badge rounded-pill text-muted" data-bs-toggle="tooltip" title="Flood attempts after direct retries exhausted (when no configured paths)"><i class="bi bi-info-circle"></i></span></td>
                                                <td class="pe-0"><input type="number" class="form-control form-control-sm" id="settDirectFloodRetries" min="0" max="5" value="1"></td>
                                            </tr>
                                            <tr>
                                                <td class="ps-0">Interval (s) <span class="badge rounded-pill text-muted" data-bs-toggle="tooltip" title="Seconds to wait between direct retries"><i class="bi bi-info-circle"></i></span></td>
                                                <td class="pe-0"><input type="number" class="form-control form-control-sm" id="settDirectInterval" min="5" max="300" value="30"></td>
                                            </tr>
                                        </tbody>
                                    </table>

                                    <h6 class="text-muted mb-2">When no path (FLOOD)</h6>
                                    <table class="table table-sm table-borderless mb-3 align-middle">
                                        <tbody>
                                            <tr>
                                                <td class="ps-0">Max retries <span class="badge rounded-pill text-muted" data-bs-toggle="tooltip" title="Flood retry attempts (also used after path rotation)"><i class="bi bi-info-circle"></i></span></td>
                                                <td class="pe-0" style="width:5rem"><input type="number" class="form-control form-control-sm" id="settFloodMaxRetries" min="0" max="10" value="3"></td>
                                            </tr>
                                            <tr>
                                                <td class="ps-0">Interval (s) <span class="badge rounded-pill text-muted" data-bs-toggle="tooltip" title="Seconds to wait between flood retries"><i class="bi bi-info-circle"></i></span></td>
                                                <td class="pe-0"><input type="number" class="form-control form-control-sm" id="settFloodInterval" min="5" max="300" value="60"></td>
                                            </tr>
                                        </tbody>
                                    </table>

                                    <h6 class="text-muted mb-2">Other</h6>
                                    <table class="table table-sm table-borderless mb-3 align-middle">
                                        <tbody>
                                            <tr>
                                                <td class="ps-0">Grace period (s) <span class="badge rounded-pill text-muted" data-bs-toggle="tooltip" title="Wait for late ACKs after all retries exhausted"><i class="bi bi-info-circle"></i></span></td>
                                                <td class="pe-0" style="width:5rem"><input type="number" class="form-control form-control-sm" id="settGracePeriod" min="10" max="300" value="60"></td>
                                            </tr>
                                        </tbody>
                                    </table>

                                    <div class="d-flex gap-2">
                                        <button type="submit" class="btn btn-primary btn-sm">Save</button>
                                        <button type="button" class="btn btn-outline-secondary btn-sm" id="settingsResetBtn">Reset to defaults</button>
                                    </div>
                                </form>
                            </div>
                        </div>
                        <div class="tab-pane fade" id="tabSettingsChat">
                            <form id="chatSettingsForm">
                                <h6 class="text-muted mb-2">Quote</h6>
                                <table class="table table-sm table-borderless mb-3 align-middle">
                                    <tbody>
                                        <tr>
                                            <td class="ps-0">Quote length (bytes) <span class="badge rounded-pill text-muted" data-bs-toggle="tooltip" title="Default max UTF-8 bytes for truncated quotes"><i class="bi bi-info-circle"></i></span></td>
                                            <td class="pe-0" style="width:5rem"><input type="number" class="form-control form-control-sm" id="settQuoteMaxBytes" min="5" max="120" value="20"></td>
                                        </tr>
                                    </tbody>
                                </table>

                                <h6 class="text-muted mb-2">Route popup</h6>
                                <p class="text-muted small mb-2">The popup shown when tapping "SNR | Hops" under a message. Also applies to DMs.</p>
                                <table class="table table-sm table-borderless mb-3 align-middle">
                                    <tbody>
                                        <tr>
                                            <td class="ps-0">Auto-close after (s) <span class="badge rounded-pill text-muted" data-bs-toggle="tooltip" title="Seconds before the route popup closes automatically"><i class="bi bi-info-circle"></i></span></td>
                                            <td class="pe-0" style="width:5rem"><input type="number" class="form-control form-control-sm" id="settPathPopupTimeout" min="1" max="60" value="8"></td>
                                        </tr>
                                        <tr>
                                            <td class="ps-0">Don't close automatically <span class="badge rounded-pill text-muted" data-bs-toggle="tooltip" title="Popup stays open until you tap outside it"><i class="bi bi-info-circle"></i></span></td>
                                            <td class="pe-0">
                                                <div class="form-check form-switch mb-0">
                                                    <input class="form-check-input" type="checkbox" id="settPathPopupNoAutoclose">
                                                </div>
                                            </td>
                                        </tr>
                                    </tbody>
                                </table>
                                <div class="d-flex gap-2">
                                    <button type="submit" class="btn btn-primary btn-sm">Save</button>
                                    <button type="button" class="btn btn-outline-secondary btn-sm" id="chatSettingsResetBtn">Reset to defaults</button>
                                </div>
                            </form>
                        </div>
                        <div class="tab-pane fade" id="tabSettingsInterface">
                            <h6 class="text-muted mb-2">Layout</h6>
                            <p class="text-muted small mb-2">Window width above which the channel/contact list is shown as a sidebar. Below this width it collapses to a dropdown at the top of the screen. Saved per device (browser).</p>
                            <table class="table table-sm table-borderless mb-3 align-middle">
                                <tbody>
                                    <tr>
                                        <td class="ps-0">Sidebar breakpoint (px) <span class="badge rounded-pill text-muted" data-bs-toggle="tooltip" title="Default: 992. Range: 600-2000."><i class="bi bi-info-circle"></i></span></td>
                                        <td class="pe-0" style="width:10rem">
                                            <div class="d-flex gap-1">
                                                <input type="number" class="form-control form-control-sm" id="settSidebarBreakpoint" min="600" max="2000" step="1" value="992">
                                                <button type="button" class="btn btn-outline-secondary btn-sm" id="settSidebarBreakpointReset" title="Reset to default (992)"><i class="bi bi-arrow-counterclockwise"></i></button>
                                            </div>
                                        </td>
                                    </tr>
                                </tbody>
                            </table>
                            <hr>
                            <form id="uiSettingsForm">
                                <h6 class="text-muted mb-2">Notifications</h6>
                                <p class="text-muted small mb-2">Controls the small toasts shown after actions (e.g. "Advert Sent", errors).</p>
                                <table class="table table-sm table-borderless mb-3 align-middle">
                                    <tbody>
                                        <tr>
                                            <td class="ps-0">Auto-close after (s) <span class="badge rounded-pill text-muted" data-bs-toggle="tooltip" title="Seconds before a notification closes automatically"><i class="bi bi-info-circle"></i></span></td>
                                            <td class="pe-0" style="width:5rem"><input type="number" class="form-control form-control-sm" id="settToastTimeout" min="1" max="60" step="0.5" value="2"></td>
                                        </tr>
                                        <tr>
                                            <td class="ps-0">Don't close automatically <span class="badge rounded-pill text-muted" data-bs-toggle="tooltip" title="Notifications stay until dismissed via their close button"><i class="bi bi-info-circle"></i></span></td>
                                            <td class="pe-0">
                                                <div class="form-check form-switch mb-0">
                                                    <input class="form-check-input" type="checkbox" id="settToastNoAutoclose">
                                                </div>
                                            </td>
                                        </tr>
                                        <tr>
                                            <td class="ps-0">Position on screen</td>
                                            <td class="pe-0">
                                                <select class="form-select form-select-sm" id="settToastPosition">
                                                    <option value="top-left">Top left</option>
                                                    <option value="top-right">Top right</option>
                                                    <option value="bottom-left">Bottom left</option>
                                                    <option value="bottom-right">Bottom right</option>
                                                    <option value="center">Center</option>
                                                </select>
                                            </td>
                                        </tr>
                                    </tbody>
                                </table>
                                <div class="d-flex gap-2">
                                    <button type="submit" class="btn btn-primary btn-sm">Save</button>
                                    <button type="button" class="btn btn-outline-secondary btn-sm" id="uiSettingsResetBtn">Reset to defaults</button>
                                </div>
                            </form>
                        </div>
                        <div class="tab-pane fade" id="tabSettingsAppearance">
                            <h6 class="text-muted mb-3">Theme</h6>
                            <div class="d-flex flex-column gap-2">
                                <div class="theme-option active" data-theme-value="light" onclick="setTheme('light')">
                                    <div class="theme-option-preview light">
                                        <i class="bi bi-sun"></i>
                                    </div>
                                    <div>
                                        <div class="theme-option-label">Light</div>
                                        <div class="theme-option-desc">Classic bright interface</div>
                                    </div>
                                </div>
                                <div class="theme-option" data-theme-value="dark" onclick="setTheme('dark')">
                                    <div class="theme-option-preview dark">
                                        <i class="bi bi-moon-stars" style="color: #60a5fa;"></i>
                                    </div>
                                    <div>
                                        <div class="theme-option-label">Dark</div>
                                        <div class="theme-option-desc">Easy on the eyes, deep navy palette</div>
                                    </div>
                                </div>
                            </div>

                            <hr>
                            <h6 class="text-muted mb-3">Quick Access Buttons</h6>
                            <div class="form-check mb-3">
                                <input class="form-check-input" type="checkbox" id="settHideFab">
                                <label class="form-check-label" for="settHideFab">Hide Quick Access buttons</label>
                                <small class="d-block text-muted">When hidden, all items appear in the Main Menu.</small>
                            </div>
                            <div id="fabAppearanceControls">
                                <table class="table table-sm align-middle mb-3" id="settItemPlacementTable">
                                    <thead>
                                        <tr>
                                            <th class="ps-0 fw-normal text-muted small">Item</th>
                                            <th class="pe-0 text-end fw-normal text-muted small">Placement</th>
                                        </tr>
                                    </thead>
                                    <tbody>
                                        <tr data-placement-key="filter">
                                            <td class="ps-0">Filter messages</td>
                                            <td class="pe-0 text-end">
                                                <div class="btn-group btn-group-sm" role="group" aria-label="Filter placement">
                                                    <input type="radio" class="btn-check" name="place-filter" id="place-filter-fab" value="fab" autocomplete="off">
                                                    <label class="btn btn-outline-primary" for="place-filter-fab">Quick Access</label>
                                                    <input type="radio" class="btn-check" name="place-filter" id="place-filter-menu" value="menu" autocomplete="off">
                                                    <label class="btn btn-outline-primary" for="place-filter-menu">Main Menu</label>
                                                </div>
                                            </td>
                                        </tr>
                                        <tr data-placement-key="search">
                                            <td class="ps-0">Search messages</td>
                                            <td class="pe-0 text-end">
                                                <div class="btn-group btn-group-sm" role="group" aria-label="Search placement">
                                                    <input type="radio" class="btn-check" name="place-search" id="place-search-fab" value="fab" autocomplete="off">
                                                    <label class="btn btn-outline-primary" for="place-search-fab">Quick Access</label>
                                                    <input type="radio" class="btn-check" name="place-search" id="place-search-menu" value="menu" autocomplete="off">
                                                    <label class="btn btn-outline-primary" for="place-search-menu">Main Menu</label>
                                                </div>
                                            </td>
                                        </tr>
                                        <tr data-placement-key="dm">
                                            <td class="ps-0">Direct Messages</td>
                                            <td class="pe-0 text-end">
                                                <div class="btn-group btn-group-sm" role="group" aria-label="DM placement">
                                                    <input type="radio" class="btn-check" name="place-dm" id="place-dm-fab" value="fab" autocomplete="off">
                                                    <label class="btn btn-outline-primary" for="place-dm-fab">Quick Access</label>
                                                    <input type="radio" class="btn-check" name="place-dm" id="place-dm-menu" value="menu" autocomplete="off">
                                                    <label class="btn btn-outline-primary" for="place-dm-menu">Main Menu</label>
                                                </div>
                                            </td>
                                        </tr>
                                        <tr data-placement-key="contacts">
                                            <td class="ps-0">Contact Management</td>
                                            <td class="pe-0 text-end">
                                                <div class="btn-group btn-group-sm" role="group" aria-label="Contacts placement">
                                                    <input type="radio" class="btn-check" name="place-contacts" id="place-contacts-fab" value="fab" autocomplete="off">
                                                    <label class="btn btn-outline-primary" for="place-contacts-fab">Quick Access</label>
                                                    <input type="radio" class="btn-check" name="place-contacts" id="place-contacts-menu" value="menu" autocomplete="off">
                                                    <label class="btn btn-outline-primary" for="place-contacts-menu">Main Menu</label>
                                                </div>
                                            </td>
                                        </tr>
                                        <tr data-placement-key="settings">
                                            <td class="ps-0">Settings</td>
                                            <td class="pe-0 text-end">
                                                <div class="btn-group btn-group-sm" role="group" aria-label="Settings placement">
                                                    <input type="radio" class="btn-check" name="place-settings" id="place-settings-fab" value="fab" autocomplete="off">
                                                    <label class="btn btn-outline-primary" for="place-settings-fab">Quick Access</label>
                                                    <input type="radio" class="btn-check" name="place-settings" id="place-settings-menu" value="menu" autocomplete="off">
                                                    <label class="btn btn-outline-primary" for="place-settings-menu">Main Menu</label>
                                                </div>
                                            </td>
                                        </tr>
                                        <tr data-placement-key="advert">
                                            <td class="ps-0">Send Advert</td>
                                            <td class="pe-0 text-end">
                                                <div class="btn-group btn-group-sm" role="group" aria-label="Advert placement">
                                                    <input type="radio" class="btn-check" name="place-advert" id="place-advert-fab" value="fab" autocomplete="off">
                                                    <label class="btn btn-outline-primary" for="place-advert-fab">Quick Access</label>
                                                    <input type="radio" class="btn-check" name="place-advert" id="place-advert-menu" value="menu" autocomplete="off">
                                                    <label class="btn btn-outline-primary" for="place-advert-menu">Main Menu</label>
                                                </div>
                                            </td>
                                        </tr>
                                        <tr data-placement-key="floodadvert">
                                            <td class="ps-0">Flood Advert</td>
                                            <td class="pe-0 text-end">
                                                <div class="btn-group btn-group-sm" role="group" aria-label="Flood Advert placement">
                                                    <input type="radio" class="btn-check" name="place-floodadvert" id="place-floodadvert-fab" value="fab" autocomplete="off">
                                                    <label class="btn btn-outline-primary" for="place-floodadvert-fab">Quick Access</label>
                                                    <input type="radio" class="btn-check" name="place-floodadvert" id="place-floodadvert-menu" value="menu" autocomplete="off">
                                                    <label class="btn btn-outline-primary" for="place-floodadvert-menu">Main Menu</label>
                                                </div>
                                            </td>
                                        </tr>
                                        <tr data-placement-key="map">
                                            <td class="ps-0">Map</td>
                                            <td class="pe-0 text-end">
                                                <div class="btn-group btn-group-sm" role="group" aria-label="Map placement">
                                                    <input type="radio" class="btn-check" name="place-map" id="place-map-fab" value="fab" autocomplete="off">
                                                    <label class="btn btn-outline-primary" for="place-map-fab">Quick Access</label>
                                                    <input type="radio" class="btn-check" name="place-map" id="place-map-menu" value="menu" autocomplete="off">
                                                    <label class="btn btn-outline-primary" for="place-map-menu">Main Menu</label>
                                                </div>
                                            </td>
                                        </tr>
                                        <tr data-placement-key="console">
                                            <td class="ps-0">Console</td>
                                            <td class="pe-0 text-end">
                                                <div class="btn-group btn-group-sm" role="group" aria-label="Console placement">
                                                    <input type="radio" class="btn-check" name="place-console" id="place-console-fab" value="fab" autocomplete="off">
                                                    <label class="btn btn-outline-primary" for="place-console-fab">Quick Access</label>
                                                    <input type="radio" class="btn-check" name="place-console" id="place-console-menu" value="menu" autocomplete="off">
                                                    <label class="btn btn-outline-primary" for="place-console-menu">Main Menu</label>
                                                </div>
                                            </td>
                                        </tr>
                                        <tr data-placement-key="deviceinfo">
                                            <td class="ps-0">Device Info</td>
                                            <td class="pe-0 text-end">
                                                <div class="btn-group btn-group-sm" role="group" aria-label="Device Info placement">
                                                    <input type="radio" class="btn-check" name="place-deviceinfo" id="place-deviceinfo-fab" value="fab" autocomplete="off">
                                                    <label class="btn btn-outline-primary" for="place-deviceinfo-fab">Quick Access</label>
                                                    <input type="radio" class="btn-check" name="place-deviceinfo" id="place-deviceinfo-menu" value="menu" autocomplete="off">
                                                    <label class="btn btn-outline-primary" for="place-deviceinfo-menu">Main Menu</label>
                                                </div>
                                            </td>
                                        </tr>
                                        <tr data-placement-key="syslog">
                                            <td class="ps-0">System Log</td>
                                            <td class="pe-0 text-end">
                                                <div class="btn-group btn-group-sm" role="group" aria-label="System Log placement">
                                                    <input type="radio" class="btn-check" name="place-syslog" id="place-syslog-fab" value="fab" autocomplete="off">
                                                    <label class="btn btn-outline-primary" for="place-syslog-fab">Quick Access</label>
                                                    <input type="radio" class="btn-check" name="place-syslog" id="place-syslog-menu" value="menu" autocomplete="off">
                                                    <label class="btn btn-outline-primary" for="place-syslog-menu">Main Menu</label>
                                                </div>
                                            </td>
                                        </tr>
                                    </tbody>
                                </table>
                                <table class="table table-sm table-borderless mb-3 align-middle">
                                    <tbody>
                                        <tr>
                                            <td class="ps-0">Button size (px)</td>
                                            <td class="pe-0 d-flex align-items-center gap-2" style="width:12rem">
                                                <input type="range" class="form-range flex-grow-1" id="settFabSize" min="28" max="72" step="2" value="56">
                                                <span class="text-muted small" id="settFabSizeVal" style="min-width:2.5rem;text-align:right">56</span>
                                            </td>
                                        </tr>
                                        <tr>
                                            <td class="ps-0">Spacing (px)</td>
                                            <td class="pe-0 d-flex align-items-center gap-2">
                                                <input type="range" class="form-range flex-grow-1" id="settFabGap" min="2" max="24" step="1" value="12">
                                                <span class="text-muted small" id="settFabGapVal" style="min-width:2.5rem;text-align:right">12</span>
                                            </td>
                                        </tr>
                                        <tr>
                                            <td class="ps-0">Position</td>
                                            <td class="pe-0">
                                                <button type="button" class="btn btn-outline-secondary btn-sm" id="settFabResetPos">Reset to default</button>
                                            </td>
                                        </tr>
                                    </tbody>
                                </table>
                            </div>
                        </div>
                        <div class="tab-pane fade" id="tabSettingsContacts">
                            <table class="table table-sm table-borderless mb-0 align-middle">
                                <tbody>
                                    <tr>
                                        <td class="ps-0">Manual approval enabled
                                            <span class="badge rounded-pill text-muted" data-bs-toggle="tooltip"
                                                title="When enabled, new contacts must be manually approved before they can communicate with your node"><i class="bi bi-info-circle"></i></span>
                                        </td>
                                        <td class="pe-0">
                                            <div class="form-check form-switch mb-0">
                                                <input class="form-check-input" type="checkbox" id="settManualApproval">
                                            </div>
                                        </td>
                                    </tr>
                                    <tr>
                                        <td class="ps-0" id="settSuppressAdvertNotifsLabel">Suppress new advert notifications
                                            <span class="badge rounded-pill text-muted" data-bs-toggle="tooltip"
                                                title="Hide the badge over Contact Management and the browser notification when new pending contacts arrive. The Pending Contacts list itself still shows them. Requires Manual approval ON."><i class="bi bi-info-circle"></i></span>
                                        </td>
                                        <td class="pe-0">
                                            <div class="form-check form-switch mb-0">
                                                <input class="form-check-input" type="checkbox" id="settSuppressAdvertNotifs">
                                            </div>
                                        </td>
                                    </tr>
                                    <tr>
                                        <td class="ps-0" id="settAutoIgnoreAdvertsLabel">Automatically add new contacts to "Ignored"
                                            <span class="badge rounded-pill text-muted" data-bs-toggle="tooltip"
                                                title="Every new advert is automatically marked as Ignored — no notifications, no badge. Contacts still appear under Existing Contacts (Cache) and can be promoted with 'To Device'. Requires Manual approval ON."><i class="bi bi-info-circle"></i></span>
                                        </td>
                                        <td class="pe-0">
                                            <div class="form-check form-switch mb-0">
                                                <input class="form-check-input" type="checkbox" id="settAutoIgnoreAdverts">
                                            </div>
                                        </td>
                                    </tr>
                                </tbody>
                            </table>
                        </div>
                        <div class="tab-pane fade" id="tabSettingsRegions">
                            <div class="alert alert-info py-2 small mb-3 mt-2">
                                <i class="bi bi-info-circle"></i> Only repeaters allowing a region will forward messages tagged with it.
                                Find standardised region names at
                                <a href="https://regions.meshcore.nz/" target="_blank" rel="noopener">regions.meshcore.nz</a>.
                            </div>
                            <h6 class="mb-2">Region Registry</h6>
                            <div id="regionsList" class="list-group mb-3">
                                <div class="text-center text-muted py-3 small">
                                    <div class="spinner-border spinner-border-sm"></div> Loading...
                                </div>
                            </div>
                            <form id="addRegionForm" class="row g-2 mb-0">
                                <div class="col-8">
                                    <input type="text" class="form-control form-control-sm" id="newRegionName"
                                           placeholder="Region name (e.g. pl, pl-ma)" required maxlength="30" autocomplete="off">
                                </div>
                                <div class="col-4">
                                    <button type="submit" class="btn btn-primary btn-sm w-100">
                                        <i class="bi bi-plus-circle"></i> Add
                                    </button>
                                </div>
                            </form>
                            <div class="form-text small">
                                Tip: pick the default region via the radio button, or select <em>None</em> to fall back to the firmware default. The chosen region is also pushed to the firmware so any untagged channel uses it.
                            </div>
                        </div>
                        <div class="tab-pane fade" id="tabSettingsAnalyzer">
                            <div class="alert alert-info py-2 small mb-3 mt-2">
                                <i class="bi bi-info-circle"></i> Add MeshCore Analyzer services to choose from when clicking
                                <i class="bi bi-clipboard-data"></i> under a group chat message. The URL must contain the
                                <code>{packetHash}</code> placeholder &mdash; it is replaced with the message's packet hash.
                            </div>
                            <h6 class="mb-2">Analyzer Services</h6>
                            <div id="analyzersList" class="list-group mb-3">
                                <div class="text-center text-muted py-3 small">
                                    <div class="spinner-border spinner-border-sm"></div> Loading...
                                </div>
                            </div>
                            <button type="button" class="btn btn-primary btn-sm" id="addAnalyzerBtn">
                                <i class="bi bi-plus-circle"></i> Add analyzer
                            </button>
                            <div class="form-text small mt-2">
                                Tip: star one analyzer to use it without being asked. Clear the star to be prompted on every click.
                                Disabled analyzers stay in the list but are hidden from the chooser.
                            </div>
                        </div>
                        <div class="tab-pane fade" id="tabSettingsNotifications">
                            <p class="text-muted small mb-3">Browser notifications appear when the app is hidden or in the background.</p>
                            <button id="notificationsToggle" class="list-group-item list-group-item-action d-flex align-items-center gap-3 border rounded" type="button" style="width: 100%;">
                                <i class="bi bi-bell" style="font-size: 1.5rem;"></i>
                                <div class="flex-grow-1 text-start">
                                    <div class="d-flex justify-content-between align-items-center">
                                        <span>Notifications</span>
                                        <span id="notificationStatus" class="badge bg-secondary">Disabled</span>
                                    </div>
                                    <small class="text-muted d-block mt-1" style="font-size: 0.75rem;">
                                        Works when app is hidden
                                    </small>
                                </div>
                            </button>
                        </div>
                    </div>
                </div>
                <div class="modal-footer py-2">
                    <button type="button" class="btn btn-secondary btn-sm" data-bs-dismiss="modal">Close</button>
                </div>
            </div>
        </div>
    </div>

    <!-- Analyzer Edit Modal (create + edit) -->
    <div class="modal fade" id="analyzerEditModal" tabindex="-1" style="z-index: 1080;">
        <div class="modal-dialog modal-dialog-centered">
            <div class="modal-content">
                <div class="modal-header py-2">
                    <h6 class="modal-title"><i class="bi bi-clipboard-data"></i> <span id="analyzerEditModalTitle">Add analyzer</span></h6>
                    <button type="button" class="btn-close" data-bs-dismiss="modal"></button>
                </div>
                <form id="analyzerEditForm">
                    <div class="modal-body">
                        <input type="hidden" id="analyzerEditId" value="">
                        <div class="mb-3">
                            <label class="form-label small mb-1" for="analyzerEditName">Name</label>
                            <input type="text" class="form-control form-control-sm" id="analyzerEditName"
                                   placeholder="e.g. MarWoj Analyzer" required maxlength="60" autocomplete="off">
                        </div>
                        <div class="mb-3">
                            <label class="form-label small mb-1" for="analyzerEditUrl">URL template</label>
                            <input type="text" class="form-control form-control-sm" id="analyzerEditUrl"
                                   placeholder="https://analyzer.example.com/#/packets/{packetHash}" required autocomplete="off">
                            <div class="form-text small">Must include <code>{packetHash}</code>.</div>
                        </div>
                        <div class="form-check form-switch">
                            <input class="form-check-input" type="checkbox" id="analyzerEditDisabled">
                            <label class="form-check-label small" for="analyzerEditDisabled">Disabled</label>
                        </div>
                        <div id="analyzerEditError" class="alert alert-danger py-1 small mt-3 d-none"></div>
                    </div>
                    <div class="modal-footer py-2">
                        <button type="button" class="btn btn-secondary btn-sm" data-bs-dismiss="modal">Cancel</button>
                        <button type="submit" class="btn btn-primary btn-sm">Save</button>
                    </div>
                </form>
            </div>
        </div>
    </div>

    <!-- Analyzer Chooser Modal -->
    <div class="modal fade" id="analyzerChooserModal" tabindex="-1" style="z-index: 1080;">
        <div class="modal-dialog modal-dialog-centered modal-sm">
            <div class="modal-content">
                <div class="modal-header py-2">
                    <h6 class="modal-title"><i class="bi bi-clipboard-data"></i> Choose analyzer</h6>
                    <button type="button" class="btn-close" data-bs-dismiss="modal"></button>
                </div>
                <div class="modal-body p-2">
                    <div id="analyzerChooserList" class="list-group"></div>
                </div>
            </div>
        </div>
    </div>

    <!-- Coordinate Picker Map Modal -->
    <div class="modal fade" id="coordPickerModal" tabindex="-1" style="z-index: 1080;">
        <div class="modal-dialog modal-lg modal-dialog-centered">
            <div class="modal-content">
                <div class="modal-header py-2">
                    <h6 class="modal-title"><i class="bi bi-geo-alt"></i> Pick Coordinates</h6>
                    <button type="button" class="btn-close" data-bs-dismiss="modal"></button>
                </div>
                <div class="modal-body p-0">
                    <div id="coordPickerMap" style="height: 400px; width: 100%;"></div>
                </div>
                <div class="modal-footer py-2">
                    <span class="me-auto small text-muted" id="coordPickerLabel">Click on the map to select coordinates</span>
                    <button type="button" class="btn btn-sm btn-secondary" data-bs-dismiss="modal">Cancel</button>
                    <button type="button" class="btn btn-sm btn-primary" id="coordPickerConfirmBtn" disabled>Confirm</button>
                </div>
            </div>
        </div>
    </div>

    <!-- Quote Dialog Modal -->
    <div class="modal fade" id="quoteModal" tabindex="-1">
        <div class="modal-dialog modal-sm modal-dialog-centered">
            <div class="modal-content">
                <div class="modal-header py-2">
                    <h6 class="modal-title"><i class="bi bi-quote"></i> Quote message</h6>
                    <button type="button" class="btn-close btn-close-sm" data-bs-dismiss="modal"></button>
                </div>
                <div class="modal-body py-2">
                    <p class="text-muted small mb-2" id="quotePreview"></p>
                    <div class="d-flex gap-2 align-items-center mb-2">
                        <label class="form-label mb-0 small text-nowrap" for="quoteBytesInput">Max bytes:</label>
                        <input type="number" class="form-control form-control-sm" id="quoteBytesInput" min="5" max="120" style="width:5rem">
                    </div>
                </div>
                <div class="modal-footer py-1">
                    <button type="button" class="btn btn-outline-secondary btn-sm" id="quoteTruncatedBtn">Truncated</button>
                    <button type="button" class="btn btn-primary btn-sm" id="quoteFullBtn">Full quote</button>
                </div>
            </div>
        </div>
    </div>

    <!-- Map Modal (Leaflet) -->
    <div class="modal fade" id="mapModal" tabindex="-1">
        <div class="modal-dialog modal-lg modal-dialog-centered">
            <div class="modal-content">
                <div class="modal-header">
                    <h5 class="modal-title"><i class="bi bi-geo-alt"></i> <span id="mapModalTitle">Map</span></h5>
                    <button type="button" class="btn-close" data-bs-dismiss="modal"></button>
                </div>
                <div class="modal-body p-0">
                    <!-- Type filter (hidden for single contact view) -->
                    <div id="mapTypeFilter" class="d-none px-3 py-2 border-bottom bg-light">
                        <div class="d-flex flex-wrap gap-2 align-items-center">
                            <span class="map-filter-badge active" data-type="1" id="mapFilterCOM">COM</span>
                            <span class="map-filter-badge active" data-type="2" id="mapFilterREP">REP</span>
                            <span class="map-filter-badge active" data-type="3" id="mapFilterROOM">ROOM</span>
                            <span class="map-filter-badge active" data-type="4" id="mapFilterSENS">SENS</span>
                            <div class="form-check form-switch ms-auto mb-0">
                                <input class="form-check-input" type="checkbox" id="mapCachedSwitch">
                                <label class="form-check-label small" for="mapCachedSwitch">Cached</label>
                            </div>
                        </div>
                    </div>
                    <div id="leafletMap" style="height: 400px; width: 100%;"></div>
                </div>
            </div>
        </div>
    </div>

    <!-- Update Modal -->
    <div class="modal fade" id="updateModal" tabindex="-1" data-bs-backdrop="static" data-bs-keyboard="false">
        <div class="modal-dialog modal-dialog-centered">
            <div class="modal-content">
                <div class="modal-header">
                    <h5 class="modal-title"><i class="bi bi-cloud-download"></i> Update mc-webui</h5>
                </div>
                <div class="modal-body text-center py-4">
                    <div id="updateStatus">
                        <div class="spinner-border text-primary mb-3" role="status">
                            <span class="visually-hidden">Loading...</span>
                        </div>
                        <p id="updateMessage" class="mb-0">Checking for updates...</p>
                        <p id="updateWhatsNew" class="d-none mt-2 mb-0"><a href="#" target="_blank" class="text-muted small"><i class="bi bi-github"></i> What's new?</a></p>
                    </div>
                    <div id="updateProgress" class="d-none">
                        <div class="progress mb-3" style="height: 8px;">
                            <div class="progress-bar progress-bar-striped progress-bar-animated"
                                 role="progressbar" style="width: 100%"></div>
                        </div>
                        <p id="updateProgressMessage" class="text-muted mb-0">Updating...</p>
                    </div>
                    <div id="updateResult" class="d-none">
                        <i id="updateResultIcon" class="bi fs-1 mb-3 d-block"></i>
                        <p id="updateResultMessage" class="mb-0"></p>
                    </div>
                </div>
                <div class="modal-footer justify-content-center" id="updateFooter">
                    <button type="button" class="btn btn-secondary" data-bs-dismiss="modal" id="updateCancelBtn">Cancel</button>
                    <button type="button" class="btn btn-primary d-none" id="updateConfirmBtn">Update Now</button>
                    <button type="button" class="btn btn-primary d-none" id="updateReloadBtn" onclick="location.reload()">Reload Page</button>
                </div>
            </div>
        </div>
    </div>

    <!-- Backup Modal -->
    <div class="modal fade" id="backupModal" tabindex="-1">
        <div class="modal-dialog">
            <div class="modal-content">
                <div class="modal-header">
                    <h5 class="modal-title"><i class="bi bi-database-down"></i> Database Backup</h5>
                    <button type="button" class="btn-close" data-bs-dismiss="modal"></button>
                </div>
                <div class="modal-body">
                    <div class="d-flex justify-content-between align-items-center mb-3">
                        <button class="btn btn-primary" id="createBackupBtn" onclick="createBackup()">
                            <i class="bi bi-plus-circle"></i> Create Backup
                        </button>
                        <span id="backupAutoStatus" class="text-muted small"></span>
                    </div>
                    <div id="backupList">
                        <div class="text-center text-muted py-3">
                            <div class="spinner-border spinner-border-sm"></div> Loading...
                        </div>
                    </div>
                    <hr class="my-3">
                    <h6 class="mb-2"><i class="bi bi-arrows-collapse"></i> Optimize database</h6>
                    <p class="text-muted small mb-2">
                        Reclaim space freed by message retention. Runs SQLite <code>VACUUM</code>;
                        readers keep working but writes are paused for a few seconds.
                    </p>
                    <div class="d-flex justify-content-between align-items-center">
                        <button class="btn btn-outline-primary btn-sm" id="vacuumDbBtn" onclick="optimizeDatabase()">
                            <i class="bi bi-arrows-collapse"></i> Optimize now
                        </button>
                        <span id="vacuumDbStatus" class="text-muted small">Current size: …</span>
                    </div>
                </div>
            </div>
        </div>
    </div>

    <!-- Search Modal -->
    <div class="modal fade" id="searchModal" tabindex="-1">
        <div class="modal-dialog modal-lg">
            <div class="modal-content">
                <div class="modal-header">
                    <h5 class="modal-title"><i class="bi bi-search"></i> Search Messages</h5>
                    <button type="button" class="btn-close" data-bs-dismiss="modal"></button>
                </div>
                <div class="modal-body">
                    <div class="input-group mb-3">
                        <input type="text" class="form-control" id="searchInput" placeholder="Search all messages..." autofocus>
                        <button class="btn btn-primary" type="button" id="searchBtn">
                            <i class="bi bi-search"></i>
                        </button>
                        <button class="btn btn-outline-secondary" type="button" id="searchHelpBtn" title="Search syntax help">
                            <i class="bi bi-question-circle"></i>
                        </button>
                    </div>
                    <div id="searchHelp" class="alert alert-light small mb-3" style="display:none;">
                        <strong>Search tips:</strong>
                        <ul class="mb-1 ps-3">
                            <li><code>hello world</code> — messages containing both words</li>
                            <li><code>"hello world"</code> — exact phrase</li>
                            <li><code>hello OR world</code> — either word</li>
                            <li><code>hello NOT world</code> — hello but not world</li>
                            <li><code>hell*</code> — prefix match (hello,hellas...)</li>
                        </ul>
                        <div class="text-muted">Special characters (<code>. , - :</code>) should be wrapped in quotes.<br>
                        <a href="https://www.sqlite.org/fts5.html#full_text_query_syntax" target="_blank" rel="noopener">Full FTS5 syntax reference <i class="bi bi-box-arrow-up-right"></i></a></div>
                    </div>
                    <div id="searchResults">
                        <div class="text-center text-muted py-4">
                            <i class="bi bi-search" style="font-size: 2rem;"></i>
                            <p class="mt-2 mb-0">Search across all channel and direct messages</p>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>

    <!-- Toast container for notifications (position classes applied by JS from ui_settings) -->
    <div class="toast-container position-fixed top-0 start-0 p-3" data-toast-container>
        <div id="notificationToast" class="toast" role="alert">
            <div class="toast-header">
                <strong class="me-auto">mc-webui</strong>
                <button type="button" class="btn-close" data-bs-dismiss="toast"></button>
            </div>
            <div class="toast-body"></div>
        </div>
    </div>

    <!-- Bootstrap 5 JS Bundle (local) -->
    <script src="{{ url_for('static', filename='vendor/bootstrap/js/bootstrap.bundle.min.js') }}"></script>

    <!-- Leaflet JS -->
    <script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"
            integrity="sha256-20nQCchB9co0qIjJZRGuk2/Z9VM+kNiyxNV1lvTlZBo="
            crossorigin=""></script>

    <!-- Message Content Processing Utilities (must load before app.js and dm.js) -->
    <script src="{{ url_for('static', filename='js/message-utils.js') }}"></script>

    <!-- Filter Utilities (must load before app.js) -->
    <script src="{{ url_for('static', filename='js/filter-utils.js') }}"></script>

    <!-- SocketIO for real-time updates -->
    <script src="{{ url_for('static', filename='vendor/socket.io/socket.io.min.js') }}"></script>

    <!-- FAB Utilities (drag, sizing — must load before app.js) -->
    <script src="{{ url_for('static', filename='js/fab-utils.js') }}"></script>

    <!-- Custom JS -->
    <!-- QR Code generator (for Device Share) -->
    <script src="https://cdn.jsdelivr.net/npm/qrcodejs@1.0.0/qrcode.min.js"></script>

    <script src="{{ url_for('static', filename='js/app.js') }}"></script>

    <!-- PWA Viewport Fix for Android -->
    <script>
        // Fix viewport corruption on Android PWA after page reload
        window.addEventListener('load', function() {
            // Force viewport recalculation without modifying body height
            setTimeout(() => {
                window.scrollTo(0, 0);
                // Force reflow using a less invasive method
                void(document.documentElement.offsetHeight);
                // Trigger resize event to recalculate layout
                window.dispatchEvent(new Event('resize'));
            }, 150);
        });
    </script>

    <!-- Service Worker Registration for PWA -->
    <script>
        // Register Service Worker for PWA functionality
        if ('serviceWorker' in navigator) {
            window.addEventListener('load', () => {
                navigator.serviceWorker.register('/static/js/sw.js')
                    .then((registration) => {
                        console.log('Service Worker registered:', registration.scope);
                    })
                    .catch((error) => {
                        console.error('Service Worker registration failed:', error);
                    });
            });
        }
    </script>

    <!-- Theme Switching -->
    <script>
        function setTheme(theme) {
            document.documentElement.setAttribute('data-theme', theme);
            document.documentElement.setAttribute('data-bs-theme', theme);
            localStorage.setItem('mc-webui-theme', theme);
            // Update theme selector UI
            document.querySelectorAll('.theme-option').forEach(function(el) {
                el.classList.toggle('active', el.getAttribute('data-theme-value') === theme);
            });
        }

        // Initialize theme selector UI on settings modal open
        document.addEventListener('DOMContentLoaded', function() {
            var current = localStorage.getItem('mc-webui-theme') || 'light';
            document.querySelectorAll('.theme-option').forEach(function(el) {
                el.classList.toggle('active', el.getAttribute('data-theme-value') === current);
            });

            // --- FAB appearance controls ---
            var fabSizeSlider = document.getElementById('settFabSize');
            var fabSizeVal = document.getElementById('settFabSizeVal');
            var fabGapSlider = document.getElementById('settFabGap');
            var fabGapVal = document.getElementById('settFabGapVal');
            var fabResetPos = document.getElementById('settFabResetPos');

            // Load saved values
            var savedSize = localStorage.getItem('mc-webui-fab-size');
            var savedGap = localStorage.getItem('mc-webui-fab-gap');
            if (savedSize && fabSizeSlider) { fabSizeSlider.value = savedSize; fabSizeVal.textContent = savedSize; }
            if (savedGap && fabGapSlider) { fabGapSlider.value = savedGap; fabGapVal.textContent = savedGap; }

            // Live preview on slider change
            if (fabSizeSlider) {
                fabSizeSlider.addEventListener('input', function() {
                    var v = this.value;
                    fabSizeVal.textContent = v;
                    document.documentElement.style.setProperty('--fab-custom-size', v + 'px');
                    localStorage.setItem('mc-webui-fab-size', v);
                });
            }
            if (fabGapSlider) {
                fabGapSlider.addEventListener('input', function() {
                    var v = this.value;
                    fabGapVal.textContent = v;
                    document.documentElement.style.setProperty('--fab-custom-gap', v + 'px');
                    localStorage.setItem('mc-webui-fab-gap', v);
                });
            }

            // Reset position button
            if (fabResetPos) {
                fabResetPos.addEventListener('click', function() {
                    localStorage.removeItem('mc-webui-fab-pos');
                    localStorage.removeItem('mc-webui-fab-pos-dm');
                    var container = document.getElementById('fabContainer');
                    if (container) {
                        container.style.left = '';
                        container.style.right = '16px';
                        container.style.top = '80px';
                    }
                });
            }
        });
    </script>

    {% block extra_scripts %}{% endblock %}
</body>
</html>
