/* ============================================================
   Design tokens
   ============================================================ */
:root {
    /* Brand */
    --color-brand:               #2563eb;
    --color-brand-hover:         #1d4ed8;
    --color-brand-active:        #1e40af;

    /* Text */
    --color-text:                #0f172a;
    --color-text-strong:         #1e293b;
    --color-text-header:         #334155;
    --color-text-label:          #374151;
    --color-text-muted:          #475569;
    --color-text-subtle:         #64748b;
    --color-text-faint:          #94a3b8;
    --color-text-placeholder:    #9ca3af;
    --color-text-input:          #111827;
    --color-text-on-brand:       #ffffff;

    /* Surface */
    --color-surface:             #ffffff;
    --color-surface-app:         #f8fafc;
    --color-surface-subtle:      #f1f5f9;
    --color-surface-emphasis:    #e2e8f0;
    --color-surface-sidebar:     #1e293b;

    /* Border */
    --color-border:              #e5e7eb;
    --color-border-strong:       #e2e8f0;
    --color-border-input:        #d1d5db;

    /* Status */
    --color-success:             #16a34a;
    --color-success-modified:    #26b050;
    --color-danger:              #dc2626;
    --color-danger-bright:       #e50000;
    --color-warning:             #ca8a04;
    --color-warning-strong:      #b45309;
    --color-info:                #0284c7;

    /* Discipline identity colors — single source of truth for report-type
       chips, pills, menu glyphs and search suggestions (razor meta dicts
       reference these via var()). Chosen for pairwise hue separation:
       warm zone = FER red + FERCS amber only; Facade fuchsia sits 30° from
       DCD violet (the same comfortable distance as BCA blue vs Drainage
       cyan); PFSR lime stands alone between green and amber. Fuchsia and
       lime use the -700 shades so white type-pill text keeps AA contrast. */
    --disc-bca:                  #2563eb;
    --disc-bcapersol:            #16a34a;
    --disc-fer:                  #dc2626;
    --disc-fercs:                #ca8a04;
    --disc-dcd:                  #7c3aed;
    --disc-drainage:             #0891b2;
    --disc-facade:               #a21caf;
    --disc-pfsr:                 #4d7c0f;

    /* Radii */
    --radius-sm:                 4px;
    --radius-md:                 6px;
    --radius-lg:                 8px;
    --radius-xl:                 10px;
    --radius-pill:               999px;

    /* Type sizes (6-step scale) */
    --font-xs:                   11px;   /* uppercase labels, micro meta */
    --font-sm:                   12px;   /* small text, meta */
    --font-base:                 13px;   /* table cells, UI */
    --font-md:                   14px;   /* body, inputs, buttons */
    --font-lg:                   15px;   /* section titles */
    --font-xl:                   22px;   /* page titles */

    /* Font weights */
    --weight-normal:             400;
    --weight-medium:             500;
    --weight-semibold:           600;

    /* Shadows */
    --shadow-button:             0 1px 2px rgba(15, 23, 42, 0.06);
    --shadow-card:               0 1px 3px rgba(15, 23, 42, 0.04);
    --shadow-sticky:             0 -4px 12px rgba(15, 23, 42, 0.08);
    --ring-brand:                0 0 0 3px rgba(37, 99, 235, 0.15);
    --ring-brand-soft:           0 0 0 3px rgba(37, 99, 235, 0.1);

    /* Letter spacing */
    --letter-tight:              -0.01em;
    --letter-wide:                0.05em;
    --letter-wider:               0.06em;

    /* Line heights */
    --line-tight:                1.25;   /* headings */
    --line-snug:                 1.35;   /* dense UI text */
    --line-base:                 1.5;    /* body */
    --line-relaxed:              1.65;   /* long-form copy */

    /* Transitions */
    --transition-fast:           0.12s ease;

    /* Font family — self-hosted Inter (css/fonts.css), system stack as fallback.
       Inter won the 2026-08 trial against Plus Jakarta Sans on grid readability. */
    --font-family:               'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
    --bs-body-font-family:       var(--font-family);
}

/* ============================================================
   Tabler icons — base properties for any ti-* class, so a glyph
   works no matter how Blazorise assembles the class list (it may
   emit e.g. "fas ti-home" without the .ti base class; the stray
   "fas" is inert now that FontAwesome css is gone).
   .ti-spin replaces FontAwesome's fa-spin for busy indicators.
   ============================================================ */
