/* Design tokens (colors, typography, spacing, radius, shadows) moved to
 * wwwroot/theme/theme.css (2026-09-19) - the single source of truth for
 * the whole app's look and feel, linked separately in App.razor/index.html.
 * Edit that file to change the brand color, a dark-mode surface tone, the
 * base font, etc. See .claude/memory/css_theme_tokens_2026_09_19.md.
 */

[data-theme="dark"] .card, 
[data-theme="dark"] .tab-content, 
[data-theme="dark"] .border,
[data-bs-theme="dark"] .card,
[data-bs-theme="dark"] .tab-content,
[data-bs-theme="dark"] .border {
    background: var(--bg-surface) !important;
    border-color: var(--border-color) !important;
}

[data-theme="dark"] .sidebar,
[data-bs-theme="dark"] .sidebar {
    background-color: #030712 !important;
    border-right: 1px solid var(--border-color);
}

[data-theme="dark"] .top-row,
[data-bs-theme="dark"] .top-row {
    background-color: #0b0f19 !important;
    border-bottom: 1px solid var(--border-color) !important;
}

[data-theme="dark"] .bg-white,
[data-bs-theme="dark"] .bg-white {
    background-color: var(--bg-surface) !important;
    color: var(--text-main) !important;
}

[data-theme="dark"] .bg-light,
[data-bs-theme="dark"] .bg-light,
[data-theme="dark"] .bg-light-subtle,
[data-bs-theme="dark"] .bg-light-subtle {
    background-color: var(--bg-elevated) !important;
    color: var(--text-main) !important;
}

[data-theme="dark"] .card-header,
[data-bs-theme="dark"] .card-header {
    background-color: var(--bg-elevated) !important;
    color: var(--text-main) !important;
    border-bottom: 1px solid var(--border-color) !important;
}

[data-theme="dark"] .card-footer,
[data-bs-theme="dark"] .card-footer {
    background-color: var(--bg-elevated) !important;
    color: var(--text-main) !important;
    border-top: 1px solid var(--border-color) !important;
}

[data-theme="dark"] .text-dark,
[data-bs-theme="dark"] .text-dark {
    color: var(--text-main) !important;
}

/* Bootstrap 5.3 paints each CELL from --bs-table-bg (set to #f8f9fa by .table-light), not from
   the row's background - so overriding background-color alone left light cells in dark mode
   (e.g. the invoice builder's new-line row, 2026-10-01). Remap the table variables too. */
[data-theme="dark"] .table-light,
[data-bs-theme="dark"] .table-light {
    --bs-table-bg: var(--bg-elevated);
    --bs-table-color: var(--text-main);
    --bs-table-border-color: var(--border-color);
    --bs-table-striped-bg: var(--bg-elevated);
    --bs-table-striped-color: var(--text-main);
    --bs-table-active-bg: var(--bg-elevated);
    --bs-table-active-color: var(--text-main);
    --bs-table-hover-bg: var(--bg-elevated);
    --bs-table-hover-color: var(--text-main);
    background-color: var(--bg-elevated) !important;
    color: var(--text-main) !important;
}

[data-theme="dark"] .list-group-item,
[data-bs-theme="dark"] .list-group-item {
    background-color: var(--bg-surface) !important;
    color: var(--text-main) !important;
    border-color: var(--border-color) !important;
}

[data-theme="dark"] .modal-content,
[data-bs-theme="dark"] .modal-content {
    background-color: var(--bg-surface) !important;
    border-color: var(--border-color) !important;
    color: var(--text-main) !important;
}

[data-theme="dark"] .modal-header,
[data-bs-theme="dark"] .modal-header,
[data-theme="dark"] .modal-footer,
[data-bs-theme="dark"] .modal-footer {
    border-color: var(--border-color) !important;
}

[data-theme="dark"] .dropdown-menu,
[data-bs-theme="dark"] .dropdown-menu {
    background-color: var(--bg-surface) !important;
    border-color: var(--border-color) !important;
    color: var(--text-main) !important;
}

[data-theme="dark"] .dropdown-item,
[data-bs-theme="dark"] .dropdown-item {
    color: var(--text-main) !important;
}

[data-theme="dark"] .dropdown-item:hover,
[data-theme="dark"] .dropdown-item:focus,
[data-bs-theme="dark"] .dropdown-item:hover,
[data-bs-theme="dark"] .dropdown-item:focus {
    background-color: var(--bg-elevated) !important;
    color: #ffffff !important;
}

[data-theme="dark"] .form-control,
[data-theme="dark"] .form-select,
[data-bs-theme="dark"] .form-control,
[data-bs-theme="dark"] .form-select {
    background-color: var(--border-color) !important;
    border-color: var(--input-border) !important;
    color: var(--text-main) !important;
}

[data-theme="dark"] .form-control:focus,
[data-theme="dark"] .form-select:focus,
[data-bs-theme="dark"] .form-control:focus,
[data-bs-theme="dark"] .form-select:focus {
    background-color: var(--bg-elevated) !important;
    color: var(--text-main) !important;
}

[data-theme="dark"] select option,
[data-bs-theme="dark"] select option {
    background-color: var(--bg-surface);
    color: var(--text-main);
}

/* Syncfusion Dialogs Dark Mode adaptation */
[data-theme="dark"] .e-dialog,
[data-bs-theme="dark"] .e-dialog {
    background-color: var(--bg-surface) !important;
    border-color: var(--border-color) !important;
}

[data-theme="dark"] .e-dialog .e-dlg-header-content,
[data-bs-theme="dark"] .e-dialog .e-dlg-header-content {
    background-color: var(--bg-elevated) !important;
    color: var(--text-main) !important;
    border-bottom: 1px solid var(--border-color) !important;
}

[data-theme="dark"] .e-dialog .e-dlg-content,
[data-bs-theme="dark"] .e-dialog .e-dlg-content {
    background-color: var(--bg-surface) !important;
    color: var(--text-main) !important;
}

[data-theme="dark"] .e-dialog .e-footer-container,
[data-bs-theme="dark"] .e-dialog .e-footer-container {
    background-color: #161f30 !important;
    border-top: 1px solid var(--border-color) !important;
}

[data-theme="dark"] .e-dialog .e-dlg-closeicon-btn .e-btn-icon,
[data-bs-theme="dark"] .e-dialog .e-dlg-closeicon-btn .e-btn-icon {
    color: var(--text-main) !important;
}

/* Syncfusion Dropdowns & Popups Dark Mode */
[data-theme="dark"] .e-popup,
[data-theme="dark"] .e-dropdownbase,
[data-theme="dark"] .e-popup.e-ddl,
[data-bs-theme="dark"] .e-popup,
[data-bs-theme="dark"] .e-dropdownbase,
[data-bs-theme="dark"] .e-popup.e-ddl {
    background-color: var(--bg-surface) !important;
    border-color: var(--border-color) !important;
    color: var(--text-main) !important;
}

[data-theme="dark"] .e-dropdownbase .e-list-item,
[data-bs-theme="dark"] .e-dropdownbase .e-list-item {
    color: var(--text-main) !important;
    background-color: var(--bg-surface) !important;
}

[data-theme="dark"] .e-dropdownbase .e-list-item:hover,
[data-theme="dark"] .e-dropdownbase .e-list-item.e-hover,
[data-bs-theme="dark"] .e-dropdownbase .e-list-item:hover,
[data-bs-theme="dark"] .e-dropdownbase .e-list-item.e-hover {
    background-color: var(--bg-elevated) !important;
    color: #ffffff !important;
}

[data-theme="dark"] .e-dropdownbase .e-list-item.e-item-focus,
[data-theme="dark"] .e-dropdownbase .e-list-item.e-active,
[data-bs-theme="dark"] .e-dropdownbase .e-list-item.e-item-focus,
[data-bs-theme="dark"] .e-dropdownbase .e-list-item.e-active {
    background-color: rgba(99, 102, 241, 0.2) !important;
    color: var(--primary) !important;
}

/* Syncfusion Calendar & DatePicker Dark Mode */
[data-theme="dark"] .e-calendar,
[data-theme="dark"] .e-calendar .e-content,
[data-theme="dark"] .e-calendar .e-header,
[data-bs-theme="dark"] .e-calendar,
[data-bs-theme="dark"] .e-calendar .e-content,
[data-bs-theme="dark"] .e-calendar .e-header {
    background-color: var(--bg-surface) !important;
    color: var(--text-main) !important;
    border-color: var(--border-color) !important;
}

[data-theme="dark"] .e-calendar .e-header .e-title,
[data-theme="dark"] .e-calendar .e-header .e-prev,
[data-theme="dark"] .e-calendar .e-header .e-next,
[data-bs-theme="dark"] .e-calendar .e-header .e-title,
[data-bs-theme="dark"] .e-calendar .e-header .e-prev,
[data-bs-theme="dark"] .e-calendar .e-header .e-next {
    color: var(--text-main) !important;
}

