﻿:root {
    --brand-burgundy: #87374f;
    --brand-burgundy-bright: #a54763;
    --brand-blue: #1f6899;
    --brand-blue-bright: #2d88c2;
    --brand-blue-soft: #74b0d5;
    --color-text-on-dark: #f5f7fb;
    --color-text-muted-on-dark: #afbfd4;
    --color-ink: #162236;
    --color-ink-soft: #5f708a;
    --color-surface-light: #f6f8fc;
    --color-surface-dark: #071019;
}

html, body {
    font-family: 'Manrope', sans-serif;
    color: var(--mud-palette-text-primary, #162236);
    background: var(--mud-palette-background, #f3f6fb);
}

html {
    scroll-behavior: smooth;
}

body {
    min-height: 100vh;
    margin: 0;
}

a, .btn-link {
    color: var(--brand-blue-soft);
    transition: transform 120ms ease, opacity 120ms ease, color 120ms ease, background 120ms ease;
}

a:hover, .btn-link:hover {
    opacity: 0.96;
}

button,
input,
textarea,
select {
    font: inherit;
}

.form-control:focus {
    outline: none;
    border-color: rgba(116, 176, 213, 0.8);
    box-shadow: 0 0 0 0.18rem rgba(116, 176, 213, 0.18);
}

h1:focus {
    outline: none;
}

p {
    line-height: 1.6;
}

.blazor-error-boundary {
    background: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTYiIGhlaWdodD0iNDkiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeGxpbmxucz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgb3ZlcmZsb3c9ImhpZGRlbiI+PGRlZnM+PGNsaXBQYXRoIGlkPSJjbGlwMCI+PHJlY3QgeD0iMjM1IiB5PSI1MSIgd2lkdGg9IjU2IiBoZWlnaHQ9IjQ5Ii8+PC9jbGlwUGF0aD48L2RlZnM+PGcgY2xpcC1wYXRoPSJ1cmwoI2NsaXAwKSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTIzNSAtNTEpIj48cGF0aCBkPSJNMjYzLjUwNiA1MUMyNjQuNzE3IDUxIDI2NS44MTMgNTEuNDgzNyAyNjYuNjA2IDUyLjI2NThMMjY3LjA1MiA1Mi43OTg3IDI2Ny41MzkgNTMuNjI4MyAyOTAuMTg1IDkyLjE4MzEgMjkwLjU0NSA5Mi43OTUgMjkwLjY1NiA5Mi45OTZDMjkwLjg3NyA5My41MTMgMjkxIDk0LjA4MTUgMjkxIDk0LjY3ODIgMjkxIDk3LjA2NTEgMjg5LjAzOCA5OSAyODYuNjE3IDk5TDI0MC4zODMgOTlDMjM3Ljk2MyA5OSAyMzYgOTcuMDY1MSAyMzYgOTQuNjc4MiAyMzYgOTQuMzc5OSAyMzYuMDMxIDk0LjA4ODYgMjM2LjA4OSA5My44MDcyTDIzNi4zMzggOTMuMDE2MiAyMzYuODU4IDkyLjEzMTQgMjU5LjQ3MyA1My42Mjk0IDI1OS45NjEgNTIuNzk4NSAyNjAuNDA3IDUyLjI2NThDMjYxLjIgNTEuNDgzNyAyNjIuMjk2IDUxIDI2My41MDYgNTFaTTI2My41ODYgNjYuMDE4M0MyNjAuNzM3IDY2LjAxODMgMjU5LjMxMyA2Ny4xMjQ1IDI1OS4zMTMgNjkuMzM3IDI1OS4zMTMgNjkuNjEwMiAyNTkuMzMyIDY5Ljg2MDggMjU5LjM3MSA3MC4wODg3TDI2MS43OTUgODQuMDE2MSAyNjUuMzggODQuMDE2MSAyNjcuODIxIDY5Ljc0NzVDMjY3Ljg2IDY5LjczMDkgMjY3Ljg3OSA2OS41ODc3IDI2Ny44NzkgNjkuMzE3OSAyNjcuODc5IDY3LjExODIgMjY2LjQ0OCA2Ni4wMTgzIDI2My41ODYgNjYuMDE4M1pNMjYzLjU3NiA4Ni4wNTQ3QzI2MS4wNDkgODYuMDU0NyAyNTkuNzg2IDg3LjMwMDUgMjU5Ljc4NiA4OS43OTIxIDI1OS43ODYgOTIuMjgzNyAyNjEuMDQ5IDkzLjUyOTUgMjYzLjU3NiA5My41Mjk1IDI2Ni4xMTYgOTMuNTI5NSAyNjcuMzg3IDkyLjI4MzcgMjY3LjM4NyA4OS43OTIxIDI2Ny4zODcgODcuMzAwNSAyNjYuMTE2IDg2LjA1NDcgMjYzLjU3NiA4Ni4wNTQ3WiIgZmlsbD0iI0ZGRTUwMCIgZmlsbC1ydWxlPSJldmVub2RkIi8+PC9nPjwvc3ZnPg==) no-repeat 1rem/1.8rem, #b32121;
    padding: 1rem 1rem 1rem 3.7rem;
    color: white;
}

.blazor-error-boundary::after {
    content: "An error has occurred.";
}

.backoffice-theme-host .sf-grid.e-grid {
    border: 1px solid var(--backoffice-syncfusion-border) !important;
    border-radius: 1rem !important;
    background: var(--backoffice-syncfusion-surface) !important;
    color: var(--backoffice-syncfusion-text) !important;
    border-color: var(--backoffice-syncfusion-border) !important;
    min-width: 0 !important;
    max-width: 100% !important;
    overflow: hidden;
    box-shadow: 0 18px 34px rgba(7, 16, 27, 0.12);
}

.backoffice-theme-host .sf-grid.e-grid .e-gridheader,
.backoffice-theme-host .sf-grid.e-grid .e-columnheader,
.backoffice-theme-host .sf-grid.e-grid .e-headercontent,
.backoffice-theme-host .sf-grid.e-grid .e-gridcontent,
.backoffice-theme-host .sf-grid.e-grid .e-content,
.backoffice-theme-host .sf-grid.e-grid .e-table,
.backoffice-theme-host .sf-grid.e-grid .e-gridpager,
.backoffice-theme-host .sf-grid.e-grid .e-pagercontainer,
.backoffice-theme-host .sf-grid.e-grid .e-parentmsgbar,
.backoffice-theme-host .sf-grid.e-grid .e-pagerexternalmsg {
    background: var(--backoffice-syncfusion-surface) !important;
    color: var(--backoffice-syncfusion-text) !important;
}

.backoffice-theme-host .sf-grid.e-grid .e-headercell,
.backoffice-theme-host .sf-grid.e-grid .e-detailheadercell,
.backoffice-theme-host .sf-grid.e-grid .e-filterbarcell {
    background: var(--backoffice-syncfusion-header) !important;
    color: var(--backoffice-syncfusion-text) !important;
    border-color: var(--backoffice-syncfusion-border) !important;
    font-weight: 800;
}

.backoffice-theme-host .sf-grid.e-grid .e-headercell .e-headertext,
.backoffice-theme-host .sf-grid.e-grid .e-filterbarcell,
.backoffice-theme-host .sf-grid.e-grid .e-rowcell,
.backoffice-theme-host .sf-grid.e-grid .e-summarycell,
.backoffice-theme-host .sf-grid.e-grid .e-pagercontainer,
.backoffice-theme-host .sf-grid.e-grid .e-parentmsgbar,
.backoffice-theme-host .sf-grid.e-grid .e-pagerdropdown,
.backoffice-theme-host .sf-grid.e-grid .e-pagerexternalmsg,
.backoffice-theme-host .sf-grid.e-grid .e-icons {
    color: var(--backoffice-syncfusion-text) !important;
}

.backoffice-theme-host .sf-grid.e-grid .e-row,
.backoffice-theme-host .sf-grid.e-grid .e-altrow,
.backoffice-theme-host .sf-grid.e-grid .e-row .e-rowcell,
.backoffice-theme-host .sf-grid.e-grid .e-altrow .e-rowcell,
.backoffice-theme-host .sf-grid.e-grid .e-gridcontent tr,
.backoffice-theme-host .sf-grid.e-grid .e-gridcontent td {
    background: var(--backoffice-syncfusion-surface) !important;
}

.backoffice-theme-host .sf-grid.e-grid .e-rowcell,
.backoffice-theme-host .sf-grid.e-grid .e-gridpager,
.backoffice-theme-host .sf-grid.e-grid .e-summaryrow,
.backoffice-theme-host .sf-grid.e-grid .e-filterbarcell,
.backoffice-theme-host .sf-grid.e-grid .e-headercell {
    border-color: var(--backoffice-syncfusion-border) !important;
}

/* The header container and the column resize-handles keep Syncfusion's hardcoded light
   rgb(224,224,224) (and currentColor) borders, which the header-cell theming above does not cover —
   in dark mode they drew the harsh white horizontal line under the header and the bright vertical
   lines between columns. Re-border them with the theme variable. */
.backoffice-theme-host .sf-grid.e-grid .e-gridheader,
.backoffice-theme-host .sf-grid.e-grid .e-headercontent,
.backoffice-theme-host .sf-grid.e-grid .e-rhandler,
.backoffice-theme-host .e-pivotview .e-grid .e-gridheader,
.backoffice-theme-host .e-pivotview .e-grid .e-headercontent,
.backoffice-theme-host .e-pivotview .e-grid .e-rhandler {
    border-color: var(--backoffice-syncfusion-border) !important;
}

.backoffice-theme-host .sf-grid.e-grid .e-row:hover .e-rowcell,
.backoffice-theme-host .sf-grid.e-grid .e-altrow:hover .e-rowcell {
    background: var(--backoffice-syncfusion-row-hover) !important;
}

.backoffice-theme-host .sf-grid.e-grid .e-emptyrow,
.backoffice-theme-host .sf-grid.e-grid .e-emptyrow td {
    background: var(--backoffice-syncfusion-surface) !important;
    color: var(--backoffice-syncfusion-text) !important;
}

.backoffice-theme-host .sf-grid.e-grid .e-gridpager {
    border-top: 1px solid var(--backoffice-syncfusion-border) !important;
}

.backoffice-theme-host .sf-grid.e-grid .e-gridpager,
.backoffice-theme-host .sf-grid.e-grid .sf-pager.e-pager,
.backoffice-theme-host .sf-grid.e-grid .e-pagercontainer,
.backoffice-theme-host .sf-grid.e-grid .e-parentmsgbar,
.backoffice-theme-host .sf-grid.e-grid .e-numericcontainer {
    background: var(--backoffice-syncfusion-surface) !important;
}

.backoffice-theme-host .sf-grid.e-grid .e-parentmsgbar,
.backoffice-theme-host .sf-grid.e-grid .e-parentmsgbar span,
.backoffice-theme-host .sf-grid.e-grid .e-pagenomsg,
.backoffice-theme-host .sf-grid.e-grid .e-pagecountmsg {
    color: var(--backoffice-syncfusion-muted) !important;
}

.backoffice-theme-host .sf-grid.e-grid .e-pagercontainer .e-link,
.backoffice-theme-host .sf-grid.e-grid .e-pagercontainer .e-first,
.backoffice-theme-host .sf-grid.e-grid .e-pagercontainer .e-prev,
.backoffice-theme-host .sf-grid.e-grid .e-pagercontainer .e-next,
.backoffice-theme-host .sf-grid.e-grid .e-pagercontainer .e-last,
.backoffice-theme-host .sf-grid.e-grid .e-mfirst,
.backoffice-theme-host .sf-grid.e-grid .e-mprev,
.backoffice-theme-host .sf-grid.e-grid .e-mnext,
.backoffice-theme-host .sf-grid.e-grid .e-mlast {
    color: var(--backoffice-syncfusion-muted) !important;
    background: transparent !important;
    border-color: transparent !important;
    box-shadow: none !important;
    border-radius: 0.75rem;
}

.backoffice-theme-host .sf-grid.e-grid .e-pagercontainer .e-link:hover,
.backoffice-theme-host .sf-grid.e-grid .e-pagercontainer .e-first:hover,
.backoffice-theme-host .sf-grid.e-grid .e-pagercontainer .e-prev:hover,
.backoffice-theme-host .sf-grid.e-grid .e-pagercontainer .e-next:hover,
.backoffice-theme-host .sf-grid.e-grid .e-pagercontainer .e-last:hover,
.backoffice-theme-host .sf-grid.e-grid .e-mfirst:hover,
.backoffice-theme-host .sf-grid.e-grid .e-mprev:hover,
.backoffice-theme-host .sf-grid.e-grid .e-mnext:hover,
.backoffice-theme-host .sf-grid.e-grid .e-mlast:hover {
    background: var(--backoffice-syncfusion-accent-soft) !important;
    color: var(--backoffice-syncfusion-accent) !important;
}

.backoffice-theme-host .sf-grid.e-grid .e-pagercontainer .e-link.e-disable,
.backoffice-theme-host .sf-grid.e-grid .e-pagercontainer .e-first.e-disable,
.backoffice-theme-host .sf-grid.e-grid .e-pagercontainer .e-prev.e-disable,
.backoffice-theme-host .sf-grid.e-grid .e-pagercontainer .e-next.e-disable,
.backoffice-theme-host .sf-grid.e-grid .e-pagercontainer .e-last.e-disable,
.backoffice-theme-host .sf-grid.e-grid .e-mfirst.e-disable,
.backoffice-theme-host .sf-grid.e-grid .e-mprev.e-disable,
.backoffice-theme-host .sf-grid.e-grid .e-mnext.e-disable,
.backoffice-theme-host .sf-grid.e-grid .e-mlast.e-disable {
    opacity: 0.5;
    background: transparent !important;
    color: var(--backoffice-syncfusion-muted) !important;
}

.backoffice-theme-host .sf-grid.e-grid .e-pagercontainer .e-currentitem,
.backoffice-theme-host .sf-grid.e-grid .e-pagercontainer .e-currentitem.e-active,
.backoffice-theme-host .sf-grid.e-grid .e-pagercontainer .e-currentitem:hover,
.backoffice-theme-host .sf-grid.e-grid .e-pagercontainer .e-currentitem:focus,
.backoffice-theme-host .sf-grid.e-grid .e-pagercontainer .e-currentitem:focus-visible {
    background: color-mix(in srgb, var(--backoffice-syncfusion-accent) 22%, var(--backoffice-syncfusion-surface)) !important;
    color: var(--backoffice-syncfusion-text) !important;
    border: 1px solid color-mix(in srgb, var(--backoffice-syncfusion-accent) 72%, white 8%) !important;
    border-radius: 0.9rem !important;
    font-weight: 800;
    box-shadow: none !important;
    outline: none !important;
    text-decoration: none !important;
}

.backoffice-theme-host .sf-grid.e-grid .e-filterbarcell {
    background: var(--backoffice-syncfusion-header) !important;
    color: var(--backoffice-syncfusion-text) !important;
    border-color: var(--backoffice-syncfusion-border) !important;
    padding: 0.35rem !important;
}

.backoffice-theme-host .sf-grid.e-grid .e-filterbarcell .e-filterdiv,
.backoffice-theme-host .sf-grid.e-grid .e-filterbarcell .e-fltrinputdiv {
    background: transparent !important;
    padding: 0 !important;
}

.backoffice-theme-host .sf-grid.e-grid .e-filterbarcell .e-input-group,
.backoffice-theme-host .sf-grid.e-grid .e-filterbarcell .e-input-group.e-control-wrapper {
    background: var(--backoffice-syncfusion-input-background) !important;
    border: 1px solid var(--backoffice-syncfusion-input-border) !important;
    border-color: var(--backoffice-syncfusion-input-border) !important;
    border-radius: 0.85rem !important;
    box-shadow: none !important;
}

.backoffice-theme-host .sf-grid.e-grid .e-filterbarcell .e-input-group:focus-within,
.backoffice-theme-host .sf-grid.e-grid .e-filterbarcell .e-input-group.e-control-wrapper:focus-within {
    border-color: var(--backoffice-syncfusion-accent) !important;
    box-shadow: 0 0 0 2px var(--backoffice-syncfusion-accent-soft) !important;
}

.backoffice-theme-host .sf-grid.e-grid .e-filterbarcell input,
.backoffice-theme-host .sf-grid.e-grid .e-filterbarcell input::placeholder {
    color: var(--backoffice-syncfusion-muted) !important;
}

.backoffice-theme-host .sf-grid.e-grid .e-filterbarcell input {
    background: transparent !important;
    color: var(--backoffice-syncfusion-text) !important;
    padding: 0.55rem 0.85rem !important;
    border: none !important;
    box-shadow: none !important;
    border-radius: 0;
}

.backoffice-theme-host .sf-grid.e-grid .e-filterbarcell .e-clear-icon {
    background: transparent !important;
    color: var(--backoffice-syncfusion-muted) !important;
    border-left: 1px solid var(--backoffice-syncfusion-input-border);
}

/* Syncfusion grid toolbar (Add / Edit / Delete / Update / Cancel) — inherit backoffice theme. */
.backoffice-theme-host .sf-grid.e-grid .e-toolbar,
.backoffice-theme-host .sf-grid.e-grid .e-toolbar .e-toolbar-items,
.backoffice-theme-host .sf-grid.e-grid .e-toolbar .e-toolbar-item,
.backoffice-theme-host .sf-grid.e-grid .e-toolbar .e-toolbar-pop {
    background: var(--backoffice-syncfusion-header) !important;
    color: var(--backoffice-syncfusion-text) !important;
    border-color: var(--backoffice-syncfusion-border) !important;
}

.backoffice-theme-host .sf-grid.e-grid .e-toolbar {
    border-bottom: 1px solid var(--backoffice-syncfusion-border) !important;
}

.backoffice-theme-host .sf-grid.e-grid .e-toolbar .e-tbar-btn,
.backoffice-theme-host .sf-grid.e-grid .e-toolbar .e-tbar-btn .e-tbar-btn-text,
.backoffice-theme-host .sf-grid.e-grid .e-toolbar .e-tbar-btn .e-icons {
    background: transparent !important;
    color: var(--backoffice-syncfusion-text) !important;
}

.backoffice-theme-host .sf-grid.e-grid .e-toolbar .e-tbar-btn:hover,
.backoffice-theme-host .sf-grid.e-grid .e-toolbar .e-tbar-btn:focus {
    background: var(--backoffice-syncfusion-row-hover) !important;
    color: var(--backoffice-syncfusion-text) !important;
}

.backoffice-theme-host .sf-grid.e-grid .e-toolbar .e-tbar-btn.e-overlay,
.backoffice-theme-host .sf-grid.e-grid .e-toolbar .e-tbar-btn[aria-disabled="true"] {
    color: var(--backoffice-syncfusion-muted) !important;
    opacity: 0.55;
}

/* Hoist the backoffice Syncfusion theme variables to body level so portaled popups
   (edit dialog, dropdowns, etc.) inherit the correct colors per active theme.
   The :has() selector keeps a single source of truth on the layout host. */
body:has(.backoffice-theme-host.backoffice-layout-dark) {
    --backoffice-syncfusion-surface: #101927;
    --backoffice-syncfusion-surface-alt: #162235;
    --backoffice-syncfusion-header: #1b2a40;
    --backoffice-syncfusion-border: rgba(157, 176, 201, 0.28);
    --backoffice-syncfusion-text: #edf3fb;
    --backoffice-syncfusion-muted: #aebdd0;
    --backoffice-syncfusion-accent: #69b9e6;
    --backoffice-syncfusion-accent-soft: rgba(105, 185, 230, 0.18);
    --backoffice-syncfusion-row-hover: rgba(105, 185, 230, 0.12);
    /* Flattened equivalents of surface / row-hover, with NO alpha. Only used by the pivot's frozen
       row-header column: those cells have scrolled value cells passing underneath them, so any
       transparency lets two rows of numbers show through each other. */
    --backoffice-syncfusion-frozen: #1b2a40;
    /* row-hover rgba(105,185,230,0.12) flattened over #1b2a40. Written out rather than color-mix()d
       so the computed value stays a plain opaque colour that is trivial to assert on. */
    --backoffice-syncfusion-frozen-hover: #243b54;
    --backoffice-syncfusion-input-background: #0c1420;
    --backoffice-syncfusion-input-border: rgba(105, 185, 230, 0.34);
}

body:has(.backoffice-theme-host.backoffice-layout-light) {
    --backoffice-syncfusion-surface: rgba(255, 255, 255, 0.98);
    --backoffice-syncfusion-surface-alt: rgba(247, 250, 253, 0.98);
    --backoffice-syncfusion-header: rgba(242, 246, 251, 0.98);
    --backoffice-syncfusion-border: rgba(92, 114, 140, 0.16);
    --backoffice-syncfusion-text: #18304b;
    --backoffice-syncfusion-muted: #607390;
    --backoffice-syncfusion-accent: #1f6899;
    --backoffice-syncfusion-accent-soft: rgba(31, 104, 153, 0.12);
    --backoffice-syncfusion-row-hover: rgba(31, 104, 153, 0.06);
    /* See the dark block: fully opaque, because the frozen column is painted over moving content. */
    --backoffice-syncfusion-frozen: #f2f6fb;
    /* row-hover rgba(31,104,153,0.06) flattened over #f2f6fb. */
    --backoffice-syncfusion-frozen-hover: #e5edf5;
    --backoffice-syncfusion-input-background: rgba(255, 255, 255, 0.98);
    --backoffice-syncfusion-input-border: rgba(31, 104, 153, 0.16);
}

/* Edit dialog popups portal to body, so style globally using the hoisted variables.
   `.e-dlg-container` is the outer wrapper Syncfusion injects around the dialog —
   theme it too so semi-transparent surfaces don't show a white seam underneath. */
body .e-dlg-container:has(> .e-dialog),
body .e-dialog.e-popup,
body .e-dialog.e-popup > *,
body .e-dialog.e-popup .e-dlg-header-content,
body .e-dialog.e-popup .e-dlg-content,
body .e-dialog.e-popup .e-footer-content {
    background: var(--backoffice-syncfusion-surface) !important;
    color: var(--backoffice-syncfusion-text) !important;
    border-color: var(--backoffice-syncfusion-border) !important;
}

body .e-dlg-container {
    background: transparent !important;
}

body .e-dialog.e-popup .e-dlg-header,
body .e-dialog.e-popup .e-dlg-header *,
body .e-dialog.e-popup label,
body .e-dialog.e-popup .e-label,
body .e-dialog.e-popup .e-float-text,
body .e-dialog.e-popup .e-float-text.e-label-top,
body .e-dialog.e-popup .e-float-text.e-label-bottom {
    color: var(--backoffice-syncfusion-text) !important;
}

body .e-dialog.e-popup .e-input,
body .e-dialog.e-popup .e-input-group,
body .e-dialog.e-popup .e-input-group.e-control-wrapper {
    background: var(--backoffice-syncfusion-input-background) !important;
    color: var(--backoffice-syncfusion-text) !important;
    border-color: var(--backoffice-syncfusion-input-border) !important;
}

body .e-dialog.e-popup .e-input::placeholder {
    color: var(--backoffice-syncfusion-muted) !important;
}

/* Row add/edit dialog: wider than Syncfusion's narrow default. */
body .e-dialog.e-popup.e-edit-dialog,
body .e-dialog.e-popup.e-edit-dialog .e-dlg-content {
    min-width: 36rem !important;
    width: min(48rem, calc(100vw - 4rem)) !important;
}


/* FileManager context menu portals to body — theme it with the hoisted vars. */
body ul.e-contextmenu {
    background: var(--backoffice-syncfusion-surface) !important;
    border-color: var(--backoffice-syncfusion-border) !important;
    color: var(--backoffice-syncfusion-text) !important;
}

body ul.e-contextmenu .e-menu-item,
body ul.e-contextmenu .e-menu-item .e-caret,
body ul.e-contextmenu .e-menu-item .e-menu-icon {
    color: var(--backoffice-syncfusion-text) !important;
    background: transparent !important;
}

body ul.e-contextmenu .e-menu-item.e-focused,
body ul.e-contextmenu .e-menu-item:hover {
    background: var(--backoffice-syncfusion-row-hover) !important;
}

body ul.e-contextmenu .e-menu-item.e-disabled {
    color: var(--backoffice-syncfusion-muted) !important;
}

body ul.e-contextmenu .e-separator {
    border-color: var(--backoffice-syncfusion-border) !important;
}

/* Pivot toolbar dropdown menus — Export (PDF/Excel/CSV), Show/Hide Sub-total & Grand-total, and
   the chart-type menu — portal to body inside `.e-menu-popup`, a DIFFERENT structure from the
   `ul.e-contextmenu` themed above. The popup surface already inherited the dark variable, but
   Syncfusion's light default left the menu-item text near-black (rgb 36,36,36), i.e. invisible on
   the dark surface. Theme the popup surface and its items with the hoisted vars (right in light
   AND dark). Scoped to `.e-menu-popup` so the pivot toolbar's own inline menu bars are untouched. */
body .e-menu-popup,
body .e-menu-container.e-menu-popup,
body .e-contextmenu-container.e-menu-popup {
    background: var(--backoffice-syncfusion-surface) !important;
    border-color: var(--backoffice-syncfusion-border) !important;
    color: var(--backoffice-syncfusion-text) !important;
}

body .e-menu-popup .e-menu-item,
body .e-menu-popup .e-menu-item .e-caret,
body .e-menu-popup .e-menu-item .e-menu-icon,
body .e-menu-popup .e-menu-item .e-menu-url {
    background: transparent !important;
    color: var(--backoffice-syncfusion-text) !important;
}

body .e-menu-popup .e-menu-item.e-focused,
body .e-menu-popup .e-menu-item.e-selected,
body .e-menu-popup .e-menu-item:hover {
    background: var(--backoffice-syncfusion-row-hover) !important;
    color: var(--backoffice-syncfusion-text) !important;
}

body .e-menu-popup .e-menu-item.e-disabled {
    color: var(--backoffice-syncfusion-muted) !important;
}

body .e-menu-popup .e-separator {
    border-color: var(--backoffice-syncfusion-border) !important;
}

/* The Number-Formatting and Conditional-Formatting dialogs open value-field / format-type /
   condition / font DROPDOWN LISTS whose popups portal to body separately as `.e-ddl.e-popup`
   (the dialog frame itself is already covered by the `.e-dialog.e-popup` rules above), otherwise
   rendering Syncfusion's light list surface with near-black text. */
body .e-popup.e-ddl,
body .e-popup.e-ddl .e-list-parent,
body .e-popup.e-ddl .e-list-item {
    background: var(--backoffice-syncfusion-surface) !important;
    color: var(--backoffice-syncfusion-text) !important;
    border-color: var(--backoffice-syncfusion-border) !important;
}

body .e-popup.e-ddl .e-list-item.e-active,
body .e-popup.e-ddl .e-list-item.e-hover,
body .e-popup.e-ddl .e-list-item:hover {
    background: var(--backoffice-syncfusion-row-hover) !important;
    color: var(--backoffice-syncfusion-text) !important;
}

/* Conditional-formatting colour-picker popup surface. */
body .e-colorpicker-popup,
body .e-colorpicker-popup .e-container {
    background: var(--backoffice-syncfusion-surface) !important;
    color: var(--backoffice-syncfusion-text) !important;
    border-color: var(--backoffice-syncfusion-border) !important;
}

/* The chart-type menu popup ends with "Multiple Axis" / "Show legend" CHECKBOXES whose labels are
   not `.e-menu-item`s, so the menu-item rule above missed them and they stayed Syncfusion's dim
   default on the dark popup. Theme the checkbox label + frame with the hoisted variables. */
body .e-menu-popup .e-checkbox-wrapper .e-label,
body .e-menu-popup .e-checkbox-wrapper .e-checkbox {
    color: var(--backoffice-syncfusion-text) !important;
}

body .e-menu-popup .e-checkbox-wrapper .e-frame {
    background: var(--backoffice-syncfusion-input-background) !important;
    border-color: var(--backoffice-syncfusion-input-border) !important;
}

body .e-menu-popup .e-checkbox-wrapper .e-frame.e-check {
    background: var(--backoffice-syncfusion-accent) !important;
    border-color: var(--backoffice-syncfusion-accent) !important;
    color: #fff !important;
}

/* ── Syncfusion pivot view (dataset Analyze tab) ──────────────────────────
   The pivot's internal grid already inherits the .sf-grid.e-grid rules above;
   these cover the pivot-specific chrome: toolbar, grouping bar, field chips,
   the field list (inline and dialog), and the chart-type menu. Field list and
   menus portal to body, so they use the hoisted theme variables. */
.backoffice-theme-host .e-pivotview,
.backoffice-theme-host .e-pivotview .e-pivot-toolbar,
.backoffice-theme-host .e-pivotview .e-pivot-toolbar .e-toolbar-items,
.backoffice-theme-host .e-pivotview .e-pivot-toolbar .e-toolbar-item,
.backoffice-theme-host .e-pivotview .e-grouping-bar,
.backoffice-theme-host .e-pivotview .e-axis-container,
.backoffice-theme-host .e-pivotview .e-group-rows,
.backoffice-theme-host .e-pivotview .e-group-columns,
.backoffice-theme-host .e-pivotview .e-group-values,
.backoffice-theme-host .e-pivotview .e-group-filters {
    background: var(--backoffice-syncfusion-header) !important;
    color: var(--backoffice-syncfusion-text) !important;
    border-color: var(--backoffice-syncfusion-border) !important;
}

/* Several toolbar controls (Chart type, Sub-total, Grand-total, Export) are Syncfusion `.e-menu`s,
   not plain buttons, so their icons/carets keep Syncfusion's own dark rgb(66,66,66) glyph colour
   instead of inheriting the toolbar's text colour — on the dark toolbar they looked greyed-out /
   disabled next to the plain buttons. Colour the inline toolbar menu icons like the rest. */
.backoffice-theme-host .e-pivotview .e-pivot-toolbar .e-menu .e-menu-item,
.backoffice-theme-host .e-pivotview .e-pivot-toolbar .e-menu .e-menu-item .e-menu-icon,
.backoffice-theme-host .e-pivotview .e-pivot-toolbar .e-menu .e-menu-item .e-caret {
    color: var(--backoffice-syncfusion-text) !important;
}

/* PivotView renders its result grid without the `.sf-grid` marker used by the
   reusable dataset grids above. Theme that internal grid explicitly so the
   matrix never falls back to Syncfusion's light surfaces in dark mode. */
.backoffice-theme-host .e-pivotview .e-grid,
.backoffice-theme-host .e-pivotview .e-grid .e-gridheader,
.backoffice-theme-host .e-pivotview .e-grid .e-headercontent,
.backoffice-theme-host .e-pivotview .e-grid .e-gridcontent,
.backoffice-theme-host .e-pivotview .e-grid .e-content,
.backoffice-theme-host .e-pivotview .e-grid .e-table {
    background: var(--backoffice-syncfusion-surface) !important;
    color: var(--backoffice-syncfusion-text) !important;
    border-color: var(--backoffice-syncfusion-border) !important;
}

.backoffice-theme-host .e-pivotview .e-grid .e-headercell,
.backoffice-theme-host .e-pivotview .e-grid .e-columnsheader,
.backoffice-theme-host .e-pivotview .e-grid .e-rowsheader {
    background: var(--backoffice-syncfusion-header) !important;
    color: var(--backoffice-syncfusion-text) !important;
    border-color: var(--backoffice-syncfusion-border) !important;
}

.backoffice-theme-host .e-pivotview .e-grid .e-row,
.backoffice-theme-host .e-pivotview .e-grid .e-altrow,
.backoffice-theme-host .e-pivotview .e-grid .e-rowcell,
.backoffice-theme-host .e-pivotview .e-grid .e-valuescontent {
    background: var(--backoffice-syncfusion-surface) !important;
    color: var(--backoffice-syncfusion-text) !important;
    border-color: var(--backoffice-syncfusion-border) !important;
}

/* The grouping-bar drop-zone containers hardcode a light rgb(224,224,224) 1px border that is not
   theme-aware, so in dark mode they drew harsh bright-white lines around the row/column/value/filter
   drop areas. Re-border with the theme variable (subtle in both light and dark). */
.backoffice-theme-host .e-pivotview .e-left-axis-fields,
.backoffice-theme-host .e-pivotview .e-right-axis-fields,
.backoffice-theme-host .e-pivotview .e-axis-table,
.backoffice-theme-host .e-pivotview .e-axis-table td,
.backoffice-theme-host .e-pivotview .e-group-row,
.backoffice-theme-host .e-pivotview .e-group-rows,
.backoffice-theme-host .e-pivotview .e-group-columns,
.backoffice-theme-host .e-pivotview .e-group-values,
.backoffice-theme-host .e-pivotview .e-group-filters {
    border-color: var(--backoffice-syncfusion-border) !important;
}

.backoffice-theme-host .e-pivotview .e-grid .e-gtot,
.backoffice-theme-host .e-pivotview .e-grid .e-stot,
.backoffice-theme-host .e-pivotview .e-grid .e-summarycell {
    background: var(--backoffice-syncfusion-surface-alt) !important;
    color: var(--backoffice-syncfusion-text) !important;
    border-color: var(--backoffice-syncfusion-border) !important;
    font-weight: 750;
}

.backoffice-theme-host .e-pivotview .e-grid .e-row:hover .e-rowcell,
.backoffice-theme-host .e-pivotview .e-grid .e-row:hover .e-valuescontent,
.backoffice-theme-host .e-pivotview .e-grid .e-cellselectionbackground,
.backoffice-theme-host .e-pivotview .e-grid .e-selectionbackground {
    background: var(--backoffice-syncfusion-row-hover) !important;
    color: var(--backoffice-syncfusion-text) !important;
}

/* Caret injected onto composite value pills (see analyze-pivot.js
   attachCalculatedMeasureMenus). Syncfusion draws no value-type dropdown on a calculated field, so
   this is the only aggregation affordance those chips have. Sized to sit with Syncfusion's own
   pill icons rather than to stand out. */
.backoffice-theme-host .e-pivotview .e-pivot-button .caducore-agg-menu {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.25rem;
    min-width: 1.25rem;
    height: 100%;
    margin-left: 0.125rem;
    cursor: pointer;
    font-size: 0.75rem;
    line-height: 1;
    color: var(--backoffice-syncfusion-text) !important;
    opacity: 0.85;
}

.backoffice-theme-host .e-pivotview .e-pivot-button .caducore-agg-menu:hover {
    opacity: 1;
    background: var(--backoffice-syncfusion-row-hover) !important;
    border-radius: 2px;
}

/* ── Analyze drill-through dialog ─────────────────────────────────────────
   The row list is virtualized over the WHOLE result (see AnalyzeDrillThroughDialog), which only
   works if two things hold. First, the scroll container must be this element and nothing between it
   and the rows may also scroll — Virtualize measures the nearest scrollable ancestor, and an
   intermediate one makes it size against the wrong viewport and render a handful of rows into a
   tall empty scroll extent. Second, every row must be exactly ItemSize tall, or the spacer maths
   and the real content drift apart; hence the fixed height and the clip-don't-wrap cells. */
.analyze-drillthrough-scroll {
    height: 60vh;
    max-height: 60vh;
    overflow: auto;
    border: 1px solid var(--backoffice-syncfusion-border);
    border-radius: 4px;
}

.analyze-drillthrough-table {
    width: 100%;
    border-collapse: collapse;
    table-layout: auto;
}

.analyze-drillthrough-table thead th {
    position: sticky;
    top: 0;
    z-index: 1;
    background: var(--backoffice-syncfusion-header);
    color: var(--backoffice-syncfusion-text);
    text-align: left;
    font-weight: 600;
    white-space: nowrap;
    padding: 0 0.75rem;
    height: 33px;
    border-bottom: 1px solid var(--backoffice-syncfusion-border);
}

.analyze-drillthrough-table tbody tr.analyze-drillthrough-row {
    height: 33px;
    max-height: 33px;
}

.analyze-drillthrough-table tbody td {
    height: 33px;
    max-width: 18rem;
    padding: 0 0.75rem;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    color: var(--backoffice-syncfusion-text);
    border-bottom: 1px solid var(--backoffice-syncfusion-border);
}

.analyze-drillthrough-table tbody tr:nth-child(even) td {
    background: var(--backoffice-syncfusion-surface-alt);
}

.analyze-drillthrough-placeholder td {
    color: var(--backoffice-syncfusion-muted);
}

/* ── Frozen row-header column ─────────────────────────────────────────────
   The pivot pins the row-header cells (.e-leftfreeze) while the value cells scroll horizontally
   UNDERNEATH them. That only reads correctly if those cells are fully opaque — and the theme's
   row-hover / selection colours are deliberately translucent (rgba(...,0.12)), which is fine for
   an ordinary row sitting on a solid surface and wrong here: hovering a row made the scrolled
   numbers show straight through its row header, so a row rendered as "0,64Bitcoin". Measured live:
   the frozen cell's computed background was rgba(105,185,230,0.12).
   These rules restate the same colours pre-flattened against the surface, so the hover still reads
   as a hover but nothing shows through. Listed after the generic row/hover rules on purpose —
   equal specificity, later wins. */
.backoffice-theme-host .e-pivotview .e-grid .e-leftfreeze,
.backoffice-theme-host .e-pivotview .e-grid .e-rowsheader.e-leftfreeze {
    background-color: var(--backoffice-syncfusion-frozen) !important;
}

.backoffice-theme-host .e-pivotview .e-grid .e-row:hover .e-leftfreeze,
.backoffice-theme-host .e-pivotview .e-grid .e-leftfreeze.e-selectionbackground,
.backoffice-theme-host .e-pivotview .e-grid .e-leftfreeze.e-cellselectionbackground,
.backoffice-theme-host .e-pivotview .e-grid .e-leftfreeze.e-active {
    background-color: var(--backoffice-syncfusion-frozen-hover) !important;
}

.backoffice-theme-host .e-pivotview .e-grid .e-headertext,
.backoffice-theme-host .e-pivotview .e-grid .e-cellvalue,
.backoffice-theme-host .e-pivotview .e-grid .e-icons {
    color: var(--backoffice-syncfusion-text) !important;
}

.backoffice-theme-host .e-pivotview .e-pivot-toolbar .e-tbar-btn,
.backoffice-theme-host .e-pivotview .e-pivot-toolbar .e-tbar-btn .e-tbar-btn-text,
.backoffice-theme-host .e-pivotview .e-pivot-toolbar .e-tbar-btn .e-icons,
.backoffice-theme-host .e-pivotview .e-pivot-toolbar .e-menu-wrapper,
.backoffice-theme-host .e-pivotview .e-pivot-toolbar .e-menu-wrapper ul,
.backoffice-theme-host .e-pivotview .e-pivot-toolbar .e-menu-wrapper .e-menu-item,
.backoffice-theme-host .e-pivotview .e-pivot-toolbar .e-menu-wrapper .e-menu-item .e-icons {
    background: transparent !important;
    color: var(--backoffice-syncfusion-text) !important;
}

.backoffice-theme-host .e-pivotview .e-pivot-toolbar .e-tbar-btn:hover,
.backoffice-theme-host .e-pivotview .e-pivot-toolbar .e-tbar-btn:focus,
.backoffice-theme-host .e-pivotview .e-pivot-toolbar .e-menu-wrapper .e-menu-item.e-focused,
/* .e-selected is applied to the chart-menu anchor while its popup is open —
   the stock theme fills it light-gray, which clashes on the dark toolbar. */
.backoffice-theme-host .e-pivotview .e-pivot-toolbar .e-menu-wrapper .e-menu-item.e-selected {
    background: var(--backoffice-syncfusion-row-hover) !important;
    color: var(--backoffice-syncfusion-text) !important;
}

/* Grouping-bar / field-list chips ("producttype", "Sum of productprice", …). */
.backoffice-theme-host .e-pivotview .e-pivot-button,
body .e-pivotfieldlist-container .e-pivot-button {
    background: var(--backoffice-syncfusion-surface-alt) !important;
    color: var(--backoffice-syncfusion-text) !important;
    border: 1px solid var(--backoffice-syncfusion-border) !important;
}

.backoffice-theme-host .e-pivotview .e-pivot-button .e-pvt-btn-content,
.backoffice-theme-host .e-pivotview .e-pivot-button .e-icons,
body .e-pivotfieldlist-container .e-pivot-button .e-pvt-btn-content,
body .e-pivotfieldlist-container .e-pivot-button .e-icons {
    background: transparent !important;
    color: var(--backoffice-syncfusion-text) !important;
}

.backoffice-theme-host .e-pivotview .e-pivot-button:hover,
body .e-pivotfieldlist-container .e-pivot-button:hover {
    background: var(--backoffice-syncfusion-row-hover) !important;
}

/* Drop-target prompts ("Drop filter here", …). */
.backoffice-theme-host .e-pivotview .e-draggable-prompt,
.backoffice-theme-host .e-pivotview .e-drop-indicator,
body .e-pivotfieldlist-container .e-draggable-prompt {
    color: var(--backoffice-syncfusion-muted) !important;
}

/* Field list — both the inline panel and the "Field List" dialog share these
   classes; the dialog frame itself is themed by the generic e-dialog rules. */
body .e-pivotfieldlist-container .e-field-header-container,
body .e-pivotfieldlist-container .e-field-header,
body .e-pivotfieldlist-container .e-field-table,
body .e-pivotfieldlist-container .e-field-list-container,
body .e-pivotfieldlist-container .e-axis-table,
body .e-pivotfieldlist-container .e-axis-container,
body .e-pivotfieldlist-container .e-field-list-rows,
body .e-pivotfieldlist-container .e-field-list-columns,
body .e-pivotfieldlist-container .e-field-list-values,
body .e-pivotfieldlist-container .e-field-list-filters,
body .e-pivotfieldlist-container .e-treeview,
body .e-pivotfieldlist-container .e-treeview .e-list-item,
body .e-pivotfieldlist-container .e-treeview .e-text-content {
    background: var(--backoffice-syncfusion-surface) !important;
    color: var(--backoffice-syncfusion-text) !important;
    border-color: var(--backoffice-syncfusion-border) !important;
}

body .e-pivotfieldlist-container .e-field-header,
body .e-pivotfieldlist-container .e-axis-header,
body .e-pivotfieldlist-container .e-treeview .e-list-text,
body .e-pivotfieldlist-container .e-sort-ascend-icon,
body .e-pivotfieldlist-container .e-sort-descend-icon,
body .e-pivotfieldlist-container .e-icons {
    color: var(--backoffice-syncfusion-text) !important;
}

body .e-pivotfieldlist-container .e-treeview .e-list-item.e-hover > .e-fullrow,
body .e-pivotfieldlist-container .e-treeview .e-list-item.e-active > .e-fullrow {
    background: var(--backoffice-syncfusion-row-hover) !important;
    border-color: transparent !important;
}

/* Unchecked field checkboxes; checked keep the accent fill below. */
body .e-pivotfieldlist-container .e-checkbox-wrapper .e-frame,
.backoffice-theme-host .e-pivotview .e-checkbox-wrapper .e-frame {
    background: var(--backoffice-syncfusion-input-background) !important;
    border-color: var(--backoffice-syncfusion-input-border) !important;
    color: var(--backoffice-syncfusion-text) !important;
}

body .e-pivotfieldlist-container .e-checkbox-wrapper .e-frame.e-check,
.backoffice-theme-host .e-pivotview .e-checkbox-wrapper .e-frame.e-check {
    background: var(--backoffice-syncfusion-accent) !important;
    border-color: var(--backoffice-syncfusion-accent) !important;
    color: var(--backoffice-syncfusion-surface) !important;
}

/* ── Member-filter (checkbox) editor dialog ───────────────────────────────
   The pivot member editor portals to body as an .e-member-editor-dialog wrapping an
   .e-member-editor-outer-container. The generic dialog block above themes the frame; these
   cover the member list. IMPORTANT: each member's text lives in a `.e-list-text` span that
   Syncfusion hard-codes to a near-black color (rgb(36,36,36)) — invisible on the dark
   surface. Force the bright text color there (and on the "(All)" node) so members are legible. */
body .e-member-editor-dialog,
body .e-member-editor-dialog .e-dlg-content,
body .e-member-editor-outer-container,
body .e-member-editor-container {
    background: var(--backoffice-syncfusion-surface) !important;
    color: var(--backoffice-syncfusion-text) !important;
    border-color: var(--backoffice-syncfusion-border) !important;
}

body .e-member-editor-dialog .e-list-item,
body .e-member-editor-dialog .e-list-item .e-list-text,
body .e-member-editor-dialog .e-text-content,
body .e-member-editor-dialog .e-checkbox-wrapper .e-label {
    color: var(--backoffice-syncfusion-text) !important;
    background: transparent !important;
}

body .e-member-editor-dialog .e-list-item.e-hover,
body .e-member-editor-dialog .e-list-item.e-hover .e-fullrow {
    background: var(--backoffice-syncfusion-row-hover) !important;
}

/* Focused / active / keyboard-navigated member row. Syncfusion paints these states with a
   light theme background (a near-white .e-fullrow) that is unreadable on the dark surface — the
   .e-hover rule above did not cover .e-node-focus / .e-active. Theme all of them to the dark
   hover surface and keep the text bright. (This is the "select a value -> white background"
   member-filter bug.) */
body .e-member-editor-dialog .e-list-item.e-node-focus,
body .e-member-editor-dialog .e-list-item.e-node-focus > .e-fullrow,
body .e-member-editor-dialog .e-list-item.e-active,
body .e-member-editor-dialog .e-list-item.e-active > .e-fullrow,
body .e-member-editor-dialog .e-list-item.e-hover > .e-fullrow {
    background: var(--backoffice-syncfusion-row-hover) !important;
    border-color: transparent !important;
}
body .e-member-editor-dialog .e-list-item.e-node-focus .e-list-text,
body .e-member-editor-dialog .e-list-item.e-active .e-list-text {
    color: var(--backoffice-syncfusion-text) !important;
}

/* ── Analyze pivot: mandatory deferred layout ─────────────────────────────
   Deferred layout update is enforced: a live re-query on every field tick would re-mount the
   pivot and close the field list mid-edit, and each tick would hit the backend. Hide the field
   list's "Defer Layout Update" checkbox so it can't be turned off. It defaults to checked, so
   hiding its wrapper locks defer ON. The wrapper (.e-checkbox-layout) holds only that checkbox;
   the Apply/Cancel buttons live elsewhere in the footer and stay visible. */
.e-checkbox-layout:has(input[id$="PivotFieldListDeferUpdateCheckBox"]) {
    display: none !important;
}

/* ── Analyze pivot: Field List as a centered modal ────────────────────────
   By default the Field List opens as a small (~300px wide, max-height 550px) NON-modal popup
   absolutely positioned against the pivot, so the page has to scroll to it and the drop zones
   are too cramped to use. Re-frame it as a centered, roomy dialog that matches the app's other
   (MudBlazor) modals. Syncfusion writes the popup's top/left/width as inline styles (not
   !important), so these override the anchored placement, and a full-viewport box-shadow ring
   fakes the backdrop the non-modal popup otherwise lacks. */
body .e-dialog.e-pivotfieldlist-container.e-popup {
    position: fixed !important;
    /* Wide, TALL, and centred on BOTH axes — transform-free (a transform breaks the field list's
       drag hit-testing). Values below were derived by live-measuring the open dialog, not guessed:
       - Centring uses viewport units, NOT inset:0+margin:auto. A transformed ancestor makes the
         fixed containing block taller than the viewport, so margin:auto centred it far too low;
         `top: calc(50vh - height/2)` is viewport-relative and reliable (height is 620 -> 310).
         Horizontal centring is left:50% + a negative half-width margin.
       - Height is a DEFINITE 620px (capped 88vh) so it is genuinely tall; the internal regions are
         grown to fill it via min-height (below) — NOT flex overrides, which collapse the 2x2 grid.
       Syncfusion writes top/left/width/height as non-!important inline styles, so these win. */
    top: max(2vh, calc(50vh - 310px)) !important;
    left: 50% !important;
    right: auto !important;
    bottom: auto !important;
    margin: 0 0 0 calc(min(1040px, 94vw) / -2) !important;
    transform: none !important;
    width: min(1040px, 94vw) !important;
    max-width: 94vw !important;
    height: min(620px, 88vh) !important;
    max-height: 88vh !important;
    z-index: 1401 !important;
    box-shadow: 0 0 0 100vmax rgba(0, 0, 0, 0.5), 0 24px 60px rgba(0, 0, 0, 0.55) !important;
}

/* Make the tree AND the four drop zones (incl. their actual .e-axis-content droppables) FILL the
   tall dialog via a flex chain, so there is no dead space and the drop targets are large. Earlier
   `min-height` only grew the zone WRAPPERS — the inner .e-axis-content droppable stayed ~133px with
   empty space below it. The chain below flexes every level to fill. CRITICAL: it never sets
   `.e-axis-table { flex-direction }` (that is what collapses the native 2x2 grid) — it only sets
   height:auto on it and flexes the columns/zones INSIDE. Live-verified: dialog 620px, content fills
   header(80)+content(476)+footer(62), droppables ~198px, tree ~442px, 2x2 intact, ~11px slack above
   the footer. See Tasks/TELEMETRY_AND_FIELDLIST_DRAG_PLAN.txt. */
body .e-dialog.e-pivotfieldlist-container.e-popup > .e-dlg-content {
    height: 100% !important;
    max-height: none !important;
    box-sizing: border-box !important;
}
body .e-dialog.e-pivotfieldlist-container.e-popup .e-field-list-container {
    height: 100% !important;
    align-items: stretch !important;
}
body .e-dialog.e-pivotfieldlist-container.e-popup .e-field-table {
    display: flex !important;
    flex-direction: column !important;
    height: auto !important;
    min-height: 0 !important;
}
body .e-dialog.e-pivotfieldlist-container.e-popup .e-field-list-tree-outer-div {
    flex: 1 1 auto !important;
    min-height: 0 !important;
    height: auto !important;
}
/* height:auto only — NEVER flex-direction here (that collapses the 2x2). */
body .e-dialog.e-pivotfieldlist-container.e-popup .e-axis-table {
    height: auto !important;
}
body .e-dialog.e-pivotfieldlist-container.e-popup .e-left-axis-fields,
body .e-dialog.e-pivotfieldlist-container.e-popup .e-right-axis-fields {
    display: flex !important;
    flex-direction: column !important;
    height: auto !important;
    min-height: 0 !important;
}
body .e-dialog.e-pivotfieldlist-container.e-popup .e-field-list-filters,
body .e-dialog.e-pivotfieldlist-container.e-popup .e-field-list-rows,
body .e-dialog.e-pivotfieldlist-container.e-popup .e-field-list-columns,
body .e-dialog.e-pivotfieldlist-container.e-popup .e-field-list-values {
    flex: 1 1 0 !important;
    min-height: 0 !important;
    display: flex !important;
    flex-direction: column !important;
}
body .e-dialog.e-pivotfieldlist-container.e-popup .e-axis-content {
    flex: 1 1 auto !important;
    min-height: 0 !important;
    height: auto !important;
}

/* Hide the internal additive helper columns (…__sum / __cnt / __sq) that back the composite
   Average/Variance/Std-Dev calculated fields. They must remain in the data source so the calc
   fields can reference them (Syncfusion's ExcludeFields would strip them from the ENGINE and blank
   the calc fields), so they are hidden from the field-list tree here instead — the tree node's
   data-uid is the field key. The visible measure keys (…__avg / __var_pop / __stddev_pop) never
   contain these stems, so they stay visible and pickable. */
body .e-pivotfieldlist-container .e-list-item[data-uid*="__sum"],
body .e-pivotfieldlist-container .e-list-item[data-uid*="__cnt"],
body .e-pivotfieldlist-container .e-list-item[data-uid*="__sq"] {
    display: none !important;
}

/* Remove the member-filter (funnel) control from the Field List dialog's drop-zone pills ONLY.
   Filtering a field there hits the "draft" state — the field isn't in a query yet, so the member
   editor shows only "All" + an empty entry — and it is the surface that triggered the Syncfusion
   select-all exception. Member filtering is KEPT on the MAIN pivot grouping-bar pills (those live
   outside .e-pivotfieldlist-container, so they are unaffected) where the members are actually
   loaded. AllowMemberFilter stays true. Scoped to the field-list container so only the 2x2 loses
   the funnel. (.e-btn-filter is Syncfusion's pivot-button filter icon; the title fallback covers
   markup variations.) */
body .e-pivotfieldlist-container .e-pivot-button .e-btn-filter,
body .e-pivotfieldlist-container .e-pivot-button [title="Filter" i] {
    display: none !important;
}

/* Checkbox frames inside the member editor (unchecked, checked, and tri-state). */
body .e-member-editor-dialog .e-checkbox-wrapper .e-frame {
    background: var(--backoffice-syncfusion-input-background) !important;
    border-color: var(--backoffice-syncfusion-input-border) !important;
}

body .e-member-editor-dialog .e-checkbox-wrapper .e-frame.e-check,
body .e-member-editor-dialog .e-checkbox-wrapper .e-frame.e-stop {
    background: var(--backoffice-syncfusion-accent) !important;
    border-color: var(--backoffice-syncfusion-accent) !important;
    color: var(--backoffice-syncfusion-surface) !important;
}

/* Member editor search box + "no matches" text. */
body .e-member-editor-dialog .e-input-group,
body .e-member-editor-dialog input.e-input {
    background: var(--backoffice-syncfusion-input-background) !important;
    border-color: var(--backoffice-syncfusion-input-border) !important;
    color: var(--backoffice-syncfusion-text) !important;
}

/* .e-editor-label-wrapper was dropped here: it does not exist in Syncfusion 31 or 34 (verified
   against both packages). The member editor's real containers are .e-member-editor-dialog /
   .e-member-editor-outer-container, already themed above. */
body .e-member-editor-dialog .e-nodata {
    color: var(--backoffice-syncfusion-muted) !important;
}

/* Secondary ("Cancel"/default) buttons inside Syncfusion popups keep the vendor's light-theme
   styling — white background with near-black text — which reads as a bright blob next to the
   themed primary button in dark mode. Theme them from the hoisted variables (so this is correct in
   BOTH themes); .e-primary is deliberately untouched so the accent button keeps its emphasis. */
body .e-dialog .e-footer-content .e-btn:not(.e-primary),
body .e-member-editor-dialog .e-footer-content .e-btn:not(.e-primary),
body .e-pivotfieldlist-container .e-btn:not(.e-primary) {
    background: var(--backoffice-syncfusion-surface-alt) !important;
    color: var(--backoffice-syncfusion-text) !important;
    border-color: var(--backoffice-syncfusion-input-border) !important;
}

body .e-dialog .e-footer-content .e-btn:not(.e-primary):hover,
body .e-member-editor-dialog .e-footer-content .e-btn:not(.e-primary):hover,
body .e-pivotfieldlist-container .e-btn:not(.e-primary):hover {
    background: var(--backoffice-syncfusion-row-hover) !important;
}

/* Chart-type menu and other pivot menus portal to body as .e-menu-popup. */
body .e-menu-popup,
body .e-menu-popup ul.e-menu-parent,
body .e-menu-popup .e-menu-item {
    background: var(--backoffice-syncfusion-surface) !important;
    color: var(--backoffice-syncfusion-text) !important;
    border-color: var(--backoffice-syncfusion-border) !important;
}

body .e-menu-popup .e-menu-item .e-caret,
body .e-menu-popup .e-menu-item .e-menu-icon {
    color: var(--backoffice-syncfusion-text) !important;
}

body .e-menu-popup .e-menu-item.e-focused,
body .e-menu-popup .e-menu-item:hover {
    background: var(--backoffice-syncfusion-row-hover) !important;
}

body .e-menu-popup .e-menu-item.e-selected {
    background: var(--backoffice-syncfusion-accent-soft) !important;
    color: var(--backoffice-syncfusion-text) !important;
}

/* Pivot chart renders into an SVG with its own text fills; keep axis, legend,
   and title text readable on the themed surface. Series/point labels keep
   their computed colors. */
.backoffice-theme-host .e-pivotview svg text[id*="AxisLabel"],
.backoffice-theme-host .e-pivotview svg text[id*="AxisTitle"],
.backoffice-theme-host .e-pivotview svg text[id*="legend_text"],
.backoffice-theme-host .e-pivotview svg text[id*="chart_title"] {
    fill: var(--backoffice-syncfusion-text) !important;
}

.backoffice-theme-host .e-pivotview svg rect[id$="_ChartBorder"] {
    fill: transparent !important;
}

.dashboard-state,
.dashboard-empty {
    min-height: 18rem;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0.75rem;
    text-align: center;
}

.dashboard-actions-cell {
    width: 13rem;
    text-align: right;
    white-space: nowrap;
}

.dashboard-dialog-shell {
    display: grid;
    gap: 1rem;
    min-width: min(32rem, 80vw);
}

.dashboard-dialog-tab-panel {
    padding: 1rem 0 0;
}

.dashboard-view-shell {
    display: grid;
    gap: 1.25rem;
}

.dashboard-view-header {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 1rem;
}

.dashboard-view-kicker {
    display: block;
    color: var(--mud-palette-primary);
    font-size: 0.8rem;
    font-weight: 800;
    text-transform: uppercase;
}

.dashboard-view-header h1 {
    margin: 0.15rem 0 0.25rem;
    font-size: clamp(1.8rem, 3vw, 2.8rem);
}

.dashboard-view-header p {
    margin: 0;
    color: color-mix(in srgb, currentColor 72%, transparent);
}

.dashboard-view-actions {
    display: flex;
    flex-wrap: wrap;
    justify-content: flex-end;
    gap: 0.5rem;
}

.dashboard-filter-bar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.75rem;
}