[class^="ti-"], [class*=" ti-"] {
    font-family: 'tabler-icons' !important;
    speak: none;
    font-style: normal;
    font-weight: normal;
    font-variant: normal;
    text-transform: none;
    line-height: 1;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

.ti-spin {
    display: inline-block;
    animation: ti-spin 1s linear infinite;
}

@keyframes ti-spin {
    from { transform: rotate(0deg); }
    to   { transform: rotate(360deg); }
}

@media (prefers-reduced-motion: reduce) {
    .ti-spin { animation-duration: 2.5s; }
}

/* ============================================================
   Dark theme — token overrides. Toggled by setting
   data-theme="dark" on <html>. Brand and status colours are
   intentionally preserved so brand identity stays consistent
   across themes.
   ============================================================ */
:root[data-theme="dark"] {
    /* Text */
    --color-text:                #f1f5f9;
    --color-text-strong:         #e2e8f0;
    --color-text-header:         #cbd5e1;
    --color-text-label:          #cbd5e1;
    --color-text-muted:          #94a3b8;
    --color-text-subtle:         #94a3b8;
    --color-text-faint:          #64748b;
    --color-text-placeholder:    #7b8a9e;   /* a clear step below the input text, as #9ca3af is in light */
    --color-text-input:          #f1f5f9;

    /* Surface */
    --color-surface:             #1e293b;   /* card surface */
    --color-surface-app:         #0f172a;   /* page background */
    --color-surface-subtle:      #334155;   /* hover/badge bg */
    --color-surface-emphasis:    #475569;
    --color-surface-sidebar:     #0b1220;   /* slightly darker than card so sidebar still reads as a distinct rail */

    /* Border */
    --color-border:              #334155;
    --color-border-strong:       #475569;
    --color-border-input:        #475569;

    /* Shadows — softer on dark, with a slightly lighter accent */
    --shadow-button:             0 1px 2px rgba(0, 0, 0, 0.25);
    --shadow-card:               0 1px 3px rgba(0, 0, 0, 0.30);
    --shadow-sticky:             0 -4px 12px rgba(0, 0, 0, 0.35);
}

/* Sidebar overrides for dark mode — the original rule uses
   --color-text-strong (#1e293b); explicitly point it at the
   dark-mode sidebar token to keep visual separation from the
   content surface. */
:root[data-theme="dark"] .b-layout-sider,
:root[data-theme="dark"] .b-layout-sider-content {
    background-color: var(--color-surface-sidebar) !important;
}

/* Top bar in dark mode — Blazorise applies Bootstrap's bg-white via
   Background="Background.White" on the Bar; need !important to win. */
:root[data-theme="dark"] .b-layout-header,
:root[data-theme="dark"] .b-layout-header .b-bar,
:root[data-theme="dark"] .b-layout-header .bg-white {
    background-color: var(--color-surface) !important;
}

/* Card / table header backgrounds in dark mode use the card surface */
:root[data-theme="dark"] .b-table thead th {
    background-color: var(--color-surface-subtle);
}

/* DataGrid row hover in dark */
:root[data-theme="dark"] .b-table tbody tr:hover td {
    background-color: var(--color-surface-subtle);
}

/* Form-control input background in dark — Bootstrap base is white */
:root[data-theme="dark"] .form-control,
:root[data-theme="dark"] .form-select,
:root[data-theme="dark"] input.form-control {
    background-color: var(--color-surface-app);
    color: var(--color-text-input);
}

/* Disabled / readonly form-control — Bootstrap falls back to its
   light-grey --bs-secondary-bg which reads as white edges against
   the dark page. Pin to a dark surface with muted text instead. */
:root[data-theme="dark"] .form-control:disabled,
:root[data-theme="dark"] .form-control[readonly],
:root[data-theme="dark"] .form-select:disabled,
:root[data-theme="dark"] input.form-control:disabled,
:root[data-theme="dark"] input.form-control[readonly] {
    background-color: var(--color-surface-subtle);
    color: var(--color-text-faint);
    border-color: var(--color-border-input);
    opacity: 1;
}

/* Blazorise disabled Autocomplete sets the OUTER wrapper to a light
   grey via .dropdown.dropdown-disabled.b-is-autocomplete - flips the
   visible edges around the disabled input to light grey too. Match
   the inner input's dark surface so it reads as one piece. */
:root[data-theme="dark"] .dropdown.dropdown-disabled.b-is-autocomplete {
    background-color: var(--color-surface-subtle);
}

/* Topbar search box in dark */
/* Secondary buttons in dark */
:root[data-theme="dark"] .btn-secondary {
    background-color: var(--color-surface-subtle);
    border-color: var(--color-border-strong);
    color: var(--color-text);
}

:root[data-theme="dark"] .btn-secondary:hover {
    background-color: var(--color-surface-emphasis);
    border-color: var(--color-border-strong);
    color: var(--color-text-strong);
}
/* Light buttons in dark. Bootstrap leaves .btn-light near-white under its own dark
   theme, so every quiet action sat as a bright box on a dark table. Treated exactly
   like the secondary button above. Same rule as Examen's, added the same day. */
:root[data-theme="dark"] .btn-light {
    background-color: var(--color-surface-subtle);
    border-color: var(--color-border-strong);
    color: var(--color-text);
}

:root[data-theme="dark"] .btn-light:hover,
:root[data-theme="dark"] .btn-light:focus-visible,
:root[data-theme="dark"] .btn-light:active {
    background-color: var(--color-surface-emphasis);
    border-color: var(--color-border-strong);
    color: var(--color-text-strong);
}



/* Category badge background in dark */
:root[data-theme="dark"] .category-badge {
    background: var(--color-surface-subtle);
    border-color: var(--color-border-strong);
}

/* Chip background in dark (inactive) */
:root[data-theme="dark"] .category-chip {
    background: var(--color-surface);
    border-color: var(--color-border-strong);
    color: var(--color-text-muted);
}

/* Recent-toggle background */
:root[data-theme="dark"] .recent-toggle {
    background: var(--color-surface-app);
    border-color: var(--color-border);
}

:root[data-theme="dark"] .recent-toggle-btn.active {
    background: var(--color-surface);
}

/* Skeleton shimmer for dark */
:root[data-theme="dark"] .list-skeleton-row {
    background: linear-gradient(90deg, var(--color-surface) 0%, var(--color-surface-subtle) 50%, var(--color-surface) 100%);
    background-size: 200% 100%;
}

/* List rows / dashboard rows hover on dark */
:root[data-theme="dark"] .dashboard-row:hover {
    background: var(--color-surface-subtle);
}

/* Blazorise DataGrid pagination buttons (First / Prev / page numbers / Next / Last)
   don't pick up Bootstrap's data-bs-theme — force token colours here. */
:root[data-theme="dark"] .pagination .page-link,
:root[data-theme="dark"] .b-table-pagination .page-link,
:root[data-theme="dark"] .b-table-pagination button,
:root[data-theme="dark"] .b-table-pagination .btn,
:root[data-theme="dark"] nav[aria-label*="pagination"] .page-link,
:root[data-theme="dark"] .pagination .page-item .btn {
    background-color: var(--color-surface) !important;
    color: var(--color-text) !important;
    border-color: var(--color-border) !important;
}

:root[data-theme="dark"] .pagination .page-link:hover,
:root[data-theme="dark"] .b-table-pagination .page-link:hover,
:root[data-theme="dark"] .b-table-pagination button:hover {
    background-color: var(--color-surface-subtle) !important;
}

:root[data-theme="dark"] .pagination .page-item.active .page-link,
:root[data-theme="dark"] .pagination .page-item .page-link.active {
    background-color: var(--color-brand) !important;
    border-color: var(--color-brand) !important;
    color: #fff !important;
}

:root[data-theme="dark"] .pagination .page-item.disabled .page-link {
    color: var(--color-text-faint) !important;
    background-color: var(--color-surface-app) !important;
}

/* Dropdown menus (Autocomplete suggestions, BarDropdownMenu, etc.) — Bootstrap
   doesn't always flip these. Force dark surface + hover state. */
:root[data-theme="dark"] .dropdown-menu {
    background-color: var(--color-surface) !important;
    border-color: var(--color-border) !important;
    color: var(--color-text);
}

:root[data-theme="dark"] .dropdown-menu .dropdown-item {
    color: var(--color-text);
}

:root[data-theme="dark"] .dropdown-menu .dropdown-item:hover,
:root[data-theme="dark"] .dropdown-menu .dropdown-item:focus,
:root[data-theme="dark"] .dropdown-menu .dropdown-item.active,
:root[data-theme="dark"] .dropdown-menu .dropdown-item.focused,
:root[data-theme="dark"] .dropdown-menu .dropdown-item.focus,
:root[data-theme="dark"] .dropdown-menu .dropdown-item.is-active,
:root[data-theme="dark"] .dropdown-menu .dropdown-item.b-is-active,
:root[data-theme="dark"] .dropdown-menu .dropdown-item[aria-selected="true"],
:root[data-theme="dark"] .dropdown-menu .b-is-autocomplete-suggestion.focused,
:root[data-theme="dark"] .dropdown-menu .b-is-autocomplete-suggestion-focused {
    background-color: var(--color-surface-subtle) !important;
    color: var(--color-text) !important;
}

/* Belt-and-braces: cover children so a colored child element can't
   stay light when the parent flips. */
:root[data-theme="dark"] .dropdown-menu .dropdown-item.active *,
:root[data-theme="dark"] .dropdown-menu .dropdown-item:hover *,
:root[data-theme="dark"] .dropdown-menu .dropdown-item[aria-selected="true"] * {
    color: inherit;
}

/* DataGrid selected row — Blazorise / Bootstrap apply a light blue
   highlight that makes text unreadable in dark mode. Use a subtle
   brand-tinted overlay instead. */
:root[data-theme="dark"] .b-table tbody tr.selected td,
:root[data-theme="dark"] .b-table tbody tr.b-table-row-selected td,
:root[data-theme="dark"] .b-table tbody tr.table-active td,
:root[data-theme="dark"] .b-table tbody tr.table-primary td,
:root[data-theme="dark"] .table > tbody > tr.table-active > *,
:root[data-theme="dark"] .table > tbody > tr.table-primary > * {
    background-color: rgba(37, 99, 235, 0.15) !important;
    color: var(--color-text) !important;
    --bs-table-bg-state: transparent;
}

html, body {
    font-family: var(--font-family);
    font-size: var(--font-md);
    line-height: var(--line-base);
    color: var(--color-text);
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    text-rendering: optimizeLegibility;
}

a, .btn-link {
    color: var(--color-brand);
}

.btn-primary {
    color: #fff;
    background-color: var(--color-brand);
    border-color: var(--color-brand-hover);
}

.btn-primary:hover {
    background-color: var(--color-brand-hover);
    border-color: var(--color-brand-active);
}

/* ============================================================
   Sidebar — branded dark blue-grey (var(--color-text-strong) / slate-800)
   ============================================================ */

.b-layout-sider,
.b-layout-sider-content {
    background-color: var(--color-text-strong) !important;
    /*overflow: hidden;*/
}

.b-layout-sider {
    flex-shrink: 0;
}

/* Sidebar brand — clip overflow so logo doesn't bleed when collapsed */
.b-layout-sider .b-bar-brand,
.b-layout-sider .b-bar-brand .b-bar-item,
.b-layout-sider .b-bar-brand .b-bar-link {
    overflow: hidden;
}

.b-layout-sider .b-bar-brand img {
    max-width: 100%;
    height: auto;
}

/* Sidebar nav links — hover */
.b-layout-sider .b-bar-link:hover,
.b-layout-sider .b-bar-dropdown-toggle:hover {
    background-color: rgba(255, 255, 255, 0.06) !important;
}

/* Sidebar active nav item — full-width solid blue (parent + dropdown items) */
.b-layout-sider .nav-link.active,
.b-layout-sider .b-bar-link.active,
.b-layout-sider .b-bar-item .nav-link.active,
.b-layout-sider .b-bar-dropdown-item.active,
.b-layout-sider .dropdown-item.active {
    background-color: var(--color-brand) !important;
    color: #fff !important;
}

/* Brand link should never show active highlight */
.b-layout-sider .b-bar-brand .nav-link.active,
.b-layout-sider .b-bar-brand .b-bar-link.active,
.b-layout-sider .b-bar-brand .nav-link {
    background-color: transparent !important;
}

/* ============================================================
   Content area edge — clean seam between sidebar and content
   ============================================================ */

.b-layout-sider + .b-layout {
    border-left: 1px solid var(--color-border);
    /*min-width: 0;*/
}

/* ============================================================
   Top bar — light with bottom border
   ============================================================ */

.b-layout-header {
    border-bottom: 1px solid var(--color-border);
}

.b-layout-header .b-bar {
    box-shadow: none !important;
}

.b-layout-header .b-bar-link,
.b-layout-header .b-bar-dropdown-toggle {
    color: var(--color-text-header) !important;
    font-weight: var(--weight-medium);
}

.b-layout-header .b-bar-link:hover,
.b-layout-header .b-bar-dropdown-toggle:hover {
    color: var(--color-brand) !important;
}

/* User actions (profile, logout) in top bar */
.b-layout-header .nav-link,
.b-layout-header .nav-link .svg-inline--fa,
.b-layout-header .nav-link i {
    color: var(--color-text-muted) !important;
}

.b-layout-header .nav-link:hover,
.b-layout-header .nav-link:hover .svg-inline--fa,
.b-layout-header .nav-link:hover i {
    color: var(--color-brand) !important;
}

/* ============================================================
   Content area — off-white background
   ============================================================ */

.b-layout-content {
    background-color: var(--color-surface-app);
}

/* Mouse-click focus is silent; keyboard focus shows a branded ring. */
.btn:focus,
.btn-link:focus,
.form-control:focus,
.form-select:focus,
.form-check-input:focus,
a:focus {
    outline: none;
    box-shadow: none;
}

.btn:focus-visible,
.btn-link:focus-visible,
button:focus-visible,
[role="button"]:focus-visible,
a:focus-visible {
    outline: 2px solid var(--color-brand);
    outline-offset: 2px;
    border-radius: var(--radius-md);
}

.form-control:focus-visible,
.form-select:focus-visible {
    box-shadow: var(--ring-brand);
    border-color: var(--color-brand);
}

.form-check-input:focus-visible {
    outline: 2px solid var(--color-brand);
    outline-offset: 1px;
}

.content {
    padding-top: 1.1rem;
}

h1:focus {
    outline: none;
}

.valid.modified:not([type=checkbox]) {
    outline: 1px solid var(--color-success-modified);
}

.invalid {
    outline: 1px solid var(--color-danger-bright);
}

.validation-message {
    color: var(--color-danger-bright);
}

.blazor-error-boundary {
    background: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTYiIGhlaWdodD0iNDkiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIG92ZXJmbG93PSJoaWRkZW4iPjxkZWZzPjxjbGlwUGF0aCBpZD0iY2xpcDAiPjxyZWN0IHg9IjIzNSIgeT0iNTEiIHdpZHRoPSI1NiIgaGVpZ2h0PSI0OSIvPjwvY2xpcFBhdGg+PC9kZWZzPjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMCkiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0yMzUgLTUxKSI+PHBhdGggZD0iTTI2My41MDYgNTFDMjY0LjcxNyA1MSAyNjUuODEzIDUxLjQ4MzcgMjY2LjYwNiA1Mi4yNjU4TDI2Ny4wNTIgNTIuNzk4NyAyNjcuNTM5IDUzLjYyODMgMjkwLjE4NSA5Mi4xODMxIDI5MC41NDUgOTIuNzk1IDI5MC42NTYgOTIuOTk2QzI5MC44NzcgOTMuNTEzIDI5MSA5NC4wODE1IDI5MSA5NC42NzgyIDI5MSA5Ny4wNjUxIDI4OS4wMzggOTkgMjg2LjYxNyA5OUwyNDAuMzgzIDk5QzIzNy45NjMgOTkgMjM2IDk3LjA2NTEgMjM2IDk0LjY3ODIgMjM2IDk0LjM3OTkgMjM2LjAzMSA5NC4wODg2IDIzNi4wODkgOTMuODA3MkwyMzYuMzM4IDkzLjAxNjIgMjM2Ljg1OCA5Mi4xMzE0IDI1OS40NzMgNTMuNjI5NCAyNTkuOTYxIDUyLjc5ODUgMjYwLjQwNyA1Mi4yNjU4QzI2MS4yIDUxLjQ4MzcgMjYyLjI5NiA1MSAyNjMuNTA2IDUxWk0yNjMuNTg2IDY2LjAxODNDMjYwLjczNyA2Ni4wMTgzIDI1OS4zMTMgNjcuMTI0NSAyNTkuMzEzIDY5LjMzNyAyNTkuMzEzIDY5LjYxMDIgMjU5LjMzMiA2OS44NjA4IDI1OS4zNzEgNzAuMDg4N0wyNjEuNzk1IDg0LjAxNjEgMjY1LjM4IDg0LjAxNjEgMjY3LjgyMSA2OS43NDc1QzI2Ny44NiA2OS43MzA5IDI2Ny44NzkgNjkuNTg3NyAyNjcuODc5IDY5LjMxNzkgMjY3Ljg3OSA2Ny4xMTgyIDI2Ni40NDggNjYuMDE4MyAyNjMuNTg2IDY2LjAxODNaTTI2My41NzYgODYuMDU0N0MyNjEuMDQ5IDg2LjA1NDcgMjU5Ljc4NiA4Ny4zMDA1IDI1OS43ODYgODkuNzkyMSAyNTkuNzg2IDkyLjI4MzcgMjYxLjA0OSA5My41Mjk1IDI2My41NzYgOTMuNTI5NSAyNjYuMTE2IDkzLjUyOTUgMjY3LjM4NyA5Mi4yODM3IDI2Ny4zODcgODkuNzkyMSAyNjcuMzg3IDg3LjMwMDUgMjY2LjExNiA4Ni4wNTQ3IDI2My41NzYgODYuMDU0N1oiIGZpbGw9IiNGRkU1MDAiIGZpbGwtcnVsZT0iZXZlbm9kZCIvPjwvZz48L3N2Zz4=) no-repeat 1rem/1.8rem, #b32121;
    padding: 1rem 1rem 1rem 3.7rem;
    color: white;
}

    .blazor-error-boundary::after {
        content: "An error has occurred."
    }

