/* Q-Mgr Custom Styles */
/* Theme variables and fonts are loaded once via <link> tags in App.razor
   (layout.css, qm-theme.css, q-components.css, Google Fonts) —
   do not re-@import them here; @import is render-blocking and was
   duplicating the font/theme request. */

/* ================================
   Light Mode - Component Overrides
   Theme TOKENS ([data-theme="light"] custom properties) live in
   qm-theme.css only — that is the single source of truth. This file
   only applies those variables to specific component selectors below;
   it must never redefine the tokens themselves (a duplicate copy here
   previously drifted out of sync with qm-theme.css and silently won
   the cascade since this file loads later).
   ================================ */

/* Body & Root */
[data-theme="light"] html,
[data-theme="light"] body {
    background-color: var(--qm-bg-dark) !important;
    color: var(--qm-text-primary) !important;
}

/* Header */
[data-theme="light"] .rz-layout-header {
    background: var(--qm-gradient-header) !important;
    border-bottom: 1px solid var(--qm-border) !important;
    box-shadow: var(--qm-shadow-sm) !important;
}

[data-theme="light"] .header-brand .brand-text {
    background: var(--qm-gradient-primary);
    -webkit-background-clip: text;
    -webkit-text-fill-color: transparent;
    background-clip: text;
}

[data-theme="light"] .header-datetime {
    color: var(--qm-text-secondary) !important;
    border-color: var(--qm-border) !important;
}

[data-theme="light"] .header-datetime .time {
    color: var(--qm-text-primary) !important;
}

[data-theme="light"] .theme-toggle,
[data-theme="light"] .notification-btn {
    color: var(--qm-text-secondary) !important;
}

[data-theme="light"] .theme-toggle:hover,
[data-theme="light"] .notification-btn:hover {
    background: rgba(var(--qm-primary-rgb), 0.1) !important;
    color: var(--qm-primary) !important;
}

/* Sidebar */
[data-theme="light"] .rz-sidebar {
    background: var(--qm-gradient-sidebar) !important;
    border-right: 1px solid var(--qm-border) !important;
    box-shadow: var(--qm-shadow-sm) !important;
}

[data-theme="light"] .sidebar-header {
    border-bottom: 1px solid var(--qm-border) !important;
}

[data-theme="light"] .sidebar-title {
    color: var(--qm-text-muted) !important;
}

/* Panel Menu - Navigation */
[data-theme="light"] .rz-panelmenu {
    background: transparent !important;
}

[data-theme="light"] .rz-panelmenu-header {
    color: var(--qm-text-primary) !important;
}

[data-theme="light"] .rz-panelmenu-header > a {
    color: var(--qm-text-primary) !important;
}

[data-theme="light"] .rz-panelmenu-header > a:hover {
    background: rgba(0, 0, 0, 0.04) !important;
}

[data-theme="light"] .rz-panelmenu-header > a .rz-icon {
    color: var(--qm-primary) !important;
}

[data-theme="light"] .rz-panelmenu-item a {
    color: var(--qm-text-secondary) !important;
}

[data-theme="light"] .rz-panelmenu-item:hover a {
    background: rgba(var(--qm-primary-rgb), 0.08) !important;
    color: var(--qm-primary) !important;
}

[data-theme="light"] .rz-panelmenu-item.rz-state-active a,
[data-theme="light"] .rz-panelmenu-item-selected a {
    background: var(--qm-gradient-primary) !important;
    color: var(--qm-text-on-primary) !important;
}

/* Sidebar Footer & Branch Selector */
[data-theme="light"] .sidebar-footer {
    border-top: 1px solid var(--qm-border) !important;
}

[data-theme="light"] .branch-selector {
    background: var(--qm-bg-card) !important;
    border: 1px solid var(--qm-border) !important;
}

[data-theme="light"] .branch-selector:hover {
    background: rgba(var(--qm-primary-rgb), 0.05) !important;
    border-color: var(--qm-primary) !important;
}

[data-theme="light"] .branch-selector .rzi {
    color: var(--qm-primary) !important;
}

[data-theme="light"] .branch-label {
    color: var(--qm-text-muted) !important;
}

[data-theme="light"] .branch-name {
    color: var(--qm-text-primary) !important;
}

/* Body Content */
[data-theme="light"] .rz-layout-body {
    background: var(--qm-bg-dark) !important;
}

/* Footer */
[data-theme="light"] .rz-layout-footer {
    background: var(--qm-bg-darker) !important;
    border-top: 1px solid var(--qm-border) !important;
}

[data-theme="light"] .footer-text {
    color: var(--qm-text-muted) !important;
}

/* Page Header */
[data-theme="light"] .page-header {
    background: var(--qm-gradient-header) !important;
    border-bottom: 1px solid var(--qm-border);
}

[data-theme="light"] .page-header h1 {
    color: var(--qm-text-primary) !important;
}

[data-theme="light"] .page-header .breadcrumb {
    color: var(--qm-text-secondary) !important;
}

/* Cards */
[data-theme="light"] .rz-card,
[data-theme="light"] .dashboard-card,
[data-theme="light"] .settings-card {
    background: var(--qm-bg-card) !important;
    border: 1px solid var(--qm-border) !important;
    box-shadow: var(--qm-shadow-sm) !important;
}