[data-theme="dark"] .e-calendar th,
[data-theme="dark"] .e-calendar .e-cell,
[data-bs-theme="dark"] .e-calendar th,
[data-bs-theme="dark"] .e-calendar .e-cell {
    color: var(--text-main) !important;
}

[data-theme="dark"] .e-calendar .e-cell:hover span.e-day,
[data-bs-theme="dark"] .e-calendar .e-cell:hover span.e-day {
    background-color: var(--bg-elevated) !important;
}

/* Dark scrollbars */
[data-theme="dark"] ::-webkit-scrollbar-track,
[data-bs-theme="dark"] ::-webkit-scrollbar-track {
    background: var(--bg-surface);
}
[data-theme="dark"] ::-webkit-scrollbar-thumb,
[data-bs-theme="dark"] ::-webkit-scrollbar-thumb {
    background: var(--border-color-strong);
}
[data-theme="dark"] ::-webkit-scrollbar-thumb:hover,
[data-bs-theme="dark"] ::-webkit-scrollbar-thumb:hover {
    background: var(--input-border);
}


html, body {
    font-family: var(--font-family-base) !important;
    background-color: var(--bg-app);
    color: var(--text-main);
}

a, .btn-link {
    color: var(--primary);
    text-decoration: none;
    transition: color 0.15s ease;
}

a:hover, .btn-link:hover {
    color: var(--primary-hover);
}

.btn-primary {
    color: #fff;
    background-color: var(--primary);
    border-color: var(--primary);
}

.btn:focus, .btn:active:focus, .btn-link.nav-link:focus, .form-control:focus, .form-check-input:focus {
    box-shadow: 0 0 0 0.15rem #fff, 0 0 0 0.3rem rgba(79, 70, 229, 0.25);
}

/* ── Checkboxes ─────────────────────────────────────────────────────────────
   Bootstrap's defaults are 1rem / light-grey border and are hard to see.
   Bump to 1.25rem, use a strong border, and fill with primary on check.     */
.form-check-input[type="checkbox"] {
    width: 1.25rem;
    height: 1.25rem;
    margin-top: 0.1rem;
    border: 2px solid #6b7280;
    border-radius: 4px;
    cursor: pointer;
    flex-shrink: 0;
}
.form-check-input[type="checkbox"]:checked {
    background-color: var(--primary);
    border-color: var(--primary);
}
.form-check-input[type="checkbox"]:indeterminate {
    background-color: var(--primary);
    border-color: var(--primary);
}
.form-check-input[type="checkbox"]:focus {
    border-color: var(--primary);
    box-shadow: 0 0 0 0.2rem rgba(79, 70, 229, 0.3);
}
.form-check-label {
    cursor: pointer;
    padding-left: 0.25rem;
}

.content {
    padding-top: 1.5rem;
}

h1:focus {
    outline: none;
}

.valid.modified:not([type=checkbox]) {
    outline: 1px solid var(--success);
}

.invalid {
    outline: 1px solid var(--danger);
}

.validation-message {
    color: var(--danger);
    font-size: 0.875rem;
    margin-top: 0.25rem;
}

/* Modern Card/Surface Styling */
.card, .tab-content, .border {
    background: var(--bg-surface) !important;
    border: 1px solid var(--border-color) !important;
    border-radius: var(--radius-md) !important;
    box-shadow: var(--shadow-sm) !important;
    padding: 1.5rem !important;
    margin-bottom: 1.5rem;
}

/* Phones: 24px of padding per nested surface (page + card + card-body) left a 375px screen with
   ~250px of content. Halve the surface padding and drop the card-body's side padding inside a card,
   which is already padded. */
@media (max-width: 640.98px) {
    .card, .tab-content, .border {
        padding: 0.75rem !important;
        margin-bottom: 1rem;
    }

    .card > .card-body {
        padding-left: 0;
        padding-right: 0;
    }
}

/* Tab container styling override */
.nav-tabs {
    border-bottom: 2px solid var(--border-color);
    gap: 0.25rem;
    margin-bottom: 1.25rem;
}

.nav-tabs .nav-link {
    border: none !important;
    color: var(--text-muted);
    font-weight: 500;
    padding: 0.75rem 1.25rem;
    border-radius: var(--radius-sm);
    transition: all 0.2s ease;
}

.nav-tabs .nav-link:hover {
    background-color: var(--primary-light);
    color: var(--text-main);
}

.nav-tabs .nav-link.active {
    background-color: var(--primary-light) !important;
    color: var(--primary) !important;
    font-weight: 600;
}

/* Syncfusion Grid Modern styling overrides */
.e-grid {
    border: 1px solid var(--border-color) !important;
    border-radius: var(--radius-md) !important;
    overflow: hidden !important;
    box-shadow: var(--shadow-sm) !important;
    background-color: var(--e-grid-content-bg) !important;
    color: var(--e-grid-content-color) !important;
}

.e-grid .e-gridheader {
    background-color: var(--e-grid-header-bg) !important;
    border-bottom: 1px solid var(--border-color) !important;
}

.e-grid .e-headercell {
    background-color: var(--e-grid-header-bg) !important;
    font-weight: 600 !important;
    color: var(--e-grid-header-color) !important;
    padding: 1rem !important;
}

.e-grid .e-gridcontent,
.e-grid .e-content,
.e-grid .e-table {
    background-color: var(--e-grid-content-bg) !important;
}

.e-grid .e-rowcell {
    padding: 1rem !important;
    color: var(--e-grid-content-color) !important;
    background-color: var(--e-grid-content-bg) !important;
    border-bottom: 1px solid var(--border-color) !important;
}

.e-grid .e-row:hover .e-rowcell,
.e-grid .e-row:hover {
    background-color: var(--e-grid-row-hover-bg) !important;
}

.e-grid .e-altrow .e-rowcell,
.e-grid .e-altrow {
    background-color: var(--e-grid-alt-row-bg) !important;
}

.e-grid .e-row.e-selectionbackground .e-rowcell,
.e-grid .e-row.e-selectionbackground {
    background-color: rgba(79, 70, 229, 0.2) !important;
    color: var(--text-main) !important;
}

/* Links in table cells (company names, document numbers...) - lighter in dark theme, see
   --table-link-color in theme.css. Buttons and menu items inside cells keep their own colours. */
.e-grid .e-rowcell a:not(.btn):not(.dropdown-item),
table td a:not(.btn):not(.dropdown-item) {
    color: var(--table-link-color);
}

.e-grid .e-rowcell a:not(.btn):not(.dropdown-item):hover,
table td a:not(.btn):not(.dropdown-item):hover {
    color: var(--table-link-hover);
}

.e-grid .e-pager {
    border-top: 1px solid var(--border-color) !important;
    background-color: var(--bg-surface) !important;
    color: var(--text-main) !important;
}

.e-grid .e-pager .e-pagercontainer {
    background-color: var(--bg-surface) !important;
    border-color: var(--border-color) !important;
}

.e-grid .e-pager .e-link {
    color: var(--text-main) !important;
}

/* The bootstrap5 theme paints page numbers and the first/prev/next/last buttons white, which
   left light text/icons on white boxes in dark mode. Keep them on the pager's surface. */
.e-grid .e-pager .e-numericitem:not(.e-currentitem),
.e-grid .e-pager .e-pagercontainer .e-icons,
.e-grid .e-pager .e-mfirst,
.e-grid .e-pager .e-mprev,
.e-grid .e-pager .e-mnext,
.e-grid .e-pager .e-mlast {
    background-color: transparent !important;
    border-color: var(--border-color) !important;
}

.e-grid .e-pager .e-numericitem:not(.e-currentitem):hover {
    background-color: var(--e-grid-row-hover-bg) !important;
}

.e-grid .e-pager .e-currentitem {
    background-color: var(--primary) !important;
    color: #ffffff !important;
}

/* Pager first/prev/next/last icons default to a dark-gray color meant for a light background -
   nearly invisible against this app's dark surfaces. Disabled icons get a dimmer but still
   visible muted color instead of Syncfusion's default near-transparent gray-on-gray. */
.e-grid .e-pager .e-icons {
    color: var(--text-main) !important;
}

.e-grid .e-pager .e-icons.e-disable,
.e-grid .e-pager .e-icons.e-firstpagedisabled,
.e-grid .e-pager .e-icons.e-prevpagedisabled,
.e-grid .e-pager .e-icons.e-nextpagedisabled,
.e-grid .e-pager .e-icons.e-lastpagedisabled {
    color: var(--text-muted) !important;
    opacity: 0.6 !important;
}

.e-grid .e-pager .e-icons:not(.e-disable):hover {
    color: var(--primary) !important;
}

.e-grid .e-toolbar,
.e-grid .e-toolbar .e-toolbar-items {
    background-color: var(--bg-surface) !important;
    border-color: var(--border-color) !important;
}

