/* /Components/Layout/AuthLayout.razor.rz.scp.css */
.auth-page[b-s0g87za91x] {
    min-height: 100vh;
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--bg-body);
    padding: 1rem;
}

.auth-card[b-s0g87za91x] {
    width: 100%;
    max-width: 380px;
    background: var(--bg-card);
    border: 1px solid var(--border-color);
    border-radius: var(--border-radius);
    box-shadow: var(--shadow-md);
    padding: 2rem;
}

.auth-brand[b-s0g87za91x] {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.6rem;
    font-size: 1.7rem;
    font-weight: 700;
    color: var(--accent);
    text-align: center;
    margin-bottom: 1.25rem;
    letter-spacing: -0.5px;
}

.auth-logo[b-s0g87za91x] {
    width: 40px;
    height: 40px;
    border-radius: 8px;
    box-shadow: var(--shadow-md);
}
/* /Components/Layout/DevUserSwitcher.razor.rz.scp.css */
/* Sits at the foot of the user menu's dropdown. */
.dev-switch[b-a7uxm970lq] {
    padding: 0.35rem 0.6rem 0.5rem;
}

.dev-switch-label[b-a7uxm970lq] {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    font-size: 0.72rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--text-muted);
    margin-bottom: 0.35rem;
}

.dev-switch-label .badge[b-a7uxm970lq] {
    font-size: 0.6rem;
}

.dev-switch[b-a7uxm970lq]  .form-select,
.dev-switch .form-select[b-a7uxm970lq] {
    width: 100%;
    font-size: 0.82rem;
}
/* /Components/Layout/MainLayout.razor.rz.scp.css */
.page[b-zv0afgso55] {
    position: relative;
    display: flex;
    flex-direction: column;
}

main[b-zv0afgso55] {
    flex: 1;
    /* Without this a wide grid (e.g. the projection overview) stretches the flex item and the
       whole page scrolls sideways; min-width:0 lets it shrink so the grid scrolls inside its own
       overflow container instead. */
    min-width: 0;
}

/* No border, no shadow, and the same colour as the canvas: the menu shares the page's paper
   rather than sitting on a slab of its own. Whitespace is what separates them. */
.sidebar[b-zv0afgso55] {
    background-color: var(--bg-sidebar);
    border-right: none;
    box-shadow: none;
    position: relative;
}

/* Utility chrome, not a header band — it sits on the canvas with no fill and no rule. */
.top-row[b-zv0afgso55] {
    background-color: transparent;
    border-bottom: none;
    justify-content: flex-end;
    height: 3.5rem;
    display: flex;
    align-items: center;
}

    /* Utility links, not calls to action. */
    .top-row[b-zv0afgso55]  a, .top-row[b-zv0afgso55]  .btn-link {
        white-space: nowrap;
        text-decoration: none;
    }

    .top-row[b-zv0afgso55]  a:hover, .top-row[b-zv0afgso55]  .btn-link:hover {
        text-decoration: none;
    }

    .top-row[b-zv0afgso55]  a:first-child {
        overflow: hidden;
        text-overflow: ellipsis;
    }

@media (max-width: 640.98px) {
    .top-row[b-zv0afgso55] {
        justify-content: space-between;
    }
}

@media (min-width: 641px) {
    .page[b-zv0afgso55] {
        flex-direction: row;
    }

    .sidebar[b-zv0afgso55] {
        width: 250px;
        height: 100vh;
        position: sticky;
        top: 0;
    }

    .top-row[b-zv0afgso55] {
        position: sticky;
        top: 0;
        /* Sticky makes this a stacking context, so the user menu's own z-index counts only
           inside it — this value is what the whole header, dropdown included, is worth
           against page content. It has to clear anything a page positions. */
        z-index: 1030;
        /* The row carries no fill, so page content would scroll visibly under it. Frost it
           rather than filling it: the canvas still shows through, the text underneath does not. */
        backdrop-filter: blur(8px);
        background-color: color-mix(in srgb, var(--bg-body) 82%, transparent);
    }

    .top-row.auth[b-zv0afgso55]  a:first-child {
        flex: 1;
        text-align: right;
        width: 0;
    }

    .top-row[b-zv0afgso55], article[b-zv0afgso55] {
        padding-left: 2rem !important;
        padding-right: 1.5rem !important;
    }
}

/* ═══════════════════════════════════════════════════════════
   Horizontal menu mode (data-nav="horizontal" on <html>)

   The sidebar becomes a full-width bar above the content. Only above 992px —
   below that there is not enough width for the items, so it falls back to the
   sidebar and the toggle that sets this mode is hidden.
   ═══════════════════════════════════════════════════════════ */
@media (min-width: 992px) {
    [data-nav="horizontal"] .page[b-zv0afgso55] {
        flex-direction: column;
    }

    /* Height is auto so an open submenu panel grows the bar and pushes the page down, rather
       than covering the top of the content. */
    [data-nav="horizontal"] .sidebar[b-zv0afgso55] {
        width: 100% !important;
        height: auto;
        min-height: 3.5rem;
        position: sticky;
        top: 0;
        z-index: 1031;
        display: flex;
        align-items: flex-start;
        /* Opaque, and exactly the page's own colour, so content scrolls cleanly under it. The
           bar looked white against the dashboard because the warm wash was painting *below* it
           and stopped at its edge; the wash is lifted over the bar instead (Home.razor.css), so
           the glow runs across the chrome and the page as one surface. */
        background-color: var(--bg-body);
    }

    /* Collapsing means nothing on a bar. */
    [data-nav="horizontal"] .sidebar-toggle-btn[b-zv0afgso55] {
        display: none;
    }

    /* The utility row sits on the menu bar, so the chrome stays one row tall instead of two. It
       is pinned to the top-right rather than offset by a fixed amount, because the bar's height
       now varies with whether a submenu panel is open. The row is click-through except for its
       own controls, so it never swallows a click meant for the menu beneath it. */
    [data-nav="horizontal"] main > .top-row[b-zv0afgso55] {
        position: fixed;
        top: 0;
        right: 0;
        height: 3.5rem;
        width: auto;
        z-index: 1032;
        pointer-events: none;
        backdrop-filter: none;
        background-color: transparent;
    }

    /* ::deep, not a plain child selector: the user menu is its own component and carries its own
       scope id, so a scoped `> *` rule would skip it and leave it click-through — the two buttons
       here would work and the user chip would not. */
    [data-nav="horizontal"] main > .top-row[b-zv0afgso55]  > * {
        pointer-events: auto;
    }
}

/* ── Collapse control ──
   A ring on the sidebar's edge near the bottom, out of the way of the menu itself. The chevron
   points at what the click does: inwards to collapse, outwards once collapsed. */
.sidebar-toggle-btn[b-zv0afgso55] {
    position: absolute;
    bottom: 72px;
    right: -12px;
    width: 24px;
    height: 24px;
    padding: 0;
    border-radius: 50%;
    background: var(--bg-card);
    border: 1px solid var(--border-color);
    box-shadow: var(--shadow-sm);
    display: none;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    color: var(--text-secondary);
    transition: color 0.2s ease, border-color 0.2s ease, background 0.2s ease;
    z-index: 10;
}

.sidebar-toggle-btn:hover[b-zv0afgso55] {
    color: var(--accent);
    border-color: var(--accent);
    background: var(--accent-light);
}

.sidebar-toggle-btn svg[b-zv0afgso55] {
    width: 14px;
    height: 14px;
    transition: transform 0.15s ease;
}

/* Plain selector, not :global() — that is CSS Modules syntax, which Blazor passes through
   untouched and the browser then drops. Scoped CSS puts its marker on the last element, and the
   svg is ours, so an ancestor selector on <html> works as written. */
html.nav-collapsed .sidebar-toggle-btn svg[b-zv0afgso55] {
    transform: rotate(180deg);
}

/* Only where there is a sidebar to collapse. */
@media (min-width: 641px) {
    .sidebar-toggle-btn[b-zv0afgso55] {
        display: flex;
    }
}

#blazor-error-ui[b-zv0afgso55] {
    background: var(--bg-card);
    color: var(--danger);
    border-top: 3px solid var(--danger);
    border-radius: 12px 12px 0 0;
    bottom: 0;
    box-shadow: 0 -4px 12px rgba(0, 0, 0, 0.1);
    box-sizing: border-box;
    display: none;
    left: 0;
    padding: 0.6rem 1.25rem 0.7rem 1.25rem;
    position: fixed;
    width: 100%;
    z-index: 1000;
}

    #blazor-error-ui .dismiss[b-zv0afgso55] {
        cursor: pointer;
        position: absolute;
        right: 0.75rem;
        top: 0.5rem;
        color: var(--text-secondary);
    }
/* /Components/Layout/NavMenu.razor.rz.scp.css */
/* Harvested from Trophyst's NavMenu, adapted to Promora's menu, which differs in two ways: the
   groups are CSS-only (a hidden checkbox per group drives its submenu, because the menu renders
   as static SSR) and there is a third level — Master Data → Customers / Products / Misc. */

.navbar-toggler[b-hq257zinvk] {
    appearance: none;
    cursor: pointer;
    width: 3.5rem;
    height: 2.5rem;
    color: var(--text-primary);
    position: absolute;
    top: 0.5rem;
    right: 1rem;
    border: 1px solid var(--border-color);
    border-radius: var(--border-radius-sm);
    background: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%286, 102, 241, 1%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e") no-repeat center/1.75rem var(--bg-card);
}

.navbar-toggler:checked[b-hq257zinvk] {
    background-color: var(--accent-light);
}

.top-row[b-hq257zinvk] {
    min-height: 3.5rem;
    height: 3.5rem;
    background-color: var(--bg-sidebar);
    border-bottom: none;
}

/* Wordmark: display face, uppercase and letter-spaced so it reads as a logotype rather than as
   a page heading. */
.navbar-brand[b-hq257zinvk] {
    font-family: var(--font-display);
    font-size: 1.02rem;
    color: var(--text-strong) !important;
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: 0.07em;
}

/* The mark carries its own colour and has a transparent centre, so it stands on the canvas rather
   than inside the filled square the letter P used to need — on that square it would have been
   blue on blue with the accent showing through its middle. */
.brand-mark[b-hq257zinvk] {
    width: 30px;
    height: 30px;
    flex-shrink: 0;
    object-fit: contain;
}

.nav-item[b-hq257zinvk] {
    font-size: 0.9rem;
    padding-bottom: 0.25rem;
}

    .nav-item:first-of-type[b-hq257zinvk] {
        padding-top: 1rem;
    }

/* Inline SVG icons (declared in NavMenu markup, so scoped without ::deep). */
.nav-icon[b-hq257zinvk] {
    width: 18px;
    height: 18px;
    margin-right: 14px;
    flex-shrink: 0;
}

/* Top-level icons sit in a hairline rounded square. A small detail, but a large part of why the
   reference design reads as considered rather than as a default icon-plus-label list. Deeper
   levels stay bare, so the hierarchy is still obvious at a glance. */
nav > .nav-item[b-hq257zinvk] >  .nav-link > .nav-icon,
nav > .nav-group > .nav-item > .nav-link > .nav-icon[b-hq257zinvk] {
    width: 30px;
    height: 30px;
    padding: 5px;
    margin-right: 12px;
    border: 1px solid var(--border-color);
    border-radius: var(--border-radius-sm);
    background: var(--bg-card);
    box-sizing: border-box;
    transition: border-color 0.18s ease, background 0.18s ease, color 0.18s ease;
}

/* NavLink renders its own <a> (needs ::deep); our group-toggle <label> is in-scope. */
.nav-item[b-hq257zinvk]  .nav-link,
.nav-item .nav-link[b-hq257zinvk] {
    color: var(--text-secondary);
    background: none;
    border: none;
    border-radius: 10px;
    height: 2.75rem;
    display: flex;
    align-items: center;
    width: 100%;
    padding: 0 12px;
    text-align: left;
    font-weight: 500;
    cursor: pointer;
    transition: all 0.2s ease;
}

/* Active item: the accent carries it as colour and weight, not as a filled block. The icon's
   square inverts to solid accent so the eye finds it fast. */
.nav-item[b-hq257zinvk]  a.active {
    background: transparent;
    color: var(--accent);
    font-weight: 600;
}

nav > .nav-item[b-hq257zinvk] >  a.active > .nav-icon {
    background: var(--accent);
    border-color: var(--accent);
    color: var(--text-on-accent);
}

.nav-item[b-hq257zinvk]  .nav-link:hover,
.nav-item .nav-link:hover[b-hq257zinvk] {
    background-color: var(--nav-hover-bg);
    color: var(--text-primary);
}

nav > .nav-item[b-hq257zinvk] >  .nav-link:hover > .nav-icon,
nav > .nav-group > .nav-item > .nav-link:hover > .nav-icon[b-hq257zinvk] {
    border-color: color-mix(in srgb, var(--accent) 45%, var(--border-color));
}

.nav-group-toggle[b-hq257zinvk] {
    user-select: none;
}

.nav-caret[b-hq257zinvk] {
    width: 0.85rem;
    height: 0.85rem;
    margin-left: auto;
    margin-right: 0;
    transition: transform 0.2s ease;
}

/* CSS-only collapse: a hidden checkbox toggled by the label drives the submenu and the caret. */
.nav-group-checkbox[b-hq257zinvk] {
    display: none;
}

.nav-submenu[b-hq257zinvk] {
    display: none;
}

.nav-group-checkbox:checked ~ .nav-submenu[b-hq257zinvk] {
    display: block;
}

.nav-group-checkbox:checked ~ .nav-item .nav-caret[b-hq257zinvk] {
    transform: rotate(180deg);
}

/* ── Second level ── */
.nav-submenu[b-hq257zinvk] {
    background-color: var(--bg-subtle);
    border-radius: var(--border-radius-sm);
    margin: 0 0.75rem 0.5rem 0.75rem;
    padding: 0.25rem 0;
}

.nav-submenu .nav-item[b-hq257zinvk] {
    padding-bottom: 0.125rem;
}

    .nav-submenu .nav-item:first-of-type[b-hq257zinvk] {
        padding-top: 0.25rem;
    }

.nav-submenu[b-hq257zinvk]  .nav-link,
.nav-submenu .nav-link[b-hq257zinvk] {
    height: 2.4rem;
    padding-left: 1.25rem;
    font-size: 0.85rem;
}

.nav-submenu .nav-icon[b-hq257zinvk] {
    width: 16px;
    height: 16px;
    margin-right: 12px;
}

/* ── Third level: sub-groups (Master Data → Customers / Products / Misc) ── */
.nav-subsubmenu[b-hq257zinvk] {
    background: none;
    margin: 0;
    padding: 0;
}

.nav-subsubmenu[b-hq257zinvk]  .nav-link {
    padding-left: 2.4rem;
    height: 2.2rem;
    font-size: 0.82rem;
}

.nav-scrollable[b-hq257zinvk] {
    display: none;
    background-color: var(--bg-sidebar);
    position: relative;
}

.navbar-toggler:checked ~ .nav-scrollable[b-hq257zinvk] {
    display: block;
}

@media (min-width: 641px) {
    .navbar-toggler[b-hq257zinvk] {
        display: none;
    }

    .nav-scrollable[b-hq257zinvk] {
        /* Flex column so the version footer pins to the bottom: the nav scrolls, the footer stays. */
        display: flex;
        flex-direction: column;
        height: calc(100vh - 3.5rem);
    }

    .nav-scrollable > nav[b-hq257zinvk] {
        flex: 1;
        overflow-y: auto;
        /* Bootstrap's .nav is flex-wrap: wrap — with the constrained height that wraps
           overflowing items into a second column beside the menu. Scroll instead. */
        flex-wrap: nowrap;
    }
}

.version-footer[b-hq257zinvk] {
    padding-top: 0.75rem;
    padding-bottom: 0.75rem;
    border-top: 1px solid var(--border-color);
    background-color: var(--bg-sidebar);
    flex-shrink: 0;
}

.version-link[b-hq257zinvk] {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    color: var(--text-muted);
    font-size: 0.8rem;
    text-decoration: none;
    transition: color 0.2s ease;
}

.version-link:hover[b-hq257zinvk] {
    color: var(--accent);
}

.version-link .nav-icon[b-hq257zinvk] {
    width: 14px;
    height: 14px;
    margin-right: 0;
}

/* ═══════════════════════════════════════════════════════════
   Horizontal menu mode (data-nav="horizontal" on <html>)

   Same markup, laid out as a top bar. Submenus become a full-width panel under
   the bar rather than a dropdown: the groups here are large — Master Data alone
   has three sections — and a panel lets them keep their sections and read in
   columns. Only above 992px; below that the items do not fit and the mode falls
   back to the sidebar.
   ═══════════════════════════════════════════════════════════ */
@media (min-width: 992px) {
    /* Brand sits at the left of the bar. */
    [data-nav="horizontal"] .top-row[b-hq257zinvk] {
        height: auto;
        min-height: 0;
        border-bottom: none;
        padding-right: 0.5rem;
        flex-shrink: 0;
        width: auto;
    }

    [data-nav="horizontal"] .top-row .container-fluid[b-hq257zinvk] {
        width: auto;
        padding-right: 0;
    }

    [data-nav="horizontal"] .nav-scrollable[b-hq257zinvk] {
        display: flex !important;
        flex-direction: row;
        align-items: flex-start;
        height: auto;
        min-height: 3.5rem;
        flex: 1;
        min-width: 0;
        position: static;
        /* Keep clear of the fixed top-right controls, which are out of flow and would otherwise
           be overlapped by the items as the window narrows. The width is measured and published
           by js/app.js; the fallback covers the moment before that runs. */
        padding-right: calc(var(--nav-utility-width, 20rem) + 1rem);
    }

    /* The markup carries Bootstrap's .flex-column, which only sets flex-direction — the element
       is display:block and relies on the sidebar being a column. Making it an actual flex row is
       what turns the list into a bar. Overflow stays visible so a panel can escape. */
    [data-nav="horizontal"] .nav-scrollable > nav[b-hq257zinvk] {
        display: flex;
        flex-direction: row !important;
        align-items: center;
        align-content: flex-start;
        flex-wrap: wrap;
        overflow: visible;
        min-width: 0;
    }

    /* A group is a wrapper div around its toggle and its panel. The wrapper has to sit in the bar
       as an ordinary item while its panel takes a full-width line of its own — so the wrapper is
       display:contents and its two children are laid out by the bar directly. */
    [data-nav="horizontal"] .nav-scrollable > nav > .nav-group[b-hq257zinvk] {
        display: contents;
    }

    [data-nav="horizontal"] .nav-scrollable > nav > .nav-item[b-hq257zinvk],
    [data-nav="horizontal"] .nav-scrollable > nav > .nav-group > .nav-item[b-hq257zinvk] {
        order: 0;
        height: 3.5rem;
        display: flex;
        align-items: center;
        padding: 0 1px !important;
    }

    [data-nav="horizontal"] .nav-item[b-hq257zinvk]  .nav-link,
    [data-nav="horizontal"] .nav-item .nav-link[b-hq257zinvk] {
        height: 2.4rem;
        line-height: 1;
        padding: 0 0.7rem;
        white-space: nowrap;
        border-radius: var(--border-radius-sm);
    }

    /* The boxed icons are a sidebar detail — at bar scale they crowd the row, so icons go back
       to bare glyphs here. */
    [data-nav="horizontal"] nav > .nav-item[b-hq257zinvk] >  .nav-link > .nav-icon,
    [data-nav="horizontal"] nav > .nav-group > .nav-item > .nav-link > .nav-icon[b-hq257zinvk] {
        width: 17px;
        height: 17px;
        padding: 0;
        margin-right: 8px;
        border: none;
        background: none;
        border-radius: 0;
    }

    [data-nav="horizontal"] nav > .nav-item[b-hq257zinvk] >  a.active > .nav-icon {
        background: none;
        color: var(--accent);
    }

    /* Active item is marked by an underline on the bar. */
    [data-nav="horizontal"] .nav-item[b-hq257zinvk]  a.active {
        position: relative;
    }

    [data-nav="horizontal"] .nav-item[b-hq257zinvk]  a.active::after {
        content: '';
        position: absolute;
        left: 0.7rem;
        right: 0.7rem;
        bottom: -0.55rem;
        height: 2px;
        border-radius: 2px;
        background: var(--accent);
    }

    [data-nav="horizontal"] .nav-caret[b-hq257zinvk] {
        margin-left: 4px;
    }

    /* Submenu → panel on its own line below the items. In flow, not absolute, so it pushes the
       page down instead of covering the top of it. */
    [data-nav="horizontal"] .nav-group > .nav-group-checkbox:checked ~ .nav-submenu[b-hq257zinvk] {
        order: 99;
        flex: 0 0 100%;
        margin: 0 0 0.65rem;
        padding: 1rem 1.25rem 1.1rem;
        display: grid;
        /* Fixed-width columns packed to the left rather than stretched across the viewport — on a
           wide screen a stretched grid puts 170px of empty space between an icon and its
           neighbour and is hard to scan. */
        grid-template-columns: repeat(auto-fill, 220px);
        justify-content: start;
        gap: 0 0.75rem;
        align-content: start;
        background: var(--bg-card);
        border: 1px solid var(--border-color);
        border-radius: var(--border-radius);
        box-shadow: var(--shadow-sm);
    }

    [data-nav="horizontal"] .nav-submenu[b-hq257zinvk]  .nav-link {
        padding-left: 0.6rem;
        height: 2.2rem;
    }

    /* A sub-group inside a panel becomes a section heading spanning the whole grid, with its
       items always visible underneath — collapsing a third level inside an already-open panel is
       one click too many, and the sections are what make a wide panel readable. */
    [data-nav="horizontal"] .nav-submenu .nav-subgroup[b-hq257zinvk] {
        display: contents;
    }

    [data-nav="horizontal"] .nav-submenu .nav-subgroup > .nav-item[b-hq257zinvk] {
        grid-column: 1 / -1;
        padding: 0 !important;
        margin-top: 0.5rem;
        border-top: 1px solid var(--border-subtle);
    }

    [data-nav="horizontal"] .nav-submenu .nav-subgroup:first-child > .nav-item[b-hq257zinvk] {
        margin-top: 0;
        border-top: none;
    }

    [data-nav="horizontal"] .nav-submenu .nav-subgroup-toggle[b-hq257zinvk] {
        font-size: 0.7rem;
        font-weight: 600;
        text-transform: uppercase;
        letter-spacing: 0.05em;
        color: var(--text-muted);
        height: auto;
        padding: 0.7rem 0.6rem 0.3rem;
        pointer-events: none;
    }

    [data-nav="horizontal"] .nav-submenu .nav-subgroup-toggle .nav-icon[b-hq257zinvk],
    [data-nav="horizontal"] .nav-submenu .nav-subgroup-toggle .nav-caret[b-hq257zinvk] {
        display: none;
    }

    /* Third-level items are laid out by the panel's own grid, so the sub-menu wrapper steps out
       of the way and its items are always shown. The panel rule above is scoped to .nav-group's
       own child, so it never catches this one. */
    [data-nav="horizontal"] .nav-subsubmenu[b-hq257zinvk] {
        display: contents;
    }

    /* The sidebar footer has no place on a bar; the version link is reachable from /changelog. */
    [data-nav="horizontal"] .version-footer[b-hq257zinvk] {
        display: none;
    }
}
/* /Components/Layout/ReconnectModal.razor.rz.scp.css */
.components-reconnect-first-attempt-visible[b-kcsie6nky2],
.components-reconnect-repeated-attempt-visible[b-kcsie6nky2],
.components-reconnect-failed-visible[b-kcsie6nky2],
.components-pause-visible[b-kcsie6nky2],
.components-resume-failed-visible[b-kcsie6nky2],
.components-rejoining-animation[b-kcsie6nky2] {
    display: none;
}