[data-theme="light"] .card-header {
    border-bottom: 1px solid var(--qm-border) !important;
}

[data-theme="light"] .card-header h3 {
    color: var(--qm-text-primary) !important;
}

/* Stats Cards */
[data-theme="light"] .stats-card {
    background: var(--qm-bg-card) !important;
    border: 1px solid var(--qm-border) !important;
}

[data-theme="light"] .stats-card .stats-number {
    color: var(--qm-text-primary) !important;
}

[data-theme="light"] .stats-card .stats-label {
    color: var(--qm-text-secondary) !important;
}

/* DataGrid / Tables */
[data-theme="light"] .rz-datatable {
    background: var(--qm-bg-card) !important;
    border: 1px solid var(--qm-border) !important;
}

[data-theme="light"] .rz-datatable-header,
[data-theme="light"] .rz-datatable thead {
    background: var(--qm-bg-darker) !important;
}

[data-theme="light"] .rz-datatable thead th {
    color: var(--qm-text-secondary) !important;
    border-bottom: 1px solid var(--qm-border) !important;
}

[data-theme="light"] .rz-datatable tbody tr {
    border-bottom: 1px solid var(--qm-border) !important;
}

[data-theme="light"] .rz-datatable tbody tr:hover {
    background: rgba(var(--qm-primary-rgb), 0.05) !important;
}

[data-theme="light"] .rz-datatable tbody td {
    color: var(--qm-text-primary) !important;
}

/* Form Controls */
[data-theme="light"] .rz-textbox,
[data-theme="light"] .rz-dropdown,
[data-theme="light"] .rz-inputtext,
[data-theme="light"] .rz-textarea {
    background: var(--qm-bg-card) !important;
    border: 1px solid var(--qm-border) !important;
    color: var(--qm-text-primary) !important;
}

[data-theme="light"] .rz-textbox:focus,
[data-theme="light"] .rz-dropdown.rz-state-focused {
    border-color: var(--qm-primary) !important;
    box-shadow: 0 0 0 3px rgba(var(--qm-primary-rgb), 0.1) !important;
}

[data-theme="light"] .rz-dropdown-panel {
    background: var(--qm-bg-card) !important;
    border: 1px solid var(--qm-border) !important;
    box-shadow: var(--qm-shadow-lg) !important;
}

[data-theme="light"] .rz-dropdown-item {
    color: var(--qm-text-primary) !important;
}

[data-theme="light"] .rz-dropdown-item:hover {
    background: rgba(var(--qm-primary-rgb), 0.08) !important;
}

/* Buttons */
[data-theme="light"] .rz-button-light,
[data-theme="light"] .rz-button.rz-light {
    background: var(--qm-bg-card) !important;
    border: 1px solid var(--qm-border) !important;
    color: var(--qm-text-primary) !important;
}

[data-theme="light"] .rz-button-light:hover,
[data-theme="light"] .rz-button.rz-light:hover {
    background: var(--qm-bg-darker) !important;
    border-color: var(--qm-primary) !important;
}

/* Dialogs - Use html[data-theme] for Radzen dialogs rendered at body level */
[data-theme="light"] .rz-dialog,
html[data-theme="light"] .rz-dialog {
    background: var(--qm-bg-card) !important;
    border: 1px solid var(--qm-border) !important;
    box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25) !important;
}

[data-theme="light"] .rz-dialog-titlebar,
html[data-theme="light"] .rz-dialog-titlebar {
    background: var(--qm-bg-darker) !important;
    color: var(--qm-text-primary) !important;
    border-bottom: 1px solid var(--qm-border) !important;
}

[data-theme="light"] .rz-dialog-titlebar .rz-dialog-title,
html[data-theme="light"] .rz-dialog-titlebar .rz-dialog-title {
    color: var(--qm-text-primary) !important;
}

[data-theme="light"] .rz-dialog-content,
html[data-theme="light"] .rz-dialog-content {
    background: var(--qm-bg-card) !important;
    color: var(--qm-text-primary) !important;
}

/* Radzen Confirm Dialog specific */
[data-theme="light"] .rz-dialog-wrapper,
html[data-theme="light"] .rz-dialog-wrapper {
    background: var(--qm-bg-card) !important;
}

[data-theme="light"] .rz-confirm-dialog,
html[data-theme="light"] .rz-confirm-dialog {
    background: var(--qm-bg-card) !important;
    color: var(--qm-text-primary) !important;
}

[data-theme="light"] .rz-dialog .rz-dialog-close,
html[data-theme="light"] .rz-dialog .rz-dialog-close {
    color: var(--qm-text-secondary) !important;
}

[data-theme="light"] .rz-dialog .rz-dialog-close:hover,
html[data-theme="light"] .rz-dialog .rz-dialog-close:hover {
    color: var(--qm-text-primary) !important;
    background: rgba(0, 0, 0, 0.05) !important;
}

/* Dialog Overlays */
[data-theme="light"] .dialog-overlay {
    background: rgba(0, 0, 0, 0.5) !important;
}