.darker-border-checkbox.form-check-input {
    border-color: #929292;
}

/* ============================================================
   Account menu logout item (top bar avatar dropdown)
   ============================================================ */

.user-pod-logout-item {
    list-style: none;
    margin: 0;
    padding: 0;
}

.user-pod-logout-item form {
    margin: 0;
}

.user-pod-logout {
    width: 100%;
    text-align: left;
    background: transparent;
    border: none;
    color: var(--color-danger);
    cursor: pointer;
}

.user-pod-logout:hover,
.user-pod-logout:focus {
    background: var(--color-surface-subtle);
    color: var(--color-danger);
}

/* ============================================================
   Shared report row (used by Dashboard + RecentReportsPanel)
   ============================================================ */

.dashboard-row {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 6px 8px;
    border-radius: var(--radius-md);
    cursor: pointer;
    color: var(--color-text);
    text-decoration: none;
    min-height: 40px;
    transition: background-color var(--transition-fast), color var(--transition-fast);
}

.dashboard-row:hover {
    background: var(--color-surface-subtle);
    color: var(--color-text);
    text-decoration: none;
}

.dashboard-row:focus-visible {
    outline: 2px solid var(--color-brand);
    outline-offset: 2px;
}

.row-primary {
    flex: 1 1 auto;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 1px;
}

.row-project {
    font-size: var(--font-md);
    font-weight: var(--weight-medium);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    line-height: 1.3;
}

.row-client {
    font-weight: var(--weight-normal);
    color: var(--color-text-muted);
}

.row-site {
    font-size: var(--font-base);
    color: var(--color-text-faint);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    line-height: 1.3;
}

.row-meta {
    flex: 0 0 auto;
    text-align: right;
    font-size: var(--font-sm);
    color: var(--color-text-faint);
    white-space: nowrap;
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: 1px;
}

.row-meta .author {
    font-weight: var(--weight-medium);
    color: var(--color-text-muted);
}

/* ============================================================
   Recent reports panel (used on report home pages)
   ============================================================ */

.recent-panel {
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-xl);
    box-shadow: var(--shadow-card);
    padding: 14px 12px 10px 12px;
}

.recent-panel-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin: 0 4px 8px 4px;
}

.recent-panel-title {
    font-size: var(--font-xs);
    letter-spacing: var(--letter-wider);
    text-transform: uppercase;
    color: var(--color-text-muted);
    font-weight: var(--weight-semibold);
}

.recent-toggle {
    display: inline-flex;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    overflow: hidden;
    background: var(--color-surface-app);
}

.recent-toggle-btn {
    background: transparent;
    border: none;
    padding: 4px 10px;
    font-size: var(--font-sm);
    font-weight: var(--weight-medium);
    color: var(--color-text-muted);
    cursor: pointer;
}

.recent-toggle-btn:hover {
    color: var(--color-brand);
}

.recent-toggle-btn.active {
    background: #fff;
    color: var(--color-brand);
    box-shadow: var(--shadow-button);
}

.recent-empty {
    font-size: var(--font-base);
    color: var(--color-text-faint);
    padding: 20px 8px;
    text-align: center;
    line-height: 1.5;
}

.recent-filter-bar {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
    margin: 0 4px 10px 4px;
    padding: 8px 0 0 0;
    border-top: 1px dashed var(--color-border);
}

.recent-filter-select {
    flex: 0 1 220px;
    min-width: 140px;
    padding: 4px 8px;
    font-size: var(--font-sm);
    color: var(--color-text-strong);
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    cursor: pointer;
}

.recent-filter-select:focus {
    outline: none;
    border-color: var(--color-brand);
    box-shadow: 0 0 0 0.15rem rgba(37, 99, 235, 0.15);
}

.recent-filter-clear {
    margin-left: auto;
    background: transparent;
    border: none;
    color: var(--color-brand);
    font-size: var(--font-sm);
    font-weight: var(--weight-medium);
    cursor: pointer;
    padding: 4px 6px;
}

.recent-filter-clear:hover {
    text-decoration: underline;
}

.recent-footer {
    margin-top: 8px;
    padding: 6px 4px 0 4px;
    font-size: var(--font-sm);
    color: var(--color-text-faint);
    text-align: center;
    border-top: 1px dashed var(--color-border);
}

/* ============================================================
   Report home pages — hero strip (search + new)
   ============================================================ */

.report-hero {
    display: flex;
    gap: 12px;
    align-items: center;
}

.report-hero-search {
    flex: 1 1 auto;
    min-width: 0;
}

.report-hero-search .autocomplete,
.report-hero-search .dropdown,
.report-hero-search input.form-control {
    width: 100%;
}

.report-hero-search input.form-control {
    height: 40px;
    border-radius: var(--radius-lg);
    border-color: var(--color-border);
    font-size: var(--font-md);
}

.report-hero-search input.form-control:focus {
    border-color: var(--color-brand);
    box-shadow: var(--ring-brand);
}

/* ============================================================
   List pages — loading skeleton
   ============================================================ */

.list-skeleton {
    display: flex;
    flex-direction: column;
    gap: 8px;
    padding: 4px 0 16px 0;
}

.list-skeleton-row {
    height: 42px;
    border-radius: var(--radius-md);
    background: linear-gradient(90deg, var(--color-surface-subtle) 0%, var(--color-border-strong) 50%, var(--color-surface-subtle) 100%);
    background-size: 200% 100%;
    animation: shimmer 1.4s infinite ease-in-out;
}

/* Vary widths for natural feel */
.list-skeleton-row:nth-child(1) { width: 100%; }
.list-skeleton-row:nth-child(2) { width: 96%; }
.list-skeleton-row:nth-child(3) { width: 100%; }
.list-skeleton-row:nth-child(4) { width: 92%; }
.list-skeleton-row:nth-child(5) { width: 98%; }

/* Loading shimmer reads as motion; hold a static placeholder tint instead
   when the viewer asks for reduced motion. Covers the dashboard's
   .loading-row too (same keyframes, defined in Index.razor.css). */
@media (prefers-reduced-motion: reduce) {
    .list-skeleton-row, .loading-row {
        animation: none;
        background: var(--color-surface-subtle);
    }
}

/* ============================================================
   DataGrid — empty state
   ============================================================ */

.b-table-empty-row td,
.table tbody tr.b-table-empty-row td {
    text-align: center;
    color: var(--color-text-faint);
    padding: 40px 16px !important;
    font-size: var(--font-base);
    border: none !important;
}

/* ============================================================
   Edit pages — flatten inner tab-panel cards
   ============================================================ */

.tab-content .tab-pane .card {
    border: none;
    box-shadow: none;
    background: transparent;
}

.tab-content .tab-pane .card .card-body {
    padding: 0 0 8px 0;
}

/* Section cards that have a CardHeader — show a subtle label rule */
.tab-content .tab-pane .card .card-header {
    background: transparent;
    border: none;
    border-bottom: 1px solid var(--color-border);
    padding: 4px 0 8px 0;
}