/* Modern Button styling */
.e-btn, .btn {
    border-radius: var(--radius-sm) !important;
    font-weight: 500 !important;
    padding: 0.5rem 1.25rem !important;
    transition: all 0.2s ease !important;
}

.e-primary, .btn-primary {
    background-color: var(--primary) !important;
    border-color: var(--primary) !important;
    color: #ffffff !important;
}

.e-primary:hover, .btn-primary:hover {
    background-color: var(--primary-hover) !important;
    border-color: var(--primary-hover) !important;
    transform: translateY(-1px);
    box-shadow: 0 4px 12px rgba(79, 70, 229, 0.2);
}

.e-btn.e-disabled, .e-btn:disabled, .btn:disabled {
    background-color: var(--bg-disabled) !important;
    border-color: var(--bg-disabled) !important;
    color: var(--text-disabled) !important;
    box-shadow: none !important;
    transform: none !important;
    cursor: not-allowed !important;
    opacity: 1 !important;
}

.e-success, .btn-success {
    background-color: var(--success) !important;
    border-color: var(--success) !important;
    color: #ffffff !important;
}

.e-success:hover, .btn-success:hover {
    transform: translateY(-1px);
    box-shadow: 0 4px 12px rgba(16, 185, 129, 0.2);
}

.e-warning, .btn-warning {
    background-color: var(--warning) !important;
    border-color: var(--warning) !important;
    color: #ffffff !important;
}

.e-warning:hover, .btn-warning:hover {
    transform: translateY(-1px);
    box-shadow: 0 4px 12px rgba(245, 158, 11, 0.2);
}

.e-danger, .btn-danger {
    background-color: var(--danger) !important;
    border-color: var(--danger) !important;
    color: #ffffff !important;
}

.e-danger:hover, .btn-danger:hover {
    transform: translateY(-1px);
    box-shadow: 0 4px 12px rgba(239, 68, 68, 0.2);
}

/* Inputs & Form controls */
.form-control, .form-select, .e-input, .e-input-group, .e-input-wrapper, .e-float-input {
    border-radius: var(--radius-sm) !important;
    border: 2px solid var(--input-border) !important;
    background-color: var(--input-bg) !important;
    transition: all 0.2s ease !important;
    color: var(--text-main) !important;
}

.form-control, .form-select, .e-input {
    padding: 0.5rem 0.75rem !important;
}

.form-control:focus, .form-select:focus, .e-input-focus, .e-input-group.e-input-focus, .e-input-wrapper.e-input-focus {
    border-color: var(--primary) !important;
    background-color: var(--input-bg-focus) !important;
    box-shadow: 0 0 0 3px rgba(79, 70, 229, 0.15) !important;
}

/* Header typography */
h1, h2, h3, h4, h5, h6 {
    font-weight: 700 !important;
    color: var(--text-main);
    letter-spacing: -0.025em;
}

h1 {
    font-size: 2.25rem;
    margin-bottom: 1.5rem;
}

/* Badges */
.badge {
    padding: 0.35em 0.65em !important;
    font-weight: 600 !important;
    border-radius: 50px !important;
}

.bg-primary {
    background-color: var(--primary-light) !important;
    color: var(--primary) !important;
}

.bg-success {
    background-color: rgba(16, 185, 129, 0.1) !important;
    color: var(--success) !important;
}

.bg-danger {
    background-color: rgba(239, 68, 68, 0.1) !important;
    color: var(--danger) !important;
}

.blazor-error-boundary {
    background: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTYiIGhlaWdodD0iNDkiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIG92ZXJmbG93PSJoaWRkZW4iPjxkZWZzPjxjbGlwUGF0aCBpZD0iY2xpcDAiPjxyZWN0IHg9IjIzNSIgeT0iNTEiIHdpZHRoPSI1NiIgaGVpZ2h0PSI0OSIvPjwvY2xpcFBhdGg+PC9kZWZzPjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMCkiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0yMzUgLTUxKSI+PHBhdGggZD0iTTI2My41MDYgNTFDMjY0LjcxNyA1MSAyNjUuODEzIDUxLjQ4MzcgMjY2LjYwNiA1Mi4yNjU4TDI2Ny4wNTIgNTIuNzk4NyAyNjcuNTM5IDUzLjYyODMgMjkwLjE4NSA5Mi4xODMxIDI5MC41NDUgOTIuNzk1IDI5MC42NTYgOTIuOTk2QzI5MC44NzcgOTMuNTEzIDI5MSA5NC4wODE1IDI5MSA5NC42NzgyIDI5MSA5Ny4wNjUxIDI4OS4wMzggOTkgMjg2LjYxNyA5OUwyNDAuMzgzIDk5QzIzNy45NjMgOTkgMjM2IDk3LjA2NTEgMjM2IDk0LjY3ODIgMjM2IDk0LjM3OTkgMjM2LjAzMSA5NC4wODg2IDIzNi4wODkgOTMuODA3MkwyMzYuMzM4IDkzLjAxNjIgMjM2Ljg1OCA5Mi4xMzE0IDI1OS40NzMgNTMuNjI5NCAyNTkuOTYxIDUyLjc5ODUgMjYwLjQwNyA1Mi4yNjU4QzI2MS4yIDUxLjQ4MzcgMjYyLjI5NiA1MSAyNjMuNTA2IDUxWk0yNjMuNTg2IDY2LjAxODNDMjYwLjczNyA2Ni4wMTgzIDI1OS4zMTMgNjcuMTI0NSAyNTkuMzEzIDY5LjMzNyAyNTkuMzEzIDY5LjYxMDIgMjU5LjMzMiA2OS44NjA4IDI1OS4zNzEgNzAuMDg4N0wyNjEuNzk1IDg0LjAxNjEgMjY1LjM4IDg0LjAxNjEgMjY3LjgyMSA2OS43NDc1QzI2Ny44NiA2OS43MzA5IDI2Ny44NzkgNjkuNTg3NyAyNjcuODc5IDY5LjMxNzkgMjY3LjgyOSA2Ny4xMTgyIDI2Ni40NDggNjYuMDE4MyAyNjMuNTg2IDY2LjAxODNaTTI2My41NzYgODYuMDU0N0MyNjEuMDQ5IDg2LjA1NDcgMjU5Ljc4NiA4Ny4zMDA1IDI1OS43ODYgODkuNzkyMSAyNTkuNzg2IDkyLjI4MzcgMjYxLjA0OSA5My41Mjk1IDI2My41NzYgOTMuNTI5NSAyNjYuMTE2IDkzLjUyOTUgMjY3LjM4NyA5Mi4yODM3IDI2Ny4zODcgODkuNzkyMSAyNjcuMzg3IDg3LjMwMDUgMjY2LjExNiA4Ni4wNTQ3IDI2My41NzYgODYuMDU0N1oiIGZpbGw9IiNGRkU1MDAiIGZpbGwtcnVsZT0iZXZlbm9kZCIvPjwvZz48L3N2Zz4=) no-repeat 1rem/1.8rem, #b32121;
    padding: 1rem 1rem 1rem 3.7rem;
    color: white;
}

.blazor-error-boundary::after {
    content: "An error has occurred."
}

.form-floating > .form-control-plaintext::placeholder, .form-floating > .form-control::placeholder {
    color: var(--bs-secondary-color);
    text-align: end;
}

.form-floating > .form-control-plaintext:focus::placeholder, .form-floating > .form-control:focus::placeholder {
    text-align: start;
}

/* Premium Visual Redesign & Animations */
.hover-lift {
    transition: transform 0.25s cubic-bezier(0.4, 0, 0.2, 1), box-shadow 0.25s cubic-bezier(0.4, 0, 0.2, 1) !important;
}
.hover-lift:hover {
    transform: translateY(-4px) !important;
    box-shadow: 0 12px 20px -8px rgba(79, 70, 229, 0.15) !important;
}

.fade-in {
    animation: fadeIn 0.4s ease-out forwards;
}

@keyframes fadeIn {
    from {
        opacity: 0;
        transform: translateY(8px);
    }
    to {
        opacity: 1;
        transform: translateY(0);
    }
}

/* Custom modern scrollbars */
::-webkit-scrollbar {
    width: 8px;
    height: 8px;
}
::-webkit-scrollbar-track {
    background: var(--input-bg);
}
::-webkit-scrollbar-thumb {
    background: #cbd5e1;
    border-radius: 4px;
}
::-webkit-scrollbar-thumb:hover {
    background: var(--input-border);
}

/* Syncfusion Dialog Premium Overrides */
.e-dialog {
    border-radius: var(--radius-lg) !important;
    border: 1px solid var(--border-color) !important;
    box-shadow: 0 20px 25px -5px rgba(15, 23, 42, 0.1), 0 10px 10px -5px rgba(15, 23, 42, 0.04) !important;
    background-color: var(--bg-surface) !important;
    overflow: hidden !important;
}

