{% extends "admin/base.html" %}
{% load i18n static admin_extras %}
{% block dark-mode-vars %}
  <link rel="stylesheet" href="{% static "admin/css/dark_mode.css" %}">
  <script>
    (function () {
      const defaultTheme = 'dark';
      let theme = defaultTheme;

      try {
        const storage = window.localStorage;
        const storedTheme = storage.getItem('theme');
        const validThemes = ['light', 'dark', 'auto'];

        if (storedTheme === null) {
          storage.setItem('theme', defaultTheme);
        } else if (validThemes.indexOf(storedTheme) !== -1) {
          theme = storedTheme;
        } else {
          storage.setItem('theme', defaultTheme);
        }
      } catch (error) {
        theme = defaultTheme;
      }

      document.documentElement.dataset.theme = theme;
    })();
  </script>
  <script src="{% static "admin/js/theme.js" %}"></script>
{% endblock %}
{% block title %}{% if title %}{{ title }} | {% endif %}{{ site_title|default:_('Django site admin') }}{% endblock %}
{% block extrahead %}
{{ block.super }}
<script
  src="https://unpkg.com/htmx.org@1.9.12/dist/htmx.min.js"
  integrity="sha384-OLBgp1GsljhM2TJ+sbHjaiH9txEUvgdDTAzHv2P24donTt6/529l+9Ua0vFImLlb"
  crossorigin="anonymous"
  defer
></script>
{% if badge_node and badge_node.role %}
  {% if badge_node.role.name == "Control" %}
<link rel="icon" href="data:image/png;base64,{% include 'admin/favicon_control.txt' %}">
  {% elif badge_node.role.name == "Watchtower" or badge_node.role.name == "Constellation" %}
<link rel="icon" href="data:image/png;base64,{% include 'admin/favicon_watchtower.txt' %}">
  {% elif badge_node.role.name == "Satellite" %}
<link rel="icon" href="data:image/png;base64,{% include 'admin/favicon_satellite.txt' %}">
  {% else %}
<link rel="icon" href="data:image/png;base64,{% include 'admin/favicon.txt' %}">
  {% endif %}
{% elif current_site_domain == "arthexis.com" %}
<link rel="icon" href="data:image/png;base64,{% include 'admin/favicon_arthexis.txt' %}">
{% else %}
<link rel="icon" href="data:image/png;base64,{% include 'admin/favicon.txt' %}">
{% endif %}
<script id="admin-filter-empty-groups">
document.addEventListener('DOMContentLoaded', function () {
    const nav = document.getElementById('nav-filter');
    const sidebar = document.getElementById('nav-sidebar');
    if (!nav || !sidebar) {
        return;
    }

    const modules = Array.from(sidebar.querySelectorAll('.module'));

    function toggleEmptyGroups() {
        const query = nav.value.trim().toLowerCase();
        const visibleModules = [];

        modules.forEach(function (module) {
            const hasVisibleRows = Array.from(module.querySelectorAll('tr')).some(function (row) {
                return row.style.display !== 'none' && row.querySelector('th[scope="row"]');
            });

            if (hasVisibleRows) {
                module.style.display = '';
                visibleModules.push(module);
            } else {
                module.style.display = 'none';
            }
        });

        // Ensure modules remain expanded while filtering and during normal navigation.
        visibleModules.forEach(function (module) {
            module.classList.remove('collapsed');
        });
    }

    nav.addEventListener('change', toggleEmptyGroups);
    nav.addEventListener('input', toggleEmptyGroups);
    nav.addEventListener('keyup', toggleEmptyGroups);

    toggleEmptyGroups();
});
</script>
<script id="admin-sidebar-collapse-toggle-visibility">
document.addEventListener('DOMContentLoaded', function () {
    const sidebar = document.getElementById('nav-sidebar');
    if (!sidebar) {
        return;
    }

    const toggles = sidebar.querySelectorAll('.app-collapse-toggle');
    if (!toggles.length) {
        return;
    }

    toggles.forEach(function (button) {
        button.hidden = true;
        button.setAttribute('aria-hidden', 'true');
        button.setAttribute('tabindex', '-1');
    });
});
</script>
{% now "c" as current_time %}
{% now "T" as current_tz %}
<script id="admin-server-clock">
document.addEventListener('DOMContentLoaded', function () {
    const clock = document.getElementById('server-clock');
    if (!clock) {
        return;
    }
    const serverStart = Date.parse("{{ current_time|escapejs }}");
    const clientStart = Date.now();
    const tz = "{{ TIME_ZONE|escapejs }}";
    function pad(n) {
        return String(n).padStart(2, '0');
    }
    function update() {
        const now = new Date(serverStart + (Date.now() - clientStart));
        const formatted = `${now.getFullYear()}-${pad(now.getMonth() + 1)}-${pad(now.getDate())} ${pad(now.getHours())}:${pad(now.getMinutes())}:${pad(now.getSeconds())}`;
        clock.textContent = `${formatted} {{ current_tz|escapejs }}`;
        const dateFull = new Intl.DateTimeFormat([], { timeZone: tz, year: 'numeric', month: 'long', day: 'numeric' }).format(now);
        const weekday = new Intl.DateTimeFormat([], { timeZone: tz, weekday: 'long' }).format(now);
        const tzName = new Intl.DateTimeFormat([], { timeZone: tz, timeZoneName: 'long' })
            .formatToParts(now)
            .find(part => part.type === 'timeZoneName').value;
        clock.title = `${dateFull}\n${weekday}\n${tzName}`;
    }
    update();
    setInterval(update, 1000);
});
</script>
{% if request.user.is_authenticated and request.user.is_staff %}
{% include "core/version_check.html" %}
{% endif %}
<script id="admin-breadcrumb-copy">
document.addEventListener('DOMContentLoaded', function () {
    const breadcrumbs = document.querySelector('.breadcrumbs');
    if (!breadcrumbs || breadcrumbs.dataset.copyEnhanced === '1') {
        return;
    }

    const breadcrumbText = breadcrumbs.textContent.replace(/\s+/g, ' ').trim();
    if (!breadcrumbText) {
        return;
    }

    const copyLabel = '{% translate "Copy" %}';
    const copiedLabel = '{% translate "Copied" %}';
    const copyErrorLabel = '{% translate "Copy failed" %}';

    function copyText(value) {
        if (navigator.clipboard && navigator.clipboard.writeText) {
            return navigator.clipboard.writeText(value);
        }

        return new Promise(function (resolve, reject) {
            const textarea = document.createElement('textarea');
            textarea.value = value;
            textarea.setAttribute('readonly', '');
            textarea.style.position = 'absolute';
            textarea.style.left = '-9999px';
            document.body.appendChild(textarea);
            const selection = document.getSelection();
            const selected = selection && selection.rangeCount > 0 ? selection.getRangeAt(0) : null;
            textarea.select();

            try {
                document.execCommand('copy');
                resolve();
            } catch (error) {
                reject(error);
            }

            document.body.removeChild(textarea);

            if (selected && selection) {
                selection.removeAllRanges();
                selection.addRange(selected);
            }
        });
    }

    function setStatus(label) {
        breadcrumbsCopyLink.textContent = label;
        window.setTimeout(function () {
            breadcrumbsCopyLink.textContent = copyLabel;
        }, 2000);
    }

    const breadcrumbsCopyLink = document.createElement('a');
    breadcrumbsCopyLink.href = '#';
    breadcrumbsCopyLink.className = 'breadcrumbs__copy-link';
    breadcrumbsCopyLink.textContent = copyLabel;
    breadcrumbsCopyLink.dataset.breadcrumbCopy = '1';
    breadcrumbsCopyLink.setAttribute('role', 'button');
    breadcrumbsCopyLink.setAttribute('aria-label', '{% translate "Copy breadcrumb to clipboard" %}');

    breadcrumbs.dataset.copyEnhanced = '1';
    breadcrumbs.dataset.breadcrumbText = breadcrumbText;
    breadcrumbs.appendChild(breadcrumbsCopyLink);

    breadcrumbsCopyLink.addEventListener('click', function (event) {
        event.preventDefault();
        const breadcrumbLabel = breadcrumbs.dataset.breadcrumbText || breadcrumbText;
        const copyValue = `In ${breadcrumbLabel} (${window.location.href})`;

        copyText(copyValue)
            .then(function () {
                setStatus(copiedLabel);
            })
            .catch(function () {
                setStatus(copyErrorLabel);
            });
    });
});
</script>
{% endblock %}
{% block extrastyle %}
{{ block.super }}
<style>
.breadcrumbs__copy-link {
    margin-left: 0.5rem;
    font-size: 0.875rem;
}

