/* ==========================================================================
   MAKERY shared application styling - valuation explorer companion

   Load order:
     Radzen theme -> radzen-overrides.css -> val-dialogs.css

   Replacement for the existing shared overrides, not an additional file.
   Existing layout, dark dashboard shell, loader effects, specialized workflows,
   semantic colors and floating-label positioning are intentionally retained.
   Explicit small/extra-small buttons and compact grids remain compact.
   ========================================================================== */

:root {
    --mk-surface: #ffffff;
    --mk-surface-soft: #fafbfc;
    --mk-ink: #252b38;
    --mk-muted: #626b7c;
    --mk-line: #e3e6ec;
    --mk-hover: #f4f8f9;
    --mk-accent: var(--rz-primary, #116471);
    --mk-accent-soft: rgba(17, 100, 113, 0.08);
    --mk-radius: 8px;
    --mk-popover-shadow: 0 8px 28px rgba(32, 41, 64, 0.10);
}

:root {
    /* 1. --- Softer, Lighter Header --- 
       We remove the default ALL-CAPS, reduce the font size,
       and change the background to be less prominent.
    */
    --rz-grid-header-background-color: var(--mk-surface-soft);
    --rz-grid-header-color: var(--mk-muted);
    --rz-grid-header-font-size: 0.875rem;
    --rz-grid-header-font-weight: 600;
    --rz-grid-header-text-transform: none; /* Removes ALL-CAPS */
    --rz-grid-header-padding: 0.75rem 1rem;
    /* 2. --- Cleaner Rows --- 
       Increase padding for more breathing room and use a
       light bottom border instead of full cell borders.
    */
    --rz-grid-cell-padding: 0.75rem 1rem;
    --rz-grid-cell-border: 1px solid var(--mk-line);
    --rz-grid-row-border: 1px solid var(--mk-line);
    /* 3. --- Better Alternating Rows (Striping) --- 
       Makes the alternating row color more subtle.
    */
    --rz-grid-stripe-background-color: #fcfdfe;
    /* 4. --- Cleaner Selected Row --- */
    --rz-grid-selected-background-color: var(--mk-accent-soft);
    --rz-grid-selected-color: var(--rz-primary-darker);
    /* 5. --- Remove Grid Container Border --- 
       This removes the main border around the entire grid component.
    */
    --rz-grid-border: none;
    --rz-grid-border-radius: 8px;
}



.custom-white-chat {
    --dxbl-chatui-message-assistant-bg: #ffffff;
    --dxbl-chatui-messagelist-padding-y: 0;
    --dxbl-chatui-messagelist-padding-x: 0;
}

    /* Optional: If you also want to remove the border/shadow to make it truly flat */
    .custom-white-chat .dxbl-ai-chat-message-assistant {
        box-shadow: none !important;
        border: 1px solid #e0e0e0 !important; /* Adds a subtle border instead */
    }

.busy-dialog-container {
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 1rem 1.5rem;
}

/* Smooth, modern spinning animation */
.custom-spin {
    animation: spin 1.2s linear infinite;
}

@keyframes spin {
    100% {
        transform: rotate(360deg);
    }
}

/* =========================================
   AI Loader & Gemini Wave Effects
   ========================================= */

/* Ghost button styling: just text in normal state */
.ai-cancel-btn {
    background: transparent !important;
    border: 1px solid transparent !important;
    box-shadow: none !important;
    color: rgba(255, 255, 255, 0.5) !important;
    border-radius: 24px !important;
    padding: 4px 24px !important;
    transition: all 0.3s ease !important;
    font-weight: 300;
    letter-spacing: 0.5px;
    cursor: pointer;
    box-sizing: border-box !important;
}

    .ai-cancel-btn:hover {
        background: rgba(255, 60, 60, 0.15) !important;
        border: 1px solid rgba(255, 60, 60, 0.4) !important;
        color: #ffffff !important;
        box-shadow: 0 0 15px rgba(255, 60, 60, 0.2) !important;
    }

/* --- Ultra-Premium AI Full-Screen Overlay (Cool Palette, Smooth Wake-Up) --- */
.ai-loader-wrapper {
    position: fixed;
    top: 0;
    left: 0;
    width: 100vw;
    height: 100vh;
    z-index: 9999;
    background-color: #030305; /* Pitch black with just a 1% hint of midnight blue */
    overflow: hidden;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    color: white;
}

.rz-dialog.fsi-shell {
    display: flex;
    flex-direction: column;
    overflow: hidden;
}

    .rz-dialog.fsi-shell > .rz-dialog-content {
        flex: 1 1 auto;
        min-height: 0; /* ohne das schrumpft der Body nicht -> Footer rutscht raus */
        display: flex;
        flex-direction: column;
        overflow: hidden;
    }

    /* Titel ist "" -> leere Titlebar frisst sonst Höhe */
    .rz-dialog.fsi-shell > .rz-dialog-titlebar:empty {
        display: none;
    }

/* Base Blob Styling */
.gemini-wave-1, .gemini-wave-2, .gemini-wave-3 {
    position: absolute;
    filter: blur(120px); /* Increased from 90px for maximum liquid smoothness */
    z-index: 0;
    opacity: 0; /* They start completely invisible (black screen) */
    pointer-events: none;
    border-radius: 50%;
    mix-blend-mode: screen;
}

/* Electric Cyan Blob */
.gemini-wave-1 {
    width: 65vw;
    height: 65vw;
    background: radial-gradient(circle, rgba(0, 212, 255, 0.7) 0%, transparent 70%);
    top: -10%;
    left: -10%;
    /* Fades in over 4s, then drifts infinitely */
    animation: wake-up 4s ease-out forwards, drift-1 26s ease-in-out infinite alternate;
}

/* Deep Slate / Desaturated Indigo */
.gemini-wave-2 {
    width: 55vw;
    height: 55vw;
    background: radial-gradient(circle, rgba(75, 80, 130, 0.6) 0%, transparent 70%);
    bottom: -10%;
    right: -10%;
    animation: wake-up 5s ease-out forwards 0.5s, drift-2 32s ease-in-out infinite alternate;
}

/* Royal Blue Core Blob */
.gemini-wave-3 {
    width: 75vw;
    height: 75vw;
    background: radial-gradient(circle, rgba(10, 132, 255, 0.5) 0%, transparent 70%);
    top: 20%;
    left: 20%;
    /* Delays the start by 1s */
    animation: wake-up 6s ease-out forwards 1s, drift-3 28s ease-in-out infinite alternate;
}

/* Foreground Content */
.content-layer {
    z-index: 3;
    display: flex;
    flex-direction: column;
    align-items: center;
    /* Optional: We fade the text/button in slightly after the lights turn on */
    opacity: 0;
    animation: wake-up-content 3s ease-out forwards 1.5s;
}

/* =========================================
   The Smooth Animations
   ========================================= */

/* The initial ignition from pitch black */
@keyframes wake-up {
    0% {
        opacity: 0;
    }

    100% {
        opacity: 0.85;
    }
}

/* Smooth lift and fade for the text and cancel button */
@keyframes wake-up-content {
    0% {
        opacity: 0;
        transform: translateY(10px);
    }

    100% {
        opacity: 1;
        transform: translateY(0);
    }
}

/* Much slower, wider, smoother drifting paths */
@keyframes drift-1 {
    0% {
        transform: translate(0, 0) scale(1);
    }

    50% {
        transform: translate(20vw, 15vh) scale(1.2);
    }

    100% {
        transform: translate(-10vw, 25vh) scale(0.9);
    }
}

@keyframes drift-2 {
    0% {
        transform: translate(0, 0) scale(1);
    }

    50% {
        transform: translate(-25vw, -20vh) scale(1.3);
    }

    100% {
        transform: translate(15vw, -10vh) scale(0.8);
    }
}

@keyframes drift-3 {
    0% {
        transform: translate(0, 0) scale(0.8);
    }

    50% {
        transform: translate(-15vw, 25vh) scale(1.1);
    }

    100% {
        transform: translate(20vw, -15vh) scale(1);
    }
}

/* ==========================================================================
   1. RADZEN OVERRIDES: SCOPED TO THIS SPECIFIC DIALOG ONLY
   ========================================================================== */

/* Target ONLY the mask inside our specific wrapper (Almost pure Makery Black) */
.makery-immersive-loader .rz-dialog-mask,
.rz-dialog-wrapper:has(.makery-immersive-loader) .rz-dialog-mask {
    /* Pure black with 95% opacity */
    background-color: rgba(0, 0, 0, 0.95) !important;
    /* THE FIX: Override Radzen's default 50% opacity! */
    opacity: 1 !important;
    backdrop-filter: blur(4px) !important;
    z-index: 1000 !important;
}

/* Make the Dialog container itself completely invisible */
.makery-immersive-loader .rz-dialog,
.rz-dialog.makery-immersive-loader {
    background-color: transparent !important;
    box-shadow: none !important;
    border: none !important;
}

    /* Nuke the title bar */
    .makery-immersive-loader .rz-dialog-titlebar,
    .rz-dialog.makery-immersive-loader .rz-dialog-titlebar {
        display: none !important;
    }

    /* Make the internal content wrapper transparent */
    .makery-immersive-loader .rz-dialog-content,
    .rz-dialog.makery-immersive-loader .rz-dialog-content {
        padding: 0 !important;
        background-color: transparent !important;
    }


/* ==========================================================================
   2. LOADER CONTENT: DOTS & TEXT (Unchanged)
   ========================================================================== */

.ai-loader-wrapper {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-direction: column;
    gap: 2rem;
    padding: 2rem;
}

.ai-text {
    color: #ffffff;
    font-weight: 500;
    font-size: 1.15rem;
    letter-spacing: 0.5px;
    text-align: center;
}

.loading-dots {
    display: flex;
    gap: 0.75rem;
    align-items: center;
    justify-content: center;
    height: 40px;
}

    .loading-dots .dot {
        width: 14px;
        height: 14px;
        border-radius: 50%;
        background-color: var(--rz-makery-petrol);
        animation: dot-wave 1.4s infinite ease-in-out;
    }

        .loading-dots .dot:nth-child(1) {
            animation-delay: 0s;
        }

        .loading-dots .dot:nth-child(2) {
            animation-delay: 0.15s;
        }

        .loading-dots .dot:nth-child(3) {
            animation-delay: 0.3s;
        }

@keyframes dot-wave {
    0%, 100% {
        transform: translateY(0) scale(0.8);
        opacity: 0.5;
        background-color: var(--rz-makery-petrol);
        box-shadow: none;
    }

    50% {
        transform: translateY(-8px) scale(1.5);
        opacity: 1;
        background-color: var(--rz-makery-aqua);
        box-shadow: 0 0 12px rgba(66, 189, 191, 0.6);
    }
}

.dxbl-chatui-root .dxbl-chatui .dxbl-chatui-submitarea {
    padding: 0;
}

/* 6. --- Remove All Cell Borders --- 
   The CSS variables above control most borders, but to ensure
   no cell borders (left/right), we target the class directly.
*/
.rz-data-grid .rz-grid-table td {
    border: none;
}

.dxbl-ai-chat-message-regenerate-button {
    display: none !important;
}

.dxbl-scroll-viewer-vert-scroll-bar,
.dxbl-scroll-viewer-hor-scroll-bar {
    display: none !important;
}

/* 7. --- Subtle Row Hover Effect --- 
   This adds a simple background change when you hover over a row.
*/
.rz-data-grid .rz-grid-table tbody tr:not(.rz-state-selected):hover {
    background-color: var(--mk-hover);
}

/* 8. --- Clean Pager ---
   Minor tweaks to the pager at the bottom.
*/
.rz-pager {
    border-top: 1px solid var(--mk-line);
    background-color: #fff;
    padding-top: 1rem;
}


/* Flatten the RadzenLogin component to blend into the page */
.clean-login .rz-card {
    box-shadow: none !important;
    border: none !important;
    padding: 0 !important;
    background: transparent !important;
}

/* Modernize the Input Fields */
.clean-login input.rz-textbox {
    height: 48px; /* Taller inputs = Modern look */
    background-color: var(--rz-base-200); /* Slightly grey background for inputs */
    border: 1px solid transparent;
}

    .clean-login input.rz-textbox:focus {
        background-color: var(--rz-base-100);
        border-color: var(--rz-primary);
    }

/* Modernize the Login Button */
.clean-login .rz-login-button {
    height: 48px;
    font-weight: 600;
    letter-spacing: 0.5px;
    margin-top: 1rem;
    width: 100%;
}


.my-popup {
    display: none;
    position: absolute;
    overflow: auto;
    /* FIX: Use a fixed reasonable width for desktop */
    width: 600px;
    /* FIX: Safety cap so it never exceeds screen width on weirdly resized windows */
    max-width: 95vw;
    height: 50vh;
    min-height: 200px;
    border: var(--rz-panel-border);
    background-color: var(--rz-panel-background-color);
    box-shadow: var(--rz-panel-shadow);
    border-radius: var(--rz-border-radius);
    z-index: 1000; /* Ensure it floats above other elements */
}

/* Responsive adjustments for TABLETS and MOBILES */
@media (max-width: 768px) {
    .my-popup {
        /* On small screens, switch back to relative width */
        width: 90vw;
        height: 50vh;
        min-height: 200px;
        min-width: unset; /* Remove min-width to prevent overflow on very small phones */
        padding: 1rem;
    }
}

@media (max-width: 576px) {
    :root {
        --rz-gap: 3rem;
    }
}

@media (max-width: 1000px) {
    .rz-steps-title {
        display: none;
    }
}

@media (max-width: 576px) {
    .rz-steps [role=tablist] {
        display: block;
    }

    .rz-steps .rz-steps-item {
        display: block;
        padding: 0.25rem 0;
    }

    /* Show titles again for vertical layout */
    .rz-steps-title {
        display: block;
    }
}

.main-app-layout .rz-layout {
    height: auto !important;
}

/* .rz-body { */
/* max-width: 2000px; */
/* margin-left: auto; */
/* margin-right: auto; */
/* width: 95%; */
/* } */

.rz-body {
    max-width: 100% !important;
    width: 100% !important;
    margin: 0 !important;
    padding: 0 !important;
    background-color: #000000 !important; /* Prevents white flash */
    min-width: 320px; /* A safe minimum for small mobile screens */
}



a {
    color: black; /* Changes the text color from blue to black */
    text-decoration: none; /* Removes the underline */
}

    a:hover {
        color: dimgray; /* Changes color on hover */
        text-decoration: underline; /* Optional: Adds underline on hover */
    }

.strikethrough-numeric input {
    text-decoration: line-through;
    color: red;
}


.no-animation-dialog .rz-dialog.rz-open {
    animation: none !important;
}

.fullscreenContent .rz-dialog-content {
    flex: 1 1 auto;
    padding: var(--rz-dialog-content-padding);
    overflow: auto;
}

.stretched-dialog {
    flex: 1 1 auto !important;
    min-height: 0 !important;
    display: flex !important;
    flex-direction: column;
    overflow: hidden;
}

/* Targets the input element WITHIN the component that has the 'bold-numeric' class */
.bold-numeric input {
    font-weight: bold;
}

.rz-steps ul {
    padding: 0 1rem; /* PL CSS war padding: 0; */
}

.rz-dialog-confirm-buttons > .rz-secondary {
    background-color: var(--rz-danger) !important;
}

.rz-badge {
    text-transform: none;
}

.rz-datalist-content {
    padding: 0;
}

.custom-rzdatalist .rz-datalist-data {
    padding: 0 !important; /* Forces padding to 0 for RadzenDataList */
}

.custom-rzdatalist .rz-steps ul {
    padding: 0 1rem !important; /* Keep padding for steps inside the custom class */
}


.rz-fileupload-row {
    display: none;
}

.rz-fileupload-files {
    padding: 0;
}

.rz-button {
    text-transform: none; /* PL CSS war nicht da */
}

/* PL CSS unklar ob das funktioniert auf nicht windows rechnern */
body, .rz-main-content {
    font-family: "Segoe UI", "Roboto", sans-serif;
}

.rz-dialog-wrapper:has(.hide-modal-overlay) .rz-dialog-mask {
    background-color: transparent !important;
}

.rz-pager.rz-density-compact .rz-pager-element, .rz-fileupload .rz-button, .rz-button-sm {
    font-size: 0.8rem; /* PL CSS 0.75rem; */
    letter-spacing: normal; /* PL CSS war 0.75px*/
    text-transform: none; /* PL CSS war uppercase; */
}

.rz-button-xs {
    text-transform: none; /* PL CSS war uppercase */
}

.rz-card {
    /* PL CSS border-radius: var(--rz-card-border-radius); */
    border-radius: var(--mk-radius);
    padding: 1rem 0; /* 1rem top and bottom, 0 left and right */
}

    .rz-card.rz-variant-filled {
        box-shadow: none; /* PL CSS war var(--rz-card-shadow) */
    }

.rz-menu:not(.rz-profile-menu) {
    background-color: transparent; /* PL CSS war var(--rz-menu-top-item-background-color); */
}

.rz-steps .rz-widget-content {
    padding: 1rem 1rem; /* PL CSS */
}


.rz-steps-buttons {
    display: flex;
    justify-content: space-between;
    padding-block: var(--rz-steps-buttons-padding-block);
    padding-inline: var(--rz-steps-buttons-padding-inline);
    position: absolute; /* PL CSS Position the buttons at the bottom */
    bottom: 0; /* PL CSS Align buttons to the bottom of the container */
    left: 0; /* PL CSS Align buttons to the left */
    width: 100%; /* PL CSS Ensure the buttons span the full width of the container */

    padding-left: 1rem; /* PL CSS Add 1rem padding to the left */
    padding-right: 1rem; /* PL CSS Add 1rem padding to the right */
}

.rz-fileupload-buttonbar {
    background-color: transparent; /* PL CSS war var(--rz-upload-button-bar-background-color); */
}


.rz-g > div, .rz-datalist-data > li {
    background-color: transparent; /* PL CSS war var(--rz-datalist-item-background-color); */
}

.rz-tabview-nav {
    padding: 0 !important; /* PL CSS war ohne important */
}


.rz-form-field-label {
    padding: 0 !important; /* PL CSS war var(--rz-form-field-label-padding); */
    font-weight: 600; /* Match the valuation form labels. */
    inset-inline-start: auto !important; /* PL CSS war var(--rz-form-field-label-inset-inline-start); */
}

input, textarea {
    font-size: var(--rz-input-font-size);
}

/* --- DASHBOARD STYLES --- */
.dashboard-background {
    min-height: 100vh;
    width: 100%;
    background-color: #000000;
    /* The cool radial gradient spotlight */
    background-image: radial-gradient(circle at 50% -10%, var(--rz-primary-darker) 0%, #000000 60%);
    padding: 2rem;
    display: flex;
    justify-content: center;
}

.main-container {
    /* We re-apply a max-width here so the content doesn't stretch too wide on huge screens */
    max-width: 2000px;
    width: 95%;
    margin-top: 2rem;
}


.glow-icon-wrapper {
    background: rgba(255,255,255,0.05);
    padding: 12px;
    border-radius: 50%;
    border: 1px solid rgba(255,255,255,0.1);
    display: flex;
    align-items: center;
    justify-content: center;
}


.modern-search-wrapper {
    position: relative;
}

.modern-input.rz-textbox {
    background-color: rgba(255, 255, 255, 0.05) !important;
    border: 1px solid rgba(255, 255, 255, 0.1) !important;
    border-radius: 8px !important;
    color: white !important;
    height: 50px;
    transition: all 0.3s ease;
    font-size: 1rem;
}

    .modern-input.rz-textbox:focus {
        background-color: rgba(255, 255, 255, 0.1) !important;
        border-color: var(--rz-primary) !important;
        box-shadow: 0 0 15px rgba(var(--rz-primary-rgb), 0.2);
    }

.modern-input::placeholder {
    color: rgba(255, 255, 255, 0.3);
}

/* Card Glassmorphism */
.app-box {
    background: rgba(255, 255, 255, 0.03);
    backdrop-filter: blur(10px);
    border: 1px solid rgba(255, 255, 255, 0.08);
    border-radius: 16px;
    padding: 1.5rem;
    display: flex;
    flex-direction: column;
    height: 100%;
    min-height: 240px;
    position: relative;
    transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}

.hover-card:hover {
    transform: translateY(-5px);
    background: rgba(255, 255, 255, 0.06);
    border-color: white;
    box-shadow: 0 10px 30px -10px rgba(0, 0, 0, 0.5);
}

.icon-wrapper {
    width: 48px;
    height: 48px;
    border-radius: 10px;
    background-color: rgba(255, 255, 255, 0.05);
    border: 1px solid rgba(255, 255, 255, 0.1);
    display: flex;
    align-items: center;
    justify-content: center;
    transition: all 0.3s ease;
}

.hover-card:hover .icon-wrapper {
    background-color: var(--rz-primary);
    border-color: var(--rz-primary);
}

.box-content {
    display: flex;
    flex-direction: column;
    height: 100%;
}

.box-header {
    display: flex;
    align-items: center;
    gap: 1rem;
    margin-bottom: 1rem;
}

.box-footer {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-top: auto;
    padding-top: 1rem;
    border-top: 1px solid rgba(255, 255, 255, 0.05);
}

.modern-btn-primary {
    width: 100%;
    margin-left: 0.5rem;
    text-transform: uppercase;
    font-weight: 700;
    letter-spacing: 0.5px;
}

.modern-btn-secondary {
    border-color: rgba(255,255,255,0.2) !important;
    color: rgba(255,255,255,0.6) !important;
}

    .modern-btn-secondary:hover {
        background-color: white !important;
        color: black !important;
    }

.modern-menu .rz-navigation-item-wrapper {
    color: white !important;
}

    .modern-menu .rz-navigation-item-wrapper:hover {
        background-color: rgba(255,255,255,0.1) !important;
    }


.rz-steps ul {
    padding: 0rem;
}

.rz-steps .rz-widget-content {
    padding: 0rem;
}

:root {
    --rz-tabs-tab-text-transform: none;
    --rz-tabs-tab-letter-spacing: normal;
    --rz-row-gap: 2rem; /* PL CSS war 1rem; */
    --rz-makery-gray: #eeeef0;
    --rz-makery-darkgray: #8b969d;
    --rz-makery-aqua: #42bdbf;
    --rz-makery-aqua-planning: rgba(217, 242, 242, 1.0);
    --rz-makery-black: #020104;
    --rz-makery-petrol: #116471;
    --rz-makery-petrol-darker: #0B505A;
    --rz-makery-petrol-lighter: rgba(17, 100, 113, 0.12);
    --rz-makery-brown: #9b694d;
    --rz-makery-darkred: #dc024a /* PL war vorher #6b0023 */;
    --rz-makery-darkgreen: #026106;
    --rz-makery-lightyellow: #ffffdc;
    --rz-sidebar-toggle-hover-background-color: var(--rz-makery-aqua);
    --rz-primary: var(--rz-makery-petrol);
    --rz-switch-checked-circle-background-color: var(--rz-primary);
    --rz-primary-darker: var(--rz-makery-petrol-darker);
    --rz-primary-lighter: var(--rz-makery-petrol-lighter);
    --rz-on-primary-lighter: var(--rz-primary-darker);
    --rz-secondary: #848884;
    --rz-info-light: #3689ca; /* PL CSS war #4dabf5; */
    --rz-info: #619ca4; /* PL war var(--rz-primary); */
    --rz-success: var(--rz-makery-darkgreen); /* PL CSS war #6f9e71 oder #4caf50; */
    --rz-warning: #f2b254; /* PL CSS war #ff9800; */
    --rz-danger: #a86078; /*PL CSS WAR #FD4248; oder #f44336*/
    --rz-danger-light: #cc4237; /* PL CSS WAR #f6695e; */
    --rz-root-font-size: 15px; /* PL CSS war 16px */
    --rz-body-background-color: black; /* PL CSS war #eeeff1; oder var(--rz-base-100) */
    --rz-card-padding: 2rem; /* PL CSS */
    --rz-card-background-color: var(--mk-surface);
    --rz-datalist-background-color: transparent; /* PL CSS war var(--rz-base-background-color); */
    --rz-datalist-item-margin-inline: 0.0rem; /* PL CSS war 0.5rem */
    --rz-datalist-item-background-color: transparent; /* PL CSS war var(--rz-base-background-color); */
    --rz-form-field-start-end-padding-inline: 0.75rem; /* PL CSS war 0.75rem */
    --rz-form-field-label-floating-top: -1.25rem; /* PL CSS war -0.5625rem; aber dann auch die höhe ingesamt wieder zurücksetzen */
    --rz-form-field-label-floating-background-color: transparent; /* PL CSS war var(--rz-input-background-color); */
    --rz-grid-cell-font-size: 1.0rem; /* PL CSS war 0.875rem*/
    --rz-grid-selected-background-color: var(--mk-accent-soft);
    --rz-grid-selected-color: var(--rz-primary-darker);
    --rz-grid-header-font-size: 0.875rem;
    --rz-input-height: 40px;
    --rz-input-background-color: var(--mk-surface);
    --rz-input-disabled-border: none; /* PL CSS war var(--rz-border-disabled); */
    --rz-input-disabled-background-color: transparent; /* PL CSS war var(--rz-base-background-color); */
    --rz-input-disabled-color: var(--rz-text-color, #252b38);
    --rz-input-disabled-border-block-end: none;
    --rz-input-hover-background-color: #f8fcfd;
    --rz-menu-top-item-hover-color: var(--rz-primary); /* PL CSS war var(--rz-on-primary); */
    --rz-menu-top-item-selected-color: var(--rz-primary); /* PL CSS war var(--rz-on-primary); */
    --rz-menu-top-item-icon-color: var(--rz-primary); /* PL CSS war var(--rz-on-primary); */
    --rz-menu-top-item-icon-hover-color: var(--rz-primary); /* PL CSS war var(--rz-on-primary); */
    --rz-steps-number-selected-background: var(--rz-primary); /* PL CSS war var(--rz-secondary); */
    --rz-tabs-padding: 1rem 0rem; /* PL CSS war 1rem*/
    --rz-form-field-margin-block: 0; /* PL CSS war 0.5rem 0*/
    --rz-card-background-color: var(--mk-surface);
    --rz-datepicker-calendar-selected-hover-background-color: var(--rz-primary);
    --rz-upload-choose-background-color: white;
    --rz-steps-color: white;
    --rz-steps-title-selected-color: var(--rz-makery-aqua);
}

/* Custom Tippy.js Tooltip */
.tippy-box[data-theme~='custom'] {
    background-color: #4a90e2; /* Nice blue color */
    color: white;
    font-size: 14px;
    font-weight: bold;
    padding: 8px 12px;
    border-radius: 6px;
    box-shadow: 0px 4px 10px rgba(0, 0, 0, 0.2);
}

    .tippy-box[data-theme~='custom'][data-placement^='top'] > .tippy-arrow::before {
        border-top-color: #4a90e2; /* Arrow color */
    }

    .tippy-box[data-theme~='custom'][data-placement^='bottom'] > .tippy-arrow::before {
        border-bottom-color: #4a90e2;
    }


/* Row state styles. Exactly one class is set per row in OnLedgerRowRender;
   precedence there is critical > flag > ai > total. !important is applied
   consistently so the grid's base cell styles can't override any of them. */

/* Critical - loudest state (e.g. conflicts) */
tr.fsi-critical-row td {
    background: rgba(220, 38, 38, 0.12) !important;
}

    tr.fsi-critical-row td:first-child {
        border-left: 4px solid #dc2626;
    }

tr.fsi-critical-row .fsi-prov {
    color: #dc2626;
    font-weight: 600;
}

/* fsi-flag-row is no longer emitted: RowClass returns one amber class,
   fsi-verify-row, for every row that reads "Check this". The second amber
   wash split rows that ask the user for the same thing. Kept as a comment
   rather than a dead rule so it is not resurrected by pattern-matching. */

/* Verify band - a machine mapping below its confidence floor. Amber like the
   open flag because it is a question, not a fault, but the edge is DASHED so
   "the AI guessed, read it" never reads the same as "this row is annotated".
   Precedence in StaticFsiLedgerPresentation.RowClass: total > critical >
   verify > flag. */
tr.fsi-verify-row td {
    background: rgba(245, 158, 11, 0.07) !important;
}

    tr.fsi-verify-row td:first-child {
        border-left: 4px dashed #f59e0b;
    }

tr.fsi-verify-row .fsi-prov {
    color: #b45309;
}

/* Unmapped with figures - blocks like the verify band, but a different KIND of
   work: the target cell is empty and the user supplies the answer rather than
   reading a proposal. Solid edge, not dashed: nothing guessed here, so there is
   no machine proposal for a dashed edge to stand for. */
tr.fsi-unmapped-row td {
    background: var(--fsi-unmapped-soft, rgba(124, 58, 237, 0.08)) !important;
}

    tr.fsi-unmapped-row td:first-child {
        border-left: 4px solid var(--fsi-unmapped, #7c3aed);
    }

tr.fsi-unmapped-row .fsi-prov {
    color: var(--fsi-unmapped-ink, #5b21b6);
}

/* AI-suggested - machine-proposed, not yet human-confirmed */
tr.fsi-ai-row td {
    background: rgba(59, 130, 246, 0.10) !important;
    box-shadow: inset 0 0 8px rgba(59, 130, 246, 0.18) !important;
}

    tr.fsi-ai-row td:first-child {
        border-left: 3px solid #3b82f6;
    }

/* Detected total - structural, quietest of the four */
tr.fsi-total-row td {
    font-weight: 600;
    border-top: 1px solid var(--fsi-rule, #d0d0d0);
    background: var(--fsi-total-bg, #f6f7f9) !important;
}

    tr.fsi-total-row td:first-child {
        border-left: 3px solid var(--fsi-rule, #d0d0d0);
    }


/* =====================================================================
   ReviewWizardDialog.razor.css  (scoped)
   Clean, restrained business-finance look: cool slate/navy + white, thin
   hairline rules, no heavy shadows. AI-set fields carry a left accent + tag.
   Sized to fill a large/wide Radzen dialog shell.
   ===================================================================== */

.fsi-dialog {
    --fsi-navy: #1f2a44;
    --fsi-slate: #55627a;
    --fsi-line: #e2e6ee;
    --fsi-bg: #ffffff;
    --fsi-bg-soft: #f6f8fb;
    --fsi-accent: #2f6df6; /* AI accent */
    --fsi-accent-soft: #eaf1ff;
    --fsi-warn: #b4531a;
    --fsi-warn-soft: #fdf1e8;
    /* "Needs a target": its own hue, not a third shade of amber. Violet reads as
       urgent without reading as an error, and it is the one blocker where the
       user authors the answer instead of confirming one. */
    --fsi-unmapped: #7c3aed;
    --fsi-unmapped-soft: rgba(124, 58, 237, 0.08);
    --fsi-unmapped-ink: #5b21b6;
    display: flex;
    flex-direction: column;
    width: 100%;
    height: 100%;
    min-width: 0;
    max-width: none;
    color: var(--fsi-navy);
    font-feature-settings: "tnum" 1; /* tabular figures for finance */
}

/* ---- Header ---- */
.fsi-header {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 1rem;
    padding: 0 0 1rem 0;
    border-bottom: 1px solid var(--fsi-line);
    flex: 0 0 auto;
}

.fsi-header-title {
    display: flex;
    gap: 0.85rem;
    align-items: baseline;
    min-width: 0;
}

/* Right-hand rail of the header: file chip on top, coverage strip below.
   The strip used to sit inside .fsi-header-title, where it read as part of
   the heading; here it is clearly a separate status object. */
.fsi-header-aside {
    margin-left: auto;
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: 0.5rem;
    flex: 0 0 auto;
}

.fsi-coverage {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    padding: 0.35rem 0.6rem 0.35rem 0.7rem;
    border: 1px solid var(--fsi-line);
    border-radius: 8px;
    background: var(--fsi-bg-soft);
}

.fsi-coverage-label {
    font-size: 0.72rem;
    font-weight: 500;
    letter-spacing: normal;
    text-transform: none;
    color: var(--fsi-slate);
    white-space: nowrap;
}

@media (max-width: 900px) {
    .fsi-header {
        flex-wrap: wrap;
    }

    .fsi-header-aside {
        margin-left: 0;
        align-items: flex-start;
    }
}

.fsi-step-index {
    font-size: 0.8rem;
    font-weight: 700;
    letter-spacing: 0.08em;
    color: var(--fsi-accent);
    border: 1px solid var(--fsi-accent);
    border-radius: 4px;
    padding: 0.1rem 0.4rem;
}

.fsi-header h2 {
    margin: 0;
    font-size: 1.15rem;
    font-weight: 650;
}

.fsi-header p {
    margin: 0.2rem 0 0;
    font-size: 0.85rem;
    color: var(--fsi-slate);
}

.fsi-file-chip {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    max-width: 16rem;
    padding: 0.35rem 0.6rem;
    background: var(--fsi-bg-soft);
    border: 1px solid var(--fsi-line);
    border-radius: 6px;
    font-size: 0.8rem;
    color: var(--fsi-slate);
}

    .fsi-file-chip span {
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
    }

/* ---- Body ---- */
.fsi-body {
    display: flex;
    flex-direction: column;
    gap: 1.25rem;
    padding: 1.25rem 0;
    flex: 1 1 auto;
    min-height: 0;
    overflow: auto;
}

/* ---- Dropzone Container ---- */
.fsi-dropzone {
    position: relative;
    display: flex;
    height: 100%;
    width: 100%;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0.6rem;
    text-align: center;
    padding: 2.5rem 1.5rem;
    border: 1.5px dashed var(--fsi-line);
    border-radius: 10px;
    background: var(--fsi-bg-soft);
    cursor: pointer;
    transition: border-color .15s, background .15s;
    overflow: hidden;
}

    .fsi-dropzone:hover {
        border-color: var(--fsi-accent);
        background: var(--fsi-accent-soft);
    }

    .fsi-dropzone.is-busy {
        pointer-events: none;
        opacity: 0.7;
    }

/* ---- Text & Visual Content Overlay ---- */
.fsi-dropzone-text {
    pointer-events: none; /* Passes click/drag events directly through to RadzenUpload */
    z-index: 1;
}

    .fsi-dropzone-text strong {
        display: block;
        font-size: 0.95rem;
    }

    .fsi-dropzone-text span {
        font-size: 0.8rem;
        color: var(--fsi-slate);
    }

.fsi-dropzone-icon {
    font-size: 2rem;
    color: var(--fsi-accent);
    pointer-events: none;
    z-index: 1;
}

.fsi-dropzone-spinner {
    position: absolute;
    top: 0.75rem;
    right: 0.75rem;
    z-index: 3;
}

/* ---- Stretch RadzenUpload across the entire dropzone invisibly ---- */
.fsi-dropzone .fsi-upload {
    position: absolute;
    inset: 0;
    width: 100% !important;
    height: 100% !important;
    opacity: 0; /* Keeps Radzen functionality while making its button bar invisible */
    cursor: pointer;
    z-index: 2;
}

    /* Force Radzen's internal wrapper structures to stretch 100% */
    .fsi-dropzone .fsi-upload .rz-fileupload,
    .fsi-dropzone .fsi-upload .rz-fileupload-buttonbar,
    .fsi-dropzone .fsi-upload .rz-fileupload-choose,
    .fsi-dropzone .fsi-upload input[type="file"] {
        position: absolute;
        inset: 0;
        width: 100% !important;
        height: 100% !important;
        margin: 0 !important;
        padding: 0 !important;
        cursor: pointer !important;
    }

/* Hidden accessible input fallback */
.fsi-dropzone-input {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    border: 0;
    overflow: hidden;
    clip: rect(0 0 0 0);
    clip-path: inset(50%);
    white-space: nowrap;
}

/* ---- Toolbar (sheet picker + autodetect) ---- */
.fsi-toolbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    padding: 0.65rem 0.85rem;
    background: var(--fsi-bg-soft);
    border: 1px solid var(--fsi-line);
    border-radius: 8px;
    /*    max-width: 1100px;
*/
}

.fsi-toolbar-left, .fsi-toolbar-right {
    display: flex;
    align-items: center;
    gap: 0.6rem;
}

.fsi-sheet-single {
    font-size: 0.85rem;
    color: var(--fsi-slate);
}

.fsi-field-inline {
    flex-direction: row;
    align-items: center;
    gap: 0.5rem;
}

/* ---- Choice panel (detect vs. enter manually) ---- */
.fsi-choice {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1.25rem;
    padding: 1.5rem 1.25rem;
    border: 1px solid var(--fsi-line);
    border-radius: 10px;
    background: linear-gradient(90deg, var(--fsi-accent-soft) 0%, var(--fsi-bg-soft) 60%);
    /*    max-width: 1100px;
*/
}

.fsi-choice-lead {
    display: flex;
    align-items: center;
    gap: 0.85rem;
}

.fsi-choice-icon {
    font-size: 1.6rem;
    color: var(--fsi-accent);
}

.fsi-choice-lead strong {
    display: block;
    font-size: 0.95rem;
}

.fsi-choice-lead span {
    font-size: 0.82rem;
    color: var(--fsi-slate);
}

.fsi-choice-actions {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    flex-shrink: 0;
}

/* ---- Field grid ---- */
.fsi-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0.85rem 1rem;
    max-width: 1100px;
}

.fsi-field {
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
    padding: 0.65rem 0.75rem;
    border: 1px solid var(--fsi-line);
    border-radius: 8px;
    background: var(--fsi-bg);
    transition: border-color .15s, box-shadow .15s;
}

    .fsi-field.is-ai {
        border-left: 3px solid var(--fsi-accent);
        background: linear-gradient(90deg, var(--fsi-accent-soft) 0%, #fff 18%);
    }

    .fsi-field.is-readonly {
        background: var(--fsi-bg-soft);
    }

.fsi-label-row {
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.fsi-label {
    font-size: 0.72rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--fsi-slate);
}

.fsi-readonly-value {
    font-size: 0.95rem;
    font-weight: 600;
}

.fsi-hint {
    font-size: 0.72rem;
    color: var(--fsi-slate);
}

.fsi-hint-inline {
    font-size: 0.72rem;
    color: var(--fsi-slate);
    font-weight: 400;
    margin-left: 0.4rem;
}

/* ---- AI / warning tags ---- */
.fsi-ai-tag {
    font-size: 0.66rem;
    font-weight: 700;
    letter-spacing: 0.04em;
    color: var(--fsi-accent);
    background: var(--fsi-accent-soft);
    padding: 0.05rem 0.4rem;
    border-radius: 999px;
}

.fsi-warn-tag {
    font-size: 0.66rem;
    font-weight: 700;
    letter-spacing: 0.04em;
    color: var(--fsi-warn);
    background: var(--fsi-warn-soft);
    padding: 0.05rem 0.4rem;
    border-radius: 999px;
    white-space: nowrap;
}

/* ---- Scale block ---- */
.fsi-scale {
    padding: 0.9rem 1rem;
    border: 1px solid var(--fsi-line);
    border-radius: 8px;
    background: var(--fsi-bg);
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    max-width: 1100px;
}

    .fsi-scale.is-ai {
        border-left: 3px solid var(--fsi-accent);
        background: linear-gradient(90deg, var(--fsi-accent-soft) 0%, #fff 18%);
    }

    .fsi-scale.is-warning {
        border-left: 3px solid var(--fsi-warn);
        background: var(--fsi-warn-soft);
    }

.fsi-scale-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
}

.fsi-scale-preview {
    font-size: 0.85rem;
    color: var(--fsi-slate);
}

    .fsi-scale-preview strong {
        color: var(--fsi-navy);
    }

/* ---- Periods ---- */
.fsi-periods {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    max-width: 1100px;
}

.fsi-periods-grid {
    width: 100%;
    border: 1px solid var(--fsi-line);
    border-radius: 8px;
    overflow: hidden;
}

.fsi-periods-toolbar {
    margin-left: auto;
}

.fsi-periods-empty {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    padding: 1rem 1.25rem;
    border: 1px dashed var(--fsi-line);
    border-radius: 8px;
    background: var(--fsi-bg-soft);
    font-size: 0.85rem;
    color: var(--fsi-slate);
}

/* ---- Footer ---- */
.fsi-footer {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 1rem 0 0;
    border-top: 1px solid var(--fsi-line);
    flex: 0 0 auto;
}

.fsi-footer-right {
    display: flex;
    align-items: center;
    gap: 0.85rem;
}

.fsi-footer-note {
    font-size: 0.8rem;
    color: var(--fsi-warn);
}

/* =====================================================================
   Step 2 — Review ledger
   ===================================================================== */

/* Running state centers in the tall dialog. */
.fsi-running {
    align-items: center;
    justify-content: center;
    gap: 1rem;
    color: var(--fsi-slate);
    flex: 1 1 auto;
    min-height: 220px;
}

/* ---- Filter chips ---- */
.fsi-chips {
    display: flex;
    gap: 0.5rem;
    flex: 0 0 auto;
}

.fsi-chip {
    font-size: 0.78rem;
    font-weight: 600;
    padding: 0.35rem 0.75rem;
    border: 1px solid var(--fsi-line);
    border-radius: 999px;
    background: var(--fsi-bg);
    color: var(--fsi-slate);
    cursor: pointer;
    transition: border-color .15s, background .15s, color .15s;
}

    .fsi-chip:hover {
        border-color: var(--fsi-accent);
    }

    .fsi-chip.is-active {
        background: var(--fsi-navy);
        color: #fff;
        border-color: var(--fsi-navy);
    }

    .fsi-chip.is-alert {
        color: var(--fsi-warn);
        border-color: var(--fsi-warn);
    }

        .fsi-chip.is-alert.is-active {
            background: var(--fsi-warn);
            color: #fff;
        }




/* =============================================================================
   Flag treatment on a MAPPED review row
   A suspicious sign is a likely posting error (expense came in positive) that
   silently corrupts totals -> treat as CRITICAL: red edge, red glyph, sits at
   the top of needs-you. Ambiguous value / partial period are softer amber hints
   on an otherwise-valid mapping. All clear once the human touches the row.
   ============================================================================= */

.fsi-ledger {
    --fsi-critical: #dc2626; /* red */
    --fsi-critical-soft: rgba(220, 38, 38, 0.12);
    --fsi-flag: #f59e0b; /* amber (soft hints) */
    --fsi-flag-soft: rgba(245, 158, 11, 0.10);
    --fsi-verify: #f59e0b; /* same amber: one "needs you" family */
    --fsi-verify-soft: rgba(245, 158, 11, 0.07);
    --fsi-verify-ink: #b45309; /* darker amber so the glyph stays legible on the wash */
}

    /* --- Critical (wrong sign): red edge + wash + emphasized glyph ------------- */
    .fsi-ledger .fsi-critical-row td:first-child::before {
        content: "";
        position: absolute;
        inset-block: 0;
        inset-inline-start: 0;
        width: 3px;
        background: var(--fsi-critical);
        border-radius: 0 2px 2px 0;
    }

    .fsi-ledger .fsi-critical-row td:first-child {
        position: relative;
    }

    .fsi-ledger .fsi-critical-row td {
        background: var(--fsi-critical-soft);
        box-shadow: inset 0 0 0 9999px var(--fsi-critical-soft);
    }

    .fsi-ledger .fsi-critical-row {
        box-shadow: 0 0 12px -2px rgba(220, 38, 38, 0.28);
    }
        /* The provenance glyph + flag text go red so the "check sign" reads as an alarm. */
        .fsi-ledger .fsi-critical-row .fsi-prov {
            color: var(--fsi-critical);
            font-weight: 600;
        }

            .fsi-ledger .fsi-critical-row .fsi-prov .rz-icon,
            .fsi-ledger .fsi-critical-row .fsi-prov i {
                color: var(--fsi-critical);
            }

    /* --- The amber band: one treatment for every "Check this" row -------------- */
    /* The .fsi-flag-row half of this pair is gone. It was set apart from the
       verify band on purpose -- solid edge for annotated, dashed for unread --
       but that is a distinction the wash does not need to carry, and it made two
       rows asking the same question look like different kinds of problem. */
    .fsi-ledger .fsi-verify-row td:first-child::before {
        content: "";
        position: absolute;
        inset-block: 0;
        inset-inline-start: 0;
        width: 3px;
        background: repeating-linear-gradient( to bottom, var(--fsi-verify) 0 5px, transparent 5px 9px );
        border-radius: 0 2px 2px 0;
    }

    .fsi-ledger .fsi-verify-row td:first-child {
        position: relative;
    }

    .fsi-ledger .fsi-verify-row td {
        background: var(--fsi-verify-soft);
    }

    .fsi-ledger .fsi-verify-row .fsi-prov {
        color: var(--fsi-verify-ink);
    }

    /* --- The violet band: a row with figures and no target ---------------------
       Solid bar rather than the verify band's dashes. The dashes stand for "a
       machine proposed this, read it"; there is no proposal on an unmapped row,
       so a dashed edge would be claiming something that is not there. */
    .fsi-ledger .fsi-unmapped-row td:first-child::before {
        content: "";
        position: absolute;
        inset-block: 0;
        inset-inline-start: 0;
        width: 3px;
        background: var(--fsi-unmapped);
        border-radius: 0 2px 2px 0;
    }

    .fsi-ledger .fsi-unmapped-row td:first-child {
        position: relative;
    }

    .fsi-ledger .fsi-unmapped-row td {
        background: var(--fsi-unmapped-soft);
    }

    .fsi-ledger .fsi-unmapped-row .fsi-prov {
        color: var(--fsi-unmapped-ink);
    }

@media (prefers-reduced-motion: reduce) {
    .fsi-ledger .fsi-critical-row td,
    .fsi-ledger .fsi-verify-row td,
    .fsi-ledger .fsi-unmapped-row td {
        transition: none;
    }
}



/* ---- Provenance cell ---- */
.fsi-prov {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    font-size: 0.72rem;
    color: var(--fsi-slate);
}

    .fsi-prov .rz-icon, .fsi-prov i {
        font-size: 0.95rem;
    }

    .fsi-prov.is-conflict {
        color: var(--fsi-warn);
        font-weight: 600;
    }

/* Confidence hairline — thin left-edge fill, only on Llm / FuzzyMatch. */
.fsi-hairline {
    margin-top: 0.3rem;
    height: 2px;
    width: 100%;
    background: var(--fsi-line);
    border-radius: 2px;
    overflow: hidden;
}

    .fsi-hairline span {
        display: block;
        height: 100%;
        background: var(--fsi-accent);
    }

/* ---- Line-item (source -> translated) ---- */
.fsi-src {
    font-size: 0.88rem;
    font-weight: 550;
}

.fsi-src-en {
    font-size: 0.76rem;
    color: var(--fsi-slate);
}

/* ---- Target picker / offers / conflicts ---- */
.fsi-target {
    display: flex;
    flex-direction: column;
    gap: 0.45rem;
}

    .fsi-target.is-pending .rz-dropdown {
        border-style: dashed;
        border-color: var(--fsi-accent);
    }



.fsi-accept {
    margin-top: 0.3rem;
}

.fsi-conflict {
    margin-top: 0.4rem;
    font-size: 0.74rem;
    color: var(--fsi-warn);
    background: var(--fsi-warn-soft);
    border-radius: 6px;
    padding: 0.3rem 0.5rem;
}

/* ---- Period values (display-only) — scroll horizontally when many years ---- */
/* The component emits --fsi-period-count and --fsi-period-track on BOTH the
   header and the body div, and the track has to be the fixed rem width, not
   1fr. With 1fr the header divided its own box into equal shares while the
   column reserved PeriodCount * 5.5rem, so header labels and figures drifted
   further apart with every extra year. Explicit repeat() ties both to the same
   definition the column width is computed from. */
.fsi-vals-head,
.fsi-vals {
    display: grid;
    grid-template-columns: repeat(var(--fsi-period-count, 1), var(--fsi-period-track, 5.5rem));
    gap: 0.5rem;
    width: max-content;
}

.fsi-val-cell {
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
    flex: 0 0 auto; /* fixed width per period; never shrink */
    text-align: right;
}

.fsi-val,
.fsi-val-period {
    text-align: right; /* figures align on the right edge */
    font-variant-numeric: tabular-nums; /* digits stop jittering between rows */
    white-space: nowrap;
}

.fsi-val {
    font-size: 0.82rem;
    font-variant-numeric: tabular-nums;
    text-align: right;
    white-space: nowrap;
    min-width: 5rem;
}

/* ---- "N ready" disclosure ---- */
.fsi-disclosure {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    background: none;
    border: none;
    cursor: pointer;
    font-size: 0.82rem;
    color: var(--fsi-accent);
    padding: 0.25rem 0;
    flex: 0 0 auto;
}

/* ---- Skipped drawer ---- */
.fsi-skipped {
    border: 1px dashed var(--fsi-line);
    border-radius: 8px;
    padding: 0.75rem 1rem;
    background: var(--fsi-bg-soft);
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
    flex: 0 0 auto;
}

.fsi-skip-row {
    font-size: 0.82rem;
    color: var(--fsi-slate);
}

/* ---- Responsive ---- */
@media (max-width: 640px) {
    .fsi-grid {
        grid-template-columns: 1fr;
    }

    .fsi-toolbar {
        flex-direction: column;
        align-items: stretch;
    }

    .fsi-choice {
        flex-direction: column;
        align-items: stretch;
    }

    .fsi-choice-actions {
        justify-content: flex-end;
    }
}

/* The per-cell flex/overflow-x version of this rule lived here and silently
   re-broke the horizontal scroll: it came later in the file, so it beat the
   grid definition above and gave every cell its own scroller again. The
   column declares the track width and the grid's own scroller handles the
   overflow -- do not reintroduce a per-cell overflow-x here. */

.fsi-val-period {
    font-size: .7rem;
    color: var(--fsi-muted, #888);
    text-transform: uppercase;
    letter-spacing: .03em;
}

/* ---- Section picker (multiple statements on one sheet) ---- */
.fsi-section-picker {
    display: flex;
    flex-direction: column;
    gap: 1rem;
    padding: 1.25rem;
    border: 1px solid var(--fsi-line);
    border-radius: 10px;
    background: var(--fsi-bg);
}

    .fsi-section-picker > .rz-text-subtitle1 {
        font-size: 1rem;
        font-weight: 650;
        color: var(--fsi-navy);
    }

.fsi-section-picker-hint {
    font-size: 0.85rem;
    color: var(--fsi-slate);
    margin-top: -0.75rem;
}

.fsi-section-list {
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
}

.fsi-section-card {
    padding: 0 !important;
    border: 1px solid var(--fsi-line) !important;
    border-radius: 8px !important;
    background: var(--fsi-bg-soft) !important;
    box-shadow: none !important;
    transition: border-color .15s, background .15s, box-shadow .15s;
}

    .fsi-section-card:hover {
        border-color: var(--fsi-accent) !important;
        background: var(--fsi-accent-soft) !important;
        box-shadow: 0 1px 6px -2px rgba(47, 109, 246, 0.35);
    }

.fsi-section-card-body {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    padding: 0.85rem 1rem;
}

.fsi-section-card-text {
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
    min-width: 0;
}

    .fsi-section-card-text .rz-text-body1 {
        font-size: 0.92rem;
        font-weight: 600;
        color: var(--fsi-navy);
    }

    .fsi-section-card-text .rz-text-caption {
        font-size: 0.75rem;
        color: var(--fsi-slate);
        font-variant-numeric: tabular-nums;
    }

/* ================================================================
   Manual range editor — three inputs + explicit "Read this range"
   ================================================================ */
.fsi-manual-range {
    display: flex;
    flex-direction: column;
    gap: 1rem;
    padding: 1.25rem;
    border: 1px solid var(--fsi-line);
    border-radius: 10px;
    background: var(--fsi-bg);
}

.fsi-manual-range-head {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 1rem;
}

    .fsi-manual-range-head .rz-text-subtitle1 {
        font-size: 1rem;
        font-weight: 650;
        color: var(--fsi-navy);
    }

.fsi-manual-range-hint {
    font-size: 0.85rem;
    color: var(--fsi-slate);
    margin-top: 0.15rem;
    max-width: 52ch;
}

/* Row of labelled inputs (statement + three row numbers). The base .fsi-field
   provides the label/control stack; here we only lay them out in a wrap row. */
.fsi-manual-range-inputs {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: 0.85rem 1rem;
}

    .fsi-manual-range-inputs .fsi-field {
        flex: 0 0 auto;
    }

    /* Keep the three numeric boxes compact and equal; let the statement
       dropdown take a bit more room. */
    .fsi-manual-range-inputs .rz-numeric {
        width: 6rem;
    }

    .fsi-manual-range-inputs .rz-dropdown {
        min-width: 12rem;
    }

.fsi-manual-range-warn {
    font-size: 0.78rem;
    color: var(--fsi-danger, #c0392b);
    line-height: 1.35;
}

/* Right-aligned action row: Cancel (quiet) + Read this range (primary). */
.fsi-manual-range-actions {
    display: flex;
    justify-content: flex-end;
    align-items: center;
    gap: 0.5rem;
    padding-top: 0.25rem;
    border-top: 1px solid var(--fsi-line);
}

/* ================================================================
   "Edit range" banner — sits above the layout fields once a window
   has been read (autodetect, picker, or manual all show it)
   ================================================================ */
.fsi-range-banner {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    padding: 0.6rem 0.85rem;
    margin-bottom: 1rem;
    border: 1px solid var(--fsi-line);
    border-left: 3px solid var(--fsi-accent);
    border-radius: 8px;
    background: var(--fsi-bg-soft);
}

.fsi-range-banner-text {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    min-width: 0;
    font-size: 0.85rem;
    color: var(--fsi-slate);
}

    .fsi-range-banner-text .rz-icon {
        color: var(--fsi-accent);
        font-size: 1.1rem;
    }

    /* The row/header numbers read in navy tabular figures so they stand out
       against the surrounding slate text. */
    .fsi-range-banner-text strong {
        color: var(--fsi-navy);
        font-weight: 650;
        font-variant-numeric: tabular-nums;
    }

/* Stack banner contents on narrow dialogs so the button never crowds the text. */
@media (max-width: 560px) {
    .fsi-range-banner {
        flex-direction: column;
        align-items: flex-start;
        gap: 0.5rem;
    }
}

.fsi-section-card-actions {
    display: flex;
    gap: .5rem;
    align-items: center;
    justify-content: flex-end;
}

.ic {
    display: flex;
    flex-direction: column;
    gap: 1.25rem;
}

/* ---- Summary ---- */
.ic-summary {
    display: flex;
    align-items: center;
    gap: 1.5rem;
    padding: 1rem 1.25rem;
    border: 1px solid var(--rz-base-300);
    border-radius: 10px;
    background: var(--rz-base-background-color);
}

.ic-summary-fig {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    line-height: 1;
    padding-right: 1.5rem;
    border-right: 1px solid var(--rz-base-300);
}

.ic-summary-n {
    font-size: 2.25rem;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    letter-spacing: -0.02em;
}

.ic-summary-unit {
    margin-top: 0.35rem;
    font-size: 0.75rem;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--rz-text-secondary-color);
}

.ic-summary-meta {
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
    min-width: 0;
}

.ic-summary-line {
    display: flex;
    gap: 0.75rem;
    font-size: 0.875rem;
}

.ic-key {
    flex: 0 0 3.5rem;
    color: var(--rz-text-secondary-color);
}

.ic-val {
    font-weight: 500;
}

.ic-val-muted {
    font-weight: 400;
    color: var(--rz-text-secondary-color);
}

/* ---- Mode cards ---- */
.ic-modes {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    border: 0;
    margin: 0;
    padding: 0;
}

.ic-legend {
    padding: 0 0 0.6rem;
    font-size: 0.8125rem;
    font-weight: 600;
    color: var(--rz-text-secondary-color);
}

.ic-mode {
    display: flex;
    align-items: flex-start;
    gap: 0.75rem;
    padding: 0.75rem 0.9rem;
    border: 1px solid var(--rz-base-300);
    border-radius: 10px;
    cursor: pointer;
    transition: border-color 120ms ease, background-color 120ms ease;
}

    .ic-mode:hover {
        border-color: var(--rz-primary-light);
    }

    .ic-mode.is-selected {
        border-color: var(--rz-primary);
        background: var(--rz-primary-lighter);
    }

.ic-radio {
    margin-top: 0.15rem;
    accent-color: var(--rz-primary);
    flex: 0 0 auto;
}

.ic-mode:focus-within {
    outline: 2px solid var(--rz-primary);
    outline-offset: 2px;
}

.ic-mode-body {
    display: flex;
    flex-direction: column;
    gap: 0.2rem;
    min-width: 0;
}

.ic-mode-title {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    font-size: 0.9375rem;
    font-weight: 500;
}

.ic-mode-detail {
    font-size: 0.8125rem;
    line-height: 1.45;
    color: var(--rz-text-secondary-color);
}

/* Destructive option: set apart, never pre-selected. */
.ic-mode-danger {
    margin-top: 0.4rem;
    border-style: dashed;
}

    .ic-mode-danger .ic-mode-title {
        color: var(--rz-danger);
    }

    .ic-mode-danger .rzi {
        font-size: 1rem;
    }

    .ic-mode-danger:hover {
        border-color: var(--rz-danger-light);
    }

    .ic-mode-danger.is-selected {
        border-style: solid;
        border-color: var(--rz-danger);
        background: var(--rz-danger-lighter);
    }

/* ---- Note + footer ---- */
.ic-note {
    display: flex;
    align-items: center;
    gap: 0.45rem;
    margin: 0;
    font-size: 0.8125rem;
    color: var(--rz-text-secondary-color);
}

    .ic-note .rzi {
        font-size: 1rem;
    }

.ic-footer {
    display: flex;
    justify-content: flex-end;
    gap: 0.6rem;
    border-top: 1px solid var(--rz-base-300);
    margin-top: 0.25rem;
    padding-top: 1rem;
}

@media (prefers-reduced-motion: reduce) {
    .ic-mode {
        transition: none;
    }
}

.ic-alert {
    position: relative;
    padding: .7rem .9rem .75rem 1.15rem;
    border-radius: 8px;
    background: var(--rz-warning-lighter);
    font-size: .875rem;
}

    /* The bar does the work the icon used to. */
    .ic-alert::before {
        content: "";
        position: absolute;
        inset: .55rem auto .55rem .5rem;
        width: 3px;
        border-radius: 2px;
        background: var(--rz-warning);
    }

.ic-alert-eyebrow {
    display: block;
    margin-bottom: .15rem;
    font-size: .6875rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .07em;
    color: var(--rz-warning-dark);
}

.ic-alert strong {
    display: block;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
}

.ic-alert p {
    margin: .2rem 0 0;
    line-height: 1.45;
    color: var(--rz-text-secondary-color);
}

/* Blocking states keep the same shape, red instead of amber. */
.ic-alert-danger {
    background: var(--rz-danger-lighter);
}

    .ic-alert-danger::before {
        background: var(--rz-danger);
    }

    .ic-alert-danger .ic-alert-eyebrow {
        color: var(--rz-danger);
    }


/* =====================================================================
   ImportSourceDashboard — three equal source tiles.
   Same slate/navy language as the wizards; tokens are redeclared here
   because scoped CSS doesn't inherit from ReviewWizardDialog's scope.
   ===================================================================== */

.imp-dash {
    --imp-navy: #1f2a44;
    --imp-slate: #55627a;
    --imp-line: #e2e6ee;
    --imp-bg: #ffffff;
    --imp-bg-soft: #f6f8fb;
    /* Theme-driven accent. Fallbacks keep the tile readable if the Radzen
       theme variables aren't present on the page. */
    --imp-accent: var(--rz-primary, #2f6df6);
    --imp-accent-soft: var(--rz-primary-lighter, #eaf1ff);
    display: flex;
    flex-direction: column;
    gap: 1.5rem;
    color: var(--imp-navy);
    font-feature-settings: "tnum" 1;
}

/* ---- Grid: equal columns, equal heights ---- */
.imp-sources {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 1rem;
    align-items: stretch;
}

/* ---- Tile ---- */
.imp-tile {
    position: relative;
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
    overflow: hidden;
    padding: 1.5rem 1.35rem 1.35rem;
    border: 1px solid var(--imp-line);
    border-radius: 14px;
    background: var(--imp-bg);
    transition: border-color 160ms ease, box-shadow 160ms ease, transform 160ms ease;
}

    .imp-tile:hover:not(.is-locked):not(.is-busy) {
        border-color: var(--imp-accent);
        box-shadow: 0 8px 26px -14px rgba(31, 42, 68, 0.45);
        transform: translateY(-2px);
    }

    .imp-tile:focus-within {
        border-color: var(--imp-accent);
    }

    .imp-tile.is-locked {
        background: var(--imp-bg-soft);
    }

    .imp-tile.is-busy {
        border-color: var(--imp-accent);
    }

/* Top hairline: fills with accent on hover. The only motion on the tile
   besides the lift — it reads as "this one is armed". */
.imp-rule {
    position: absolute;
    inset: 0 auto auto 0;
    height: 3px;
    width: 100%;
    background: var(--imp-line);
    transform: scaleX(0.18);
    transform-origin: left center;
    transition: transform 220ms ease, background-color 220ms ease;
}

.imp-tile:hover:not(.is-locked) .imp-rule,
.imp-tile.is-busy .imp-rule,
.imp-tile:focus-within .imp-rule {
    background: var(--imp-accent);
    transform: scaleX(1);
}

.imp-tile.is-locked .imp-rule {
    transform: scaleX(0.18);
}

/* Signature: the source token blown up and clipped into the bottom-right
   corner. Gives each tile a distinct silhouette without a second palette. */
.imp-watermark {
    position: absolute;
    right: -0.35rem;
    bottom: -1.1rem;
    font-family: "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: 4.75rem;
    font-weight: 700;
    letter-spacing: -0.04em;
    line-height: 1;
    color: var(--imp-navy);
    opacity: 0.045;
    pointer-events: none;
    user-select: none;
    transition: opacity 200ms ease, color 200ms ease;
}

.imp-tile:hover:not(.is-locked) .imp-watermark {
    color: var(--imp-accent);
    opacity: 0.09;
}

.imp-tile.is-locked .imp-watermark {
    opacity: 0.03;
}

/* ---- Top row: token + qualifiers ---- */
.imp-tile-top {
    position: relative;
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.45rem;
}

.imp-token {
    font-family: "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: 0.66rem;
    font-weight: 700;
    letter-spacing: 0.12em;
    color: var(--imp-slate);
    background: var(--imp-bg-soft);
    border: 1px solid var(--imp-line);
    border-radius: 5px;
    padding: 0.2rem 0.45rem;
    white-space: nowrap;
    transition: color 160ms ease, border-color 160ms ease, background-color 160ms ease;
}

.imp-tile:hover:not(.is-locked) .imp-token {
    color: var(--imp-accent);
    border-color: var(--imp-accent);
    background: var(--imp-accent-soft);
}

.imp-badge {
    font-size: 0.6rem;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--imp-accent);
    background: var(--imp-accent-soft);
    padding: 0.15rem 0.45rem;
    border-radius: 999px;
}

.imp-meta {
    margin-left: auto;
    font-size: 0.68rem;
    text-transform: uppercase;
    letter-spacing: 0.07em;
    color: var(--imp-slate);
    white-space: nowrap;
}

/* ---- Type ---- */
.imp-title {
    position: relative;
    margin: 0.35rem 0 0;
    font-size: 1.22rem;
    font-weight: 650;
    line-height: 1.2;
    letter-spacing: -0.015em;
}

.imp-text {
    position: relative;
    margin: 0;
    font-size: 0.85rem;
    line-height: 1.55;
    color: var(--imp-slate);
}

/* ---- Foot: pinned so buttons align across tiles ---- */
.imp-tile-foot {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 0.6rem;
    margin-top: auto;
    padding-top: 1.1rem;
}

.imp-lock-reason {
    margin: 0;
    font-size: 0.78rem;
    font-weight: 500;
    color: var(--imp-navy);
}

.imp-progress {
    display: flex;
    align-items: center;
    gap: 0.45rem;
    margin: 0;
    font-size: 0.78rem;
    color: var(--imp-accent);
}

/* ---- Footer note ---- */
.imp-foot-note {
    display: flex;
    align-items: center;
    gap: 0.45rem;
    margin: 0;
    font-size: 0.8rem;
    color: var(--imp-slate);
}

    .imp-foot-note .rz-icon,
    .imp-foot-note .rzi {
        font-size: 1rem;
    }

/* ---- Responsive ---- */
@media (max-width: 1024px) {
    .imp-sources {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

@media (max-width: 680px) {
    .imp-sources {
        grid-template-columns: 1fr;
    }

    .imp-watermark {
        font-size: 3.75rem;
    }
}

@media (prefers-reduced-motion: reduce) {
    .imp-tile,
    .imp-rule,
    .imp-watermark,
    .imp-token {
        transition: none;
    }

        .imp-tile:hover:not(.is-locked):not(.is-busy) {
            transform: none;
        }
}

/* ============================================================
   Carrying amount import wizard — additions to the fsi-* set
   Only the classes that the planning workbook wizard does not
   already define. Everything else is reused as-is.
   ============================================================ */

/* Wide phases (categorization, resulting balance sheet) need the
   full dialog width; the narrow step-01 body keeps the wizard's
   default padding. */
.fsi-dialog .fsi-body-wide {
    padding: 0.75rem 1rem 1rem;
    max-width: none;
}

/* Embedded phases bring their own scroll container: BalanceSheetDataImporter
   scrolls its RadzenDataList, and step 03 scrolls the body. Only one of them
   may scroll at a time, otherwise the same content gets two scrollbars. */
.fsi-dialog .fsi-body-embed {
    overflow: hidden;
    display: flex;
    flex-direction: column;
    min-height: 0;
}

    /* The importer renders alerts and its RadzenStack as siblings. Only the stack
   may take the leftover height — the alerts keep their natural one, or they
   get squashed into a sliver. */
    .fsi-dialog .fsi-body-embed > .rz-alert {
        flex: 0 0 auto;
    }

    .fsi-dialog .fsi-body-embed > .rz-stack {
        flex: 1 1 auto;
        min-height: 0;
    }

    /* The data list is sized against the viewport (90vh), which ignores the header
   and footer sitting above and below it inside the dialog. A percentage
   max-height needs every ancestor to be height-constrained, so the flex chain
   is carried all the way down to the list. */
    .fsi-dialog .fsi-body-embed .rz-stack,
    .fsi-dialog .fsi-body-embed .rz-card,
    .fsi-dialog .fsi-body-embed .rz-card-content,
    .fsi-dialog .fsi-body-embed .rz-card-body {
        min-height: 0;
    }

    .fsi-dialog .fsi-body-embed > .rz-stack > .rz-card {
        flex: 1 1 auto;
        display: flex;
        flex-direction: column;
        min-height: 0;
        overflow: hidden;
    }

        .fsi-dialog .fsi-body-embed > .rz-stack > .rz-card > .rz-stack {
            flex: 1 1 auto;
            min-height: 0;
        }

    /* Toolbar, filter and header row stay put; the list absorbs the rest. */
    .fsi-dialog .fsi-body-embed .custom-rzdatalist {
        flex: 1 1 auto;
        height: auto !important;
        min-height: 8rem;
        max-height: none !important;
        overflow: auto !important;
    }

    /* Step 03 is a pair of grids with no inner scroller of its own — that one
   does need the body to scroll. */
    .fsi-dialog .fsi-body-embed.fsi-body-scroll {
        display: block;
        overflow: auto;
    }

/* A grouped block inside the body: heading, explanation, fields.
   No card border — the dialog is already a surface, and boxing a form inside
   a box adds a frame without adding meaning. A hairline above the fields
   separates the two just as clearly. */
.fsi-dialog .fsi-section {
    display: flex;
    flex-direction: column;
    gap: 1.75rem;
    padding: 0.5rem 0 1rem;
}

.fsi-dialog .fsi-section-head {
    display: flex;
    flex-direction: column;
    gap: 0.3125rem;
    padding-bottom: 1rem;
    border-bottom: 1px solid var(--rz-base-300, #e6e6e6);
}

    .fsi-dialog .fsi-section-head strong {
        font-size: 0.9375rem;
        font-weight: 600;
        letter-spacing: -0.005em;
        line-height: 1.3;
    }

    .fsi-dialog .fsi-section-head span {
        font-size: 0.8125rem;
        line-height: 1.5;
        max-width: 46rem;
        color: var(--rz-text-secondary-color, #6b6b6b);
    }

/* ---------- Form fields (step 01) ----------
   RadzenFormField is left at its defaults: the floating label already sits on
   top. The grid only handles placement and lets each field size itself. */

.fsi-dialog .fsi-field-grid {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    align-items: start;
    row-gap: 2rem;
    column-gap: 1.5rem;
}

/* Fixed three-column rhythm: fields stay the same width whether a group has
   one control or five, instead of stretching to fill the row. */
.fsi-dialog .fsi-grid-3 > .rz-form-field {
    max-width: 22rem;
}

.fsi-dialog .fsi-field-grid .rz-form-field {
    width: 100%;
    min-width: 0;
}

/* A labelled block of related fields, separated by a hairline so the eye can
   tell "which columns to read" from "how to read the numbers". */
.fsi-dialog .fsi-field-group {
    display: flex;
    flex-direction: column;
    gap: 1.25rem;
    padding-top: 1.75rem;
    margin-top: 0.5rem;
    border-top: 1px solid var(--rz-base-200, #eee);
}

.fsi-dialog .fsi-subhead {
    display: block;
    line-height: 1;
    font-size: 0.75rem;
    font-weight: 600;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--rz-text-secondary-color, #6b6b6b);
}

.fsi-dialog .fsi-switch-row {
    display: flex;
    align-items: center;
    gap: 0.625rem;
    padding-top: 0.5rem;
}

/* Disabled dropzone: readable, not decorative. */
.fsi-dialog .fsi-dropzone.is-disabled {
    opacity: 0.55;
    pointer-events: none;
}

/* Busy dropzone. The upload input underneath must stay in the DOM while the
   browser streams the file, so the busy state is layered on top rather than
   replacing the markup — removing the input mid-read kills the file handle. */
.fsi-dialog .fsi-dropzone.is-busy {
    position: relative;
    pointer-events: none;
}

    .fsi-dialog .fsi-dropzone.is-busy > *:not(.fsi-dropzone-spinner) {
        opacity: 0.35;
    }

.fsi-dialog .fsi-dropzone .fsi-dropzone-spinner {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.625rem;
    font-size: 0.875rem;
    color: var(--rz-text-secondary-color, #6b6b6b);
}

@media (max-width: 1280px) {
    .fsi-dialog .fsi-field-grid {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

@media (max-width: 760px) {
    .fsi-dialog .fsi-field-grid {
        grid-template-columns: minmax(0, 1fr);
    }
}

/* Step 01 is narrow content in a wide dialog. Without this the body keeps the
   wizard's reading width and leaves the right half of the shell empty. */
.fsi-dialog .fsi-body-form {
    max-width: none;
    width: 100%;
}

@media (prefers-reduced-motion: reduce) {
    .fsi-dialog * {
        animation-duration: 0.01ms !important;
        transition-duration: 0.01ms !important;
    }
}

/* =====================================================================
   ReviewWizardDialog — scroll containment additions
   Append to radzen-overrides.css (or the scoped ReviewWizardDialog css).
   These rules come AFTER the existing .fsi-body block so they win on
   equal specificity where they need to.
   ===================================================================== */

/* Beta banner: a fixed-height row inside the shell, like the header and
   footer. Only .fsi-body may take the leftover space and scroll. */
.fsi-dialog > .fsi-banner {
    flex: 0 0 auto;
    margin-bottom: 1rem;
}

/* ---- Review phase ----
   The ledger grid is height:100% and virtualized, so it owns the vertical
   scrolling. The body must clip instead of scrolling, or the same rows get
   two scrollbars. */
.fsi-dialog .fsi-body-ledger {
    display: flex;
    flex-direction: column;
    min-height: 0;
    overflow: hidden;
}

    /* Chips, alerts and the disclosure keep their natural height; the grid
   absorbs what is left. */
    .fsi-dialog .fsi-body-ledger > .fsi-chips,
    .fsi-dialog .fsi-body-ledger > .rz-alert,
    .fsi-dialog .fsi-body-ledger > .fsi-disclosure {
        flex: 0 0 auto;
    }

    .fsi-dialog .fsi-body-ledger > .fsi-ledger {
        flex: 1 1 auto;
        min-height: 0;
        height: auto !important;
    }

        /* Radzen puts the scroller on an inner wrapper; carry the height constraint
   down to it so the grid scrolls internally rather than growing. */
        .fsi-dialog .fsi-body-ledger > .fsi-ledger .rz-data-grid-data {
            min-height: 0;
        }

    /* The empty state replaces the grid and should take the same space. */
    .fsi-dialog .fsi-body-ledger > .fsi-ledger-empty {
        flex: 1 1 auto;
        min-height: 0;
        overflow: auto;
    }

    /* The skipped drawer renders below the grid. With the body clipping, a long
   list would be unreachable — cap it and let it scroll on its own. */
    .fsi-dialog .fsi-body-ledger > .fsi-skipped {
        flex: 0 0 auto;
        max-height: 14rem;
        overflow: auto;
    }

/* =====================================================================
   ReviewWizardDialog — scroll containment additions
   Append to radzen-overrides.css (or the scoped ReviewWizardDialog css).
   These rules come AFTER the existing .fsi-body block so they win on
   equal specificity where they need to.
   ===================================================================== */

/* Beta banner: a fixed-height row inside the shell, like the header and
   footer. Only .fsi-body may take the leftover space and scroll. */
.fsi-dialog > .fsi-banner {
    flex: 0 0 auto;
    margin-bottom: 1rem;
}

/* ---- Review phase ----
   The ledger grid is height:100% and virtualized, so it owns the vertical
   scrolling. The body must clip instead of scrolling, or the same rows get
   two scrollbars. */
.fsi-dialog .fsi-body-ledger {
    display: flex;
    flex-direction: column;
    min-height: 0;
    overflow: hidden;
}

    /* Chips, alerts and the disclosure keep their natural height; the grid
   absorbs what is left. */
    .fsi-dialog .fsi-body-ledger > .fsi-chips,
    .fsi-dialog .fsi-body-ledger > .rz-alert,
    .fsi-dialog .fsi-body-ledger > .fsi-disclosure {
        flex: 0 0 auto;
    }

    .fsi-dialog .fsi-body-ledger > .fsi-ledger {
        flex: 1 1 auto;
        min-height: 0;
        height: auto !important;
    }

        /* Radzen puts the scroller on an inner wrapper; carry the height constraint
   down to it so the grid scrolls internally rather than growing. */
        .fsi-dialog .fsi-body-ledger > .fsi-ledger .rz-data-grid-data {
            min-height: 0;
        }

    /* The empty state replaces the grid and should take the same space. */
    .fsi-dialog .fsi-body-ledger > .fsi-ledger-empty {
        flex: 1 1 auto;
        min-height: 0;
        overflow: auto;
    }

    /* The skipped drawer renders below the grid. With the body clipping, a long
   list would be unreachable — cap it and let it scroll on its own. */
    .fsi-dialog .fsi-body-ledger > .fsi-skipped {
        flex: 0 0 auto;
        max-height: 14rem;
        overflow: auto;
    }


/* =====================================================================
   Peer filter dialog + AI research panel
   Scoped to .fsi-peer / .fsi-research so nothing leaks into the wizards.
   .fsi-grid and .fsi-field are already owned by the wizard field layout -
   these blocks deliberately avoid both names.
   ===================================================================== */

.fsi-peer {
    min-width: 0; /* auto-fit in .fsi-cols-2 handles the stacking now */
    height: 100%;
}

/* ---- Filter panel ---- */
.fsi-filters {
    display: flex;
    flex-direction: column;
    gap: 1rem;
    padding: 1rem;
    border: 1px solid var(--fsi-line);
    border-radius: 10px;
    background: var(--fsi-bg-soft);
    flex: 0 0 auto;
}

.fsi-filter-field {
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
    min-width: 0;
}

.fsi-filter-label {
    font-size: 0.72rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--fsi-slate);
}

.fsi-cols-2 {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(20rem, 100%), 1fr));
    gap: 1rem;
}

.fsi-cols-2-wide {
    gap: 2rem;
}

.fsi-group-title {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    margin: 0 0 0.75rem;
    padding-bottom: 0.375rem;
    border-bottom: 1px solid var(--fsi-line);
    font-size: 0.875rem;
    font-weight: 600;
    color: var(--fsi-navy);
}

    .fsi-group-title span {
        font-size: 0.6875rem;
        font-weight: 500;
        color: var(--fsi-slate);
    }

.fsi-range {
    display: grid;
    grid-template-columns: 9.5rem minmax(0, 1fr);
    align-items: center;
    gap: 0.5rem;
    margin-bottom: 0.5rem;
}

.fsi-range-label {
    font-size: 0.8125rem;
    line-height: 1.2;
    color: var(--fsi-navy);
}

    .fsi-range-label em {
        display: block;
        font-style: normal;
        font-size: 0.6875rem;
        color: var(--fsi-slate);
    }

.fsi-range-inputs {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0.375rem;
    min-width: 0;
}

/* =====================================================================
   Result frame

   The grid has to fill the frame in BOTH axes. Radzen won't do either on
   its own: vertically it sizes to content, horizontally it sizes to the
   sum of the column widths and hands the overflow to an inner scroller.
   Every rule below exists to undo one of those two behaviours.
   ===================================================================== */

.fsi-results {
    position: relative;
    display: flex;
    flex-direction: column;
    flex: 1 1 auto;
    min-height: 420px; /* a floor, never a cap */
    width: 100%;
    border: 1px solid var(--fsi-line);
    border-radius: 10px;
    overflow: hidden;
}

/* The dialog body scrolls by default; when it hosts a full-size grid the
   grid owns the scrolling instead, so the frame is free to stretch. */
.fsi-peer > .fsi-body,
.fsi-research > .fsi-body {
    overflow: visible;
}

/* --- Vertical: carry the height down to the scrollable data area --- */
.fsi-results .rz-data-grid,
.fsi-results .rz-datatable {
    display: flex;
    flex-direction: column;
    flex: 1 1 auto;
    min-height: 0;
    width: 100%;
    height: 100%;
    border: none;
}

.fsi-results .rz-data-grid-data,
.fsi-results .rz-datatable-scrollable-body,
.fsi-results .rz-datatable-scrollable-view,
.fsi-results .rz-datatable-scrollable-wrapper {
    flex: 1 1 auto;
    min-height: 0;
    max-height: none !important; /* Radzen writes an inline max-height */
    width: 100% !important;
}

.fsi-results .rz-data-grid-data,
.fsi-results .rz-datatable-scrollable-body {
    overflow: auto;
}

    /* --- Horizontal: kill the content-width table and the inner scroller ---
   Radzen sets an inline pixel width on the table (and on the frozen-column
   wrappers) whenever any column is frozen or every column has a fixed
   Width. Forcing 100% makes the columns share the real dialog width. */
    .fsi-results .rz-grid-table,
    .fsi-results .rz-data-grid-data > table,
    .fsi-results .rz-datatable-scrollable-header-box,
    .fsi-results .rz-datatable-scrollable-body-table,
    .fsi-results .rz-datatable-scrollable-header-table {
        width: 100% !important;
        min-width: 100% !important;
        table-layout: fixed;
    }

/* Radzen's frozen-column machinery wraps the grid in fixed-width boxes.
   Neutralise the wrappers; the columns keep their own widths. */
.fsi-results .rz-frozen-cells,
.fsi-results .rz-datatable-frozen-view,
.fsi-results .rz-datatable-unfrozen-view {
    width: auto !important;
    max-width: none !important;
    float: none !important;
}

/* Long values truncate inside their cell instead of widening the table. */
.fsi-results .rz-grid-table td,
.fsi-results .rz-grid-table th {
    overflow: hidden;
    text-overflow: ellipsis;
}

/* Paginator stays pinned to the bottom edge of the frame. */
.fsi-results .rz-pager,
.fsi-results .rz-paginator {
    flex: 0 0 auto;
    width: 100%;
    border-top: 1px solid var(--fsi-line);
}

.fsi-results-spinner {
    position: absolute;
    inset: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0.75rem;
}

    .fsi-results-spinner p {
        margin: 0;
        color: var(--fsi-slate);
    }

/* =====================================================================
   AI research panel - embedded in a page, not a modal. There is no fixed
   parent height to inherit, so the grid grows with its rows.
   ===================================================================== */

.fsi-panel-embedded {
    box-shadow: none;
    border: none;
    background: transparent;
    height: auto;
}

    .fsi-panel-embedded > .fsi-body {
        overflow: visible;
        min-height: 0;
    }

    .fsi-panel-embedded .fsi-results {
        flex: 0 0 auto;
        min-height: 0;
        height: auto;
    }

        .fsi-panel-embedded .fsi-results .rz-data-grid,
        .fsi-panel-embedded .fsi-results .rz-datatable {
            height: auto;
        }

        .fsi-panel-embedded .fsi-results .rz-data-grid-data {
            max-height: none !important;
            overflow: visible;
        }

        /* The excerpt column carries prose - let it wrap rather than clip. */
        .fsi-panel-embedded .fsi-results .rz-grid-table td {
            overflow: visible;
            text-overflow: clip;
        }

/* ---- Toolbar variant carrying the agent actions ---- */
.fsi-toolbar-actions {
    flex-wrap: wrap;
    row-gap: 0.5rem;
}

    .fsi-toolbar-actions .fsi-toolbar-left,
    .fsi-toolbar-actions .fsi-toolbar-right {
        flex-wrap: wrap;
    }

.fsi-switch {
    display: inline-flex;
    align-items: center;
    gap: 0.375rem;
}

.fsi-toolbar-divider {
    width: 1px;
    align-self: stretch;
    margin: 0 0.25rem;
    background: var(--fsi-line);
}

.fsi-inline-field {
    display: inline-flex;
    align-items: center;
    gap: 0.375rem;
}

.fsi-label-inline {
    font-size: 0.72rem;
    font-weight: 600;
    letter-spacing: 0.05em;
    color: var(--fsi-slate);
    white-space: nowrap;
}

/* ---- Cell treatments ---- */
.fsi-cell-inline {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 4px;
}

.fsi-excerpt {
    max-height: 80px;
    overflow-y: auto;
    font-size: 0.875rem;
    line-height: 1.45;
    white-space: normal;
    word-break: break-word;
    cursor: help;
}

.fsi-empty {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.375rem;
    padding: 2.5rem 1rem;
    text-align: center;
}

    .fsi-empty .rzi,
    .fsi-empty .rz-icon {
        font-size: 1.75rem;
        color: var(--fsi-slate);
    }

    .fsi-empty strong {
        font-size: 0.95rem;
        color: var(--fsi-navy);
    }

    .fsi-empty span {
        font-size: 0.85rem;
        color: var(--fsi-slate);
    }

/* ---- Responsive ---- */
@media (max-width: 900px) {
    .fsi-range {
        grid-template-columns: 1fr;
    }
}

/* =====================================================================
   Planning charts - nine panels grouped by unit of measure
   ===================================================================== */

.fsi-charts > .fsi-body {
    gap: 2rem;
}

.fsi-chart-section {
    display: flex;
    flex-direction: column;
    gap: 1rem;
}

/* The section head is a rule with a label sitting on it: it separates the
   three unit regimes without adding another boxed container. */
.fsi-section-head {
    display: flex;
    align-items: baseline;
    gap: 0.75rem;
    margin: 0;
    padding-bottom: 0.5rem;
    border-bottom: 1px solid var(--fsi-line);
    font-size: 0.78rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--fsi-navy);
}

    .fsi-section-head em {
        font-style: normal;
        font-weight: 500;
        text-transform: none;
        letter-spacing: 0;
        font-size: 0.78rem;
        color: var(--fsi-slate);
    }

.fsi-chart-row {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 1rem;
    align-items: stretch;
}

.fsi-chart {
    display: flex;
    flex-direction: column;
    min-width: 0;
    margin: 0;
    padding: 1rem 1rem 0.5rem;
    border: 1px solid var(--fsi-line);
    border-radius: 10px;
    background: var(--fsi-bg);
}

    .fsi-chart > figcaption {
        display: flex;
        align-items: baseline;
        gap: 0.4rem;
        font-size: 0.92rem;
        font-weight: 600;
        color: var(--fsi-navy);
    }

        /* The three-letter code is the working vocabulary; the full name is
       there for anyone who doesn't have it memorised. */
        .fsi-chart > figcaption abbr {
            font-family: "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
            font-size: 0.68rem;
            font-weight: 700;
            letter-spacing: 0.08em;
            color: var(--fsi-slate);
            text-decoration: none;
            border: 1px solid var(--fsi-line);
            border-radius: 4px;
            padding: 0.1rem 0.35rem;
        }

@media (max-width: 1200px) {
    .fsi-chart-row {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

@media (max-width: 760px) {
    .fsi-chart-row {
        grid-template-columns: 1fr;
    }
}

/* =====================================================================
   Probability of default helper
   ===================================================================== */

.fsi-pod {
    min-width: 720px;
    height: 100%;
}

    .fsi-pod > .fsi-body {
        overflow: auto;
    }

/* ---- Input blocks ---- */
.fsi-input-block {
    display: flex;
    flex-direction: column;
    gap: 0.85rem;
    padding: 1.1rem 1.25rem;
    border: 1px solid var(--fsi-line);
    border-radius: 10px;
    background: var(--fsi-bg);
}

.fsi-input-lead {
    margin: 0;
    max-width: 68ch;
    font-size: 0.85rem;
    line-height: 1.5;
    color: var(--fsi-slate);
}

    .fsi-input-lead strong {
        color: var(--fsi-navy);
        font-weight: 650;
        font-variant-numeric: tabular-nums;
    }

.fsi-input-single {
    display: flex;
    flex-direction: column;
    gap: 0.3rem;
    max-width: 16rem;
}

    .fsi-input-single .rz-numeric {
        width: 100%;
    }

/* ---- Outcome: the adjustment leads, the two values support it ---- */
.fsi-outcome {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 1.5rem;
    padding: 1.15rem 1.35rem;
    border: 1px solid var(--fsi-line);
    border-left: 3px solid var(--fsi-accent);
    border-radius: 10px;
    background: linear-gradient(90deg, var(--fsi-accent-soft) 0%, var(--fsi-bg-soft) 65%);
}

.fsi-outcome-lead {
    display: flex;
    flex-direction: column;
    gap: 0.2rem;
    min-width: 0;
}

.fsi-outcome-label {
    font-size: 0.72rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--fsi-slate);
}

.fsi-outcome-figure {
    font-size: 2rem;
    font-weight: 650;
    line-height: 1;
    letter-spacing: -0.02em;
    font-variant-numeric: tabular-nums;
    color: var(--fsi-accent);
}

.fsi-outcome-pair {
    display: flex;
    align-items: center;
    gap: 1rem;
}

.fsi-outcome-item {
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
}

.fsi-outcome-key {
    font-size: 0.72rem;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--fsi-slate);
}

.fsi-outcome-val {
    font-size: 1rem;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
    color: var(--fsi-navy);
}

    .fsi-outcome-val em {
        font-style: normal;
        font-size: 0.75rem;
        font-weight: 500;
        color: var(--fsi-slate);
    }

.fsi-outcome-arrow {
    color: var(--fsi-slate);
    flex: 0 0 auto;
}

/* The per-period grid is one transposed input row - it must not scroll
   internally, and the label column stays readable. */
.fsi-pod .fsi-periods-grid .rz-data-grid,
.fsi-pod .fsi-periods-grid .rz-datatable {
    border: none;
    width: 100%;
}

.fsi-pod .fsi-periods-grid .rz-grid-table {
    width: 100% !important;
}

.fsi-chart-wide {
    width: 100%;
}

@media (max-width: 760px) {
    .fsi-pod {
        min-width: 0;
    }

    .fsi-outcome {
        flex-direction: column;
        align-items: flex-start;
    }
}

/* =====================================================================
   Relative weighting calculator
   ===================================================================== */

.fsi-weighting {
    min-width: min(1080px, 92vw);
    height: 100%;
}

/* ---- Toolbar: primary action left, destructive action far right ---- */
.fsi-toolbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 0.75rem;
}

.fsi-toolbar-main,
.fsi-toolbar-end {
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

/* ---- Wide grid, scrolled inside its own frame ---- */
.fsi-grid-frame {
    border: 1px solid var(--fsi-line);
    border-radius: 10px;
    overflow: hidden;
    background: var(--fsi-bg);
}

.fsi-weighting-grid {
    overflow-x: auto;
}

    .fsi-weighting-grid .rz-data-grid,
    .fsi-weighting-grid .rz-datatable {
        border: none;
    }

    /* The footer row carries the weighted results - it is the answer, so it
   gets a rule above it and holds still while the body scrolls. */
    .fsi-weighting-grid .rz-datatable-tfoot > tr > td,
    .fsi-weighting-grid .rz-grid-table tfoot > tr > td {
        border-top: 2px solid var(--fsi-navy);
        background: var(--fsi-bg-soft);
        font-variant-numeric: tabular-nums;
    }

.fsi-total-label {
    font-size: 0.72rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--fsi-slate);
}

.fsi-row-delete {
    opacity: 0.55;
    transition: opacity 0.12s ease;
}

    .fsi-weighting-grid tr:hover .fsi-row-delete,
    .fsi-row-delete:focus-visible {
        opacity: 1;
    }

/* ---- Legend for the two value states in the grid ---- */
.fsi-legend {
    display: flex;
    flex-wrap: wrap;
    gap: 1.25rem;
    padding: 0 0.25rem;
    font-size: 0.78rem;
    color: var(--fsi-slate);
}

.fsi-legend-item {
    display: inline-flex;
    align-items: center;
    gap: 0.45rem;
}

.fsi-swatch {
    width: 0.85rem;
    height: 0.85rem;
    border-radius: 3px;
    border: 1px solid var(--fsi-line);
    flex: 0 0 auto;
}

.fsi-swatch-source {
    background: var(--rz-makery-lightyellow);
}

.fsi-swatch-excluded {
    background: transparent;
    border-color: var(--rz-makery-darkred);
    position: relative;
}

    .fsi-swatch-excluded::after {
        content: "";
        position: absolute;
        inset: 45% 10% auto 10%;
        border-top: 1px solid var(--rz-makery-darkred);
    }

/* ---- Empty state ---- */
.fsi-empty {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0.6rem;
    padding: 3.5rem 1.5rem;
    border: 1px dashed var(--fsi-line);
    border-radius: 10px;
    background: var(--fsi-bg-soft);
    text-align: center;
}

    .fsi-empty .rzi {
        font-size: 2rem;
        color: var(--fsi-slate);
        opacity: 0.6;
    }

    .fsi-empty strong {
        font-size: 1rem;
        color: var(--fsi-navy);
    }

    .fsi-empty p {
        margin: 0 0 0.5rem;
        max-width: 42ch;
        font-size: 0.85rem;
        color: var(--fsi-slate);
    }

/* ---- Unsaved indicator in the footer ---- */
.fsi-footer-left {
    display: flex;
    align-items: center;
    min-height: 1.5rem;
}

.fsi-unsaved {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    font-size: 0.82rem;
    color: var(--fsi-slate);
}

.fsi-unsaved-dot {
    width: 0.5rem;
    height: 0.5rem;
    border-radius: 50%;
    background: var(--fsi-accent);
    flex: 0 0 auto;
}

@media (max-width: 900px) {
    .fsi-weighting {
        min-width: 0;
    }

    .fsi-toolbar {
        flex-direction: column;
        align-items: stretch;
    }

    .fsi-toolbar-end {
        justify-content: flex-end;
    }
}

.fsi-empty {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    gap: 1rem;
    /*    max-width: 30rem;
*/
    /*    margin: 0 auto;
*/ padding: 2.5rem 1.5rem;
}

.fsi-empty__icon {
    display: grid;
    place-items: center;
    width: 3rem;
    height: 3rem;
    border-radius: 50%;
    background: var(--rz-base-200);
    color: var(--rz-text-secondary-color);
}

    .fsi-empty__icon .rzi {
        font-size: 1.5rem;
    }

.fsi-empty__copy {
    display: flex;
    flex-direction: column;
    gap: .375rem;
}

.fsi-empty__title {
    margin: 0;
}

.fsi-empty__body {
    margin: 0;
    color: var(--rz-text-secondary-color);
}

.fsi-empty__blocks {
    list-style: none;
    margin: 0;
    padding: 0;
    width: 100%;
    display: flex;
    flex-direction: column;
    gap: .25rem;
    max-height: 9rem;
    overflow-y: auto;
}

.fsi-empty__block {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: .5rem;
    padding: .5rem .75rem;
    border: 1px solid var(--rz-base-300);
    border-radius: var(--rz-border-radius, 4px);
    background: var(--rz-base-100);
    font-size: .8125rem;
    line-height: 1.2;
}

.fsi-empty__block-label {
    text-transform: uppercase;
    letter-spacing: .04em;
    font-size: .6875rem;
    color: var(--rz-text-tertiary-color, var(--rz-text-secondary-color));
}

.fsi-empty__block-value {
    font-variant-numeric: tabular-nums;
}

.fsi-empty__block-sep {
    width: 1px;
    height: .875rem;
    background: var(--rz-base-300);
}

/* =============================================================================
   Ledger type scale — one ramp, three steps
   =============================================================================
   The ledger had six sizes across its cells (0.7 / 0.72 / 0.74 / 0.76 / 0.82 /
   0.88rem) plus --rz-grid-cell-font-size at 1.0rem from the theme. Nothing
   distinguished them semantically, so the eye had to re-measure every column.

   Three steps, each earning its place:
     --fsi-t-item  0.8125rem  the line item. The only thing the user reads as
                              language, so it is the largest.
     --fsi-t-data  0.8125rem  the figures. Same size as the item on purpose --
                              a statement's label and its number are one
                              sentence, and setting them apart made the row
                              read as two unrelated columns.
     --fsi-t-meta  0.6875rem  everything about the row rather than in it:
                              provenance, translation, period headers, flags.

   Weight and colour carry the hierarchy instead of size, which is what keeps
   forty rows scannable.
   ============================================================================= */

.fsi-ledger {
    --fsi-t-item: 0.8125rem;
    --fsi-t-data: 0.8125rem;
    --fsi-t-meta: 0.6875rem;
    /* The theme's 1.0rem cell size is the loudest voice in the grid and nothing
       in the ledger wants it. Scoped to .fsi-ledger so the periods grid in
       Step 1 keeps the global setting. */
    --rz-grid-cell-font-size: var(--fsi-t-item);
}

    /* Figures and labels share one ramp AND one numeral treatment. tabular-nums
       was set on .fsi-val only, so a year in a header or a count in a flag
       jittered against the column below it. */
    .fsi-ledger .fsi-src {
        font-size: var(--fsi-t-item);
        font-weight: 550;
    }

    .fsi-ledger .fsi-src-en,
    .fsi-ledger .fsi-prov,
    .fsi-ledger .fsi-val-period,
    .fsi-ledger .fsi-conflict,
    .fsi-ledger .fsi-kept-out,
    .fsi-ledger .fsi-verified {
        font-size: var(--fsi-t-meta);
    }

    .fsi-ledger .fsi-val {
        font-size: var(--fsi-t-data);
    }

    /* Icons scale with the text they sit beside instead of holding a fixed rem,
       which is what made the provenance glyph look oversized once the label
       shrank. */
    .fsi-ledger .fsi-prov .rz-icon,
    .fsi-ledger .fsi-prov i {
        font-size: 1.15em;
    }

    /* The action column is the only place with buttons, and Radzen's
       ExtraSmall still comes in above the meta step. */
    .fsi-ledger .rz-button.rz-button-xs {
        font-size: var(--fsi-t-meta);
    }

/* =============================================================================
   Confidence verification
   =============================================================================
   A machine mapping below its tier's floor blocks the import until the user
   looks at it. Two surfaces: the row (fsi-verify-row, above) and the per-row
   button. There is no bulk bar -- every decision is made one row at a time.
   ============================================================================= */

/* The notice stack above the grid. One box per open blocker.
   ---------------------------------------------------------------------------
   Bordered rather than filled: these are standing conditions, not alerts, and
   they sit directly above a grid already using the same two colours as a row
   wash. A filled box would out-shout the rows it is pointing at.

   The stack is capped and scrolls. Five notices at once is possible on a fresh
   tenant with a messy workbook, and an unbounded stack would push the grid --
   the thing the notices are asking the user to look at -- off the screen. */
.fsi-notices {
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
    overflow-y: auto;
    flex: 0 0 auto;
}

.fsi-notice {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    padding: 0.5rem 0.7rem;
    border: 1px solid var(--fsi-verify, #f59e0b);
    border-radius: 8px;
    background: var(--fsi-verify-soft, rgba(245, 158, 11, 0.07));
}

    /* Red is a fault: the library disagrees with itself and no amount of reading
       resolves it, only a decision. Amber is a question. Same meanings the row
       wash carries, so a notice and the rows it names never contradict. */
    .fsi-notice.is-critical {
        border-color: var(--fsi-critical, #dc2626);
        background: var(--fsi-critical-soft, rgba(220, 38, 38, 0.12));
    }

    /* Violet: a row with figures and nowhere to put them. Same tokens as
       tr.fsi-unmapped-row, so the box and the rows it counts are one colour. */
    .fsi-notice.is-unmapped {
        border-color: var(--fsi-unmapped, #7c3aed);
        background: var(--fsi-unmapped-soft, rgba(124, 58, 237, 0.08));
    }

        .fsi-notice.is-unmapped .fsi-notice-text .rz-icon,
        .fsi-notice.is-unmapped .fsi-notice-text i {
            color: var(--fsi-unmapped-ink, #5b21b6);
        }

    /* Grey is structural: a detected total or subtotal stays out of the import
       and never blocks it. Same tokens as tr.fsi-total-row, so the notice and
       the rows it counts read as the same colour. */
    .fsi-notice.is-total {
        border-color: var(--fsi-rule, #d0d0d0);
        background: var(--fsi-total-bg, #f6f7f9);
    }

        .fsi-notice.is-total .fsi-notice-text .rz-icon,
        .fsi-notice.is-total .fsi-notice-text i {
            color: var(--fsi-slate, #55627a);
        }

    .fsi-notice .fsi-notice-text {
        display: flex;
        align-items: center;
        gap: 0.5rem;
        font-size: 0.75rem;
        color: var(--fsi-ink, #1f2933);
    }

        /* The glyph never shrinks. It is the severity cue, and a squeezed icon
           column is the first thing to go when the detail line runs long. */
        .fsi-notice .fsi-notice-text .rz-icon,
        .fsi-notice .fsi-notice-text i {
            flex: 0 0 auto;
            color: var(--fsi-verify-ink, #b45309);
            font-size: 1.1rem;
        }

    .fsi-notice.is-critical .fsi-notice-text .rz-icon,
    .fsi-notice.is-critical .fsi-notice-text i {
        color: var(--fsi-critical, #dc2626);
    }

    /* The headline carries the count and sits on its own line above the detail:
       scanning five notices means reading five counts, and an inline bold run
       forces the eye through the prose to find the next one. */
    .fsi-notice .fsi-notice-text strong {
        display: block;
    }

    /* The shortcut holds its width so the text column takes the compression. */
    .fsi-notice > .rz-button {
        flex: 0 0 auto;
    }

@media (max-width: 900px) {
    .fsi-notice {
        flex-direction: column;
        align-items: stretch;
    }
}

/* Cleared state. Deliberately understated: it reads as a receipt, and it is
   also the undo, so it must not compete with the rows still waiting. */
.fsi-verified {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    margin-top: 0.3rem;
    padding: 0.15rem 0.35rem;
    border: 0;
    border-radius: 5px;
    background: transparent;
    color: var(--fsi-slate, #64748b);
    cursor: pointer;
    font: inherit;
    font-size: var(--fsi-t-meta, 0.6875rem);
}

    .fsi-verified .rz-icon, .fsi-verified i {
        font-size: 1.05em;
        color: var(--fsi-verify-ink, #b45309);
    }

    .fsi-verified:hover {
        background: var(--fsi-verify-soft, rgba(245, 158, 11, 0.07));
        color: var(--fsi-ink, #1f2933);
    }

    /* Keyboard focus has to be visible on a control whose resting state is
       borderless and transparent. */
    .fsi-verified:focus-visible {
        outline: 2px solid var(--fsi-verify-ink, #b45309);
        outline-offset: 1px;
    }

/* A settled row recedes. Opacity rather than a colour per element, so
   one rule covers the label, the figures, the picker and the glyph without
   fighting each of their own colours. 0.55 keeps the figures legible at this
   size -- below about 0.5 the tabular digits start to break up.

   RowClass emits "fsi-excluded-row fsi-total-row" for an excluded total, so the
   total's weight and top rule survive the dimming. A subtotal has to keep
   reading as a subtotal even while it recedes: it is the row that tells you
   where one section of the statement ends. */
tr.fsi-excluded-row td {
    opacity: 0.55;
    background: var(--fsi-excluded-bg, #fbfbfc) !important;
}

/* The outcome label is the one thing on the row that must stay readable --
       it is the explanation for why everything around it is faded. */
tr.fsi-excluded-row .fsi-not-imported {
    opacity: 1;
}

/* Hover restores full contrast. The row is still interactive (the picker
       brings it back into the import), and a control you can use should not
       look disabled while you are pointing at it. */
tr.fsi-excluded-row:hover td {
    opacity: 0.9;
}

/* Focus-within, not just hover: keyboard users reach the picker by tab, and
       they need the same restoration a mouse user gets. */
tr.fsi-excluded-row:focus-within td {
    opacity: 1;
}

/* An excluded TOTAL keeps its weight and its top rule. Restated here rather
       than relying on source order, because .fsi-excluded-row is emitted first
       in the class attribute and the two rules would otherwise be a coin flip
       on which one set the background. */
tr.fsi-excluded-row.fsi-total-row td {
    font-weight: 600;
    border-top: 1px solid var(--fsi-rule, #d0d0d0);
    background: var(--fsi-total-bg, #f6f7f9) !important;
}

    tr.fsi-excluded-row.fsi-total-row td:first-child {
        border-left: 3px solid var(--fsi-rule, #d0d0d0);
    }

/* Reduced motion has nothing to do here, but reduced transparency does: some
   users disable it at the OS level, and an opacity-based state is exactly what
   that setting is about. Fall back to a colour shift. */
@media (prefers-reduced-transparency: reduce) {
    tr.fsi-excluded-row td {
        opacity: 1;
        color: var(--fsi-muted, #94a3b8);
    }
}

/* A live detected total is grey and grey only. RowClass no longer emits
   "fsi-total-row fsi-verify-row" together: a total never blocks the import, so
   it must not wear the amber that means "this is holding you up". The former
   amber-over-total override was deleted here rather than commented out. */


/* Peer dialog shell: body must shrink, footer must keep its space */
.fsi-dialog {
    height: 100%;
    min-height: 0;
    overflow: hidden;
}

    .fsi-dialog > .fsi-body {
        flex: 1 1 auto;
        min-height: 0;
        overflow: auto;
    }

    .fsi-dialog > .fsi-footer {
        flex: 0 0 auto;
        background: #fff;
        position: relative;
        z-index: 1;
    }


/* ---- Peer dialog: narrow screens ---- */

/* =====================================================================
   DataCoverageStrip — flat variant inside the wizard header
   Compact by intent: no hover growth (the tooltip already answers the
   question at this size), and "no data" is a hollow ring rather than a
   filled red dot. Missing history is not an error, it is the reason the
   import exists — and filled/hollow survives red-green colour blindness.
   ===================================================================== */

.fsi-coverage .dcs--flat {
    font-size: 0.75rem;
    border-collapse: collapse;
    margin: 0;
}

    .fsi-coverage .dcs--flat th,
    .fsi-coverage .dcs--flat td {
        padding: 0.1rem 0.45rem;
        text-align: center;
        border: none;
    }

    .fsi-coverage .dcs--flat th {
        font-size: 0.66rem;
        font-weight: 500;
        letter-spacing: 0.02em;
        color: var(--fsi-slate);
        font-variant-numeric: tabular-nums;
    }

    .fsi-coverage .dcs--flat .dcs__rowlabel {
        text-align: left;
        padding-left: 0;
        padding-right: 0.6rem;
        white-space: nowrap;
        color: var(--fsi-slate);
    }

    /* Hover belongs to the full-size strip, not to a 7px dot in a header. */
    .fsi-coverage .dcs--flat tbody tr:hover {
        background: none;
    }

        .fsi-coverage .dcs--flat tbody tr:hover .dcs__dot {
            transform: none;
        }

    .fsi-coverage .dcs--flat .dcs__dot {
        width: 7px;
        height: 7px;
        box-shadow: none;
    }

    .fsi-coverage .dcs--flat .dcs__mark.on .dcs__dot {
        background: var(--dcs-on);
        box-shadow: none;
    }

    /* "No data" is a FILLED GREY dot, not a red one and not a hollow ring.
       Red says "this is wrong"; an empty year is not wrong, it is the reason
       the import exists. Grey filled beats a ring because it keeps the exact
       size and optical weight of the "on" dot -- a 1px ring at 7px reads
       lighter and makes an empty row look sparse rather than neutral. Filled
       petrol vs filled grey is a pure value contrast, so it also survives
       greyscale printing and red-green colour blindness. */
    .fsi-coverage .dcs--flat .dcs__mark.off .dcs__dot {
        background: var(--dcs-off);
        border: none;
        box-shadow: none;
        opacity: 1;
    }

    /* The plan divider is the one structural line worth keeping: it marks
       where actuals stop and planning begins. */
    .fsi-coverage .dcs--flat th.is-first-plan,
    .fsi-coverage .dcs--flat td.is-first-plan {
        border-left: 1px solid var(--fsi-line);
    }

    /* Columns this file will touch, once IncomingYears is passed in. */
    .fsi-coverage .dcs--flat th.is-incoming {
        color: var(--fsi-accent);
        font-weight: 700;
    }

    .fsi-coverage .dcs--flat td.is-incoming {
        background: var(--fsi-accent-soft);
    }

/* =====================================================================
   mk-comet - Makery spinner
   Indeterminate: a comet head trailing into nothing.
   Determinate:   an arc growing from 12 o'clock over a track.
   Proportions follow the 80px original: track = size/8, head = size/10.
   The donut hole is a MASK, not a filled disc, so one element works on
   white, on --fsi-bg-soft, and on the near-black overlay.

   GROUND HANDLING
   The previous version used one fixed ramp (deep petrol -> pale aqua) on
   every surface, which cannot work: a comet reads as a comet because the
   head is the brightest thing and the tail dies into the background. On a
   near-black overlay that means head = pale aqua. On white it means the
   opposite - head = deep petrol, tail = pale aqua - or the head simply
   vanishes (#8ee7e8 sits at ~1.6:1 against white).

   So the ramp is now three tokens, and only their VALUES flip per ground.
   The shape, timing, glow geometry and mask are identical, so it is the
   same object in two lights rather than two different spinners.
   ===================================================================== */

.mk-comet {
    --mk-comet-size: 2.75rem;
    --mk-comet-track: calc(var(--mk-comet-size) / 12);
    --mk-comet-head: calc(var(--mk-comet-size) / 10);
    --mk-comet-speed: 1s;
    /* Light ground is the default: most surfaces in the app are white or
       --fsi-bg-soft. c1 = head, c2 = mid, c3 = where the tail dies out. */
    --mk-comet-c1: #10707e;
    --mk-comet-c2: #43aab3;
    --mk-comet-c3: #b8e6e7;
    /* On light, "glow" is a soft shadow the head casts, not emitted light.
       A luminous halo on white just fogs the head and greys the edge. */
    --mk-comet-halo: rgba(16, 112, 126, 0.16);
    --mk-comet-halo-blur: 0 1px 2px rgba(16, 112, 126, 0.22);
    --mk-comet-bloom: none;
    position: relative;
    display: inline-block;
    width: var(--mk-comet-size);
    height: var(--mk-comet-size);
    flex: 0 0 auto;
    animation: mk-comet-spin var(--mk-comet-speed) linear infinite;
}

    /* Tail. The fade runs head -> mid -> pale -> transparent. Ending in
       transparent rather than in a colour is what lets the same rule sit on
       white, on the soft grey panel and on the overlay without a seam. */
    .mk-comet::before {
        content: "";
        position: absolute;
        inset: 0;
        border-radius: 50%;
        background: conic-gradient( transparent 0deg, transparent 150deg, var(--mk-comet-c3) 232deg, var(--mk-comet-c2) 300deg, var(--mk-comet-c1) 348deg, var(--mk-comet-c1) 360deg );
        filter: var(--mk-comet-bloom);
        -webkit-mask: radial-gradient(farthest-side, transparent calc(100% - var(--mk-comet-track)), #000 calc(100% - var(--mk-comet-track)));
        mask: radial-gradient(farthest-side, transparent calc(100% - var(--mk-comet-track)), #000 calc(100% - var(--mk-comet-track)));
    }

    /* Head, on the ring midline at 12 o'clock. Two shadows: a tight ring
       that keeps the head legible on ANY ground by giving it its own edge,
       and a ground-specific bloom or drop shadow. */
    .mk-comet::after {
        content: "";
        position: absolute;
        top: calc(var(--mk-comet-track) / 2);
        left: 50%;
        width: var(--mk-comet-head);
        height: var(--mk-comet-head);
        transform: translate(-50%, -50%);
        border-radius: 50%;
        background: var(--mk-comet-c1);
        box-shadow: 0 0 0 3px var(--mk-comet-halo), var(--mk-comet-halo-blur);
    }

@keyframes mk-comet-spin {
    to {
        transform: rotate(360deg);
    }
}

/* ---- Dark ground ----------------------------------------------------
   Same ramp, inverted in value: the head becomes the light source and the
   tail sinks into petrol before it disappears. This is also where a real
   bloom belongs - emitted light only reads against a dark surface.

   Three ways in, one token set:
     .mk-comet--on-dark          Ground.Dark on the comet itself
     .mk-comet-host--on-dark     Ground.Dark via the host (also sets label ink)
     .mk-comet--auto             Ground.Auto, resolved by the OS scheme below
   Light is the default and needs no class, so a comet with no modifier is
   still correct on the surfaces most of this app uses. */
.mk-comet--on-dark,
.mk-comet-host--on-dark .mk-comet {
    --mk-comet-c1: #a8f2f3;
    --mk-comet-c2: #35a9b1;
    --mk-comet-c3: #11616e;
    --mk-comet-halo: rgba(142, 231, 232, 0.28);
    --mk-comet-halo-blur: 0 0 12px rgba(142, 231, 232, 0.75);
    --mk-comet-bloom: drop-shadow(0 0 4px rgba(142, 231, 232, 0.5));
}

/* Ground.Auto. Deliberately NOT the default: this app paints its own dark
   surfaces (the loader overlay, the dashboard) on machines set to light, so
   defaulting to the OS scheme would get those wrong. Auto is for components
   that genuinely sit on the page background. */
@media (prefers-color-scheme: dark) {
    .mk-comet--auto,
    .mk-comet-host--auto .mk-comet {
        --mk-comet-c1: #a8f2f3;
        --mk-comet-c2: #35a9b1;
        --mk-comet-c3: #11616e;
        --mk-comet-halo: rgba(142, 231, 232, 0.28);
        --mk-comet-halo-blur: 0 0 12px rgba(142, 231, 232, 0.75);
        --mk-comet-bloom: drop-shadow(0 0 4px rgba(142, 231, 232, 0.5));
    }

    .mk-comet-host--auto {
        color: #cdeff0;
    }

        .mk-comet-host--auto .mk-comet--value {
            --mk-comet-track-color: rgba(255, 255, 255, .16);
        }
}

/* ---- Sizes ---- */
.mk-comet--sm {
    --mk-comet-size: 1.4rem;
    --mk-comet-speed: 0.85s;
}

.mk-comet--lg {
    --mk-comet-size: 5rem;
}

/* At 1.4rem the head is 2.24px and the ring halo is wider than the dot it
   surrounds, which turns the head into a smudge. Tighten both. */
.mk-comet--sm::after {
    box-shadow: 0 0 0 1.5px var(--mk-comet-halo);
}

/* ---- Determinate ----------------------------------------------------
   No spin: the arc's length is the message, so rotating it as well would
   say two things at once. The track behind the arc is what stops a short
   arc reading as a fragment instead of "8% of the way round".
   The arc is a flat c2 rather than the comet ramp - a gradient along a
   progress arc makes the same percentage look different at different
   angles. */
.mk-comet--value {
    --mk-comet-pct: 0;
    animation: none;
}

    .mk-comet--value::before {
        background: conic-gradient( var(--mk-comet-c2) 0deg, var(--mk-comet-c2) calc(var(--mk-comet-pct) * 3.6deg), var(--mk-comet-track-color, #e1e7ea) calc(var(--mk-comet-pct) * 3.6deg), var(--mk-comet-track-color, #e1e7ea) 360deg );
        filter: none;
        transition: background .25s linear;
    }

    /* Head rides the end of the arc. The rotation lives on ::after alone, so
       it never collides with a positioning transform on the host. No bloom
       here: a determinate ring is a readout, not an animation. */
    .mk-comet--value::after {
        top: 50%;
        left: 50%;
        background: var(--mk-comet-c1);
        box-shadow: 0 0 0 2px var(--mk-comet-halo);
        transform: rotate(calc(var(--mk-comet-pct) * 3.6deg)) translateY(calc(var(--mk-comet-size) / -2 + var(--mk-comet-track) / 2)) translate(-50%, -50%);
        transform-origin: 0 0;
        transition: transform .25s linear;
    }

    /* At 0% there is no arc, so a head sitting at 12 o'clock would claim
       progress that has not happened. The component adds this class; the
       earlier [style*=...] sniff depended on an exact serialisation of the
       inline custom property and silently stopped matching. */
    .mk-comet--value.mk-comet--zero::after {
        opacity: 0;
    }

/* Motion is the whole message in indeterminate mode. Slow it rather than
   stopping it -- a frozen partial ring reads as a broken graphic. */
@media (prefers-reduced-motion: reduce) {
    .mk-comet {
        animation-duration: 3s;
    }

        .mk-comet::before {
            filter: none;
        }

        .mk-comet::after {
            box-shadow: 0 0 0 3px var(--mk-comet-halo);
        }

    .mk-comet--value::before,
    .mk-comet--value::after {
        transition: none;
    }
}

/* Host exists so the spin animation and any positioning transform never
   land on the same element. Column stack: comet, then the label under it. */
.mk-comet-host {
    display: inline-flex;
    flex-direction: column;
    align-items: center;
    gap: 0.65rem;
    line-height: 0; /* kills descender space under the inline comet */
}

/* The label restores its own line-height -- the host zeroes it for the
   comet's sake, which would otherwise collapse the text to nothing. */
.mk-comet-label {
    line-height: 1.35;
    font-size: 0.85rem;
    text-align: center;
    max-width: 22ch; /* wraps to a second line instead of stretching the host */
    text-wrap: balance;
}

/* On light grounds the host sets no colour at all, so the label inherits
   whatever the surrounding text uses -- always readable, nothing to keep in
   sync. On dark it needs ink of its own, plus a determinate track, which is
   a hole punched in the ground rather than part of the palette and so has
   to follow the surface it sits on. */
.mk-comet-host--on-dark {
    color: #cdeff0;
}

    .mk-comet-host--on-dark .mk-comet--value {
        --mk-comet-track-color: rgba(255, 255, 255, .16);
    }

.mk-comet-host--centered {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
}

/* The two dark surfaces this app already owns, so a comet dropped into
   either one is correct without the caller remembering the modifier. */
.ai-loader-wrapper .mk-comet,
.dashboard-background .mk-comet,
.makery-immersive-loader .mk-comet {
    --mk-comet-c1: #a8f2f3;
    --mk-comet-c2: #35a9b1;
    --mk-comet-c3: #11616e;
    --mk-comet-halo: rgba(142, 231, 232, 0.28);
    --mk-comet-halo-blur: 0 0 12px rgba(142, 231, 232, 0.75);
    --mk-comet-bloom: drop-shadow(0 0 4px rgba(142, 231, 232, 0.5));
}

.ai-loader-wrapper .mk-comet-host,
.makery-immersive-loader .mk-comet-host {
    color: #cdeff0;
}

/* =====================================================================
   DataCoverageStrip tokens
   Declared globally so the strip looks the same wherever it is used, not
   only inside .fsi-coverage. Only the "on" state carries a halo: a halo
   around grey is just a larger grey smudge.
   ===================================================================== */

.dcs {
    /* Data available -> green. Deep enough to read as a status colour beside
       the petrol UI rather than as a traffic light. */
    --dcs-on: #1a8f57;
    --dcs-on-halo: rgba(26, 143, 87, 0.14);
    /* No data -> a DARKER grey than the old #c7ced2, which dissolved into the
       soft header ground. This one holds its own weight, so an empty year
       reads as "nothing here" instead of "nothing rendered". */
    --dcs-off: #8b969d;
    --dcs-off-halo: transparent;
    --dcs-line: #e2e6ee;
    --dcs-faint: #eef1f4;
    --dcs-muted: #55627a;
    border-collapse: collapse;
    font-variant-numeric: tabular-nums;
}

    /* ---- Base strip geometry: the full-size variant carried tokens but no
       actual dot rules, so it fell back to whatever the page gave it. ---- */
    .dcs th,
    .dcs td {
        padding: 0.25rem 0.6rem;
        text-align: center;
        border: none;
    }

    .dcs th {
        font-size: 0.72rem;
        font-weight: 500;
        color: var(--dcs-muted);
    }

    .dcs .dcs__rowlabel {
        text-align: left;
        padding-left: 0;
        padding-right: 0.75rem;
        white-space: nowrap;
        color: var(--dcs-muted);
    }

    .dcs .dcs__dot {
        display: inline-block;
        width: 10px;
        height: 10px;
        border-radius: 50%;
        background: var(--dcs-off);
        transition: transform .12s ease, box-shadow .12s ease;
    }

    /* Data available */
    .dcs .dcs__mark.on .dcs__dot {
        background: var(--dcs-on);
        box-shadow: 0 0 0 3px var(--dcs-on-halo);
    }

    /* No data: filled darker grey, never red. Red says "this is wrong"; an
       empty year is not wrong, it is the reason the import exists. Filled
       keeps the exact size and optical weight of the "on" dot, so the
       difference is pure hue + value and survives greyscale printing and
       red-green colour blindness. */
    .dcs .dcs__mark.off .dcs__dot {
        background: var(--dcs-off);
        border: none;
        box-shadow: none;
        opacity: 1;
    }

    /* The plan divider is the one structural line worth keeping: it marks
       where actuals stop and planning begins. */
    .dcs th.is-first-plan,
    .dcs td.is-first-plan {
        border-left: 1px solid var(--dcs-line);
    }

    .dcs tbody tr:hover {
        background: var(--dcs-faint);
    }

/* Screen-reader-only state text rendered next to every dot. */
.dcs__sr {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    clip-path: inset(50%);
    white-space: nowrap;
}

@media (prefers-reduced-motion: reduce) {
    .dcs .dcs__dot {
        transition: none;
    }
}

.peer-status {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 5px;
    min-width: 88px;
    padding: 3px 9px;
    border: 1px solid transparent;
    border-radius: 999px;
    box-shadow: none;
    font-family: inherit;
    font-size: 12px;
    font-weight: 500;
    line-height: 18px;
    white-space: nowrap;
    cursor: pointer;
    transition: background-color 120ms ease, border-color 120ms ease;
}

.peer-status__icon {
    width: 14px;
    height: 14px;
    flex-shrink: 0;
}

.peer-status.is-included {
    color: #276749;
    background: #edf6f0;
    border-color: #d8eade;
}

    .peer-status.is-included:hover:not(:disabled) {
        background: #deeee3;
        border-color: #adcdb8;
    }

.peer-status.is-excluded {
    color: #626b76;
    background: #f3f4f6;
    border-color: #e2e5e9;
}

    .peer-status.is-excluded:hover:not(:disabled) {
        background: #e8ebef;
        border-color: #bdc4ce;
    }

.peer-status:focus-visible {
    outline: 2px solid #326eaa;
    outline-offset: 2px;
}

.peer-status:disabled {
    opacity: 0.55;
    cursor: not-allowed;
}

@media (prefers-reduced-motion: reduce) {
    .peer-status {
        transition: none;
    }
}

.peer-group-grid tr.peer-row-excluded > td.peer-name-cell,
.peer-group-grid tr.peer-row-excluded > td.peer-name-cell .rz-cell-data {
    color: #737b86;
}

.peer-group-grid tr.peer-row-excluded > td.peer-value-cell,
.peer-group-grid tr.peer-row-excluded > td.peer-value-cell span,
.peer-group-grid tr.peer-row-excluded > td.peer-value-cell input {
    color: #858c96 !important;
}

    .peer-group-grid tr.peer-row-excluded > td.peer-name-cell,
    .peer-group-grid tr.peer-row-excluded > td.peer-value-cell,
    .peer-group-grid tr.peer-row-excluded > td.peer-diagnostic-cell,
    .peer-group-grid tr.peer-row-excluded > td.peer-value-cell input {
        text-decoration-line: line-through;
        text-decoration-thickness: 1px;
    }

/* Replace the previous sense-check-specific rules in the global stylesheet.
   Shared peer-status styles used by other grids remain unchanged. */

.sense-check-grid .sense-check-status-wrap {
    position: relative;
    display: inline-block;
    width: 104px;
    max-width: 100%;
    vertical-align: middle;
}

.sense-check-grid select.sense-check-status {
    appearance: none;
    -webkit-appearance: none;
    box-sizing: border-box;
    display: block;
    width: 100%;
    height: 30px;
    margin: 0;
    padding: 0 30px 0 10px;
    border: 1px solid #d8dfe5;
    border-radius: 6px;
    background: #ffffff;
    background-image: none;
    box-shadow: none;
    color: #344958;
    font-family: inherit;
    font-size: 12px;
    font-weight: 500;
    line-height: normal;
    cursor: pointer;
    transition: border-color 120ms ease, background-color 120ms ease;
}

    .sense-check-grid select.sense-check-status.is-ignored {
        color: #737b86;
        border-color: #e2e6ea;
        background: #f8f9fa;
    }

    .sense-check-grid select.sense-check-status:hover:not(:disabled) {
        border-color: #a7b5c1;
        background: #f7f9fa;
    }

    .sense-check-grid select.sense-check-status:focus-visible {
        border-color: #62879d;
        outline: 2px solid #326eaa;
        outline-offset: 2px;
    }

    .sense-check-grid select.sense-check-status:disabled {
        opacity: 0.55;
        cursor: not-allowed;
    }

    .sense-check-grid select.sense-check-status option {
        background: #ffffff;
        color: #334155;
    }

.sense-check-grid .sense-check-status-chevron {
    position: absolute;
    top: 50%;
    right: 11px;
    box-sizing: border-box;
    width: 6px;
    height: 6px;
    margin-top: -4px;
    border-right: 1.5px solid #7c8a96;
    border-bottom: 1.5px solid #7c8a96;
    transform: rotate(45deg);
    pointer-events: none;
}

.sense-check-grid select.sense-check-status:hover:not(:disabled) + .sense-check-status-chevron,
.sense-check-grid select.sense-check-status:focus-visible + .sense-check-status-chevron {
    border-color: #455d6e;
}

.sense-check-grid .sense-check-comment-wrap {
    width: 100%;
    min-width: 0;
}

/* Specificity overrides the standard Radzen input frame in this grid only. */
.sense-check-grid input.sense-check-comment {
    box-sizing: border-box;
    width: 100%;
    min-width: 0;
    height: 32px;
    padding: 5px 8px;
    border: 1px solid #dfe4e9;
    border-radius: 4px;
    background: #fafbfc;
    box-shadow: none;
    color: #334155;
    font: inherit;
    line-height: 20px;
    text-align: left;
    transition: border-color 120ms ease, background-color 120ms ease;
}

    .sense-check-grid input.sense-check-comment::placeholder {
        color: #737b86;
        opacity: 1;
    }

    .sense-check-grid input.sense-check-comment:hover:not(:disabled):not(:focus) {
        border-color: #d7dee5;
        background: #fafbfc;
    }

    .sense-check-grid input.sense-check-comment:focus {
        border-color: #62879d;
        background: #ffffff;
        outline: 2px solid #dce9f0;
        outline-offset: 1px;
        box-shadow: none;
    }

    .sense-check-grid input.sense-check-comment:disabled {
        opacity: 0.55;
        cursor: not-allowed;
    }

@media (prefers-reduced-motion: reduce) {
    .sense-check-grid select.sense-check-status,
    .sense-check-grid input.sense-check-comment {
        transition: none;
    }
}

@media (forced-colors: active) {
    .sense-check-grid input.sense-check-comment,
    .sense-check-grid select.sense-check-status {
        border-color: ButtonText;
    }

    .sense-check-grid .sense-check-status-chevron {
        border-color: ButtonText;
    }

    .sense-check-grid select.sense-check-status:focus-visible,
    .sense-check-grid input.sense-check-comment:focus {
        outline-color: Highlight;
    }
}

.sense-check-grid .sense-check-priority {
    display: inline-flex;
    align-items: center;
    padding: 2px 8px;
    border: 1px solid;
    border-radius: 4px;
    font-size: 11px;
    font-weight: 500;
    line-height: 18px;
    white-space: nowrap;
}

.sense-check-grid .sense-check-step {
    display: inline;
    padding: 0;
    border: 0;
    background: transparent;
    color: #326783;
    font: inherit;
    text-align: left;
    white-space: normal;
    overflow-wrap: anywhere;
    cursor: pointer;
    text-underline-offset: 3px;
}

    .sense-check-grid .sense-check-step:hover {
        text-decoration: underline;
    }

    .sense-check-grid .sense-check-step:focus-visible {
        outline: 2px solid #326eaa;
        outline-offset: 3px;
        border-radius: 2px;
    }


/*
 * Shared alignment for Radzen numeric grids.
 * Add this stylesheet globally AFTER the Radzen theme (not in .razor.css).
 * Alternatively, append these rules to your existing global stylesheet.
 *
 * Usage:
 * - Wrapper: class="numeric-grid"
 * - Every numeric RadzenFormField: class="numeric-grid-field"
 * - Header RadzenFormField: class="numeric-grid-field numeric-grid-header"
 * - Every field's End template must contain:
 *     <span class="numeric-grid-field-end">optional reset button</span>
 *   Keep the span rendered even when the button is hidden.
 * - Keep ShowUpDown="false" for numeric inputs using this layout.
 * - Use identical column widths and column counts in headers and data rows.
 *
 * Override --numeric-grid-end-width and --numeric-grid-input-padding-end
 * on an individual wrapper if needed; both headers and values share them.
 */

.numeric-grid {
    --numeric-grid-end-width: 2.5rem;
    overflow-x: auto;
}

    .numeric-grid .numeric-grid-field {
        width: 100%;
        box-sizing: border-box;
    }

        .numeric-grid .numeric-grid-field .rz-numeric {
            display: block;
            width: 100%;
            min-width: 0;
        }

        .numeric-grid .numeric-grid-field .rz-numeric-input,
        .numeric-grid .numeric-grid-header .rz-textbox {
            text-align: right;
            box-sizing: border-box;
        }

    /* Same outlined form-field geometry as data cells, with invisible borders. */
    .numeric-grid .numeric-grid-header {
        --rz-input-background-color: transparent;
        --rz-input-border: 1px solid transparent;
        --rz-input-hover-border: 1px solid transparent;
        --rz-input-border-block-end: 1px solid transparent;
        --rz-input-hover-border-block-end: 1px solid transparent;
    }

        .numeric-grid .numeric-grid-header .rz-textbox {
            display: block;
            width: 100%;
            min-width: 0;
            font-weight: bold;
        }

    /* A persistent equal-width slot prevents reset buttons from shifting values. */
    .numeric-grid .numeric-grid-field-end {
        display: inline-flex;
        flex: 0 0 var(--numeric-grid-end-width);
        width: var(--numeric-grid-end-width);
        min-width: var(--numeric-grid-end-width);
        align-items: center;
        justify-content: center;
    }


/* ==========================================================================
   Shared component finish
   Keep selectors modest: component-specific rules and Radzen semantic state
   classes must win. No changes to popup positioning, dialog sizes or overflow.
   ========================================================================== */

/* Buttons: shape and type only. Filled, outlined, text, destructive and disabled
   treatments continue to come from Radzen and the component's ButtonStyle. */
.rz-button {
    border-radius: 6px;
    font-weight: 600;
    letter-spacing: normal;
}

    .rz-button .rz-button-text {
        letter-spacing: normal;
    }

    .rz-button.rz-button-md {
        min-height: 40px;
        font-size: 0.875rem;
    }

/* Preserve compact toolbars and dense grid editors, including inherited input
   heights. Explicit component dimensions and the valuation dialog still win. */
:where(.rz-density-compact) {
    --rz-input-height: 2rem;
}

/* Only Radzen form inputs: not native file inputs, switches or checkbox icons.
   No global border/background replacement that could erase validation states. */
:where(input.rz-textbox, input.rz-inputtext, input.rz-numeric-input, input.rz-datepicker-input, textarea.rz-textarea) {
    caret-color: currentColor;
}

/* Keyboard focus remains visible without changing error or selected colors.
   The light ring is intentional on the dark dashboard search field. */
:where(.rz-button, .rz-textbox, .rz-inputtext, .rz-textarea, .rz-dropdown, .rz-multiselect, .rz-numeric-input, .rz-datepicker-input, .rz-pager-element, .rz-dialog-titlebar-close):focus-visible,
:where(.rz-tabview-nav a, .rz-navigation-item-link):focus-visible {
    outline: 2px solid var(--mk-accent);
    outline-offset: -2px;
}

.modern-input.rz-textbox:focus-visible {
    outline-color: #b7e7e8;
}

/* Surface treatments: retain card padding, variants, dialog chrome and sizes.
   :where keeps specialized shells and immersive-loader overrides stronger. */
.rz-card.rz-variant-outlined {
    border-color: var(--mk-line);
}

.rz-dialog {
    border: 1px solid var(--mk-line);
    border-radius: 12px;
    box-shadow: 0 16px 48px rgba(20, 35, 45, 0.16);
}

.rz-dialog-titlebar {
    background-color: var(--mk-surface);
    color: var(--mk-ink);
}

.rz-dialog-title {
    font-weight: 650;
    letter-spacing: -0.02em;
}

/* Popup panels may be rendered outside their input's parent. These selectors
   intentionally style the panels, not their placement, height or stacking. */
.rz-dropdown-panel, .rz-multiselect-panel, .rz-autocomplete-panel {
    border: 1px solid var(--mk-line);
    border-radius: var(--mk-radius);
    box-shadow: var(--mk-popover-shadow);
}

/* Tabs stay legible without forcing all selected/disabled states to one color. */
.rz-tabview-nav {
    border-color: var(--mk-line);
}

    .rz-tabview-nav li a {
        font-weight: 600;
        letter-spacing: normal;
        text-transform: none;
    }

/* Subtle baseline details; semantic badge fills and cell annotations survive. */
.rz-badge {
    border-radius: 5px;
    font-weight: 600;
    letter-spacing: normal;
}

.rz-pager-element {
    border-radius: 6px;
}

/* Respect the existing dark dashboard and white navigation labels. Unify the
   action typography without turning the shell light or changing its spacing. */
.modern-btn-primary {
    text-transform: none;
    font-weight: 600;
    letter-spacing: normal;
    border-radius: 6px;
}

/* Align neutral surfaces in the import workflow, while preserving its separate
   AI, warning, conflict and unmapped color signals. */
.fsi-dialog {
    --fsi-navy: var(--mk-ink);
    --fsi-slate: var(--mk-muted);
    --fsi-line: var(--mk-line);
    --fsi-bg: var(--mk-surface);
    --fsi-bg-soft: var(--mk-surface-soft);
}

.imp-dash {
    --imp-navy: var(--mk-ink);
    --imp-slate: var(--mk-muted);
    --imp-line: var(--mk-line);
    --imp-bg: var(--mk-surface);
    --imp-bg-soft: var(--mk-surface-soft);
}

/* MAKERY alerts
   Append this entire block LAST in radzen-overrides.css, after older alert rules.
   No Razor changes. Only outlined alerts are affected.
   Dark surfaces: existing .rz-body and .dashboard-background.
   Light surfaces: existing Radzen cards/dialogs/panels and valuation shells.
   Custom surfaces can set the --notice-* variables locally if needed.
*/

:root,
:where(.rz-card, .rz-dialog, .rz-panel, .val-dialog, .valuation-explorer, .fsi-dialog) {
    --notice-text: #465264;
    --notice-title: #253241;
    --notice-info: #116471;
    --notice-info-bg: #f5f8f9;
    --notice-warning: #905411;
    --notice-warning-bg: #fff7eb;
    --notice-danger: #a93650;
    --notice-danger-bg: #fff1f4;
    --notice-success: #276d47;
    --notice-success-bg: #eff7f2;
    --notice-focus: #116471;
}

/* These tokens inherit through rows/columns, then reset at a light surface. */
:where(.rz-body, .dashboard-background) {
    --notice-text: #bdcdd1;
    --notice-title: #edf4f5;
    --notice-info: #87bfc8;
    --notice-info-bg: rgba(255, 255, 255, 0.025);
    --notice-warning: #f2c078;
    --notice-warning-bg: rgba(242, 178, 84, 0.085);
    --notice-danger: #ffafbe;
    --notice-danger-bg: rgba(214, 88, 117, 0.12);
    --notice-success: #9cd6b0;
    --notice-success-bg: rgba(104, 177, 131, 0.08);
    --notice-focus: #9dd9e0;
}

/* Additional specificity intentionally beats the earlier alert experiments.
   Important declarations are limited to their previous important overrides. */
.rz-alert.rz-variant-outlined[class] {
    --notice-accent: var(--notice-info);
    --notice-background: var(--notice-info-bg);
    width: 100%;
    max-width: 100%;
    min-width: 0;
    box-sizing: border-box;
    margin: 4px 0;
    padding: 9px 12px;
    gap: 10px;
    align-items: flex-start;
    background: var(--notice-background) !important;
    color: var(--notice-text) !important;
    border: 0 !important;
    border-radius: 6px !important;
    box-shadow: none !important;
    font-family: inherit;
    font-size: 0.875rem;
    font-weight: 400;
    line-height: 1.55;
}

.rz-alert.rz-variant-outlined.rz-warning[class] {
    --notice-accent: var(--notice-warning);
    --notice-background: var(--notice-warning-bg);
}

.rz-alert.rz-variant-outlined.rz-danger[class] {
    --notice-accent: var(--notice-danger);
    --notice-background: var(--notice-danger-bg);
}

.rz-alert.rz-variant-outlined.rz-success[class] {
    --notice-accent: var(--notice-success);
    --notice-background: var(--notice-success-bg);
}

.rz-alert.rz-variant-outlined[class] .rz-alert-item {
    flex: 1 1 auto;
    min-width: 0;
    align-items: flex-start;
    gap: 10px;
}

.rz-alert.rz-variant-outlined[class] .rz-alert-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 20px;
    width: 20px;
    height: 20px;
    margin: 0;
    padding: 0;
    background: transparent !important;
    color: var(--notice-accent) !important;
    border: 0;
    border-radius: 0;
    font-size: 18px;
    line-height: 20px;
}

.rz-alert.rz-variant-outlined[class] .rz-alert-message {
    flex: 1 1 auto;
    min-width: 0;
    margin: 0;
    color: inherit;
    line-height: inherit;
    overflow-wrap: anywhere;
}

.rz-alert.rz-variant-outlined[class] .rz-alert-title {
    margin: 0 0 2px;
    color: var(--notice-title);
    font-size: inherit;
    font-weight: 600;
    line-height: inherit;
    letter-spacing: normal;
}

.rz-alert.rz-variant-outlined[class] strong {
    color: var(--notice-title);
    font-weight: 600;
}

.rz-alert.rz-variant-outlined[class] a:not(.rz-button) {
    color: var(--notice-title);
    text-decoration: underline;
    text-underline-offset: 3px;
}

.rz-alert.rz-variant-outlined[class] .rz-button.rz-variant-text {
    align-self: flex-start;
    color: var(--notice-text);
}

.rz-alert.rz-variant-outlined[class] :is(button, a):focus-visible {
    outline: 2px solid var(--notice-focus);
    outline-offset: 2px;
}

.rz-notification .rz-notification-item-wrapper,
.rz-notification .rz-notification-item {
    border-radius: 8px !important;
    overflow: hidden;
}

/* Hide the primary-action half. */
.ellipsis-menu > button:first-of-type {
    display: none;
}

/* Make the remaining dropdown toggle a standalone button. */
.ellipsis-menu > button:last-of-type {
    border-radius: var(--rz-border-radius, 4px);
    border-inline-start: 0;
}

/* Allow this dialog's content to use its available height. */
.planning-data-dialog .rz-dialog-content {
    display: flex;
    flex-direction: column;
    flex: 1 1 auto;
    min-height: 0;
}

/* Stretch the viewer and card to fill the dialog content. */
.planning-data-dialog .excel-data-container {
    display: flex;
    flex-direction: column;
    flex: 1 0 auto;
    min-width: 0;
    box-sizing: border-box;
}

.planning-data-dialog .cool-dashboard-card {
    display: flex;
    flex-direction: column;
    flex: 1 0 auto;
    min-width: 0;
}

.planning-data-dialog .data-viewer-layout {
    flex: 1 0 auto;
    min-width: 0;
}

/* Center within the remaining space below the header. */
.planning-data-dialog .data-viewer-loading {
    display: flex;
    align-items: center;
    justify-content: center;
    flex: 1 0 auto;
    min-height: 200px;
}

.transaction-row-actions {
    display: flex;
    flex-wrap: nowrap;
    align-items: center;
    justify-content: flex-end;
    gap: 4px;
    min-height: 36px;
}