.e-dialog .e-dlg-header-content {
    background-color: var(--bg-surface) !important;
    border-bottom: 1px solid var(--border-color) !important;
    padding: 1.25rem 1.5rem !important;
}

.e-dialog .e-dlg-header {
    font-size: 1.25rem !important;
    font-weight: 700 !important;
    color: var(--text-main) !important;
    letter-spacing: -0.02em !important;
}

.e-dialog .e-dlg-content {
    padding: 1.5rem !important;
    color: var(--text-main) !important;
    background-color: var(--bg-surface) !important;
}

.e-dialog .e-footer-container {
    background-color: var(--bg-surface) !important;
    border-top: 1px solid var(--border-color) !important;
    padding: 1rem 1.5rem !important;
    display: flex !important;
    justify-content: flex-end !important;
    gap: 0.75rem !important;
}

/* Style Dialog Close button */
.e-dialog .e-dlg-closeicon-btn {
    border-radius: 50% !important;
    background-color: transparent !important;
    border: none !important;
    width: 32px !important;
    height: 32px !important;
    display: flex !important;
    align-items: center !important;
    justify-content: center !important;
    transition: all 0.2s ease !important;
    color: var(--text-muted) !important;
    margin: 0 !important;
}

.e-dialog .e-dlg-closeicon-btn:hover {
    background-color: var(--primary-light) !important;
    color: var(--text-main) !important;
}

/* Dialog Form layout spacing adjustments */
.e-dialog form .mb-3 {
    margin-bottom: 1.25rem !important;
}

.e-dialog form label {
    font-weight: 600 !important;
    font-size: 0.875rem !important;
    color: var(--text-main) !important;
    margin-bottom: 0.4rem !important;
}

/* Dialog Form inputs high visibility styling */
.e-dialog .form-control, 
.e-dialog .form-select, 
.e-dialog .e-input, 
.e-dialog .e-input-group, 
.e-dialog .e-input-wrapper, 
.e-dialog .e-float-input {
    border: 2px solid var(--input-border) !important;
    background-color: var(--input-bg) !important;
}

.e-dialog .form-control:focus, 
.e-dialog .form-select:focus, 
.e-dialog .e-input-focus, 
.e-dialog .e-input-group.e-input-focus, 
.e-dialog .e-input-wrapper.e-input-focus {
    border-color: var(--primary) !important;
    background-color: var(--input-bg-focus) !important;
    box-shadow: 0 0 0 3px rgba(79, 70, 229, 0.2) !important;
}



/* ====================================================================
 * Component-scoped CSS (CSS isolation) used to be hand-copied here because
 * the real Blazor-generated bundle (RecuriaAspire.SharedUI's .styles.css,
 * aggregated per-app as RecuriaAspire.Web.styles.css) was never linked in
 * App.razor. That bundle is now linked directly (2026-09-19) and is what
 * actually serves every .razor.css file's rules, properly scoped - so the
 * ~840-line manual duplicate that used to live here (MainLayout, NavMenu,
 * PortalLayout, Login, Home, ConnectivityErrorBoundary) has been removed.
 * Edit the component's own .razor.css file directly; no second copy-paste
 * step is needed anymore. See .claude/memory/app_css_manual_sync_gap_2026_08.md
 * for why this used to be necessary and why it no longer is.
 * ====================================================================
 */

/* The rules below were physically inside the removed block above but were never scoped
   ([b-xxxxxxxx]) to begin with - they are genuinely global overrides, not a duplicate of
   anything in a .razor.css file, so deleting the block would have silently dropped them
   (caught live: the sidebar-collapse button rendered as an unstyled browser-default button
   after the first trim). Kept here, not moved into a component's .razor.css, since none of
   them are actually scoped to one component's rendered markup. */

.sidebar .text-light-emphasis {
    color: var(--chrome-text-muted) !important;
}

/* ====================================================================
 * Collapsible sidebar
 * ==================================================================== */
.nav-collapse-bar {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    padding: 0.4rem 0.5rem;
    background-color: var(--chrome-bg);
    border-bottom: 1px solid var(--chrome-border);
    flex-shrink: 0;
}

.nav-collapse-btn {
    background: none;
    border: none;
    color: var(--icon-muted);
    cursor: pointer;
    padding: 0.3rem 0.4rem;
    border-radius: 4px;
    line-height: 1;
    font-size: 1.1rem;
    transition: color 0.15s, background-color 0.15s;
}

.nav-collapse-btn:hover {
    color: #f1f5f9;
    background-color: rgba(255,255,255,0.08);
}

/* Phones use the hamburger instead; collapsing only does anything from 641px up, and the bar
   sat exactly where the hamburger is drawn, so the two overlapped. */
@media (max-width: 640.98px) {
    .nav-collapse-bar {
        display: none;
    }
}

@media (min-width: 641px) {
    .sidebar.nav-collapsed {
        width: 48px !important;
        overflow: hidden;
        transition: width 0.2s ease;
    }

    .sidebar:not(.nav-collapsed) {
        transition: width 0.2s ease;
    }

    .sidebar.nav-collapsed .nav-collapse-bar {
        justify-content: center;
        padding: 0.4rem 0;
    }

    .sidebar.nav-collapsed .top-row,
    .sidebar.nav-collapsed .navbar-toggler,
    .sidebar.nav-collapsed .nav-scrollable {
        display: none !important;
    }
}

/* Create Subscription product/service picker: popup should shrink to fit its
   longest item, but never grow past double the field's own width. */
.product-picker-wide.e-popup {
    max-width: 1870px !important;
    width: auto !important;
}

/* ==========================================================================
   AI Assistant Floating Balloon, SfDialog & SfAIAssistView Theming
   ========================================================================== */

.ai-assistant-fab {
    position: fixed;
    right: 1.5rem;
    bottom: 1.5rem;
    width: 3.5rem;
    height: 3.5rem;
    border-radius: 50%;
    border: none;
    background: linear-gradient(135deg, var(--accent-indigo) 0%, var(--accent-blue) 50%, var(--accent-cyan) 100%);
    color: #fff;
    font-size: 1.35rem;
    display: flex;
    align-items: center;
    justify-content: center;
    box-shadow: 0 6px 20px rgba(99, 102, 241, 0.4);
    z-index: 1060;
    cursor: pointer;
    transition: transform 0.2s cubic-bezier(0.4, 0, 0.2, 1), box-shadow 0.2s cubic-bezier(0.4, 0, 0.2, 1);
}

.ai-assistant-fab:hover {
    transform: scale(1.08);
    box-shadow: 0 8px 25px rgba(99, 102, 241, 0.55);
}

.ai-assistant-fab:active {
    transform: scale(0.95);
}

.ai-assistant-fab-open {
    background: linear-gradient(135deg, var(--primary) 0%, var(--accent-blue-dark) 100%);
    box-shadow: 0 4px 16px rgba(79, 70, 229, 0.5);
}