#components-reconnect-modal.components-reconnect-show .components-reconnect-first-attempt-visible[b-kcsie6nky2],
#components-reconnect-modal.components-reconnect-show .components-rejoining-animation[b-kcsie6nky2],
#components-reconnect-modal.components-reconnect-paused .components-pause-visible[b-kcsie6nky2],
#components-reconnect-modal.components-reconnect-resume-failed .components-resume-failed-visible[b-kcsie6nky2],
#components-reconnect-modal.components-reconnect-retrying[b-kcsie6nky2],
#components-reconnect-modal.components-reconnect-retrying .components-reconnect-repeated-attempt-visible[b-kcsie6nky2],
#components-reconnect-modal.components-reconnect-retrying .components-rejoining-animation[b-kcsie6nky2],
#components-reconnect-modal.components-reconnect-failed[b-kcsie6nky2],
#components-reconnect-modal.components-reconnect-failed .components-reconnect-failed-visible[b-kcsie6nky2] {
    display: block;
}


#components-reconnect-modal[b-kcsie6nky2] {
    background-color: white;
    width: 20rem;
    margin: 20vh auto;
    padding: 2rem;
    border: 0;
    border-radius: 0.5rem;
    box-shadow: 0 3px 6px 2px rgba(0, 0, 0, 0.3);
    opacity: 0;
    transition: display 0.5s allow-discrete, overlay 0.5s allow-discrete;
    animation: components-reconnect-modal-fadeOutOpacity-b-kcsie6nky2 0.5s both;
    &[open]

{
    animation: components-reconnect-modal-slideUp-b-kcsie6nky2 1.5s cubic-bezier(.05, .89, .25, 1.02) 0.3s, components-reconnect-modal-fadeInOpacity-b-kcsie6nky2 0.5s ease-in-out 0.3s;
    animation-fill-mode: both;
}

}

#components-reconnect-modal[b-kcsie6nky2]::backdrop {
    background-color: rgba(0, 0, 0, 0.4);
    animation: components-reconnect-modal-fadeInOpacity-b-kcsie6nky2 0.5s ease-in-out;
    opacity: 1;
}

@keyframes components-reconnect-modal-slideUp-b-kcsie6nky2 {
    0% {
        transform: translateY(30px) scale(0.95);
    }

    100% {
        transform: translateY(0);
    }
}

@keyframes components-reconnect-modal-fadeInOpacity-b-kcsie6nky2 {
    0% {
        opacity: 0;
    }

    100% {
        opacity: 1;
    }
}

@keyframes components-reconnect-modal-fadeOutOpacity-b-kcsie6nky2 {
    0% {
        opacity: 1;
    }

    100% {
        opacity: 0;
    }
}

.components-reconnect-container[b-kcsie6nky2] {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 1rem;
}

#components-reconnect-modal p[b-kcsie6nky2] {
    margin: 0;
    text-align: center;
}

#components-reconnect-modal button[b-kcsie6nky2] {
    border: 0;
    background-color: #6b9ed2;
    color: white;
    padding: 4px 24px;
    border-radius: 4px;
}

    #components-reconnect-modal button:hover[b-kcsie6nky2] {
        background-color: #3b6ea2;
    }

    #components-reconnect-modal button:active[b-kcsie6nky2] {
        background-color: #6b9ed2;
    }

.components-rejoining-animation[b-kcsie6nky2] {
    position: relative;
    width: 80px;
    height: 80px;
}

    .components-rejoining-animation div[b-kcsie6nky2] {
        position: absolute;
        border: 3px solid #0087ff;
        opacity: 1;
        border-radius: 50%;
        animation: components-rejoining-animation-b-kcsie6nky2 1.5s cubic-bezier(0, 0.2, 0.8, 1) infinite;
    }

        .components-rejoining-animation div:nth-child(2)[b-kcsie6nky2] {
            animation-delay: -0.5s;
        }