.tab-content .tab-pane .card .card-header .card-title {
    font-size: var(--font-xs);
    font-weight: var(--weight-semibold);
    text-transform: uppercase;
    letter-spacing: var(--letter-wider);
    color: var(--color-text-muted);
}

/* ============================================================
   Edit pages — sticky action bar
   ============================================================ */

.edit-actions-sticky {
    position: sticky;
    bottom: 0;
    z-index: 20;
    background: var(--color-surface);
    border-top: 1px solid var(--color-border-strong);
    box-shadow: var(--shadow-sticky);
    padding: 14px 24px;
    display: flex;
    gap: 8px;
    align-items: center;
    margin-top: 16px;
}

/* ============================================================
   Generation tray (top bar)
   ============================================================ */

/* Search + tray live in one flex row we control (the Blazorise bar's own
   start/end groups stack on this layout), so placement is independent of it. */
.b-layout-header .topbar-row,
.b-layout-header .topbar-row .b-bar-item {
    width: 100%;
    flex: 1 1 auto;
}

.topbar-row-inner {
    display: flex;
    align-items: center;
    width: 100%;
    /* Right-align the utility cluster with the content cards' edge below
       (LayoutContent runs Padding.Is4.OnX); without this the avatar sat a
       few px off the viewport edge. */
    padding-right: 16px;
}

.topbar-tray {
    /* First icon of the right-hand utility cluster: auto margin pushes the
       whole cluster right; the old 24px right margin predates the cluster
       and left the tray orphaned mid-bar. */
    margin-left: auto;
    margin-right: 0;
    position: relative;
}

/* The tray dropdown must float as an overlay, not sit in flow (which would
   stretch the flex row and grow the whole header when opened). */
.topbar-tray .dropdown-menu {
    position: absolute !important;
    top: calc(100% + 6px);
    right: 0;
    left: auto !important;
    z-index: 1100;
}

/* Subtle borderless icon button instead of the default white btn-light box. */
.gen-tray-toggle.btn,
.gen-tray-toggle.btn:active,
.gen-tray-toggle.btn:focus {
    position: relative;
    background: transparent !important;
    border: none !important;
    box-shadow: none !important;
    color: var(--color-text-header) !important;
    padding: 4px 8px;
    font-size: 1.15rem;
    line-height: 1;
}

.gen-tray-toggle.btn:hover {
    color: var(--color-brand) !important;
}

/* Hide Bootstrap's dropdown caret - the cloud icon is the affordance. */
.gen-tray-toggle.dropdown-toggle::after {
    display: none;
}

.gen-tray-badge {
    position: absolute;
    top: -2px;
    right: -2px;
    min-width: 16px;
    height: 16px;
    padding: 0 4px;
    border-radius: 8px;
    background: #16a34a;
    color: #fff;
    font-size: 10px;
    line-height: 16px;
    text-align: center;
    font-weight: 700;
}

/* ============================================================
   Edit pages — generating indicator
   ============================================================ */

.generating-indicator {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: var(--font-base);
    font-weight: var(--weight-medium);
    color: var(--color-brand);
    margin-left: auto;
}

.generating-indicator .spinner-border {
    width: 1rem;
    height: 1rem;
    border-width: 2px;
    color: var(--color-brand);
}

/* ============================================================
   Edit pages — breadcrumb
   ============================================================ */

.edit-breadcrumb {
    font-size: var(--font-base);
    margin-top: 14px;
    margin-bottom: 10px;
}

.edit-breadcrumb a {
    color: var(--color-text-muted);
    text-decoration: none;
    display: inline-flex;
    align-items: center;
    gap: 5px;
}

.edit-breadcrumb a:hover {
    color: var(--color-brand);
}

/* ============================================================
   Typography
   ============================================================ */

h1, h2, h3, h4, h5, h6 {
    color: var(--color-text);
    letter-spacing: var(--letter-tight);
    line-height: var(--line-tight);
    font-weight: var(--weight-semibold);
}

/* Page-level headings — all non-dashboard pages use <Heading Size="HeadingSize.Is4">,
   which renders as h4. Match the Dashboard heading style. */
.b-layout-content h4 {
    font-size: var(--font-xl);
}

/* ============================================================
   Cards
   ============================================================ */

.card {
    background-color: var(--color-surface);
    border-color: var(--color-border);
    border-radius: var(--radius-xl);
    box-shadow: var(--shadow-card);
}

.card-header {
    background-color: transparent;
    border-bottom-color: var(--color-border);
    padding: 10px 16px;
}

.card-title {
    font-size: var(--font-lg);
    font-weight: var(--weight-semibold);
    color: var(--color-text);
    margin: 0;
}

/* ============================================================
   Tabs
   ============================================================ */

.nav-tabs {
    border-bottom-color: var(--color-border);
    gap: 2px;
    flex-wrap: wrap;
}

.nav-tabs .nav-link {
    font-size: var(--font-base);
    font-weight: var(--weight-medium);
    color: var(--color-text-muted);
    border-radius: var(--radius-md) var(--radius-md) 0 0;
    padding: 7px 14px;
    border-color: transparent;
    white-space: nowrap;
    transition: color var(--transition-fast), background-color var(--transition-fast), border-color var(--transition-fast);
}

.nav-tabs .nav-link:hover {
    color: var(--color-brand);
    background-color: var(--color-surface-subtle);
    border-color: transparent;
}

.nav-tabs .nav-link.active {
    color: var(--color-brand);
    font-weight: var(--weight-semibold);
    background-color: var(--color-surface);
    border-color: var(--color-border) var(--color-border) var(--color-surface);
}

/* ============================================================
   Form fields
   ============================================================ */

.b-field-label,
.form-label,
label.form-label,
label.b-field-label {
    font-size: var(--font-base);
    font-weight: var(--weight-medium);
    color: var(--color-text-label) !important;
    margin-bottom: 4px;
}

.form-control,
.form-select {
    border-radius: var(--radius-md);
    border-color: var(--color-border-input);
    font-size: var(--font-md);
    color: var(--color-text-input);
    transition: border-color var(--transition-fast), box-shadow var(--transition-fast);
}

.form-control:focus,
.form-select:focus {
    border-color: var(--color-brand);
    box-shadow: var(--ring-brand-soft);
}

.form-control::placeholder,
input.form-control::placeholder,
.form-select::placeholder {
    color: var(--color-text-placeholder) !important;
    opacity: 1;
}

/* Bootstrap floating labels keep the placeholder transparent (the label sits in its
   place). The !important rule above otherwise re-shows the placeholder, so it collides
   with the floating label - re-assert transparency for form-floating inputs (more
   specific + !important, so it wins). Fixes the /Account/* management fields. */
.form-floating > .form-control::placeholder,
.form-floating > input.form-control::placeholder {
    color: transparent !important;
}

/* ============================================================
   Buttons
   ============================================================ */

.btn {
    border-radius: var(--radius-md);
    font-size: var(--font-md);
    font-weight: var(--weight-medium);
    transition:
        background-color var(--transition-fast),
        border-color var(--transition-fast),
        color var(--transition-fast),
        box-shadow var(--transition-fast),
        transform var(--transition-fast);
}

/* Tactile press feedback on real button clicks (only when not disabled).
   Cancel the transition during press so it feels snappy. */
.btn:not(:disabled):active {
    transform: translateY(1px);
    transition-duration: 0s;
}

.btn-secondary {
    background-color: var(--color-surface-subtle);
    border-color: var(--color-border-strong);
    color: var(--color-text-header);
}

.btn-secondary:hover {
    background-color: var(--color-border-strong);
    border-color: #cbd5e1;
    color: var(--color-text-strong);
}

/* ============================================================
   DataGrid / Tables
   ============================================================ */

.b-table {
    font-size: var(--font-base);
    /* Lining figures of equal width so numbers, dates and FRLs stay aligned per column */
    font-variant-numeric: tabular-nums;
}

.b-table thead th {
    font-size: var(--font-xs);
    font-weight: var(--weight-semibold);
    text-transform: uppercase;
    letter-spacing: var(--letter-wide);
    color: var(--color-text-muted);
    background-color: var(--color-surface-app);
    border-bottom: 1px solid var(--color-border) !important;
    padding: 8px 12px;
}

.b-table tbody td {
    padding: 8px 12px;
    color: var(--color-text-strong);
    border-bottom-color: var(--color-surface-subtle) !important;
    vertical-align: middle;
}

.b-table tbody tr:hover td {
    background-color: var(--color-surface-app);
}

.cell-clamp {
    display: -webkit-box;
    -webkit-line-clamp: 4;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

/* Muted product list shown under a tested-system description in the grids.
   Wraps freely to as many lines as needed so full product names are visible
   (no ellipsis). Normal wrapping (not white-space:nowrap) means it never widens
   the table / forces a horizontal scrollbar. Colour is theme-aware for contrast. */
.ts-products-line {
    color: var(--color-text-subtle);
    font-size: 12px;
    margin-top: 3px;
    white-space: normal;
    overflow-wrap: anywhere;
}

.page-title-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 12px;
    margin: 16px 0 12px 0;
}

.page-title-row h4 {
    margin: 0;
}

.topbar-search {
    flex: 1 1 auto;
    max-width: 480px;
    min-width: 240px;
    margin-left: 24px;
}
/* Suggestions dropdown: at least the input width, but allowed to grow wider for legibility */
/* Allow flex children to shrink so the inner ellipsis works */
/* Truncate any long line inside each suggestion row */
/* ============================================================
   Nav rail (2026-08 redesign) — sectioned sidebar, light in light
   mode (Auth0-style single surface) and darker-than-content in
   dark mode. The :has(.nav-rail) guards keep every rule inert
   while Ui:UseClassicNav renders the old Bar instead.
   ============================================================ */

.b-layout-sider:has(.nav-rail),
.b-layout-sider:has(.nav-rail) .b-layout-sider-content {
    background: var(--color-surface-app) !important;
}

.b-layout-sider:has(.nav-rail) {
    border-right: 1px solid var(--color-border);
}