.ai-assistant-badge {
    position: absolute;
    top: -4px;
    right: -4px;
    min-width: 1.4rem;
    height: 1.4rem;
    padding: 0 0.35rem;
    border-radius: 9999px;
    background-color: var(--danger);
    color: #ffffff;
    font-size: 0.75rem;
    font-weight: 700;
    line-height: 1.4rem;
    text-align: center;
    box-shadow: 0 0 0 2px var(--bs-body-bg, #fff), 0 2px 6px rgba(239, 68, 68, 0.6);
    animation: ai-pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
}

@keyframes ai-pulse {
    0%, 100% {
        transform: scale(1);
    }
    50% {
        transform: scale(1.15);
    }
}

/* SfDialog overrides for AI Assistant Window.
   Syncfusion's non-modal SfDialog (IsModal="false") renders .e-dialog as position:absolute,
   parented directly under <body> with an inline top/left computed in document coordinates -
   there is no .e-dlg-container wrapper to anchor it, so it scrolls away with the page instead
   of staying put like the FAB. Force position:fixed anchored to the viewport corner and ignore
   Syncfusion's inline top/left entirely (DialogPositionData X="right" Y="bottom" in the .razor
   only drives the initial open animation, not final placement). */
.ai-assistant-dialog.e-dialog {
    position: fixed !important;
    top: auto !important;
    left: auto !important;
    right: 1.5rem !important;
    bottom: 1.5rem !important;
    max-width: calc(100vw - 2rem) !important;
    max-height: calc(100vh - 2rem) !important;
    border-radius: 12px !important;
    overflow: hidden !important;
    box-shadow: 0 20px 40px rgba(0, 0, 0, 0.22) !important;
    border: 1px solid var(--bs-border-color, var(--border-color)) !important;
    background: var(--bs-body-bg, #ffffff) !important;
}

/* Phones: same 12px margins as every other dialog (see the .e-dialog phone rule), opened from
   the avatar menu since the floating button is hidden at this width. */
@media (max-width: 640.98px) {
    .ai-assistant-dialog.e-dialog {
        right: 12px !important;
        bottom: 12px !important;
        width: calc(100vw - 24px) !important;
        max-width: calc(100vw - 24px) !important;
        max-height: calc(100dvh - 24px) !important;
    }
}

.ai-assistant-dialog .e-dlg-header-content {
    background: var(--bs-tertiary-bg, var(--bg-app)) !important;
    border-bottom: 1px solid var(--bs-border-color, var(--border-color)) !important;
    padding: 0.75rem 1rem !important;
}

.ai-assistant-dialog .e-dlg-header {
    width: 100%;
}

.ai-assistant-dialog .e-dlg-content {
    padding: 0.75rem !important;
    overflow: hidden !important;
    background: var(--bs-body-bg, #ffffff) !important;
}

.ai-dialog-body-container {
    height: 100%;
    display: flex;
    flex-direction: column;
    overflow: hidden;
}

/* SfAIAssistView general styling */
.ai-assistview-custom.e-aiassistview {
    height: 100% !important;
    border: none !important;
    background: transparent !important;
}

.ai-assistview-custom .e-views {
    background: transparent !important;
}

.ai-assistview-custom .e-banner-view {
    background: transparent !important;
}

.ai-banner-icon {
    font-size: 2.25rem;
}

/* Pending write confirmation action cards */
.ai-pending-card {
    background: var(--bs-tertiary-bg, var(--bg-app));
    border: 1px solid rgba(245, 158, 11, 0.35) !important;
    border-left: 3px solid var(--warning) !important;
    font-size: 0.875rem;
}

/* Dark Mode Overrides for Assistant Dialog & SfAIAssistView */
[data-theme="dark"] .ai-assistant-dialog.e-dialog,
[data-bs-theme="dark"] .ai-assistant-dialog.e-dialog {
    background: var(--bg-surface) !important;
    border: 1px solid var(--border-color-strong) !important;
    box-shadow: 0 20px 45px rgba(0, 0, 0, 0.6) !important;
}

[data-theme="dark"] .ai-assistant-dialog .e-dlg-header-content,
[data-bs-theme="dark"] .ai-assistant-dialog .e-dlg-header-content {
    background: var(--bg-elevated) !important;
    border-bottom: 1px solid var(--border-color-strong) !important;
    color: var(--text-main) !important;
}

[data-theme="dark"] .ai-assistant-dialog .e-dlg-closeicon-btn,
[data-bs-theme="dark"] .ai-assistant-dialog .e-dlg-closeicon-btn {
    color: var(--icon-muted) !important;
}

[data-theme="dark"] .ai-assistant-dialog .e-dlg-closeicon-btn:hover,
[data-bs-theme="dark"] .ai-assistant-dialog .e-dlg-closeicon-btn:hover {
    color: var(--text-main) !important;
}

[data-theme="dark"] .ai-assistant-dialog .e-dlg-content,
[data-bs-theme="dark"] .ai-assistant-dialog .e-dlg-content {
    background: var(--bg-surface) !important;
    color: var(--text-main) !important;
}

[data-theme="dark"] .ai-assistview-custom.e-aiassistview,
[data-bs-theme="dark"] .ai-assistview-custom.e-aiassistview {
    background: var(--bg-surface) !important;
    color: var(--text-main) !important;
}

[data-theme="dark"] .ai-assistview-custom .e-view,
[data-bs-theme="dark"] .ai-assistview-custom .e-view {
    background: var(--bg-surface) !important;
    color: var(--text-main) !important;
}

[data-theme="dark"] .ai-assistview-custom .e-footer,
[data-bs-theme="dark"] .ai-assistview-custom .e-footer {
    background: var(--bg-elevated) !important;
    border-top: 1px solid var(--border-color-strong) !important;
}

[data-theme="dark"] .ai-assistview-custom textarea.e-input,
[data-bs-theme="dark"] .ai-assistview-custom textarea.e-input {
    background: var(--bg-surface) !important;
    color: var(--text-main) !important;
    border: 1px solid var(--border-color-strong) !important;
}

[data-theme="dark"] .ai-assistview-custom .e-suggestion-item,
[data-bs-theme="dark"] .ai-assistview-custom .e-suggestion-item {
    background: var(--bg-elevated) !important;
    border: 1px solid var(--border-color-strong) !important;
    color: var(--accent-blue-light) !important;
}

[data-theme="dark"] .ai-assistview-custom .e-suggestion-item:hover,
[data-bs-theme="dark"] .ai-assistview-custom .e-suggestion-item:hover {
    background: var(--border-color-strong) !important;
    color: var(--accent-blue-lighter) !important;
}

[data-theme="dark"] .ai-assistview-custom .e-prompt-item,
[data-bs-theme="dark"] .ai-assistview-custom .e-prompt-item {
    background: var(--accent-purple-bg) !important;
    color: var(--accent-purple-text) !important;
    border: 1px solid var(--primary-hover) !important;
}

[data-theme="dark"] .ai-assistview-custom .e-response-item,
[data-bs-theme="dark"] .ai-assistview-custom .e-response-item {
    background: var(--bg-elevated) !important;
    color: var(--text-main) !important;
    border: 1px solid var(--border-color-strong) !important;
}

[data-theme="dark"] .ai-pending-card,
[data-bs-theme="dark"] .ai-pending-card {
    background: rgba(var(--bg-elevated-rgb), 0.75) !important;
    border: 1px solid rgba(245, 158, 11, 0.4) !important;
    border-left: 3px solid var(--warning) !important;
    color: var(--text-main) !important;
}

/* Corrected dark-mode fixes (2026-09-19): the .e-suggestion-item/.e-prompt-item/.e-response-item
   rules above target class names that were guessed, not the ones SfAIAssistView actually renders
   - confirmed live via computed-style DOM inspection in the browser. Left the old rules in place
   (harmless, unmatched) and added the real selectors below so every part of the dialog is legible
   in dark mode: the header title row, the "AI Assist" tab strip, suggestion chips, the footer
   toolbar/send button, and prompt bubbles all inherited Bootstrap's light-mode default text color
   instead of the dialog's dark background. */
[data-theme="dark"] .ai-assistant-dialog .e-dlg-header *,
[data-bs-theme="dark"] .ai-assistant-dialog .e-dlg-header * {
    color: var(--text-main) !important;
}

[data-theme="dark"] .ai-assistview-custom .e-view-content,
[data-bs-theme="dark"] .ai-assistview-custom .e-view-content,
[data-theme="dark"] .ai-assistview-custom .e-view-header,
[data-bs-theme="dark"] .ai-assistview-custom .e-view-header {
    color: var(--text-main) !important;
    background: transparent !important;
}

[data-theme="dark"] .ai-assistview-custom .e-toolbar,
[data-bs-theme="dark"] .ai-assistview-custom .e-toolbar {
    background: var(--bg-elevated) !important;
    border-color: var(--border-color-strong) !important;
}

[data-theme="dark"] .ai-assistview-custom .e-toolbar-items,
[data-bs-theme="dark"] .ai-assistview-custom .e-toolbar-items {
    background: transparent !important;
}

[data-theme="dark"] .ai-assistview-custom .e-toolbar-item,
[data-bs-theme="dark"] .ai-assistview-custom .e-toolbar-item,
[data-theme="dark"] .ai-assistview-custom .e-toolbar .e-tab-text,
[data-bs-theme="dark"] .ai-assistview-custom .e-toolbar .e-tab-text {
    color: var(--text-main) !important;
}

[data-theme="dark"] .ai-assistview-custom .e-suggestion-list li,
[data-bs-theme="dark"] .ai-assistview-custom .e-suggestion-list li {
    color: var(--accent-blue-light) !important;
    border-color: var(--input-border) !important;
}

[data-theme="dark"] .ai-assistview-custom .e-footer,
[data-bs-theme="dark"] .ai-assistview-custom .e-footer,
[data-theme="dark"] .ai-assistview-custom .e-footer *,
[data-bs-theme="dark"] .ai-assistview-custom .e-footer * {
    color: var(--text-main) !important;
}

[data-theme="dark"] .ai-assistview-custom .e-footer-icons-wrapper .e-tbar-btn,
[data-bs-theme="dark"] .ai-assistview-custom .e-footer-icons-wrapper .e-tbar-btn {
    background: var(--border-color-strong) !important;
}

[data-theme="dark"] .ai-assistview-custom .e-prompt-text,
[data-bs-theme="dark"] .ai-assistview-custom .e-prompt-text {
    background: var(--accent-purple-bg) !important;
    color: var(--accent-purple-text) !important;
    border: 1px solid var(--primary-hover) !important;
}


/* ============================================================================
 * Shared layout utility classes (2026-09-19) - extracted from inline style="..."
 * attributes repeated across many pages. Inline styles scattered across ~50
 * page files made layout bugs hard to trace (nothing to grep for, no single
 * place to fix a shared idiom). These give the common patterns one name and
 * one definition; page-specific one-off styles still live in that page's own
 * .razor.css instead of inline.
 * ============================================================================ */

/* Full-viewport invisible click-catcher, closes a menu/dropdown on outside click.
   Two z-index tiers matching the two stacking contexts already in use around the app. */
.click-away-backdrop {
    position: fixed;
    top: 0;
    left: 0;
    width: 100vw;
    height: 100vh;
    z-index: 1040;
}

.click-away-backdrop-high {
    position: fixed;
    top: 0;
    left: 0;
    width: 100vw;
    height: 100vh;
    z-index: 1049;
}

/* Autocomplete/typeahead suggestion dropdown panel (line-item SKU/description lookups
   on Invoice/Order/Quote builders). Never wider than the viewport, so phones don't scroll sideways. */
.autocomplete-menu {
    min-width: min(max(100%, 420px), calc(100vw - 16px));
    max-height: 260px;
    overflow-y: auto;
    z-index: 1050;
    margin-top: 1px;
}

.autocomplete-menu-compact {
    max-height: 200px;
    overflow-y: auto;
    z-index: 1050;
    margin-top: 1px;
}

/* Row-actions kebab menu - positioned via JS right after open, starts hidden/fixed
   at (0,0) to avoid a flash at the wrong location before JS repositions it. */
.row-actions-menu {
    position: fixed;
    top: 0;
    left: 0;
    visibility: hidden;
    z-index: 1050;
    min-width: 180px;
}

/* Row-actions trigger on touch screens: the button keeps its compact look (rows stay at
   --control-height) but an invisible overlay grows the tap area to at least 44x44px. */
@media (pointer: coarse) {
    .row-actions-trigger {
        position: relative;
    }

    .row-actions-trigger::after {
        content: "";
        position: absolute;
        top: 50%;
        left: 50%;
        width: max(100%, 44px);
        height: max(100%, 44px);
        transform: translate(-50%, -50%);
    }
}

/* RowActionsMenu used with a custom TriggerContent (e.g. a clickable status pill) instead of the
   default "..." button - strips the native <button> chrome so the trigger reads as a plain badge. */
.status-pill-trigger {
    border: none;
    cursor: pointer;
}

.status-pill-trigger:hover {
    filter: brightness(1.1);
}

/* Small circular icon/avatar holder, 32x32 - the standard compact icon-circle size. */
.icon-circle-sm {
    width: 2rem;
    height: 2rem;
}

/* Preformatted-but-wrapping text (preserve whitespace/newlines from user input, still wrap). */
.text-prewrap {
    white-space: pre-wrap;
}

/* Height-capped, vertically scrollable box for lists/notes that can grow long. */
.scroll-box-sm {
    max-height: 120px;
    overflow-y: auto;
}

.scroll-box-md {
    max-height: 150px;
    overflow-y: auto;
    padding-right: 5px;
}

.cursor-pointer {
    cursor: pointer;
}

/* Semi-transparent dark scrim behind a custom (non-Bootstrap) modal-style overlay. */
.modal-scrim {
    background: rgba(0, 0, 0, 0.5);
}

/* Narrow centered page container - the standard content width for portal/public pages
   (contracts, secure exchange, drop box). See [[feedback_dialog_width_default]] for the
   66% convention this matches. */
.page-container-narrow {
    width: 66%;
    min-width: 320px;
    max-width: 1400px;
    margin: 0 auto;
}

/* Table column width utilities - percentage-based, used across several data-grid tables
   to keep column proportions consistent without repeating the raw percentage inline. */
.col-w-8 { width: 8%; }
.col-w-10 { width: 10%; }
.col-w-12 { width: 12%; }
.col-w-13 { width: 13%; }

/* Dropdown/panel width variants (autocomplete results, small popovers). */
.max-w-280 { max-width: 280px; }
.max-w-320 { max-width: 320px; }
.max-w-420 { max-width: 420px; }

/* Small stacking-order utilities, extracted from one-off inline style="z-index: N" attributes
   sprinkled around click-away backdrops and dropdown menus. */
.z-1040 { z-index: 1040; }
.z-1050 { z-index: 1050; }

/* Custom (non-Bootstrap-JS) dropdown menu, positioned below its trigger via plain CSS since
   these dropdowns are opened/closed with a bool flag in code, not Bootstrap's JS plugin. */
.dropdown-menu-positioned-start {
    position: absolute;
    left: 0;
    top: 100%;
    z-index: 1050;
}

.dropdown-menu-positioned-end {
    position: absolute;
    right: 0;
    top: 100%;
    z-index: 1050;
}

/* Shared between MainLayout and PortalLayout's topbar tenant switcher. */
.topbar-icon-compact {
    font-size: 0.95rem;
}

.tenant-select-compact {
    max-width: 180px;
    box-shadow: none;
    font-size: 0.85rem;
}

.col-w-26 { width: 26%; }

/* Wider variant of .autocomplete-menu for description-search dropdowns needing more room. */
.autocomplete-menu-wide {
    min-width: min(max(100%, 560px), calc(100vw - 16px));
    max-height: 260px;
    overflow-y: auto;
    z-index: 1050;
    margin-top: 1px;
}

.max-w-75pct { max-width: 75%; }

/* Shared between ClientFile and SupplierFile's site-list rows. */
.site-address-pin-icon {
    background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='%234f46e5' viewBox='0 0 16 16'><path d='M8 16s6-5.686 6-10A6 6 0 0 0 2 6c0 4.314 6 10 6 10zm0-7a3 3 0 1 1 0-6 3 3 0 0 1 0 6z'/></svg>");
    background-size: cover;
    width: 0.9rem;
    height: 0.9rem;
    display: inline-block;
    vertical-align: middle;
    margin-right: 0.35rem;
}

.badge-xs {
    font-size: 0.65rem;
}

.badge-xxs {
    font-size: 0.6rem;
}

/* Shared client-branding header bar (logo + colored strip) used on public/portal
   secure-exchange and drop-box pages. Background color is per-tenant data and stays inline. */
.branding-header-bar {
    color: #fff;
}

.branding-logo {
    max-height: 48px;
    max-width: 180px;
    object-fit: contain;
}

/* Narrow centered container for embeddable public pages (drop box), full width when embedded
   in an iframe, capped/centered otherwise. */
.page-container-embed {
    width: 100%;
    padding: 0 0.5rem;
}

.page-container-narrow-public {
    width: 66%;
    min-width: 320px;
    max-width: 1100px;
    margin: 2rem auto;
    padding: 0 1rem;
}

/* 66% of viewport with extra top/bottom margin, per the standing width rule for client-facing
   pages ([[feedback_dialog_width_default]]) - shared by public secure-exchange/contract-sign pages. */
.page-container-narrow-padded {
    width: 66%;
    min-width: 320px;
    max-width: 1400px;
    margin: 2rem auto;
    padding: 0 1rem;
}

/* Shared document preview iframe container, used by Template Library and Template Editor. */
.template-preview-frame-container {
    height: 600px;
    overflow: auto;
    background: #888;
}

.template-preview-frame {
    width: 100%;
    height: 100%;
    border: none;
    background: #fff;
}

.row-actions-menu-wide {
    position: fixed;
    top: 0;
    left: 0;
    visibility: hidden;
    z-index: 1050;
    min-width: 200px;
}

.col-w-25 { width: 25%; }
.input-w-80 { width: 80px; }
.input-w-100 { width: 100px; }

/* Shared contract signing view (body viewer + signature name input), used by both the public
   and portal contract-signing pages. */
.contract-body-viewer {
    height: 600px;
    overflow-y: auto;
    padding: 2rem;
    background: #fff;
}

.signature-name-input {
    max-width: 380px;
}

.col-w-24 { width: 24%; }
.col-w-5 { width: 5%; }
.col-w-7 { width: 7%; }
.col-w-17 { width: 17%; }
.col-w-18 { width: 18%; }
.col-w-48 { width: 48%; }

/* Invoice/Quote/Order line tables: no number spinners - they ate most of the Qty / Unit Price /
   Rebate boxes and hid values above two digits. Arrow keys still step the value. */
.line-items input[type=number] {
    -moz-appearance: textfield;
    appearance: textfield;
}

.line-items input[type=number]::-webkit-outer-spin-button,
.line-items input[type=number]::-webkit-inner-spin-button {
    -webkit-appearance: none;
    margin: 0;
}
.col-w-9 { width: 9%; }

.hint-bg-primary-light { background: var(--primary-light); }
.col-w-40 { width: 40px; }

.textarea-code-sm { font-size: 0.82rem; }

.badge-existing-user { font-size: 0.65em; }

/* Session Lock Screen Overlay (Resilience Plan Tier 2) */
.session-lock-overlay {
    position: fixed;
    top: 0;
    left: 0;
    width: 100vw;
    height: 100vh;
    background: rgba(15, 23, 42, 0.78);
    backdrop-filter: blur(8px);
    -webkit-backdrop-filter: blur(8px);
    z-index: 10050;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 1.5rem;
}

.session-lock-card {
    background: var(--bg-surface, #ffffff);
    color: var(--text-main, #0f172a);
    border-radius: 12px;
    padding: 2.25rem 2rem;
    width: 100%;
    max-width: 420px;
    box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.3), 0 8px 10px -6px rgba(0, 0, 0, 0.3);
    border: 1px solid var(--border-color, #e2e8f0);
}

/* Subtle Circuit Reconnection Status Indicator (Resilience Plan Tier 5) */
#components-reconnect-modal {
    position: fixed;
    top: 1rem;
    right: 1.5rem;
    z-index: 10060;
    display: none;
    background: #ffffff;
    color: #0f172a;
    box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -4px rgba(0, 0, 0, 0.1);
    border-radius: 8px;
    padding: 0.6rem 1rem;
    font-size: 0.85rem;
    font-weight: 500;
    border: 1px solid #cbd5e1;
}

/* Phones: the text is wider than the space left of right:1.5rem, so it touched the left edge. */
@media (max-width: 640.98px) {
    #components-reconnect-modal {
        top: 12px;
        left: 12px;
        right: 12px;
    }
}

#components-reconnect-modal.components-reconnect-show {
    display: block !important;
}

#components-reconnect-modal.components-reconnect-show > .components-reconnect-show {
    display: flex !important;
}

#components-reconnect-modal.components-reconnect-show > .components-reconnect-failed,
#components-reconnect-modal.components-reconnect-show > .components-reconnect-rejected {
    display: none !important;
}

