        :root {
            --bg: #f4f5f7; --surface: #fff; --border: #e2e2e8; --text: #1a1a1a; --text-muted: #6c6f7c;
            --header-bg: #1a1a2e; --header-text: #fff; --accent: #1a1a2e;
            --input-bg: #fff; --input-border: #ccc; --row-alt: #fafbfd; --code-bg: #f0f0f3;
            --error-bg: #fdecea; --error-text: #611a15; --error-border: #f5c6cb;
            --warn-bg: #fff8e1; --warn-text: #7a5900; --warn-border: #f5deb0;
        }
        html[data-theme="dark"] {
            --bg: #14151c; --surface: #1d1e28; --border: #333544; --text: #e7e8ec; --text-muted: #9a9caa;
            --header-bg: #0c0d13; --header-text: #e7e8ec; --accent: #4b5bd6;
            --input-bg: #23242f; --input-border: #40424f; --row-alt: #22232e; --code-bg: #2a2b38;
            --error-bg: #3a1c1c; --error-text: #f5b8b3; --error-border: #6b2c2c;
            --warn-bg: #3a2f10; --warn-text: #f5d78a; --warn-border: #6b5a26;
        }
        body { font-family: system-ui, sans-serif; margin: 0; background: var(--bg); color: var(--text); transition: background 0.15s, color 0.15s; }

        header {
            background: var(--header-bg); color: var(--header-text); padding: 0.75rem 1.5rem;
            display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; gap: 1rem;
        }
        header .brand { justify-self: start; font-weight: 600; }
        header nav { justify-self: center; display: flex; align-items: center; gap: 1rem; }
        header nav .nav-divider { width: 1px; height: 1.1rem; background: rgba(255,255,255,0.2); margin: 0 0.15rem; }
        header .right { justify-self: end; display: flex; align-items: center; gap: 0.6rem; }
        header a { color: var(--header-text); text-decoration: none; opacity: 0.85; }
        header a:hover { opacity: 1; }
        /* The base button rule below adds margin-top for form buttons like
           "Save settings" - header buttons must not inherit that, and both
           need the same explicit height so the round toggle and the
           pill-shaped logout button sit on a shared baseline instead of
           each sizing itself from its own padding. */
        header .right button { margin-top: 0; height: 2.25rem; box-sizing: border-box; }

        .theme-toggle {
            background: transparent; color: var(--header-text); border: 1px solid rgba(255,255,255,0.25);
            border-radius: 20px; width: 2.25rem; padding: 0;
            cursor: pointer; font-size: 1rem; line-height: 1; display: inline-flex; align-items: center; justify-content: center;
        }
        .theme-toggle:hover { border-color: rgba(255,255,255,0.5); }

        main { max-width: 1030px; margin: 2rem auto; padding: 0 1rem; }
        /* FocusOnNavigate (Routes.razor) moves keyboard focus to each page's
           <h2> after navigation, so screen readers announce the new page -
           a genuine accessibility feature, kept as-is. This only suppresses
           the browser's default visible focus ring around it, since that
           outline reads as unintended debug styling to a sighted user; the
           focus itself (and what a screen reader announces) is unaffected -
           that's driven by DOM focus state, not by whether it's drawn. Real
           keyboard navigation (Tab) still shows normal focus rings on every
           actual interactive element (links, buttons, inputs) - this rule
           only targets the one heading that's focused programmatically,
           never by a user pressing Tab. */
        main h2:focus { outline: none; }
        footer {
            max-width: 1030px; margin: 2rem auto 1.5rem auto; padding: 1rem 1rem 0 1rem;
            border-top: 1px solid var(--border); color: var(--text-muted);
            font-size: 0.8rem; text-align: center;
        }
        .card { background: var(--surface); border: 1px solid var(--border); border-radius: 8px; padding: 1.5rem; margin-bottom: 1.5rem; }
        .error { background: var(--error-bg); color: var(--error-text); border: 1px solid var(--error-border); border-radius: 6px; padding: 0.75rem 1rem; margin-bottom: 1rem; }
        .success-banner {
            background: color-mix(in srgb, #22c55e 12%, var(--surface));
            border: 1px solid color-mix(in srgb, #22c55e 45%, var(--border));
            color: var(--text); border-radius: 6px; padding: 0.9rem 1.1rem; margin-bottom: 1rem;
        }
        .success-banner strong.success-title { color: #16a34a; }
        .success-banner .token-display {
            display: block; background: var(--code-bg); color: var(--text);
            padding: 0.5rem 0.7rem; border-radius: 4px; margin: 0.5rem 0; font-size: 0.95rem;
            word-break: break-all;
        }
        .sync-notice {
            /* Lives INSIDE <main> now (not a sibling), so it automatically
               shares the exact same width as the cards around it instead
               of trying to hand-match two independently computed box
               models - that mismatch was why it looked wider before. */
            margin-top: 0.5rem; padding: 0.85rem 1.1rem;
            background: var(--warn-bg); color: var(--warn-text); border: 1px solid var(--warn-border);
            border-radius: 6px; font-size: 0.9rem;
        }
        label { display: block; font-weight: 600; margin: 0.75rem 0 0.25rem; font-size: 0.9rem; }
        input[type=text], input[type=password], input[type=number], select, textarea {
            width: 100%; padding: 0.5rem; border: 1px solid var(--input-border); border-radius: 4px; box-sizing: border-box;
            background: var(--input-bg); color: var(--text); font-family: inherit; font-size: 0.95rem;
        }
        textarea { resize: vertical; min-height: 4.5rem; }
        button, .btn { background: var(--accent); color: #fff; border: none; padding: 0.55rem 1.1rem; border-radius: 4px; cursor: pointer; font-size: 0.9rem; font-family: inherit; margin-top: 1rem; display: inline-flex; align-items: center; text-decoration: none; }
        button.secondary, .btn.secondary { background: var(--text-muted); }
        button.danger, .btn.danger { background: #b3261e; }
        table { width: 100%; border-collapse: collapse; margin-top: 1rem; }
        th, td { text-align: left; padding: 0.5rem 0.6rem; border-bottom: 1px solid var(--border); font-size: 0.9rem; vertical-align: middle; }
        /* The base button rule adds margin-top for form buttons like "Save
           settings" that sit below an input - inside a table row that
           margin has nothing to align against, so action buttons (Disable,
           Delete, etc.) dropped visibly out of line with the row's text. */
        td button, td .btn { margin-top: 0; vertical-align: middle; }
        /* Action-column buttons (Edit/Disable/Delete etc.) must stay on one
           line - without this, a long value in an earlier column (a
           filename, an advert name) could squeeze this cell enough that
           the last button wraps onto its own line. */
        /* Right-aligns action-button cells (Edit/Disable/Delete etc.) - opt-in
           via CellClass on the relevant <DataColumn>, not automatic for every
           table's last column, since not every table's last column holds
           action buttons (e.g. the Dashboard's stale-sites table ends with a
           plain "Last check-in" date, which should stay left-aligned). */
        .table-actions-cell { text-align: right; }
        td form.inline { display: inline-flex; vertical-align: middle; }
        tr:nth-child(even) td { background: var(--row-alt); }
        .badge { display: inline-block; padding: 0.1rem 0.5rem; border-radius: 10px; font-size: 0.75rem; vertical-align: middle; }
        .badge-admin { background: #e3e0ff; color: #33267a; }
        .badge-user { background: #e6e6e6; color: #333; }
        .badge-disabled { background: var(--error-bg); color: var(--error-text); }
        .badge-active { background: #d7f5df; color: #166534; }
        form.inline { display: inline; }
        code { background: var(--code-bg); color: var(--text); padding: 0.15rem 0.4rem; border-radius: 3px; font-size: 0.85em; }
        main a:not(.btn) { color: var(--accent); }

        /* Dashboard stat cards */
        .stat-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 1rem; margin-bottom: 1.5rem; }
        .stat-card {
            background: var(--surface); border: 1px solid var(--border); border-radius: 8px;
            padding: 1.1rem 1.25rem;
        }
        .stat-card.stat-green {
            border-color: color-mix(in srgb, #22c55e 45%, var(--border));
            background: color-mix(in srgb, #22c55e 8%, var(--surface));
        }
        .stat-card.stat-amber {
            border-color: color-mix(in srgb, #f59e0b 45%, var(--border));
            background: color-mix(in srgb, #f59e0b 8%, var(--surface));
        }
        .stat-card.stat-red {
            border-color: color-mix(in srgb, #ef4444 45%, var(--border));
            background: color-mix(in srgb, #ef4444 8%, var(--surface));
        }
        .stat-label { font-size: 0.85rem; color: var(--text-muted); margin-bottom: 0.35rem; }
        .stat-value { font-size: 1.9rem; font-weight: 700; line-height: 1; }
        .stat-value .stat-sub { font-size: 1.1rem; font-weight: 500; color: var(--text-muted); }
        .section-header {
            display: flex; align-items: center; justify-content: space-between;
            margin-bottom: 0.75rem;
        }
        .section-header h3 { margin: 0; }

        /* Searchable/sortable data tables */
        .table-search-input {
            max-width: 280px; margin-bottom: 0.75rem;
            background: var(--input-bg); color: var(--text); border: 1px solid var(--input-border);
            border-radius: 4px; padding: 0.5rem; font-family: inherit; font-size: 0.95rem;
        }
        /* When the search box joins a page-provided toolbar row (e.g.
           Sites' bulk-action buttons) instead of sitting on its own line,
           it shouldn't carry that line's bottom spacing too - the
           container itself already handles spacing before the table. */
        .table-toolbar-slot .table-search-input { margin-bottom: 0; max-width: 220px; }
        /* The search box and toolbar buttons have slightly different
           padding/font metrics, which left them looking subtly uneven even
           though both were already vertically centered in the flex row - an
           identical explicit height (matching the header's button height)
           makes the whole toolbar line up cleanly regardless of that. */
        .table-toolbar-slot .table-search-input,
        .table-toolbar-slot button {
            height: 2.25rem; box-sizing: border-box; margin-top: 0;
        }
        table.data-table thead th { cursor: pointer; user-select: none; white-space: nowrap; }
        table.data-table thead th:hover { color: var(--accent); }
        /* table-layout:fixed is what makes the "no horizontal scroll, ever"
           guarantee possible: without it, a column grows to fit its longest
           content (a long filename, say) and can push the whole table wider
           than its container. With it, column widths come only from the
           header row (see DataColumn's Width param / DataTable's HeaderStyle)
           and never from body content - so a long value wraps onto a second
           line within its cell instead of stretching the table. Row height
           grows to fit when that happens; the table's width never does. */
        table.data-table { table-layout: fixed; width: 100%; }
        table.data-table th, table.data-table td { overflow-wrap: break-word; word-break: break-word; }
        /* For cell content that can't be length-limited at entry (e.g. an
           uploaded file's original filename) - truncates with an ellipsis
           instead of breaking the table layout, with the full value
           available as a native tooltip on hover (via the title attribute
           set alongside this class). */
        .truncate-cell {
            max-width: 100%; overflow: hidden; text-overflow: ellipsis;
            white-space: nowrap; display: inline-block; vertical-align: middle;
        }
        table.data-table thead th:not(:empty)::after {
            content: "\25B2"; margin-left: 0.3em; font-size: 0.8em; opacity: 0;
        }
        table.data-table thead th[data-sort-dir]::after { opacity: 0.7; }
        table.data-table thead th[data-sort-dir="desc"]::after { content: "\25BC"; }
        .table-no-results { color: var(--text-muted); padding: 0.75rem 0; font-size: 0.9rem; }
        /* Scrollable table body: the whole result set stays on one page and
           the table scrolls inside a fixed-height area, with the header row
           kept in view via position:sticky. */
        .table-scroll { overflow-y: auto; overflow-x: hidden; border: 1px solid var(--border); border-radius: 8px; }
        .table-scroll table.data-table { margin: 0; }
        .table-scroll table.data-table thead th {
            position: sticky; top: 0; z-index: 1;
            background: var(--surface); box-shadow: inset 0 -1px 0 var(--border);
        }
        .table-rowcount { color: var(--text-muted); font-size: 0.82rem; margin: 0.4rem 0.1rem 0.75rem; }
        /* The inline "now editing this row" panel (Sites/Users' RowDetail) -
           a top accent border to visually set it apart from the row above
           it being edited. The panel's own background comes from an inline
           style on its <td> (it needs the same --row-alt value normal
           alternating rows use), so this class only adds the border. */
        tr.edit-row > td { border-top: 2px solid var(--accent); }
        /* The inline "confirm this deletion" panel (Videos/Users' RowDetail) -
           same idea as edit-row, but a danger-tinted border instead of the
           accent color, since this is a destructive confirmation, not an edit. */
        tr.confirm-row > td { border-top: 2px solid var(--error-border); }
        /* Groups the search box and any page-provided toolbar buttons (e.g.
           Sites' bulk actions) into one panel above the table - only used on
           pages that provide a toolbar. */
        .table-controls-panel {
            background: var(--row-alt); border: 1px solid var(--border); border-radius: 8px;
            padding: 0.85rem 1rem; margin-bottom: 1rem;
        }
        .table-selected-badge {
            background: var(--code-bg); color: var(--text-muted); border-radius: 20px;
            padding: 0.25rem 0.7rem; font-size: 0.82rem; font-weight: 600; white-space: nowrap;
        }