@keyframes components-rejoining-animation-b-kcsie6nky2 {
    0% {
        top: 40px;
        left: 40px;
        width: 0;
        height: 0;
        opacity: 0;
    }

    4.9% {
        top: 40px;
        left: 40px;
        width: 0;
        height: 0;
        opacity: 0;
    }

    5% {
        top: 40px;
        left: 40px;
        width: 0;
        height: 0;
        opacity: 1;
    }

    100% {
        top: 0px;
        left: 0px;
        width: 80px;
        height: 80px;
        opacity: 0;
    }
}
/* /Components/Layout/SignLayout.razor.rz.scp.css */
.sign-page[b-3a0ct16ol2] {
    min-height: 100vh;
    background: var(--bg-body, #f5f7fa);
    padding: 32px 16px;
    display: flex;
    justify-content: center;
    align-items: flex-start;
}

.sign-card[b-3a0ct16ol2] {
    width: 100%;
    max-width: 960px;
    background: var(--bg-card, #fff);
    border: 1px solid var(--border-color, #e5e7eb);
    border-radius: 14px;
    padding: 28px 32px;
    box-shadow: 0 2px 8px rgba(0, 0, 0, .06);
}

.sign-brand[b-3a0ct16ol2] {
    display: flex;
    align-items: center;
    gap: 10px;
    font-size: 1.25rem;
    font-weight: 700;
    color: var(--accent, #2563eb);
    margin-bottom: 20px;
    padding-bottom: 14px;
    border-bottom: 2px solid var(--accent, #2563eb);
}

.sign-logo[b-3a0ct16ol2] {
    width: 28px;
    height: 28px;
}
/* /Components/Layout/UserMenu.razor.rz.scp.css */
.user-menu[b-lzro0634gc] {
    position: relative;
    margin-left: 1rem;
}

.user-chip[b-lzro0634gc] {
    display: flex;
    align-items: center;
    gap: 0.45rem;
    background: none;
    border: 1px solid transparent;
    border-radius: 999px;
    padding: 0.3rem 0.8rem;
    color: var(--text-secondary);
    font-size: 0.9rem;
    cursor: pointer;
    text-decoration: none;
    white-space: nowrap;
}

.user-chip:hover[b-lzro0634gc] {
    background-color: var(--nav-hover-bg);
    border-color: var(--border-color);
}

.chip-icon[b-lzro0634gc] {
    width: 1.1rem;
    height: 1.1rem;
    flex-shrink: 0;
}

.chip-caret[b-lzro0634gc] {
    width: 0.75rem;
    height: 0.75rem;
    flex-shrink: 0;
}

.chip-name[b-lzro0634gc] {
    max-width: 14rem;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* Invisible click-away layer under the dropdown */
.user-menu-backdrop[b-lzro0634gc] {
    position: fixed;
    inset: 0;
    z-index: 1040;
}

.user-menu-dropdown[b-lzro0634gc] {
    position: absolute;
    right: 0;
    top: calc(100% + 0.35rem);
    z-index: 1041;
    min-width: 15rem;
    background: var(--bg-elevated);
    border: 1px solid var(--border-color);
    border-radius: 10px;
    box-shadow: var(--shadow-md);
    padding: 0.4rem;
}

.dropdown-user[b-lzro0634gc] {
    padding: 0.4rem 0.6rem;
}

.dropdown-entry[b-lzro0634gc] {
    display: flex;
    align-items: center;
    gap: 0.55rem;
    width: 100%;
    background: none;
    border: none;
    border-radius: 6px;
    padding: 0.45rem 0.6rem;
    font-size: 0.88rem;
    color: inherit;
    text-decoration: none;
    cursor: pointer;
    text-align: left;
}

.dropdown-entry:hover[b-lzro0634gc] {
    background-color: var(--nav-hover-bg);
}

.entry-icon[b-lzro0634gc] {
    width: 1rem;
    height: 1rem;
    flex-shrink: 0;
}

/* ── Security tab ── */
.qr-box[b-lzro0634gc] {
    width: 180px;
    height: 180px;
    padding: 6px;
    /* Stays white in both themes on purpose: a QR reader needs dark-on-light to scan. */
    background: #fff;
    border: 1px solid var(--border-color);
    border-radius: 8px;
}

.recovery-codes[b-lzro0634gc] {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0.25rem 1rem;
}

.recovery-codes code[b-lzro0634gc] {
    font-size: 0.85rem;
}
/* /Components/Pages/Agreements/Details.razor.rz.scp.css */
/* Agreement line grid — same readable sizing and two-line header style as the projection grid. */
.agreement-grid[b-dxsoruelzw] {
    font-size: 0.9rem;
}

.agreement-grid th[b-dxsoruelzw] {
    font-size: 0.72rem;
    text-transform: uppercase;
    letter-spacing: 0.02em;
    font-weight: 600;
    color: var(--text-secondary, #4b5563);
    white-space: normal;      /* multi-line headers */
    line-height: 1.15;
    vertical-align: bottom;
}

/* No spinner buttons — arrow keys navigate the grid, typing edits the value */
.agreement-grid input[type="number"][b-dxsoruelzw]::-webkit-outer-spin-button,
.agreement-grid input[type="number"][b-dxsoruelzw]::-webkit-inner-spin-button {
    -webkit-appearance: none;
    margin: 0;
}

.agreement-grid input[type="number"][b-dxsoruelzw] {
    -moz-appearance: textfield;
    appearance: textfield;
}

/* The "why is this zero" mark in the support cell. Absolutely placed so it cannot be pushed onto
   a line of its own beneath the full-width number input in edit mode, which is how it came to sit
   under the box looking like a stray character. */
.soa-cell[b-dxsoruelzw] { position: relative; }

.soa-cell .soa-why[b-dxsoruelzw] {
    position: absolute;
    left: .3rem;
    top: 50%;
    transform: translateY(-50%);
    font-size: .6875rem;
    line-height: 1;
    color: var(--bs-secondary-color, #6c757d);
    cursor: help;
}

/* Its own gutter inside the cell, so the mark never sits on the input's left edge where it would
   swallow clicks meant for the box. The figure is right-aligned, so the space costs nothing. */
.soa-cell .form-control[b-dxsoruelzw] { padding-left: 1.15rem; }

/* A line that does not land on the margin it was priced against. */
.margin-drift[b-dxsoruelzw] {
    margin-left: .2rem;
    font-size: .625rem;
    color: var(--bs-secondary-color, #6c757d);
    cursor: help;
}
/* /Components/Pages/Agreements/Index.razor.rz.scp.css */
/* The three rankable columns. Only these carry the affordance — the rest of the header is what you
   filter by, above the table, not what you sort by. */
.agr-sortable[b-oy7j7fupiq] {
    cursor: pointer;
    user-select: none;
    white-space: nowrap;
}

.agr-sortable:hover[b-oy7j7fupiq] {
    color: var(--accent, #2563eb);
}
/* /Components/Pages/Agreements/Reporting.razor.rz.scp.css */
/* ── KPI cards: Insight360/mock style — white card, tinted icon chip, big value ── */

.soa-kpis[b-785yz4miuj] {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
    gap: 12px;
}

.soa-kpi[b-785yz4miuj] {
    background: var(--bg-card, #fff);
    border: 1px solid var(--border-color, #e5e7eb);
    border-radius: 14px;
    padding: 16px 18px;
    display: flex;
    flex-direction: column;
    gap: 6px;
    box-shadow: 0 1px 2px rgba(0, 0, 0, .04);
}

.soa-kpi-top[b-785yz4miuj] {
    display: flex;
    align-items: center;
    gap: 10px;
}

.soa-kpi-icon[b-785yz4miuj] {
    width: 40px;
    height: 40px;
    border-radius: 10px;
    background: color-mix(in srgb, var(--kpi-color, #888) 14%, transparent);
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
}

.soa-kpi-icon svg[b-785yz4miuj] {
    width: 20px;
    height: 20px;
    stroke: var(--kpi-color, #888);
    fill: none;
    stroke-width: 2;
    stroke-linecap: round;
    stroke-linejoin: round;
}

.soa-kpi-label[b-785yz4miuj] {
    font-size: 0.76rem;
    font-weight: 600;
    color: var(--text-muted, #6c757d);
    text-transform: uppercase;
    letter-spacing: 0.02em;
}

.soa-kpi-value[b-785yz4miuj] {
    font-size: 1.7rem;
    font-weight: 700;
    line-height: 1.1;
}

.soa-kpi-caption[b-785yz4miuj] {
    font-size: 0.74rem;
    color: var(--text-muted, #6c757d);
}

/* ── Investment flow ───────────────────────────────────────────────────────
   The same chevron language as the dashboard pipelines — interlocking stages tinted along a ramp
   so the colour itself says how far through the lifecycle you are looking. It is a separate set of
   rules rather than a reuse of .hd-flow because the two carry different things: that one shows a
   count and a share, this one money, a share of budget, and the gap to budget underneath. */
.ivf-head[b-785yz4miuj] {
    padding: 16px 18px 12px;
}

.ivf-title[b-785yz4miuj] {
    font-family: var(--font-display);
    font-size: 19px;
    font-weight: 700;
    letter-spacing: -0.01em;
    color: var(--text-strong);
}

.ivf-caption[b-785yz4miuj] {
    font-size: 13px;
    color: var(--text-secondary);
    margin-top: 2px;
}

.ivf-track[b-785yz4miuj] {
    display: flex;
    gap: 3px;
    margin: 0 14px;
    border-radius: 12px;
    /* Squares off the outer ends, which the chevron clip-path cannot round itself. */
    overflow: hidden;
    --flow-start: #e1ebfc;
    --flow-end: #ddf2e6;
    --flow-icon: #8d99a8;
    --notch: 14px;
}

[data-theme="dark"] .ivf-track[b-785yz4miuj] {
    --flow-start: #1e2a3d;
    --flow-end: #1c3029;
    --flow-icon: #7c8896;
}

.ivf-step[b-785yz4miuj] {
    flex: 1 1 0;
    min-width: 0;
    border: 0;
    padding: 16px 22px 14px;
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    cursor: pointer;
    background: color-mix(in srgb, var(--flow-end) var(--tint, 0%), var(--flow-start));
    /* Notched on the left, pointed on the right: each stage slots into the next. */
    clip-path: polygon(0 0, calc(100% - var(--notch)) 0, 100% 50%, calc(100% - var(--notch)) 100%, 0 100%, var(--notch) 50%);
    transition: transform .15s, filter .15s;
}

/* The two ends face outwards, so the flow reads as one bar with a direction. */
.ivf-first[b-785yz4miuj] { clip-path: polygon(0 0, calc(100% - var(--notch)) 0, 100% 50%, calc(100% - var(--notch)) 100%, 0 100%); }
.ivf-last[b-785yz4miuj]  { clip-path: polygon(0 0, 100% 0, 100% 100%, 0 100%, var(--notch) 50%); }

/* box-shadow would be clipped away with the corners; drop-shadow follows the chevron. */
.ivf-step:hover:not(:disabled)[b-785yz4miuj] {
    transform: translateY(-2px);
    filter: drop-shadow(0 5px 10px rgba(16, 24, 40, 0.16));
}

.ivf-step:focus-visible[b-785yz4miuj] { outline: 2px solid var(--accent); outline-offset: -3px; }
.ivf-step:disabled[b-785yz4miuj] { cursor: default; opacity: .62; }

.ivf-icon[b-785yz4miuj] {
    width: 36px; height: 36px;
    border-radius: 50%;
    background: var(--bg-card);
    color: var(--flow-icon);
    display: flex; align-items: center; justify-content: center;
    margin-bottom: 9px;
    flex-shrink: 0;
}

.ivf-icon svg[b-785yz4miuj] {
    width: 18px; height: 18px;
    stroke: currentColor; fill: none;
    stroke-width: 2; stroke-linecap: round; stroke-linejoin: round;
}

.ivf-label[b-785yz4miuj] {
    font-size: 12px;
    font-weight: 600;
    line-height: 1.15;
    color: var(--text-secondary);
    display: flex;
    flex-direction: column;
    align-items: center;
}

.ivf-sublabel[b-785yz4miuj] {
    font-size: 10px;
    font-weight: 500;
    color: var(--text-muted);
}

.ivf-value[b-785yz4miuj] {
    font-size: 22px;
    font-weight: 700;
    color: var(--text-strong);
    line-height: 1.1;
    margin-top: 7px;
    white-space: nowrap;
}

.ivf-share[b-785yz4miuj] {
    font-size: 12px;
    color: var(--text-secondary);
    margin-top: 3px;
    min-height: 16px;
}

.ivf-delta[b-785yz4miuj] {
    font-size: 11px;
    color: var(--text-muted);
    margin-top: 10px;
    line-height: 1.25;
    min-height: 28px;
    display: flex;
    flex-direction: column;
}

.ivf-delta-note[b-785yz4miuj] { font-size: 10px; }

/* ── Lifecycle rail ── */
.ivf-rail[b-785yz4miuj] {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 12px 18px 16px;
}

.ivf-rail-label[b-785yz4miuj] {
    font-size: 11px;
    color: var(--text-muted);
    white-space: nowrap;
    padding-left: 10px;
    border-left: 2px solid var(--border-color);
}

.ivf-rail-line[b-785yz4miuj] {
    flex: 1;
    display: flex;
    align-items: center;
    justify-content: space-between;
    height: 2px;
    background: color-mix(in srgb, var(--accent) 45%, transparent);
    border-radius: 2px;
}

.ivf-rail-dot[b-785yz4miuj] {
    width: 9px; height: 9px;
    border-radius: 50%;
    background: var(--accent);
    flex-shrink: 0;
}

/* A stage with nothing in it is hollow, so the rail shows how far the money actually got. */
.ivf-rail-dot-empty[b-785yz4miuj] {
    background: var(--bg-card);
    box-shadow: inset 0 0 0 2px color-mix(in srgb, var(--accent) 45%, transparent);
}

.ivf-note[b-785yz4miuj] {
    font-size: 12px;
    color: var(--text-muted);
    padding: 0 18px 16px;
}

/* Below about 1100px six chevrons cannot hold their figures, so the track scrolls sideways
   rather than crushing them. */
@media (max-width: 1100px) {
    .ivf-track[b-785yz4miuj] { overflow-x: auto; }
    .ivf-step[b-785yz4miuj] { flex: 0 0 178px; }
}

/* ── Investment split ──────────────────────────────────────────────────────
   A ranked bar list rather than a donut: five slices of similar size are hard to order by eye,
   and this is read top to bottom without effort. The bar is scaled against the largest row, not
   the total, so the smallest row is still a visible bar rather than a sliver. */

/* Ranked rows without a logo mark — the claim stages and the investment types are not customers,
   so the row drops the first column and gives the width to the name. Not clickable either: these
   two lists describe money already accounted for, and there is nothing behind a row to open. */
.rr-row[b-785yz4miuj] {
    grid-template-columns: minmax(90px, auto) minmax(40px, 1fr) auto 44px;
    cursor: default;
}

.rr-row:hover[b-785yz4miuj] { background: none; }

.rr-sub[b-785yz4miuj] {
    margin-left: 6px;
    font-weight: 400;
    font-size: 0.74rem;
    color: var(--text-muted);
}
/* /Components/Pages/Ai/RunEditor.razor.rz.scp.css */
/* Bootstrap's .card sets display:flex, and a <details> told to be a flex container renders its
   contents whether it is open or not — the arrow turns, the panel never closes. The element has to
   stay display:block for the browser's own open/closed behaviour to work, so the card's look is
   taken from it without the layout mode that breaks it. */
details.card[b-5vw1lv1r4l] {
    display: block;
}

details.card > summary[b-5vw1lv1r4l] {
    list-style: none;
}

details.card > summary[b-5vw1lv1r4l]::-webkit-details-marker {
    display: none;
}

/* A caret of our own, since the native marker is suppressed to keep the card header's look. */
details.card > summary[b-5vw1lv1r4l]::after {
    content: "⌄";
    float: right;
    color: var(--text-muted);
    transition: transform .15s;
}

details.card[open] > summary[b-5vw1lv1r4l]::after {
    content: "⌃";
}
/* /Components/Pages/Catalogue/CustomerDetails.razor.rz.scp.css */

/* ── Logotype ──
   Same 34px circle the investment split uses, so what you upload is previewed at the size it will
   actually be drawn. object-fit keeps a non-square image from stretching. */
.cust-logo[b-4cp8y0yz7z] {
    width: 34px;
    height: 34px;
    border-radius: 50%;
    flex-shrink: 0;
    overflow: hidden;
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--accent-light);
    border: 1px solid var(--border-color);
}

.cust-logo img[b-4cp8y0yz7z] {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.cust-logo-initials[b-4cp8y0yz7z] {
    font-size: 12px;
    font-weight: 700;
    color: var(--accent);
}
/* /Components/Pages/Changelog.razor.rz.scp.css */
.changelog-container[b-0y5o0m1a6a] {
    max-width: 800px;
}

.changelog-item[b-0y5o0m1a6a] {
    background: var(--bg-card, #fff);
    border-radius: 12px;
    margin-bottom: 1rem;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08);
    overflow: hidden;
}

.changelog-item.latest[b-0y5o0m1a6a] {
    border: 2px solid var(--accent, #2563eb);
}

.changelog-header[b-0y5o0m1a6a] {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 1rem 1.25rem;
    cursor: pointer;
    transition: background-color 0.2s ease;
}

.changelog-header:hover[b-0y5o0m1a6a] {
    background-color: var(--bg-subtle, #f5f7fa);
}

.version-badge[b-0y5o0m1a6a] {
    font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Monaco, Consolas, monospace;
    font-size: 0.95rem;
    font-weight: 600;
    color: var(--text-primary, #1f2937);
    padding: 0.25rem 0.75rem;
    background-color: var(--bg-subtle, #f5f7fa);
    border-radius: 6px;
}

.version-badge.badge-latest[b-0y5o0m1a6a] {
    background: linear-gradient(135deg, rgba(37, 99, 235, 0.15), rgba(37, 99, 235, 0.1));
    color: var(--accent, #2563eb);
}

.release-date[b-0y5o0m1a6a] {
    font-size: 0.875rem;
}

.expand-icon[b-0y5o0m1a6a] {
    color: var(--text-muted, #8a94a6);
    transition: transform 0.2s ease;
}

.expand-icon.expanded[b-0y5o0m1a6a] {
    transform: rotate(180deg);
}

.changelog-body[b-0y5o0m1a6a] {
    padding: 0 1.25rem 1.25rem;
    border-top: 1px solid var(--border-color, #e5e9f0);
}

.changes-list[b-0y5o0m1a6a] {
    list-style: none;
    padding: 0;
    margin: 1rem 0 0 0;
}

.changes-list li[b-0y5o0m1a6a] {
    position: relative;
    padding: 0.5rem 0 0.5rem 1.5rem;
    color: var(--text-secondary, #4b5563);
    line-height: 1.5;
}

.changes-list li[b-0y5o0m1a6a]::before {
    content: "";
    position: absolute;
    left: 0;
    top: 0.9rem;
    width: 6px;
    height: 6px;
    background-color: var(--accent, #2563eb);
    border-radius: 50%;
}
/* /Components/Pages/Customers/Reporting.razor.rz.scp.css */
/* ── KPI cards: same Insight360/mock style as the SOA dashboard ── */

.soa-kpis[b-drwu4qdj7j] {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
    gap: 12px;
}

.soa-kpi[b-drwu4qdj7j] {
    background: var(--bg-card, #fff);
    border: 1px solid var(--border-color, #e5e7eb);
    border-radius: 14px;
    padding: 16px 18px;
    display: flex;
    flex-direction: column;
    gap: 6px;
    box-shadow: 0 1px 2px rgba(0, 0, 0, .04);
}

.soa-kpi-top[b-drwu4qdj7j] {
    display: flex;
    align-items: center;
    gap: 10px;
}

.soa-kpi-icon[b-drwu4qdj7j] {
    width: 40px;
    height: 40px;
    border-radius: 10px;
    background: color-mix(in srgb, var(--kpi-color, #888) 14%, transparent);
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
}

.soa-kpi-icon svg[b-drwu4qdj7j] {
    width: 20px;
    height: 20px;
    stroke: var(--kpi-color, #888);
    fill: none;
    stroke-width: 2;
    stroke-linecap: round;
    stroke-linejoin: round;
}

.soa-kpi-label[b-drwu4qdj7j] {
    font-size: 0.76rem;
    font-weight: 600;
    color: var(--text-muted, #6c757d);
    text-transform: uppercase;
    letter-spacing: 0.02em;
}

.soa-kpi-value[b-drwu4qdj7j] {
    font-size: 1.7rem;
    font-weight: 700;
    line-height: 1.1;
}

.soa-kpi-caption[b-drwu4qdj7j] {
    font-size: 0.74rem;
    color: var(--text-muted, #6c757d);
}

/* ── Customer table ── */

.row-link[b-drwu4qdj7j] {
    cursor: pointer;
}

.sortable[b-drwu4qdj7j] {
    cursor: pointer;
    user-select: none;
    white-space: nowrap;
}

.sortable:hover[b-drwu4qdj7j] {
    color: var(--accent, #2563eb);
}

/* ── KPI stacks beside the compact pie: two boxes share the column height ── */
.kpi-stack[b-drwu4qdj7j] {
    display: flex;
    flex-direction: column;
    gap: 1rem;
}

.kpi-stack .soa-kpi[b-drwu4qdj7j] {
    flex: 1;
}

/* ── The two ranked cards under the headline figures ───────────────────────
   Both are isp-* lists (app.css) — the round logo mark, the name, a bar, the figures. What is
   local here is what each list does with its bar: the investment split draws two of them, and the
   ROI ranking draws one that can run either side of zero. */
/* Every column a fixed size but the bar. Each row is its own grid container, so an "auto" column
   is measured per row — a long customer name would step that row's bar in and leave the list with
   a ragged edge down the middle. Fixed columns make the rows line up, and make the axis below the
   ROI list able to echo the same template and land under the right column. */
.cbar-row[b-drwu4qdj7j] {
    grid-template-columns: 30px 8.5rem minmax(60px, 1fr) 4.6rem;
}

.cbar-axis-row[b-drwu4qdj7j] {
    padding-top: 2px;
    padding-bottom: 0;
    cursor: default;
}

.cbar-axis-row:hover[b-drwu4qdj7j] { background: none; }

/* Two thin bars where the single isp bar would be. */
.cbar-pair[b-drwu4qdj7j] {
    display: flex;
    flex-direction: column;
    gap: 3px;
}

.cbar-track[b-drwu4qdj7j] {
    position: relative;
    display: block;
    height: 9px;
    border-radius: 5px;
    background: var(--bg-subtle);
    overflow: hidden;
}

.cbar-fill[b-drwu4qdj7j] {
    position: absolute;
    top: 0;
    bottom: 0;
    border-radius: 5px;
    min-width: 2px;
}

.cbar-fill-committed[b-drwu4qdj7j] { left: 0; background: #2563eb; }
.cbar-fill-spent[b-drwu4qdj7j]     { left: 0; background: #0891b2; }

/* The header swatches carry the same two values — change them together. */
.cbar-key[b-drwu4qdj7j] {
    width: 10px;
    height: 10px;
    border-radius: 2px;
    display: inline-block;
}

.cbar-key-committed[b-drwu4qdj7j] { background: #2563eb; }
.cbar-key-spent[b-drwu4qdj7j]     { background: #0891b2; }

.cbar-nums[b-drwu4qdj7j] {
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    line-height: 1.25;
}

.cbar-num-sub[b-drwu4qdj7j] {
    font-size: 0.74rem;
    color: var(--text-secondary);
    font-variant-numeric: tabular-nums;
}

/* ── The diverging ROI bar ── */
.cbar-div[b-drwu4qdj7j] {
    height: 22px;
    overflow: visible;
}

.cbar-zero[b-drwu4qdj7j] {
    position: absolute;
    top: -2px;
    bottom: -2px;
    width: 1px;
    background: var(--border-color);
    z-index: 1;
}

.cbar-fill-pos[b-drwu4qdj7j] { background: #16a34a; }
.cbar-fill-bad[b-drwu4qdj7j],
.cbar-fill-neg[b-drwu4qdj7j] { background: #ef7a7a; }

/* Endpoints of the range, with zero sitting where it actually falls between them. */
.cbar-axis[b-drwu4qdj7j] {
    position: relative;
    display: block;
    height: 1em;
    font-size: 0.7rem;
    color: var(--text-muted);
    font-variant-numeric: tabular-nums;
}

.cbar-axis-min[b-drwu4qdj7j],
.cbar-axis-max[b-drwu4qdj7j],
.cbar-axis-zero[b-drwu4qdj7j] {
    position: absolute;
    top: 0;
    white-space: nowrap;
}

.cbar-axis-min[b-drwu4qdj7j] { left: 0; }
.cbar-axis-max[b-drwu4qdj7j] { right: 0; }

.cbar-axis-zero[b-drwu4qdj7j] {
    left: var(--zero, 0%);
    transform: translateX(-50%);
}

/* ── ROI pill ──────────────────────────────────────────────────────────────
   One width for all of them: the ROI column is scanned down, not read across, and chips that
   change width with their digits make a ragged edge that hides the pattern in the colours. */
.roi-pill[b-drwu4qdj7j] {
    display: inline-block;
    min-width: 4.4rem;
    padding: 2px 8px;
    border-radius: 999px;
    border: 1px solid transparent;
    font-size: 0.78rem;
    font-weight: 600;
    text-align: center;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

.roi-pill-good[b-drwu4qdj7j] {
    background: color-mix(in srgb, #16a34a 14%, transparent);
    border-color: color-mix(in srgb, #16a34a 30%, transparent);
    color: #15803d;
}

.roi-pill-weak[b-drwu4qdj7j] {
    background: color-mix(in srgb, #d97706 14%, transparent);
    border-color: color-mix(in srgb, #d97706 30%, transparent);
    color: #b45309;
}

.roi-pill-flat[b-drwu4qdj7j] {
    background: var(--bg-subtle);
    border-color: var(--border-color);
    color: var(--text-secondary);
}

.roi-pill-bad[b-drwu4qdj7j] {
    background: color-mix(in srgb, #dc2626 13%, transparent);
    border-color: color-mix(in srgb, #dc2626 28%, transparent);
    color: #b91c1c;
}

/* No matched spend to measure — not a score, so it carries no colour at all. */
.roi-pill-none[b-drwu4qdj7j] {
    background: none;
    border-color: transparent;
    color: var(--text-muted);
}

/* The light-mode greens and reds go muddy on the ember ground. */
[data-theme="dark"] .roi-pill-good[b-drwu4qdj7j] { color: #5fd99a; }
[data-theme="dark"] .roi-pill-weak[b-drwu4qdj7j] { color: #f0c060; }
[data-theme="dark"] .roi-pill-bad[b-drwu4qdj7j]  { color: #f08a7f; }
[data-theme="dark"] .cbar-fill-pos[b-drwu4qdj7j] { background: #34c07a; }
[data-theme="dark"] .cbar-fill-neg[b-drwu4qdj7j] { background: #e0736f; }

/* A bar that runs past the frame ends in a zigzag rather than a clean edge, so it cannot be read
   as one that merely reaches the end of the scale. The teeth are on the outer end only — the end
   at zero stays square, because that end is exact. */
.cbar-clip-low[b-drwu4qdj7j] {
    border-top-left-radius: 0;
    border-bottom-left-radius: 0;
    clip-path: polygon(5px 0, 100% 0, 100% 100%, 5px 100%, 0 83%, 5px 66%, 0 50%, 5px 33%, 0 16%);
}

.cbar-clip-high[b-drwu4qdj7j] {
    border-top-right-radius: 0;
    border-bottom-right-radius: 0;
    clip-path: polygon(0 0, calc(100% - 5px) 0, 100% 16%, calc(100% - 5px) 33%, 100% 50%, calc(100% - 5px) 66%, 100% 83%, calc(100% - 5px) 100%, 0 100%);
}

.cbar-note[b-drwu4qdj7j] {
    margin-top: 8px;
    font-size: 0.72rem;
    line-height: 1.35;
    color: var(--text-muted);
}
/* /Components/Pages/Customers/ReportingDetails.razor.rz.scp.css */
/* ── KPI cards: same Insight360/mock style as the SOA dashboard ── */

.soa-kpis[b-uvx92ucib3] {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
    gap: 12px;
}

.soa-kpi[b-uvx92ucib3] {
    background: var(--bg-card, #fff);
    border: 1px solid var(--border-color, #e5e7eb);
    border-radius: 14px;
    padding: 16px 18px;
    display: flex;
    flex-direction: column;
    gap: 6px;
    box-shadow: 0 1px 2px rgba(0, 0, 0, .04);
}

.soa-kpi-top[b-uvx92ucib3] {
    display: flex;
    align-items: center;
    gap: 10px;
}

.soa-kpi-icon[b-uvx92ucib3] {
    width: 40px;
    height: 40px;
    border-radius: 10px;
    background: color-mix(in srgb, var(--kpi-color, #888) 14%, transparent);
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
}

.soa-kpi-icon svg[b-uvx92ucib3] {
    width: 20px;
    height: 20px;
    stroke: var(--kpi-color, #888);
    fill: none;
    stroke-width: 2;
    stroke-linecap: round;
    stroke-linejoin: round;
}

.soa-kpi-label[b-uvx92ucib3] {
    font-size: 0.76rem;
    font-weight: 600;
    color: var(--text-muted, #6c757d);
    text-transform: uppercase;
    letter-spacing: 0.02em;
}

.soa-kpi-value[b-uvx92ucib3] {
    font-size: 1.7rem;
    font-weight: 700;
    line-height: 1.1;
}

.soa-kpi-caption[b-uvx92ucib3] {
    font-size: 0.74rem;
    color: var(--text-muted, #6c757d);
}

/* ── Status dot in the agreements table ── */

.status-dot[b-uvx92ucib3] {
    display: inline-block;
    width: 9px;
    height: 9px;
    border-radius: 50%;
    background: var(--dot, #6c757d);
    margin-right: 4px;
}

/* ── Detail pages: fixed 2 rows × 3 boxes (tidier than one long strip) ── */
.soa-kpis.two-rows[b-uvx92ucib3] {
    grid-template-columns: repeat(3, minmax(0, 1fr));
}

@media (max-width: 900px) {
    .soa-kpis.two-rows[b-uvx92ucib3] {
        grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
    }
}
/* /Components/Pages/Forecasts/Entry.razor.rz.scp.css */
/* Worksheet grid — Trophyst campaign-table header style + vertical field separators. */
.projection-grid[b-k3c370q2lj] {
    font-size: 12.6px;
    width: 100%;
}

.projection-grid th[b-k3c370q2lj] {
    font-size: 10.1px;
    text-transform: uppercase;
    letter-spacing: 0.02em;
    font-weight: 600;
    color: var(--text-secondary, #4b5563);
    white-space: normal;      /* multi-line headers */
    line-height: 1.15;
    padding: 0.3rem 0.4rem;
    vertical-align: bottom;
    border-bottom: 2px solid var(--border-color, #dbe1ea);
    border-right: 1px solid var(--border-color, #e5e9f0);
}

.projection-grid td[b-k3c370q2lj] {
    padding: 0.25rem 0.35rem;
    vertical-align: middle;
    border-right: 1px solid var(--border-color, #e5e9f0);
}

.projection-grid th:last-child[b-k3c370q2lj],
.projection-grid td:last-child[b-k3c370q2lj] {
    border-right: 0;
}

.projection-grid thead[b-k3c370q2lj] {
    position: sticky;
    top: 0;
    z-index: 5;
}

/* Opaque header cells + a soft drop-shadow, so scrolling rows don't ghost through the
   frozen header (the group-banner tints are translucent by design). */
.forecast-grid thead th[b-k3c370q2lj] {
    background-color: var(--bg-elevated, #fff);
}

.forecast-grid thead tr:last-child th[b-k3c370q2lj] {
    box-shadow: 0 6px 8px -6px rgba(0, 0, 0, 0.22);
}

/* The grid is its own bounded scroll panel so the header can truly freeze: sticky anchors
   to THIS scroll box, and the body scrolls under a frozen thead (Excel-style). The height is
   refined in JS (stickyStrip.fit) to reach the viewport bottom; this calc is the fallback. */
.forecast-scroll[b-k3c370q2lj] {
    max-height: calc(100vh - 240px);
    overflow: auto;
}

/* Keep keyboard/focus navigation from tucking a row under the (tall) sticky header.
   --fc-strip-h is the measured header height, published by stickyStrip.sync. */
.forecast-grid tbody tr[b-k3c370q2lj],
.forecast-grid tbody input[b-k3c370q2lj] {
    scroll-margin-top: calc(var(--fc-strip-h, 120px) + 0.5rem);
}

/* ── Mini-calendar rides inside the sticky <thead> as its own full-width row ── */
.forecast-grid .fc-cal-cell[b-k3c370q2lj] {
    padding: 0 !important;
    border: 0 !important;
    text-transform: none;
    letter-spacing: normal;
    font-weight: 400;
    vertical-align: top;
    border-bottom: 1px solid var(--border-color, #dbe1ea) !important;
}

.fc-oneliner[b-k3c370q2lj] {
    background: var(--bg-elevated, #fff);
    overflow: hidden;
}

/* The harvested pcal, sized for the header context. */
.fc-ol-pcal .pcal-track[b-k3c370q2lj] {
    min-width: 640px;
}

.fc-ol-pcal .pcal-label[b-k3c370q2lj] {
    background: var(--bg-elevated, #fff);
}

/* Normal-price field focused: campaign bars dim, the window shading reads as "outside". */
.fc-oneliner.fc-outside .pcal-bar[b-k3c370q2lj] {
    opacity: 0.4;
}

.fc-oneliner.fc-outside .pcal-inperiod[b-k3c370q2lj] {
    background: rgba(22, 163, 74, 0.1);
}

.projection-grid tbody tr:hover[b-k3c370q2lj] {
    background-color: rgba(37, 99, 235, 0.05);
}

/* Compact inputs so the grid rows stay tight */
.projection-grid input.form-control-sm[b-k3c370q2lj] {
    padding: 0.15rem 0.3rem;
    font-size: 11.9px;
}

/* No spinner buttons — arrow keys navigate the grid, typing edits the value */
.projection-grid input[type="number"][b-k3c370q2lj]::-webkit-outer-spin-button,
.projection-grid input[type="number"][b-k3c370q2lj]::-webkit-inner-spin-button {
    -webkit-appearance: none;
    margin: 0;
}

.projection-grid input[type="number"][b-k3c370q2lj] {
    -moz-appearance: textfield;
    appearance: textfield;
}

/* Perspective group banner + customer-group tinting */
.projection-grid .grp-row th[b-k3c370q2lj] {
    text-align: center;
    font-size: 9.8px;
    letter-spacing: 0.06em;
    padding: 0.25rem 0.4rem;
    border-bottom: 1px solid var(--border-color, #dbe1ea);
    vertical-align: middle;
}

.projection-grid .grp-blank[b-k3c370q2lj] {
    border-right: 0;
}

/* Tints layered as an image over the opaque header background above (so they stay opaque). */
.projection-grid .grp-our[b-k3c370q2lj] {
    background-image: linear-gradient(rgba(37, 99, 235, 0.10), rgba(37, 99, 235, 0.10));
    color: #1d4ed8;
}

.projection-grid .grp-customer[b-k3c370q2lj] {
    background-image: linear-gradient(rgba(217, 119, 6, 0.12), rgba(217, 119, 6, 0.12));
    color: #b45309;
}

.projection-grid th.grp-customer-col[b-k3c370q2lj] {
    background: rgba(217, 119, 6, 0.06);
}

.projection-grid td.grp-customer-col[b-k3c370q2lj] {
    background: rgba(217, 119, 6, 0.03);
}
/* /Components/Pages/Home.razor.rz.scp.css */
/* ── Promora dashboard (hd-*) — the shared page furniture lives in app.css ── */

/* Greeting (kept for the pending-activation card) */
.hd-hello[b-40apetgema] {
    font-size: 28px;
    font-weight: 700;
    color: var(--text-strong);
}

.hd-subtitle[b-40apetgema] {
    color: var(--text-secondary);
    font-size: 14px;
}

/* KPI action cards */
.hd-kpis[b-40apetgema] {
    display: flex;
    flex-direction: column;
    gap: 14px;
}

.hd-kpi-row[b-40apetgema] {
    display: flex;
    gap: 14px;
}

.hd-kpi[b-40apetgema] {
    flex: 1 1 0;
    min-width: 0;
    display: flex;
    align-items: flex-start;
    gap: 10px;
    text-align: left;
    padding: 13px 14px;
    background: var(--bg-card);
    border: 1px solid var(--border-color);
    border-radius: 12px;
    cursor: pointer;
    transition: transform 0.15s, box-shadow 0.15s, border-color 0.15s;
}

.hd-kpi:hover:not(:disabled)[b-40apetgema] {
    border-color: var(--kpi-color, var(--text-muted));
    box-shadow: 0 6px 16px rgba(0, 0, 0, 0.08);
    transform: translateY(-2px);
}

.hd-kpi:disabled[b-40apetgema] { cursor: default; opacity: 0.85; }
.hd-kpi:focus-visible[b-40apetgema] { outline: 2px solid var(--kpi-color, var(--text-muted)); outline-offset: 2px; }

.hd-kpi-icon[b-40apetgema] {
    width: 34px;
    height: 34px;
    border-radius: 10px;
    background: var(--kpi-color, #ced4da);
    color: #fff;
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
}

.hd-kpi-icon svg[b-40apetgema] {
    width: 18px; height: 18px;
    stroke: currentColor; fill: none;
    stroke-width: 2; stroke-linecap: round; stroke-linejoin: round;
}

.hd-kpi-body[b-40apetgema] { min-width: 0; flex: 1; }

.hd-kpi-title[b-40apetgema] {
    font-size: 12.5px;
    font-weight: 700;
    color: var(--text-strong);
    line-height: 1.2;
}

.hd-kpi-desc[b-40apetgema] {
    font-size: 11px;
    color: var(--text-secondary);
    margin-top: 2px;
    line-height: 1.25;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

.hd-kpi-link[b-40apetgema] {
    display: inline-block;
    margin-top: 8px;
    font-size: 12px;
    font-weight: 600;
    color: var(--kpi-color, var(--text-secondary));
}

.hd-kpi-count[b-40apetgema] {
    font-size: 24px;
    font-weight: 700;
    line-height: 1;
    color: var(--text-strong);
    flex-shrink: 0;
}

.hd-panel-footnote[b-40apetgema] {
    padding: 8px 18px 2px;
    font-size: 12px;
    color: var(--text-muted);
}
.hd-panel-footnote a[b-40apetgema] { color: var(--text-secondary); }

/* Narrower viewports: let the balanced rows wrap to fewer, wider cards. */
@media (max-width: 1100px) {
    .hd-kpi-row[b-40apetgema] { flex-wrap: wrap; }
    .hd-kpi[b-40apetgema] { flex: 1 1 44%; }
}

@media (max-width: 560px) {
    .hd-kpi[b-40apetgema] { flex: 1 1 100%; }
}

/* Panel header */
.hd-panel-header[b-40apetgema] {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 14px 18px;
    border-bottom: 1px solid var(--border-subtle);
}

.hd-panel-title[b-40apetgema] {
    font-size: 15px;
    font-weight: 700;
    color: var(--text-strong);
}

.hd-panel-caption[b-40apetgema] {
    font-size: 12px;
    color: var(--text-muted);
    margin-top: 2px;
}

.hd-panel-action[b-40apetgema] {
    font-size: 13px;
    font-weight: 600;
    color: var(--accent);
    text-decoration: none;
    white-space: nowrap;
}

.hd-panel-action:hover[b-40apetgema] { text-decoration: underline; }
.hd-panel-body[b-40apetgema] { padding: 16px 18px; }
.hd-panel-body.p-0[b-40apetgema] { padding: 0; }

/* Pipeline */
.hd-pipeline-wrap[b-40apetgema] {
    display: flex;
    align-items: stretch;
    gap: 18px;
}

/* ── Flow ──────────────────────────────────────────────────────────────────
   The stages are chevrons that interlock, so the eye reads a direction instead of a row of boxes,
   and they are tinted along a ramp from the first stage to the last — the colour itself carries how
   far through the pipeline a stage sits. --tint is the position on that ramp, set per stage from
   the markup, which is what lets one rule serve pipelines of any length. */
.hd-flow[b-40apetgema] {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 12px;
    --flow-start: #e1ebfc;
    --flow-end: #ddf2e6;
    /* One metallic grey for every stage icon. The per-status colours still drive the badges and
       the action cards; inside the flow the tinted chevrons already carry the progression, and
       seven different icon colours on top of them was a colour too many. */
    --flow-icon: #8d99a8;
    --notch: 13px;
}

.hd-flow-track[b-40apetgema] {
    display: flex;
    gap: 3px;
    border-radius: 12px;
    /* Squares off the outer ends, which the chevron clip-path cannot round itself. */
    overflow: hidden;
}

.hd-flow-step[b-40apetgema] {
    flex: 1 1 0;
    min-width: 0;
    border: 0;
    padding: 15px 20px 13px;
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    cursor: pointer;
    background: color-mix(in srgb, var(--flow-end) var(--tint, 0%), var(--flow-start));
    /* Notched on the left, pointed on the right: each stage slots into the next. */
    clip-path: polygon(0 0, calc(100% - var(--notch)) 0, 100% 50%, calc(100% - var(--notch)) 100%, 0 100%, var(--notch) 50%);
    transition: transform .15s, filter .15s;
}

/* The two ends face outwards, so the flow reads as one bar with a direction. */
.hd-flow-first[b-40apetgema] {
    clip-path: polygon(0 0, calc(100% - var(--notch)) 0, 100% 50%, calc(100% - var(--notch)) 100%, 0 100%);
}

.hd-flow-last[b-40apetgema] {
    clip-path: polygon(0 0, 100% 0, 100% 100%, 0 100%, var(--notch) 50%);
}

/* box-shadow would be clipped away with the corners; drop-shadow follows the chevron. */
.hd-flow-step:hover:not(:disabled)[b-40apetgema] {
    transform: translateY(-2px);
    filter: drop-shadow(0 5px 10px rgba(16, 24, 40, 0.16));
}

.hd-flow-step:focus-visible[b-40apetgema] { outline: 2px solid var(--accent); outline-offset: -3px; }
.hd-flow-step:disabled[b-40apetgema] { cursor: default; opacity: .62; }

.hd-flow-circle[b-40apetgema] {
    width: 34px; height: 34px;
    border-radius: 50%;
    background: var(--flow-icon);
    color: #fff;
    display: flex; align-items: center; justify-content: center;
    margin-bottom: 8px;
    flex-shrink: 0;
}

.hd-flow-circle svg[b-40apetgema] {
    width: 17px; height: 17px;
    stroke: currentColor; fill: none;
    stroke-width: 2; stroke-linecap: round; stroke-linejoin: round;
}

.hd-flow-label[b-40apetgema] {
    font-size: 10px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.3px;
    line-height: 1.2;
    color: var(--text-secondary);
    min-height: 24px;
    display: flex; align-items: center; justify-content: center;
}

.hd-flow-count[b-40apetgema] {
    font-size: 23px;
    font-weight: 700;
    color: var(--text-strong);
    line-height: 1;
    margin-top: 5px;
}

.hd-flow-share[b-40apetgema] {
    font-size: 10px;
    font-weight: 600;
    letter-spacing: .2px;
    color: var(--text-secondary);
    margin-top: 5px;
    min-height: 13px;
}

[data-theme="dark"] .hd-flow[b-40apetgema] {
    --flow-start: #1e2a3d;
    --flow-end: #1c3029;
    --flow-icon: #7c8896;
}

.hd-pipeline-summary[b-40apetgema] {
    display: flex;
    flex-direction: column;
    justify-content: center;
    gap: 14px;
    padding: 8px 18px;
    border-left: 1px solid var(--border-subtle);
    min-width: 150px;
}

.hd-summary-stat[b-40apetgema] { text-align: center; }

.hd-summary-num[b-40apetgema] {
    font-size: 26px;
    font-weight: 700;
    color: var(--text-strong);
    line-height: 1;
}

.hd-summary-accent[b-40apetgema] { color: var(--accent); }

.hd-summary-label[b-40apetgema] {
    font-size: 11px;
    text-transform: uppercase;
    letter-spacing: 0.4px;
    font-weight: 600;
    color: var(--text-secondary);
    margin-top: 5px;
}

.hd-summary-divider[b-40apetgema] { height: 1px; background: var(--border-subtle); }

@media (max-width: 992px) {
    .hd-pipeline-wrap[b-40apetgema] { flex-direction: column; }
    .hd-flow-track[b-40apetgema] { overflow-x: auto; }
    .hd-flow-step[b-40apetgema] { flex: 0 0 148px; }
    .hd-pipeline-summary[b-40apetgema] {
        flex-direction: row;
        justify-content: space-around;
        border-left: none;
        border-top: 1px solid var(--border-subtle);
        padding-top: 14px;
    }
    .hd-summary-divider[b-40apetgema] { width: 1px; height: auto; }
}

@media (max-width: 560px) {
    .hd-flow-step[b-40apetgema] { flex: 0 0 130px; }
}

/* Table links inside panels */
[b-40apetgema] .table a {
    color: var(--accent);
    text-decoration: none;
    font-weight: 500;
}

[b-40apetgema] .table a:hover { text-decoration: underline; }
/* /Components/Pages/Products/Reporting.razor.rz.scp.css */
/* ── KPI cards: same Insight360/mock style as the SOA dashboard ── */

.soa-kpis[b-ezaktehu39] {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
    gap: 12px;
}

.soa-kpi[b-ezaktehu39] {
    background: var(--bg-card, #fff);
    border: 1px solid var(--border-color, #e5e7eb);
    border-radius: 14px;
    padding: 16px 18px;
    display: flex;
    flex-direction: column;
    gap: 6px;
    box-shadow: 0 1px 2px rgba(0, 0, 0, .04);
}

.soa-kpi-top[b-ezaktehu39] {
    display: flex;
    align-items: center;
    gap: 10px;
}

.soa-kpi-icon[b-ezaktehu39] {
    width: 40px;
    height: 40px;
    border-radius: 10px;
    background: color-mix(in srgb, var(--kpi-color, #888) 14%, transparent);
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
}

.soa-kpi-icon svg[b-ezaktehu39] {
    width: 20px;
    height: 20px;
    stroke: var(--kpi-color, #888);
    fill: none;
    stroke-width: 2;
    stroke-linecap: round;
    stroke-linejoin: round;
}

.soa-kpi-label[b-ezaktehu39] {
    font-size: 0.76rem;
    font-weight: 600;
    color: var(--text-muted, #6c757d);
    text-transform: uppercase;
    letter-spacing: 0.02em;
}

.soa-kpi-value[b-ezaktehu39] {
    font-size: 1.7rem;
    font-weight: 700;
    line-height: 1.1;
}

.soa-kpi-caption[b-ezaktehu39] {
    font-size: 0.74rem;
    color: var(--text-muted, #6c757d);
}

/* ── Customer table ── */

.row-link[b-ezaktehu39] {
    cursor: pointer;
}

.sortable[b-ezaktehu39] {
    cursor: pointer;
    user-select: none;
    white-space: nowrap;
}

.sortable:hover[b-ezaktehu39] {
    color: var(--accent, #2563eb);
}

/* ── KPI stacks beside the compact pie: two boxes share the column height ── */
.kpi-stack[b-ezaktehu39] {
    display: flex;
    flex-direction: column;
    gap: 1rem;
}

.kpi-stack .soa-kpi[b-ezaktehu39] {
    flex: 1;
}
/* /Components/Pages/Products/ReportingDetails.razor.rz.scp.css */
/* ── KPI cards: same Insight360/mock style as the SOA dashboard ── */

.soa-kpis[b-fprc174o8l] {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
    gap: 12px;
}

.soa-kpi[b-fprc174o8l] {
    background: var(--bg-card, #fff);
    border: 1px solid var(--border-color, #e5e7eb);
    border-radius: 14px;
    padding: 16px 18px;
    display: flex;
    flex-direction: column;
    gap: 6px;
    box-shadow: 0 1px 2px rgba(0, 0, 0, .04);
}

.soa-kpi-top[b-fprc174o8l] {
    display: flex;
    align-items: center;
    gap: 10px;
}

.soa-kpi-icon[b-fprc174o8l] {
    width: 40px;
    height: 40px;
    border-radius: 10px;
    background: color-mix(in srgb, var(--kpi-color, #888) 14%, transparent);
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
}

.soa-kpi-icon svg[b-fprc174o8l] {
    width: 20px;
    height: 20px;
    stroke: var(--kpi-color, #888);
    fill: none;
    stroke-width: 2;
    stroke-linecap: round;
    stroke-linejoin: round;
}

.soa-kpi-label[b-fprc174o8l] {
    font-size: 0.76rem;
    font-weight: 600;
    color: var(--text-muted, #6c757d);
    text-transform: uppercase;
    letter-spacing: 0.02em;
}

.soa-kpi-value[b-fprc174o8l] {
    font-size: 1.7rem;
    font-weight: 700;
    line-height: 1.1;
}

.soa-kpi-caption[b-fprc174o8l] {
    font-size: 0.74rem;
    color: var(--text-muted, #6c757d);
}

/* ── Status dot in the agreements table ── */

.status-dot[b-fprc174o8l] {
    display: inline-block;
    width: 9px;
    height: 9px;
    border-radius: 50%;
    background: var(--dot, #6c757d);
    margin-right: 4px;
}

/* ── Detail pages: fixed 2 rows × 3 boxes (tidier than one long strip) ── */
.soa-kpis.two-rows[b-fprc174o8l] {
    grid-template-columns: repeat(3, minmax(0, 1fr));
}

@media (max-width: 900px) {
    .soa-kpis.two-rows[b-fprc174o8l] {
        grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
    }
}
/* /Components/Pages/Projections/CampaignPeriods.razor.rz.scp.css */
/* The picture is cropped square on the period's own colour, exactly as the calendar draws it — so
   the thumbnail here is a preview rather than an approximation. */
.cp-thumb[b-4meflg4g1g] {
    width: 42px;
    height: 30px;
    border-radius: 6px;
    overflow: hidden;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: var(--cp-color, var(--bg-subtle));
    border: 1px solid var(--border-color);
}

.cp-thumb-lg[b-4meflg4g1g] { width: 72px; height: 52px; }

.cp-thumb img[b-4meflg4g1g] { width: 100%; height: 100%; object-fit: cover; }

.cp-swatch[b-4meflg4g1g] {
    display: inline-block;
    width: 14px; height: 14px;
    border-radius: 4px;
    vertical-align: -2px;
    margin-right: 6px;
    border: 1px solid var(--border-color);
}

.cp-pick[b-4meflg4g1g] {
    width: 30px; height: 30px;
    border-radius: 7px;
    border: 2px solid transparent;
    cursor: pointer;
    padding: 0;
}

.cp-pick-on[b-4meflg4g1g] {
    border-color: var(--text-strong);
    box-shadow: 0 0 0 2px var(--bg-card) inset;
}
/* /Components/Pages/Projections/CategoryDetails.razor.rz.scp.css */
/* Worksheet grid — Trophyst campaign-table header style + vertical field separators. */
.projection-grid[b-fg2rh2as0g] {
    font-size: 12.6px;
    width: 100%;
}

.projection-grid th[b-fg2rh2as0g] {
    font-size: 10.1px;
    text-transform: uppercase;
    letter-spacing: 0.02em;
    font-weight: 600;
    color: var(--text-secondary, #4b5563);
    white-space: normal;      /* multi-line headers */
    line-height: 1.15;
    padding: 0.3rem 0.4rem;
    vertical-align: bottom;
    border-bottom: 2px solid var(--border-color, #dbe1ea);
    border-right: 1px solid var(--border-color, #e5e9f0);
}

.projection-grid td[b-fg2rh2as0g] {
    padding: 0.25rem 0.35rem;
    vertical-align: middle;
    border-right: 1px solid var(--border-color, #e5e9f0);
}

.projection-grid th:last-child[b-fg2rh2as0g],
.projection-grid td:last-child[b-fg2rh2as0g] {
    border-right: 0;
}

.projection-grid thead[b-fg2rh2as0g] {
    position: sticky;
    top: 0;
    z-index: 5;
}

.projection-grid tbody tr:hover[b-fg2rh2as0g] {
    background-color: rgba(37, 99, 235, 0.05);
}

/* Compact inputs so the grid rows stay tight */
.projection-grid input.form-control-sm[b-fg2rh2as0g] {
    padding: 0.15rem 0.3rem;
    font-size: 11.9px;
}

/* No spinner buttons — arrow keys navigate the grid, typing edits the value */
.projection-grid input[type="number"][b-fg2rh2as0g]::-webkit-outer-spin-button,
.projection-grid input[type="number"][b-fg2rh2as0g]::-webkit-inner-spin-button {
    -webkit-appearance: none;
    margin: 0;
}

.projection-grid input[type="number"][b-fg2rh2as0g] {
    -moz-appearance: textfield;
    appearance: textfield;
}

/* Perspective group banner + customer-group tinting */
.projection-grid .grp-row th[b-fg2rh2as0g] {
    text-align: center;
    font-size: 9.8px;
    letter-spacing: 0.06em;
    padding: 0.25rem 0.4rem;
    border-bottom: 1px solid var(--border-color, #dbe1ea);
    vertical-align: middle;
}

.projection-grid .grp-blank[b-fg2rh2as0g] {
    background: transparent;
    border-right: 0;
}

.projection-grid .grp-our[b-fg2rh2as0g] {
    background: rgba(37, 99, 235, 0.08);
    color: #1d4ed8;
}

.projection-grid .grp-customer[b-fg2rh2as0g] {
    background: rgba(217, 119, 6, 0.10);
    color: #b45309;
}

.projection-grid th.grp-customer-col[b-fg2rh2as0g] {
    background: rgba(217, 119, 6, 0.06);
}

.projection-grid td.grp-customer-col[b-fg2rh2as0g] {
    background: rgba(217, 119, 6, 0.03);
}

/* Compact "apply to all customers of this article" button on Support / RRP cells. */
.fill-all-btn[b-fg2rh2as0g] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 20px;
    height: 20px;
    padding: 0;
    flex-shrink: 0;
    border: 1px solid var(--border-color, #ccd2da);
    border-radius: 4px;
    background: var(--bs-body-bg, #fff);
    color: var(--bs-secondary-color, #6b7280);
    cursor: pointer;
    line-height: 1;
}

.fill-all-btn:hover[b-fg2rh2as0g] {
    background: rgba(37, 99, 235, 0.10);
    border-color: rgba(37, 99, 235, 0.55);
    color: #1d4ed8;
}

.fill-all-btn:disabled[b-fg2rh2as0g] {
    opacity: 0.45;
    cursor: default;
}

.fill-all-btn svg[b-fg2rh2as0g] {
    width: 12px;
    height: 12px;
    fill: none;
    stroke: currentColor;
    stroke-width: 2;
    stroke-linecap: round;
    stroke-linejoin: round;
}

/* ── Timeline overview: product rows × week columns, campaign blocks tinted ── */
.ovw-scroll[b-fg2rh2as0g] {
    overflow-x: auto;
}

.ovw-grid[b-fg2rh2as0g] {
    border-collapse: separate;
    border-spacing: 0;
    width: max-content;
    min-width: 100%;
    font-size: 0.8rem;
}

.ovw-grid th[b-fg2rh2as0g],
.ovw-grid td[b-fg2rh2as0g] {
    border-right: 1px solid var(--border-color, #e5e7eb);
    border-bottom: 1px solid var(--border-color, #e5e7eb);
    padding: 3px 6px;
    text-align: center;
    white-space: nowrap;
}

.ovw-grid .ovw-wk[b-fg2rh2as0g] {
    min-width: 42px;
    font-weight: 600;
    color: var(--bs-secondary-color, #6b7280);
    background: var(--bs-tertiary-bg, #f8f9fa);
}

.ovw-grid .ovw-month[b-fg2rh2as0g] {
    font-weight: 600;
    background: var(--bs-tertiary-bg, #f8f9fa);
    color: var(--bs-secondary-color, #6b7280);
    letter-spacing: 0.03em;
}

/* Product label column pinned while the timeline scrolls sideways. */
.ovw-grid .ovw-prod[b-fg2rh2as0g] {
    position: sticky;
    left: 0;
    z-index: 2;
    background: var(--bs-body-bg, #fff);
    text-align: left;
    min-width: 170px;
    max-width: 220px;
    border-right: 2px solid var(--border-color, #d1d5db);
}

.ovw-grid thead .ovw-prod[b-fg2rh2as0g] {
    z-index: 3;
    background: var(--bs-tertiary-bg, #f8f9fa);
}

.ovw-grid .ovw-prod-art[b-fg2rh2as0g] {
    font-weight: 600;
}

.ovw-grid .ovw-prod-name[b-fg2rh2as0g] {
    font-size: 0.72rem;
    color: var(--bs-secondary-color, #6b7280);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    max-width: 210px;
}

.ovw-grid .ovw-prod-cust[b-fg2rh2as0g] {
    font-size: 0.74rem;
    font-weight: 600;
    color: #b45309;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    max-width: 210px;
}

/* Multi-select customer dropdown (native <details>; click-away handled globally in app.js). */
.ms-dd[b-fg2rh2as0g] {
    position: relative;
}

.ms-dd > summary[b-fg2rh2as0g] {
    list-style: none;
    cursor: pointer;
    min-width: 11rem;
    white-space: nowrap;
}

.ms-dd > summary[b-fg2rh2as0g]::-webkit-details-marker {
    display: none;
}

.ms-panel[b-fg2rh2as0g] {
    position: absolute;
    right: 0;
    z-index: 30;
    margin-top: 2px;
    background: var(--bs-body-bg, #fff);
    border: 1px solid var(--border-color, #dee2e6);
    border-radius: 8px;
    padding: 8px;
    min-width: 14rem;
    max-height: 320px;
    overflow: auto;
    box-shadow: 0 6px 16px rgba(0, 0, 0, 0.12);
}

.ms-actions[b-fg2rh2as0g] {
    display: flex;
    align-items: center;
    padding-bottom: 6px;
    margin-bottom: 4px;
    border-bottom: 1px solid var(--border-color, #eee);
}

.ms-item[b-fg2rh2as0g] {
    display: block;
    font-size: 0.85rem;
    padding: 2px 0;
    cursor: pointer;
}

.ms-item input[b-fg2rh2as0g] {
    margin-right: 6px;
}

/* Campaign block vs the ordinary stretch between campaigns. Each campaign block carries a
   leading divider and alternates its tint so two adjacent campaigns stay distinct. */
.ovw-grid td.ovw-camp[b-fg2rh2as0g] {
    background: rgba(37, 99, 235, 0.12);
    color: #1d4ed8;
    font-weight: 600;
    border-left: 2px solid rgba(37, 99, 235, 0.55);
}

.ovw-grid td.ovw-camp.ovw-camp-alt[b-fg2rh2as0g] {
    background: rgba(37, 99, 235, 0.24);
}

.ovw-grid td.ovw-ord[b-fg2rh2as0g] {
    color: var(--bs-secondary-color, #6b7280);
}

.ovw-grid td.ovw-clickable[b-fg2rh2as0g] {
    cursor: pointer;
}

.ovw-grid td.ovw-clickable:hover[b-fg2rh2as0g] {
    outline: 2px solid rgba(37, 99, 235, 0.8);
    outline-offset: -2px;
}

/* Flash the worksheet line jumped to from the overview, fading back to normal. */
tr.ws-hl > td[b-fg2rh2as0g] {
    animation: ws-flash-b-fg2rh2as0g 2.4s ease-out 1;
}

@keyframes ws-flash-b-fg2rh2as0g {
    0% { background-color: rgba(244, 63, 94, 0.40); }
    100% { background-color: transparent; }
}
/* /Components/Pages/Projections/Details.razor.rz.scp.css */
/* Worksheet grid — Trophyst campaign-table header style + vertical field separators. */
.projection-grid[b-kilr4bi1hg] {
    font-size: 12.6px;
    width: 100%;
}

.projection-grid th[b-kilr4bi1hg] {
    font-size: 10.1px;
    text-transform: uppercase;
    letter-spacing: 0.02em;
    font-weight: 600;
    color: var(--text-secondary, #4b5563);
    white-space: normal;      /* multi-line headers */
    line-height: 1.15;
    padding: 0.3rem 0.4rem;
    vertical-align: bottom;
    border-bottom: 2px solid var(--border-color, #dbe1ea);
    border-right: 1px solid var(--border-color, #e5e9f0);
}

.projection-grid td[b-kilr4bi1hg] {
    padding: 0.25rem 0.35rem;
    vertical-align: middle;
    border-right: 1px solid var(--border-color, #e5e9f0);
}

.projection-grid th:last-child[b-kilr4bi1hg],
.projection-grid td:last-child[b-kilr4bi1hg] {
    border-right: 0;
}

.projection-grid thead[b-kilr4bi1hg] {
    position: sticky;
    top: 0;
    z-index: 5;
}

.projection-grid tbody tr:hover[b-kilr4bi1hg] {
    background-color: rgba(37, 99, 235, 0.05);
}

/* Compact inputs so the grid rows stay tight */
.projection-grid input.form-control-sm[b-kilr4bi1hg] {
    padding: 0.15rem 0.3rem;
    font-size: 11.9px;
}

/* No spinner buttons — arrow keys navigate the grid, typing edits the value */
.projection-grid input[type="number"][b-kilr4bi1hg]::-webkit-outer-spin-button,
.projection-grid input[type="number"][b-kilr4bi1hg]::-webkit-inner-spin-button {
    -webkit-appearance: none;
    margin: 0;
}

.projection-grid input[type="number"][b-kilr4bi1hg] {
    -moz-appearance: textfield;
    appearance: textfield;
}

/* Perspective group banner + customer-group tinting */
.projection-grid .grp-row th[b-kilr4bi1hg] {
    text-align: center;
    font-size: 9.8px;
    letter-spacing: 0.06em;
    padding: 0.25rem 0.4rem;
    border-bottom: 1px solid var(--border-color, #dbe1ea);
    vertical-align: middle;
}

.projection-grid .grp-blank[b-kilr4bi1hg] {
    background: transparent;
    border-right: 0;
}

.projection-grid .grp-our[b-kilr4bi1hg] {
    background: rgba(37, 99, 235, 0.08);
    color: #1d4ed8;
}

.projection-grid .grp-customer[b-kilr4bi1hg] {
    background: rgba(217, 119, 6, 0.10);
    color: #b45309;
}

.projection-grid th.grp-customer-col[b-kilr4bi1hg] {
    background: rgba(217, 119, 6, 0.06);
}

.projection-grid td.grp-customer-col[b-kilr4bi1hg] {
    background: rgba(217, 119, 6, 0.03);
}

/* ── Overview tab: product rows × week columns, campaign blocks tinted ── */
.ovw-scroll[b-kilr4bi1hg] { overflow-x: auto; }

.ovw-grid[b-kilr4bi1hg] {
    border-collapse: separate;
    border-spacing: 0;
    width: max-content;
    min-width: 100%;
    font-size: 0.8rem;
}

.ovw-grid th[b-kilr4bi1hg],
.ovw-grid td[b-kilr4bi1hg] {
    border-right: 1px solid var(--border-color, #e5e7eb);
    border-bottom: 1px solid var(--border-color, #e5e7eb);
    padding: 3px 6px;
    text-align: center;
    white-space: nowrap;
}

.ovw-grid .ovw-wk[b-kilr4bi1hg] {
    min-width: 42px;
    font-weight: 600;
    color: var(--bs-secondary-color, #6b7280);
    background: var(--bs-tertiary-bg, #f8f9fa);
}

.ovw-grid .ovw-month[b-kilr4bi1hg] {
    font-weight: 600;
    background: var(--bs-tertiary-bg, #f8f9fa);
    color: var(--bs-secondary-color, #6b7280);
    letter-spacing: 0.03em;
}

.ovw-grid .ovw-prod[b-kilr4bi1hg] {
    position: sticky;
    left: 0;
    z-index: 2;
    background: var(--bs-body-bg, #fff);
    text-align: left;
    min-width: 170px;
    max-width: 220px;
    border-right: 2px solid var(--border-color, #d1d5db);
}

.ovw-grid thead .ovw-prod[b-kilr4bi1hg] {
    z-index: 3;
    background: var(--bs-tertiary-bg, #f8f9fa);
}

.ovw-grid .ovw-prod-art[b-kilr4bi1hg] { font-weight: 600; }

.ovw-grid .ovw-prod-name[b-kilr4bi1hg] {
    font-size: 0.72rem;
    color: var(--bs-secondary-color, #6b7280);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    max-width: 210px;
}

.ovw-grid .ovw-prod-cust[b-kilr4bi1hg] {
    font-size: 0.74rem;
    font-weight: 600;
    color: #b45309;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    max-width: 210px;
}

.ovw-grid td.ovw-camp[b-kilr4bi1hg] {
    background: rgba(37, 99, 235, 0.12);
    color: #1d4ed8;
    font-weight: 600;
    border-left: 2px solid rgba(37, 99, 235, 0.55);
}

.ovw-grid td.ovw-camp.ovw-camp-alt[b-kilr4bi1hg] { background: rgba(37, 99, 235, 0.24); }

.ovw-grid td.ovw-ord[b-kilr4bi1hg] { color: var(--bs-secondary-color, #6b7280); }

/* Multi-select filter dropdown (native <details>; click-away handled globally in app.js). */
.ms-dd[b-kilr4bi1hg] { position: relative; }

.ms-dd > summary[b-kilr4bi1hg] {
    list-style: none;
    cursor: pointer;
    min-width: 10rem;
    white-space: nowrap;
}

.ms-dd > summary[b-kilr4bi1hg]::-webkit-details-marker { display: none; }

.ms-panel[b-kilr4bi1hg] {
    position: absolute;
    right: 0;
    z-index: 30;
    margin-top: 2px;
    background: var(--bs-body-bg, #fff);
    border: 1px solid var(--border-color, #dee2e6);
    border-radius: 8px;
    padding: 8px;
    min-width: 14rem;
    max-height: 320px;
    overflow: auto;
    box-shadow: 0 6px 16px rgba(0, 0, 0, 0.12);
}

.ms-actions[b-kilr4bi1hg] {
    display: flex;
    align-items: center;
    padding-bottom: 6px;
    margin-bottom: 4px;
    border-bottom: 1px solid var(--border-color, #eee);
}

.ms-item[b-kilr4bi1hg] {
    display: block;
    font-size: 0.85rem;
    padding: 2px 0;
    cursor: pointer;
}

.ms-item input[b-kilr4bi1hg] { margin-right: 6px; }

/* ── KPI strip ─────────────────────────────────────────────────────────────
   Five figures across the head of the plan. A grid rather than a wrapping flex row so they hold
   equal widths whatever the viewer's permissions leave visible — a planner who cannot see margin
   gets three cards that fill the row, not three chips and a gap. */
.prj-kpis[b-kilr4bi1hg] {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(215px, 1fr));
    gap: 0.75rem;
}

.prj-kpi[b-kilr4bi1hg] {
    display: flex;
    align-items: center;
    gap: 0.8rem;
    padding: 0.8rem 0.9rem;
    background: var(--bg-card);
    border: 1px solid var(--border-color);
    border-radius: var(--border-radius, 10px);
    box-shadow: var(--shadow-sm);
}

.prj-kpi-icon[b-kilr4bi1hg] {
    flex: 0 0 auto;
    width: 42px;
    height: 42px;
    border-radius: 12px;
    display: grid;
    place-items: center;
    background: color-mix(in srgb, var(--kpi-tint) 14%, transparent);
    color: var(--kpi-tint);
}

.prj-kpi-icon svg[b-kilr4bi1hg] {
    width: 21px;
    height: 21px;
}

/* min-width:0 so a long figure ellipsises inside the card instead of forcing the grid wider. */
.prj-kpi-body[b-kilr4bi1hg] {
    min-width: 0;
}

.prj-kpi-label[b-kilr4bi1hg] {
    font-size: 0.78rem;
    line-height: 1.2;
    color: var(--text-secondary);
}

/* Scales with the viewport so "7,486,060 EUR" stays on one line on a laptop and still reads big
   on a wide screen — the display face and the negative tracking are what make it read as a
   headline rather than as bold body text. */
.prj-kpi-value[b-kilr4bi1hg] {
    font-family: var(--font-display);
    font-size: clamp(1.15rem, 0.95rem + 0.55vw, 1.5rem);
    font-weight: 700;
    letter-spacing: -0.015em;
    line-height: 1.2;
    color: var(--text-strong);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.prj-kpi-sub[b-kilr4bi1hg] {
    font-size: 0.72rem;
    line-height: 1.25;
    color: var(--text-muted);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* One hue per figure, so the strip is scannable by colour before it is read. Lifted on dark for
   the same reason the accent is — the light-mode hues go muddy on the ember ground. */
.prj-kpi-turnover[b-kilr4bi1hg]  { --kpi-tint: #2563eb; }
.prj-kpi-marginpct[b-kilr4bi1hg] { --kpi-tint: #d97706; }
.prj-kpi-marginval[b-kilr4bi1hg] { --kpi-tint: #059669; }
.prj-kpi-support[b-kilr4bi1hg]   { --kpi-tint: #e11d48; }
.prj-kpi-roi[b-kilr4bi1hg]       { --kpi-tint: #7c3aed; }

[data-theme="dark"] .prj-kpi-turnover[b-kilr4bi1hg]  { --kpi-tint: #60a5fa; }
[data-theme="dark"] .prj-kpi-marginpct[b-kilr4bi1hg] { --kpi-tint: #f0b155; }
[data-theme="dark"] .prj-kpi-marginval[b-kilr4bi1hg] { --kpi-tint: #4ec99a; }
[data-theme="dark"] .prj-kpi-support[b-kilr4bi1hg]   { --kpi-tint: #f2748c; }
[data-theme="dark"] .prj-kpi-roi[b-kilr4bi1hg]       { --kpi-tint: #a98cf0; }

/* ── Tab strip with the plan-wide actions on it ────────────────────────────
   The rule belongs to the row, not to the <ul>: the buttons take the right-hand end, and a rule
   drawn by .nav-tabs would stop where the tabs stop and leave the card below joined to nothing.
   The tab links keep Bootstrap's -1px pull, so the active one still sits over this border. */
.prj-tabbar[b-kilr4bi1hg] {
    border-bottom: 1px solid var(--border-color);
}

.prj-tabbar-actions[b-kilr4bi1hg] {
    padding-bottom: 0.4rem;
}
/* /Components/Pages/Projections/Outcome.razor.rz.scp.css */
/* ── Agreement map: projection on top, agreements hanging under it (pure CSS org chart) ── */

.po-map[b-rsyabbt38e] {
    text-align: center;
}

.po-root[b-rsyabbt38e] {
    display: flex;
    flex-direction: column;
    align-items: center;
}

.po-node[b-rsyabbt38e] {
    display: inline-flex;
    flex-direction: column;
    gap: 2px;
    padding: 0.6rem 1rem;
    background: var(--bg-card, #fff);
    border: 1px solid var(--border-color, #dee2e6);
    border-radius: 10px;
    text-decoration: none;
    color: inherit;
    text-align: left;
    box-shadow: 0 1px 2px rgba(0, 0, 0, .06);
}

.po-node-projection[b-rsyabbt38e] {
    border-top: 4px solid var(--accent, #2563eb);
    align-items: center;
    text-align: center;
}

.po-stem[b-rsyabbt38e] {
    width: 2px;
    height: 1.5rem;
    background: var(--border-color, #dee2e6);
}

.po-branches[b-rsyabbt38e] {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 0 1rem;
    list-style: none;
    margin: 0;
    padding: 0;
}

.po-branch[b-rsyabbt38e] {
    position: relative;
    padding-top: 1.5rem;
    margin-bottom: 1rem;
}

/* vertical stub up from each card */
.po-branch[b-rsyabbt38e]::before {
    content: "";
    position: absolute;
    top: 0;
    left: 50%;
    width: 2px;
    height: 1.5rem;
    background: var(--border-color, #dee2e6);
}

/* horizontal rail across the row of cards */
.po-branch[b-rsyabbt38e]::after {
    content: "";
    position: absolute;
    top: 0;
    left: -0.5rem;
    right: -0.5rem;
    height: 2px;
    background: var(--border-color, #dee2e6);
}

.po-branch:first-child[b-rsyabbt38e]::after { left: 50%; }
.po-branch:last-child[b-rsyabbt38e]::after { right: 50%; }
.po-branch:only-child[b-rsyabbt38e]::after { display: none; }

a.po-node-agreement:hover[b-rsyabbt38e] {
    transform: translateY(-1px);
    box-shadow: 0 4px 10px rgba(0, 0, 0, .10);
}

.po-node-agreement[b-rsyabbt38e] {
    border-left: 4px solid var(--accent, #2563eb);
    min-width: 200px;
    transition: transform .1s ease, box-shadow .1s ease;
}

.po-node-pending[b-rsyabbt38e] {
    opacity: .55;
    border-style: dashed;
}

.po-node-number[b-rsyabbt38e] {
    font-weight: 700;
    font-size: 11.9px;
}

.po-node-title[b-rsyabbt38e] {
    font-weight: 600;
}

.po-node-cust[b-rsyabbt38e] {
    font-size: 11.2px;
}

.po-node-meta[b-rsyabbt38e],
.po-node-committed[b-rsyabbt38e] {
    font-size: 10.1px;
    color: var(--text-muted, #6c757d);
}

.po-node-agreement .badge[b-rsyabbt38e] {
    align-self: flex-start;
}

/* Dense mode — kicks in automatically above ~12 agreements so a full-year projection
   with 70–80 boxes still reads as a tree. */
.po-dense[b-rsyabbt38e] {
    gap: 0 0.5rem;
}

.po-dense .po-branch[b-rsyabbt38e] {
    padding-top: 1rem;
    margin-bottom: 0.5rem;
}

.po-dense .po-branch[b-rsyabbt38e]::before {
    height: 1rem;
}

.po-dense .po-node-agreement[b-rsyabbt38e] {
    min-width: 140px;
    padding: 0.35rem 0.6rem;
    gap: 1px;
}

.po-dense .po-node-number[b-rsyabbt38e] {
    font-size: 10.5px;
}

.po-dense .po-node-cust[b-rsyabbt38e] {
    font-size: 10.1px;
}

.po-dense .po-node-committed[b-rsyabbt38e] {
    font-size: 9.1px;
}

.po-dense .po-node-agreement .badge[b-rsyabbt38e] {
    font-size: 7.7px !important;
}

@media (max-width: 768px) {
    .po-branches[b-rsyabbt38e] {
        flex-direction: column;
        align-items: center;
    }

    .po-branch[b-rsyabbt38e]::after {
        display: none;
    }
}
/* /Components/Pages/Projections/RrpPlanning.razor.rz.scp.css */
/* The price grid. Fifty-two columns of number, so every pixel of chrome is one the numbers do not
   get — the cells carry no borders of their own beyond a hairline, and the week rules do the work
   of separating them. */
.rrp-scroll[b-ww0nfi2h5q] {
    overflow-x: auto;
    max-height: 70vh;
    overflow-y: auto;
}

/* Sized to its contents and no wider. min-width:100% was the mistake here: with 52 columns and a
   wide screen the browser had a thousand spare pixels to hand out, so every cell grew to four
   centimetres and a year became two metres of side-scrolling. A week column is now as wide as the
   number it holds. */
.rrp-grid[b-ww0nfi2h5q] {
    border-collapse: separate;
    border-spacing: 0;
    width: max-content;
    /* The same size the SOA tab reads at. The week columns pay for it in width — a five-digit
       price needs the room — and the year scrolls a little further as a result. Worth it: two
       tabs over one list that render at two different sizes read as two different tools. */
    font-size: 0.875rem;
}

.rrp-grid th[b-ww0nfi2h5q],
.rrp-grid td[b-ww0nfi2h5q] {
    border-right: 1px solid var(--border-subtle);
    border-bottom: 1px solid var(--border-subtle);
    padding: 0;
    white-space: nowrap;
}

/* The identifying columns stay put while the year scrolls past them — without this the grid is
   unusable two months in, because a column of numbers with no name against it says nothing. Five
   three of them: what identifies a product. Brand and department fold away with the rest, because
   they are read now and then rather than worked with. Each is sticky at its own offset, so the
   widths below and the lefts have to stay in step. */
.rrp-fix[b-ww0nfi2h5q] {
    position: sticky;
    z-index: 2;
    background: var(--bg-card);
    text-align: left;
    padding: 3px 8px;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* The lefts are this grid's business; the WIDTHS are shared with the SOA tab (.rrp-c-* below),
   so the first four columns line up between the two views instead of each finding its own size —
   one too wide here, too narrow there. */
.rrp-f0[b-ww0nfi2h5q] { left: 0; padding: 3px 4px; text-align: center; }
.rrp-f1[b-ww0nfi2h5q] { left: 30px; }
.rrp-f2[b-ww0nfi2h5q] { left: 150px; }
.rrp-f3[b-ww0nfi2h5q] {
    left: 390px;
    border-right: 2px solid var(--border-color);
}

/* ── The four columns both tabs share ── */
.rrp-c-sel[b-ww0nfi2h5q]  { width: 30px;  min-width: 30px;  max-width: 30px; }
.rrp-c-art[b-ww0nfi2h5q]  { width: 120px; min-width: 120px; max-width: 120px; }
.rrp-c-prod[b-ww0nfi2h5q] { width: 240px; min-width: 240px; max-width: 240px; }
.rrp-c-cat[b-ww0nfi2h5q]  { width: 120px; min-width: 120px; max-width: 120px; }

/* A row's identity is not an emphasis. These are <th> in the grid because they label the row for
   a screen reader, which is a semantic, not an instruction to embolden them. */
.rrp-grid tbody th[b-ww0nfi2h5q] { font-weight: 400; }

/* The corner cell: sticky in both directions like the columns under it, but sized by them rather
   than by itself, so it can span the four and hold the control that folds the next six. */
/* Written as .rrp-grid thead .rrp-corner, not as .rrp-corner: ".rrp-grid thead th" below is the
   more specific selector and was winning the z-index, so the corner sat at 3 with the month
   headings and lost to them on document order — January slid over the button as the year
   scrolled. Every rule here that has to beat that one is qualified the same way. */
.rrp-grid thead .rrp-corner[b-ww0nfi2h5q] {
    position: sticky;
    left: 0;
    z-index: 5;
    background: var(--bg-subtle);
    text-align: left;
    padding: 2px 6px;
}

/* Small enough not to grow the row it sits in. */
.rrp-check[b-ww0nfi2h5q] { width: 13px; height: 13px; margin: 0; vertical-align: middle; cursor: pointer; }

/* The band a line follows, in the band's own colour. */
.rrp-band-dot[b-ww0nfi2h5q] {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    flex-shrink: 0;
    display: inline-block;
}

/* The attributes are reference, not the point — they read one step quieter than the name. */
.rrp-attr[b-ww0nfi2h5q] { color: var(--text-secondary); }

.rrp-grid thead th[b-ww0nfi2h5q] {
    position: sticky;
    z-index: 3;
    background: var(--bg-subtle);
    font-weight: 600;
    color: var(--text-secondary);
    text-align: center;
    padding: 2px 4px;
}

.rrp-months th[b-ww0nfi2h5q] { top: 0; }
.rrp-weeknos th[b-ww0nfi2h5q] { top: 22px; }

/* The corner: sticky in both directions, so it sits above both the month row and the names. */
/* Left, not centred: these three head columns of text, and the SOA tab sets them the same way.
   The centring above is meant for the week and month headings, which sit over numbers. The
   checkbox column keeps it, because what it heads is centred too. */
.rrp-grid thead .rrp-fix[b-ww0nfi2h5q] {
    z-index: 4;
    background: var(--bg-subtle);
    text-align: left;
}

.rrp-grid thead .rrp-f0[b-ww0nfi2h5q] { text-align: center; }

.rrp-months th[b-ww0nfi2h5q] { font-size: 0.8rem; letter-spacing: 0.03em; }
.rrp-weeknos th.rrp-fix[b-ww0nfi2h5q] { font-size: 0.78rem; color: var(--text-secondary); }

/* Room for five digits and a thousands separator — "19 990" — and not a character more. Wider
   than it was, because the cells inside now render at the shared size. */
.rrp-weeknos th:not(.rrp-fix)[b-ww0nfi2h5q] {
    font-size: 0.75rem;
    color: var(--text-muted);
    width: 66px;
    min-width: 66px;
    max-width: 66px;
}

.rrp-cell[b-ww0nfi2h5q] { width: 66px; }

.rrp-prod[b-ww0nfi2h5q] { display: flex; align-items: center; gap: 6px; }

.rrp-prod-name[b-ww0nfi2h5q] {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.rrp-remove[b-ww0nfi2h5q] {
    margin-left: auto;
    padding: 0 4px;
    line-height: 1;
    font-size: 1rem;
    text-decoration: none;
    opacity: 0;
}

.rrp-grid tbody tr:hover .rrp-remove[b-ww0nfi2h5q] { opacity: 1; }

/* ── The cells ──
   An input with no chrome at all: the grid is the chrome, and 52 bordered boxes a row would be a
   wall. It gains an outline only when it has focus. */
.rrp-input[b-ww0nfi2h5q] {
    width: 100%;
    min-width: 0;
    border: 0;
    background: transparent;
    padding: 3px 4px;
    text-align: right;
    font-size: 0.875rem;
    font-variant-numeric: tabular-nums;
    color: inherit;
}

.rrp-input:focus[b-ww0nfi2h5q] {
    outline: 2px solid var(--accent);
    outline-offset: -2px;
    background: var(--bg-card);
}

/* Three states, and the order of the colours is the order of the work. Red is a price nobody but
   the planner has seen. Amber is one that has been handed over and is somebody else's to answer.
   Confirmed is plain — the absence of a colour is what "settled" looks like, and it is the state
   most of a finished sheet should be in.

   Amber rather than a second red, because "sent" is not a problem: a planner scanning a column
   wants the reds, which are still theirs, to be the only thing that shouts. */
.rrp-unconfirmed[b-ww0nfi2h5q] { color: #c0392b; }
.rrp-sent[b-ww0nfi2h5q] { color: #b26a00; }
.rrp-ok[b-ww0nfi2h5q] { color: var(--text-primary); }

/* Late is a third fact, and the cell already spends its text colour on confirmation and its
   background on the kind of price. So it gets an edge — visible down a column, and it cannot
   collide with either of the other two. */
.rrp-overdue[b-ww0nfi2h5q] { box-shadow: inset 2px 0 0 #c0392b; }

/* ── One tint, one meaning ─────────────────────────────────────────────────
   Four grades against the base price used to colour every cell in the sheet, with a legend under
   it to decode them — which made an ordinary year a quilt and gave the eye nowhere to land. The
   only cell worth finding is the one priced UNDER the campaign price: that is a cut the margin
   groups were never agreed against, and where the margin control stops telling the truth until an
   exception says what we will actually fund. So that cell alone is pink, and a white grid with a
   few pink cells needs no key. */
.rrp-deep[b-ww0nfi2h5q] { background: color-mix(in srgb, #e0518a 16%, transparent); }

[data-theme="dark"] .rrp-unconfirmed[b-ww0nfi2h5q] { color: #f08a7f; }
[data-theme="dark"] .rrp-sent[b-ww0nfi2h5q] { color: #e0a33c; }
[data-theme="dark"] .rrp-overdue[b-ww0nfi2h5q] { box-shadow: inset 2px 0 0 #f08a7f; }
[data-theme="dark"] .rrp-deep[b-ww0nfi2h5q] { background: color-mix(in srgb, #f07ba8 20%, transparent); }

/* ── Picking cells out ─────────────────────────────────────────────────────
   Excel's gesture and, as far as possible, Excel's look: the picked block is a wash with a border,
   not a colour of its own, so it reads as "these ones" over whatever the cells already say. */
.rrp-wk-head[b-ww0nfi2h5q] { user-select: none; }
.rrp-picking .rrp-wk-head[b-ww0nfi2h5q] { cursor: cell; }
.rrp-picking .rrp-wk-head:hover[b-ww0nfi2h5q] { color: var(--text-primary); }

/* ── Selection mode ────────────────────────────────────────────────────────
   The inputs stop taking the pointer entirely. That is the whole reason the mode exists: while a
   click could land on a price input, the browser was placing a caret and extending a text
   selection at the same time as we were trying to read a click, and a hair of movement between
   press and release made it a drag that fired no click at all. Inert inputs leave exactly one
   thing a click can mean. */
.rrp-picking .rrp-input[b-ww0nfi2h5q] {
    pointer-events: none;
    background: transparent;
    cursor: cell;
}

.rrp-picking td[b-ww0nfi2h5q] { cursor: cell; }
.rrp-picking[b-ww0nfi2h5q] { user-select: none; }

/* A single picked cell has to be as findable as a picked column, and a hairline outline on one
   66px cell among fifty-two was not: the count in the bar went up and the planner could not see
   which cell had done it. Wash and a real border, the way a spreadsheet marks a selection. */
.rrp-picked[b-ww0nfi2h5q] {
    box-shadow: inset 0 0 0 2px var(--accent, #2563eb);
    background-image: linear-gradient(color-mix(in srgb, #2563eb 14%, transparent),
                                      color-mix(in srgb, #2563eb 14%, transparent));
}
.rrp-grid thead .rrp-picked-head[b-ww0nfi2h5q] {
    background: color-mix(in srgb, #2563eb 16%, var(--bg-subtle));
    color: var(--text-primary);
}

/* The cell the panel on the right is describing. One at a time, so it can afford to be solid. */
.rrp-inspected[b-ww0nfi2h5q] { outline: 2px solid var(--accent, #2563eb); outline-offset: -2px; }

/* One frame, not two. Clicking a cell both inspects it (a ring on the cell) and focuses the input
   inside it (a ring of its own, two pixels in), which drew a box inside a box. The cell's ring is
   the one that survives: it is the same mark whether or not focus has since moved on, which is
   what the panel on the right is describing. An input reached by the arrow keys without a click
   still gets its own ring — there is no cell ring to collide with there. */
.rrp-inspected .rrp-input:focus[b-ww0nfi2h5q] { outline: none; }

/* ── Where an exception is set ─────────────────────────────────────────────
   A corner flag rather than a background: the background is already saying whether the price is
   under the campaign, and these two facts travel together — an exception usually exists BECAUSE
   the cell is pink — so they must be readable at once rather than overwriting each other. */
.rrp-exc[b-ww0nfi2h5q] { position: relative; }
.rrp-exc[b-ww0nfi2h5q]::after {
    content: "";
    position: absolute;
    top: 0;
    right: 0;
    border-top: 7px solid #7a3fa0;
    border-left: 7px solid transparent;
}

.rrp-grid thead .rrp-exc-head[b-ww0nfi2h5q] { box-shadow: inset 0 -2px 0 #7a3fa0; }

/* ── The product detail panel ──────────────────────────────────────────────
   Folded away by default: these are set once per product and then left alone, while the weeks are
   worked in every day. They sit between the name and the year so they scroll away with the weeks
   rather than eating the sticky column. */
/* It replaced the column heading, so it has to read as a control rather than as a label. */
.rrp-grid .rrp-detail[b-ww0nfi2h5q] {
    width: 96px;
    min-width: 96px;
    max-width: 96px;
    text-align: center;
    padding: 1px 3px;
}

.rrp-grid thead .rrp-detail[b-ww0nfi2h5q] { background: var(--bg-subtle); }

/* A tint down the panel so the eye knows where the year starts. */
.rrp-grid tbody .rrp-detail[b-ww0nfi2h5q] { background: color-mix(in srgb, var(--bg-subtle) 55%, transparent); }

/* The two price inputs used to be a size down and left-aligned, from when they lived in a folded
   detail panel. They are money in a column of money now: same size as every other figure, and
   ranged right with them. */
.rrp-detail-input[type="date"][b-ww0nfi2h5q] { padding: 2px; }

/* The marker chips carry their own colour, set inline from the marker. */
.rrp-marker[b-ww0nfi2h5q] {
    width: 100%;
    border: 1px solid var(--border-color);
    border-radius: 4px;
    background: transparent;
    font-size: 0.8rem;
    padding: 1px 2px;
    color: var(--text-primary);
}

/* ── The weeks a selected calendar block covers ────────────────────────────
   An OUTLINE rather than a background or an inset shadow, because both of those are already
   spoken for — the background says what kind of price a cell holds and the inset shadow says it is
   past its confirmation date. Outline is the one channel left, and it reads as a frame around the
   period rather than as another property of the price. */
.rrp-lit[b-ww0nfi2h5q] {
    outline: 2px solid color-mix(in srgb, var(--accent) 60%, transparent);
    outline-offset: -2px;
}

.rrp-weeknos th.rrp-lit-head[b-ww0nfi2h5q] {
    background: var(--accent);
    color: var(--text-on-accent);
    font-weight: 700;
}

/* What is lit, and how to stop. Sits under the calendar so it reads as part of it. */
.rrp-selbar[b-ww0nfi2h5q] {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-top: 8px;
    padding: 5px 10px;
    border-radius: var(--border-radius-sm, 6px);
    background: var(--accent-light);
    font-size: 0.78rem;
}

.rrp-selbar-dot[b-ww0nfi2h5q] {
    width: 9px;
    height: 9px;
    border-radius: 50%;
    flex-shrink: 0;
}

/* ── The Excel menu ──────────────────────────────────────────────────────
   Hand-rolled rather than Bootstrap's: this application ships Bootstrap's CSS but not its
   JavaScript, and the user menu in the header solves it the same way — a flag, a backdrop that
   catches the click outside, and an absolutely positioned list. */
.rrp-menu[b-ww0nfi2h5q] { position: relative; }

.rrp-menu-caret[b-ww0nfi2h5q] { font-size: 0.7rem; opacity: 0.7; }

.rrp-menu-backdrop[b-ww0nfi2h5q] {
    position: fixed;
    inset: 0;
    z-index: 1040;
}

.rrp-menu-list[b-ww0nfi2h5q] {
    position: absolute;
    right: 0;
    top: calc(100% + 0.35rem);
    z-index: 1041;
    min-width: 15rem;
    background: var(--bg-elevated);
    border: 1px solid var(--border-color);
    border-radius: 10px;
    box-shadow: var(--shadow-md);
    padding: 0.35rem;
}

.rrp-menu-item[b-ww0nfi2h5q] {
    display: block;
    width: 100%;
    text-align: left;
    border: 0;
    background: none;
    border-radius: 6px;
    padding: 0.4rem 0.6rem;
    font-size: 0.82rem;
    color: var(--text-primary);
    cursor: pointer;
}

.rrp-menu-item:hover:not(:disabled)[b-ww0nfi2h5q] { background: var(--bg-subtle); }
.rrp-menu-item:disabled[b-ww0nfi2h5q] { opacity: 0.5; cursor: default; }

.rrp-menu-note[b-ww0nfi2h5q] {
    padding: 0.4rem 0.6rem 0.2rem;
    font-size: 0.72rem;
    color: var(--text-muted);
    border-top: 1px solid var(--border-subtle);
    margin-top: 0.3rem;
}

/* ── The two tabs ──────────────────────────────────────────────────────── */
/* The body sits flush under the tab strip, so the two read as one panel rather than a strip and
   a card that happen to be near each other. */
/* ── The tab strip and the cell inspector that shares its line ─────────────
   The panel sits level with the tabs, hard right. A reader clicking down a column keeps their eye
   at the top of the sheet; a panel under the grid would be below the fold on every screen the
   grid is worth filling. It has to survive being empty, so it holds its height. */
.rrp-tabrow[b-ww0nfi2h5q] {
    display: flex;
    align-items: flex-end;
    gap: 1rem;
    flex-wrap: wrap;
}

.rrp-tabrow .nav-tabs[b-ww0nfi2h5q] { flex: 0 0 auto; border-bottom: 0; }

/* Sits on the tabs' line rather than above the grid: it changes what the grid DOES, so it belongs
   where the grid is chosen, and it must be findable again to get back out. */
.rrp-pickbtn[b-ww0nfi2h5q] { flex: 0 0 auto; margin-bottom: 6px; white-space: nowrap; }

/* One line, and it stays one line. The parts are ordered by how much they are worth: the name and
   week say WHICH cell, the three figures are the answer, and the working is context. Only the two
   text ends may shrink, the working first and hardest — a truncated explanation is a small loss,
   a truncated margin is a wrong number. */
.rrp-inspector[b-ww0nfi2h5q] {
    flex: 1 1 22rem;
    min-width: 0;
    display: flex;
    align-items: baseline;
    flex-wrap: nowrap;
    white-space: nowrap;
    overflow: hidden;
    gap: 12px;
    min-height: 34px;
    padding: 6px 10px;
    font-size: 0.8rem;
    border-bottom: 1px solid var(--border-color);
}

.rrp-insp-name[b-ww0nfi2h5q] { flex: 0 1 auto; min-width: 3rem; overflow: hidden; text-overflow: ellipsis; }
.rrp-insp-wk[b-ww0nfi2h5q] { flex: 0 0 auto; color: var(--text-secondary); }

.rrp-insp-exc[b-ww0nfi2h5q] {
    flex: 0 0 auto;
    font-size: 0.65rem;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    font-weight: 700;
    color: #7a3fa0;
    border: 1px solid currentColor;
    border-radius: 3px;
    padding: 0 4px;
}

.rrp-insp-fig[b-ww0nfi2h5q] { flex: 0 0 auto; display: inline-flex; align-items: baseline; gap: 5px; }

.rrp-insp-lbl[b-ww0nfi2h5q] { color: var(--text-secondary); font-size: 0.72rem; }

.rrp-insp-val[b-ww0nfi2h5q] { font-weight: 600; font-variant-numeric: tabular-nums; }

/* The same two tints the perspective banners use, so a figure means the same thing wherever it
   is read on this page. */
.rrp-insp-our .rrp-insp-lbl[b-ww0nfi2h5q] { color: #1d4ed8; }
.rrp-insp-cust .rrp-insp-lbl[b-ww0nfi2h5q] { color: #b45309; }

.rrp-insp-note[b-ww0nfi2h5q] {
    flex: 0 3 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    color: var(--text-muted);
    font-size: 0.72rem;
}

.rrp-tabbody[b-ww0nfi2h5q] {
    border-top-left-radius: 0;
    border-top-right-radius: 0;
}

/* And the scroller inside it takes the same shape. app.css rounds all four corners of a
   .table-responsive that fills a card body — right for a card that is only a table, wrong under a
   tab strip: it clipped the SOA heading row's top corners, while the week grid's own scroller
   carries no radius and met the edge square. The two tabs were showing the same seam two ways.
   Square where the tabs meet it, rounded at the foot, in both. */
.rrp-tabbody > .card-body.p-0 > .table-responsive[b-ww0nfi2h5q],
.rrp-tabbody > .card-body.p-0 > .rrp-scroll[b-ww0nfi2h5q] {
    border-radius: 0 0 var(--border-radius) var(--border-radius);
}

.nav-tabs .nav-link[b-ww0nfi2h5q] { cursor: pointer; }

/* The SOA table is a plain table, not the week grid — no sticky columns, because sixteen columns
   fit where fifty-two do not. Its numbers line up the way the grid's do. */
.rrp-soa td[b-ww0nfi2h5q],
.rrp-soa th[b-ww0nfi2h5q] { white-space: nowrap; }

.rrp-soa td.text-end[b-ww0nfi2h5q],
.rrp-soa th.text-end[b-ww0nfi2h5q] { font-variant-numeric: tabular-nums; }

.rrp-soa .rrp-detail-input[b-ww0nfi2h5q] { width: 100%; }

/* Product carries no width on purpose — see the colgroup. It is the column that grows. */
.rrp-soa col:not([class])[b-ww0nfi2h5q] { width: auto; }

/* The house style shouts its table headings in small caps. Here that would put the SOA tab in a
   different voice from the week grid beside it, which is quieter — so inside this one table the
   headings read as words, at the grid's own size and weight. */
.rrp-soa > thead th[b-ww0nfi2h5q] {
    text-transform: none;
    letter-spacing: normal;
    font-size: 0.78rem;
    font-weight: 600;
    color: var(--text-secondary);
    background: var(--bg-subtle);
}

/* The same line under the header as the grid draws. */
.rrp-soa > thead[b-ww0nfi2h5q] { border-bottom: 1px solid var(--border-subtle); }

/* Sixteen columns do not fit a laptop, so the table scrolls rather than squeezing the names to
   nothing. Fixed layout, so the four shared columns keep the width the grid gives them. */
/* The sum of the widths below. Stated, because a fixed layout with no total stretches its
   columns to whatever the content wants — which is how this table ended up 30% wider than the
   grid it is supposed to line up with. */
.rrp-soa[b-ww0nfi2h5q] {
    table-layout: fixed;
    width: 100%;
    /* min-width is set inline: it depends on which optional columns are switched on. */
}

/* ── The two perspectives ──
   The same banner and the same tints the full-planning grid uses, because they are the same two
   ideas: what the line does to us, and what it does to the customer. A reader who knows one grid
   should not have to learn the other. */
.rrp-soa .grp-row th[b-ww0nfi2h5q] {
    font-size: 0.72rem;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    font-weight: 700;
    padding-top: 2px;
    padding-bottom: 2px;
}

/* The full-planning grids leave this stretch transparent. Here it sits directly opposite the
   week grid's month row, which is tinted — so it takes the same tint, and the banner row reads as
   a header in both tabs rather than as white space in one of them. */
.rrp-soa .grp-blank[b-ww0nfi2h5q] { background: var(--bg-subtle); border-right: 0; }
.rrp-soa .grp-our[b-ww0nfi2h5q] { background: rgba(37, 99, 235, 0.08); color: #1d4ed8; }
.rrp-soa .grp-customer[b-ww0nfi2h5q] { background: rgba(217, 119, 6, 0.10); color: #b45309; }
/* Both banners carry their colour down over the figures they head, at a fraction of the strength
   — enough to say where one perspective ends and the other begins as the eye runs along a row,
   not enough to compete with the numbers. The heading row takes the stronger of the two. */
.rrp-soa th.grp-our-col[b-ww0nfi2h5q] { background: rgba(37, 99, 235, 0.05); }
.rrp-soa td.grp-our-col[b-ww0nfi2h5q] { background: rgba(37, 99, 235, 0.025); }
.rrp-soa th.grp-customer-col[b-ww0nfi2h5q] { background: rgba(217, 119, 6, 0.06); }
.rrp-soa td.grp-customer-col[b-ww0nfi2h5q] { background: rgba(217, 119, 6, 0.03); }

/* The house's compact table sets its cells a size below what the week grid uses, which left the
   two price inputs — styled from the grid — visibly larger than the figures beside them. One size
   for every number on the page. */
.rrp-soa td[b-ww0nfi2h5q] { font-size: 0.875rem; }

.rrp-soa col.rrp-c-sel[b-ww0nfi2h5q]  { width: 30px; }
.rrp-soa col.rrp-c-art[b-ww0nfi2h5q]  { width: 120px; }
.rrp-soa col.rrp-c-cat[b-ww0nfi2h5q]  { width: 120px; }
.rrp-soa .rrp-c-band[b-ww0nfi2h5q]   { width: 160px; }
.rrp-soa .rrp-c-launch[b-ww0nfi2h5q] { width: 112px; }
.rrp-soa .rrp-c-brand[b-ww0nfi2h5q] { width: 110px; }
.rrp-soa .rrp-c-dept[b-ww0nfi2h5q]  { width: 95px; }
.rrp-soa .rrp-c-mark[b-ww0nfi2h5q]  { width: 92px; }
.rrp-soa .rrp-c-num[b-ww0nfi2h5q]   { width: 108px; }

/* Long names give way rather than pushing the numbers off the screen. */
.rrp-soa td[b-ww0nfi2h5q],
.rrp-soa th[b-ww0nfi2h5q] { overflow: hidden; text-overflow: ellipsis; }

/* ── One row height in both tabs ──
   The two tables are built differently — one is the week grid with its own padding, the other the
   house's compact table — and left alone they settle a few pixels apart, which is visible the
   moment you switch between them. Stated once, for both. */
.rrp-soa tbody td[b-ww0nfi2h5q],
.rrp-grid tbody th[b-ww0nfi2h5q],
.rrp-grid tbody td[b-ww0nfi2h5q] {
    height: 30px;
    padding-top: 1px;
    padding-bottom: 1px;
}

.rrp-soa .rrp-marker[b-ww0nfi2h5q],
.rrp-soa .rrp-input[b-ww0nfi2h5q] { padding-top: 1px; padding-bottom: 1px; }

/* The menu now serves two sheets, so it says which one it is offering before it offers it. */
.rrp-menu-head[b-ww0nfi2h5q] {
    padding: .35rem .75rem .15rem;
    font-size: .72rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .04em;
    color: var(--text-muted);
}
/* /Components/Pages/Promoters/PromoterPerformance.razor.rz.scp.css */
/* Multi-select filter dropdown (native <details>; click-away handled globally in app.js).
   Same behaviour as the projection filters — scoped CSS means each page carries its own copy. */
.ms-dd[b-n46rn14a01] {
    position: relative;
}

.ms-dd > summary[b-n46rn14a01] {
    list-style: none;
    cursor: pointer;
    min-width: 9rem;
    white-space: nowrap;
}

.ms-dd > summary[b-n46rn14a01]::-webkit-details-marker {
    display: none;
}

.ms-panel[b-n46rn14a01] {
    position: absolute;
    z-index: 30;
    margin-top: 2px;
    background: var(--bs-body-bg, #fff);
    border: 1px solid var(--border-color, #dee2e6);
    border-radius: 8px;
    padding: 8px;
    min-width: 14rem;
    max-height: 320px;
    overflow: auto;
    box-shadow: 0 6px 16px rgba(0, 0, 0, 0.12);
}

.ms-actions[b-n46rn14a01] {
    display: flex;
    align-items: center;
    padding-bottom: 6px;
    margin-bottom: 4px;
    border-bottom: 1px solid var(--border-color, #eee);
}

.ms-item[b-n46rn14a01] {
    display: block;
    font-size: 0.85rem;
    padding: 2px 0;
    cursor: pointer;
}

.ms-item input[b-n46rn14a01] {
    margin-right: 6px;
}

/* A folded-out organisation sits under its customer: same columns, quieter ground, so the
   indent reads as "part of the row above" rather than as another customer. */
.sub-row > td[b-n46rn14a01] {
    background-color: color-mix(in srgb, var(--bs-secondary-bg, #e9ecef) 45%, transparent);
    font-size: 0.9375rem;
}
/* /Components/Pages/Promoters/PromoterSheetDetails.razor.rz.scp.css */
/*
    The grid's number fields drop their spinners.

    Two reasons, and the second is the real one. They are visual clutter in a dense grid, where
    every row carries three of them. And they are now a lie: the arrow keys move between cells —
    see gridNavigation — so the little arrows promise an increment that pressing the arrow keys no
    longer performs. An affordance that does the opposite of what it depicts is worse than none.

    Typing, pasting and the arrows on the field itself all still work; only the rendered buttons go.
*/
.promoter-grid input[type="number"][b-ai9ozsj0yv]::-webkit-outer-spin-button,
.promoter-grid input[type="number"][b-ai9ozsj0yv]::-webkit-inner-spin-button {
    -webkit-appearance: none;
    appearance: none;
    margin: 0;
}

.promoter-grid input[type="number"][b-ai9ozsj0yv] {
    -moz-appearance: textfield;
    appearance: textfield;
}
/* /Components/Pages/Sales/ActionSignals.razor.rz.scp.css */
/* Multi-select filter dropdown (native <details>; click-away handled globally in app.js).
   Same behaviour as the projection filters — scoped CSS means each page carries its own copy. */
.ms-dd[b-cuvxeq9y7r] {
    position: relative;
}

.ms-dd > summary[b-cuvxeq9y7r] {
    list-style: none;
    cursor: pointer;
    min-width: 9rem;
    white-space: nowrap;
}

.ms-dd > summary[b-cuvxeq9y7r]::-webkit-details-marker {
    display: none;
}

.ms-panel[b-cuvxeq9y7r] {
    position: absolute;
    z-index: 30;
    margin-top: 2px;
    background: var(--bs-body-bg, #fff);
    border: 1px solid var(--border-color, #dee2e6);
    border-radius: 8px;
    padding: 8px;
    min-width: 14rem;
    max-height: 320px;
    overflow: auto;
    box-shadow: 0 6px 16px rgba(0, 0, 0, 0.12);
}

.ms-actions[b-cuvxeq9y7r] {
    display: flex;
    align-items: center;
    padding-bottom: 6px;
    margin-bottom: 4px;
    border-bottom: 1px solid var(--border-color, #eee);
}

.ms-item[b-cuvxeq9y7r] {
    display: block;
    font-size: 0.85rem;
    padding: 2px 0;
    cursor: pointer;
}

.ms-item input[b-cuvxeq9y7r] {
    margin-right: 6px;
}

/* A folded-out organisation sits under its customer: same columns, quieter ground, so the
   indent reads as "part of the row above" rather than as another customer. */
.sub-row > td[b-cuvxeq9y7r] {
    background-color: color-mix(in srgb, var(--bs-secondary-bg, #e9ecef) 45%, transparent);
    font-size: 0.9375rem;
}

/* ── Where the signal is concentrated ──────────────────────────────────────
   A ranked bar per category, drawn by hand rather than charted: the list is at
   most eight rows, each needs its name, its bar and its count on one line, and
   a chart library's category axis would cost a second scale to say the same
   thing. The fill takes the signal's own colour so the panel cannot be mistaken
   for the other tab's. */
.cat-bars[b-cuvxeq9y7r] {
    display: flex;
    flex-direction: column;
    gap: 7px;
}

.cat-row[b-cuvxeq9y7r] {
    display: grid;
    grid-template-columns: minmax(110px, 190px) minmax(0, 1fr) 56px;
    align-items: center;
    gap: 10px;
    font-size: .875rem;
}

.cat-name[b-cuvxeq9y7r] {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    text-align: right;
    color: var(--text-strong);
}

.cat-track[b-cuvxeq9y7r] {
    height: 12px;
    border-radius: 6px;
    background: var(--bg-subtle);
    overflow: hidden;
}

.cat-fill[b-cuvxeq9y7r] {
    display: block;
    height: 100%;
    border-radius: 6px;
}

.cat-lost[b-cuvxeq9y7r] { background: #dc2626; }
.cat-over[b-cuvxeq9y7r] { background: #d97706; }

.cat-value[b-cuvxeq9y7r] {
    font-variant-numeric: tabular-nums;
    color: var(--text-secondary);
}

/* The availability tab has three figures, not four. */
.kpi-row-3[b-cuvxeq9y7r] {
    grid-template-columns: repeat(3, minmax(0, 1fr));
}

@media (max-width: 1200px) {
    .kpi-row-3[b-cuvxeq9y7r] { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 860px) {
    .kpi-row-3[b-cuvxeq9y7r] { grid-template-columns: 1fr; }
    .cat-row[b-cuvxeq9y7r] { grid-template-columns: minmax(90px, 130px) minmax(0, 1fr) 48px; }
}
/* /Components/Pages/Sales/MarketReporting.razor.rz.scp.css */
/* Multi-select filter dropdown (native <details>; click-away handled globally in app.js).
   Same behaviour as the projection filters — scoped CSS means each page carries its own copy. */
.ms-dd[b-9b2tvx0c8t] {
    position: relative;
}

.ms-dd > summary[b-9b2tvx0c8t] {
    list-style: none;
    cursor: pointer;
    min-width: 9rem;
    white-space: nowrap;
}

.ms-dd > summary[b-9b2tvx0c8t]::-webkit-details-marker {
    display: none;
}

.ms-panel[b-9b2tvx0c8t] {
    position: absolute;
    z-index: 30;
    margin-top: 2px;
    background: var(--bs-body-bg, #fff);
    border: 1px solid var(--border-color, #dee2e6);
    border-radius: 8px;
    padding: 8px;
    min-width: 14rem;
    max-height: 320px;
    overflow: auto;
    box-shadow: 0 6px 16px rgba(0, 0, 0, 0.12);
}

.ms-actions[b-9b2tvx0c8t] {
    display: flex;
    align-items: center;
    padding-bottom: 6px;
    margin-bottom: 4px;
    border-bottom: 1px solid var(--border-color, #eee);
}

.ms-item[b-9b2tvx0c8t] {
    display: block;
    font-size: 0.85rem;
    padding: 2px 0;
    cursor: pointer;
}

.ms-item input[b-9b2tvx0c8t] {
    margin-right: 6px;
}

/* A folded-out organisation sits under its customer: same columns, quieter ground, so the
   indent reads as "part of the row above" rather than as another customer. */
.sub-row > td[b-9b2tvx0c8t] {
    background-color: color-mix(in srgb, var(--bs-secondary-bg, #e9ecef) 45%, transparent);
    font-size: 0.9375rem;
}

/* ── Customer and country marks ────────────────────────────────────────────*/
.mr-cust[b-9b2tvx0c8t] {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    min-width: 0;
}

/* Smaller than the mark on the ROI screens: this one sits in a dense table row. */
.mr-mark[b-9b2tvx0c8t] {
    width: 24px; height: 24px;
    font-size: 10px;
}

/* ── Trend ─────────────────────────────────────────────────────────────────*/
.mr-trend[b-9b2tvx0c8t] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 26px; height: 22px;
    border-radius: 6px;
    font-size: 14px;
    font-weight: 700;
    line-height: 1;
}

.mr-trend-up[b-9b2tvx0c8t]   { color: var(--status-success); background: color-mix(in srgb, var(--success) 18%, transparent); }
.mr-trend-down[b-9b2tvx0c8t] { color: var(--status-danger);  background: color-mix(in srgb, var(--danger) 18%, transparent); }
.mr-trend-flat[b-9b2tvx0c8t] { color: var(--status-warning); background: color-mix(in srgb, var(--warning) 22%, transparent); }

/* ── Country split: ring beside its own numbers ───────────────────────────*/
.mr-split[b-9b2tvx0c8t] {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.15fr);
    align-items: center;
    gap: 12px;
}

.mr-split-chart[b-9b2tvx0c8t] { min-width: 0; }

.mr-country-table[b-9b2tvx0c8t] { font-size: .875rem; }
.mr-country-table thead th[b-9b2tvx0c8t] { border-top: 0; }

.mr-dot[b-9b2tvx0c8t] {
    display: inline-block;
    width: 9px; height: 9px;
    border-radius: 50%;
    margin-right: 8px;
    vertical-align: 1px;
}

/* ── Top selling stores ────────────────────────────────────────────────────
   A ranked list rather than a bar chart, because the position is what the
   panel is for and a category axis cannot carry a rank and a name at once. */
.mr-rank[b-9b2tvx0c8t] {
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.mr-rank-row[b-9b2tvx0c8t] {
    display: grid;
    grid-template-columns: 24px minmax(90px, 230px) minmax(0, 1fr) 72px;
    align-items: center;
    gap: 10px;
    font-size: .875rem;
}

.mr-rank-no[b-9b2tvx0c8t] {
    width: 22px; height: 22px;
    border-radius: 50%;
    display: flex; align-items: center; justify-content: center;
    font-size: 11px;
    font-weight: 700;
    background: var(--bg-subtle);
    color: var(--text-muted);
}

/* The podium is worth seeing from across the room; the rest is a list. */
.mr-rank-top[b-9b2tvx0c8t] {
    background: color-mix(in srgb, var(--warning) 26%, transparent);
    color: var(--status-warning);
}

.mr-rank-name[b-9b2tvx0c8t] {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    color: var(--text-strong);
}

.mr-rank-track[b-9b2tvx0c8t] {
    height: 10px;
    border-radius: 5px;
    background: var(--bg-subtle);
    overflow: hidden;
}

.mr-rank-bar[b-9b2tvx0c8t] {
    display: block;
    height: 100%;
    border-radius: 5px;
    background: #2563eb;
}

.mr-rank-value[b-9b2tvx0c8t] {
    text-align: right;
    font-variant-numeric: tabular-nums;
    color: var(--text-secondary);
}

/* ── Narrow screens ───────────────────────────────────────────────────────
   The KPI row's own breakpoints travelled with it into app.css. */
@media (max-width: 860px) {
    .mr-split[b-9b2tvx0c8t] { grid-template-columns: 1fr; }
    .mr-rank-row[b-9b2tvx0c8t] { grid-template-columns: 22px minmax(0, 1fr) 64px; }
    .mr-rank-track[b-9b2tvx0c8t] { display: none; }
}
/* /Components/Pages/Sales/SellOutPerformance.razor.rz.scp.css */
/* Multi-select filter dropdown (native <details>; click-away handled globally in app.js).
   Scoped CSS means each page carries its own copy — same as Market Reporting. */
.ms-dd[b-d16wr2z2ja] { position: relative; }
.ms-dd > summary[b-d16wr2z2ja] { list-style: none; cursor: pointer; min-width: 9rem; white-space: nowrap; }
.ms-dd > summary[b-d16wr2z2ja]::-webkit-details-marker { display: none; }

.ms-panel[b-d16wr2z2ja] {
    position: absolute;
    z-index: 30;
    margin-top: 2px;
    background: var(--bs-body-bg, #fff);
    border: 1px solid var(--border-color, #dee2e6);
    border-radius: 8px;
    padding: 8px;
    min-width: 14rem;
    max-height: 320px;
    overflow: auto;
    box-shadow: 0 6px 16px rgba(0, 0, 0, .12);
}

.ms-actions[b-d16wr2z2ja] {
    display: flex;
    align-items: center;
    padding-bottom: 6px;
    margin-bottom: 4px;
    border-bottom: 1px solid var(--border-color, #eee);
}

.ms-item[b-d16wr2z2ja] { display: block; font-size: .85rem; padding: 2px 0; cursor: pointer; }
.ms-item input[b-d16wr2z2ja] { margin-right: 6px; }

/* ── The table ────────────────────────────────────────────────────────────────
   Thirteen columns of numbers. Everything here is in service of keeping a row
   readable across that width: the name column stays put while the rest scrolls,
   and the two period blocks are separated by a rule so the eye can tell which
   half of the table it is in. */
.perf-table[b-d16wr2z2ja] { font-size: .8125rem; border-collapse: separate; border-spacing: 0; }

.perf-table th[b-d16wr2z2ja],
.perf-table td[b-d16wr2z2ja] { vertical-align: middle; white-space: nowrap; }

.perf-table .block-row th[b-d16wr2z2ja],
.perf-table .group-row th[b-d16wr2z2ja],
.perf-table .head-row th[b-d16wr2z2ja] {
    font-size: .6875rem;
    letter-spacing: .04em;
    text-transform: uppercase;
    color: var(--bs-secondary-color, #6c757d);
    font-weight: 600;
    text-align: center;
    background: var(--bs-tertiary-bg, #f8f9fa);
}

.perf-table .block-row th.block[b-d16wr2z2ja] {
    font-size: .75rem;
    color: var(--bs-body-color);
    border-bottom: 1px solid var(--border-color, #dee2e6);
}

/* ── Telling the two periods apart ─────────────────────────────────────────────
   Thirteen columns of numbers in one typeface is a wall, and the commonest mistake
   a reader can make here is taking a year-to-date figure for this week's. So the
   two blocks are tinted differently and separated by a rule.

   The tint is a background-IMAGE, not a background-colour, on purpose: that leaves
   the colour slot free for whatever the row or the heading already paints, so a
   block tint composes with the heading's own ground and the total row's instead of
   replacing it. Written as flat rgba rather than mixed from a theme token, because
   the tokens here are creams — mixing one into a cream page produced a tint that
   measured as different and looked identical. Weak on purpose: it has to group the
   columns without competing with the red and green that carry the meaning.

   The two tints are cool against warm, and NEITHER is the blue the rings are drawn
   in. This-week used to be tinted with the primary blue itself, which put a blue
   ring on a blue ground in the one column a reader looks at first. Slate separates
   the block just as well and leaves blue to mean "a figure", not "a period". */
.perf-table .cw-col[b-d16wr2z2ja] {
    background-image: linear-gradient(rgba(51, 65, 85, .07), rgba(51, 65, 85, .07));
}

.perf-table .ytd-col[b-d16wr2z2ja] {
    background-image: linear-gradient(rgba(180, 110, 20, .07), rgba(180, 110, 20, .07));
}

[data-theme="dark"] .perf-table .cw-col[b-d16wr2z2ja] {
    background-image: linear-gradient(rgba(148, 178, 222, .09), rgba(148, 178, 222, .09));
}

[data-theme="dark"] .perf-table .ytd-col[b-d16wr2z2ja] {
    background-image: linear-gradient(rgba(232, 180, 92, .08), rgba(232, 180, 92, .08));
}

/* The rule between "this week" and "year to date". The two tables are not the same width — the
   share table carries thirteen columns and the product table nine — so each names its own
   boundary rather than sharing a column number that only happens to line up. */
.share-table th:nth-child(2)[b-d16wr2z2ja],
.share-table td:nth-child(2)[b-d16wr2z2ja],
.share-table th:nth-child(8)[b-d16wr2z2ja],
.share-table td:nth-child(8)[b-d16wr2z2ja] { border-left: 2px solid var(--border-color, #ced4da); }

.product-table th:nth-child(5)[b-d16wr2z2ja],
.product-table td:nth-child(5)[b-d16wr2z2ja],
.product-table th:nth-child(7)[b-d16wr2z2ja],
.product-table td:nth-child(7)[b-d16wr2z2ja] { border-left: 2px solid var(--border-color, #ced4da); }

/* ── The heading, lifted off the rows ──────────────────────────────────────────
   It used to be the same weight and ground as the data under it, so on a long list
   the heading read as the first row. It now sits on its own surface, under a firm
   rule, and stays put while the rows scroll past. */
.perf-table thead th[b-d16wr2z2ja] {
    position: sticky;
    top: 0;
    z-index: 4;
    background-color: #e7e2d9;
}

[data-theme="dark"] .perf-table thead th[b-d16wr2z2ja] { background-color: #2b2521; }

.perf-table thead tr:last-child th[b-d16wr2z2ja] {
    border-bottom: 2px solid var(--bs-secondary-color, #6c757d);
}

.perf-table thead .sticky-name[b-d16wr2z2ja] { z-index: 5; background-color: #e7e2d9; }
[data-theme="dark"] .perf-table thead .sticky-name[b-d16wr2z2ja] { background-color: #2b2521; }

/* ── Sorting ─────────────────────────────────────────────────────────────────── */
.perf-table th.sortable[b-d16wr2z2ja] { cursor: pointer; user-select: none; white-space: nowrap; }
.perf-table th.sortable:hover[b-d16wr2z2ja] { background: var(--bs-secondary-bg, #dee2e6); }

.perf-table th.sorted[b-d16wr2z2ja] { color: var(--bs-body-color); }

.sort-mark[b-d16wr2z2ja] {
    display: inline-block;
    width: .75em;
    margin-left: .15rem;
    font-size: .625rem;
    opacity: .75;
}

.perf-table .num[b-d16wr2z2ja] { text-align: right; }
.perf-table .strong[b-d16wr2z2ja] { font-weight: 600; }
.perf-table .extra[b-d16wr2z2ja] { font-size: .6875rem; line-height: 1.2; }

/* The name column holds still while thirteen columns of numbers scroll past it. */
.perf-table .sticky-name[b-d16wr2z2ja] {
    position: sticky;
    left: 0;
    z-index: 2;
    background: var(--bs-body-bg, #fff);
    text-align: left;
    min-width: 11rem;
}

.perf-table thead .sticky-name[b-d16wr2z2ja] { z-index: 3; background: var(--bs-tertiary-bg, #f8f9fa); }

.perf-table .total-row td[b-d16wr2z2ja] {
    font-weight: 600;
    background: var(--bs-tertiary-bg, #f1f3f5);
    border-top: 2px solid var(--border-color, #dee2e6);
}

/* ── Bars ─────────────────────────────────────────────────────────────────────
   A number and its bar share a cell: the number is the answer, the bar is the
   comparison, and putting the bar under rather than beside keeps the column
   narrow enough that thirteen of them fit. */
.bar[b-d16wr2z2ja] {
    height: 4px;
    margin-top: 3px;
    border-radius: 2px;
    background: var(--bs-secondary-bg, #e9ecef);
    overflow: hidden;
}

.bar-fill[b-d16wr2z2ja] { height: 100%; border-radius: 2px; background: var(--bs-primary, #0d6efd); }

/* ── Rings ────────────────────────────────────────────────────────────────── */
/* Ring, then figure, both anchored to the right of the cell.
   The figure is given a fixed width and tabular digits so "1%" and "100%" occupy the same space:
   without that the whole group shifts with the width of the number, and the rings wander left and
   right down the column instead of stacking. The coverage badge is ordered FIRST so it grows
   leftward — hanging it off the right-hand end would push the ring out of line on exactly the rows
   that most want comparing. */
.pct[b-d16wr2z2ja] { display: flex; align-items: center; justify-content: flex-end; gap: .35rem; white-space: nowrap; }

.pct .donut[b-d16wr2z2ja] { order: 2; }

.pct > span:not(.partial)[b-d16wr2z2ja] {
    order: 3;
    /* Wide enough for a BOLD "100%", which is what the total row holds — sized for the widest
       figure the column can show, not the widest ordinary one, or the total row's ring sits a
       pixel and a half out of line with every row above it. */
    min-width: 2.6rem;
    text-align: right;
    font-variant-numeric: tabular-nums;
}

.pct .partial[b-d16wr2z2ja] { order: 1; }

.donut[b-d16wr2z2ja] { flex: 0 0 auto; }
.donut circle[b-d16wr2z2ja] { fill: none; stroke-width: 5; }

/* The track is mixed from the INK, not set to a colour of its own.
   It used to be --bs-secondary-bg, which resolves to a cream on this theme —
   rgb(243, 236, 227) — and the two column grounds it sits on are creams three and
   ten units away from it. Measured as different, invisible on screen: the ring read
   as a floating arc with no circle behind it, and at 0% as nothing at all.
   A mix of currentColor composites over whatever is behind it, so the track stays a
   fixed step darker than its ground on every one of them — the two column tints, the
   heading's ground, the total row's — and inverts by itself in dark mode, where the
   ink is the cream and the ground is not. */
.donut .donut-track[b-d16wr2z2ja] { stroke: color-mix(in srgb, currentColor 30%, transparent); }
.donut .donut-value[b-d16wr2z2ja] { stroke: var(--bs-primary, #0d6efd); }

/* Last year's ring is quieter than this year's but still has to read against the
   track now sitting behind it, so it is mixed with the ground rather than left
   half-transparent over it. */
.donut.muted .donut-value[b-d16wr2z2ja] { stroke: color-mix(in srgb, var(--bs-primary, #0d6efd) 60%, transparent); }

/* Coverage, shown only when it is not the whole story — see MarginCell. */
.partial[b-d16wr2z2ja] {
    font-size: .625rem;
    padding: 0 .25rem;
    border-radius: 3px;
    background: var(--bs-warning-bg-subtle, #fff3cd);
    color: var(--bs-warning-text-emphasis, #664d03);
    cursor: help;
}

/* ── Change ───────────────────────────────────────────────────────────────── */
.delta[b-d16wr2z2ja] { font-variant-numeric: tabular-nums; }
.delta .arrow[b-d16wr2z2ja] { font-size: .625rem; margin-right: .15rem; }
/* Not the -text-emphasis tokens: in dark mode those are the DARK end of the ramp and all but
   vanish against the dark ground. These two read on both themes. */
.delta.up[b-d16wr2z2ja] { color: #1a9f5a; }
.delta.down[b-d16wr2z2ja] { color: #e05260; }
.delta.flat[b-d16wr2z2ja] { color: var(--bs-secondary-color, #6c757d); }
/* /Components/Shared/ImagePicker.razor.rz.scp.css */
/* The picture control. A preview, the two ways of setting one, and the shelf of shipped
   pictures — in that order, because the preview is what the reader is checking. */
.imgpick-top[b-w8xpx4kp83] {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
}

.imgpick-preview[b-w8xpx4kp83] {
    width: 76px;
    height: 48px;
    border-radius: 6px;
    border: 1px solid var(--border-color);
    background: var(--bg-subtle);
    overflow: hidden;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
}

.imgpick-preview img[b-w8xpx4kp83] { width: 100%; height: 100%; object-fit: cover; }

.imgpick-empty[b-w8xpx4kp83] {
    font-size: 0.7rem;
    color: var(--text-muted);
}

.imgpick-actions[b-w8xpx4kp83] { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }

/* A shelf rather than a grid: it wraps, and a customer who adds twenty of their own does not get
   a wall of them in the middle of a form. */
.imgpick-shelf[b-w8xpx4kp83] {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    margin-top: 8px;
    max-height: 132px;
    overflow-y: auto;
}

.imgpick-tile[b-w8xpx4kp83] {
    width: 58px;
    height: 38px;
    padding: 0;
    border: 1px solid var(--border-color);
    border-radius: 5px;
    overflow: hidden;
    background: none;
    cursor: pointer;
}

.imgpick-tile:hover[b-w8xpx4kp83] { border-color: var(--accent); }
.imgpick-tile:focus-visible[b-w8xpx4kp83] { outline: 2px solid var(--accent); outline-offset: 1px; }
.imgpick-tile img[b-w8xpx4kp83] { width: 100%; height: 100%; object-fit: cover; display: block; }
/* /Components/Shared/MarketingCalendarStrip.razor.rz.scp.css */
/* The year strip. Rows are a label and a track; everything inside a track is positioned as a
   percentage of the year, so an event that starts mid-week starts mid-column. */
.mcal[b-fdqbocubxa] {
    --mcal-label: 150px;
    font-size: 0.78rem;
}

.mcal-head[b-fdqbocubxa],
.mcal-row[b-fdqbocubxa] {
    display: grid;
    grid-template-columns: var(--mcal-label) 1fr;
    align-items: center;
}

.mcal-label[b-fdqbocubxa] {
    display: flex;
    align-items: center;
    gap: 7px;
    padding-right: 10px;
    overflow: hidden;
}

.mcal-dot[b-fdqbocubxa] {
    width: 9px;
    height: 9px;
    border-radius: 50%;
    flex-shrink: 0;
}

.mcal-band-name[b-fdqbocubxa] {
    font-weight: 600;
    color: var(--text-primary);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.mcal-track[b-fdqbocubxa] {
    position: relative;
    height: 34px;
}

/* Double height, to match the projection calendar — but only on a band that has a picture to
   show. 34px gives a picture nothing to be; 68px on a band with no picture is empty rent, and a
   strip of five of them is most of a screen. */
.mcal-row-tall .mcal-track[b-fdqbocubxa] { height: 68px; }

.mcal-head .mcal-track[b-fdqbocubxa] { height: 18px; }
.mcal-weeks .mcal-track[b-fdqbocubxa] { height: 14px; }

.mcal-month[b-fdqbocubxa],
.mcal-week[b-fdqbocubxa] {
    position: absolute;
    top: 0;
    text-align: center;
    color: var(--text-secondary);
    font-size: 0.7rem;
    white-space: nowrap;
    overflow: hidden;
}

.mcal-month[b-fdqbocubxa] {
    font-weight: 600;
    border-left: 1px solid var(--border-color);
}

/* 52 numbers across a laptop screen is about 18px each — small, and only read when hunted for. */
.mcal-week[b-fdqbocubxa] {
    font-size: 0.6rem;
    color: var(--text-muted);
}

/* One rule per week, behind the bars. */
.mcal-rule[b-fdqbocubxa] {
    position: absolute;
    top: 2px;
    bottom: 2px;
    width: 1px;
    background: var(--border-subtle);
}

.mcal-row + .mcal-row[b-fdqbocubxa] { margin-top: 2px; }

.mcal-row .mcal-track[b-fdqbocubxa] {
    background: var(--bg-subtle);
    border-radius: 6px;
}

/* A bar is painted in its band's colour and carries the band's picture at its head — the same
   treatment the projection calendar gives a campaign window, so the two read as one family. */
.mcal-bar[b-fdqbocubxa] {
    position: absolute;
    top: 5px;
    bottom: 5px;
    display: flex;
    align-items: center;
    gap: 5px;
    padding: 0 7px;
    border-radius: 6px;
    background: var(--band);
    color: #fff;
    /* Band colours are chosen by a person and some of them are pale. The shadow costs nothing and
       keeps the label legible on the light ones. */
    text-shadow: 0 1px 2px rgba(0, 0, 0, .45);
    box-shadow: 0 1px 3px rgba(0, 0, 0, .25);
    font-weight: 600;
    overflow: hidden;
    white-space: nowrap;
}

/* ── The picture ──
   Its own layer, with a width in pixels rather than a share of the bar: a block that runs a
   quarter is a very wide box, and covering it scales the picture up until only a slice through
   the middle is left. A panel at the head, the same however long the block runs — the 45% ceiling
   is for blocks too short to give it even that.

   Two gradients do the work. The dark wash keeps white text readable over a photograph of unknown
   brightness; the mask fades the picture out over its last stretch so it settles into the band's
   colour instead of ending on a hard vertical edge. */
.mcal-bar-hasart[b-fdqbocubxa]::before {
    content: "";
    position: absolute;
    top: 0; bottom: 0; left: 0;
    width: min(78px, 45%);
    background-image:
        linear-gradient(90deg, rgba(0,0,0,.45) 0%, rgba(0,0,0,.18) 60%, rgba(0,0,0,.05) 100%),
        var(--art);
    background-size: auto, cover;
    background-position: center, center;
    background-repeat: no-repeat, no-repeat;
    -webkit-mask-image: linear-gradient(90deg, #000 0%, #000 62%, transparent 100%);
            mask-image: linear-gradient(90deg, #000 0%, #000 62%, transparent 100%);
    pointer-events: none;
}

/* Two lines now there is room: what it is, and when. The dates were only in the tooltip before,
   which is no use to someone scanning the year. */
.mcal-bar-label[b-fdqbocubxa] {
    position: relative;   /* above the picture layer */
    z-index: 1;
    display: flex;
    flex-direction: column;
    justify-content: center;
    line-height: 1.25;
    overflow: hidden;
}

/* Clear of the picture rather than over it — the same measurement, so the two cannot drift. */
.mcal-bar-hasart .mcal-bar-label[b-fdqbocubxa] { padding-left: calc(min(78px, 45%) - 2px); }

/* Too short for two lines: the name is the half worth keeping. */
.mcal-bar-tight .mcal-bar-dates[b-fdqbocubxa] { display: none; }
.mcal-bar-tight .mcal-bar-label[b-fdqbocubxa] { justify-content: center; }

.mcal-bar-dates[b-fdqbocubxa] {
    font-size: 0.66rem;
    font-weight: 500;
    opacity: 0.85;
    overflow: hidden;
    text-overflow: ellipsis;
}

.mcal-bar-name[b-fdqbocubxa] {
    overflow: hidden;
    text-overflow: ellipsis;
}

/* A single day: a diamond on the day itself. A little larger now the rows are. */
.mcal-marker[b-fdqbocubxa] {
    position: absolute;
    top: 50%;
    width: 12px;
    height: 12px;
    margin-left: -6px;
    transform: translateY(-50%) rotate(45deg);
    border-radius: 1px;
}

.mcal-editable .mcal-bar[b-fdqbocubxa],
.mcal-editable .mcal-marker[b-fdqbocubxa] { cursor: pointer; }
.mcal-editable .mcal-row .mcal-track[b-fdqbocubxa] { cursor: copy; }
.mcal-editable .mcal-bar:hover[b-fdqbocubxa] { filter: brightness(1.06); }

/* ── Editing ──────────────────────────────────────────────────────────────
   Grips are inside the bar rather than outside it, so a narrow event is still grabbable in the
   middle to move — an edge handle that overhung would leave nothing to drag on a three-day block. */
.mcal-grip[b-fdqbocubxa] {
    position: absolute;
    top: 0;
    bottom: 0;
    width: 7px;
    cursor: ew-resize;
}

.mcal-grip-l[b-fdqbocubxa] { left: 0; }
.mcal-grip-r[b-fdqbocubxa] { right: 0; }

.mcal-editable .mcal-bar[b-fdqbocubxa] { cursor: grab; touch-action: none; }
.mcal-editable .mcal-marker[b-fdqbocubxa] { cursor: grab; touch-action: none; }
.mcal-editable .mcal-row .mcal-track[b-fdqbocubxa] { cursor: crosshair; touch-action: none; }

.mcal-dragging[b-fdqbocubxa] {
    cursor: grabbing;
    z-index: 5;
    box-shadow: var(--shadow-md);
}

/* The block being dragged out of empty track, before it exists. */
.mcal-ghost[b-fdqbocubxa] {
    position: absolute;
    top: 5px;
    bottom: 5px;
    border-radius: 5px;
    border: 2px dashed var(--accent);
    background: var(--accent-light);
    pointer-events: none;
}

/* The block whose weeks the grid below is lighting up. */
.mcal-selected[b-fdqbocubxa] {
    outline: 2px solid var(--accent);
    outline-offset: 1px;
    z-index: 4;
}