#components-reconnect-modal.components-reconnect-failed {
    display: block !important;
    border-color: #ef4444;
}

#components-reconnect-modal.components-reconnect-failed > .components-reconnect-failed {
    display: flex !important;
}

#components-reconnect-modal.components-reconnect-failed > .components-reconnect-show,
#components-reconnect-modal.components-reconnect-failed > .components-reconnect-rejected {
    display: none !important;
}

#components-reconnect-modal.components-reconnect-rejected {
    display: block !important;
    border-color: #f59e0b;
}

#components-reconnect-modal.components-reconnect-rejected > .components-reconnect-rejected {
    display: flex !important;
}

#components-reconnect-modal.components-reconnect-rejected > .components-reconnect-show,
#components-reconnect-modal.components-reconnect-rejected > .components-reconnect-failed {
    display: none !important;
}

#components-reconnect-modal > div {
    display: none;
}

/* Line-item rebate box (Invoice, Quote and Order builders): amount + a % / $ toggle. The toggle
   was squeezed to a sliver next to the number spinner in a 13% column (2026-10-01). Keep both on
   one line, give the toggle a fixed clickable width, and drop the spinner arrows - rebates are
   typed, and the arrows took most of the remaining width. */
.rebate-group {
    flex-wrap: nowrap;
}