:root {
    --user-story-card-bg: var(--body-bg, #ffffff);
    --user-story-card-fg: var(--body-fg, #212529);
    --user-story-card-border: rgba(15, 23, 42, 0.12);
    --user-story-input-bg: var(--body-bg, #ffffff);
    --user-story-input-border: rgba(15, 23, 42, 0.15);
    --user-story-checkbox-border: rgba(15, 23, 42, 0.25);
    --user-story-muted: rgba(15, 23, 42, 0.6);
    --user-story-focus-ring: rgba(37, 99, 235, 0.2);
    --user-story-alert-success-bg: rgba(34, 197, 94, 0.12);
    --user-story-alert-success-border: rgba(34, 197, 94, 0.35);
    --user-story-alert-success-fg: #047857;
    --user-story-alert-danger-bg: rgba(248, 113, 113, 0.12);
    --user-story-alert-danger-border: rgba(248, 113, 113, 0.35);
    --user-story-alert-danger-fg: #b91c1c;
    --user-story-close-hover-bg: rgba(15, 23, 42, 0.08);
    --auto-upgrade-failover-bg: rgba(248, 113, 113, 0.12);
    --auto-upgrade-failover-border: rgba(185, 28, 28, 0.35);
    --auto-upgrade-failover-title: #b91c1c;
    --auto-upgrade-failover-link: #b91c1c;
    --auto-upgrade-failover-button-bg: #dc2626;
    --auto-upgrade-failover-button-hover: #b91c1c;
    --auto-upgrade-failover-button-secondary-border: rgba(185, 28, 28, 0.4);
}

.chat-widget {
    position: fixed;
    left: 1.5rem;
    bottom: 1.5rem;
    z-index: 1090;
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 0.5rem;
}

.chat-toggle {
    position: relative;
    border: 0;
    border-radius: 50%;
    width: 3rem;
    height: 3rem;
    padding: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: linear-gradient(135deg, #15803d, #34d399);
    color: #f0fdf4;
    box-shadow: 0 1.25rem 2.5rem rgba(15, 23, 42, 0.35);
    transition: transform 0.2s ease, box-shadow 0.2s ease;
}

.chat-toggle:hover,
.chat-toggle:focus-visible {
    transform: translateY(-2px) scale(1.02);
    box-shadow: 0 1.75rem 3rem rgba(15, 23, 42, 0.45);
}

.chat-toggle .chat-toggle-icon {
    display: inline-flex;
}

.chat-toggle .chat-toggle-icon svg {
    width: 1.5rem;
    height: 1.5rem;
    display: block;
}

.chat-toggle .chat-toggle-label {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

.chat-toggle .chat-unread {
    position: absolute;
    top: -0.35rem;
    right: -0.35rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 1.5rem;
    height: 1.5rem;
    padding: 0 0.35rem;
    border-radius: 999px;
    font-size: 0.65rem;
    background: #16a34a;
    color: #fff;
    box-shadow: 0 0.35rem 0.85rem rgba(14, 116, 44, 0.45);
}

.chat-toggle .chat-unread[hidden] {
    display: none;
}

.chat-overlay {
    position: fixed;
    inset: 0;
    display: flex;
    align-items: flex-end;
    justify-content: flex-start;
    padding: 1.5rem;
    background: rgba(15, 23, 42, 0.45);
    z-index: 1080;
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.2s ease;
}

.chat-overlay.show {
    opacity: 1;
    pointer-events: auto;
}

.chat-drawer {
    width: min(28rem, 100%);
    border-radius: 1rem;
    background: var(--body-bg);
    color: var(--body-fg);
    box-shadow: 0 1.5rem 3rem rgba(15, 23, 42, 0.45);
    border: 1px solid rgba(21, 128, 61, 0.25);
    overflow: hidden;
    transform: translateY(1rem);
    opacity: 0;
    transition: transform 0.25s ease, opacity 0.25s ease;
    display: flex;
    flex-direction: column;
}

.chat-overlay.show .chat-drawer {
    transform: translateY(0);
    opacity: 1;
}

.chat-widget.open .chat-toggle {
    visibility: hidden;
    opacity: 0;
    pointer-events: none;
}

.chat-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    padding: 1rem 1.25rem;
    background: linear-gradient(135deg, rgba(22, 163, 74, 0.18), rgba(16, 185, 129, 0.25));
    border-bottom: 1px solid rgba(21, 128, 61, 0.35);
}

.chat-header h2 {
    margin: 0;
    font-size: 1rem;
}

.chat-header small {
    display: block;
    font-size: 0.75rem;
    opacity: 0.8;
}

.chat-close {
    border: 0;
    background: transparent;
    color: var(--body-fg);
    width: 2.5rem;
    height: 2.5rem;
    border-radius: 999px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    transition: background-color 0.15s ease, color 0.15s ease, transform 0.15s ease;
}

.chat-close::before {
    content: "\00d7";
    font-size: 1.25rem;
    font-weight: 700;
    line-height: 1;
}

.chat-close:hover,
.chat-close:focus-visible {
    background: rgba(21, 128, 61, 0.12);
    color: #15803d;
    transform: translateY(-1px);
    outline: none;
}

.chat-messages {
    flex: 1 1 auto;
    max-height: 18rem;
    overflow-y: auto;
    padding: 1rem 1.25rem;
    display: flex;
    flex-direction: column;
    gap: 0.85rem;
}

.chat-message {
    display: flex;
    flex-direction: column;
    gap: 0.2rem;
    font-size: 0.9rem;
    line-height: 1.45;
}

.chat-message.staff {
    align-items: flex-end;
}

.chat-message.staff .chat-meta {
    text-align: right;
}

.chat-bubble {
    padding: 0.6rem 0.9rem;
    border-radius: 0.85rem;
    background: rgba(34, 197, 94, 0.16);
    border: 1px solid rgba(22, 163, 74, 0.15);
    max-width: 100%;
    word-break: break-word;
    white-space: pre-wrap;
}

.chat-message.staff .chat-bubble {
    background: rgba(21, 128, 61, 0.22);
    border-color: rgba(21, 128, 61, 0.3);
}

.chat-meta {
    font-size: 0.75rem;
    color: rgba(21, 94, 49, 0.75);
}

.chat-form {
    border-top: 1px solid rgba(21, 128, 61, 0.25);
    padding: 0.75rem 1.25rem 1.25rem;
    background: var(--body-bg);
}

.chat-form textarea {
    resize: vertical;
    min-height: 3.5rem;
}

.chat-form .chat-input {
    width: 100%;
    max-width: 100%;
    box-sizing: border-box;
    display: block;
    background: var(--body-bg);
    color: var(--body-fg);
    border: 1px solid rgba(21, 128, 61, 0.35);
    border-radius: 0.75rem;
    padding: 0.75rem 0.9rem;
    line-height: 1.5;
    box-shadow: inset 0 0.08rem 0.35rem rgba(15, 23, 42, 0.12);
}

.chat-input::placeholder {
    color: rgba(21, 94, 49, 0.7);
}

.chat-input:focus-visible {
    outline: 2px solid rgba(22, 163, 74, 0.35);
    outline-offset: 2px;
    border-color: rgba(22, 163, 74, 0.6);
}

.chat-actions {
    margin-top: 0.5rem;
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: 0.75rem;
}

.chat-actions .chat-session-hint {
    color: rgba(21, 94, 49, 0.65);
}

.chat-form .button-primary,
.chat-form .btn-primary {
    background: linear-gradient(135deg, #15803d, #22c55e);
    border-color: #15803d;
    color: #052e16;
    box-shadow: 0 0.75rem 1.5rem rgba(15, 23, 42, 0.25);
}

.chat-form .button-primary:hover,
.chat-form .button-primary:focus-visible,
.chat-form .btn-primary:hover,
.chat-form .btn-primary:focus-visible {
    background: linear-gradient(135deg, #166534, #16a34a);
    border-color: #166534;
    color: #f0fdf4;
}

.chat-session-hint {
    font-size: 0.75rem;
    opacity: 0.7;
}

body.chat-open {
    overflow: hidden;
}

@media (max-width: 575.98px) {
    .chat-widget {
        left: 1rem;
        bottom: 1rem;
    }
}

@media (max-width: 767.98px) {
    .chat-overlay {
        align-items: stretch;
        justify-content: flex-start;
        padding: 1rem;
    }

    .chat-drawer {
        width: 100%;
        max-width: none;
        border-radius: 1rem;
    }
}

[data-theme="dark"] {
    --user-story-card-bg: #0f172a;
    --user-story-card-fg: #f8fafc;
    --user-story-card-border: rgba(148, 163, 184, 0.25);
    --user-story-input-bg: #1e293b;
    --user-story-input-border: rgba(148, 163, 184, 0.35);
    --user-story-checkbox-border: rgba(148, 163, 184, 0.35);
    --user-story-muted: rgba(148, 163, 184, 0.85);
    --user-story-focus-ring: rgba(59, 130, 246, 0.45);
    --user-story-alert-success-bg: rgba(34, 197, 94, 0.16);
    --user-story-alert-success-border: rgba(34, 197, 94, 0.45);
    --user-story-alert-success-fg: #22c55e;
    --user-story-alert-danger-bg: rgba(248, 113, 113, 0.18);
    --user-story-alert-danger-border: rgba(248, 113, 113, 0.45);
    --user-story-alert-danger-fg: #fca5a5;
    --user-story-close-hover-bg: rgba(148, 163, 184, 0.25);
    --auto-upgrade-failover-bg: rgba(248, 113, 113, 0.18);
    --auto-upgrade-failover-border: rgba(248, 113, 113, 0.45);
    --auto-upgrade-failover-title: #fca5a5;
    --auto-upgrade-failover-link: #fca5a5;
    --auto-upgrade-failover-button-bg: #f87171;
    --auto-upgrade-failover-button-hover: #fca5a5;
    --auto-upgrade-failover-button-secondary-border: rgba(248, 113, 113, 0.45);
}

body.login #header {
    padding-top: 1em;
    padding-bottom: 1em;
}

body.login #branding {
    flex-direction: column;
    align-items: center;
}

body.login #site-name {
    margin-inline-end: 0;
}

body.login #site-badges {
    margin-top: 0.5em;
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
}
body.login #site-badges .badge {
    margin-right: 0.5em;
    font-size: 0.7em;
    padding: 2px 4px;
    border-radius: 4px;
    color: white;
}
body.login #site-badges .badge a {
    color: white;
    text-decoration: none;
}
body.login .badge-unknown {background-color:#6c757d;}

.auto-upgrade-failover-banner {
    align-items: flex-start;
    background-color: var(--auto-upgrade-failover-bg);
    border: 1px solid var(--auto-upgrade-failover-border);
    border-radius: 14px;
    box-shadow: 0 14px 40px rgba(15, 23, 42, 0.12);
    color: inherit;
    display: flex;
    flex-wrap: wrap;
    gap: 1.25rem;
    margin: 1.5rem 0;
    padding: 1.25rem 1.5rem;
}

.auto-upgrade-failover-body {
    flex: 1 1 300px;
    min-width: 0;
}

.auto-upgrade-failover-title {
    color: var(--auto-upgrade-failover-title);
    display: block;
    font-size: 1.1rem;
    font-weight: 700;
    margin-bottom: 0.25rem;
}

.auto-upgrade-failover-detail {
    line-height: 1.6;
    margin: 0;
}

.auto-upgrade-failover-detail a {
    color: var(--auto-upgrade-failover-link);
    font-weight: 600;
    text-decoration: underline;
}

.auto-upgrade-failover-meta {
    display: flex;
    flex-wrap: wrap;
    gap: 0.75rem;
    list-style: none;
    margin: 0.75rem 0 0;
    padding: 0;
    font-size: 0.85rem;
    opacity: 0.85;
}

.auto-upgrade-failover-actions {
    align-items: center;
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
}

.auto-upgrade-failover-actions form {
    display: inline;
}

.auto-upgrade-failover-actions .button {
    background-color: var(--auto-upgrade-failover-button-bg);
    border: none;
    border-radius: 999px;
    color: #fff;
    font-weight: 600;
    padding: 0.45rem 1.4rem;
    transition: background-color 0.2s ease, transform 0.2s ease;
}

.auto-upgrade-failover-actions .button:hover,
.auto-upgrade-failover-actions .button:focus-visible {
    background-color: var(--auto-upgrade-failover-button-hover);
    color: #fff;
    transform: translateY(-1px);
}

.auto-upgrade-failover-actions .auto-upgrade-failover-button-secondary {
    background: transparent;
    border: 1px solid var(--auto-upgrade-failover-button-secondary-border);
    color: inherit;
    padding: 0.45rem 1.4rem;
}

[data-theme="dark"] .auto-upgrade-failover-actions .auto-upgrade-failover-button-secondary {
    color: var(--body-fg, #f8fafc);
}

.auto-upgrade-failover-actions .auto-upgrade-failover-button-secondary:hover,
.auto-upgrade-failover-actions .auto-upgrade-failover-button-secondary:focus-visible {
    background-color: rgba(15, 23, 42, 0.08);
    color: inherit;
    transform: none;
}

@media (max-width: 960px) {
    .auto-upgrade-failover-banner {
        padding: 1.25rem;
    }

    .auto-upgrade-failover-actions {
        width: 100%;
        justify-content: flex-start;
    }
}

#server-clock {
    font-family: monospace;
    font-size: 0.9rem;
}

.user-tools-placeholder {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    color: var(--body-quiet-color, #6b7280);
    font-size: 0.9rem;
}

.user-tools-spinner {
    width: 0.85rem;
    height: 0.85rem;
    border: 2px solid var(--border-color, rgba(15, 23, 42, 0.2));
    border-top-color: var(--link-fg, #2563eb);
    border-radius: 999px;
    display: inline-flex;
    animation: user-tools-spin 0.9s linear infinite;
}

@keyframes user-tools-spin {
    0% {
        transform: rotate(0deg);
    }
    100% {
        transform: rotate(360deg);
    }
}

body:not(.login) #header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding-top: 0;
    padding-bottom: 0;
}

body:not(.login) #branding,
body:not(.login) #user-tools {
    float: none;
}

body:not(.login) #branding {
    display: flex;
    align-items: center;
}