[data-theme="light"] .dialog-content,
[data-theme="light"] .branch-dialog {
    background: var(--qm-bg-card) !important;
    border: 1px solid var(--qm-border) !important;
}

[data-theme="light"] .dialog-header {
    border-bottom: 1px solid var(--qm-border) !important;
}

[data-theme="light"] .dialog-header h3 {
    color: var(--qm-text-primary) !important;
}

[data-theme="light"] .branch-item {
    background: transparent !important;
}

[data-theme="light"] .branch-item:hover {
    background: rgba(var(--qm-primary-rgb), 0.05) !important;
}

[data-theme="light"] .branch-item.active {
    background: rgba(var(--qm-primary-rgb), 0.08) !important;
    border: 1px solid var(--qm-primary) !important;
}

[data-theme="light"] .branch-item-name {
    color: var(--qm-text-primary) !important;
}

[data-theme="light"] .branch-item-address {
    color: var(--qm-text-muted) !important;
}

/* Notifications Panel */
[data-theme="light"] .notifications-panel {
    background: var(--qm-bg-card) !important;
    border: 1px solid var(--qm-border) !important;
    box-shadow: var(--qm-shadow-lg) !important;
}

[data-theme="light"] .notifications-header {
    border-bottom: 1px solid var(--qm-border) !important;
}

[data-theme="light"] .notifications-header h3 {
    color: var(--qm-text-primary) !important;
}

[data-theme="light"] .notification-item {
    border-bottom: 1px solid var(--qm-border) !important;
}

[data-theme="light"] .notification-item:hover {
    background: var(--qm-bg-darker) !important;
}

[data-theme="light"] .notification-item.unread {
    background: rgba(var(--qm-primary-rgb), 0.05) !important;
}

[data-theme="light"] .notification-title {
    color: var(--qm-text-primary) !important;
}

[data-theme="light"] .notification-message {
    color: var(--qm-text-secondary) !important;
}

[data-theme="light"] .notification-time {
    color: var(--qm-text-muted) !important;
}

/* Profile Menu */
[data-theme="light"] .rz-profile-menu-dropdown {
    background: var(--qm-bg-card) !important;
    border: 1px solid var(--qm-border) !important;
}

[data-theme="light"] .rz-profile-menu-item {
    color: var(--qm-text-primary) !important;
}

[data-theme="light"] .rz-profile-menu-item:hover {
    background: rgba(var(--qm-primary-rgb), 0.08) !important;
}

/* Tabs */
[data-theme="light"] .rz-tabview-nav {
    border-bottom: 1px solid var(--qm-border) !important;
}

[data-theme="light"] .rz-tabview-nav li a {
    color: var(--qm-text-secondary) !important;
}

[data-theme="light"] .rz-tabview-nav li.rz-state-active a {
    color: var(--qm-primary) !important;
}

/* Notifications Toast - Radzen renders these at body level */
[data-theme="light"] .rz-notification,
html[data-theme="light"] .rz-notification {
    background: var(--qm-bg-card) !important;
    border: 1px solid var(--qm-border) !important;
    color: var(--qm-text-primary) !important;
    box-shadow: var(--qm-shadow-lg) !important;
}

[data-theme="light"] .rz-notification-content,
html[data-theme="light"] .rz-notification-content {
    color: var(--qm-text-primary) !important;
}

/* Radzen Tooltip - renders at body level */
[data-theme="light"] .rz-tooltip,
html[data-theme="light"] .rz-tooltip {
    background: var(--qm-bg-card) !important;
    color: var(--qm-text-primary) !important;
    border: 1px solid var(--qm-border) !important;
    box-shadow: var(--qm-shadow-md) !important;
}

/* Radzen Context Menu - renders at body level */
[data-theme="light"] .rz-contextmenu,
html[data-theme="light"] .rz-contextmenu {
    background: var(--qm-bg-card) !important;
    border: 1px solid var(--qm-border) !important;
    box-shadow: var(--qm-shadow-lg) !important;
}

[data-theme="light"] .rz-contextmenu-item,
html[data-theme="light"] .rz-contextmenu-item {
    color: var(--qm-text-primary) !important;
}

[data-theme="light"] .rz-contextmenu-item:hover,
html[data-theme="light"] .rz-contextmenu-item:hover {
    background: rgba(var(--qm-primary-rgb), 0.08) !important;
}

/* Radzen Dropdown Panel - often renders at body level */
[data-theme="light"] .rz-dropdown-panel,
html[data-theme="light"] .rz-dropdown-panel {
    background: var(--qm-bg-card) !important;
    border: 1px solid var(--qm-border) !important;
    box-shadow: var(--qm-shadow-lg) !important;
}

[data-theme="light"] .rz-dropdown-item,
html[data-theme="light"] .rz-dropdown-item {
    color: var(--qm-text-primary) !important;
}

[data-theme="light"] .rz-dropdown-item:hover,
html[data-theme="light"] .rz-dropdown-item:hover {
    background: rgba(var(--qm-primary-rgb), 0.08) !important;
}

/* Radzen Multiselect/Checkbox in dropdown - light theme */
[data-theme="light"] .rz-dropdown-panel .rz-chkbox-label,
html[data-theme="light"] .rz-dropdown-panel .rz-chkbox-label,
[data-theme="light"] .rz-multiselect-item,
html[data-theme="light"] .rz-multiselect-item,
[data-theme="light"] .rz-listbox-item,
html[data-theme="light"] .rz-listbox-item {
    color: var(--qm-text-primary) !important;
}