:root[data-theme="dark"] .b-layout-sider:has(.nav-rail),
:root[data-theme="dark"] .b-layout-sider:has(.nav-rail) .b-layout-sider-content {
    background: var(--color-surface-sidebar) !important;
}

.nav-rail {
    display: flex;
    flex-direction: column;
    height: 100%;
    padding: 10px 8px 16px 8px;
    overflow-y: auto;
    min-width: 230px;
}

.nav-rail-brand {
    display: flex;
    align-items: center;
    gap: 9px;
    padding: 4px 10px 12px 10px;
    font-size: 15px;
    font-weight: var(--weight-semibold);
    color: var(--color-text);
    text-decoration: none;
    letter-spacing: var(--letter-tight);
}

.nav-rail-brand:hover { color: var(--color-text); }

.nav-rail-logo { width: 28px; height: 28px; }

.nav-rail-section {
    display: flex;
    align-items: center;
    justify-content: space-between;
    width: 100%;
    font-size: var(--font-xs);
    letter-spacing: var(--letter-wider);
    text-transform: uppercase;
    font-weight: var(--weight-semibold);
    color: var(--color-text-subtle);
    padding: 14px 10px 4px 10px;
    background: transparent;
    border: none;
    text-align: left;
}

.nav-rail-section i { font-size: 13px; }

.nav-rail-section-toggle { cursor: pointer; border-radius: var(--radius-md); }

.nav-rail-section-toggle:hover { color: var(--color-text-header); }

.nav-rail-item {
    display: flex;
    align-items: center;
    gap: 9px;
    font-size: var(--font-base);
    font-weight: var(--weight-medium);
    color: var(--color-text-header);
    text-decoration: none;
    padding: 6px 10px;
    border-radius: var(--radius-md);
    white-space: nowrap;
    transition: background-color var(--transition-fast), color var(--transition-fast);
}

.nav-rail-item i {
    font-size: 16px;
    width: 18px;
    text-align: center;
    flex: 0 0 auto;
}

.nav-rail-item:hover {
    background: var(--color-surface-subtle);
    color: var(--color-text);
    text-decoration: none;
}

.nav-rail-item.active {
    background: rgba(37, 99, 235, 0.10);
    color: var(--color-brand-hover);
}