body:not(.login) #site-name {
    margin: 0;
    display: flex;
    align-items: center;
}

body:not(.login) #site-name > a {
    margin-right: 10px;
    margin-bottom: 0;
}

body:not(.login) #site-badges {
    margin-left: 0.5em;
    display: flex;
    align-items: center;
}

body:not(.login) #site-badges .badge {
    margin-right: 0.25em;
    padding: 2px 6px;
    border-radius: 4px;
    font-size: 0.8em;
    color: white;
}

body:not(.login) #site-badges .badge a {
    color: white;
    text-decoration: none;
}

body:not(.login) .badge-unknown {background-color:#6c757d;}
#nav-sidebar .module h2 {
    cursor: default;
}
.form-row {
    margin-top: 0;
    margin-bottom: 0;
}
.form-row > div:only-child input[type="text"]:not(.vDateField):not(.vTimeField),
.form-row > div:only-child textarea {
    width: 150% !important;
}

.form-row .datetime {
    display: flex;
    gap: 0.5em;
}

.favorite-star {
    color: #666;
    text-decoration: none;
    margin-right: 4px;
    background: none;
    border: none;
    padding: 0;
    line-height: 1;
    cursor: pointer;
}
.favorite-star.favorited {
    color: gold;
}
.favorite-star.user-data-star {
    color: #0d6efd;
    background: none;
    border: none;
    padding: 0;
    line-height: 1;
    cursor: pointer;
}
.favorite-star.user-data-star.has-user-data {
    color: gold;
}
.favorite-star.user-data-star.disabled {
    cursor: default;
}
.favorite-toggle-form {
    display: inline;
}