[data-theme="light"] .rz-dropdown-panel .rz-chkbox-box,
html[data-theme="light"] .rz-dropdown-panel .rz-chkbox-box {
    border-color: var(--qm-border) !important;
    background: var(--qm-bg-card) !important;
}

[data-theme="light"] .rz-dropdown-panel .rz-chkbox-box.rz-state-active,
html[data-theme="light"] .rz-dropdown-panel .rz-chkbox-box.rz-state-active {
    background: var(--qm-primary) !important;
    border-color: var(--qm-primary) !important;
}

/* Radzen Menu - renders at body level */
[data-theme="light"] .rz-menu,
html[data-theme="light"] .rz-menu {
    background: var(--qm-bg-card) !important;
    border: 1px solid var(--qm-border) !important;
}

[data-theme="light"] .rz-menu-item,
html[data-theme="light"] .rz-menu-item {
    color: var(--qm-text-primary) !important;
}

[data-theme="light"] .rz-menu-item:hover,
html[data-theme="light"] .rz-menu-item:hover {
    background: rgba(var(--qm-primary-rgb), 0.08) !important;
}

/* Radzen Popup/Overlay */
[data-theme="light"] .rz-popup,
html[data-theme="light"] .rz-popup {
    background: var(--qm-bg-card) !important;
    border: 1px solid var(--qm-border) !important;
    box-shadow: var(--qm-shadow-lg) !important;
}

/* Scrollbars */
[data-theme="light"] ::-webkit-scrollbar-track {
    background: var(--qm-bg-card-hover);
}

[data-theme="light"] ::-webkit-scrollbar-thumb {
    background: var(--qm-border-hover);
}

[data-theme="light"] ::-webkit-scrollbar-thumb:hover {
    background: var(--qm-primary);
}

/* Loading Overlay */
[data-theme="light"] .loading-overlay {
    background: rgba(248, 250, 252, 0.95) !important;
}

[data-theme="light"] .loading-text {
    color: var(--qm-text-secondary) !important;
}

/* ================================
   Base Overrides
   ================================ */
html, body {
    font-family: var(--qm-font-primary, 'Poppins', 'Segoe UI', -apple-system, sans-serif);
    transition: background-color 0.3s ease, color 0.3s ease;
}

/* Smooth theme transitions */
*, *::before, *::after {
    transition: background-color 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease;
}

/* Dashboard Cards */
.dashboard-card {
    border-radius: var(--qm-radius-lg);
    transition: transform 0.2s, box-shadow 0.3s;
}

.dashboard-card:hover {
    transform: translateY(-4px);
}

/* Queue Board */
.token-badge {
    font-size: var(--qm-text-stat);
    padding: 0.75rem 1.25rem;
    border-radius: var(--qm-radius-md);
    font-family: 'Poppins', sans-serif;
    font-weight: 700;
}

/* Print Styles */
@media print {
    /* The app shell.
       This block used to name only Radzen's own classes (.rz-sidebar, .rz-layout-header,
       .rz-layout-footer) — none of which this app renders. Its shell is .qm-sidebar /
       .qm-header / .qm-footer, so every printed page carried the whole navigation down the
       left-hand side and the report itself started a third of the way across the paper.
       The Radzen selectors are kept for any Radzen-rendered surface that still uses them. */
    .no-print,
    .qm-sidebar,
    .qm-header,
    .qm-footer,
    .rz-sidebar,
    .rz-layout-header,
    .rz-layout-footer {
        display: none !important;
    }

    /* .qm-main is offset by the sidebar's width, which no longer exists on paper. */
    .qm-main,
    .qm-main.expanded {
        margin-left: 0 !important;
        padding: 0 !important;
        width: 100% !important;
    }

    .qm-app {
        display: block !important;
    }

    /* Cards and panels are screen furniture. On paper the shadow prints as a grey smudge and the
       fill wastes toner; the border alone is enough to keep a block legible. */
    .q-card,
    .qm-card {
        box-shadow: none !important;
        border: 1px solid #999 !important;
        break-inside: avoid;
        page-break-inside: avoid;
    }

    a[href]::after { content: ""; }

    @page {
        size: A4 portrait;
        margin: 14mm;
    }

    body {
        background: white !important;
        color: black !important;
    }

    .print-token {
        width: 80mm;
        padding: 10mm;
        font-family: monospace;
    }

    .print-token .token-number {
        font-size: 48pt;
        font-weight: bold;
        text-align: center;
    }
}

/* Animations */
.fade-in {
    animation: fadeIn 0.3s ease-in;
}

@keyframes fadeIn {
    from { opacity: 0; }
    to { opacity: 1; }
}

.slide-up {
    animation: slideUp 0.3s ease-out;
}

@keyframes slideUp {
    from { opacity: 0; transform: translateY(20px); }
    to { opacity: 1; transform: translateY(0); }
}

/* Theme toggle button animation */
.theme-toggle {
    position: relative;
    overflow: hidden;
}