.dashboard-filter-dialog {
    height: min(70vh, 42rem);
    width: 100%;
    display: flex;
    overflow: hidden;
    background: var(--mud-palette-background-grey);
}

.dashboard-filter-dialog-nav {
    width: 14rem;
    flex: 0 0 14rem;
    border-right: 1px solid var(--mud-palette-divider);
    overflow-y: auto;
    background: var(--mud-palette-background);
    padding: 0.5rem 0;
}

.dashboard-filter-dialog-content {
    flex: 1 1 auto;
    min-width: 0;
    overflow-y: auto;
    background: var(--mud-palette-background);
    padding: 1rem;
}

.dashboard-visual-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 1rem;
}

/* ════════════════════════════════════════════════════════════════════
   Dashboard view canvas
   View mode uses the SAME positioning math as the layout editor
   (DashboardGridGeometry) so a saved layout renders pixel-identical in
   both pages. No Syncfusion: every panel is an absolutely positioned div
   inside a position:relative canvas.
   ════════════════════════════════════════════════════════════════════ */
.dashboard-view-canvas-wrapper {
    width: 100%;
    min-width: 0;
}

.dashboard-view-canvas {
    position: relative;
    width: 100%;
    min-width: 0;
    box-sizing: border-box;
}

.dashboard-view-panel {
    position: absolute;
    box-sizing: border-box;
    overflow: hidden;
}