.rebate-group .form-control {
    min-width: 4.5rem;
    -moz-appearance: textfield;
    appearance: textfield;
}

.rebate-group .form-control::-webkit-outer-spin-button,
.rebate-group .form-control::-webkit-inner-spin-button {
    -webkit-appearance: none;
    margin: 0;
}

.rebate-group .rebate-toggle {
    flex: 0 0 2.25rem;
    min-width: 2.25rem;
    padding-left: 0;
    padding-right: 0;
    font-weight: 600;
}

/* Phones: document line items (opt-in class line-items-stack on Invoice/Quote/Order...) turn each
   row into a small card - 8 columns don't fit 375px, and the table used to widen the whole page.
   Still one table with the new-line row in tfoot (line-item standing rule), and no scroll
   container, so the SKU/description autocomplete dropdowns aren't clipped. Each cell carries its
   column title in data-label; li-* classes mark the full-width and total cells. */
@media (max-width: 640.98px) {
    table.line-items-stack,
    table.line-items-stack > tbody,
    table.line-items-stack > tfoot {
        display: block;
        width: 100%;
    }

    table.line-items-stack > thead {
        display: none;
    }

    /* Cells flow in source order, two per row; the ones below span the full width. Works for
       every editor's column set (Invoice/Quote/Order, Credit Notes, Purchases). */
    table.line-items-stack > tbody > tr,
    table.line-items-stack > tfoot > tr {
        position: relative;
        display: grid;
        grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
        gap: 0.5rem 0.75rem;
        padding: 0.75rem;
        margin-bottom: 0.75rem;
        border: var(--border-width) solid var(--border-color);
        border-radius: var(--radius-sm);
        background-color: var(--bg-surface);
    }

    /* The new-line row reads as "add another" rather than as a saved line. */
    table.line-items-stack > tfoot > tr {
        background-color: var(--bg-elevated);
        border-style: dashed;
    }

    table.line-items-stack > tbody > tr > td,
    table.line-items-stack > tfoot > tr > td {
        display: block;
        min-width: 0;
        padding: 0 !important;
        border: 0;
        background-color: transparent !important;
        box-shadow: none !important;
    }

    table.line-items-stack td[data-label]::before {
        content: attr(data-label);
        display: block;
        margin-bottom: 0.15rem;
        font-size: var(--font-size-xs);
        font-weight: 600;
        color: var(--text-muted);
    }

    table.line-items-stack td.li-sku,
    table.line-items-stack td.li-desc,
    table.line-items-stack tr:not(:has(> td.li-account)) > td.li-tax {
        grid-column: 1 / -1;
    }

    table.line-items-stack td.li-total {
        grid-column: 2;
        align-self: end;
    }

    /* Room for the remove button beside the first field. */
    table.line-items-stack tr:has(> td.li-remove:not(:empty)) > td:first-child {
        padding-right: 3.5rem !important;
    }

    /* Remove button in the card's top-right corner (the first field leaves room for it). */
    table.line-items-stack td.li-remove {
        position: absolute;
        top: 0.75rem;
        right: 0.75rem;
    }

    table.line-items-stack td.li-remove:empty {
        display: none;
    }

    table.line-items-stack td.li-remove .btn {
        min-width: 44px;
        min-height: 44px;
    }

    /* Suggestions match the field's width - the generic 100vw cap doesn't allow for the field
       starting ~37px in, so they ran past the right edge. */
    table.line-items-stack .autocomplete-menu,
    table.line-items-stack .autocomplete-menu-wide {
        min-width: 100%;
        width: 100%;
    }
}

/* Phones: product suggestions keep one line each (SKU, description, price) and the list scrolls
   sideways to show the rest - at ~300px the description was cut and the price wrapped under it.
   The price is inline at the end of the line rather than floated right, so it scrolls with it. */
@media (max-width: 640.98px) {
    .autocomplete-menu,
    .autocomplete-menu-wide {
        overflow-x: auto;
        overscroll-behavior-x: contain;
    }

    .autocomplete-menu .dropdown-item,
    .autocomplete-menu-wide .dropdown-item {
        width: max-content;
        min-width: 100%;
        white-space: nowrap;
    }

    .autocomplete-menu .dropdown-item .float-end,
    .autocomplete-menu-wide .dropdown-item .float-end {
        float: none !important;
        margin-left: 1rem;
    }
}

/* Bootstrap modals follow the same 75vw default as SfDialog forms (see
   .claude/memory/feedback_dialog_width_default.md). Small confirm prompts keep Bootstrap's default. */
.modal-dialog.modal-75vw {
    --bs-modal-width: 75vw;
}

/* Phones: every SfDialog fills the screen width minus a small margin. 75vw is too narrow there
   and fixed 400/420px confirms are too wide. Width only - Syncfusion keeps doing the positioning,
   so dragging/resizing (AI assistant) still works. */
@media (max-width: 640.98px) {
    .e-dialog {
        width: calc(100vw - 24px) !important;
        max-width: calc(100vw - 24px) !important;
        max-height: calc(100dvh - 24px) !important;
    }
}

/* STANDING RULE - every input, select and dropdown takes its height from --control-height
   (theme/theme.css), so changing that one token resizes them all. Text vertically centred and
   left-padded. See .claude/memory/feedback_dropdown_alignment_standard.md. */
input.form-control:not(.form-control-sm):not(.form-control-lg):not(.form-control-color):not([type=range]),
select.form-select:not(.form-select-sm):not(.form-select-lg):not([multiple]):not([size]),
.e-input-group:not(.e-multi-line-input):not(.e-grid *):not(.e-pager *),
.e-input-wrapper:not(.e-multi-line-input):not(.e-grid *):not(.e-pager *) {
    height: var(--control-height);
}

input.form-control.form-control-sm:not([type=range]),
select.form-select.form-select-sm:not([multiple]):not([size]) {
    height: var(--control-height-sm);
}