.theme-toggle .rz-icon {
    transition: transform 0.3s ease;
}

.theme-toggle:hover .rz-icon {
    transform: rotate(15deg);
}

/* Notification badge animation */
.notification-badge {
    animation: badge-pulse 2s infinite;
}

@keyframes badge-pulse {
    0%, 100% { transform: scale(1); }
    50% { transform: scale(1.1); }
}

/* Branch selector hover effect */
.branch-selector {
    position: relative;
    overflow: hidden;
}

.branch-selector::after {
    content: '';
    position: absolute;
    top: 0;
    left: -100%;
    width: 100%;
    height: 100%;
    background: linear-gradient(90deg, transparent, rgba(var(--qm-primary-rgb), 0.1), transparent);
    transition: left 0.5s ease;
}

.branch-selector:hover::after {
    left: 100%;
}

/* ================================
   Mobile Utility Classes
   ================================ */

/* Hide/Show utilities */
.hide-mobile {
    display: block;
}
.show-mobile {
    display: none;
}

@media (max-width: 768px) {
    .hide-mobile {
        display: none !important;
    }
    .show-mobile {
        display: block !important;
    }
}

/* Text alignment for mobile */
@media (max-width: 576px) {
    .text-center-mobile {
        text-align: center !important;
    }
    .text-left-mobile {
        text-align: left !important;
    }
}

/* Flex utilities for mobile */
@media (max-width: 768px) {
    .flex-column-mobile {
        flex-direction: column !important;
    }
    .flex-wrap-mobile {
        flex-wrap: wrap !important;
    }
    .gap-sm-mobile {
        gap: 8px !important;
    }
}

/* Width utilities for mobile */
@media (max-width: 576px) {
    .w-100-mobile {
        width: 100% !important;
    }
    .max-w-100-mobile {
        max-width: 100% !important;
    }
}

/* ================================
   Common Page Patterns - Responsive
   ================================ */

/* Page Header — the LAYOUT of the band. The title size is .qm-main h1 (layout.css) and nothing
   else may set it.

   The 2026-09-18 note here said app.css loads last and therefore decides the band. It does not:
   css/components/admin.css and shared.css are linked after it in App.razor, and qm-theme.css
   carried a `padding: 32px` plus a full-bleed negative margin and a decorative radial blob that
   this file's padding-bottom could only partly override. All three are gone; this is the home now.

   Density (2026-09-19): 12px padding + 16px margin + a 1.45 subtitle came to 107px on a two-line
   header. A page is read for its data, so the band states the page and gets out of the way. */
.page-header {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: var(--q-row-gap, 8px);
    margin-bottom: var(--qm-block-gap, 16px);
    padding-bottom: var(--qm-page-header-gap, 12px);
    border-bottom: 1px solid var(--qm-border);
}

/* `.header-right` is what seven pages call their actions row. Same object, same rule — a band
   element must not escape the scale by being spelled differently. */
.page-header .header-right {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: var(--q-row-gap, 8px);
    margin-left: auto;
}

/* A PAGE'S BUTTONS SIT TOP RIGHT, ON THE TITLE ROW — everywhere (2026-09-19, "standardise the
   location of the action buttons"). `margin-left: auto` is what puts them there even when the
   row has nothing else in it: `.page-header` is space-between, and a lone child of a
   space-between row sits at the START, which is how the hub sections' buttons came to be on the
   left. Those sections now render into the hub's own row through QPageActions; this rule is the
   backstop for any page that still has a band of buttons alone. An outlet with no open section
   renders nothing, so an empty row takes no space. */
.page-header .header-actions {
    margin-left: auto;
    justify-content: flex-end;
}

.page-header .header-actions:empty {
    display: none;
}

/* THE TITLE AND ITS SUBTITLE SHARE ONE LINE (2026-09-19, second pass). Reported as "the heading
   / title bar is still big and occupying a lot of space, yet it has mainly the page title" — and
   that was right: a 22px title stacked over a 12.5px subtitle is two text lines to say one thing,
   and the subtitle is the half nobody re-reads. Baseline-aligned on one row, the subtitle takes
   whatever width is left and truncates; the whole sentence is on the QInfo beside the title.

   The band is now one row tall — the actions, or the title line, whichever is taller.
   31 pages wrote their own .page-header rule before this file owned it. */
.page-header .header-content,
.page-header .header-left {
    display: flex;
    /* CENTRE, not baseline. A QInfo in the h1 is an inline-flex element, which moves the h1 line
       box baseline and pushed the subtitle onto a second line — measured 52px against 33px for
       the same band without one. */
    align-items: center;
    gap: 10px;
    min-width: 0;
    flex: 1 1 340px;
}

.page-header h1 {
    /* The TITLE never shrinks and never wraps; the subtitle beside it absorbs the squeeze and
       truncates. With `flex: 0 1 auto` a long subtitle competed for the row and pushed a short
       title onto two lines — Class Teachers measured 52px against 33px for the same markup with a
       shorter sentence. */
    flex: 0 0 auto;
    white-space: nowrap;
}