.dashboard-view-empty {
    width: 100%;
    min-height: 20rem;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    opacity: 0.5;
}

/* ════════════════════════════════════════════════════════════════════
   Custom Dashboard Layout Editor
   Dedicated page – no Syncfusion, no class collisions with the view-mode
   styles. All selectors are scoped under .layout-editor-*.
   ════════════════════════════════════════════════════════════════════ */

.layout-editor-shell {
    display: flex;
    flex-direction: column;
    gap: 1rem;
    padding: 1.5rem 2rem 3rem;
    max-width: 100%;
    min-width: 0;
}

.layout-editor-header {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 1rem;
    flex-wrap: wrap;
}

.layout-editor-header h1 {
    margin: 0.2rem 0 0.2rem;
    font-size: 1.55rem;
    font-weight: 700;
}

.layout-editor-header p {
    margin: 0;
    opacity: 0.7;
    font-size: 0.85rem;
}

.layout-editor-kicker {
    text-transform: uppercase;
    font-size: 0.7rem;
    letter-spacing: 0.08em;
    opacity: 0.6;
    font-weight: 600;
}

.layout-editor-actions {
    display: flex;
    gap: 0.5rem;
    align-items: center;
}

.layout-editor-canvas-wrapper {
    width: 100%;
    min-width: 0;
}