.content-title-with-favorite {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin-bottom: 1rem;
}

.content-title-with-favorite h1 {
    margin: 0;
}
.user-data-column {
    text-align: center;
    width: 2.5rem;
}

/* Highlight the currently selected model row */
.current-model > th,
.current-model > td {
    background: var(--selected-row);
}

.related-widget-wrapper {
    display: flex;
    align-items: center;
    gap: 4px;
    flex-wrap: nowrap;
}

.related-widget-wrapper > div {
    display: flex;
    align-items: center;
    gap: 4px;
    flex: 1 1 auto;
    min-width: 0;
}

.related-widget-wrapper input,
.related-widget-wrapper select,
.related-widget-wrapper textarea {
    flex: 1 1 auto;
    min-width: 0;
    width: auto !important;
}

.related-widget-wrapper .related-lookup {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    box-sizing: border-box;
    flex: 0 0 auto;
    width: 2.25rem;
    height: 2.25rem;
    margin-left: 0;
    border: 1px solid var(--border-color);
    border-radius: 4px;
    background-color: var(--button-bg);
    background-repeat: no-repeat;
    background-position: center;
    background-size: 1rem;
}

.related-widget-wrapper .related-lookup:hover {
    background-color: var(--button-hover-bg);
}

/* Ensure related object buttons match theme */
.related-widget-wrapper-link {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    box-sizing: border-box;
    width: 2.25rem;
    height: 2.25rem;
    padding: 0;
    border: 1px solid var(--border-color);
    border-radius: 4px;
    background: var(--button-bg);
    color: var(--button-fg);
}