/* `.header-left` belongs to the app topbar (layout.css), where it is a horizontal
   flex row sitting opposite `.header-right`. Nine page headers reuse the same class
   name for a stacked title block — h1, breadcrumb, subtitle, and sometimes a notice —
   and inherited that row, which laid those four out side by side across the full
   width. Worst on Billing/Modules, where the trial notice broke into columns with the
   sentence split across them. Scoped to `.page-header` so the topbar is untouched. */
.page-header .header-left {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 4px;
}

.page-header h1 {
    /* Size comes from .qm-main h1 — one home for the title scale. */
    margin: 0 0 2px;
    display: flex;
    align-items: center;
    gap: 12px;
}

.page-header h1 i {
    color: var(--qm-primary);
}

/* ONE LINE, BESIDE THE TITLE. A subtitle explains the page to somebody reading it for the first
   time and then costs every later visit a whole line of the screen for ever. The full sentence
   lives on the QInfo beside the title — see QInfo.razor for why that is a popover and not a
   tooltip.

   `.breadcrumb` is in this list because eleven pages use it as their strapline rather than as a
   trail (Billing Overview's read "Manage your subscription, invoices and payment methods"). It is
   the same element by a different name, so it gets the same rule instead of escaping the band. */
.page-header .subtitle,
.page-header .page-subtitle,
.page-header .breadcrumb {
    margin: 0;
    flex: 1 1 auto;
    min-width: 0;
    font-size: var(--qm-text-sm);
    line-height: 1.4;
    color: var(--qm-text-muted);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

@media (max-width: 576px) {
    .page-header {
        margin-bottom: 10px;
        padding-bottom: 8px;
    }

    /* Size comes from .qm-main h1's own phone rule — one home, on the phone too. */
    .page-header h1 {
        gap: 8px;
    }

    .page-header h1 i {
        font-size: var(--qm-text-lg);
    }

    /* On a phone there is no room for both on one line, and no room to stack them either. The
       QInfo beside the title carries the sentence, so the band is the title alone. */
    .page-header .subtitle,
    .page-header .page-subtitle,
    .page-header .breadcrumb {
        display: none;
    }
}

/* Content Cards */
.content-card {
    background: var(--qm-bg-card);
    border: 1px solid var(--qm-border);
    border-radius: var(--qm-radius-lg);
    padding: 24px;
    margin-bottom: 20px;
}

@media (max-width: 576px) {
    .content-card {
        padding: 16px;
        border-radius: var(--qm-radius-lg);
        margin-bottom: 12px;
    }
}

/* Form Groups - Mobile Optimized */
/* Spacing comes from layout.css's --qm-field-gap. This file loads after layout.css, so the
   20px that used to sit here beat the token and made it inert — the same shape of bug as
   qm-theme.css's .page-header h1 beating .qm-main h1. Label and control styling below stays. */

.form-group label {
    display: block;
    font-size: var(--qm-text-base);
    font-weight: 600;
    color: var(--qm-text-muted);
    margin-bottom: 8px;
    text-transform: uppercase;
    letter-spacing: 0.5px;
}

.form-group .form-control,
.form-group .form-select {
    width: 100%;
    padding: 12px 16px;
    background: var(--qm-bg-elevated);
    border: 1px solid var(--qm-border);
    border-radius: var(--qm-radius-md);
    color: var(--qm-text-primary);
    font-size: var(--qm-text-md);
    transition: all 0.2s ease;
}

.form-group .form-control:focus,
.form-group .form-select:focus {
    border-color: var(--qm-primary);
    box-shadow: 0 0 0 3px rgba(var(--qm-primary-rgb), 0.15);
    outline: none;
}

@media (max-width: 576px) {
    .form-group {
        margin-bottom: 16px;
    }

    .form-group .form-control,
    .form-group .form-select {
        padding: 14px 16px;
        font-size: 16px; /* NOT a scale token: Safari zooms the page when a focused input is under 16px. Prevents iOS zoom on focus */
        border-radius: var(--qm-radius-md);
    }
}

/* Buttons - Mobile Touch Friendly */
.btn-primary,
.btn-secondary {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    padding: 12px 24px;
    border-radius: var(--qm-radius-md);
    font-size: var(--qm-text-base);
    font-weight: 600;
    cursor: pointer;
    transition: all 0.2s ease;
    border: none;
    min-height: 44px; /* Touch target */
}

.btn-primary {
    background: var(--qm-gradient-primary);
    color: var(--qm-text-on-primary);
}

.btn-primary:hover {
    transform: translateY(-1px);
    box-shadow: 0 4px 20px rgba(var(--qm-primary-rgb), 0.4);
}

.btn-secondary {
    background: var(--qm-bg-elevated);
    border: 1px solid var(--qm-border);
    color: var(--qm-text-primary);
}

.btn-secondary:hover {
    background: var(--qm-bg-card-hover);
    border-color: var(--qm-primary);
}

@media (max-width: 576px) {
    .btn-primary,
    .btn-secondary {
        padding: 14px 20px;
        font-size: var(--qm-text-md);
        border-radius: var(--qm-radius-md);
        min-height: 48px;
    }

    /* Full width buttons on mobile when in button group */
    .btn-group-mobile .btn-primary,
    .btn-group-mobile .btn-secondary {
        width: 100%;
    }
}

/* Data Tables - Mobile Responsive */
.data-table {
    width: 100%;
    border-collapse: collapse;
}

/* A row is a line of data, not a card: 9px, not 14px (2026-09-19, the compaction pass). */
.data-table th,
.data-table td {
    padding: 9px 12px;
    text-align: left;
    vertical-align: middle;
    border-bottom: 1px solid var(--qm-border);
}

.data-table tbody tr:last-child td { border-bottom: 0; }

/* Two cell kinds every table has, defined once. A figure lines up on its right edge with
   tabular digits so a column can be read down; a row's buttons sit at its right end. */
.data-table .num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.data-table .row-actions { text-align: right; white-space: nowrap; width: 1%; }
.data-table .row-muted td { color: var(--qm-text-muted); }
.data-table .cell-sub { display: block; margin-top: 2px; font-size: var(--qm-text-xs); color: var(--qm-text-muted); }
.data-table .cell-tags { display: inline-flex; flex-wrap: wrap; gap: 4px; }

.data-table th {
    font-size: var(--qm-text-sm);
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    color: var(--qm-text-muted);
}

@media (max-width: 768px) {
    .data-table-responsive {
        display: block;
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
    }

    .data-table th,
    .data-table td {
        padding: 8px 10px;
        font-size: var(--qm-text-base);
    }
}

/* Card Grids - Responsive */
.card-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
    gap: 20px;
}