/* The canvas is a position:relative container; every panel inside is
   absolutely positioned with percentages for left/width (responsive)
   and pixels for top/height (predictable row sizing). */
.layout-editor-canvas {
    position: relative;
    width: 100%;
    min-width: 0;
    background: transparent;
    box-shadow: inset 0 0 0 1px rgba(128, 128, 128, 0.22);
    border-radius: 8px;
    box-sizing: border-box;
    user-select: none;
}

/* Faint dashed column guides so the grid is legible */
.layout-editor-grid-col {
    position: absolute;
    border-left: 1px dashed rgba(128, 128, 128, 0.18);
    border-right: 1px dashed rgba(128, 128, 128, 0.18);
    pointer-events: none;
    z-index: 0;
}

/* Each chart panel: absolute positioning controlled inline by C#.
   No transforms, no transitions on layout properties — JS sets pixel
   values directly during drag/resize. */
/* No header strip — the whole panel body is the drag handle. */
.layout-editor-panel {
    position: absolute;
    background: transparent;
    border: 1px solid rgba(128, 128, 128, 0.35);
    border-radius: 6px;
    overflow: hidden;
    box-sizing: border-box;
    z-index: 1;
}

.layout-editor-panel:hover {
    border-color: rgba(128, 128, 128, 0.7);
}