.related-widget-wrapper > .related-widget-wrapper-link {
    margin-left: 0;
}

.related-widget-wrapper-link:hover {
    background: var(--button-hover-bg);
}

/* Style object action buttons like history links */
.object-tools li button {
    border: none;
    border-radius: 15px;
    display: block;
    float: left;
    padding: 5px 12px;
    line-height: 1rem;
    background: var(--object-tools-bg);
    color: var(--object-tools-fg);
    font-weight: 400;
    font-size: 0.6875rem;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    cursor: pointer;
}

.object-tools li button:focus,
.object-tools li button:hover {
    background-color: var(--object-tools-hover-bg);
}

/* Language dropdown styling */
.language-select {
    background: none;
    border: none;
    color: var(--header-link-color);
    cursor: pointer;
}

.language-select option {
    background-color: var(--body-bg);
    color: var(--body-fg);
}

/* Align delete button with other submit-row buttons */
.submit-row a.deletelink {
    margin-left: 0;
    display: inline-block;
    padding: 0.625rem 0.9375rem;
    height: 0.9375rem;
    line-height: 0.9375rem;
    border-radius: 4px;
    background: var(--delete-button-bg, #ba2121);
    color: var(--button-fg);
    font-weight: 600;
    text-transform: uppercase;
    text-decoration: none;
}

.submit-row a.deletelink:focus,
.submit-row a.deletelink:hover {
    background: var(--delete-button-hover-bg, #a41515);
    color: var(--button-fg);
}

/* Keep dual-selector widgets oriented left-to-right */
.selector {
    flex-direction: row;
}

.selector-available {
    order: 0;
}

.selector ul.selector-chooser {
    order: 1;
}

.selector-chosen {
    order: 2;
}

.user-story-toggle {
    position: fixed;
    right: 1.75rem;
    bottom: 1.75rem;
    width: 3rem;
    height: 3rem;
    border-radius: 50%;
    border: 0;
    background: linear-gradient(135deg, #facc15, #fb923c);
    color: #1f2937;
    display: flex;
    align-items: center;
    justify-content: center;
    box-shadow: 0 1.25rem 2.5rem rgba(15, 23, 42, 0.35);
    transition: transform 0.2s ease, box-shadow 0.2s ease;
    z-index: 1080;
}

.user-story-toggle:hover,
.user-story-toggle:focus-visible {
    transform: translateY(-2px) scale(1.02);
    box-shadow: 0 1.75rem 3rem rgba(15, 23, 42, 0.45);
}

.user-story-toggle svg {
    width: 1.75rem;
    height: 1.75rem;
    display: block;
}

body.user-story-open .user-story-toggle {
    visibility: hidden;
    opacity: 0;
    pointer-events: none;
}

body.user-story-open {
    overflow: hidden;
}

.user-story-overlay {
    position: fixed;
    inset: 0;
    display: flex;
    align-items: flex-end;
    justify-content: flex-end;
    padding: 1.5rem;
    background: rgba(15, 23, 42, 0.45);
    z-index: 1070;
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.2s ease;
}

.user-story-overlay.show {
    opacity: 1;
    pointer-events: auto;
}

.user-story-card {
    width: min(28rem, 100%);
    border-radius: 1rem;
    box-shadow: 0 1.5rem 3rem rgba(15, 23, 42, 0.45);
    background: var(--user-story-card-bg);
    color: var(--user-story-card-fg);
    transform: translateY(1rem);
    transition: transform 0.25s ease;
}

.user-story-card .card-header {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 1rem;
    padding: 1.25rem 1.25rem 0.75rem;
    border-bottom: 1px solid var(--user-story-card-border);
}

.user-story-card .card-body {
    padding: 1rem 1.25rem 1.5rem;
}

.user-story-card .card-title {
    margin-bottom: 0.25rem;
}

.user-story-card .card-subtitle {
    margin-bottom: 0;
}

.user-story-card .btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    padding: 0.65rem 1rem;
    border: none;
    border-radius: 0.75rem;
    font-weight: 600;
    letter-spacing: 0.02em;
    background: linear-gradient(135deg, #2563eb, #0ea5e9);
    color: #ffffff;
    cursor: pointer;
    transition: transform 0.15s ease, box-shadow 0.15s ease, opacity 0.15s ease;
}

.user-story-card .btn:hover,
.user-story-card .btn:focus-visible {
    transform: translateY(-1px);
    box-shadow: 0 1rem 2rem rgba(14, 165, 233, 0.35);
    text-decoration: none;
}

.user-story-card .btn:disabled {
    opacity: 0.6;
    cursor: not-allowed;
    box-shadow: none;
}

.user-story-card .btn-close {
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2rem;
    height: 2rem;
    border: none;
    border-radius: 50%;
    background: transparent;
    color: inherit;
    cursor: pointer;
    transition: background-color 0.15s ease, color 0.15s ease;
}

.user-story-card .btn-close::before {
    content: "\00d7";
    font-size: 1.25rem;
    line-height: 1;
}

.user-story-card .btn-close:hover,
.user-story-card .btn-close:focus-visible {
    background-color: var(--user-story-close-hover-bg);
}

.user-story-card .form-control,
.user-story-card textarea {
    width: 100%;
    border-radius: 0.5rem;
    border: 1px solid var(--user-story-input-border);
    padding: 0.5rem 0.75rem;
    background: var(--user-story-input-bg);
    color: var(--user-story-card-fg);
    transition: border-color 0.15s ease, box-shadow 0.15s ease;
    resize: vertical;
}

.user-story-card .form-control::placeholder,
.user-story-card textarea::placeholder {
    color: var(--user-story-muted);
}

.user-story-card .form-control:focus,
.user-story-card textarea:focus {
    border-color: #2563eb;
    box-shadow: 0 0 0 0.2rem var(--user-story-focus-ring);
    outline: none;
}

.user-story-card .form-check-input {
    width: 1.15rem;
    height: 1.15rem;
    border-radius: 0.35rem;
    border: 1px solid var(--user-story-checkbox-border);
    background-color: var(--user-story-input-bg);
    color: var(--user-story-card-fg);
    cursor: pointer;
}

.user-story-card .mb-3 {
    margin-bottom: 1rem;
}

.user-story-card .mt-3 {
    margin-top: 1rem;
}

.user-story-card .w-100 {
    width: 100%;
}

.user-story-card .py-2 {
    padding-top: 0.5rem;
    padding-bottom: 0.5rem;
}

.user-story-card .d-none {
    display: none !important;
}

.user-story-card .form-check-input:focus {
    border-color: #2563eb;
    box-shadow: 0 0 0 0.2rem var(--user-story-focus-ring);
}

.user-story-overlay.show .user-story-card {
    transform: translateY(0);
}

.user-story-rating {
    display: inline-flex;
    flex-direction: row-reverse;
    gap: 0.35rem;
}

.user-story-feedback-options {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    flex-wrap: wrap;
}

.user-story-card .form-label,
.user-story-card .form-text,
.user-story-card .form-check-label {
    display: block;
}

.user-story-card .form-text {
    color: var(--user-story-muted);
    font-size: 0.85rem;
    margin-top: 0.3rem;
}

.user-story-card .text-muted {
    color: var(--user-story-muted) !important;
}

.user-story-clipboard {
    margin: 0;
    margin-left: auto;
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
}

.user-story-clipboard .form-check-input {
    margin-top: 0;
}

.user-story-rating input {
    position: absolute;
    opacity: 0;
    pointer-events: none;
}

.user-story-rating label {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 1.75rem;
    color: rgba(148, 163, 184, 0.7);
    cursor: pointer;
    transition: transform 0.2s ease, color 0.2s ease;
}

.user-story-rating label:hover,
.user-story-rating label:focus-visible,
.user-story-rating label:hover ~ label {
    color: #fbbf24;
}

.user-story-rating input:checked ~ label {
    color: #f59e0b;
}

.user-story-rating label:active {
    transform: scale(0.95);
}

.user-story-alert {
    transition: opacity 0.2s ease;
}

.user-story-card .alert {
    margin-bottom: 0;
    border-radius: 0.75rem;
    border: 1px solid transparent;
    padding: 0.75rem 1rem;
}

.user-story-card .alert-success {
    background-color: var(--user-story-alert-success-bg);
    border-color: var(--user-story-alert-success-border);
    color: var(--user-story-alert-success-fg);
}

.user-story-card .alert-danger {
    background-color: var(--user-story-alert-danger-bg);
    border-color: var(--user-story-alert-danger-border);
    color: var(--user-story-alert-danger-fg);
}

@media (max-width: 767.98px) {
    .user-story-toggle {
        right: 1.25rem;
        bottom: 1.25rem;
    }

    .user-story-overlay {
        align-items: stretch;
        padding: 1rem;
    }

    .user-story-card {
        width: 100%;
        border-radius: 1rem;
    }
}
</style>
{% endblock %}
{% block branding %}
<h1 id="site-name">
  <a href="{% url 'admin:index' %}"><span id="server-clock"></span></a>
</h1>
<div id="site-badges">
  {% if badge_site %}
    <span class="badge" style="background-color: {{ badge_site_color }};">
      <a href="{% url 'admin:pages_siteproxy_changelist' %}">SITE</a>:
      <a href="{% url 'admin:pages_siteproxy_change' badge_site.pk %}">{{ badge_admin_site_name }}</a>
      <span style="display:none">SITE: {{ badge_admin_site_name }}</span>
    </span>
  {% else %}
    <span class="badge badge-unknown">
      <a href="{% url 'admin:pages_siteproxy_changelist' %}">SITE</a>: Unknown
      <span style="display:none">SITE: Unknown</span>
    </span>
  {% endif %}
  {% if badge_node %}
    <span class="badge" style="background-color: {{ badge_node_color }};">
      <a href="{% url 'admin:nodes_node_changelist' %}">NODE</a>:
      <a href="{% url 'admin:nodes_node_change' badge_node.pk %}">{{ badge_node.hostname }}</a>
      <span style="display:none">NODE: {{ badge_node.hostname }}</span>
    </span>
    {% if badge_node.role %}
      <span class="badge" style="background-color: {{ badge_node_color }};">
        <a href="{% url 'admin:nodes_noderole_changelist' %}">ROLE</a>:
        <a href="{% url 'admin:nodes_noderole_change' badge_node.role.pk %}">{{ badge_node.role.name }}</a>
        <span style="display:none">ROLE: {{ badge_node.role.name }}</span>
      </span>
    {% endif %}
  {% else %}
    <span class="badge badge-unknown">
      <a href="{% url 'admin:nodes_node_changelist' %}">NODE</a>: Unknown
      <span style="display:none">NODE: Unknown</span>
    </span>
  {% endif %}
</div>
{% endblock %}
{% block userlinks %}
  <span
    id="user-tools-loader"
    hx-get="{% url 'admin-user-tools' %}"
    hx-target="#user-tools"
    hx-trigger="load"
    hx-swap="innerHTML"
  >
    <span class="user-tools-placeholder" aria-live="polite" aria-busy="true">
      <span class="user-tools-spinner" aria-hidden="true"></span>
      <span>{% trans "Loading account tools…" %}</span>
    </span>
    <span id="user-tools-inline-fallback" hidden>
      {% include "admin/includes/user_tools.html" %}
    </span>
  </span>
  <noscript>
    {% include "admin/includes/user_tools.html" %}
  </noscript>
  <script>
    document.addEventListener("DOMContentLoaded", function () {
      const loader = document.getElementById("user-tools-loader");
      const fallback = document.getElementById("user-tools-inline-fallback");

      function renderFallback() {
        if (!loader || !fallback) {
          return;
        }
        fallback.hidden = false;
        loader.replaceChildren(fallback);
      }

      if (!window.htmx) {
        renderFallback();
        return;
      }

      if (!loader) {
        return;
      }

      htmx.on(loader, "htmx:responseError", renderFallback);
      htmx.on(loader, "htmx:sendError", renderFallback);
      htmx.on(loader, "htmx:timeout", renderFallback);
    });
  </script>
{% endblock %}
{% block nav-global %}{% endblock %}
{% block nav-sidebar %}
  <button class="sticky toggle-nav-sidebar" id="toggle-nav-sidebar" aria-label="{% translate 'Toggle navigation' %}"></button>
  <nav class="sticky" id="nav-sidebar" aria-label="{% translate 'Sidebar' %}">
    <input type="search" id="nav-filter"
           placeholder="{% translate 'Start typing to filter…' %}"
           aria-label="{% translate 'Filter navigation items' %}">
    {% include 'admin/app_list.html' with app_list=available_apps %}
  </nav>
{% endblock %}
{% block messages %}
  {% if request.user.is_authenticated and request.user.is_staff and auto_upgrade_failover %}
    <section class="auto-upgrade-failover-banner" role="alert" aria-live="polite">
      <div class="auto-upgrade-failover-body">
        <span class="auto-upgrade-failover-title">{% trans "Auto-upgrade reverted to failover mode" %}</span>
        <p class="auto-upgrade-failover-detail">
          {{ auto_upgrade_failover.detail }}
          <a href="{% url 'admin:system-upgrade-report' %}">{% trans "Review auto-upgrade log" %}</a>.
        </p>
        {% if auto_upgrade_failover.created or auto_upgrade_failover.revision %}
          <ul class="auto-upgrade-failover-meta">
            {% if auto_upgrade_failover.created %}
              <li>{% blocktrans with timestamp=auto_upgrade_failover.created|date:'SHORT_DATETIME_FORMAT' %}Recorded {{ timestamp }}{% endblocktrans %}</li>
            {% endif %}
            {% if auto_upgrade_failover.revision %}
              <li>{% blocktrans with revision=auto_upgrade_failover.revision|slice:':7' %}Revision {{ revision }}{% endblocktrans %}</li>
            {% endif %}
          </ul>
        {% endif %}
      </div>
      <div class="auto-upgrade-failover-actions">
        <form action="{% url 'admin:system-upgrade-dismiss-failover' %}" method="post">
          {% csrf_token %}
          <input type="hidden" name="next" value="{{ request.get_full_path }}">
          <button type="submit" class="button auto-upgrade-failover-button-secondary">{% trans "Dismiss" %}</button>
        </form>
        <form action="{% url 'admin:system-upgrade-run-check' %}" method="post">
          {% csrf_token %}
          <input type="hidden" name="channel" value="normal">
          <input type="hidden" name="next" value="{{ request.get_full_path }}">
          <button type="submit" class="button">{% trans "Retry upgrade" %}</button>
        </form>
      </div>
    </section>
  {% endif %}
  {% include "admin/includes/messages.html" %}
{% endblock %}
{% block footer %}
  {{ block.super }}
  {% if chat_enabled and request.user.is_authenticated %}
    <div
      id="chat-widget"
      class="chat-widget"
      data-path="{{ chat_socket_path }}"
      data-session-storage-key="pages.chat.session"
      data-connected-text="{% trans 'Connected' %}"
      data-connecting-text="{% trans 'Connecting…' %}"
      data-disconnected-text="{% trans 'Disconnected' %}"
      data-unread-text="{% trans 'New' %}"
      data-open-text="{% trans 'Need help?' %}"
      data-close-text="{% trans 'Close chat' %}"
      data-session-label="{% trans 'Session' %}"
      data-empty-text="{% trans 'Say hello to start the conversation.' %}"
      data-error-text="{% trans 'We could not send your message. Please retry.' %}"
      data-staff-join-text="{% trans 'A staff member joined the chat.' %}"
      data-staff-leave-text="{% trans 'A staff member left the chat.' %}"
      data-visitor-join-text="{% trans 'You joined the chat.' %}"
      data-visitor-leave-text="{% trans 'You left the chat.' %}"
      data-staff="{{ request.user.is_staff|yesno:"true,false" }}"
    >
      <button
        type="button"
        class="chat-toggle"
        data-chat-toggle
        aria-expanded="false"
        aria-controls="chat-drawer"
        aria-label="{% trans 'Need help?' %}"
      >
        <span class="chat-toggle-icon" aria-hidden="true">
          <svg viewBox="0 0 24 24" focusable="false" aria-hidden="true">
            <path
              fill="currentColor"
              d="M12 3c-4.97 0-9 3.582-9 8 0 1.93.78 3.69 2.08 5.08-.097.86-.43 2.348-1.4 3.734a.75.75 0 00.902 1.133c2.115-.633 3.422-1.522 4.09-2.073A10.63 10.63 0 0012 19c4.97 0 9-3.582 9-8s-4.03-8-9-8z"
            ></path>
          </svg>
        </span>
        <span class="chat-toggle-label">{% trans "Need help?" %}</span>
        <span class="chat-unread" data-chat-unread hidden>{% trans "New" %}</span>
      </button>
      <div
        class="chat-overlay"
        data-chat-overlay
        role="presentation"
        hidden
      >
        <aside
          id="chat-drawer"
          class="chat-drawer"
          data-chat-drawer
          role="dialog"
          aria-modal="true"
          aria-labelledby="chat-title"
          aria-label="{% trans 'Support chat' %}"
        >
          <header class="chat-header">
            <div>
              <h2 class="mb-0" id="chat-title">{% trans "Support" %}</h2>
              <small data-chat-status>{% trans "Connecting…" %}</small>
            </div>
            <button type="button" class="chat-close" data-chat-close aria-label="{% trans 'Close chat' %}"></button>
          </header>
          <div
            class="chat-messages"
            data-chat-messages
            role="log"
            aria-live="polite"
            aria-relevant="additions"
          ></div>
          <form class="chat-form" data-chat-form>
            <label class="visually-hidden" for="chat-message-input">{% trans "Message" %}</label>
            <textarea
              id="chat-message-input"
              class="vLargeTextField chat-input"
              name="message"
              rows="3"
              data-chat-input
              placeholder="{% trans 'Type your message…' %}"
              required
            ></textarea>
            <div class="chat-actions">
              <span class="chat-session-hint" data-chat-session-hint></span>
              <button type="submit" class="button button-primary">{% trans "Send" %}</button>
            </div>
          </form>
        </aside>
      </div>
    </div>
    <script src="{% static 'pages/js/chat.js' %}" defer></script>
  {% endif %}
  {% include "admin/includes/user_story_feedback.html" %}
{% endblock %}