@media (max-width: 768px) {
    .card-grid {
        grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
        gap: 16px;
    }
}

@media (max-width: 576px) {
    .card-grid {
        grid-template-columns: 1fr;
        gap: 12px;
    }
}

/* Stats Grid - Responsive */
.stats-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
    gap: 20px;
}

@media (max-width: 576px) {
    .stats-grid {
        grid-template-columns: repeat(2, 1fr);
        gap: 12px;
    }

    .stats-grid .stat-card {
        padding: var(--qm-statcard-pad);
    }

    .stats-grid .stat-value {
        font-size: var(--qm-statcard-value);
    }

    .stats-grid .stat-label {
        font-size: var(--qm-statcard-label);
    }
}

/* Empty states — the older class. The same sizes as QEmptyState (q-components.css), read from the
   same --qm-empty-* tokens, so the two families cannot drift apart again. */
.empty-state {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    gap: 4px;
    padding: var(--qm-empty-pad);
    background: var(--qm-bg-card);
    border: 1px solid var(--qm-border);
    border-radius: var(--qm-radius-lg);
    color: var(--qm-text-muted);
}

.q-card .empty-state { border: 0; background: transparent; padding: 12px 8px; }

/* THE ICON SITS BESIDE THE HEADING, NOT ABOVE IT. Stacked, an empty state was four rows tall — icon,
   title, sentence, button — and a sentence that wrapped made it taller still (157–178px measured).
   Beside, the icon spans the title and the sentence, so the whole thing is the height of its text.
   A grid rather than a flex row because the button, when there is one, spans the full width below. */
.empty-state {
    display: grid;
    grid-template-columns: auto minmax(0, max-content);
    justify-content: center;
    align-items: center;
    column-gap: 12px;
    row-gap: 2px;
    text-align: left;
}

.empty-state > i:not(.q-btn__icon),
.empty-state > .rzi,
.empty-state > .q-icon,
.empty-state > .empty-state-icon {
    grid-row: span 2;
    align-self: center;
    margin: 0;
}

.empty-state > h3,
.empty-state > h4,
.empty-state > p {
    grid-column: 2;
}

/* Anything else in the block — a button, a link row — sits to the right on the same row, as in
   QEmptyState; on a phone it goes underneath. */
.empty-state > :not(i):not(.rzi):not(.q-icon):not(.empty-state-icon):not(h3):not(h4):not(p) {
    grid-column: 3;
    grid-row: 1 / span 2;
    margin: 0 0 0 8px;
}

@media (max-width: 576px) {
    .empty-state > :not(i):not(.rzi):not(.q-icon):not(.empty-state-icon):not(h3):not(h4):not(p) {
        grid-column: 1 / -1; grid-row: auto; justify-self: center; margin: 6px 0 0;
    }
}


/* :not(.q-btn__icon) — this is meant for the decorative icon an empty state shows on its own.
   Unscoped it also matched a QButton's internal icon inside the block and blew the button up. */
.empty-state i:not(.q-btn__icon),
.empty-state .rzi,
.empty-state > .q-icon,
.empty-state-icon {
    font-size: var(--qm-empty-icon);
    line-height: 1;
    color: var(--qm-text-muted);
    opacity: 0.5;
    margin: 0 0 2px;
}

.empty-state h3,
.empty-state h4 {
    margin: 0;
    font-size: var(--qm-text-md);
    color: var(--qm-text-primary);
}

.empty-state p {
    margin: 0;
    font-size: var(--qm-text-sm);
    color: var(--qm-text-muted);
}


/* Action Bars - Mobile Sticky */
.action-bar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 16px 0;
    margin-bottom: 20px;
}