.layout-editor-panel-dragging,
.layout-editor-panel-resizing {
    border-color: rgba(128, 128, 128, 0.95) !important;
    box-shadow: 0 6px 18px rgba(0, 0, 0, 0.18);
    opacity: 0.95;
    pointer-events: none; /* let the global JS listeners own the mouse */
}

.layout-editor-panel-body {
    position: absolute;
    inset: 0;
    overflow: hidden;
}

/* Transparent overlay above the chart that captures all pointer events.
   This serves two purposes: it stops the chart from receiving tooltips/clicks
   during layout editing, and it makes the entire panel face a drag handle. */
.layout-editor-panel-body-blocker {
    position: absolute;
    inset: 0;
    z-index: 10;
    cursor: grab;
    background: transparent;
}

.layout-editor-panel-body-blocker:active {
    cursor: grabbing;
}

/* Resize handle in bottom-right corner */
.layout-editor-panel-resize {
    position: absolute;
    right: 0;
    bottom: 0;
    width: 16px;
    height: 16px;
    cursor: nwse-resize;
    background:
        linear-gradient(
            135deg,
            transparent 0%,
            transparent 50%,
            rgba(128, 128, 128, 0.55) 50%,
            rgba(128, 128, 128, 0.55) 60%,
            transparent 60%,
            transparent 70%,
            rgba(128, 128, 128, 0.55) 70%,
            rgba(128, 128, 128, 0.55) 80%,
            transparent 80%
        );
    z-index: 20;
}