/* Phones and tablets: iOS Safari zooms the whole page into any field under 16px when it's tapped,
   which shifts fixed elements and leaves the page zoomed. Any touch screen (pointer: coarse - an
   iPad is wider than the phone breakpoint) and any phone-width window: Bootstrap fields (0.875rem
   when small), Syncfusion inputs (14px) and unstyled fields go to 16px. Heights still come from
   --control-height above, so alignment with neighbouring buttons is unchanged. */
@media (max-width: 640.98px), (pointer: coarse) {
    input.form-control,
    select.form-select,
    textarea.form-control,
    input.e-input,
    textarea.e-input,
    .e-input-group input,
    .e-input-group textarea,
    input:is([type=text], [type=search], [type=email], [type=tel], [type=url], [type=number], [type=password], [type=date], [type=datetime-local], [type=time], [type=month]),
    input:not([type]),
    select,
    textarea {
        font-size: 16px !important;
    }
}

/* Notched / rounded iPhones (viewport-fit=cover, Web App.razor): the page runs under the status
   bar, the notch and the home indicator, so the elements touching an edge keep clear of it.
   env() is 0 everywhere else (desktop, Android, the MAUI app's WebView, which keeps its own
   viewport), so these change nothing there. */
#blazor-error-ui {
    padding-bottom: calc(0.75rem + env(safe-area-inset-bottom, 0px));
}

.ai-assistant-fab {
    bottom: calc(1.5rem + env(safe-area-inset-bottom, 0px));
    right: calc(1.5rem + env(safe-area-inset-right, 0px));
}

#components-reconnect-modal {
    top: calc(1rem + env(safe-area-inset-top, 0px)) !important;
}

/* The height alone sets the size and the browser centres the text, so drop Bootstrap's vertical
   padding - at 40px/35px it would leave less room than the line height and clip descenders. */
input.form-control:not(.form-control-color):not([type=range]),
select.form-select:not([multiple]):not([size]),
.e-input-group:not(.e-multi-line-input):not(.e-grid *):not(.e-pager *) > input.e-input {
    padding-top: 0 !important;
    padding-bottom: 0 !important;
}

/* Buttons follow the same tokens, so a button beside a field is the same height. Padding is derived
   from the line height rather than a fixed height, so a label that wraps still grows to fit. */
.btn:not(.btn-sm):not(.btn-lg),
.e-btn:not(.e-small):not(.e-bigger) {
    padding-top: calc((var(--control-height) - 1lh - 2px) / 2) !important;
    padding-bottom: calc((var(--control-height) - 1lh - 2px) / 2) !important;
}

.btn.btn-sm,
.e-btn.e-small {
    padding-top: calc((var(--control-height-sm) - 1lh - 2px) / 2) !important;
    padding-bottom: calc((var(--control-height-sm) - 1lh - 2px) / 2) !important;
}

/* Buttons and addons inside an input group take the field's height (they stretch), not their own. */
.input-group > .btn:not(.btn-lg):not(.btn-link),
.input-group > .input-group-text {
    padding-top: 0 !important;
    padding-bottom: 0 !important;
}

/* Syncfusion pins the inner <input> at 30px; let it fill the taller box so its text stays centred.
   Grids and pagers are left at Syncfusion's compact sizing. */
.e-input-group:not(.e-multi-line-input):not(.e-grid *):not(.e-pager *) > input.e-input,
.e-input-wrapper:not(.e-multi-line-input):not(.e-grid *):not(.e-pager *) > input.e-input {
    height: auto;
    align-self: stretch;
}

/* Selected value of a dropdown that uses <ValueTemplate> (e.g. the client pickers):
   Syncfusion renders it as an unpadded block, so it hugs the top-left of the box. */
.e-ddl .e-input-value {
    display: flex;
    align-items: center;
    padding-left: 0.75rem;
    overflow: hidden;
    white-space: nowrap;
}

/* ---- Import/Export category picker (ImportExportCategoryPicker.razor) ----
   Toolbar: title, "x of y selected", Select all / Clear. Groups in a responsive grid; each group's
   checkbox sits in the same column as its items' checkboxes, items indented beneath it. */
.ie-picker-toolbar {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    flex-wrap: wrap;
}

.ie-picker-count {
    font-size: var(--font-size-sm);
    opacity: 0.8;
}

.ie-picker-actions {
    margin-left: auto;
    display: flex;
    gap: var(--space-2);
}

.ie-picker-grid {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: var(--space-3);
}

@media (max-width: 1199.98px) {
    .ie-picker-grid {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

@media (max-width: 767.98px) {
    .ie-picker-grid {
        grid-template-columns: minmax(0, 1fr);
    }
}

.ie-group {
    border: var(--border-width) solid var(--border-color);
    border-radius: var(--radius-sm);
    background-color: var(--bg-elevated);
    padding: var(--space-3);
}

.ie-group-header {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    padding-bottom: var(--space-2);
    margin-bottom: var(--space-2);
    border-bottom: var(--border-width) solid var(--border-color);
}

.ie-group-header .form-check-input {
    margin: 0;
    float: none;
}

.ie-group-title {
    font-weight: var(--font-weight-semibold);
    text-transform: uppercase;
    font-size: var(--font-size-sm);
    letter-spacing: 0.02em;
    cursor: pointer;
    margin: 0;
}

.ie-group-count {
    margin-left: auto;
    font-size: var(--font-size-xs);
    color: var(--text-muted);
    white-space: nowrap;
}

/* Items indented so their checkboxes line up under the group checkbox's right edge. */
.ie-group-items .form-check {
    margin-bottom: var(--space-1);
}

@media (min-width: 768px) {
    .h-100-md {
        height: calc(100% - 1rem);
    }
}

/* Database clone developer tool (Admin > Import/Export): set apart from the tenant backup above
   by a heavier rule, since it moves the WHOLE database rather than one tenant's records. */
.database-clone-section {
    margin-top: var(--space-6);
    padding-top: var(--space-4);
    border-top: calc(var(--border-width) * 3) dashed var(--border-color-strong);
}

.database-clone-meta {
    font-size: var(--font-size-sm);
    color: var(--text-muted);
    margin-bottom: var(--space-3);
    overflow-wrap: anywhere;
}

/* Upload/restore status line, written by databaseClone.upload (fileDownload.js). */
.database-clone-progress {
    margin-top: var(--space-2);
    font-size: var(--font-size-sm);
    color: var(--text-muted);
    min-height: 1.25rem;
}

/* Database clone restore progress: step + spinner, one bar, detail and elapsed time. */
.database-clone-progress {
    margin-top: var(--space-3);
    padding: var(--space-3);
    border: var(--border-width) solid var(--border-color);
    border-radius: var(--radius-sm);
    background-color: var(--bg-elevated);
}

.database-clone-progress-step {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    flex-wrap: wrap;
    margin-bottom: var(--space-2);
}

.database-clone-bar {
    display: block;
    width: 100%;
    height: 0.75rem;
    accent-color: var(--primary);
}

.database-clone-progress-detail {
    display: flex;
    justify-content: space-between;
    gap: var(--space-2);
    margin-top: var(--space-1);
    font-size: var(--font-size-sm);
    color: var(--text-muted);
}

.payment-apply-col { width: 9rem; }

/* ----- In-app notification bell (top bar) ----- */
.notification-bell { position: relative; display: inline-flex; align-items: center; }
.notification-badge {
    position: absolute; top: -6px; right: -8px; min-width: 18px; height: 18px; padding: 0 4px;
    border-radius: 9px; background: var(--danger); color: var(--text-light);
    font-size: 11px; line-height: 18px; text-align: center; font-weight: 600;
}
.notification-panel {
    position: absolute; top: calc(100% + 10px); right: -8px; width: min(380px, 90vw); max-height: 70vh;
    overflow-y: auto; z-index: 1060; background: var(--bg-surface);
    border: 1px solid var(--border-color); border-radius: var(--radius-sm); color: var(--text-main);
}
.notification-item { padding: 10px 14px; border-bottom: 1px solid var(--border-color); cursor: pointer; }
.notification-item:hover { background: var(--bg-elevated); }
.notification-item.unread { border-left: 3px solid var(--primary); }
.notification-time { font-size: 11px; opacity: .7; margin-top: 2px; }

/* Phones: anchored to the bell, the panel ran off the left edge (bell is near the right). Anchor it
   to the whole top bar instead, 12px in from both sides; and give the bell a 44px tap target. */
@media (max-width: 640.98px) {
    main > .top-row { position: relative; }
    .notification-bell { position: static; }
    .notification-bell > button { min-width: 44px; min-height: 44px; justify-content: center; }
    .notification-badge { top: 4px; right: 2px; }
    .notification-panel { top: calc(100% + 4px); left: 12px; right: 12px; width: auto; }
}

.coa-code-col { width: 7rem; }
.coa-itc-col { width: 10rem; }
.coa-flag-col { width: 9rem; }
.coa-actions-col { width: 4rem; }

.credit-totals td { padding-left: 1.5rem; }