@media (max-width: 576px) {
    .action-bar {
        flex-direction: column;
        gap: 12px;
    }

    .action-bar > * {
        width: 100%;
    }

    /* Sticky action bar at bottom for mobile */
    .action-bar-sticky {
        position: fixed;
        bottom: 0;
        left: 0;
        right: 0;
        background: var(--qm-bg-card);
        border-top: 1px solid var(--qm-border);
        padding: 12px 16px;
        padding-bottom: max(12px, env(safe-area-inset-bottom));
        z-index: 100;
        margin: 0;
    }
}

/* Tabs: every tab strip is QTabs (q-components.css). The last hand-built one, UsersSetup's
   .tabs-container, moved onto it on 2026-09-17 and its rules were removed here. */

/* Search Input - Mobile Optimized */
.search-input-group {
    position: relative;
    max-width: 400px;
}

.search-input-group input {
    width: 100%;
    padding: 12px 16px 12px 44px;
    background: var(--qm-bg-elevated);
    border: 1px solid var(--qm-border);
    border-radius: var(--qm-radius-md);
    color: var(--qm-text-primary);
    font-size: var(--qm-text-base);
}

.search-input-group i {
    position: absolute;
    left: 16px;
    top: 50%;
    transform: translateY(-50%);
    color: var(--qm-text-muted);
}

@media (max-width: 576px) {
    .search-input-group {
        max-width: 100%;
    }

    .search-input-group input {
        padding: 14px 16px 14px 44px;
        font-size: 16px; /* NOT a scale token: Safari zooms the page when a focused input is under 16px. Prevents iOS zoom */
        border-radius: var(--qm-radius-md);
    }
}

/* Floating Action Button (FAB) */
.fab {
    position: fixed;
    bottom: 24px;
    right: 24px;
    width: 56px;
    height: 56px;
    border-radius: 50%;
    background: var(--qm-gradient-primary);
    color: var(--qm-text-on-primary);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: var(--qm-text-stat);
    border: none;
    cursor: pointer;
    box-shadow: 0 4px 20px rgba(var(--qm-primary-rgb), 0.4);
    transition: all 0.2s ease;
    z-index: 100;
}

.fab:hover {
    transform: scale(1.1);
    box-shadow: 0 6px 30px rgba(var(--qm-primary-rgb), 0.5);
}

@media (max-width: 576px) {
    .fab {
        bottom: max(24px, calc(env(safe-area-inset-bottom) + 16px));
        right: 16px;
    }
}

/* Pull to Refresh Indicator */
.pull-refresh-indicator {
    display: none;
    justify-content: center;
    padding: 16px;
    color: var(--qm-text-muted);
}

@media (max-width: 768px) {
    .pull-refresh-indicator.visible {
        display: flex;
    }
}

/* Skeleton Loading - Mobile */
.skeleton {
    background: linear-gradient(90deg,
        var(--qm-bg-elevated) 25%,
        var(--qm-bg-card) 50%,
        var(--qm-bg-elevated) 75%);
    background-size: 200% 100%;
    animation: skeleton-loading 1.5s infinite;
    border-radius: var(--qm-radius-md);
}

@keyframes skeleton-loading {
    0% { background-position: 200% 0; }
    100% { background-position: -200% 0; }
}

/* Bottom Sheet (Mobile Only) */
@media (max-width: 576px) {
    .bottom-sheet {
        position: fixed;
        bottom: 0;
        left: 0;
        right: 0;
        background: var(--qm-bg-card);
        border-top: 1px solid var(--qm-border);
        border-radius: var(--qm-radius-lg) var(--qm-radius-lg) 0 0;
        padding: 20px;
        padding-bottom: max(20px, env(safe-area-inset-bottom));
        z-index: 1000;
        transform: translateY(100%);
        transition: transform 0.3s ease;
    }

    .bottom-sheet.open {
        transform: translateY(0);
    }

    .bottom-sheet-handle {
        width: 40px;
        height: 4px;
        background: var(--qm-border);
        border-radius: var(--qm-radius-full);
        margin: 0 auto 16px;
    }
}

/* Blazor Server's built-in circuit-failure banner. Framework JS toggles this
   element's visibility directly by id ("blazor-error-ui") whenever the current
   circuit hits an unhandled exception or the connection can't be recovered —
   without it present in the DOM, a dropped circuit fails completely silently
   (buttons stop responding, no feedback at all). */
#blazor-error-ui {
    background: var(--qm-warning);
    color: var(--qm-text-on-primary);
    bottom: 0;
    box-shadow: 0 -2px 8px rgba(0, 0, 0, 0.25);
    display: none;
    left: 0;
    padding: 0.9rem 3.5rem 0.9rem 1.25rem;
    position: fixed;
    width: 100%;
    z-index: 10000;
    font-size: var(--qm-text-base);
}

#blazor-error-ui .reload {
    color: var(--qm-text-on-primary);
    text-decoration: underline;
    font-weight: 600;
    margin-left: 12px;
}

#blazor-error-ui .dismiss {
    cursor: pointer;
    position: absolute;
    right: 1rem;
    top: 0.75rem;
}

/* Themed replacement for Bootstrap's .text-muted (which is fixed gray #6c757d and ignores
   --qm-* in both themes). Use this on any inline helper text instead of text-muted. */
.qm-text-muted {
    color: var(--qm-text-muted);
}