.layout-editor-panel-resize:hover {
    background-color: rgba(128, 128, 128, 0.15);
}

/* Snap-target preview shown during drag/resize. Hidden by default;
   JS adds .layout-editor-ghost-visible to reveal it. */
.layout-editor-ghost {
    position: absolute;
    display: none;
    border: 2px dashed rgba(128, 128, 128, 0.7);
    background: rgba(128, 128, 128, 0.10);
    border-radius: 6px;
    pointer-events: none;
    z-index: 50;
    box-sizing: border-box;
}

.layout-editor-ghost-visible {
    display: block;
}

.layout-editor-empty {
    position: absolute;
    inset: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    opacity: 0.5;
    pointer-events: none;
}

/* Global cursors while interacting so the cursor doesn't flicker
   when the mouse leaves the panel */
body.layout-editor-grabbing,
body.layout-editor-grabbing * {
    cursor: grabbing !important;
}

body.layout-editor-resizing,
body.layout-editor-resizing * {
    cursor: nwse-resize !important;
}

.caducore-gauge-tooltip {
    background: rgba(33, 33, 33, 0.92);
    color: #ffffff;
    padding: 6px 10px;
    border-radius: 4px;
    font-size: 12px;
    font-weight: 500;
    white-space: nowrap;
    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.25);
    pointer-events: none;
}

.dashboard-visual {
    position: relative;
    height: 100%;
    width: 100%;
    min-width: 0;
    display: flex;
    flex-direction: column;
    padding: 0;
    background: transparent;
    border: none;
    border-radius: 0;
    overflow: hidden;
    box-sizing: border-box;
}

