﻿/* Carrefour brand identity — blue primary, red secondary. */
:root {
    --queens-primary: #004E9F;   /* Carrefour blue */
    --queens-secondary: #E2001A; /* Carrefour red */
    /* Clean, professional type: Inter (Latin + numerals), Cairo (Arabic), Segoe UI offline fallback. */
    --qs-font: 'Inter', 'Cairo', 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
    /* Text contrast tokens — the ONLY grays report copy should use. Inline styles across pages
       reference these so the whole app can be re-tuned here. All ≥ WCAG AA on white:
       text-1 body/headings, text-2 labels/captions, text-3 de-emphasized helper text. */
    --qs-text-1: #16202e;
    /* "No faint" rule: all three text tokens collapse to the darkest — zero color hierarchy,
       so every label/caption/helper reads at full contrast. */
    --qs-text-2: #16202e;
    --qs-text-3: #16202e;
    /* Design-system v2 tokens: ONE hero gradient (ReportHero / Dashboard / assistant header all
       consume this — never re-declare it), surface scale, radius scale, phone bottom-nav height. */
    --qs-hero-grad: linear-gradient(120deg, #06234a 0%, #0a3a6b 50%, #0c5b66 100%);
    --qs-canvas: #f3f5f9;
    --qs-surface: #ffffff;
    --qs-radius-s: 8px;
    --qs-radius-m: 12px;
    --qs-radius-l: 16px;
    --qs-bottomnav-h: 62px;
}

html, body {
    font-family: var(--qs-font);
    color: var(--qs-text-1);
    font-weight: 600;
    text-rendering: optimizeLegibility;
    /* No -webkit-font-smoothing:antialiased / grayscale here: on low-DPI Windows screens it thins
       Inter's strokes and reads as "faint". Subpixel default keeps text solid. */
}

/* Apply the family to MudBlazor's root too (it sets its own font-family via the theme). */
.mud-typography, .mud-input, .mud-button-root, .mud-table, body .mud-application {
    font-family: var(--qs-font);
    font-weight: 600;
}

/* Tabular figures so numbers line up in columns — a cleaner, more professional data read. */
.mud-table, .mud-table td, .mud-table th,
.qs-kpi-value, .qs-kpi-sub, .qs-kpi-label {
    font-variant-numeric: tabular-nums;
    font-feature-settings: "tnum" 1;
}

/* Financial figures: real tabular numerals so columns of numbers line up perfectly. */
.mud-table-root td, .mud-table-root th,
.qs-kpi-value, .qs-ledger-tbl td, .qs-ledger-tbl th,
td[style*="text-align:right"], .mud-table-cell {
    font-variant-numeric: tabular-nums;
    font-feature-settings: 'tnum' 1, 'lnum' 1;
}

/* ============================================================================
   Executive report styling — applies to every MudTable + report KPI card.
   Conditional inline row colors (e.g. verification/bank-rec) still win over the
   zebra below because inline styles out-rank these class rules.
   ============================================================================ */

/* Table header: quiet, uppercase, tinted */
.mud-table-root thead th {
    background: #f6f7f9;
    color: var(--qs-text-2);
    font-weight: 700 !important;
    font-size: .76rem !important;
    text-transform: uppercase;
    letter-spacing: .04em;
    border-bottom: 2px solid #e7e9ee !important;
}

/* Zebra striping + row hover */
.mud-table-root tbody tr:nth-of-type(even) { background: #fafbfd; }
.mud-table-root tbody tr:hover { background: #eef3ff; }

/* Tabular figures so columns line up */
.mud-table-root td, .mud-table-root th { font-variant-numeric: tabular-nums; }

/* TOTAL / footer row emphasis */
.mud-table-root tfoot td {
    border-top: 2px solid #dfe3ea !important;
    background: #f6f7f9;
    font-weight: 700;
}

/* ---- KPI cards ---- */
.qs-kpi {
    border-radius: 14px !important;
    border-left: 3px solid var(--kpi-accent, var(--queens-primary));
    box-shadow: 0 1px 2px rgba(20,30,60,.04), 0 8px 20px rgba(20,30,60,.05);
    transition: box-shadow .2s ease, transform .2s ease, border-color .2s ease;
}
.qs-kpi:hover {
    box-shadow: 0 2px 4px rgba(20,30,60,.05), 0 14px 32px rgba(33,37,64,.11);
    transform: translateY(-2px);
}
.qs-kpi .qs-kpi-label {
    font-size: .74rem; text-transform: uppercase; letter-spacing: .05em;
    color: var(--qs-text-2); font-weight: 700;
}
.qs-kpi .qs-kpi-value {
    font-size: 1.6rem; font-weight: 750; line-height: 1.12; letter-spacing: -.015em;
    font-variant-numeric: tabular-nums; color: var(--qs-text-1);
}
.qs-kpi .qs-kpi-sub { font-size: .78rem; color: var(--qs-text-3); font-weight: 500; }

/* ---- Share / proportion bar inside a table cell ---- */
.qs-bar {
    height: 6px; width: 72px; border-radius: 4px; background: #edeff3;
    display: inline-block; vertical-align: middle; overflow: hidden; margin-left: 8px;
}
.qs-bar > i { display: block; height: 100%; border-radius: 4px; background: linear-gradient(90deg, var(--queens-primary), #4d90d9); }

/* ---- RAG health pills ---- */
.qs-rag {
    display: flex; align-items: center; gap: 10px; min-width: 210px; flex: 1 1 210px;
    padding: 8px 12px; border: 1px solid #e7e9ee; border-left-width: 4px; border-radius: 8px; background: #fff;
}
.qs-rag-dot { width: 10px; height: 10px; border-radius: 50%; flex: 0 0 auto; }

/* ============================================================================
   Modern sidebar navigation (.qs-nav) — rounded hover pills, brand active state,
   quiet uppercase group headers. Scoped to the nav so it won't touch other menus.
   ============================================================================ */
.qs-nav { padding: 10px 10px 24px; }

/* Links & group headers — rounded, roomy, smooth */
.qs-nav .mud-nav-link {
    border-radius: 10px;
    margin: 2px 6px;
    padding-top: 9px;
    padding-bottom: 9px;
    font-size: .9rem;
    color: var(--qs-text-1);
    font-weight: 600;
    transition: background .15s ease, color .15s ease, box-shadow .15s ease;
}
.qs-nav .mud-nav-link:hover { background: #e8f1fb; color: var(--queens-primary); }

.qs-nav .mud-nav-link .mud-nav-link-icon {
    color: var(--qs-text-1);
    min-width: 34px;
    transition: color .15s ease;
}
.qs-nav .mud-nav-link:hover .mud-nav-link-icon { color: var(--queens-primary); }

/* Active item — brand pill with an inset accent bar */
.qs-nav .mud-nav-link.active,
.qs-nav .mud-nav-link.mud-nav-link-active {
    background: linear-gradient(90deg, rgba(0, 78, 159, .12), rgba(0, 78, 159, .03));
    color: var(--queens-primary);
    font-weight: 600;
    box-shadow: inset 3px 0 0 var(--queens-primary);
}
.qs-nav .mud-nav-link.active .mud-nav-link-icon,
.qs-nav .mud-nav-link.mud-nav-link-active .mud-nav-link-icon { color: var(--queens-primary); }

/* Group header (GL / Inventory / Purchase / …) — quiet, uppercase section label */
.qs-nav .mud-nav-group { margin-top: 10px; }
.qs-nav .mud-nav-group > .mud-nav-link {
    text-transform: uppercase;
    letter-spacing: .07em;
    font-size: .76rem;
    font-weight: 700;
    color: var(--qs-text-2);
}
.qs-nav .mud-nav-group > .mud-nav-link:hover { background: transparent; color: var(--queens-primary); }
.qs-nav .mud-nav-group > .mud-nav-link .mud-nav-link-icon { color: var(--qs-text-1); }

/* Slightly indent the items inside a group so the hierarchy reads */
.qs-nav .mud-collapse-container .mud-nav-link { padding-left: 18px; }

/* ============================================================================
   Menu bar (.qs-menubar) — the primary navigation gets its own light row that
   sticks directly under the app bar, so the app bar holds only brand + account
   controls. Buttons must read DARK here (they default to white for the app bar).
   ============================================================================ */
.qs-menubar {
    position: sticky;
    top: var(--mud-appbar-height, 64px);
    z-index: 20;
    display: flex;
    align-items: stretch;
    background: var(--qs-surface);
    border-bottom: 1px solid var(--qs-border);
    /* extra end padding so the last item's notification badge never clips */
    padding: 0 20px 0 8px;
    min-height: 44px;
    overflow-x: auto;
    overflow-y: hidden;
    /* Scrolled content must not bleed through the sticky strip's rounded page cards. */
    backdrop-filter: saturate(180%) blur(6px);
}
.qs-menubar::-webkit-scrollbar { height: 0; }
/* One clean strip: items spread evenly across the full width, never wrapping. */
.qs-menubar .qs-topnav {
    width: 100%;
    gap: 2px;
    justify-content: space-evenly;
    align-items: center;
    flex-wrap: nowrap;
}
.qs-menubar .qs-topnav .mud-button-root {
    color: var(--qs-text-1);
    font-weight: 600;
    font-size: .85rem;
    border-radius: var(--qs-radius-s);
    padding: 6px 12px;
    min-height: 34px;
    white-space: nowrap;
}
/* The strip is navigation, not a toolbar: no hover lift, no shadow. */
.qs-menubar .mud-button-root:hover { box-shadow: none; transform: none; }
.qs-menubar .qs-topnav .mud-button-root .mud-icon-root { color: var(--qs-text-2); }
.qs-menubar .qs-topnav .mud-button-root:hover { background: #eef2f8; color: var(--queens-primary); }
.qs-menubar .qs-topnav .mud-button-root:hover .mud-icon-root { color: var(--queens-primary); }

/* ============================================================================
   App bar (.qs-appbar) — identity on the left, account controls on the right.
   Navigation lives in .qs-menubar below it, so nothing here may wrap or clip.
   ============================================================================ */
.qs-appbar .mud-toolbar { gap: 2px; }
.qs-appbar .mud-button-root,
.qs-appbar .mud-typography { white-space: nowrap; }
.qs-appbar .mud-button-root:hover { background: rgba(255, 255, 255, .14); box-shadow: none; transform: none; }

/* Identity: name in white, role as a quiet outlined pill (was a filled red chip that read as an alert). */
.qs-user-text {
    display: inline-flex; align-items: center; gap: 8px;
    margin-inline-end: 10px; white-space: nowrap;
}
.qs-user-name { font-size: .86rem; font-weight: 600; color: #fff; }
.qs-user-role {
    font-size: .68rem; font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
    color: #dbe7f7; border: 1px solid rgba(255, 255, 255, .40); border-radius: 999px;
    padding: 2px 8px; line-height: 1.5;
}

/* Below ~1280px the account controls are what runs out of room first: drop the
   sign-out label (icon stays) before anything is allowed to clip or wrap. */
@media (max-width: 1279.98px) {
    .qs-signout-text { display: none; }
}

/* ============================================================================
   Top-bar navigation (.qs-topnav) — horizontal dropdown menus, rendered in the
   .qs-menubar strip on desktop and stacked inside the drawer on phones.
   ============================================================================ */
.qs-topnav-wrap { overflow-x: auto; overflow-y: hidden; }
.qs-topnav-wrap::-webkit-scrollbar { height: 0; }            /* hide the strip's scrollbar */
.qs-topnav { gap: 2px; flex-wrap: nowrap; }
.qs-topnav .mud-button-root {
    text-transform: none;            /* readable labels, not SHOUTING CAPS */
    font-weight: 600;
    white-space: nowrap;
    letter-spacing: .01em;
    border-radius: 8px;
    padding: 4px 10px;
}
.qs-topnav .mud-button-root:hover { background: rgba(255, 255, 255, .14); }
/* tighten the dropdown caret so it hugs the label */
.qs-topnav .mud-button-root .mud-button-icon-end { margin-left: -2px; }

/* ============================================================================
   Module rail (.qs-module-rail) — thin fixed strip on the far left holding the
   POS / GLS switch. The app bar and main content are pushed right by its width.
   ============================================================================ */
:root { --qs-rail-w: 68px; }

.qs-module-rail {
    position: fixed;
    top: 0; left: 0; bottom: 0;
    width: var(--qs-rail-w);
    z-index: 1301;                                   /* above the app bar (1300) */
    background: var(--queens-primary, #004e9f);
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: 6px;
    padding: 10px 8px;
    box-shadow: 2px 0 6px rgba(0, 0, 0, .18);
}

.qs-module-btn {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 2px;
    padding: 9px 2px;
    border: 0;
    border-radius: 10px;
    background: transparent;
    color: rgba(255, 255, 255, .72);
    font: 700 .68rem/1 inherit;
    letter-spacing: .04em;
    cursor: pointer;
    transition: background .15s ease, color .15s ease;
}
.qs-module-btn .mud-icon-root { font-size: 1.35rem; }
.qs-module-btn:hover { background: rgba(255, 255, 255, .12); color: #fff; }
.qs-module-btn--active {
    background: #fff;
    color: var(--queens-primary, #004e9f);
    box-shadow: 0 1px 4px rgba(0, 0, 0, .25);
}
.qs-module-btn--active:hover { background: #fff; color: var(--queens-primary, #004e9f); }

/* Module labels longer than POS/GLS (e.g. "Support") would spill past the 68px rail. The
   span never exceeds the button, and --wide relaxes the size/tracking so a real word fits
   instead of being clipped. Add --wide to any future module whose label runs long. */
.qs-module-btn > span {
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.qs-module-btn--wide { font-size: .60rem; letter-spacing: .01em; }

/* Offset the app bar and content so the rail never overlaps them */
.qs-appbar-railed { left: var(--qs-rail-w) !important; width: calc(100% - var(--qs-rail-w)) !important; }
.qs-content-railed { margin-left: var(--qs-rail-w); }

/* Report directory cards (/gls/reports) — lift + accent border on hover */
.qs-report-card { transition: box-shadow .15s ease, transform .15s ease; border: 1px solid transparent; }
.qs-report-card:hover {
    box-shadow: 0 4px 14px rgba(0, 78, 159, .16) !important;
    transform: translateY(-2px);
    border-color: rgba(0, 78, 159, .25);
}

/* ---- AI insights markdown spacing ---- */
.report-insights-md h1, .report-insights-md h2, .report-insights-md h3 { font-size: 1.02rem; margin: .5rem 0 .2rem; font-weight: 700; }
.report-insights-md ul, .report-insights-md ol { margin: .2rem 0 .6rem 1.15rem; }
.report-insights-md p { margin: .3rem 0; }
.report-insights-md li { margin: .12rem 0; }

/* ============================================================================
   Mobile / responsive shell (≤ md, 960px). The 68px module rail and the
   in-app-bar menu strip don't fit a phone, so below 960px we hide the rail,
   drop the content offset, and move navigation into a temporary drawer opened
   by the hamburger in the app bar (see MainLayout.razor + TopNavMenu).
   ============================================================================ */
.qs-appbar-burger { margin-right: 2px; }

/* Drawer body: module switch row on top, vertical full-width menu below. */
.qs-mobile-drawer .mud-drawer-content { padding: 12px 10px; }
.qs-mobile-mods { display: flex; gap: 10px; margin-bottom: 4px; }
.qs-mobile-mods .qs-module-btn { flex: 1 1 0; color: var(--qs-text-1); background: #f1f4f9; }
.qs-mobile-mods .qs-module-btn--active { background: var(--queens-primary); color: #fff; }

/* The horizontal top-bar menu, re-laid-out vertically inside the drawer. */
.qs-mobile-drawer .qs-topnav { flex-direction: column; align-items: stretch; gap: 2px; }
.qs-mobile-drawer .qs-topnav .mud-button-root {
    width: 100%; justify-content: flex-start; color: var(--qs-text-1); white-space: normal;
}
.qs-mobile-drawer .qs-topnav .mud-button-root:hover { background: #e8f1fb; }

@media (max-width: 959.98px) {
    .qs-module-rail { display: none; }
    .qs-appbar-railed { left: 0 !important; width: 100% !important; }
    .qs-content-railed { margin-left: 0; }
    html[dir="rtl"] .qs-appbar-railed { right: 0 !important; }
    html[dir="rtl"] .qs-content-railed { margin-right: 0; }
    /* RAG health pills stack full-width instead of forcing 210px overflow. */
    .qs-rag { min-width: 0; flex-basis: 100%; }
}

@media (max-width: 599.98px) {
    .qs-assistant-cta { display: none; }   /* AI still reachable via the bottom nav + FAB + drawer */
    .qs-user-text { display: none; }
    .qs-brand-text { display: none; }       /* logo alone — frees width for the burger + actions */
    .qs-signout-text { display: none; }     /* sign-out becomes icon-only so the app bar never overflows */

    /* Phone bottom navigation is fixed — reserve space so page content never hides behind it,
       and lift the AI FAB above it. Safe-area inset keeps it clear of iPhone home indicators. */
    .mud-main-content { padding-bottom: calc(var(--qs-bottomnav-h) + env(safe-area-inset-bottom, 0px) + 8px); }
    /* The floating assistant button is redundant on phones — the bottom nav already has
       "Ask AI" — and it covered figures in card lists, so it is hidden at this width. */
    .qs-ga-fab { display: none !important; }

    /* Touch-friendlier table rows on phones (desktop stays dense). */
    .mud-table-root tbody td, .mud-table-root thead th { padding-top: 9px; padding-bottom: 9px; }
}

/* ── Phone bottom navigation (.qs-bottomnav) — Home / Reports / Ask AI / Menu.
      Direction-agnostic flex (RTL mirrors automatically); hidden in print and above 600px. ── */
.qs-bottomnav {
    position: fixed; bottom: 0; left: 0; right: 0;
    height: calc(var(--qs-bottomnav-h) + env(safe-area-inset-bottom, 0px));
    padding-bottom: env(safe-area-inset-bottom, 0px);
    display: flex; align-items: stretch; justify-content: space-around;
    background: var(--qs-surface);
    border-top: 1px solid #e3e8f0;
    box-shadow: 0 -4px 16px rgba(20, 30, 60, .08);
    z-index: 1350;                                   /* above content + appbar, below dialogs */
}
.qs-bottomnav-btn {
    flex: 1 1 0; border: 0; background: transparent; cursor: pointer;
    display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px;
    color: var(--qs-text-2); font: 600 .68rem/1.1 var(--qs-font);
    -webkit-tap-highlight-color: transparent;
    transition: color .15s ease;
}
.qs-bottomnav-btn .mud-icon-root { font-size: 1.45rem; }
.qs-bottomnav-btn--active { color: var(--queens-primary); }
.qs-bottomnav-btn--active .mud-icon-root { color: var(--queens-primary); }

/* ============================================================================
   GUI enhancement pass — a cohesive polish applied to EVERY report at once via
   the shared hooks (MudPaper cards, .mud-table-root, .qs-kpi, .qs-toolbar).
   Additive and conservative so it lifts the look without fighting existing rules.
   ============================================================================ */

/* --- Canvas: a soft tint so white report cards visibly lift off the page --- */
.mud-main-content { background: #f3f5f9; }

/* --- Report titles (Typo.h4 + inline icon) get a bit more presence --- */
.mud-main-content .mud-typography-h4 {
    display: inline-flex; align-items: center; gap: .45rem;
    font-weight: 700; letter-spacing: -.01em; color: var(--qs-text-1);
}
.mud-main-content .mud-typography-h4 .mud-icon-root { color: var(--queens-primary); }

/* --- Cards: crisp hairline border + softer layered shadow on the elevation-1
       papers that reports use for filter bars, KPI tiles, chart panels and
       result tables. Slightly more radius + a gentle hover lift so chart cards
       read as premium, tactile surfaces. --- */
.mud-main-content .mud-paper.mud-elevation-1 {
    border: 1px solid #e8edf3;
    border-radius: 14px;
    box-shadow:
        0 1px 2px rgba(20, 30, 60, .03),
        0 4px 10px rgba(20, 30, 60, .04),
        0 12px 28px rgba(20, 30, 60, .05) !important;
    transition: box-shadow .2s ease, transform .2s ease, border-color .2s ease;
}
/* Breathing room between cards: a wider gap under stacked cards, and extra vertical
   space between wrapped grid rows (KPI tiles, chart panels) — a calmer, less cramped read. */
.mud-main-content .mud-paper.mb-3 { margin-bottom: 22px !important; }
.mud-main-content .mud-paper.mb-4 { margin-bottom: 30px !important; }
.mud-main-content .mud-grid { row-gap: 8px; }
/* Hover lift for display cards (chart panels, result tables, KPI tiles).
   The filter/toolbar surface (.qs-toolbar) is excluded — it holds live controls
   the user reaches into, so it should stay put rather than lift on hover. */
.mud-main-content .mud-paper.mud-elevation-1:not(.qs-toolbar):hover {
    border-color: #dbe3ee;
    box-shadow:
        0 1px 2px rgba(20, 30, 60, .04),
        0 6px 14px rgba(20, 30, 60, .06),
        0 18px 40px rgba(20, 30, 60, .08) !important;
    transform: translateY(-2px);
}

/* --- Chart-card subtitle helper: quiet caption a card wrapper can place under
       its title (e.g. "Visits by weekday · last 90 days"). --- */
.qs-chart-subtitle {
    font-size: 12.5px;
    line-height: 1.35;
    color: var(--qs-text-2);
    font-weight: 500;
    letter-spacing: .01em;
    margin-top: 1px;
}

/* --- Captions & secondary text: readable, never faint. Scoped to light surfaces
       (main content + dialogs) so text on dark heroes/app bar keeps its own colors. --- */
.mud-main-content .mud-typography-caption,
.mud-dialog .mud-typography-caption {
    font-size: .8rem;
    color: var(--qs-text-1);
    font-weight: 600;
}
.mud-main-content .mud-typography-body2,
.mud-dialog .mud-typography-body2 {
    font-weight: 600;
    color: var(--qs-text-1);
}
/* Section headings sit above body — 700 for a clear, professional hierarchy. */
.mud-main-content .mud-typography-subtitle1,
.mud-main-content .mud-typography-subtitle2,
.mud-dialog .mud-typography-subtitle1,
.mud-dialog .mud-typography-subtitle2 {
    font-weight: 700;
    color: var(--qs-text-1);
}
.mud-main-content .mud-text-secondary,
.mud-main-content .mud-text-surface,
.mud-main-content .mud-text-tertiary,
.mud-dialog .mud-text-secondary,
.mud-dialog .mud-text-surface,
.mud-dialog .mud-text-tertiary {
    color: var(--qs-text-1) !important;
}

/* --- Shared filter / toolbar card — subtle vertical wash + rounded, so the
       controls read as one grouped surface. Opt in with class="qs-toolbar". --- */
.qs-toolbar {
    border: 1px solid #e5eaf1 !important;
    border-radius: 12px !important;
    background: linear-gradient(180deg, #ffffff, #f7f9fc) !important;
    box-shadow: 0 1px 2px rgba(20, 30, 60, .05) !important;
}

/* --- Tables: rounded clipped container, denser rows, crisper header & hover --- */
.mud-table-root { border-radius: 10px; }
.mud-table-root tbody tr { transition: background .12s ease; }
.mud-table-root tbody td, .mud-table-root thead th { padding-top: 6px; padding-bottom: 6px; }
.mud-table-root tbody tr:hover { background: #eaf1ff; }
.mud-table-root tfoot td { color: var(--qs-text-1); }

/* --- KPI tiles: faint gradient wash for a little depth (hover lift already set) --- */
.qs-kpi { background: linear-gradient(180deg, #ffffff, #fbfcfe); }

/* --- Account-type group header / subtotal rows on the classified Balance Sheet --- */
.qs-grp-hdr {
    background: #eef3fb !important; color: var(--queens-primary) !important;
    font-weight: 700 !important; text-transform: uppercase; letter-spacing: .04em;
    font-size: .72rem !important; border-top: 1px solid #d7e2f2 !important;
}
.qs-grp-ftr {
    background: #f7f9fc !important; font-weight: 700 !important; color: var(--qs-text-1) !important;
    border-bottom: 2px solid #e3e8f0 !important;
}

/* --- Item Movement (Comprehensive): dense rows, group-banded columns, and a Balance column frozen to the
       right edge (Item stays frozen left) so the closing value is always visible on the very wide table. --- */
.qs-imf td, .qs-imf th { padding: 2px 7px !important; font-size: .78rem; }
.qs-imf .qs-imf-gstart { border-left: 2px solid #e2e8f1 !important; }         /* boundary between column groups */
.qs-imf thead th.qs-imf-hodd { background: #eef4fc !important; }              /* alternate group banding in the header */
.qs-imf thead th.qs-imf-hbal { background: #e7f2e7 !important; color: #1b7e34 !important; }
.qs-imf .qs-imf-balq {
    position: sticky; right: 130px; z-index: 2; min-width: 100px; width: 100px;
    background: #eef7ee !important; font-weight: 600;
}
.qs-imf .qs-imf-balc {
    position: sticky; right: 0; z-index: 2; min-width: 130px; width: 130px;
    background: #eef7ee !important; font-weight: 700; box-shadow: -6px 0 8px -6px rgba(0,0,0,.18);
}
.qs-imf thead th.qs-imf-balq, .qs-imf thead th.qs-imf-balc { z-index: 5; }    /* header freeze above body */

/* --- Drill-down rows: signal that clicking opens the account statement --- */
.qs-drill { cursor: pointer; }
.qs-drill:hover td:nth-child(2) { text-decoration: underline; text-decoration-color: rgba(0,78,159,.4); }

/* --- Refined professional statement coloring: brand-blue column headers + totals,
       dark-slate body text. Codes/amounts keep their own inline colors (inline wins). --- */
.mud-main-content .mud-table-root thead th,
.qs-ledger-tbl thead th { color: var(--queens-primary); }
/* Dark-slate body text — the second selector out-specifies MudBlazor's own .mud-table-cell color
   so account names render clearly instead of the theme's faint default gray. */
.mud-main-content .mud-table-root tbody td,
.mud-main-content .mud-table-root tbody td.mud-table-cell { color: var(--qs-text-1); }
.mud-main-content .mud-table-root tfoot td { color: var(--queens-primary); }
/* Same table polish inside dialogs (they render outside .mud-main-content). */
.mud-dialog .mud-table-root thead th { color: var(--queens-primary); }
.mud-dialog .mud-table-root tbody td.mud-table-cell { color: var(--qs-text-1); }
.mud-dialog .mud-table-root td, .mud-dialog .mud-table-root th { font-variant-numeric: tabular-nums; }

/* --- Custom ledger tables (Stock Card etc.) share the zebra + hover polish --- */
.qs-ledger-tbl tbody tr:nth-of-type(even) td { background: #fafbfd; }
.qs-ledger-tbl tbody tr:hover td { background: #eaf1ff; }

/* --- Modern thin scrollbars throughout --- */
* { scrollbar-width: thin; scrollbar-color: #c6cdd8 transparent; }
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-thumb {
    background: #cdd4df; border-radius: 8px;
    border: 2px solid transparent; background-clip: padding-box;
}
::-webkit-scrollbar-thumb:hover { background: #b1bac8; }

/* --- Mobile: tighten page padding and let wide tables scroll horizontally --- */
@media (max-width: 959.98px) {
    .mud-main-content .pa-4 { padding: 12px !important; }
    .mud-table-container { overflow-x: auto; -webkit-overflow-scrolling: touch; }
}

/* --- Print: white canvas, drop the card chrome so ink goes to the data --- */
@media print {
    .mud-main-content { background: #fff; }
    .mud-main-content .mud-paper.mud-elevation-1,
    .mud-main-content .mud-paper.mud-elevation-1:hover {
        border: 1px solid #e8edf3;
        box-shadow: none !important;
        transform: none !important;
    }
    .qs-kpi, .qs-kpi:hover {
        box-shadow: none !important;
        transform: none !important;
    }
}

/* ===========================================================================
   Pseudo-3D chart treatment — scoped to the Customer Visits charts page.
   `.qs-charts-3d` wraps the chart grid. Pure CSS/SVG (no 3D library): layered
   SVG drop-shadow filters fake a side face + cast shadow so bars/slices/tiles
   read as extruded and raised, while the plot itself stays flat so axes and
   tooltips remain accurate. Combined with gradient fills (enabled on the page
   master) this gives a glossy 3D look.
   =========================================================================== */
.qs-charts-3d .apexcharts-bar-area,
.qs-charts-3d .apexcharts-rangebar-area {
    /* right sliver = side face; soft offset = cast shadow */
    filter: drop-shadow(2px 0 0 rgba(15, 23, 55, .20)) drop-shadow(3px 5px 3px rgba(15, 23, 55, .28));
}
.qs-charts-3d .apexcharts-pie-area,
.qs-charts-3d .apexcharts-donut-slice {
    filter: drop-shadow(2px 4px 4px rgba(15, 23, 55, .34));
}
.qs-charts-3d .apexcharts-treemap-rect {
    filter: drop-shadow(2px 2px 0 rgba(15, 23, 55, .16)) drop-shadow(2px 4px 3px rgba(15, 23, 55, .24));
}
.qs-charts-3d .apexcharts-heatmap-rect {
    filter: drop-shadow(1px 1px 0 rgba(15, 23, 55, .12)) drop-shadow(1px 2px 1px rgba(15, 23, 55, .16));
}
.qs-charts-3d .apexcharts-marker {
    filter: drop-shadow(1.5px 2px 1px rgba(15, 23, 55, .40));
}
.qs-charts-3d .apexcharts-line,
.qs-charts-3d .apexcharts-area {
    filter: drop-shadow(0 3px 3px rgba(15, 23, 55, .22));
}
/* The radar/polar web lifts a touch too. */
.qs-charts-3d .apexcharts-radar-series polygon,
.qs-charts-3d .apexcharts-pie path {
    filter: drop-shadow(1px 2px 2px rgba(15, 23, 55, .22));
}
@media print {
    .qs-charts-3d *, .qs-charts-3d *:hover { filter: none !important; }
}

/* ===========================================================================
   DESIGN SYSTEM v3 — cohesive professional polish, applied globally.
   Additive only: new tokens + app-wide rules that lift every page at once
   (accessibility, semantic color, elevation, motion) without fighting the
   mature per-section styling above.
   =========================================================================== */

:root {
    /* ---- Semantic color tokens (the ONLY colors report values should use for
            gain / loss / caution / neutral). Matches the greens/reds already
            hand-coded across ~120 pages so nothing shifts, but new code — and
            the utility classes below — now have one source of truth. ---- */
    --qs-pos: #1b7e34;   --qs-pos-bg: #e7f4ec;   /* positive / gain / in-stock */
    --qs-neg: #c0261c;   --qs-neg-bg: #fbeceb;   /* negative / loss / over-cost */
    --qs-warn: #b76e00;  --qs-warn-bg: #fdf3e3;  /* caution / watch */
    --qs-info: #0a5bd3;  --qs-info-bg: #e9f1fd;  /* informational / brand-tint */
    --qs-muted: var(--qs-text-3);

    /* ---- Elevation scale — soft, blue-tinted, consistent everywhere ---- */
    --qs-shadow-1: 0 1px 2px rgba(20,30,60,.05);
    --qs-shadow-2: 0 4px 14px rgba(20,30,60,.08);
    --qs-shadow-3: 0 12px 30px rgba(20,30,60,.10);

    /* ---- Focus ring — one accessible, brand-colored ring for the whole app ---- */
    --qs-ring: 0 0 0 3px rgba(0,78,159,.30);

    /* ---- Hairline border used by cards / dividers ---- */
    --qs-border: #e6ebf2;
}

/* Semantic value utilities — use in any table cell / KPI: class="qs-pos" etc. */
.qs-pos { color: var(--qs-pos) !important; }
.qs-neg { color: var(--qs-neg) !important; }
.qs-warn { color: var(--qs-warn) !important; }
.qs-info { color: var(--qs-info) !important; }
.qs-num  { font-variant-numeric: tabular-nums; font-feature-settings: 'tnum' 1, 'lnum' 1; }

/* Soft semantic pills — status chips that read clearly on white. */
.qs-pill { display:inline-flex; align-items:center; gap:5px; font-weight:700; font-size:.72rem;
    line-height:1; padding:4px 9px; border-radius:999px; letter-spacing:.01em; }
.qs-pill--pos  { color:var(--qs-pos);  background:var(--qs-pos-bg); }
.qs-pill--neg  { color:var(--qs-neg);  background:var(--qs-neg-bg); }
.qs-pill--warn { color:var(--qs-warn); background:var(--qs-warn-bg); }
.qs-pill--info { color:var(--qs-info); background:var(--qs-info-bg); }

/* ---------------------------------------------------------------------------
   Accessibility: a single, consistent keyboard focus ring. Only shows for
   keyboard users (:focus-visible), never on mouse click, so it's invisible to
   pointer users but makes the whole app keyboard-navigable — a professional
   baseline MudBlazor doesn't provide out of the box.
   --------------------------------------------------------------------------- */
:where(a, button, .mud-button-root, .mud-icon-button, .mud-nav-link,
       .qs-module-btn, .qs-bottomnav-btn, .qs-repdir-chip, .qs-report-card,
       .qs-rh-print, .qs-rh-ask, [tabindex]:not([tabindex="-1"])):focus-visible {
    outline: none;
    box-shadow: var(--qs-ring);
    border-radius: 8px;
    position: relative;
    z-index: 1;
}
/* On the dark app bar / rail, use a white ring so it stays visible on blue.
   (.qs-rh is no longer here: the report heading is light now, so it keeps the brand ring.) */
.mud-appbar :focus-visible,
.qs-module-rail :focus-visible {
    box-shadow: 0 0 0 3px rgba(255,255,255,.75);
}

/* Blazor's <FocusOnNavigate Selector="h1"> (Routes.razor) moves focus to the page heading on every
   navigation so screen readers announce it. Chrome then paints its default focus ring around the
   title — suppress it for that programmatic case; keyboard users still get the ring above on the
   controls they actually tab to. */
h1[tabindex="-1"]:focus { outline: none; }

/* Brand-tinted text selection instead of the browser default blue. */
::selection { background: rgba(0,78,159,.20); color: var(--qs-text-1); }

/* ---------------------------------------------------------------------------
   Cleaner buttons: MudBlazor ships SHOUTING-UPPERCASE labels by default. This
   app already opted out on the top nav; make it app-wide for a calmer, more
   professional read. Slightly firmer weight + the shared radius token.
   (Icon buttons and the print/report chrome keep their own styling.)
   --------------------------------------------------------------------------- */
.mud-button-root:not(.mud-icon-button) {
    text-transform: none;
    font-weight: 600;
    letter-spacing: .01em;
    border-radius: var(--qs-radius-s);
}
/* Filled primary/secondary buttons get a subtle, tactile hover lift. */
.mud-button-filled:not(:disabled):hover {
    box-shadow: var(--qs-shadow-2);
    transform: translateY(-1px);
}
.mud-button-filled { transition: box-shadow .18s ease, transform .18s ease, background-color .18s ease; }

/* ---------------------------------------------------------------------------
   Touch: on phones, guarantee comfortable 42px tap targets for buttons and
   icon buttons (Material's dense defaults are too small for a thumb).
   --------------------------------------------------------------------------- */
@media (max-width: 599.98px) {
    .mud-button-root:not(.mud-icon-button) { min-height: 42px; }
    .mud-icon-button { min-width: 42px; min-height: 42px; }
    /* Chips / small toggles stay tappable too. */
    .qs-repdir-chip { padding-top: 9px; padding-bottom: 9px; }

    /* Horizontal-scroll safety net for MudSimpleTable + classified statement tables.
       The existing ≤960px rule only wraps MudTable's .mud-table-container; MudSimpleTable
       (Balance Sheet, Trading account, statements) needs its own scroll affordance so a
       wide statement pans instead of blowing out the viewport width. */
    .mud-main-content .mud-simple-table,
    .mud-main-content .qs-ledger-tbl-wrap {
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
    }
}

/* ---------------------------------------------------------------------------
   Motion: honor the OS "reduce motion" setting — kill the count-up eases,
   hover lifts, and the live-dot pulse for users who ask for calm.
   --------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: .001ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: .001ms !important;
        scroll-behavior: auto !important;
    }
    .mud-paper.mud-elevation-1:hover, .qs-kpi:hover, .qs-report-card:hover,
    .mud-button-filled:hover, .qs-rh-ask:hover { transform: none !important; }
}

/* ===========================================================================
   DESIGN SYSTEM v4 — the "executive" pass, applied app-wide.
   Same language as the landing dashboard: white surfaces, hairline borders,
   one soft shadow, restrained color, data that never moves under the cursor.
   Everything here hangs off the hooks every report already uses
   (.mud-paper.mud-elevation-1, .mud-table-root, .qs-kpi, .qs-toolbar), so all
   ~120 report pages inherit it without touching a single page file.
   =========================================================================== */

/* ---- Surfaces: one card treatment, no hover lift on data ---------------- */
.mud-main-content .mud-paper.mud-elevation-1,
.mud-dialog .mud-paper.mud-elevation-1 {
    border: 1px solid var(--qs-border);
    border-radius: var(--qs-radius-m);
    box-shadow: var(--qs-shadow-1) !important;
}
/* Report/data cards stay put; only genuinely clickable cards keep their lift
   (.qs-report-card in the reports directory sets its own hover). */
.mud-main-content .mud-paper.mud-elevation-1:not(.qs-report-card):not(.qs-clickable):hover {
    border-color: #d7dfea;
    box-shadow: var(--qs-shadow-1) !important;
    transform: none;
}

/* ---- Page titles: one clear hierarchy on every report ------------------- */
.mud-main-content .mud-typography-h4 {
    font-size: 1.45rem;
    line-height: 1.25;
    letter-spacing: -.015em;
}
.mud-main-content .mud-typography-h5 { font-size: 1.15rem; font-weight: 700; letter-spacing: -.01em; }
.mud-main-content .mud-typography-h6 { font-size: 1rem; font-weight: 700; }

/* ---- Filter / toolbar bar ---------------------------------------------- */
.qs-toolbar {
    background: var(--qs-surface) !important;
    border: 1px solid var(--qs-border) !important;
    border-radius: var(--qs-radius-m) !important;
    box-shadow: none !important;
    /* Parameters are the smallest thing on the page. MudGrid's own gutters and MudBlazor's input
       margins were together costing well over 100px of a report's screen; they are collapsed here
       once, centrally, for every one of the ~109 pages that marks its filter surface .qs-toolbar. */
    padding: 8px 12px !important;
    margin-bottom: 10px !important;
}
.qs-toolbar > .mud-grid { margin: 0 !important; width: 100% !important; }
.qs-toolbar > .mud-grid > .mud-grid-item { padding: 3px 6px !important; }
.qs-toolbar .mud-input-control { margin-top: 0 !important; margin-bottom: 0 !important; }
.qs-toolbar .mud-form-control { margin: 0 !important; }
/* Helper text keeps its meaning ("Empty = all") without claiming a whole extra row per control. */
.qs-toolbar .mud-input-helper-text { font-size: .78rem; line-height: 1.15; margin-top: 1px; }
/* The action row sits flush; buttons do not need a paragraph of air above them. */
.qs-toolbar .mud-button-root { margin-top: 2px; }
/* Keep filter inputs a readable width instead of stretching a date across the whole screen;
   the grid still wraps them responsively. A date needs ~11 characters and a branch name ~30, so
   capping them stops a filter bar reading as four enormous empty troughs on a wide monitor. */
.qs-toolbar .mud-input-control { max-width: 340px; }
.qs-toolbar .mud-picker .mud-input-control { max-width: 190px; }
.qs-toolbar .mud-select .mud-input-control { max-width: 300px; }

/* Resting AI panel: one quiet row, so it never outranks the report's own figures. */
.qs-ri-rest { padding: 6px 10px !important; }
.qs-ri-rest .qs-ri-head { min-height: 32px; }

/* Chart skeleton — holds the chart's height while the charting library loads, so the card
   never renders as an empty white box with a caption under it. */
.qs-chart-skel { position: relative; overflow: hidden; border-radius: var(--qs-radius-s);
    background: linear-gradient(90deg, rgba(0,78,159,.05) 25%, rgba(0,78,159,.10) 37%, rgba(0,78,159,.05) 63%);
    background-size: 400% 100%; animation: qs-skel 1.4s ease-in-out infinite; }
@keyframes qs-skel { 0% { background-position: 100% 50%; } 100% { background-position: 0 50%; } }

/* Empty / "press Run" states: a quiet line, not a hero panel. A report that has not run yet
   should hand its space to the report, not to an icon explaining that it has not run yet. */
.mud-main-content .mud-paper.pa-8.text-center { padding: 18px !important; }
.mud-main-content .mud-paper.pa-8.text-center .mud-icon-root { font-size: 1.6rem !important; }

.qs-emptyline { display: flex; align-items: center; gap: 10px; padding: 10px 14px;
    background: var(--qs-surface); border: 1px solid var(--qs-border); border-radius: var(--qs-radius-m);
    font-size: .86rem; color: var(--qs-text-2); }
.qs-emptyline .mud-icon-root { color: var(--qs-text-3); }

/* Compact masthead for operational/admin screens (see Components/PageMasthead.razor).
   Same eyebrow + title as a report page, but inline so it can share a row with the page's
   action buttons. :has() gives that row the hairline the report pages get from .qs-rh. */
.qs-pm { min-width: 0; }
.qs-pm-eyebrow { font-size: .78rem; font-weight: 700; letter-spacing: .14em; text-transform: uppercase;
    color: var(--queens-primary); margin-bottom: 1px; }
.qs-pm-title { margin: 0; font-size: 1.25rem; font-weight: 700; letter-spacing: -.015em;
    line-height: 1.2; color: var(--qs-text-1); }
.mud-main-content .d-flex:has(> .qs-pm),
.mud-main-content .d-flex:has(> div > .qs-pm) {
    padding-bottom: 6px; margin-bottom: 10px !important;
    border-bottom: 1px solid var(--qs-border);
}

/* Breadcrumb trail. Sits where the brand eyebrow used to, so it costs no extra height, and
   reads at the same weight — it is navigation, not decoration, and must not be faint. */
.qs-bc { display: flex; align-items: center; flex-wrap: wrap; gap: 5px; margin-bottom: 2px;
    font-size: .78rem; font-weight: 700; letter-spacing: .02em; }
.qs-bc-link { color: var(--queens-primary); text-decoration: none; border-radius: 3px; }
.qs-bc-link:hover { text-decoration: underline; }
.qs-bc-sep { color: var(--qs-text-3); font-weight: 400; }
.qs-bc-cur { color: var(--qs-text-2); }
@media print { .qs-bc { display: none; } }

/* Format checkboxes on the report-delivery page: one per line, at their natural height.
   They sit in a narrow table cell, where an inline row collapses them on top of one another. */
.qs-fmt-list { display: flex; flex-direction: column; align-items: flex-start; }
.qs-fmt-list .mud-input-control { margin: 0 !important; }
.qs-fmt-list .mud-checkbox { margin: 0; }
.qs-fmt-list .mud-checkbox .mud-typography { font-size: .8rem; line-height: 1.4; }

/* ---- KPI cards ---------------------------------------------------------- */
.qs-kpi {
    background: var(--qs-surface);
    border: 1px solid var(--qs-border);
    border-left: 3px solid var(--kpi-accent, var(--queens-primary));
    border-radius: var(--qs-radius-m) !important;
    box-shadow: none;
}
.qs-kpi:hover { box-shadow: var(--qs-shadow-1); transform: none; }
.qs-kpi .qs-kpi-value { overflow-wrap: anywhere; }
.qs-kpi .qs-kpi-label { letter-spacing: .06em; }

/* ---- Tables: the workhorse surface -------------------------------------- */
.mud-main-content .mud-table-root thead th {
    background: #f6f8fc;
    border-bottom: 1px solid var(--qs-border) !important;
    font-size: .72rem !important;
    letter-spacing: .06em;
}
.mud-main-content .mud-table-root tbody tr:nth-of-type(even) { background: #fbfcfe; }
.mud-main-content .mud-table-root tbody tr:hover { background: #eef4ff; }
.mud-main-content .mud-table-root tbody td { border-bottom: 1px solid #f1f4f8; }
.mud-main-content .mud-table-root tfoot td {
    background: #f6f8fc;
    border-top: 1px solid var(--qs-border) !important;
}

/* Wide tables scroll inside their own box at EVERY width (not just on phones)
   with a shadow cue at the edge that fades out when you reach the end — so a
   40-column movement report pans instead of blowing out the page. */
.mud-main-content .mud-table-container,
.mud-main-content .qs-ledger-tbl-wrap {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    background:
        linear-gradient(to right, var(--qs-surface) 30%, rgba(255, 255, 255, 0)) 0 0 / 32px 100% no-repeat local,
        linear-gradient(to left, var(--qs-surface) 30%, rgba(255, 255, 255, 0)) 100% 0 / 32px 100% no-repeat local,
        radial-gradient(farthest-side at 0 50%, rgba(20, 30, 60, .14), rgba(20, 30, 60, 0)) 0 0 / 12px 100% no-repeat scroll,
        radial-gradient(farthest-side at 100% 50%, rgba(20, 30, 60, .14), rgba(20, 30, 60, 0)) 100% 0 / 12px 100% no-repeat scroll;
}

/* ---- Dialogs ------------------------------------------------------------ */
.mud-dialog { border-radius: var(--qs-radius-m); }
.mud-dialog-title { font-weight: 700; letter-spacing: -.01em; }

/* ---- Charts: quieter frame --------------------------------------------- */
.apexcharts-toolbar { opacity: .35; transition: opacity .15s ease; }
.mud-paper:hover .apexcharts-toolbar { opacity: 1; }

/* ===========================================================================
   RESPONSIVE / MOBILE-ADAPTIVE — no page may scroll sideways on a phone.
   =========================================================================== */

/* Safety net so no page can scroll sideways. `clip` — not `hidden` — because
   `hidden` turns the root into a scroll container and breaks position:sticky
   (the .qs-menubar strip and any sticky table column depend on it). */
html, body { overflow-x: clip; }
.mud-main-content, .mud-main-content .mud-container { max-width: 100%; }
.mud-main-content img, .mud-main-content svg:not(.apexcharts-svg) { max-width: 100%; }

@media (max-width: 959.98px) {
    /* Tablet: tighten the page frame so cards get the width instead of padding. */
    .mud-main-content .pa-4 { padding: 12px !important; }
    .mud-main-content .mud-paper.mb-4 { margin-bottom: 16px !important; }
    .mud-main-content .mud-paper.mb-3 { margin-bottom: 12px !important; }
}

@media (max-width: 599.98px) {
    /* Phone: denser type in tables, roomier tap targets (set above), smaller titles. */
    .mud-main-content .mud-typography-h4 { font-size: 1.15rem; }
    .mud-main-content .mud-table-root td,
    .mud-main-content .mud-table-root th { font-size: .78rem; padding-left: 8px; padding-right: 8px; }

    /* Big figures must never clip: shrink them and let them wrap. The inline
       font-size on ~98 report pages is why this needs !important. */
    .qs-kpi .qs-kpi-value { font-size: clamp(.95rem, 4.4vw, 1.15rem) !important; line-height: 1.2; }
    .qs-kpi .qs-kpi-label { font-size: .68rem; }
    .qs-kpi .qs-kpi-sub { font-size: .72rem; }

    /* Filter controls go full width — a half-width date picker is unusable. */
    .qs-toolbar .mud-input-control,
    .qs-toolbar .mud-picker .mud-input-control,
    .qs-toolbar .mud-select .mud-input-control { max-width: none; }

    /* Dialogs become sheets: full-bleed, scrollable, nothing off-screen. */
    .mud-dialog {
        width: 100vw !important;
        max-width: 100vw !important;
        margin: 0 !important;
        border-radius: 0 !important;
        max-height: 100dvh;
    }
    .mud-dialog-content { max-height: calc(100dvh - 150px); overflow-y: auto; }

    /* Chart axis labels crowd at phone width. */
    .apexcharts-xaxis text, .apexcharts-yaxis text { font-size: 10px; }
    .apexcharts-legend { font-size: 10px; }
}

/* Below 480px a two-up KPI row clips 12-digit money figures — go one-up.
   :has() is supported by every browser this app targets (Chrome/Edge/Safari). */
@media (max-width: 480px) {
    .mud-main-content .mud-grid-item:has(> .qs-kpi) { flex-basis: 100%; max-width: 100%; }
}

/* ===========================================================================
   EXECUTIVE PAGE PRIMITIVES â€” the landing-dashboard language, shared.
   Any page that should read like a board paper composes these instead of
   re-inventing a hero: .qs-eh (page header), .qs-btn (actions), .qs-brief
   (narrative line), .qs-att (exceptions), .qs-mtile (headline figure),
   .qs-card (content panel). Page-specific bits stay in the page's own style.
   =========================================================================== */

/* 12px, not 18px: with five or six bands stacked, the gaps alone were costing ~30px of the
   first screen — space that belongs to the figures, not to the air between them. */
.qs-page { display: flex; flex-direction: column; gap: 12px; }

/* ---- Page header -------------------------------------------------------- */
.qs-eh {
    display: flex; justify-content: space-between; align-items: flex-end; gap: 24px; flex-wrap: wrap;
    background: var(--qs-surface); border: 1px solid var(--qs-border);
    border-top: 3px solid var(--queens-primary); border-radius: var(--qs-radius-m); padding: 13px 18px;
}
.qs-eh-eyebrow { font-size: .72rem; font-weight: 700; letter-spacing: .14em; text-transform: uppercase; color: var(--queens-primary); }
.qs-eh-title { font-size: 1.38rem; font-weight: 700; letter-spacing: -.015em; color: var(--qs-text-1); margin: 3px 0 5px; line-height: 1.2; }
.qs-eh-meta { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; font-size: .84rem; color: var(--qs-text-2); }
.qs-eh-dot { width: 3px; height: 3px; border-radius: 50%; background: #a9b4c4; }
.qs-eh-live { width: 7px; height: 7px; border-radius: 50%; background: var(--qs-pos); box-shadow: 0 0 0 3px rgba(27, 126, 52, .14); }
.qs-eh-side { display: flex; align-items: flex-end; gap: 22px; flex-wrap: wrap; }
.qs-eh-stat { padding-inline-start: 16px; border-inline-start: 2px solid var(--qs-border); }
.qs-eh-stat-l { font-size: .7rem; font-weight: 700; letter-spacing: .1em; text-transform: uppercase; color: var(--qs-text-2); }
.qs-eh-stat-v { font-size: 1.05rem; font-weight: 700; color: var(--qs-text-1); margin-top: 2px; }
.qs-eh-stat-s { font-size: .8rem; color: var(--qs-text-2); font-variant-numeric: tabular-nums; }
.qs-eh-stat.is-pos .qs-eh-stat-v { color: var(--qs-pos); }
.qs-eh-stat.is-warn .qs-eh-stat-v { color: var(--qs-warn); }
.qs-eh-actions { display: flex; gap: 8px; }

/* ---- Actions ------------------------------------------------------------ */
.qs-btn {
    display: inline-flex; align-items: center; gap: 7px; height: 38px; padding: 0 16px;
    border: 1px solid var(--qs-border); border-radius: var(--qs-radius-s); background: var(--qs-surface);
    color: var(--qs-text-1); font: 600 .86rem/1 var(--qs-font); text-decoration: none; cursor: pointer;
    transition: background .15s ease, border-color .15s ease; white-space: nowrap;
}
.qs-btn:hover { background: #f2f5fa; border-color: #cfd8e5; }
.qs-btn .mud-icon-root { font-size: 1.05rem; }
.qs-btn-primary { background: var(--queens-primary); border-color: var(--queens-primary); color: #fff; }
.qs-btn-primary:hover { background: #013f80; border-color: #013f80; }

/* ---- Narrative line ----------------------------------------------------- */
.qs-brief {
    background: var(--qs-surface); border: 1px solid var(--qs-border);
    border-inline-start: 3px solid var(--queens-primary); border-radius: var(--qs-radius-s); padding: 14px 18px;
}
.qs-brief-k { font-size: .68rem; font-weight: 700; letter-spacing: .14em; text-transform: uppercase; color: var(--qs-text-2); margin-bottom: 5px; }
.qs-brief-t { margin: 0; font-size: .95rem; font-weight: 600; line-height: 1.55; color: var(--qs-text-1); }

/* ---- Exceptions --------------------------------------------------------- */
.qs-att { background: var(--qs-surface); border: 1px solid var(--qs-border); border-radius: var(--qs-radius-s); padding: 14px 18px 6px; }
.qs-att-h { display: flex; align-items: center; gap: 10px; margin-bottom: 8px; }
.qs-att-title { font-size: .72rem; font-weight: 700; letter-spacing: .12em; text-transform: uppercase; color: var(--qs-text-2); }
.qs-att-count { font-size: .72rem; font-weight: 700; color: var(--qs-warn); background: var(--qs-warn-bg); border-radius: 999px; padding: 2px 8px; line-height: 1.4; }
.qs-att-link { margin-inline-start: auto; font-size: .8rem; font-weight: 600; color: var(--queens-primary); text-decoration: none; }
.qs-att-link:hover { text-decoration: underline; }
.qs-att-list { list-style: none; margin: 0; padding: 0; }
.qs-att-item { display: flex; align-items: flex-start; gap: 10px; padding: 8px 0; font-size: .87rem; color: var(--qs-text-1); border-top: 1px solid #f0f3f7; }
.qs-att-dot { flex: none; width: 7px; height: 7px; border-radius: 50%; margin-top: 6px; background: var(--qs-warn); }
.qs-att-dot.sev-critical { background: var(--qs-neg); }
.qs-att-dot.sev-warning { background: var(--qs-warn); }
.qs-att-dot.sev-info { background: var(--qs-info); }
.qs-att-txt { min-width: 0; }

/* ---- Headline figures --------------------------------------------------- */
.qs-kpi-grid { display: grid; grid-template-columns: repeat(6, 1fr); gap: 12px; }
.qs-kpi-grid.cols-5 { grid-template-columns: repeat(5, 1fr); }
.qs-kpi-grid.cols-4 { grid-template-columns: repeat(4, 1fr); }
@media (max-width: 1400px) { .qs-kpi-grid, .qs-kpi-grid.cols-5, .qs-kpi-grid.cols-4 { grid-template-columns: repeat(3, 1fr); } }
@media (max-width: 780px) { .qs-kpi-grid, .qs-kpi-grid.cols-5, .qs-kpi-grid.cols-4 { grid-template-columns: repeat(2, 1fr); } }
.qs-mtile {
    background: var(--qs-surface); border: 1px solid var(--qs-border); border-radius: var(--qs-radius-s);
    padding: 11px 14px 12px; min-width: 0; transition: border-color .15s ease, box-shadow .15s ease;
}
.qs-mtile:hover { border-color: #cfd8e5; box-shadow: var(--qs-shadow-1); }
.qs-mtile.is-alert { border-inline-start: 3px solid var(--qs-neg); }
.qs-mtile.is-good { border-inline-start: 3px solid var(--qs-pos); }
.qs-mtile-label { font-size: .72rem; font-weight: 700; letter-spacing: .07em; text-transform: uppercase; color: var(--qs-text-2); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.qs-mtile-value { font-size: 1.65rem; font-weight: 700; letter-spacing: -.02em; line-height: 1.15; margin: 6px 0; color: var(--qs-text-1); font-variant-numeric: tabular-nums; overflow-wrap: anywhere; }
.qs-mtile-foot { display: flex; align-items: baseline; gap: 6px; flex-wrap: wrap; }
.qs-mtile-delta { font-size: .78rem; font-weight: 700; font-variant-numeric: tabular-nums; }
.qs-mtile-delta.up { color: var(--qs-pos); }
.qs-mtile-delta.down { color: var(--qs-neg); }
.qs-mtile-note { font-size: .74rem; color: var(--qs-text-2); font-weight: 600; }

/* ---- Content panels ----------------------------------------------------- */
.qs-card { background: var(--qs-surface); border: 1px solid var(--qs-border); border-radius: var(--qs-radius-m); padding: 16px 20px 18px; min-width: 0; }
.qs-card-h {
    display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; font-size: .75rem; font-weight: 700;
    text-transform: uppercase; letter-spacing: .1em; color: var(--qs-text-2);
    padding-bottom: 10px; margin-bottom: 12px; border-bottom: 1px solid #f0f3f7;
}
.qs-card-sub { text-transform: none; letter-spacing: 0; font-weight: 600; font-size: .78rem; color: var(--qs-text-2); }
.qs-empty { color: var(--qs-text-2); font-size: .86rem; }
.qs-row-2 { display: grid; grid-template-columns: 2fr 1fr; gap: 14px; }
.qs-row-11 { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
.qs-row-3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: 14px; }
@media (max-width: 1100px) { .qs-row-2, .qs-row-11, .qs-row-3 { grid-template-columns: 1fr; } }

/* ---- Labelled rows with a proportion bar -------------------------------- */
.qs-bar-row { padding: 6px 0; }
.qs-bar-top { display: flex; justify-content: space-between; gap: 12px; font-size: .88rem; color: var(--qs-text-2); }
.qs-bar-top b { color: var(--qs-text-1); font-variant-numeric: tabular-nums; white-space: nowrap; }
.qs-bar-name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.qs-bar-track { height: 6px; border-radius: 3px; background: #eef1f6; overflow: hidden; margin-top: 4px; }
.qs-bar-track span { display: block; height: 100%; border-radius: 3px; background: var(--queens-primary); }

/* ---- Phones ------------------------------------------------------------- */
@media (max-width: 599.98px) {
    .qs-page { gap: 12px; }
    .qs-eh { flex-direction: column; align-items: stretch; gap: 14px; padding: 16px; }
    .qs-eh-title { font-size: 1.25rem; }
    .qs-eh-meta { font-size: .8rem; row-gap: 4px; }
    .qs-eh-side { flex-direction: column; align-items: stretch; gap: 14px; }
    .qs-eh-stat { padding-inline-start: 0; border-inline-start: 0; padding-top: 12px; border-top: 1px solid var(--qs-border); }
    .qs-eh-actions { flex-direction: column; }
    .qs-btn { justify-content: center; height: 42px; }
    .qs-kpi-grid, .qs-kpi-grid.cols-5, .qs-kpi-grid.cols-4 { grid-template-columns: repeat(2, 1fr); gap: 10px; }
    .qs-mtile { padding: 12px; }
    .qs-mtile-value { font-size: 1.25rem; }
    .qs-mtile-label { font-size: .68rem; }
    .qs-card { padding: 14px; }
    .qs-brief, .qs-att { padding: 12px 14px; }
    .qs-row-2, .qs-row-11, .qs-row-3 { gap: 12px; }
}
@media (max-width: 380px) { .qs-kpi-grid, .qs-kpi-grid.cols-5, .qs-kpi-grid.cols-4 { grid-template-columns: 1fr; } }

/* ---- Print: these panels are the printed report ------------------------- */
@media print {
    .qs-eh { border: none; border-bottom: 2px solid var(--queens-primary); border-radius: 0; padding: 0 0 10px; }
    .qs-eh-live { display: none; }
    .qs-mtile, .qs-card, .qs-brief, .qs-att { box-shadow: none !important; break-inside: avoid; page-break-inside: avoid; }
    .qs-mtile { padding: 10px 12px !important; }
    .qs-mtile-value { font-size: 1.15rem; }
    .qs-card { padding: 10px 12px !important; }
    .qs-kpi-grid { grid-template-columns: repeat(6, 1fr) !important; gap: 8px !important; }
    .qs-row-3 { grid-template-columns: repeat(3, 1fr) !important; }
    .qs-row-11 { grid-template-columns: 1fr 1fr !important; }
}


/* ---- Report page heading (ReportHero) ---------------------------------- */
/* The quiet heading used by ~127 report pages. It shares the executive header's typography so the
   whole app reads as one product, and carries a hairline rule so a page opens with a deliberate
   masthead rather than text floating above a card. Deliberately NOT a banner — those were removed. */
.qs-rh { margin: 0 0 8px; padding-bottom: 6px; border-bottom: 1px solid var(--qs-border); }
.qs-rh-eyebrow {
    font-size: .78rem; font-weight: 700; letter-spacing: .14em; text-transform: uppercase;
    color: var(--queens-primary); margin-bottom: 1px;
}
.qs-rh-title {
    margin: 0; font-size: 1.25rem; font-weight: 700; letter-spacing: -.015em;
    line-height: 1.2; color: var(--qs-text-1);
}
/* Period and description share ONE line. The description is context, not content — it must not
   push the report down the page. It truncates with an ellipsis and opens on hover for the rare
   moment someone wants the whole sentence. */
.qs-rh-sub {
    display: flex; align-items: baseline; gap: 10px; flex-wrap: nowrap;
    margin-top: 3px; font-size: .84rem; color: var(--qs-text-2);
}
/* The period is a fixed, meaningful string — it never wraps or shrinks; the description beside
   it absorbs whatever width is left and truncates instead. */
.qs-rh-period { font-weight: 700; font-variant-numeric: tabular-nums; color: var(--qs-text-1);
    white-space: nowrap; flex: none; }
.qs-rh-note {
    font-weight: 600; min-width: 0;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
/* Hover reveals the full sentence without it costing a second line the rest of the time. */
.qs-rh:hover .qs-rh-note { white-space: normal; overflow: visible; }
.qs-rh + .mud-paper, .qs-rh + .mud-alert { margin-top: 0; }

@media (max-width: 599.98px) {
    .qs-rh { margin-bottom: 10px; }
    .qs-rh-title { font-size: 1.15rem; }
    .qs-rh-sub { font-size: .8rem; gap: 6px; }
}

@media print {
    /* The heading IS the printed report's title block. */
    .qs-rh { margin-bottom: 10px; padding-bottom: 6px; border-bottom: 2px solid var(--queens-primary); }
    .qs-rh-title { font-size: 1.25rem; }
}


/* ---- AI insights panel (ReportInsights) -------------------------------- */
.qs-ri { border: 1px solid var(--qs-border) !important; border-radius: var(--qs-radius-m) !important; }
.qs-ri .qs-ri-head .mud-typography-subtitle1 { min-width: 0; }
@media (max-width: 599.98px) {
    /* Title on its own line, action full width beneath it. */
    .qs-ri .qs-ri-head .mud-spacer { display: none; }
    .qs-ri .qs-ri-head > .mud-button-root { flex: 1 1 100%; }
}

/* ---- Charts on phones --------------------------------------------------- */
@media (max-width: 599.98px) {
    /* Column value labels stack on top of each other at this width â€” the axis and
       the tooltip still carry the numbers, so drop the printed labels on bars only. */
    .apexcharts-bar-series .apexcharts-datalabels { display: none; }
}


/* ---- "still working" note under a report's progress bar ----------------- */
.qs-loading-note {
    display: flex; align-items: center; gap: 8px;
    margin: 10px 2px; font-size: .85rem; color: var(--qs-text-2);
}
.qs-loading-note .mud-icon-root { color: var(--queens-primary); }


/* ===========================================================================
   "The system is working" feedback â€” boot splash + global activity indicator.
   Neither ever blocks input: the user can always navigate away.
   =========================================================================== */

/* ---- Boot splash (App.razor; removed by script once the app renders) ---- */
#qs-boot {
    position: fixed; inset: 0; z-index: 4000;
    display: flex; align-items: center; justify-content: center;
    background: var(--qs-canvas, #f3f5f9);
    transition: opacity .35s ease;
}
#qs-boot.gone { opacity: 0; pointer-events: none; }
#qs-boot .qs-boot-inner { text-align: center; }
#qs-boot .qs-boot-brand {
    font: 700 1.5rem/1 var(--qs-font); letter-spacing: .4px;
    color: var(--queens-primary, #004E9F); margin-bottom: 16px;
}
#qs-boot .qs-boot-bar {
    width: 200px; height: 3px; border-radius: 2px; margin: 0 auto;
    background: #dfe6f0; overflow: hidden;
}
#qs-boot .qs-boot-bar > span {
    display: block; width: 40%; height: 100%; border-radius: 2px;
    background: var(--queens-primary, #004E9F);
    animation: qsBootSlide 1.1s ease-in-out infinite;
}
@keyframes qsBootSlide {
    0%   { transform: translateX(-100%); }
    100% { transform: translateX(350%); }
}
#qs-boot .qs-boot-txt {
    margin-top: 12px; font: 600 .82rem/1 var(--qs-font); color: #5b6472;
}

/* ---- Global activity indicator ----------------------------------------- */
.qs-activity { position: fixed; inset: 0 0 auto 0; z-index: 3500; pointer-events: none; }
.qs-activity-bar {
    height: 3px; width: 100%; opacity: 0; transition: opacity .2s ease;
    background: linear-gradient(90deg,
        rgba(0, 78, 159, 0) 0%, var(--queens-primary, #004E9F) 45%,
        #2f80ed 55%, rgba(0, 78, 159, 0) 100%);
    background-size: 40% 100%; background-repeat: no-repeat;
}
.qs-activity.on .qs-activity-bar { opacity: 1; animation: qsActivitySlide 1.2s linear infinite; }
@keyframes qsActivitySlide {
    0%   { background-position: -40% 0; }
    100% { background-position: 140% 0; }
}
/* The plain-language note that appears once a wait drags on. */
.qs-activity-note {
    position: fixed; top: 14px; left: 50%; transform: translateX(-50%);
    background: var(--qs-surface, #fff); border: 1px solid var(--qs-border, #e6ebf2);
    border-radius: 999px; box-shadow: 0 4px 16px rgba(20, 30, 60, .12);
    padding: 7px 16px; font: 600 .82rem/1.2 var(--qs-font);
    color: var(--qs-text-1, #16202e); white-space: nowrap; max-width: calc(100vw - 32px);
    overflow: hidden; text-overflow: ellipsis;
}
@media (max-width: 599.98px) {
    .qs-activity-note { font-size: .76rem; padding: 6px 12px; }
}
@media print { .qs-activity, #qs-boot { display: none !important; } }
@media (prefers-reduced-motion: reduce) {
    .qs-activity.on .qs-activity-bar, #qs-boot .qs-boot-bar > span { animation: none; }
}


/* ================= C4 group report =======================================
   This sheet goes to head office, so it is styled as a financial document:
   one control style, one accent, rules instead of boxes, and colour reserved
   for the two things that mean something — up and down.
   ------------------------------------------------------------------------ */

/* ---- Control strip ------------------------------------------------------
   Four stacked rows became one. Fields are a fixed width so their labels and
   baselines line up instead of drifting with the length of their contents. */
.qs-c4-bar { display: flex; flex-wrap: wrap; align-items: center; gap: 10px 12px; }
.qs-c4-bar .qs-c4-ctl { flex: 0 0 190px; }
/* Beat the shared .qs-toolbar max-widths: here the field IS the column. */
.qs-c4-bar .qs-c4-ctl > *, .qs-c4-bar .qs-c4-ctl .mud-input-control {
    max-width: none !important; width: 100%;
}
.qs-c4-bar .qs-c4-sw { flex: 0 0 auto; margin: 0 0 0 4px; }

/* Actions sit at the far end of the same row and drop together, never one at a time. */
.qs-c4-bar-end { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-inline-start: auto; }
.qs-c4-bar-end .mud-button-root { margin-top: 0 !important; text-transform: none; letter-spacing: 0; }
/* The rule that sets the send apart from the things you can safely press twice. */
.qs-c4-bar-rule { width: 1px; height: 24px; background: var(--qs-border, #dfe4ec); margin: 0 2px; }
@media (max-width: 1180px) {
    .qs-c4-bar-end { margin-inline-start: 0; width: 100%; }
}

/* ---- Headline figures ---------------------------------------------------
   Uniform cards. The old ones carried four accent colours and four icons that
   encoded nothing; the only colour left is direction. */
.qs-c4-card {
    background: var(--qs-surface);
    border: 1px solid var(--qs-border, #e3e8f0);
    border-radius: var(--qs-radius-s);
    padding: 12px 16px 13px;
    height: 100%;
}
.qs-c4-card-label {
    font-size: .7rem; text-transform: uppercase; letter-spacing: .07em;
    font-weight: 700; color: var(--qs-text-2); line-height: 1.2;
}
/* The figure is the point of the card, so it is the only thing set large. Hierarchy comes from
   size, not from washing the supporting text out to grey. */
.qs-c4-card-value {
    font-size: 1.75rem; font-weight: 700; line-height: 1.15; margin-top: 6px;
    letter-spacing: -.02em; font-variant-numeric: tabular-nums; color: var(--qs-text-1);
}
.qs-c4-card-sub {
    font-size: .78rem; font-weight: 500; color: var(--qs-text-2); margin-top: 5px;
    display: flex; align-items: baseline; gap: 5px; flex-wrap: wrap;
}
/* Only the comparison itself is coloured — the words beside it stay plain, so a card is never
   an entire red sentence. */
.qs-c4-fig { font-weight: 700; font-variant-numeric: tabular-nums; }
.qs-c4-fig.is-pos { color: var(--c4-pos); }
.qs-c4-fig.is-neg { color: var(--c4-neg); }
.qs-c4-partial-mark { color: var(--c4-warn); font-weight: 700; cursor: help; }

/* ---- Reference line and notes -------------------------------------------
   "Month to date" is a different stretch of days in each calendar — Nehase 1
   is not 1 August — so the spans are stated once, quietly, under the figures. */
.qs-c4-periods {
    font-size: .78rem; font-weight: 600; color: var(--qs-text-2);
    padding: 6px 0; border-top: 1px solid var(--qs-border, #e3e8f0); margin-bottom: 2px;
}
.qs-c4-periods-label {
    text-transform: uppercase; letter-spacing: .06em; font-size: .7rem;
    font-weight: 700; margin-inline-end: 10px;
}
.qs-c4-periods [title] { cursor: help; }
.qs-c4-sep { color: var(--qs-text-3); padding: 0 7px; opacity: .5; }
.qs-c4-note { font-size: .78rem; font-weight: 600; color: var(--qs-text-2); margin-bottom: 6px; }

/* ---- Tabs ---------------------------------------------------------------
   The tab carries the section's title, so all that is left inside a panel is
   the one line saying what you are looking at. */
.qs-c4-tabs .mud-tabs-toolbar { border-bottom: 1px solid var(--qs-border); min-height: 40px; }
.qs-c4-tabs .mud-tab {
    text-transform: none; letter-spacing: 0; font-size: .84rem; font-weight: 600;
    min-height: 40px; min-width: 0; padding: 0 16px;
}
.qs-c4-tabs .mud-tab.mud-tab-active { font-weight: 700; }
.qs-c4-panel { padding-top: 12px; }
.qs-c4-note-line { font-size: .8rem; font-weight: 500; margin: 0 0 10px; color: var(--qs-text-2); }

/* Print puts the whole report on the page, not just the tab that happens to be
   open. The panels are kept alive precisely so this rule has something to show;
   !important is needed because MudBlazor hides them with an inline style. */
@media print {
    .qs-c4-tabs .mud-tabs-toolbar { display: none !important; }
    .qs-c4-tabs .mud-tabs-panels > div { display: block !important; page-break-inside: auto; }
}

/* ---- The sheet itself ---------------------------------------------------
   Rules across, nothing down. A reader follows one store along its row; the
   vertical borders were a cage around 17 columns and read as noise. */
.qs-c4 { border: 1px solid var(--qs-border, #e3e8f0); }
.qs-c4 thead th {
    font-size: .7rem !important; text-transform: uppercase; letter-spacing: .05em;
    font-weight: 700; white-space: nowrap;
    background: #f7f9fc !important; border-bottom: 2px solid var(--qs-border, #dfe4ec) !important;
}
.qs-c4 tbody td { border-bottom: 1px solid #eef1f6 !important; }

/* Type: the app sets 600 on everything, which leaves a financial table with no hierarchy at all —
   when every row is semi-bold, the subtotal rows that ARE bold stop reading as bold. Ordinary rows
   drop to 500 here. Still solid at full text contrast, never faint; the band and chain totals keep
   their inline 700/800 and now stand out from the stores they add up.
   Scoped to this sheet only — nothing else in the app changes. */
.qs-c4 tbody td { font-weight: 500; }
.qs-c4-tabs .mud-simple-table td { font-weight: 500; }