:root[data-theme="dark"] .nav-rail-item { color: #cbd5e1; }
:root[data-theme="dark"] .nav-rail-item:hover { background: rgba(255, 255, 255, 0.06); color: #f1f5f9; }
:root[data-theme="dark"] .nav-rail-item.active { background: rgba(37, 99, 235, 0.30); color: #fff; }

/* Off-canvas below tablet width: the rail slides in over the content,
   toggled by the hamburger in the top bar (html.nav-open). */
.nav-rail-mobile-toggle {
    display: none;
    width: 34px;
    height: 34px;
    border: none;
    background: transparent;
    border-radius: var(--radius-md);
    color: var(--color-text-muted);
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    margin-right: 8px;
}

.nav-rail-mobile-toggle i { font-size: 19px; }

@media (max-width: 767.98px) {
    .nav-rail-mobile-toggle { display: inline-flex; }

    .b-layout-sider:has(.nav-rail) {
        position: fixed;
        top: 0;
        bottom: 0;
        left: 0;
        width: 248px;
        z-index: 1300;
        transform: translateX(-100%);
        transition: transform 0.2s ease;
        box-shadow: none;
    }

    :root.nav-open .b-layout-sider:has(.nav-rail) {
        transform: translateX(0);
        box-shadow: 0 10px 40px rgba(15, 23, 42, 0.35);
    }

    @media (prefers-reduced-motion: reduce) {
        .b-layout-sider:has(.nav-rail) { transition: none; }
    }
}

/* ---- Desktop collapse (:root.nav-collapsed) ----
   The rail folds to a 16px strip and the content takes the width; hovering
   the strip (or tabbing into it) peeks the full rail OVER the content, and
   clicking anything that says so pins it back open. Same class-on-<html>
   mechanic as the phone off-canvas above, but persisted per browser
   (keystone-nav-collapsed, applied pre-paint in App.razor so a remembered
   collapse never shifts the page after load). Scoped to >=768px: phones keep
   the hamburger behaviour untouched. Default is expanded - nobody meets the
   collapsed rail by surprise. */

.nav-rail-head { display: flex; align-items: flex-start; }
.nav-rail-head .nav-rail-brand { flex: 1 1 auto; min-width: 0; }

.nav-rail-collapse,
.nav-rail-pin {
    display: flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    width: 22px;
    height: 22px;
    margin: 4px 2px 0 0;
    padding: 0;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    background: var(--color-surface);
    color: var(--color-text-subtle);
    font-size: 12px;
    cursor: pointer;
    transition: color var(--transition-fast), border-color var(--transition-fast);
}

.nav-rail-collapse:hover,
.nav-rail-pin:hover { color: var(--color-text); border-color: var(--color-border-strong); }

/* Pin only exists while peeking a collapsed rail; the strip only while collapsed.
   Both are display-driven off :root.nav-collapsed rather than Blazor state, so a
   remembered collapse renders correctly on first paint. */
.nav-rail-pin { display: none; }
.nav-rail-strip { display: none; }

/* The collapse affordance is desktop-only; on phones the off-canvas hamburger
   already owns show/hide and this button would be a dead control. */
@media (max-width: 767.98px) {
    .nav-rail-collapse { display: none; }
}

@media (min-width: 768px) {
    :root.nav-collapsed .b-layout-sider:has(.nav-rail) {
        width: 16px;
        min-width: 16px;
        flex: 0 0 16px;
    }

    /* The rail becomes a viewport-fixed drawer. Transition delays are the whole
       peek feel: 120ms of hover intent on the way in, 250ms of forgiveness on
       the way out. */
    :root.nav-collapsed .b-layout-sider:has(.nav-rail) .nav-rail {
        position: fixed;
        top: 0;
        bottom: 0;
        left: 0;
        z-index: 1300;
        width: 230px;
        background: var(--color-surface-app);
        border-right: 1px solid var(--color-border);
        box-shadow: 0 10px 40px rgba(15, 23, 42, 0.35);
        transform: translateX(-103%);
        transition: transform 0.18s ease 0.25s;
    }

    :root[data-theme="dark"].nav-collapsed .b-layout-sider:has(.nav-rail) .nav-rail {
        background: var(--color-surface-sidebar);
    }

    :root.nav-collapsed .b-layout-sider:has(.nav-rail):hover .nav-rail,
    :root.nav-collapsed .b-layout-sider:has(.nav-rail):focus-within .nav-rail {
        transform: translateX(0);
        transition-delay: 0.12s;
    }

    /* The 16px remnant. Viewport-fixed so Blazorise's sticky sider content can't
       clip it; sits under the drawer (1290 < 1300) so the peek covers it. */
    :root.nav-collapsed .nav-rail-strip {
        display: flex;
        align-items: center;
        justify-content: center;
        position: fixed;
        top: 0;
        bottom: 0;
        left: 0;
        width: 16px;
        z-index: 1290;
        padding: 0;
        border: none;
        border-right: 1px solid var(--color-border);
        background: var(--color-surface-app);
        color: var(--color-text-subtle);
        font-size: 11px;
        cursor: pointer;
    }

    :root.nav-collapsed .b-layout-sider:has(.nav-rail):hover .nav-rail-strip {
        background: var(--color-surface-subtle);
        color: var(--color-text-muted);
    }

    :root[data-theme="dark"].nav-collapsed .nav-rail-strip {
        background: var(--color-surface-sidebar);
    }

    :root.nav-collapsed .nav-rail-collapse { display: none; }
    :root.nav-collapsed .nav-rail-pin { display: flex; }

    @media (prefers-reduced-motion: reduce) {
        /* Keep the intent/forgiveness delays, drop the motion. */
        :root.nav-collapsed .b-layout-sider:has(.nav-rail) .nav-rail { transition-duration: 0s; }
    }
}

/* ============================================================
   Top bar — search shortcut chip + right-hand utility cluster
   (font trial switcher, theme toggle, avatar account menu)
   ============================================================ */

.search-kbd {
    position: absolute;
    right: 10px;
    top: 50%;
    transform: translateY(-50%);
    border: 1px solid var(--color-border-strong);
    background: var(--color-surface-app);
    color: var(--color-text-subtle);
    border-radius: 5px;
    font-size: 10.5px;
    font-weight: var(--weight-medium);
    padding: 1px 6px;
    pointer-events: none;
    white-space: nowrap;
}

/* Hide the chip while typing (and while the suggestions dropdown is open) */
/* Typed text must never run underneath the chip */
/* Phone widths: the shortcut chip is meaningless on touch, and the search
   box's desktop minimums (240px + 24px margin) overflowed the row and
   pushed the avatar off-screen. Let search shrink and tighten the cluster. */
@media (max-width: 767.98px) {
    .search-kbd { display: none; }

    .topbar-search {
        min-width: 0;
        margin-left: 8px;
    }    .topbar-row-inner { padding-right: 10px; }
    .topbar-divider { display: none; }
    .topbar-utils { gap: 0; margin-left: 0; }
}

.topbar-utils {
    display: flex;
    align-items: center;
    gap: 2px;
    margin-left: 2px; /* matches the intra-cluster gap so the tray reads as one of us */
    flex: 0 0 auto;
}

.topbar-icon-btn {
    width: 34px;
    height: 34px;
    border: none;
    background: transparent;
    border-radius: var(--radius-md);
    color: var(--color-text-muted);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    transition: background-color var(--transition-fast), color var(--transition-fast);
}

.topbar-icon-btn:hover {
    background: var(--color-surface-subtle);
    color: var(--color-text-strong);
}

/* No lingering box after a mouse click (Blazor keeps the button focused);
   keyboard focus still gets a visible ring. */
.topbar-icon-btn:focus { outline: none; }
.topbar-icon-btn:focus-visible {
    outline: none;
    box-shadow: var(--ring-brand-soft);
}

.topbar-icon-btn i {
    font-size: 18px;
}

/* Theme toggle renders both glyphs; the active theme picks which shows */
.theme-icon-when-dark { display: none; }
:root[data-theme="dark"] .theme-icon-when-light { display: none; }
:root[data-theme="dark"] .theme-icon-when-dark { display: inline-block; }

.topbar-divider {
    width: 1px;
    height: 22px;
    background: var(--color-border);
    margin: 0 6px;
    flex: 0 0 auto;
}

/* Same overlay requirement as .topbar-tray above: inside the header Bar,
   an open dropdown otherwise sits in flow and stretches the whole header. */
.topbar-utils .dropdown {
    position: relative;
}

.topbar-utils .dropdown-menu {
    position: absolute !important;
    top: calc(100% + 6px);
    right: 0;
    left: auto !important;
    z-index: 1100;
    min-width: 210px;
}

.topbar-avatar-toggle,
.topbar-avatar-toggle.btn,
.topbar-avatar-toggle:focus,
.topbar-avatar-toggle:focus-visible,
.topbar-avatar-toggle:hover {
    background: transparent !important;
    border: none !important;
    padding: 2px;
    box-shadow: none !important;
    outline: none;
}

/* Keyboard/programmatic focus shows as a halo on the avatar circle itself,
   not Bootstrap's rectangle around the button (Blazorise focuses the toggle
   when the menu opens, which lights :focus-visible even on mouse clicks). */
.topbar-avatar-toggle:focus-visible .topbar-avatar {
    box-shadow: var(--ring-brand-soft);
}

.topbar-avatar {
    width: 30px;
    height: 30px;
    border-radius: var(--radius-pill);
    background: var(--color-surface-emphasis);
    color: var(--color-text-strong);
    font-size: 12.5px;
    font-weight: var(--weight-semibold);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    letter-spacing: 0.02em;
    transition: box-shadow var(--transition-fast);
}

.topbar-avatar-toggle:hover .topbar-avatar {
    box-shadow: 0 0 0 3px var(--color-surface-subtle);
}

.topbar-avatar-name {
    padding: 8px 16px 4px 16px;
    font-size: var(--font-sm);
    font-weight: var(--weight-medium);
    color: var(--color-text-muted);
    white-space: nowrap;
}

/* Product category chip filter bar (Tested Product Library) */
.category-chip-bar {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    margin-bottom: 14px;
}

.category-chip {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 5px 12px;
    background: var(--color-surface);
    border: 1.5px solid var(--color-border);
    border-radius: var(--radius-pill);
    font-size: var(--font-base);
    font-weight: var(--weight-medium);
    color: var(--color-text-muted);
    cursor: pointer;
    transition: background-color var(--transition-fast), border-color var(--transition-fast), color var(--transition-fast);
}

.category-chip:hover {
    border-color: var(--chip-color, var(--color-text-faint));
    color: var(--chip-color, var(--color-text-muted));
}

.category-chip.active {
    background: var(--chip-color, var(--color-text-muted));
    border-color: var(--chip-color, var(--color-text-muted));
    color: #fff;
}

.category-chip.active .chip-dot {
    background: #fff;
}

.chip-dot {
    display: inline-block;
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--chip-color, var(--color-text-faint));
    flex: 0 0 auto;
}

.category-count {
    font-size: var(--font-xs);
    color: inherit;
    opacity: 0.75;
    margin-left: 2px;
}

/* Per-row category badge inside the grid */
.category-badge {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding: 2px 9px;
    border-radius: var(--radius-pill);
    background: var(--color-surface-subtle);
    color: var(--chip-color, var(--color-text-muted));
    font-size: var(--font-sm);
    font-weight: var(--weight-semibold);
    border: 1px solid var(--color-border-strong);
    white-space: nowrap;
}

/* ============================================================
   Tinted type chip — the discipline color (--chip-color, set inline
   per row) washes the chip background and paints icon + label.
   The bare `span` in the selector is deliberate: it outranks the
   scoped .type-badge base styles in Index.razor.css, which load
   later via Keystone.styles.css and would otherwise win the tie.
   ============================================================ */
span.type-badge.tinted {
    background: color-mix(in srgb, var(--chip-color) 12%, transparent);
    color: var(--chip-color);
}

/* Dark: a touch more tint, and lighten the discipline hue toward white so
   label and icon keep contrast on dark surfaces. 76/24 rather than a heavier
   whitening: uniform lightening compresses hues toward the same pastel and
   was blurring neighbours (DCD violet vs Facade fuchsia); keeping more of
   the native hue preserves each discipline's identity. */
:root[data-theme="dark"] span.type-badge.tinted {
    background: color-mix(in srgb, var(--chip-color) 16%, transparent);
    color: color-mix(in srgb, var(--chip-color) 76%, #fff);
}

/* ============================================================
   Status text — inline status indicator with icon + label
   (CardHeader: Ready / N incomplete / Saved h:mm tt)
   ============================================================ */

.status-text {
    display: inline-flex;
    align-items: center;
    font-size: var(--font-sm);
    font-weight: var(--weight-medium);
    color: var(--color-text-subtle);
}

.status-text--success { color: var(--color-success); }
.status-text--warning { color: var(--color-warning-strong); }
.status-text--muted {
    color: var(--color-text-subtle);
    font-weight: var(--weight-normal);
}

/* Inline parent-project link inside a report edit card header */
.parent-project-link {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    margin-left: 12px;
    padding: 2px 8px;
    font-size: var(--font-sm);
    font-weight: var(--weight-medium);
    color: var(--color-brand);
    text-decoration: none;
    border-radius: var(--radius-md);
    transition: background-color var(--transition-fast);
}

.parent-project-link:hover {
    background-color: var(--color-surface-subtle);
    color: var(--color-brand-hover);
    text-decoration: none;
}

.parent-project-link i {
    font-size: 12px;
}

/* ============================================================
   Type pill — coloured badge identifying the report/project type
   in edit page headers, paired with a coloured left bar on the card
   ============================================================ */

.type-pill {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 4px 11px;
    border-radius: 999px;
    font-size: var(--font-sm);
    font-weight: var(--weight-semibold);
    color: #fff;
    white-space: nowrap;
    line-height: 1.2;
    margin-right: 10px;
    vertical-align: middle;
}

.type-pill i {
    font-size: 0.9em;
}

/* Per-attribute mismatch indicator (TestedSystemEditForm). Sits beside the
   FieldLabel text and shows a tooltip explaining the baseline requirement. */
.field-mismatch-icon {
    color: #dc3545;
    margin-left: 6px;
    font-size: 0.9em;
    cursor: help;
}

/* Summary strip at the top of a section listing all attributes that don't
   match the baseline. Each pill is one mismatched attribute. */
.section-mismatch-strip {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
    margin: 0 0 14px 0;
    padding: 10px 14px;
    background-color: rgba(220, 53, 69, 0.08);
    border: 1px solid rgba(220, 53, 69, 0.3);
    border-radius: 6px;
    font-size: 0.85rem;
}

.section-mismatch-label {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-weight: 600;
    color: #dc3545;
    margin-right: 4px;
}

.section-mismatch-pill {
    display: inline-flex;
    align-items: baseline;
    gap: 6px;
    padding: 3px 10px;
    background-color: var(--color-surface);
    border: 1px solid rgba(220, 53, 69, 0.35);
    border-radius: 999px;
    color: #dc3545;
    font-weight: 500;
    line-height: 1.3;
}

.section-mismatch-pill .pill-req {
    color: var(--color-text-muted);
    font-weight: 400;
}

/* Baseline match-count badge on each system row (FacadeEdit systems list).
   Shows "X/Y" where X = matched attributes, Y = baseline-specified attributes. */
.baseline-score {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    font-size: 0.85rem;
    font-weight: 600;
    white-space: nowrap;
}

.baseline-score--full {
    color: var(--color-success);
}

.baseline-score--partial {
    color: #dc3545;
}

/* ============================================================
   Facade comparison grid - attribute rows x system columns
   ============================================================ */

.compare-toolbar {
    margin-bottom: 12px;
}

.compare-grid-wrap {
    overflow-x: auto;
    border: 1px solid var(--color-border);
    border-radius: 8px;
}

.compare-grid {
    border-collapse: separate;
    border-spacing: 0;
    width: 100%;
    font-size: 0.875rem;
}

.compare-grid th,
.compare-grid td {
    padding: 8px 14px;
    text-align: left;
    white-space: nowrap;
    border-bottom: 1px solid var(--color-border);
}

.compare-grid thead th {
    background: var(--color-surface-subtle);
    font-weight: 600;
    position: sticky;
    top: 0;
    z-index: 2;
}

/* Sticky first two columns so Attribute + Baseline stay visible while scrolling systems */
.compare-attr-col {
    position: sticky;
    left: 0;
    width: 190px;
    min-width: 190px;
    background: var(--color-surface);
    font-weight: 600;
    z-index: 1;
}

.compare-baseline-col {
    position: sticky;
    left: 190px;
    width: 150px;
    min-width: 150px;
    background: var(--color-surface-subtle);
    font-weight: 500;
    box-shadow: 1px 0 0 var(--color-border);
}

.compare-grid thead .compare-attr-col,
.compare-grid thead .compare-baseline-col {
    z-index: 3;
}

.compare-sys-col {
    min-width: 110px;
}

.compare-score-row td {
    background: var(--color-surface-emphasis);
    font-weight: 700;
}

.compare-cell--ok {
    color: var(--color-success);
}

.compare-cell--fail {
    color: #dc3545;
    font-weight: 600;
}

/* Identity rows (Reference ID, Description) at the top of the compare grid -
   not baseline comparisons, so neutral weight and allowed to wrap (Description
   can be long) within a capped width instead of the default nowrap. */
.compare-grid td.compare-meta-cell {
    white-space: normal;
    overflow-wrap: anywhere;
    max-width: 240px;
    vertical-align: top;
    font-weight: 400;
}

.page-title-with-pill {
    display: flex;
    align-items: center;
    gap: 12px;
    flex-wrap: wrap;
}

/* ============================================================
   Empty state — unified "no results" pattern
   ============================================================ */

.empty-state {
    text-align: center;
    color: var(--color-text-faint);
    font-size: var(--font-base);
    padding: 24px 16px;
    line-height: var(--line-relaxed);
}

/* ============================================================
   Form-field primitives
   ------------------------------------------------------------
   .field-required  — add to a FieldLabel to append a red *
   .field-error     — apply to a FieldLabel when validation fails
                      (turns label and the * red)
   .field-help      — small helper text shown below an input
   .field-error-message — validation feedback shown below an input
   ============================================================ */

.field-required::after {
    content: " *";
    color: var(--color-danger);
    font-weight: var(--weight-semibold);
}

.field-error,
.field-error.field-required::after {
    color: var(--color-danger);
}

.field-help {
    display: block;
    margin-top: 2px;
    font-size: var(--font-sm);
    color: var(--color-text-faint);
    line-height: var(--line-snug);
}

.field-error-message {
    display: block;
    margin-top: 2px;
    font-size: var(--font-sm);
    color: var(--color-danger);
    line-height: var(--line-snug);
}

/* ============================================================
   System Editor side-nav layout
   - Used on the Facade Report Tested Systems tab to navigate
     between sections of the selected system without nested
     accordions or tabs.
   - Desktop (>= 992px): vertical rail on the left, content on
     the right.
   - Below 992px: horizontal scrollable strip stacked above the
     content so the form stays usable on narrow screens.
   ============================================================ */

.system-editor {
    display: grid;
    grid-template-columns: 200px minmax(0, 1fr);
    gap: 1.5rem;
    align-items: start;
}

.system-editor-nav {
    display: flex;
    flex-direction: column;
    gap: 2px;
    padding: 0.25rem;
    background: var(--color-surface-subtle);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    position: sticky;
    top: 1rem;
}

.system-editor-nav-item {
    appearance: none;
    background: transparent;
    border: 0;
    border-radius: var(--radius-sm);
    padding: 0.45rem 0.75rem;
    text-align: left;
    font-size: var(--font-sm);
    color: var(--color-text-label);
    cursor: pointer;
    line-height: var(--line-snug);
    white-space: nowrap;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
}

.system-editor-nav-item-label {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
}

.system-editor-nav-item-dot {
    flex: 0 0 auto;
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--color-danger);
    box-shadow: 0 0 0 2px var(--color-surface-subtle);
}

.system-editor-nav-item.active .system-editor-nav-item-dot {
    /* Keep the dot legible on the brand-blue active background. */
    box-shadow: 0 0 0 2px var(--color-brand);
}

.system-editor-nav-item:hover {
    background: var(--color-surface);
    color: var(--color-text-strong);
}

.system-editor-nav-item:focus-visible {
    outline: 2px solid var(--color-brand);
    outline-offset: 1px;
}

.system-editor-nav-item.active {
    background: var(--color-brand);
    color: var(--color-text-on-brand);
    font-weight: var(--weight-semibold);
}

.system-editor-nav-item.active:hover {
    background: var(--color-brand-hover);
    color: var(--color-text-on-brand);
}

.system-editor-nav-divider {
    height: 1px;
    margin: 0.4rem 0.25rem;
    background: var(--color-border-strong);
}

.system-editor-content {
    min-width: 0;
}

@media (max-width: 991.98px) {
    .system-editor {
        grid-template-columns: minmax(0, 1fr);
        gap: 1rem;
    }

    .system-editor-nav {
        flex-direction: row;
        overflow-x: auto;
        position: static;
        padding: 0.25rem;
        gap: 0.25rem;
        -webkit-overflow-scrolling: touch;
    }

    .system-editor-nav-item {
        flex: 0 0 auto;
    }

    .system-editor-nav-divider {
        width: 1px;
        height: auto;
        margin: 0.25rem 0.25rem;
        align-self: stretch;
    }
}

/* ---- Project command center ---- */
.cc-identity {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
    font-size: var(--font-md);
    min-width: 0;
}

.cc-identity__sep {
    color: var(--color-text-muted);
}

/* Shared column template so the header row and every data row line up. */
.cc-table {
    --cc-cols: 150px 110px 185px 110px 76px 1fr;
}

/* The reports table carries an "Issued under" column, since a project's reports can sit
   under different numbers. The inspections table keeps the shared six. */
.cc-table--reports {
    --cc-cols: 150px 200px 110px 185px 110px 76px 1fr;
}

.cc-head {
    display: grid;
    grid-template-columns: var(--cc-cols);
    align-items: center;
    column-gap: 12px;
    padding: 0 8px 8px;
    border-bottom: 1px solid var(--color-border);
}

.cc-head > span {
    font-size: 11px;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    font-weight: 600;
    color: var(--color-text-faint);
    white-space: nowrap;
}

.cc-rows {
    display: flex;
    flex-direction: column;
}

/* Fixed-column grid so type / issue / status / owner / modified line up
   vertically across every row (a per-row auto grid would size independently). */
.cc-row {
    display: grid;
    grid-template-columns: var(--cc-cols);
    align-items: center;
    column-gap: 12px;
    padding: 10px 8px;
    border-bottom: 1px solid var(--color-border);
    min-height: 48px;
}

.cc-row:last-child {
    border-bottom: none;
}

/* Report type doubles as a link to that report's editor (the Open button stays too). */
.cc-row__type {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    min-width: 0;
    font-weight: 600;
    color: var(--color-text);
    text-decoration: none;
}

.cc-row__type:hover {
    color: var(--color-brand);
}

/* Underline only the label text on hover - not the type icon (an underline on the
   anchor would run under the icon too). */
.cc-row__type:hover .cc-row__type-label {
    text-decoration: underline;
}

.cc-row__issue,
.cc-row__owner {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-size: var(--font-sm);
}

.cc-row__issue {
    color: var(--color-text-muted);
}

.cc-row__owner {
    color: var(--color-text);
}

.cc-row__when {
    font-size: var(--font-sm);
    color: var(--color-text-muted);
    white-space: nowrap;
}

/* Actions split into a left-anchored main group (Open + Generate) and a
   right-pinned destructive group, so "Open" lands in the same place on every
   row and Delete is visually separated from the safe actions. */
.cc-row__actions {
    display: flex;
    align-items: center;
    gap: 8px;
    width: 100%;
}

.cc-row__actions-main {
    display: flex;
    align-items: center;
    gap: 8px;
    min-width: 0;
}

.cc-row__actions-danger {
    margin-left: auto;
    padding-left: 12px;
    border-left: 1px solid var(--color-border);
}

.cc-row__placeholder {
    color: var(--color-text-faint);
}

/* MissingFieldsBadge carries a start margin for inline use on edit-page headers;
   inside the grid cell it should sit flush so it lines up under the Status header. */
.cc-row__badge .status-text {
    margin-left: 0 !important;
}
/* ============================================================
   Command palette (B2) - portable shell styles. Token-driven,
   so dark mode needs no extra rules beyond the backdrop.
   ============================================================ */

.palette-trigger {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    min-width: 240px;
    border: 1px solid var(--color-border-input);
    background: var(--color-surface);
    color: var(--color-text-subtle);
    border-radius: var(--radius-md);
    font-size: var(--font-base);
    padding: 6px 10px;
    cursor: pointer;
    transition: border-color var(--transition-fast), color var(--transition-fast);
}

.palette-trigger:hover { border-color: var(--color-border-strong); color: var(--color-text-muted); }
.palette-trigger i { font-size: 15px; }
.palette-trigger span { flex: 1 1 auto; text-align: left; }

.search-kbd-inline {
    border: 1px solid var(--color-border-strong);
    background: var(--color-surface-app);
    color: var(--color-text-subtle);
    border-radius: 5px;
    font-size: 10.5px;
    font-weight: var(--weight-medium);
    padding: 1px 6px;
    white-space: nowrap;
}

@media (max-width: 767.98px), (hover: none) {
    .search-kbd-inline { display: none; }
    .palette-trigger { min-width: 0; }
    .palette-trigger span { display: none; }
    /* Nothing to press on a touch screen: no esc badge, no key legend. The footer
       needs the extra .palette-panel qualifier: its base display:flex rule sits later
       in this file and would otherwise win the tie at equal specificity. */
    .palette-input-row kbd { display: none; }
    .palette-panel .palette-foot { display: none; }
}

.palette-backdrop {
    position: fixed;
    inset: 0;
    z-index: 1400;
    background: rgba(15, 23, 42, 0.45);
    display: flex;
    align-items: flex-start;
    justify-content: center;
    padding: 12vh 16px 16px;
}

.palette-panel {
    width: 100%;
    max-width: 560px;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: 12px;
    box-shadow: var(--shadow-card);
    overflow: hidden;
    animation: palette-in 0.12s ease-out;
}

@keyframes palette-in {
    from { opacity: 0; transform: translateY(-6px); }
    to   { opacity: 1; transform: none; }
}

@media (prefers-reduced-motion: reduce) {
    .palette-panel { animation: none; }
}

.palette-input-row {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 12px 14px;
    border-bottom: 1px solid var(--color-border);
    color: var(--color-text-subtle);
}

.palette-input-row i { font-size: 17px; }

.palette-input-row input {
    flex: 1 1 auto;
    border: none;
    outline: none;
    background: transparent;
    color: var(--color-text);
    font-size: var(--font-md);
}

.palette-input-row input::placeholder { color: var(--color-text-faint); }

.palette-input-row kbd,
.palette-foot kbd {
    border: 1px solid var(--color-border-strong);
    background: var(--color-surface-app);
    color: var(--color-text-subtle);
    border-radius: 5px;
    font-size: 10.5px;
    padding: 1px 6px;
}

.palette-results {
    max-height: 48vh;
    overflow-y: auto;
    padding: 6px;
}

.palette-empty {
    padding: 22px 14px;
    text-align: center;
    color: var(--color-text-subtle);
    font-size: var(--font-base);
}

.palette-group-label {
    font-size: var(--font-xs);
    letter-spacing: var(--letter-wider);
    text-transform: uppercase;
    font-weight: var(--weight-semibold);
    color: var(--color-text-subtle);
    padding: 10px 10px 4px 10px;
}

.palette-item {
    display: flex;
    align-items: center;
    gap: 10px;
    width: 100%;
    border: none;
    background: transparent;
    text-align: left;
    color: var(--color-text-header);
    font-size: var(--font-base);
    padding: 7px 10px;
    border-radius: var(--radius-md);
    cursor: pointer;
}

.palette-item i { font-size: 16px; width: 18px; text-align: center; flex: 0 0 auto; color: var(--color-text-subtle); }
.palette-item.active { background: var(--color-surface-subtle); color: var(--color-text); }
.palette-item.active i { color: var(--color-brand); }

.palette-item-title { flex: 0 1 auto; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

.palette-item-subtitle {
    flex: 1 1 auto;
    min-width: 0;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    color: var(--color-text-subtle);
    font-size: var(--font-sm);
    text-align: right;
}

.palette-foot {
    display: flex;
    gap: 14px;
    padding: 8px 14px;
    border-top: 1px solid var(--color-border);
    color: var(--color-text-subtle);
    font-size: var(--font-xs);
}



/* ---------------------------------------------------------------------------
   Edit-page section rail (FerEdit; FacadeEdit and friends to follow).

   Blazorise's own vertical Tabs mode supplies the mechanism - these rules turn
   its Bootstrap tab strip into a grouped rail.

   DOM, confirmed from the running page (do not re-guess this): the Class lands on
   Blazorise's own <ul class="nav nav-tabs flex-column"> - so .section-rail-tabs IS
   the rail, with the <li class="nav-item"> items and the .rail-group headings as
   its DIRECT children. The tab panes are NOT inside it; they sit in a sibling
   column, which is why the pane rules hang off .section-rail-shell instead.
   --------------------------------------------------------------------------- */

.section-rail-tabs {
    flex: 0 0 214px;
    gap: 1px;
    padding: 6px 0 10px;
    /* Bootstrap's .nav-tabs draws a bottom edge to join the active tab to its
       pane. A rail has no such join, so this closes the box instead. */
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    background: var(--color-surface-subtle);
}

/* Let the pane column shrink. Flex items default to min-width:auto, so without
   this a wide DataGrid widens its column until the whole page scrolls sideways;
   with it, the grid scrolls inside its own Responsive container as intended. */
.section-rail-shell .tab-content,
.section-rail-shell > * > [class*="col"] { min-width: 0; }

.section-rail-tabs .rail-group {
    padding: 12px 12px 4px;
    font-size: var(--font-xs);
    font-weight: var(--weight-semibold);
    letter-spacing: var(--letter-wider);
    text-transform: uppercase;
    color: var(--color-text-faint);
}

.section-rail-tabs .rail-group:first-child,
.rail-bar + .rail-group { padding-top: 4px; }

/* Neutralise the horizontal-tab look: no tab borders, no bottom-edge join. */
.section-rail-tabs .nav-item { margin: 0; }

.section-rail-tabs .nav-link {
    display: flex;
    align-items: center;
    /* NOT space-between: with an icon, a label and a badge that would strand the
       label in the middle of the row. The badge pushes itself right instead. */
    justify-content: flex-start;
    gap: 8px;
    width: 100%;
    padding: 6px 12px;
    border: 0;
    border-radius: 0;
    box-shadow: inset 2px 0 0 transparent;
    font-size: var(--font-base);
    color: var(--color-text-muted);
    text-align: left;
    transition: background var(--transition-fast), color var(--transition-fast);
}

.section-rail-tabs .nav-link:hover {
    background: var(--color-surface);
    color: var(--color-text);
}

.section-rail-tabs .nav-link.active {
    background: var(--color-surface);
    color: var(--color-text-header);
    font-weight: var(--weight-medium);
    box-shadow: inset 2px 0 0 var(--color-brand);
}

/* Markers (RailBadge). A count, a faint dash for empty, or an amber warning -
   never a completion tick; see RailBadge.razor for why. */
.rail-badge {
    flex: 0 0 auto;
    margin-left: auto;
    min-width: 20px;
    padding: 0 6px;
    border-radius: 99px;
    background: var(--color-surface-app);
    font-size: var(--font-xs);
    font-variant-numeric: tabular-nums;
    text-align: center;
    color: var(--color-text-subtle);
}

.rail-badge--empty {
    background: none;
    color: var(--color-text-faint);
}

.rail-badge--warn {
    background: none;
    color: var(--color-warning-strong);
    font-size: var(--font-sm);
}

/* ---- Tested Systems: stack the two panes when the split stops working ----

   The panes are 5/7 on desktop, which is right at 2560 (the firm's screens) and
   badly wrong below ~1700: at 1440 the left pane's Description column is left
   with about 105px and breaks mid-word. Bootstrap already stacks these columns,
   but only below its own breakpoint, which is far too late.

   Keyed off the CONTAINER, not the viewport, so it accounts for the section rail
   being expanded (214px) or compact (44px) without knowing which. Threshold is
   derived, not guessed: Description ~= 0.417 x container - 360 (the pane is 5/12,
   less four fixed columns totalling 320px plus cell padding), so a floor of 200px
   for Description puts the stack point at a container width of ~1340px. Change
   that one number to retune. */

.ts-split-scope { container-type: inline-size; }

@container (max-width: 1340px) {
    /* Both columns take the full pane, so the grid gets the whole width and the
       system editor sits beneath it. */
    .ts-split > [class*="col-"] {
        flex: 0 0 100%;
        max-width: 100%;
        width: 100%;
    }
}

/* ---- The compact (icon) state ----
   Triggered by SectionRailToggle. Labels are visually hidden but kept in the DOM
   so each item keeps its accessible name; group headings become plain dividers;
   counts reduce to a dot. Crucially nothing is REMOVED - every section stays on
   screen and clickable, because the rail is the only route to them. */

.section-rail-tabs.compact { flex: 0 0 44px; }

.section-rail-tabs .rail-icon { flex: 0 0 auto; font-size: 15px; }

.section-rail-tabs .nav-link { position: relative; }
.section-rail-tabs.compact .nav-link { justify-content: center; padding: 7px 0; }

/* Visually hidden, not display:none - a screen reader still reads the section name. */
.section-rail-tabs.compact .rail-label {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
}

/* The group name cannot fit, but the grouping itself still helps - so the heading
   becomes the rule it was implying. */
.section-rail-tabs.compact .rail-group {
    height: 1px;
    padding: 0;
    margin: 7px 9px 5px;
    overflow: hidden;
    font-size: 0;
    background: var(--color-border);
}

/* A count cannot be read at 44px, but "something is here" and "this needs
   attention" both can. */
.section-rail-tabs.compact .rail-badge {
    position: absolute;
    top: 5px;
    right: 7px;
    width: 6px;
    height: 6px;
    min-width: 0;
    padding: 0;
    font-size: 0;
    line-height: 0;
    background: var(--color-text-faint);
}

.section-rail-tabs.compact .rail-badge i { display: none; }
.section-rail-tabs.compact .rail-badge--warn { background: var(--color-warning-strong); }
.section-rail-tabs.compact .rail-badge--empty { display: none; }

/* ---- The toggle ---- */

.rail-bar {
    display: flex;
    justify-content: flex-end;
    padding: 4px 5px;
    margin-bottom: 2px;
    border-bottom: 1px solid var(--color-border);
}

.rail-bar--compact { justify-content: center; }

.rail-toggle {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 22px;
    height: 22px;
    padding: 0;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    background: var(--color-surface);
    color: var(--color-text-subtle);
    font-size: 12px;
    cursor: pointer;
    transition: color var(--transition-fast), border-color var(--transition-fast);
}

.rail-toggle:hover { color: var(--color-text); border-color: var(--color-border-strong); }

/* Narrow screens: the rail returns to a horizontal, scrolling strip above the
   content, and the group headings drop out (they cost more width than they earn). */
@media (max-width: 767.98px) {
    .section-rail-shell > * { flex-direction: column; gap: 12px; }

    .section-rail-tabs {
        flex: 0 0 auto;
        flex-direction: row;
        width: 100%;
        overflow-x: auto;
        padding: 4px;
        gap: 4px;
    }

    .section-rail-tabs .rail-group { display: none; }

    .section-rail-tabs .nav-link {
        width: auto;
        white-space: nowrap;
        border-radius: var(--radius-md);
        box-shadow: none;
    }

    .section-rail-tabs .nav-link.active {
        box-shadow: inset 0 -2px 0 var(--color-brand);
    }

    /* Laid out as a row, the toggle's rule belongs on its trailing edge. */
    .rail-bar {
        margin: 0 4px 0 0;
        border-bottom: 0;
        border-right: 1px solid var(--color-border);
        padding: 0 6px 0 2px;
    }
}

/* ------------------------------------------------------------------ */
/* Circuit-death notice (App.razor #blazor-error-ui)                    */
/* blazor.web.js flips display to block on an unhandled circuit error; */
/* nothing else appears on that path, so the bar has to be unmissable  */
/* in both themes. One deliberate look: warning-strong with white type. */
/* ------------------------------------------------------------------ */
#blazor-error-ui {
    display: none;
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 2000;
    padding: .75rem 1.25rem;
    background: var(--color-warning-strong);
    color: #ffffff;
    box-shadow: 0 -2px 8px rgba(0, 0, 0, .25);
    font-size: .95rem;
    line-height: 1.4;
}

#blazor-error-ui .btn {
    margin-left: 1rem;
    vertical-align: baseline;
}

/* An inline form nested inside a card, e.g. the add/edit number form on a project's Numbers
   tab. Uses the theme's subtle surface so it reads as an inset in both light and dark; never
   Bootstrap's Background.Light, which is a fixed white that ignores the theme. */
.inset-panel {
    background: var(--color-surface-subtle);
    border: 1px solid var(--color-border);
}