.dashboard-visual-body {
    flex: 1 1 auto;
    min-width: 0;
    min-height: 0;
    width: 100%;
    display: flex;
    flex-direction: column;
    overflow: hidden;
}

.dashboard-visual-body > * {
    flex: 1 1 auto;
    min-width: 0;
    min-height: 0;
}

.dashboard-chart-host {
    min-width: 0;
    width: 100%;
    flex: 1 1 auto;
}

.dashboard-visual-card {
    grid-column: span 1;
}

.dashboard-visual-header {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 1rem;
}

.dashboard-visual-header span {
    color: var(--dashboard-accent);
    font-size: 0.75rem;
    font-weight: 800;
    text-transform: uppercase;
}

.dashboard-visual-header h2 {
    margin: 0.15rem 0 0;
    font-size: 1.05rem;
}

.dashboard-visual-header strong {
    color: var(--dashboard-accent);
    font-size: 1.6rem;
}

.dashboard-visual-actions {
    position: absolute;
    top: 0.35rem;
    right: 0.35rem;
    display: flex;
    align-items: center;
    gap: 0.15rem;
    padding: 0.15rem;
    border-radius: 999px;
    background: color-mix(in srgb, var(--mud-palette-surface) 85%, transparent);
    backdrop-filter: blur(4px);
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
    z-index: 10;
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.15s ease;
}

.dashboard-visual:hover .dashboard-visual-actions,
.dashboard-visual:focus-within .dashboard-visual-actions {
    opacity: 1;
    pointer-events: auto;
}

.dashboard-visual-loading {
    min-height: 11rem;
    display: grid;
    place-items: center;
}

.dashboard-card-figure {
    height: 11rem;
    display: grid;
    align-content: center;
    justify-items: center;
    gap: 0.35rem;
}

.dashboard-card-figure span {
    color: var(--dashboard-accent);
    font-size: 3rem;
    font-weight: 800;
}

.dashboard-card-figure small,
.dashboard-bar-column small {
    color: color-mix(in srgb, currentColor 62%, transparent);
}

.dashboard-bar-chart {
    height: 12rem;
    display: grid;
    grid-auto-flow: column;
    grid-auto-columns: 1fr;
    align-items: end;
    gap: 0.75rem;
    padding-top: 1rem;
}

.dashboard-bar-column {
    height: 100%;
    display: grid;
    grid-template-rows: 1fr auto;
    gap: 0.5rem;
    align-items: end;
    text-align: center;
}

.dashboard-bar-column span {
    display: block;
    min-height: 0.5rem;
    border-radius: 0.45rem 0.45rem 0 0;
    background: var(--dashboard-accent);
}

.dashboard-line-chart {
    width: 100%;
    height: 12rem;
    margin-top: 1rem;
}

.dashboard-line-chart polyline {
    fill: none;
    stroke: var(--dashboard-accent);
    stroke-width: 6;
    stroke-linecap: round;
    stroke-linejoin: round;
}

.dashboard-pie-chart {
    width: min(12rem, 80%);
    aspect-ratio: 1;
    border-radius: 50%;
    margin: 1.25rem auto 0;
    box-shadow: inset 0 0 0 1rem color-mix(in srgb, var(--mud-palette-surface) 96%, transparent);
}

.dashboard-pie-legend {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 0.45rem 0.75rem;
    margin-top: 1rem;
    color: color-mix(in srgb, currentColor 65%, transparent);
    font-size: 0.8rem;
}

@media (max-width: 900px) {
    .dashboard-filter-bar,
    .dashboard-visual-grid {
        grid-template-columns: 1fr;
    }

    .dashboard-view-header {
        flex-direction: column;
    }

    .dashboard-view-actions {
        justify-content: flex-start;
    }

    /* The filter editor's split-pane layout (nav + content) is too cramped
       on tablet — stack the nav above the content. */
    .dashboard-filter-dialog {
        flex-direction: column;
        height: auto;
        max-height: 80vh;
    }

    .dashboard-filter-dialog-nav {
        width: 100%;
        flex: 0 0 auto;
        max-height: 14rem;
        border-right: none;
        border-bottom: 1px solid var(--mud-palette-divider);
    }
}

/* ════════════════════════════════════════════════════════════════════
   Mobile (≤600px) — backoffice-wide
   Everything here is shared across pages: dialogs, dashboard view,
   layout editor, pagination chrome, and visualization-renderer
   action bars. Keep page-specific phone overrides in the page's
   scoped CSS, not here.
   ════════════════════════════════════════════════════════════════════ */
@media (max-width: 599.98px) {
    /* ── Dashboard header collapses tighter than the 900px breakpoint */
    .dashboard-view-header h1 {
        font-size: clamp(1.45rem, 6vw, 1.85rem);
    }

    .dashboard-view-header p {
        font-size: 0.88rem;
    }

    .dashboard-view-actions {
        width: 100%;
    }

    .dashboard-view-actions > * {
        flex: 1 1 auto;
    }

    /* ── Dashboard view canvas: panels stack vertically and become
       full-width so charts stay readable on a phone. The absolute
       positioning math from DashboardGridGeometry assumes ~12 columns
       of horizontal room, which doesn't make sense at this width. */
    .dashboard-view-canvas {
        height: auto !important;
        display: flex;
        flex-direction: column;
        gap: 0.75rem;
    }

    .dashboard-view-panel {
        position: static !important;
        width: 100% !important;
        left: 0 !important;
        top: 0 !important;
        height: auto !important;
        min-height: 18rem;
    }

    /* ── Layout editor: drag/resize is a desktop-class interaction
       (no touch support today). Make the toolbar usable but the
       canvas still works — the user can at least preview. */
    .layout-editor-shell {
        padding: 0.75rem 0.85rem 2rem;
        gap: 0.85rem;
    }

    .layout-editor-header {
        flex-direction: column;
        align-items: stretch;
        gap: 0.75rem;
    }

    .layout-editor-header h1 {
        font-size: 1.3rem;
    }

    .layout-editor-actions {
        width: 100%;
    }

    .layout-editor-actions > * {
        flex: 1 1 auto;
    }

    .layout-editor-canvas-editable {
        min-height: 24rem;
        padding: 4px;
    }

    /* ── Per-chart action bar in dashboard panels (fullscreen/download/
       edit/delete buttons). Reduce horizontal spacing so they don't
       crowd the chart on narrow panels. */
    .dashboard-visual-actions {
        gap: 0.1rem;
        padding: 0.2rem;
    }

    /* ── Pagination bar wraps onto a second row instead of scrolling */
    .dashboard-pagination-bar {
        flex-wrap: wrap;
    }
}

/* ════════════════════════════════════════════════════════════════════
   Dialog full-width on phones
   MudBlazor dialogs default to a centered box; on a 320–600px viewport
   that wastes horizontal pixels and the content gets cramped. Take the
   full width with a tiny side margin.
   ════════════════════════════════════════════════════════════════════ */
@media (max-width: 599.98px) {
    .mud-dialog-container .mud-dialog {
        width: calc(100vw - 1rem) !important;
        max-width: calc(100vw - 1rem) !important;
        min-width: 0 !important;
        margin: 0.5rem !important;
    }

    .mud-dialog-container .mud-dialog .mud-dialog-content {
        padding: 1rem 0.85rem;
    }

    .mud-dialog-container .mud-dialog .mud-dialog-actions {
        padding: 0.75rem 0.85rem;
        flex-wrap: wrap;
        gap: 0.4rem;
    }

    .mud-dialog-container .mud-dialog .mud-dialog-actions > * {
        flex: 1 1 auto;
    }

    /* Dialog content shells used across the app collapse their grid
       gaps so the form fields breathe in the smaller space. */
    .dynamic-dialog-shell {
        gap: 0.7rem;
    }

    .dynamic-dialog-actions-row {
        flex-direction: column;
        align-items: stretch;
        gap: 0.5rem;
    }

    .dynamic-dialog-actions-row > * {
        width: 100%;
    }

    /* ── Dashboard / chart dialogs: stack the fixed split-pane layouts ──
       These dialogs use inline pixel widths/heights for their nav+content
       split panes, so the overrides below need !important to win over the
       inline style. On a phone the nav drops above the content and both
       go full-width. */

    /* Chart type picker (categories sidebar + grid) */
    .chart-type-dialog-body {
        flex-direction: column !important;
        height: auto !important;
        max-height: 70vh;
        overflow-y: auto !important;
    }

    .chart-type-dialog-nav {
        width: 100% !important;
        border-right: none !important;
        border-bottom: 1px solid var(--mud-palette-divider) !important;
        max-height: 13rem;
    }

    /* Runtime global-filters editor (settings nav + content) */
    .dashboard-filter-dialog {
        flex-direction: column !important;
        height: auto !important;
        max-height: 78vh;
    }

    .dashboard-filter-dialog-nav {
        width: 100% !important;
        flex: 0 0 auto !important;
        max-height: 12rem;
        border-right: none !important;
        border-bottom: 1px solid var(--mud-palette-divider) !important;
    }

    /* Series editor field/operator/value row stacks vertically */
    .series-editor-condition-row {
        flex-direction: column !important;
        align-items: stretch !important;
        gap: 0.6rem !important;
    }

    /* Fullscreen visualization preview shrinks its body height so the
       chart + header fit a phone screen without inner scroll. */
    .dashboard-visual-fullscreen-body {
        height: 62vh !important;
    }
}

.caducore-gauge {
    position: relative;
}

.caducore-gauge .e-circulargauge {
    width: 100% !important;
    height: 100% !important;
}

.caducore-gauge .e-circulargauge > svg {
    width: 100% !important;
    height: 100% !important;
}

/* ══════════════════════════════════════════════════════════════════
   CRM mobile optimizations
   Shared responsive rules for the CRM content widgets (Actions kanban,
   Schedule + team-timeline calendars, Entities grid) that live inside
   the already-responsive BackOfficeEntityListPage chrome. These class
   names are app-owned, so they live in the global sheet to sidestep the
   MudBlazor CSS-isolation gotcha (child-component roots don't receive a
   scoped component's isolation attribute).
   ══════════════════════════════════════════════════════════════════ */

/* ── Actions kanban board ──
   Horizontal lane strip. On desktop, fixed 280px columns scroll if they
   overflow; on phones the columns become ~85vw so one shows at a time
   with the next peeking, and scroll-snap makes swiping land cleanly. */
.action-board-lanes {
    display: flex;
    gap: 1rem;
    align-items: flex-start;
    overflow-x: auto;
    padding-bottom: 0.5rem;
    scroll-snap-type: x proximity;
    -webkit-overflow-scrolling: touch;
}

.action-board-column {
    min-width: 280px;
    max-width: 280px;
    background: var(--mud-palette-background-grey);
    padding: 0.5rem;
    scroll-snap-align: start;
}

.action-board-addcol {
    min-width: 240px;
    max-width: 240px;
    padding: 0.5rem;
    scroll-snap-align: start;
}

.actions-dropzone {
    min-height: 62vh;
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

@media (max-width: 599.98px) {
    .action-board-lanes {
        /* Firmer snap on phones so each swipe lands on a column. */
        scroll-snap-type: x mandatory;
        gap: 0.75rem;
        /* Let a column bleed to the screen edges for more usable width. */
        margin-inline: -0.25rem;
        padding-inline: 0.25rem;
    }

    .action-board-column {
        min-width: min(85vw, 320px);
        max-width: min(85vw, 320px);
    }

    .action-board-addcol {
        min-width: min(70vw, 260px);
        max-width: min(70vw, 260px);
    }

    /* Slightly shorter columns so the board doesn't dwarf the phone screen. */
    .actions-dropzone {
        min-height: 55vh;
    }
}

/* ── Syncfusion Schedule + team timeline ──
   Both calendars ship a fixed pixel height and a single-row toolbar that
   overflows on phones. Let the toolbar wrap and cap the height so the
   grid + the lists/board below it stay reachable without a huge scroll.
   Heights are !important to beat Syncfusion's inline Height style. */
@media (max-width: 599.98px) {
    .mercodex-schedule.e-schedule,
    .mercodex-team-schedule.e-schedule {
        height: 68vh !important;
        min-height: 380px;
    }

    /* Toolbar: allow the Today / Day / Week / Month cluster to wrap
       instead of clipping, and tighten the date-range label. */
    .mercodex-schedule .e-schedule-toolbar .e-toolbar-items,
    .mercodex-team-schedule .e-schedule-toolbar .e-toolbar-items {
        flex-wrap: wrap !important;
        height: auto !important;
    }

    .mercodex-schedule .e-schedule-toolbar,
    .mercodex-team-schedule .e-schedule-toolbar {
        height: auto !important;
    }

    .mercodex-schedule .e-schedule-toolbar .e-date-range,
    .mercodex-team-schedule .e-schedule-toolbar .e-date-range {
        max-width: 46vw;
        overflow: hidden;
        text-overflow: ellipsis;
    }
}

/* --- Custom entity template picker (dialog is a separate component, so these
   app-owned classes live in the global sheet rather than Overview's scoped CSS) --- */
.entity-dialog-tab {
    display: flex;
    flex-direction: column;
    gap: 12px;
    padding-top: 8px;
}

.template-picker-state {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 16px 4px;
    color: var(--mud-palette-text-secondary);
}

.template-picker-list {
    display: flex;
    flex-direction: column;
    gap: 10px;
    max-height: 46vh;
    overflow-y: auto;
    padding: 2px;
}

.template-card {
    padding: 14px 16px;
    cursor: pointer;
    transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

.template-card:hover {
    border-color: var(--mud-palette-primary);
}

.template-card-selected {
    border-color: var(--mud-palette-primary) !important;
    box-shadow: 0 0 0 1px var(--mud-palette-primary) inset;
}

.template-card-head {
    display: flex;
    align-items: center;
    gap: 10px;
}

.template-card-title {
    flex: 1 1 auto;
    min-width: 0;
}

.template-card-desc {
    margin-top: 6px;
    color: var(--mud-palette-text-secondary);
}

.template-card-meta {
    display: block;
    margin-top: 6px;
    color: var(--mud-palette-text-secondary);
}

.template-card-groups {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    margin-top: 8px;
}

/* ============================================================================
   Front-office (landing site) theming.
   The public pages were authored with hardcoded dark colors; those are now
   mapped to these tokens (see Pages/FrontOffice). The default is the OS theme,
   resolved to a concrete value on <html data-fo-theme="..."> by the early
   script in App.razor. Only front-office CSS consumes --fo-* tokens.
   RGB triplets let the existing rgba(...) alphas keep working across themes.
   ============================================================================ */
:root {
    --fo-bg-0: #03060d;
    --fo-bg-0-rgb: 3, 6, 13;
    --fo-bg-1: #07111b;
    --fo-bg-2: #091522;
    --fo-text: #C7DBE6;
    --fo-text-rgb: 199, 219, 230;
    --fo-panel-rgb: 255, 255, 255;
    --fo-strong: #ffffff;
    --fo-header-bg: rgba(3, 6, 13, 0.6);
    --fo-header-border: rgba(199, 219, 230, 0.1);
    --fo-overlay: rgba(0, 0, 0, 0.6);
    --fo-glow-burgundy: rgba(112, 38, 50, 0.4);
    --fo-glow-teal: rgba(23, 82, 117, 0.35);
    --fo-card-shadow: 0 30px 60px rgba(0, 0, 0, 0.5);
}

html[data-fo-theme="light"] {
    --fo-bg-0: #eef2f8;
    --fo-bg-0-rgb: 238, 242, 248;
    --fo-bg-1: #ffffff;
    --fo-bg-2: #e3ebf4;
    --fo-text: #16202f;
    --fo-text-rgb: 13, 19, 31;
    --fo-panel-rgb: 20, 34, 58;
    --fo-strong: #0a1320;
    --fo-header-bg: rgba(255, 255, 255, 0.82);
    --fo-header-border: rgba(22, 32, 47, 0.14);
    --fo-overlay: rgba(15, 23, 42, 0.35);
    /* Keep the brand washes very subtle on light so the page reads clean, not reddish. */
    --fo-glow-burgundy: rgba(112, 38, 50, 0.05);
    --fo-glow-teal: rgba(23, 82, 117, 0.07);
    --fo-card-shadow: 0 24px 48px rgba(22, 32, 47, 0.14);
}

/* Text/icons on brand-colored surfaces (icon tiles, accent buttons) stay light
   in both themes because those surfaces are dark brand colors. These keep white
   where the bulk conversion flipped --fo-strong to dark. Accent buttons set via
   inline styles already keep #fff; these cover the CSS-class surfaces. */
html[data-fo-theme="light"] .icon-box,
html[data-fo-theme="light"] .capability-icon,
html[data-fo-theme="light"] .schedule-submit,
html[data-fo-theme="light"] .hero-cta-primary,
html[data-fo-theme="light"] .icon-container-small {
    color: #ffffff !important;
}

/* The service list icons sit on a transparent tile, so they must be dark on the
   light theme (the burgundy/teal icon TILES above keep white icons). */
html[data-fo-theme="light"] .service-icon-hex,
html[data-fo-theme="light"] .service-icon-hex .mud-icon-root {
    color: var(--fo-strong) !important;
}

/* The "Decide" pillar icon tile has no brand fill (it was a dark box with a light
   outline), so keep it dark on light theme so its white icon stays visible. */
html[data-fo-theme="light"] .icon-box.blue {
    background: #0a1320;
    border-color: #0a1320;
}

/* Header dropdown activators (Docs, Language) and their icons — match the rest
   of the bar (MudBlazor colors them white by default). */
html[data-fo-theme="light"] .public-header-docs .mud-button-root,
html[data-fo-theme="light"] .public-header-docs .mud-icon-root,
html[data-fo-theme="light"] .public-header-language .mud-button-root,
html[data-fo-theme="light"] .public-header-language .mud-icon-root {
    color: var(--fo-strong) !important;
}

/* Pricing plan accents tuned for the light theme: readable titles, and a premium
   gold treatment for the Founder plan (the bright gold reads poorly on white). */
html[data-fo-theme="light"] .highlighted-teal .plan-header [style*="74c7f7"] {
    color: #0f5a86 !important;
}

html[data-fo-theme="light"] .highlighted-burgundy .plan-header [style*="ff879a"] {
    color: #a8324a !important;
}

html[data-fo-theme="light"] .highlighted-premium [style*="fcce00"]:not(.mud-button-filled):not(button),
html[data-fo-theme="light"] .hero-title [style*="fcce00"] {
    color: #8a6a10 !important;
}

html[data-fo-theme="light"] .highlighted-premium {
    border-color: #caa63f !important;
    background: rgba(202, 166, 63, 0.07) !important;
    box-shadow: 0 20px 45px rgba(140, 106, 16, 0.16);
}

html[data-fo-theme="light"] .highlighted-premium .mud-button-filled[style*="fcce00"] {
    background-color: #cca02c !important;
    color: #1a1400 !important;
}

/* Per-seat monthly price in each plan header — dark (was white) on the light theme. */
html[data-fo-theme="light"] .plan-price-header {
    color: var(--fo-strong) !important;
}

/* The "(Taxes may apply)" / free-month notes were amber (unreadable on white). */
html[data-fo-theme="light"] .total-display small {
    color: rgba(var(--fo-text-rgb), 0.7) !important;
}

/* Make the accented highlight ("No long-term contracts") match the other highlight
   items instead of the standalone burgundy/pink accent. */
.highlight-accent {
    color: rgba(var(--fo-text-rgb), 0.85) !important;
}

.highlight-accent .mud-icon-root {
    color: #175275 !important;
}

/* Soften the brand glow washes on the light background. */
html[data-fo-theme="light"] .glow-left,
html[data-fo-theme="light"] .schedule-glow-left {
    background: radial-gradient(circle at 20% 30%, var(--fo-glow-burgundy) 0%, transparent 42%);
}

html[data-fo-theme="light"] .glow-right,
html[data-fo-theme="light"] .schedule-glow-right {
    background: radial-gradient(circle at 80% 20%, var(--fo-glow-teal) 0%, transparent 42%);
}

/* Black logo in the header and footers for maximum contrast on the light theme
   (the shipped asset is a white logo, so a brightness(0) filter renders it solid black). */
html[data-fo-theme="light"] .public-header-logo,
html[data-fo-theme="light"] .footer-bottom img {
    filter: brightness(0) saturate(100%);
}

html[data-fo-theme="light"] .footer-bottom img {
    opacity: 1 !important;
}

/* The lowest-alpha muted texts (trust line, footer copyright, CTA subline, footer
   links) drop below a readable contrast on the light background — give them a solid
   slate so small text stays legible. */
html[data-fo-theme="light"] .hero-trust,
html[data-fo-theme="light"] .cta-sub,
html[data-fo-theme="light"] .footer-bottom p,
html[data-fo-theme="light"] .footer-link {
    color: #47536a !important;
}

/* Theme toggle button in the public header. */
.public-header-theme-toggle {
    color: var(--fo-text) !important;
}

/* A tooltip must never swallow a click.

   MudBlazor renders tooltips into a body-level popover provider, so an open one is a real element
   sitting above the page — and because a tooltip is wider than the small icon button that triggered
   it, it overlaps that button's NEIGHBOURS. In a tight row of icon buttons (the pivot layout
   editor's four axis buttons are the case that exposed this) the tooltip for the button you just
   used covers the one you are reaching for, and the click lands on the tooltip instead. Playwright
   reports it verbatim: "<div class='mud-tooltip'>Add to rows</div> ... intercepts pointer events".

   Our tooltips are plain text with nothing to click, so making them transparent to the pointer costs
   nothing and fixes it everywhere rather than one row at a time. Note this must live in the GLOBAL
   stylesheet: the popover renders outside the originating component, so scoped CSS cannot reach it. */
.mud-tooltip {
    pointer-events: none;
}
