﻿/*
VERGENT COMMON STYLES
    Version 1.0
    Date: 08/21/2026
*/

@import url('telerik/Vergent-Theme.css');
@import url('typography.css');

/* ---- icon metrics ----
   Every icon in this app is Font Awesome art painted through a mask, usually on a span
   that still carries Telerik's `.k-icon` class. Font Awesome 7 boxes every icon
   fixed-width at 1.25em so a column of them aligns; the Telerik webfont icons these
   replaced were a 1em square. A quarter-em of extra width on each of them is enough to
   read as oversized against layouts built for the old metric, so put them back on it.

   font-awesome-regular.css is the shared sheet - the customer portal and the loan
   application are drawn to Font Awesome's metric and keep it - and it states the wide
   box twice: once on `.fa-regular` and again on `.k-icon.fa-regular`. Matching both
   tiers is why this rule names four selectors, and index.html now links that sheet
   ahead of this one so these win on document order rather than on a specificity
   trick. */
.fa-regular,
.far,
.k-icon.fa-regular,
.k-button-icon.fa-regular {
    width: 1em;
    height: 1em;
    /* The mask paints over the border box by default, and `mask-size: contain` scales the
       art to whatever that box is - so padding on an icon enlarges the artwork instead of
       insetting it. The theme pads drawer icons (`.k-drawer-item .k-icon { padding-block:
       4px }`), which stretched the nav chevrons to 24px tall against 16px everywhere else:
       a chevron is the one tall-and-narrow shape here, so it is the one that grows into the
       extra height while square art stays width-bound. A webfont glyph never did this - it
       was drawn at font-size, not scaled to the box. Paint the content box instead. */
    -webkit-mask-origin: content-box;
    mask-origin: content-box;
}

/* Telerik.SvgIcons 5.x draws its icons as strokes - `fill="none"` on the path - where 4.x
   filled them. Vergent-Theme.css predates that and only sets `fill: currentColor` on
   `.k-svg-icon > svg`, so every 5.x icon, the dialog close X among them, painted nothing.
   This is the rule the stock 15.x theme adds; the stroke width already arrives on the
   path as an attribute. */
.k-svg-icon > svg [fill="none"] {
    stroke: currentColor;
}

/* Variables */

:root {
    --nav-color: 3,82,138;
    /* Links, affordance text and focus rings. 10.9:1 on --page-ground.
       Themeable, and the theme wins: UserService.SetLmsStylePreferences appends a
       <style> to <head> setting --color-1, which ties on specificity and beats this on
       document order. Anything needing a contrast guarantee must use --header-bar. */
    --color-1: #0a2f4e;

    /* ---- the header bar fill ----
       Every filled title bar: panel headers, dialog and window title bars, the grid
       heading row. Deliberately not --color-1 — a title bar carries white 11px text and
       cannot have its ground chosen by a company theme. Holds white at 13.7:1 whatever
       a company saves, at the cost of a theme no longer repainting the title bars. */
    --header-bar: #0a2f4e;

    /* The ink on that bar. #ffffff for every company that has saved no heading
       colour and for every dark one they might save, so on an existing tenant this
       changes nothing. It exists because the bar is themeable now: nothing stops a
       company choosing a pale brand colour, and a hardcoded white label on one is
       invisible. UserService derives the pair (ThemeColor.InkFor) and emits both
       together, so ground and ink cannot arrive apart. */
    --header-bar-ink: #ffffff;
    --color-2: rgb(40,63,103);
    --color-3: rgb(31,49,80);
    --accent-1: #ffffff;
    --accent-2: #eeeeee;
    --accent-3: #fafafa;
    --accent-4: lightgray;
    --font-color-1: #ffffff;
    --font-color-2: #000000;
    --background-color: #fff;
    --selected-1: rgba(18, 116, 172, 0.25);
    /* Row separator, muted label colour and row hover for the flat panels. Shared
       vocabulary (vergent-lms-design.md §2), not specific to any one screen. */
    --hairline: #e7ecf2;
    --font-color-muted: #6f7d90;
    --row-hover: #f7fafd;
    /* Zebra stripe for a dense grid of records. Much stronger than --row-hover, which is
       a transient cue on one row where this separates every other row at a glance. */
    --row-alt: #e6ecf4;
    /* The ground a board of white panels sits on. A clear step below --hairline, so a
       panel edge still reads against it. */
    --page-ground: #dfe6ef;
    /* The two status colours, named — the hexes the flag vocabulary already uses.
       CustLoanInfoComp.razor.css consumes these via var(), so leaving them undefined
       puts a second red and a second green on the same screen. */
    --warning-color: #b02318;
    --success-color: #12784e;

    --affordance-color: var(--color-1);

    --link-color: #0d6efd;
    --tint-bg: #e9f1f8;
    --tint-border: #c2d9ea;
    --tint-strong: #d9e3ef;
    /* Outline colours for the two status pills that carry one (§6). */
    --good-border: #bcdcc9;
    --bad-border: #eccbc7;
    --surface-mix: #ffffff;
    --header-bar-hover: #143f68;
    --panel-shadow: 0 1px 2px rgba(22, 34, 47, .06);
    --overlay-shadow: 0 2px 8px rgba(22, 34, 47, .16);
    --progressbar-chunk-color: #ebebeb;
}

/* Overall Styles */

html {
    overflow: hidden;
}

html, body {
    background-color: var(--color-3);
    height: 100%;
    /* Inter, self-hosted, exactly as the two customer apps do it - see typography.css. */
    font-family: var(--font-body);
    /* Not decoration, and not optional. Inter's default figures are proportional, so
       every aligned figure in this app depends on this being asked for at the root. The
       `ch` tracks in §12 lean on it too - a `ch` is the advance of "0", which only
       describes the other nine digits while the figures are tabular. */
    font-variant-numeric: tabular-nums;
}

a {
    text-decoration: none;
}

h4 a {
    color: var(--font-color-2);
    text-decoration: none;
}

@media (max-width: 400px) {
    html {
        font-size: 12px;
    }
}

/* The :where() carries the exclusion so it costs no specificity. Telerik renders its own
   borderless <input class="k-input-inner"> inside a wrapper that already draws the box and
   focus ring, and this selector outranks Telerik's own - so without the exclusion every
   Telerik textbox grows a hairline inside its focus ring. */
input:focus:where(:not(.k-input-inner)),
textarea:focus:where(:not(.k-input-inner)),
select:focus:where(:not(.k-input-inner)) {
    border: 1px solid var(--accent-4);
}

/* IDs */

#blazor-error-ui {
    background: lightyellow;
    bottom: 0;
    box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2);
    display: none;
    left: 0;
    padding: 0.6rem 1.25rem 0.7rem 1.25rem;
    position: fixed;
    width: 100%;
    z-index: 1000;
}

    #blazor-error-ui .dismiss {
        cursor: pointer;
        position: absolute;
        right: 0.75rem;
        top: 0.5rem;
    }

#drawer2 {
    visibility: hidden;
}

#products.quick-actions a {
    display: block;
    height: 100%;
    height: 100%;
    text-align: center;
    padding: 0 .25rem;
}

    #products.quick-actions a:hover {
        cursor: pointer;
    }

/* Classes */

.action-iframe {
    width: 100%;
    height: 100%;
}

.appointment-form .k-window-content {
    background-color: var(--accent-3);
}

.blazor-error-boundary {
    background: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTYiIGhlaWdodD0iNDkiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIG92ZXJmbG93PSJoaWRkZW4iPjxkZWZzPjxjbGlwUGF0aCBpZD0iY2xpcDAiPjxyZWN0IHg9IjIzNSIgeT0iNTEiIHdpZHRoPSI1NiIgaGVpZ2h0PSI0OSIvPjwvY2xpcFBhdGg+PC9kZWZzPjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMCkiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0yMzUgLTUxKSI+PHBhdGggZD0iTTI2My41MDYgNTFDMjY0LjcxNyA1MSAyNjUuODEzIDUxLjQ4MzcgMjY2LjYwNiA1Mi4yNjU4TDI2Ny4wNTIgNTIuNzk4NyAyNjcuNTM5IDUzLjYyODMgMjkwLjE4NSA5Mi4xODMxIDI5MC41NDUgOTIuNzk1IDI5MC42NTYgOTIuOTk2QzI5MC44NzcgOTMuNTEzIDI5MSA5NC4wODE1IDI5MSA5NC42NzgyIDI5MSA5Ny4wNjUxIDI4OS4wMzggOTkgMjg2LjYxNyA5OUwyNDAuMzgzIDk5QzIzNy45NjMgOTkgMjM2IDk3LjA2NTEgMjM2IDk0LjY3ODIgMjM2IDk0LjM3OTkgMjM2LjAzMSA5NC4wODg2IDIzNi4wODkgOTMuODA3MkwyMzYuMzM4IDkzLjAxNjIgMjM2Ljg1OCA5Mi4xMzE0IDI1OS40NzMgNTMuNjI5NCAyNTkuOTYxIDUyLjc5ODUgMjYwLjQwNyA1Mi4yNjU4QzI2MS4yIDUxLjQ4MzcgMjYyLjI5NiA1MSAyNjMuNTA2IDUxWk0yNjMuNTg2IDY2LjAxODNDMjYwLjczNyA2Ni4wMTgzIDI1OS4zMTMgNjcuMTI0NSAyNTkuMzEzIDY5LjMzNyAyNTkuMzEzIDY5LjYxMDIgMjU5LjMzMiA2OS44NjA4IDI1OS4zNzEgNzAuMDg4N0wyNjEuNzk1IDg0LjAxNjEgMjY1LjM4IDg0LjAxNjEgMjY3LjgyMSA2OS43NDc1QzI2Ny44NiA2OS43MzA5IDI2Ny44NzkgNjkuNTg3NyAyNjcuODc5IDY5LjMxNzkgMjY3Ljg3OSA2Ny4xMTgyIDI2Ni40NDggNjYuMDE4MyAyNjMuNTg2IDY2LjAxODNaTTI2My41NzYgODYuMDU0N0MyNjEuMDQ5IDg2LjA1NDcgMjU5Ljc4NiA4Ny4zMDA1IDI1OS43ODYgODkuNzkyMSAyNTkuNzg2IDkyLjI4MzcgMjYxLjA0OSA5My41Mjk1IDI2My41NzYgOTMuNTI5NSAyNjYuMTE2IDkzLjUyOTUgMjY3LjM4NyA5Mi4yODM3IDI2Ny4zODcgODkuNzkyMSAyNjcuMzg3IDg3LjMwMDUgMjY2LjExNiA4Ni4wNTQ3IDI2My41NzYgODYuMDU0N1oiIGZpbGw9IiNGRkU1MDAiIGZpbGwtcnVsZT0iZXZlbm9kZCIvPjwvZz48L3N2Zz4=) no-repeat 1rem/1.8rem, #b32121;
    color: var(--font-color-1);
    padding: 1rem 1rem 1rem 3.7rem;
}

    .blazor-error-boundary::after {
        content: "An error has occurred."
    }

.body-container {
    border: 0;
    padding: 0px;
    border-radius: 4px;
}

/* Containing block for #loader-layout, which is position: absolute with auto offsets:
   with no positioned ancestor its 100% resolves against the viewport.

   A separate class rather than position on .body-container, which is shared with
   NotificationHandler - giving a shared wrapper a containing
   block would silently re-anchor any absolutely positioned descendant. */
.loader-host {
    position: relative;
}

.body-content-wrapper {
    background-color: var(--accent-1);
    padding: 1em 0.5em 1em 0.5em;
    border-radius: 4px;
}

.btn {
    border-radius: 4px;
    box-shadow: rgb(0 0 0 / 35%) 0px 1px 3px
}

    .btn .k-button-text {
        color: var(--font-color-1) !important;
    }

    .btn:hover {
        filter: grayscale(30%);
    }

    .btn:active {
        box-shadow: none;
        filter: grayscale(60%);
    }

.btn-action {
    margin: 0 .25rem;
    width: 7rem;
}

.btn-cancel .k-button-text {
    color: black !important;
}

.btn-change-all {
    width: 2.5rem;
    margin-right: 1rem;
    margin-bottom: .25rem;
    padding: 1px 3px !important;
    background-color: var(--accent-4) !important;
    color: var(--font-color-2);
}

    .btn-change-all:hover {
        background-color: var(--accent-2) !important;
    }

    .btn-change-all .k-button-text {
        color: var(--font-color-2) !important;
    }

.btn-classic {
    background-color: var(--color-2);
}

.btn-comm-toggle {
    border-radius: 4px;
}

    .btn-comm-toggle.k-rounded-full {
        border-radius: 4px;
    }

    .btn-comm-toggle.k-switch-off .k-switch-track.k-rounded-full {
        background-color: var(--accent-1);
        color: var(--font-color-2);
        border-color: var(--accent-4);
    }

.btn-cs {
    background-color: var(--color-2);
}

.btn-customer-link {
    font-size: 11px;
    color: var(--font-color-1);
    padding: 3px 6px;
}

    .btn-customer-link:hover {
        color: var(--font-color-1);
    }

.btn-danger {
    background-color: #dc3545;
}

    .btn-danger:hover {
        background-color: #bb2d3b;
    }

.btn-generic {
    background-color: var(--accent-4) !important;
    color: var(--font-color-2);
}

    .btn-generic:hover {
        background-color: var(--accent-2) !important;
    }

.btn-login {
    text-transform: uppercase;
    outline: 0;
    background: #007F0E;
    width: 100%;
    height: 3rem;
    border: 0;
    padding: 1rem;
    color: #FFFFFF;
    font-size: 12pt !important;
    -webkit-transition: all 0.3 ease;
    transition: all 0.3 ease;
    cursor: pointer;
}

    .btn-login:hover, .btn-login:active, .btn-login:focus {
        background: #43A047;
        cursor: pointer;
    }

.btn-other {
    display: table;
    margin: .25rem auto;
    width: 90%;
    background-color: var(--accent-2);
}

    .btn-other:hover, .btn-other:active, .btn-login:focus {
        background-color: #dddddd;
        color: var(--font-color-2) !important;
    }

    .btn-other > .k-button-text {
        color: var(--font-color-2) !important;
    }

.btn-primary {
    background-color: var(--color-2);
    border-color: var(--color-2);
}

    .btn-primary:hover {
        background-color: var(--color-2);
    }

    .btn-primary:active, .btn-primary:focus {
        background-color: var(--color-2);
        filter: grayscale(60%);
    }

button.telerik-blazor.k-button.k-window-action.k-dialog-action.k-button-flat.k-rounded-md.k-button-rectangle.k-button-md.k-button-flat-base.k-icon-button {
    border-radius: 4px;
}

.clickable {
    cursor: pointer;
}

.code-snippet {
    margin-top: 2rem;
    margin: .5rem 0 0 0;
    width: fit-content;
}

/* ---- Color Mode switch, in the left nav's profile menu ----
   A sun when light mode is active, a moon when dark is. The words `OnLabel`/`OffLabel`
   carry stay in the accessibility tree; they are pushed out of a 12px box and an icon is
   masked in their place. `background-color: currentColor` makes that work in both states
   - the theme sets the inactive label to `transparent` and the active one inherits the
   track's colour. The icon is a fixed 12px, so no translation can reach the thumb.

   Specificity: the generic `.k-switch` rules sit LATER in this file, so every selector
   here is deliberately qualified to outrank them rather than relying on source order.
   Dropping a qualifier silently hands the rule back.

   No dark mode block: the nav is `--color-2` chrome in both modes. */

.k-switch.color-mode-switch {
    width: 44px;
    height: 22px;
    border: none;
}

    .color-mode-switch .k-switch-track {
        width: 44px;
        height: 22px;
        border: 0;
        border-radius: 4px;
    }

    /* The hairline is an inset shadow, not a border, so the track's box stays exactly
       44x22 and the percentages the thumb travels on stay whole. */
    .color-mode-switch.k-switch-off .k-switch-track {
        background-color: rgba(255, 255, 255, .14);
        box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .22);
        color: #ffffff;
    }

    /* The lane itself goes dark when dark mode is on - the state is the point of the
       control, so it is carried by the fill and the icon, not by the icon alone. */
    .color-mode-switch.k-switch-on .k-switch-track {
        background-color: rgba(0, 0, 0, .35);
        box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .22);
        color: #ffffff;
    }

    /* Each state deepens its own fill: one shared hover rule would tie with the two
       above and stop the dark lane flashing light under the pointer. */
    .color-mode-switch.k-switch-off:hover .k-switch-track {
        background-color: rgba(255, 255, 255, .22);
    }

    .color-mode-switch.k-switch-on:hover .k-switch-track {
        background-color: rgba(0, 0, 0, .45);
    }

    /* Matches `#left-nav .k-drawer-item:focus-visible`. `:focus` alone must not draw
       one, or a mouse click leaves a ring behind. */
    .color-mode-switch:focus-visible .k-switch-track,
    .color-mode-switch.k-focus .k-switch-track {
        outline: 2px solid #ffffff;
        outline-offset: -2px;
    }

    /* 18px in a 22px lane. `!important` because the generic `span.k-switch-thumb` fill
       later in this file carries one; specificity then decides, (0,2,0) beats (0,1,1). */
    .color-mode-switch .k-switch-thumb.k-rounded-full,
    .color-mode-switch .k-switch-thumb {
        width: 18px;
        height: 18px;
        border: 0;
        border-radius: 4px;
        background-color: #dbe9f4 !important;
    }

    /* Travel: centres at 11px and 33px, so the thumb spans 2-20 and 24-42. */
    .color-mode-switch.k-switch.k-switch-off .k-switch-thumb-wrap {
        left: 11px;
    }

    .color-mode-switch.k-switch.k-switch-on .k-switch-thumb-wrap {
        left: calc(100% - 11px);
    }

    /* The icon sits in the half the thumb is not in - 5px from that edge, so 12px of
       glyph with 7px of clearance from the thumb in either state. */
    .color-mode-switch.k-switch .k-switch-label-on,
    .color-mode-switch.k-switch .k-switch-label-off {
        display: block;
        width: 12px;
        height: 12px;
        overflow: hidden;
        /* The word is still in the DOM for a screen reader; this puts it outside the
           box so only the mask below is drawn. */
        text-indent: 100px;
        white-space: nowrap;
        background-color: currentColor;
        -webkit-mask-repeat: no-repeat;
        mask-repeat: no-repeat;
        -webkit-mask-position: center;
        mask-position: center;
        -webkit-mask-size: 12px 12px;
        mask-size: 12px 12px;
    }

    .color-mode-switch.k-switch .k-switch-label-on {
        left: 5px;
        -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M20.7 14.6A9 9 0 0 1 9.4 3.3 9 9 0 1 0 20.7 14.6z'/%3E%3C/svg%3E");
        mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M20.7 14.6A9 9 0 0 1 9.4 3.3 9 9 0 1 0 20.7 14.6z'/%3E%3C/svg%3E");
    }

    .color-mode-switch.k-switch .k-switch-label-off {
        right: 5px;
        -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Ccircle cx='12' cy='12' r='5'/%3E%3Cg fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round'%3E%3Cpath d='M12 1.5v3M12 19.5v3M3.2 3.2l2.1 2.1M18.7 18.7l2.1 2.1M1.5 12h3M19.5 12h3M3.2 20.8l2.1-2.1M18.7 5.3l2.1-2.1'/%3E%3C/g%3E%3C/svg%3E");
        mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Ccircle cx='12' cy='12' r='5'/%3E%3Cg fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round'%3E%3Cpath d='M12 1.5v3M12 19.5v3M3.2 3.2l2.1 2.1M18.7 18.7l2.1 2.1M1.5 12h3M19.5 12h3M3.2 20.8l2.1-2.1M18.7 5.3l2.1-2.1'/%3E%3C/g%3E%3C/svg%3E");
    }

/* ---- Language switch, in the left nav's profile menu ----
   Same chrome as the Color Mode switch above. Two differences: it carries a word, because
   two languages have no agreed icon and a flag is the wrong answer for a culture; and the
   track keeps one fill in both positions, because English and Spanish are peers rather
   than an off and an on.

   84px is measured against the widest label in the fallback stack (`Español` at 43.86px in
   Tahoma), leaving ~8px of clearance to the thumb. Safe as a fixed width only because the
   labels are endonyms and never translated.

   Specificity: as above, every selector is qualified to outrank the generic `.k-switch`
   rules later in this file. No dark mode block - the nav is `--color-2` in both modes. */
.k-switch.language-switch {
    width: 84px;
    height: 22px;
    border: none;
}

    /* Inset shadow rather than a border, so the box stays exactly 84x22 and the percentages
       the thumb travels on stay whole. `color` is what the active label inherits. */
    .language-switch.k-switch .k-switch-track {
        width: 84px;
        height: 22px;
        border: 0;
        border-radius: 4px;
        background-color: rgba(255, 255, 255, .14);
        box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .22);
        color: var(--font-color-1);
    }

    .language-switch.k-switch:hover .k-switch-track {
        background-color: rgba(255, 255, 255, .22);
    }

    /* `:focus` alone must not draw one, or a mouse click leaves a ring behind. */
    .language-switch:focus-visible .k-switch-track,
    .language-switch.k-focus .k-switch-track {
        outline: 2px solid #ffffff;
        outline-offset: -2px;
    }

    /* `!important` because the generic `span.k-switch-thumb` fill later in this file carries
       one; with both important, specificity decides and (0,2,0) beats (0,1,1). */
    .language-switch .k-switch-thumb.k-rounded-full,
    .language-switch .k-switch-thumb {
        width: 18px;
        height: 18px;
        border: 0;
        border-radius: 4px;
        background-color: #dbe9f4 !important;
    }

    /* Travel: centres at 11px and 73px, so the thumb spans 2-20 and 64-82. */
    .language-switch.k-switch.k-switch-off .k-switch-thumb-wrap {
        left: 11px;
    }

    .language-switch.k-switch.k-switch-on .k-switch-thumb-wrap {
        left: calc(100% - 11px);
    }

    /* Centred by line-height over the full track height, not by the theme's transform,
       which is measured for a 12px icon box. `transform: none` and `margin: 0` remove it. */
    .language-switch.k-switch .k-switch-label-on,
    .language-switch.k-switch .k-switch-label-off {
        display: block;
        top: 0;
        bottom: 0;
        height: auto;
        margin: 0;
        transform: none;
        line-height: 22px;
        font-size: 11px;
        font-weight: 600;
        letter-spacing: .01em;
        text-transform: none;
        text-align: center;
        white-space: nowrap;
    }

    /* The word takes the half the thumb is not in. Both insets on both labels, so the lane is
       the same 52px either way and the word does not shift between states. */
    .language-switch.k-switch .k-switch-label-on {
        left: 8px;
        right: 24px;
    }

    .language-switch.k-switch .k-switch-label-off {
        left: 24px;
        right: 8px;
    }

    /* One word on screen at a time. The compiled theme already does this, but stated here
       because a theme that stopped would print both words on top of each other. */
    .language-switch.k-switch-off .k-switch-label-on,
    .language-switch.k-switch-on .k-switch-label-off {
        color: transparent;
    }

.component {
    border-radius: 4px;
    box-shadow: rgb(0 0 0 / 35%) 0px 1px 2px;
    color: var(--font-color-1);
    font-size: 12px;
    margin: .25rem;
    padding: 0;
    height: fit-content;
    background-color: var(--accent-3);
}

    .component .table {
        color: var(--font-color-2);
    }

.component-content-wrapper {
    background-color: var(--accent-1);
    padding: 0;
    border-bottom-right-radius: 4px;
    border-bottom-left-radius: 4px;
}

.component.k-tilelayout-item {
    background-color: var(--accent-1);
    border-radius: 4px;
    box-shadow: rgb(0 0 0 / 35%) 0px 1px 2px;
    color: var(--font-color-1);
    font-size: 12px;
    margin: .5rem .25rem;
    padding: 0;
    height: 100%;
}

.component.over {
    border: 1px dotted #666;
}

.component .col {
    padding-right: unset;
}

.component-container {
    align-items: flex-start;
    background-color: var(--accent-2);
    border-radius: 4px;
    color: var(--font-color-1);
    font-size: 13px;
    margin: 0.5rem;
    padding: 0;
    top: 0;
}

    .component-container .row {
        margin-top: unset;
        margin-right: unset;
        --bs-gutter-x: .75rem;
    }

.component-container-title {
    background-color: var(--header-bar);
    border-bottom: solid 1px var(--accent-2);
    font-size: 14px;
    margin: 0;
    padding: .25rem .5rem;
    border-top-left-radius: 4px;
    border-top-right-radius: 4px;
}

    .component-container-title a {
        color: var(--font-color-1);
        text-decoration: none;
    }

    .component-container-title.withcontrols {
        height: 39px;
    }

.component-content {
    padding: .5rem;
    color: var(--font-color-2);
}

.component-content-header {
    font-size: 0.7em;
    margin: 0px;
    font-weight: normal;
    text-transform: uppercase;
    text-align: center;
    color: var(--font-color-2);
}

.component-fail {
    background-color: red;
    font-size: 14px;
    padding: 0.25rem 0.5rem;
    border-radius: 4px;
    word-break: break-word;
}

.component-item {
    color: var(--font-color-2);
    margin-bottom: 4px;
    padding-left: 10px;
    border-radius: 4px;
    background-color: var(--accent-3);
    box-shadow: 0px 1px 1px 0px rgb(0 0 0 / 20%);
    overflow-wrap: break-word;
}

    .component-item .col {
        box-sizing: content-box;
        display: table;
    }

        .component-item .col span {
            display: table-cell;
            vertical-align: middle;
        }

.component-item-details {
    color: var(--font-color-2);
    padding-left: 10px;
    background-color: var(--accent-3);
    overflow-wrap: break-word;
    border: 1px solid var(--accent-4);
}

    .component-item-details .col {
        box-sizing: content-box;
        display: table;
    }

        .component-item-details .col span {
            display: table-cell;
            vertical-align: middle;
        }

.component-title-details {
    background-color: var(--header-bar);
    border-radius: 4px 4px 0 0;
    border-radius: 4px 4px 0 0;
    margin: 0;
    padding: 0.25rem 0.5rem;
    display: grid;
    grid-template-columns: 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr;
    color: white;
    font-size: 12px;
}

.component-piece {
    display: table;
    height: 100%;
    width: 100%;
    color: var(--font-color-2);
}

    .component-piece a {
        text-decoration: none;
    }

    .component-piece span {
        display: table-cell;
        vertical-align: middle;
    }

    /* SensitiveValue is spans all the way down - the control, the value's text, and one
       span per run from MaskedText. The coercion above turns each run into a cell of an
       anonymous table, which stacks •••-••-1111 over four rows. Only the display is
       undone; the control's own scoped CSS still does its layout. Here rather than in
       SensitiveValue.razor.css, because that bundle can be served stale after a deploy.

       nowrap because a masked identifier is one token. */
    .component-piece .sensitive-value {
        display: inline-flex;
    }

    .component-piece .sensitive-value-text,
    .component-piece .sensitive-value-text span {
        display: inline;
        vertical-align: baseline;
        white-space: nowrap;
    }

.component-title {
    background-color: var(--header-bar);
    border-bottom: solid 1px var(--accent-2);
    border-radius: 4px 4px 0 0;
    border-radius: 4px 4px 0 0;
    font-size: 14px;
    margin: 0;
    padding: .25rem .5rem;
}

    .component-title a {
        color: var(--font-color-1);
        text-decoration: none;
    }

.component-title-header {
    color: white;
    display: none;
}

.container {
    padding: 1rem;
}

.container, .container-fluid, .container-lg, .container-md, .container-sm, .container-xl, .container-xxl {
    padding-left: 0;
}

.content {
    padding-top: 0;
}

.content-wrapper {
    background-color: var(--color-3);
    height: calc(100vh - 6rem);
    overflow-y: auto;
    padding: 0 0.5em;
    width: 100%;
}

    .content-wrapper:has(.lms-iframe) {
        overflow-y: hidden;
    }

.cust-comp-btn-container {
    text-align: right;
    margin-top: .25rem;
}

.customer-btn {
    border-radius: 4px;
    color: var(--font-color-2);
    display: table;
    margin: .5rem auto;
    width: 90%;
}

    .customer-btn > .k-button-text {
        text-overflow: ellipsis;
        white-space: normal;
    }

.cust-info-container {
    display: grid;
    grid-auto-flow: column;
    margin: 0 auto;
    width: fit-content;
    text-align: center;
}

.cust-info-piece {
    float: left;
    padding: 0 .5rem;
    text-align: center;
    margin: 0.15rem 0;
    display: grid;
    grid-template-rows: 1fr 1fr;
    border-right: 1px solid var(--accent-4);
}

    .cust-info-piece:last-child {
        border-right: none;
    }

/* scrollbars */

/* Track */
::-webkit-scrollbar-track {
    background: transparent;
}

/* Handle */
::-webkit-scrollbar-thumb {
    background: #888;
}

    /* Handle on hover */
    ::-webkit-scrollbar-thumb:hover {
        background: #555;
    }

.custom-scroll {
    scrollbar-width: thin;
}

    .custom-scroll::-webkit-scrollbar {
        width: 7px;
        height: 7px;
    }

/* end scrollbars */

.customer-loan-text {
    text-align: center;
    font-size: 12px;
    font-weight: bold;
    font-family: Arial,Helvetica;
    color: var(--font-color-2);
}

.customer-search-btn {
    display: table;
    margin: 2px auto;
    width: 90%;
}

.customer-search-btn-alt {
    display: table;
    margin: 2px auto;
    width: 90%;
}

    .customer-search-btn-alt .k-button-text {
        color: var(--font-color-2) !important;
    }

.customer-search-txtbox {
    border-radius: 4px;
    display: table;
    margin: 2px auto;
    width: 90%;
}

    .customer-search-txtbox > .k-input-inner {
        color: black !important;
    }

.customer-primary-color {
    color: green;
}

.customer-warning-color {
    color: red;
}

.custom-toolbar {
    border-bottom-width: 1px;
    border-bottom: inset;
    line-height: 10px;
    padding: 3px 8px;
    width: 100%;
}

.draggable {
    width: 100%;
}

.dragging {
    opacity: 0.5;
}

.drawer-container {
    /*background-image: linear-gradient(0deg, rgba(var(--nav-color),1) 0%, rgba(var(--nav-color),.5) 50%, rgba(var(--nav-color),1) 90%);*/
    background-color: var(--color-2);
    border-right: solid 1px rgba(0, 0, 0, 0.08);
    border: 0;
    float: left;
    max-width: 13rem;
    min-height: calc(100vh - 6rem);
    position: sticky;
    width: fit-content;
    height: 100%;
}

.edit-btn {
    float: right;
    margin: 0.25rem 0.5rem 0.25rem 0.25rem;
    border-radius: 4px;
}

.edit-dialog .k-notification-group {
    margin-bottom: 15px;
    position: relative;
}

.footer {
    position: fixed;
    bottom: 0;
    width: -moz-available;
    width: -webkit-fill-available;
    background-color: var(--color-3);
    color: white;
    padding: 0.5em 0;
    z-index: 1000;
    height: 3rem;
}

.full-width {
    width: 100%;
}

.gradient-border-mask {
    position: relative;
    animation: .75s linear infinite spinner-border;
}

    .gradient-border-mask::before {
        content: "";
        position: absolute;
        top: 0;
        left: 0;
        right: 0;
        bottom: 0;
        border-radius: 50px;
        border: 5px solid transparent;
        background: linear-gradient(to right, rgb(53,109,182), rgb(49,194,237)) border-box;
        -webkit-mask: linear-gradient(#fff 0 0) padding-box, linear-gradient(#fff 0 0);
        -webkit-mask-composite: destination-out;
        mask-composite: exclude;
    }

.grid-no-scroll .k-grid-content {
    overflow-y: auto;
}

.grid-no-scroll .k-grid-header,
.grid-no-scroll .k-grid-footer {
    padding-right: 0; /* version 2.26 and older requires !important here */
}

.grid-no-scroll .k-grid-header-wrap,
.grid-no-scroll .k-grid-footer-wrap {
    border-right-width: 0;
}

.header2 {
    margin: 0 0 1em;
    padding: 0px;
    border-width: 0 0 2px;
    border-style: solid;
    width: 100%;
    font-size: 14px;
    text-transform: uppercase;
}

.hidden {
    display: none;
    visibility: hidden;
}

.input-padding {
    padding: 0;
}

.invalid {
    outline: 1px solid red;
}

.k-breadcrumb-link:hover, .k-breadcrumb-link.k-hover {
    color: inherit !important;
    background-color: inherit !important;
}

.k-button {
}

    .k-button:hover::before, .k-button.k-hover::before {
        opacity: .1;
    }

    .k-button k-icon * {
        color: var(--font-color-2) !important;
    }

.k-button-group .k-button-solid-base {
    background-color: var(--accent-4);
    color: var(--font-color-2);
}

.k-button-md {
    font-size: 11px;
    padding: 3px 6px;
}

    .k-button-md.k-icon-button {
        background-color: var(--accent-1);
        color: var(--font-color-2);
    }

.k-button-solid-base.k-selected {
    background-color: var(--color-2) !important;
    color: var(--font-color-1);
}

.k-calendar-nav * {
    color: var(--font-color-2) !important;
}

.k-card {
    border-color: var(--accent-4);
    background-color: var(--accent-1);
}

.k-card-body {
    background-color: var(--accent-1);
    color: var(--font-color-2);
}

.k-chart * {
    border-radius: 0 0 0.5rem 0.5rem;
}

.k-checkbox {
    border-radius: 4px;
    border: 1px solid var(--accent-4);
}

.k-chip-solid-base {
    background-color: var(--accent-4);
    color: var(--font-color-2);
}

.k-color-picker {
    border-radius: 4px;
}

.k-colorpicker {
    border-radius: 4px;
}

/* ---- the ColorPicker's swatch has no size of its own ----
   Every ColorPicker in this app rendered an empty box: the chosen colour was set
   correctly (inline background-color on .k-color-preview-mask) but the swatch was
   0px wide. Measured in a real Telerik 13.1 picker against this stylesheet: picker
   35.7x24, .k-input-inner 10x22, .k-color-preview 2x14, mask 0x12.

   A gap in the custom Vergent-Theme.css build, not the component. Its only
   unconditional size for the swatch is `width/height: 100%` of an unsized parent;
   both px sizings are scoped elsewhere (.k-coloreditor-preview is the popup,
   .k-icon-color-preview a different variant). With `.k-colorpicker { width:
   min-content }` the chain resolves to nothing. Stock Kendo supplies the missing
   size; this build does not. The popup portals outside .k-colorpicker, so it keeps
   its own 32x12.

   Replaces .color-picker-dropdown, a per-page workaround that only fixed the width
   - its swatch measured 52x0, also invisible. Nothing referenced that class once
   /setup/theme stopped using it. */
.k-colorpicker .k-color-preview {
    width: 1.75rem;
    height: .875rem;
}

/* ---- LoaderContainer overlay and loader tints ----
   Telerik 14.0.0 removed the OverlayThemeColor parameter outright, and dropped
   Info from LoaderContainer's ThemeColor set. The theme classes those parameters
   emitted (.k-overlay-light/-dark, .k-loader-info) still exist, so these reproduce
   them from the same tokens rather than picking a new colour. */
.loader-overlay-light .k-loader-container-overlay {
    background-color: var(--kendo-color-light, #ebebeb);
}

.loader-overlay-dark .k-loader-container-overlay {
    background-color: var(--kendo-color-dark, #424242);
}

.loader-info .k-loader,
.loader-info .k-loader + .k-loader-container-label {
    color: var(--kendo-color-info-on-surface, #3e80ed);
}

.k-column-title {
    color: var(--font-color-1);
}

.k-d-level {
    display: flex;
}

.k-datepicker {
    border-radius: 4px;
}

.k-dialog {
    border-radius: 4px;
}

    .k-dialog .k-dialog-content {
        border-bottom-left-radius: 4px;
        border-bottom-right-radius: 4px;
        background-color: var(--accent-3);
    }

.k-dialog-titlebar {
    border-radius: 4px 4px 0 0;
    background-color: var(--header-bar);
    border-top-left-radius: 4px;
    border-top-right-radius: 4px;
}

.k-dialog-titlebar-action {
    color: white !important;
}

.k-drawer {
    background-color: transparent;
    border: 0;
    transition: none !important;
    width: 100%;
}

.k-drawer-container {
    height: 95%;
    position: relative;
    width: 100%;
    transition: none !important;
}

.k-drawer-content {
    display: none;
    font-size: 18px;
    padding: 25px;
    transition: none !important;
}

.k-drawer-item {
    color: var(--font-color-1);
    font-size: .9rem;
    transition: none !important;
    gap: 0 .5rem;
}

    .k-drawer-item .k-item-text {
        padding: 0px;
        white-space: normal;
        text-wrap: balance;
        line-height: 1.2rem;
        overflow: visible;
    }

    .k-drawer-item:focus, .k-drawer-item.k-focus {
        color: var(--font-color-2);
    }

.k-item-text {
    padding: 0;
}

.k-drawer-item .k-icon * {
    color: var(--font-color-1);
}

.k-drawer-item:hover {
    background-color: var(--color-1);
    color: var(--font-color-1);
}

.k-drawer-item.k-selected {
    background-color: var(--accent-3);
    color: var(--font-color-2);
}

    .k-drawer-item.k-selected:hover {
        background-color: var(--accent-4);
        color: var(--font-color-2);
    }

.k-drawer-item.k-button-md.k-icon-button {
    color: var(--font-color-1);
}

.k-drawer-mini {
    transition: none !important;
}

    .k-drawer-mini .k-drawer-wrapper {
        width: 3rem !important;
        transition: none !important;
    }

.k-drawer-wrapper {
    width: 100% !important;
    transition: none !important;
}

.k-dropdownlist {
    border-radius: 4px;
    background-color: var(--accent-1);
    color: var(--font-color-2);
}

.k-filter-row .k-icon {
    color: var(--font-color-2) !important;
}

.k-floating-label-container * {
    color: var(--font-color-2) !important;
}

.k-form .k-label {
    font-weight: bold;
    color: var(--font-color-2);
}

.k-form .k-form-layout {
    gap: 16px;
}

.k-form > .k-form-field {
    margin-bottom: 16px;
}

.k-radio {
    width: 16px;
    height: 16px;
}

.k-list-item {
    padding-block: 6px;
}

.k-form .k-form-buttons {
    margin-top: 16px;
    margin-left: 0;
    margin-right: 0;
}

.k-form .k-form-field {
    min-width: 0;
}

.k-form-field-error .k-dropdownlist {
    border-color: #d51923;
}

.k-form fieldset legend {
    color: var(--font-color-2);
}

.k-form .k-multiselect {
    background-color: var(--accent-2);
}

.k-gauge * {
    background-color: var(--font-color-1);
    border-radius: 0 0 0.5rem 0.5rem;
}

.k-grid {
    border-radius: 4px;
    border: none;
    margin: 0;
    padding: 0;
    font-size: 13px;
}

    .k-grid .k-icon {
        color: var(--font-color-1);
    }

    .k-grid .k-button-icon {
        color: var(--font-color-2);
    }

    .k-grid td {
        padding: 3px 4px;
    }

    .k-grid th {
        padding: 4px 4px;
    }

    .k-grid .k-button-md .k-icon-button > .k-button-icon {
        min-height: 0;
        min-width: 0;
    }

    .k-grid .k-button-md.k-icon-button {
        padding: 1px;
    }

    .k-grid td.k-command-cell {
        text-align: right;
    }

.k-grid-aria-root {
    border-radius: 0 0 0.5rem 0.5rem;
}

.k-grid {
    background-color: var(--accent-2);
}

.k-list {
    background-color: var(--accent-1);
    color: var(--font-color-2);
    border-color: var(--accent-3);
}

.k-nodata {
    background-color: var(--accent-1);
    color: var(--font-color-2);
    border-color: var(--accent-3);
}

.k-list-content {
    background-color: var(--accent-1);
    color: var(--font-color-2);
    border-color: var(--accent-3);
}

.k-listbox .k-list-scroller .k-list {
    background-color: var(--accent-1);
    color: var(--font-color-2);
    border-color: var(--accent-3);
}

.k-listbox .k-list-scroller {
    border-color: var(--accent-3);
    background-color: var(--accent-1);
    color: var(--font-color-2);
}

.k-grid-header {
    border-top-left-radius: 4px;
    border-top-right-radius: 4px;
}

.k-grid .k-grid-header {
    border-bottom-width: 1px;
    background-color: var(--header-bar);
}

.k-grid-filter:hover * {
    color: var(--font-color-2) !important;
}

.k-grid-pager {
    border-radius: 0 0 0.5rem 0.5rem;
}

.k-grid-norecords {
    background-color: var(--accent-1);
    color: var(--font-color-2);
}

    .k-grid-norecords td:hover {
        background-color: var(--accent-1);
        border: 1px solid var(--accent-4);
        color: var(--font-color-2);
    }

.k-grid-toolbar {
    background-color: var(--color-1);
    border-bottom: 1px solid rgba(0, 0, 0, 0.1);
    border-top-right-radius: 4px;
}

    .k-grid-toolbar ~ .k-grid-aria-root > .k-grid-header {
        /* Remove the border from the grid header if it has a toolbar attached */
        border-radius: 0;
    }

.k-header {
    color: var(--font-color-1);
}

.k-icon.fa-pencil {
    cursor: pointer;
}

.k-in.k-link.k-menu-link.k-active {
    background-color: var(--color-1);
}

.k-i-reorder::before {
    content: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" height="1em" viewBox="0 0 320 512"><!--! Font Awesome Free 6.4.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. --><path d="M40 352l48 0c22.1 0 40 17.9 40 40l0 48c0 22.1-17.9 40-40 40l-48 0c-22.1 0-40-17.9-40-40l0-48c0-22.1 17.9-40 40-40zm192 0l48 0c22.1 0 40 17.9 40 40l0 48c0 22.1-17.9 40-40 40l-48 0c-22.1 0-40-17.9-40-40l0-48c0-22.1 17.9-40 40-40zM40 320c-22.1 0-40-17.9-40-40l0-48c0-22.1 17.9-40 40-40l48 0c22.1 0 40 17.9 40 40l0 48c0 22.1-17.9 40-40 40l-48 0zM232 192l48 0c22.1 0 40 17.9 40 40l0 48c0 22.1-17.9 40-40 40l-48 0c-22.1 0-40-17.9-40-40l0-48c0-22.1 17.9-40 40-40zM40 160c-22.1 0-40-17.9-40-40L0 72C0 49.9 17.9 32 40 32l48 0c22.1 0 40 17.9 40 40l0 48c0 22.1-17.9 40-40 40l-48 0zM232 32l48 0c22.1 0 40 17.9 40 40l0 48c0 22.1-17.9 40-40 40l-48 0c-22.1 0-40-17.9-40-40l0-48c0-22.1 17.9-40 40-40z"/></svg>');
}

.k-link:hover {
    background-color: var(--accent-4)
}

.navbar .k-link:hover {
    background-color: var(--color-1);
}

.k-input .k-icon {
    color: var(--font-color-2) !important;
}

.k-input-inner {
    background-color: var(--accent-1);
    color: var(--font-color-2);
}

.k-input-solid {
    border-color: var(--accent-4);
}

.k-listview {
    background-color: var(--accent-1);
    color: var(--font-color-1);
}

    .k-listview .k-icon {
        color: var(--font-color-1);
    }

.k-map {
    border-radius: 0 0 0.5rem 0.5rem;
}

    .k-map .km-scroll-wrapper {
        border-radius: 0 0 0.5rem 0.5rem;
    }


.k-master-row.k-table-row {
    color: var(--font-color-2);
    background-color: var(--accent-3);
}

.k-master-row .k-icon * {
    color: var(--font-color-2) !important;
}

.k-notification.telerik-blazor {
    border-radius: 4px;
}

.k-numerictextbox {
    border-radius: 4px;
}

.k-pager {
    border-radius: 4px;
}

.k-pager-info {
    color: var(--font-color-1);
}

.k-pager-input, .k-pager-sizes, .k-pager-info {
    color: white;
}

.k-pager-numbers > li > .k-link.k-selected {
    border-radius: 15px;
}

.k-pager-numbers .k-link {
    color: var(--font-color-1);
}

    .k-pager-numbers .k-link.k-state-selected, .k-pager-numbers .k-link.k-selected {
        color: var(--font-color-1);
    }

.k-pager-wrap {
    padding: 5px 8px;
}

.k-pager-wrap, .k-pager {
    background-color: var(--color-1);
}

.k-picker-solid {
    background-color: var(--accent-4);
}

.k-progressbar li.k-selected {
    color: #fff;
    background-color: #22597d;
}

.k-progressbar {
    background-color: var(--accent-1);
}

    .k-progressbar .k-item {
        border-color: var(--accent-1);
        background-color: var(--accent-4);
    }

.k-item-text {
    padding: 0;
}

.k-rounded-md {
    border-radius: 4px;
}

.k-splitter {
    background-color: var(--accent-3);
}

.k-tabstrip-content, .k-tabstrip > .k-content {
    padding: .5rem;
}

    .k-tabstrip-content.k-active, .k-tabstrip > .k-content.k-active {
        background-color: var(--accent-1);
    }

.k-tabstrip-items-wrapper {
    z-index: 1;
}

    .k-tabstrip-items-wrapper .k-item:hover, .k-tabstrip-items-wrapper .k-item.k-hover {
        color: var(--font-color-2);
        background-color: var(--accent-2);
    }

.k-tabstrip-top > .k-tabstrip-items-wrapper .k-item + .k-item {
    border-right: solid 1px rgba(0, 0, 0, 0.08);
}

.k-tabstrip-top > .k-tabstrip-items-wrapper .k-item.k-active {
    border-radius: 4px 4px 0 0;
    background-color: var(--accent-1);
}

.k-textarea,
.k-textbox {
    border-radius: 4px;
}

.k-tilelayout {
    background-color: rgba(0, 0, 0, 0);
}

.k-tilelayout-item.k-card {
    background-color: rgba(0, 0, 0, 0);
    border: none;
    padding: 0;
}

.k-tilelayout-item-header {
    margin: 0;
    padding: 0;
    border: none;
}

.k-tilelayout-item-body.k-card-body {
    padding: 0;
    background-color: rgba(0, 0, 0, 0);
}


.k-toolbar .k-icon {
    color: var(--font-color-2) !important;
}

.k-tooltip {
    background-color: var(--color-1);
    box-shadow: rgba(0, 0, 0, 0.35) 0px 5px 15px;
    color: var(--font-color-1);
    border-radius: 4px;
    padding: 8px;
}

.k-treeview * {
    color: var(--font-color-2);
}

.k-treeview-leaf-text {
    color: var(--font-color-2);
}

.k-upload .k-dropzone {
    background-color: var(--accent-2);
    padding: .25rem;
}

.k-upload-button {
    background-color: var(--accent-4) !important;
    color: var(--font-color-2);
}

    .k-upload-button:hover {
        background-color: var(--accent-2) !important;
    }

.k-widget .k-attribution {
    border-radius: 0 0 0.5rem 0;
}

.k-window {
    border-radius: 4px;
}

.k-window-content {
    background-color: var(--accent-2);
    border-bottom-left-radius: 4px;
    border-bottom-right-radius: 4px;
}

.k-window-title {
    font-size: 1rem;
    padding: 0 .5rem;
}

.k-window-titlebar {
    padding: 1rem 1rem 1rem 0.25rem;
    color: white;
    background-color: var(--header-bar);
    border-top-left-radius: 4px;
    border-top-right-radius: 4px;
}

    .k-window-titlebar .k-button-icon {
        color: var(--font-color-1);
    }

.k-window-wrapper {
    border-top-left-radius: 10px;
    border-top-right-radius: 10px;
}

.k-window-action.k-button-md.k-icon-button {
    color: var(--font-color-1);
}

/* ============================================================================
   CALL / SEND MESSAGE WINDOW TITLE — .cw-window
   Two lines of information in a title bar the theme built for one: the theme
   sets `white-space: nowrap` on .k-window-titlebar and `overflow: hidden` with
   `flex-flow: row nowrap` on .k-window-title, so the credit line was cut off
   mid-figure - on a phone at "LOC: $0.0", with INST never visible at all.

   The figures are separate elements (see WindowTitle in Home.razor), which is
   what lets them wrap as a group instead of being one unbreakable string. The
   count is also usually smaller now: CreditFigures() emits only the products
   the company runs, the way CustomerCreditAvailable.razor always has.
   ============================================================================ */

.cw-window .k-window-titlebar {
    white-space: normal;
    align-items: flex-start;
}

.cw-window .k-window-title {
    display: block;
    overflow: visible;
    text-overflow: clip;
    white-space: normal;
    min-width: 0;
}

.cw-title {
    display: flex;
    flex-direction: column;
    gap: .15rem;
    min-width: 0;
}

.cw-title-name {
    font-weight: 600;
    overflow-wrap: anywhere;
}

/* row wrap and not a fixed count: three figures fit one line on a desktop and
   two on a phone, and neither needs a breakpoint to say so. */
.cw-credits {
    display: flex;
    flex-flow: row wrap;
    align-items: baseline;
    gap: .1rem .5rem;
    font-size: .78rem;
    font-weight: 400;
    line-height: 1.3;
}

.cw-credits-label {
    opacity: .85;
}

.cw-credits-label::after {
    content: ":";
}

.cw-credit {
    display: inline-flex;
    align-items: baseline;
    gap: .25rem;
    white-space: nowrap;
}

.cw-credit-key {
    opacity: .85;
}

.cw-credit-value {
    font-variant-numeric: tabular-nums;
    font-weight: 600;
}

/* The close button is a fixed target at the top right, so it stays put whether
   the title runs to one line or three. */
.cw-window .k-window-titlebar-actions {
    margin-block: 0;
    align-self: flex-start;
}

/* ============================================================================
   WORKFLOW ACTIVITY ENTRY - .history-window (ActivityDialog.razor)
   An entry is free text that can hold an unbroken token (a key, a GUID), and
   .k-table-td's nowrap/ellipsis cut it off with no way to read the rest.
   ============================================================================ */

.history-window .k-grid td.activity-entry {
    white-space: normal;
    overflow: visible;
    text-overflow: clip;
    overflow-wrap: anywhere;
}

/* ============================================================================
   RECENT CALLS - .recent-calls
   The list under the call form in the Call Customer window, opened from an
   appointment or an action item on the home screen. Seven columns - called,
   called by, spoke to, call result, disposition, note, number called - needing
   about 735px between them.

   In app.css rather than CallLogComp.razor.css for §3's reason: every selector
   below is a Telerik-rendered element, which a scoped rule cannot reach. The
   labels are our own markup, but they are styled here too so the hide and the
   show sit together rather than in two files whose specificity has to be counted.
   ============================================================================ */

.recent-calls {
    container-type: inline-size;
    container-name: recentcalls;
}

/* Each value carries its own heading for when the row stacks. Hidden while the
   heading row is on screen - display: none rather than a visually-hidden span,
   so in table mode a column is named once rather than twice. */
.recent-calls .rc-label {
    display: none;
    font-size: 9px;
    font-weight: 700;
    letter-spacing: .06em;
    line-height: 1.35;
    text-transform: uppercase;
    color: var(--font-color-muted);
}

/* ---- the row stops being a table below 740px ----
   Seven columns on a phone give about 48px each. Below the breakpoint the row re-lays
   as one labelled record (§10, §12) using the same DOM, so the scroll, the hover and
   the striping keep working and there is no second markup path.

   A tile grid rather than named areas, because these seven fields have no hierarchy.
   8rem holds an uppercase heading over a timestamp - two columns at 390px, four at 640px.

   Deliberately last in the block: a container query adds no specificity, so the
   show-the-label rule below beats the hide above it by source order alone. */
@container recentcalls (max-width: 740px) {

    /* Both shapes: a grid with a Height renders its headings in a separate table
       inside .k-grid-header, one without renders a plain thead. */
    .recent-calls .k-grid-header,
    .recent-calls .k-grid thead {
        display: none;
    }

    /* The colgroup is where Telerik puts the column widths; left in place the tr
       grid resolves against the table's columns rather than its own tracks. */
    .recent-calls .k-grid table,
    .recent-calls .k-grid tbody {
        display: block;
    }

    .recent-calls .k-grid colgroup {
        display: none;
    }

    /* A stacked record is about four lines where a table row was one, so the window's
       250px shows two and a half. !important because Telerik writes Height inline. */
    .recent-calls .k-grid {
        height: 50vh !important;
    }

    .recent-calls .k-grid tr,
    .recent-calls .k-grid .k-table-row {
        display: grid;
        grid-template-columns: repeat(auto-fit, minmax(min(8rem, 100%), 1fr));
        align-items: start;
        gap: .25rem .6rem;
        padding: .35rem .55rem;
        border-bottom: 1px solid var(--hairline);
    }

    .recent-calls .k-grid td,
    .recent-calls .k-grid .k-table-td {
        display: block;
        min-width: 0;
        padding: 0;
        border: none;
        /* Stated rather than inherited: .k-table-td is nowrap with an ellipsis and
           only a second theme rule lets it wrap at all. A stacked note must not
           depend on that reset still being there. */
        white-space: normal;
        overflow: visible;
        overflow-wrap: break-word;
    }

    .recent-calls .rc-label {
        display: block;
    }

    /* The note is prose where the other six are fields, so it takes the record's full
       width. nth-child is safe only because CallLogComp.razor's column set is fixed and
       unconditional - add or move a column and this number moves with it. */
    .recent-calls .k-grid td:nth-child(6),
    .recent-calls .k-grid .k-table-td:nth-child(6) {
        grid-column: 1 / -1;
    }

    /* One cell spanning the row - left to the grid above, "no records" lands in the
       first tile and reads as a record with six empty fields. */
    .recent-calls .k-grid .k-grid-norecords {
        display: block;
        grid-column: 1 / -1;
        padding: .35rem .55rem;
    }
}

/* ============================================================================
   THE SHELL ON A NARROW VIEWPORT - modals, and the content gutter
   Every TelerikWindow and TelerikDialog in this app is sized for a desktop -
   50rem, 875px, 1120px, 1280px, 55rem tall - and neither Telerik nor the theme
   caps that against the viewport. On a phone the box is simply wider than the
   screen and the wrapper clips what hangs off, so on the customer edit dialog
   all eighteen fields were partly outside the viewport with no scroll that
   could reach them. Measured at 320/375/390/430/600/640/641/700/820/1024/1440.

   Two stages, because a phone and a small tablet do not want the same thing:

   1. Always: nothing may exceed the viewport. This alone fixes the 641-820px
      band, where an 800px dialog overhangs by a little and the two-column form
      is still perfectly usable once it stops.
   2. Under 40rem: full-bleed width, one column, body scrolls. A 375px-wide
      two-column form is not worth rescuing - it wants to be a list. Height is
      full-screen except on the add/edit modals (.edit-dialog), which hug their
      own content - see the rule below.

   `100%` and not `100vw` throughout: 100vw includes the classic scrollbar, so
   on a 700px window it resolved 15px wider than the content area and put the
   dialog back off-screen by 8px a side - measured, not theoretical.

   The !important on the .k-window block is not decoration. Telerik's JS writes
   width/height/top/left inline on a window from a desktop measurement, and
   inline styles are the one thing an id selector cannot outrank.

   The dialog block needs it for the same reason. `max-width: 100%` only clamps a
   dialog *wider* than the screen, so the 45-84rem ones looked done - but Telerik
   renders `Width` inline, and the customer components ship 28 dialogs at
   `Width="25rem"` and seven at `Width="25%"`. On a 430px phone that put a confirm
   box at 400px, a changelog at 107px and the details dialog edge to edge: three
   widths for three modals opened from the same panel header. A plain
   `width: 100%` loses to any inline value, hence the !important.

   Depends on no ancestor of a modal having container-type - that would make it
   the containing block for these fixed positions instead of the viewport
   (§16). It is why custresults sits on .customer-search and homeboard on
   .hs-board rather than on either page's wrapper; keep it that way.
   ============================================================================ */

.k-dialog-wrapper > .k-dialog,
.k-window {
    max-width: 100%;
    max-height: 100vh;
    max-height: 100dvh;
}

.k-dialog-wrapper > .k-dialog.edit-dialog {
    max-height: 80vh;
    max-height: 80dvh;
}

@media (max-width: 40rem) {

    .k-dialog-wrapper > .k-dialog {
        width: 100% !important;
        max-width: 100%;
        height: 100vh;
        height: 100dvh;
        max-height: 100vh;
        max-height: 100dvh;
        border-radius: 0;
    }

    /* The add/edit modals keep the full-bleed width but not the full height: a
       confirm-delete form is two or three fields, and 100dvh leaves most of the sheet
       empty. Height follows the content, capped at the viewport so a long form still
       scrolls in its body. */
    .k-dialog-wrapper > .k-dialog.edit-dialog {
        height: auto;
        max-height: 100dvh;
    }

    /* .details-dialog's own 78vh body cap is wrong once the dialog is the whole screen.
       That exception is at the foot of the DETAILS DIALOG block below - same specificity
       either way, so an override written here would lose on source order. */

    /* transform: none is the load-bearing line. A TelerikWindow renders bare as
       `.k-window.k-centered`, which centres with `top/left: 50%` plus
       `transform: translate(-50%, -50%)`. Pinning top/left without clearing the
       transform leaves the window half a screen off the left and top edges. */
    .k-window:not(.k-dialog) {
        position: fixed !important;
        top: 0 !important;
        left: 0 !important;
        transform: none !important;
        width: 100% !important;
        height: 100vh !important;
        height: 100dvh !important;
        max-width: 100%;
        max-height: 100dvh;
        border-radius: 0;
    }

    /* The body is the part that scrolls, so the title bar - and the close
       button on it - stay reachable however long the form is. */
    .k-window-content,
    .k-dialog-content {
        flex: 1 1 auto;
        min-height: 0;
        display: block;
        overflow: auto;
        overscroll-behavior: contain;
        -webkit-overflow-scrolling: touch;
    }

    /* TelerikForm Columns="2" writes grid-template-columns inline, hence the
       !important. Covers Columns="3" and "4" as well - same class, same fix. */
    .k-window .k-form-layout,
    .k-dialog .k-form-layout {
        grid-template-columns: 1fr !important;
    }

    .k-window .k-form-field,
    .k-dialog .k-form-field {
        min-width: 0;
    }

    /* ---- and the shell's own gutter ----
       .content-wrapper insets every page by .5em a side, 16px of a 345px phone. Each
       screen still owns whatever inset its own content wants. */
    .content-wrapper {
        padding-left: 0;
        padding-right: 0;
    }
}

.label {
    font-weight: bold;
    padding: 0.15rem;
    width: 12rem;
}

.language.fa-language {
    margin: 3px 0px 0px 5px;
}

.language-edit {
    border-color: #37a937;
    color: #37a937;
}

    .language-edit .k-input,
    .language-edit .k-input-value-text {
        color: var(--font-color-2);
    }

.language-select {
    border: none;
    color: white;
    background-color: var(--color-1);
    padding: 0 0 0 4px !important;
}

    .language-select:hover {
        background-color: var(--color-2);
        color: var(--font-color-1);
    }

    .language-select option {
        background-color: transparent;
        color: white;
    }

.level1Class {
    background-color: var(--color-2);
    padding-left: 2.5rem;
}

.lms-iframe {
    height: calc(100vh - 98px);
    width: 100%;
    /* Hard code white or else legacy pages look funky*/
    background-color: white;
    border-radius: 4px;
}

.main-layout {
    background-color: var(--color-2);
    display: flex;
}

.menu-path {
    font-size: 12px;
    color: #bbbbbb;
}

.navbar {
    padding: 0;
    width: 100%;
    background-color: var(--color-3);
}

.navbar-brand {
    margin-left: 0 !important;
    text-decoration: none;
}

.no-border {
    border-width: 0;
}

.no-headers-grid {
    border-radius: .5rem;
}

    .no-headers-grid .k-grid-content {
        border-radius: .5rem;
    }

    .no-headers-grid .k-grid-header {
        display: none;
    }

.no-scroll {
    overflow-y: hidden;
}

    .no-scroll ::deep .k-window-content {
        overflow-y: hidden;
    }

.noteadd-text {
    color: var(--font-color-1) !important;
}

.noteadd-title {
    color: var(--font-color-2) !important;
}

.pop-out {
    -webkit-overflow-scrolling: touch;
    background-color: var(--color-1) !important;
    background-color: white;
    border-radius: 4px;
    box-shadow: 0 2px 4px -1px rgb(0 0 0 / 20%), 0 4px 5px 0 rgb(0 0 0 / 14%), 0 1px 10px 0 rgb(0 0 0 / 12%);
    color: var(--font-color-1);
    font-size: 1em;
    max-height: calc(100vh - 48px);
    max-width: 400px;
    min-height: 64px;
    outline: 0;
    overflow: auto;
    pointer-events: auto;
    position: absolute;
    right: 1.5em;
    top: 4em;
    z-index: 1000;
}

.public-record {
    display: grid;
    grid-template-columns: 1fr 1fr 1fr 1fr;
    margin-bottom: 1rem;
    color: var(--font-color-2);
}

.public-record-title {
    grid-row: 1;
    grid-column: 1 / span 4;
    display: grid;
    grid-template-columns: 1fr 1fr 1fr 1fr;
    color: var(--font-color-1);
}

.profile-circle {
    border-radius: 50%;
    background-color: var(--color-1);
    text-align: center;
    padding: 0.5rem;
    display: inline;
    cursor: pointer;
}

.profile-menu {
    height: unset;
    margin: 0.5rem 0 0 0;
}

.ofac-whitelist-dialog {
    min-height: 260px;
    max-height: 602px;
}

.qa-btn {
    background-color: var(--color-2);
    border-radius: .5rem;
    cursor: pointer;
    display: table;
    height: 6rem;
    margin: 0 auto;
    padding-bottom: .25rem;
    width: 6rem;
}

    .qa-btn:hover {
        filter: grayscale(30%);
    }

    .qa-btn:active {
        box-shadow: none;
        filter: grayscale(60%);
        height: calc(6rem - .25rem);
        margin-left: .4rem;
        margin-top: .4rem;
        width: calc(6rem - .25rem);
    }

.quick-actions {
    list-style-type: none;
    margin: 0;
    padding: 0;
}

    .quick-actions ul {
        margin: 0;
    }

    .quick-actions li {
        color: var(--font-color-1);
        display: inline-block;
        height: 100%;
        padding: 0;
        vertical-align: top;
    }

.quick-actions-back {
    width: 1.5rem;
    padding: 0 !important;
}

.record-header {
    font-weight: bold;
}

.repay.edit-dialog .k-dialog-content {
    overflow-y: hidden;
}

.search-box {
    background-color: var(--accent-1);
    color: var(--font-color-1);
}

.settings-dropdown {
    display: inline-table !important;
    margin: 0.25rem;
    width: 4rem;
}

.slide-left {
    -webkit-animation: slide 0.5s forwards;
    animation-name: slide-left;
    animation: slide 0.5s forwards;
}

span.k-pager-input.k-label {
    color: white !important;
}

span.k-switch-thumb.k-rounded-full {
    background-color: #5889b3;
}

@-webkit-keyframes slide-left {
    from {
        margin-left: 250px;
    }

    to {
        margin-left: 0%;
    }
}

@keyframes slide-left {
    from {
        margin-left: 250px;
    }

    to {
        margin-left: 0%;
    }
}

.slide-right {
    -webkit-animation: slide 0.5s backwards;
    animation-name: slide-right;
    animation: slide 0.5s backwards;
}

@-webkit-keyframes slide-right {
    from {
        margin-left: -250px;
    }

    to {
        margin-left: 0%;
    }
}

@keyframes slide-right {
    from {
        margin-left: -250px;
    }

    to {
        margin-left: 0%;
    }
}

.snippet-button {
    display: inline;
    margin: .5rem 0;
}

.step-block {
    display: flex;
    width: 100%;
    justify-content: space-between;
    align-items: center;
}

    .step-block .markup-block {
        display: inline-block;
    }

    .step-block .k-input,
    .step-block .k-dropdownlist {
        max-width: 30%;
    }

    .step-block .save-button {
        font-size: 1em;
    }

    .step-block .k-radio-list {
        display: flex;
        flex-direction: row;
        gap: 1rem;
    }

    .step-block .k-dropzone {
        background: var(--accent-2);
        border: none;
        flex-direction: row-reverse;
    }

.system-info-row {
    background-color: var(--color-2);
    border-radius: 4px;
    margin: .25rem !important;
    padding: 0 0.5em 0 0.5em;
    box-shadow: rgb(0 0 0 / 35%) 0px 1px 2px;
    display: inline-block;
    width: fit-content;
}

.t-component {
    background-color: var(--accent-2);
    border-radius: .5rem;
    padding: 1rem;
}

.table > :not(caption) > * > * {
    padding: 0.25rem 0.25rem;
}

.tabstrip {
    background-color: var(--accent-2);
    border-radius: 4px;
}

    .tabstrip .k-tabstrip-items-wrapper .k-item {
        color: var(--font-color-2) !important;
    }

.template-wrapper {
}

    .template-wrapper .row {
        margin: 0;
    }

    .template-wrapper .col {
        margin: 0;
        padding: 0;
    }

thead.k-table-thead {
    background-color: var(--header-bar);
}

.top-row {
    z-index: 3;
}

.valid.modified:not([type=checkbox]) {
    outline: 1px solid #26b050;
}

.validation-message {
    color: red;
}

.value-right {
    text-align: right;
}

.white-arrow .k-tooltip * {
    color: var(--font-color-1);
}

.white-arrow {
    display: inline-block;
}

    .white-arrow .k-icon-button {
        display: inline-block;
    }

        .white-arrow .k-icon-button .k-icon {
            font-size: x-large;
            margin: 0;
        }

    .white-arrow .k-textbox {
        margin-bottom: .5rem;
    }

.widgets {
    align-items: flex-start;
    display: grid;
    gap: 40px;
    grid-template-columns: repeat(4, minmax(0px, 1fr));
}

.WorkflowStepDrawerContent {
    margin-top: 0.5rem;
    width: calc(100% - .5rem);
}

    .WorkflowStepDrawerContent .k-drawer-item {
        color: var(--font-color-2);
    }

        .WorkflowStepDrawerContent .k-drawer-item .k-item-text {
            padding-left: .25rem;
        }

        .WorkflowStepDrawerContent .k-drawer-item .k-icon {
            margin: 0;
        }

    .WorkflowStepDrawerContent .k-drawer-mini .k-drawer-wrapper {
        width: 2rem !important;
    }

    .WorkflowStepDrawerContent .k-drawer-content {
        display: block;
        font-size: 18px;
        padding-top: 0px;
        padding-bottom: 0px;
        padding-right: 3px;
        padding-left: 0;
        margin-top: -0.5rem;
    }

    .WorkflowStepDrawerContent .fa-circle-check {
        color: #237631;
    }

    .WorkflowStepDrawerContent .fa-circle {
        color: #237631;
    }

.WorflowStepDrawerContent .conponent-container {
    align-items: flex-start;
    background-color: rgb(238, 238, 238);
    border-radius: 0.5rem;
    color: var(--font-color-1);
    font-size: 13px;
    margin: 0rem 0.5rem 2rem;
    padding: 0px;
}

.lms-telerik-tooltip {
    max-width: 350px;
    margin: 10px;
    border-radius: 5px;
}

.error-text-large {
    color: #d51923;
    font-size: 21px;
    margin-top: 8px
}

.workflow-step {
    display: flex;
    flex-direction: column;
    gap: 1rem;
}

.highlight-text {
    background-color: #f7f883;
}


/* Form Required Field indicator */
.required-field.k-form-label:after,
.required-field .k-form-label:after {
    content: "*";
    color: red;
    vertical-align: super;
    margin-left: 1px;
}
/* Reporting CSS */
.report-grid {
    background-color: var(--accent-3);
    color: var(--font-color-1);
    border-radius: 4px;
    box-shadow: rgb(0 0 0 / 35%) 0px 1px 2px;
    font-size: 12px;
    margin: .5rem .25rem;
    padding: 0;
    height: fit-content;
    width: 99%;
}

    .report-grid .k-button {
        height: 28px;
        padding: 10px;
    }

    .report-grid a {
        color: var(--link-color) !important;
    }

    .report-grid .k-grid-footer {
        color: var(--font-color-1);
        background-color: #5889b3;
    }

    .report-grid .k-table-tfoot {
        color: var(--font-color-1);
        background-color: #5889b3;
    }

.report-header {
    background-color: var(--accent-3);
    color: var(--font-color-2);
    display: flex;
    text-align: center;
    justify-content: center;
    border-radius: 4px;
    margin: .5rem .25rem;
    width: 99%;
    left: 0;
    top: 0;
}

.report-description {
    list-style-type: none;
    margin-bottom: 0.5px;
}

.report-footer {
    color: var(--font-color-1);
    font-size: 12px;
    text-align: center;
    width: 100%;
    padding: 0 15px 0 10px;
    bottom: 0;
}

.footer-section-left {
    width: 34%;
    float: left;
    text-align: left;
}

.footer-section-center {
    width: 33%;
    float: left;
    text-align: center;
}

.footer-section-right {
    width: 32%;
    float: right;
    text-align: right;
}

/* Debugging CSS */
.debug-snippet {
    padding: 5px;
}

    .debug-snippet pre {
        border-radius: 1rem;
        background-color: #000;
        margin: 0;
        padding: 10px;
    }

    .debug-snippet code {
        display: block;
        overflow-x: auto;
        font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
        font-size: 14px;
        color: lime;
    }

    .debug-snippet ul {
        margin: 0;
        padding: 0;
    }

        .debug-snippet ul li {
            margin-bottom: 1px;
        }

    .debug-snippet li::before {
        content: "\2022"; /* Unicode for bullet symbol */
        margin: 10px;
        margin-right: 5px; /* Add some spacing between the bullet and text */
        color: #fff; /* Customize the bullet color */
    }

.k-progressbar-chunk {
    background-color: var(--progressbar-chunk-color);
}

.k-label-switch {
    color: var(--font-color-2);
}

.k-grid-content {
    background-color: var(--accent-2);
}

.component-step {
    color: var(--font-color-2);
}

.label {
    color: var(--font-color-2);
}

/* Key / Value formatting */

dl {
    display: table;
}

    dl > div {
        display: table-row;
    }

        dl > div > dt, dl > div > dd {
            display: table-cell;
            padding: 0.25em;
        }

        dl > div > dt {
            font-weight: bold;
        }

            dl > div > dt::after {
                content: ':';
            }

.component-item-details {
    padding: 0.25rem 0.5rem;
}

.k-radio {
    border-color: grey;
}

.k-list-group-sticky-header {
    font-weight: 700;
}

.k-list-group-item {
    font-weight: 700;
}

.action-window .k-dialog-content {
    padding: 0;
    overflow: hidden;
}

.k-grid td.k-selected,
.k-grid .k-table-row.k-selected > td,
.k-grid .k-table-td.k-selected,
.k-grid .k-table-row.k-selected > .k-table-td {
    background-color: var(--selected-1);
}

/* k-icon reset */
.k-icon.reset-icon {
    width: inherit;
    height: inherit;
    display: inline-block;
    outline: inherit;
    text-transform: inherit;
    text-decoration: inherit;
    vertical-align: inherit;
    font-size: inherit;
}

.error {
    color: red;
    font-style: italic;
}

.markup-block {
    display: inline-block;
}

.btn-large {
    font-size: 1.25rem;
    color: white;
}

.photo-btn {
    text-align: center;
    border-width: 1px;
    border-style: solid;
    border-radius: 4px;
    margin: 1rem;
    padding: 1rem;
}

.btn-display {
    width: 327px;
    margin: 0 auto;
}

.custom-upload-photo {
    text-align: center;
    padding: .5rem;
}

.webcam-video {
    border-radius: 4px;
}

.float-right {
    float: right;
}

.float-left {
    float: left;
}

.customer-merge-window .k-dialog-content {
    overflow-y: auto;
}

.header-item a {
    color: var(--font-color-1);
    text-decoration: underline;
}

/* Action Item Row Colors */
.ai-row-warn {
    background-color: #ffc !important;
    color: #f00 !important;
}

.ai-row-warn:hover {
    background-color: #d3dbe5 !important;
    color: #f00 !important;
}

.ai-row-warn-alt {
    background-color: #FFF1AD !important;
    color: #f00 !important;
}

.ai-row-warn-alt:hover {
    background-color: #d3dbe5 !important;
    color: #f00 !important;
}

.ai-row-notice-first-round {
    background-color: #cff !important;
    color: #000;
}

.ai-row-notice-second-round {
    background-color: #63f6a1 !important;
    color: #000;
}

.ai-row-locked {
    background-color: #e9ecef !important;
    color: #6c757d !important;
}

.ai-row-locked:hover {
    background-color: #dee2e6 !important;
    color: #6c757d !important;
}


/* NEW STYLES POST TELERIK UPDATE */
.k-rounded {
    border-radius: 4px;
}

.k-button {
    font-size: 11px;
    padding: 3px 6px;
    border-radius: 4px;
    border-color: rgba(0, 0, 0, 0.08);
}

.k-grid td, .k-grid .k-table-td {
    padding-block: 8px;
    padding-inline: 12px;
}

.k-button-group .k-button {
    background-color: var(--accent-4);
    color: var(--font-color-2);
    border-color: rgba(0, 0, 0, 0.08);
}

.k-button.k-selected {
    background-color: var(--color-2) !important;
    color: var(--font-color-1);
}

.k-button-group .k-button {
    background-color: var(--accent-4);
    color: var(--font-color-2);
}

.k-button.k-selected {
    border-color: #22597d;
    color: #fff;
    background-color: #22597d;
}

.k-active.k-tabstrip-item {
    border-radius: 4px 4px 0 0;
    background-color: var(--accent-1);
}

.k-upload-button {
    border: 1px solid rgba(0, 0, 0, 0.08);
}

.k-input.k-textarea {
    border-color: var(--accent-4);
}

.k-button-primary {
    border-color: #22597d;
    color: #fff;
    background-color: #22597d;
    background-image: linear-gradient(rgba(0, 0, 0, 0), rgba(0, 0, 0, 0.02));
}

.k-chip {
    background-color: var(--accent-4);
    color: var(--font-color-2);
    border-color: rgba(0, 0, 0, 0.08);
}

.k-input {
    border-color: var(--accent-4);
    border-radius: 4px;
    color: var(--font-color-2);
}

.k-pager {
    padding-inline: 8px;
    padding-block: 8px;
    gap: 14px;
}

.k-picker {
    border-color: rgba(0, 0, 0, 0.08);
    color: var(--font-color-2);
    background-color: var(--accent-3);
    background-image: linear-gradient(rgba(0, 0, 0, 0), rgba(0, 0, 0, 0.02));
}

.k-checkbox {
    width: 16px;
    height: 16px;
}

.k-switch .k-switch-label-on {
    left: 6px;
}

.k-switch .k-switch-label-off {
    right: 6px;
}

.k-switch.k-switch-on .k-switch-thumb-wrap {
    left: calc(100% - 0.5rem);
    border-radius: 4px;
}

.k-switch-thumb {
    height: .75rem;
    width: .75rem;
    border-radius: 4px;
}

span.k-switch-thumb {
    background-color: #5889b3 !important;
}

.k-switch-on .k-switch-thumb {
    border-color: rgba(0, 0, 0, 0.08);
    color: var(--font-color-2);
    background-color: var(--accent-3);
}

.btn-comm-toggle.k-switch-off .k-switch-track {
    background-color: var(--accent-1);
    color: var(--font-color-2);
    border-color: var(--accent-4);
}

.k-switch.k-switch-off .k-switch-thumb-wrap {
    left: 0.5rem;
}

.k-switch, .k-switch-track {
    height: 1rem;
    width: 3rem;
    border-radius: 4px;
}

.switch-container-item-right {
    font-size: 0.7rem;
}

.k-calendar-header .k-title, .k-calendar-header .k-calendar-title {
    font-weight: bold;
    color: black;
}

/* ============================================================================
   HOME SCREEN — #HomeScreenComponents
   Route /home (and the five location-scoped variants), host Pages/Home.razor.
   The fourth screen brought onto vergent-lms-design.md, and the first whose
   problem is a wide numeric matrix rather than a list of records.

   Scoped to the id on the page's wrapper for the reason in §3: .component,
   .component-title and every .k-* selector here are shared with ~30 other
   screens, and an ID selector outranks both those rules and the shared
   components' own [b-*] isolation attributes without !important.
   ============================================================================ */

#HomeScreenComponents {
    background-color: var(--page-ground);
    padding: 0 .25rem .5rem;
}

/* Sticks the location bar + tab strip to the top of the scrolling ancestor
   (.content-wrapper, overflow-y: auto) as one unit while a tall board (e.g. many
   At-a-Glance grids, or a long Leads/Messages list) scrolls underneath. The
   background-color is required, not decorative: without an opaque ground of its own,
   the board's content shows through beneath it as it scrolls past. z-index just needs
   to clear the highest one already in this file - the glance grid's sticky frozen
   column (z-index: 2, see .hs-glance-wide below).

   The top padding #HomeScreenComponents used to carry moved onto this element instead
   of staying on its parent: padding on an ancestor still pushes a sticky child down
   from its resting position, so the header visibly slid up that distance before it hit
   top: 0 and stuck - a one-time jump on the first scroll. Padding on the sticky element
   itself doesn't move its box at all, so the header now sits at the same on-screen
   position from the very first pixel of scroll. */
#HomeScreenComponents .hs-header {
    position: sticky;
    top: 0;
    z-index: 5;
    padding-top: .5rem;
    background-color: var(--page-ground);
}

#HomeScreenComponents .hs-locationbar {
    background-color: var(--accent-1);
    border: 1px solid var(--accent-4);
    border-bottom: 1px solid var(--hairline);
    border-radius: 4px 4px 0 0;
    box-shadow: var(--panel-shadow);
    margin: 0 .25rem;
    padding: .1rem .3rem;
}

#HomeScreenComponents .bc-home {
    background-color: transparent;
    border: none;
    color: var(--font-color-2);
    font-size: 11.5px;
}

#HomeScreenComponents .bc-home .k-breadcrumb-link,
#HomeScreenComponents .bc-home .k-breadcrumb-root-link {
    padding: .1rem .3rem;
    border-radius: 4px;
    font-weight: 500;
    color: var(--affordance-color);
}

    #HomeScreenComponents .bc-home .k-breadcrumb-link:hover,
    #HomeScreenComponents .bc-home .k-breadcrumb-link.k-hover,
    #HomeScreenComponents .bc-home .k-breadcrumb-root-link:hover,
    #HomeScreenComponents .bc-home .k-breadcrumb-root-link.k-hover {
        background-color: var(--tint-bg);
        color: var(--affordance-color);
    }

    #HomeScreenComponents .bc-home .k-breadcrumb-link:focus-visible,
    #HomeScreenComponents .bc-home .k-breadcrumb-root-link:focus-visible {
        outline: 2px solid var(--affordance-color);
        outline-offset: -2px;
        box-shadow: none;
    }

/* The deepest level is where you are, not somewhere to go: it reads as text. */
#HomeScreenComponents .bc-home .k-breadcrumb-container .k-breadcrumb-item:last-child .k-breadcrumb-link {
    color: var(--font-color-2);
    font-weight: 600;
    cursor: default;
}

#HomeScreenComponents .bc-home .k-breadcrumb-delimiter,
#HomeScreenComponents .bc-home .k-breadcrumb-delimiter-icon {
    color: var(--font-color-muted);
    opacity: 1;
}

/* ---- the path wraps rather than being cut off ----
   The theme lays the items out `flex-flow: row nowrap` inside `overflow: hidden`, which
   puts the deepest levels past the right edge on a phone. CollapseMode.Wrap is the
   declared intent, but the class it adds (k-breadcrumb-wrap) has no rule in either the
   custom or the stock theme, so the wrapping is these four rules.

   `flex: 1 1 0` on the item container rather than `flex-wrap` on .bc-home: the root
   "Company" link is a separate <ol>, so wrapping the nav costs it a whole line. */
#HomeScreenComponents .bc-home .k-breadcrumb-container {
    flex: 1 1 0;
    flex-wrap: wrap;
    overflow: visible;
    min-width: 0;
}

#HomeScreenComponents .bc-home .k-breadcrumb-root-item-container {
    overflow: visible;
}

    /* The items are `flex: none`, so without these they size to max-content and overflow
       however the text is allowed to wrap. */
    #HomeScreenComponents .bc-home .k-breadcrumb-item,
    #HomeScreenComponents .bc-home .k-breadcrumb-root-item {
        overflow: visible;
        max-width: 100%;
        min-width: 0;
    }

    #HomeScreenComponents .bc-home .k-breadcrumb-link,
    #HomeScreenComponents .bc-home .k-breadcrumb-root-link {
        overflow: visible;
        white-space: normal;
        overflow-wrap: anywhere;
    }

#HomeScreenComponents .hs-tabs {
    display: flex;
    flex-wrap: wrap;
    align-items: stretch;
    background-color: var(--accent-1);
    border: 1px solid var(--accent-4);
    border-top: none;
    border-radius: 0;
    box-shadow: var(--panel-shadow);
    margin: 0 .25rem;
    padding: 0 .25rem;
}

#HomeScreenComponents .hs-tab {
    appearance: none;
    background: none;
    border: none;
    border-radius: 0;
    padding: .35rem .7rem;
    font: inherit;
    font-size: 11.5px;
    font-weight: 600;
    color: var(--font-color-muted);
    cursor: pointer;
    min-height: 28px;
}

    #HomeScreenComponents .hs-tab:hover {
        background-color: var(--row-hover);
        color: var(--font-color-2);
    }

    #HomeScreenComponents .hs-tab:focus-visible {
        outline: 2px solid var(--affordance-color);
        outline-offset: -2px;
    }

    /* An inset shadow rather than a border, so the label does not shift 2px when
       the tab becomes active. */
    #HomeScreenComponents .hs-tab.is-active {
        color: var(--affordance-color);
        box-shadow: inset 0 -2px 0 var(--affordance-color);
    }

/* Unread count pill on the Messages tab label. */
#HomeScreenComponents .hs-badge {
    display: inline-block;
    margin-left: .35rem;
    padding: 0 .4rem;
    min-width: 1.1rem;
    border-radius: 1rem;
    background-color: #c00;
    color: #fff;
    font-size: 10px;
    font-weight: 700;
    line-height: 1.4rem;
    text-align: center;
}

/* ---- messages tab: inbox list beside the open conversation ----
   The two columns are a TelerikSplitter, which supplies its own drag handle between the panes
   and owns their widths - the fixed height below gives the panes' own content a stable height so
   the loader swapping in for content (a full list/thread, an empty state, or the small spinner)
   never changes how much room either column takes up and snaps the row back afterward.

   That height fills down to the footer rather than stopping at an arbitrary fixed size: #HomeScreenComponents
   sizes to its own content rather than stretching to the viewport, so a short fixed height here
   left a visible gap of page background beneath the panel before the footer. 180px is the combined
   height of everything else sharing this viewport column - the top bar, the breadcrumb/tab-strip
   bar above, and the footer below, plus a small buffer - each already a fixed-height bar; if those
   bars' own heights change this needs to move with them, the same tradeoff already accepted by the
   .lms-iframe and other calc(100vh - Npx) rules elsewhere in this file.

   Measured at 165px the panel's bottom edge actually overlapped the footer's top edge by ~6px
   (fractional layout rounding beyond what the three bars' own heights account for), leaving only
   ~2-3px of visible gap above the footer - the compose box's Send button read as flush against it.
   180px clears that overlap and leaves a deliberate ~12-15px gap instead. */
#HomeScreenComponents .hs-messages-board {
    padding: .5rem;
}

#HomeScreenComponents .hs-messages-splitter {
    height: calc(100vh - 180px);
}

#HomeScreenComponents .hs-messages-inbox {
    height: 100%;
    overflow-y: auto;
    background-color: var(--panel-bg, #fff);
    padding: .5rem;
}

#HomeScreenComponents .hs-messages-conversation {
    height: 100%;
    background-color: var(--panel-bg, #fff);
    padding: .5rem;
}

#HomeScreenComponents .hs-messages-empty {
    color: var(--font-color-muted);
    font-style: italic;
    padding: 1rem;
}

/* Single-pane - the lead detail lives in a modal (TelerikWindow) rather than a second
   pane, so the board carries the same fixed viewport height the messages splitter
   carries for its two panes - see the comment above .hs-messages-splitter. */
#HomeScreenComponents .hs-leads-board {
    padding: .5rem;
}

#HomeScreenComponents .hs-leads-inbox {
    height: calc(100vh - 180px);
    overflow-y: auto;
    background-color: var(--panel-bg, #fff);
    padding: .5rem;
}

/* Same fixed-viewport-height reasoning as .hs-leads-board/.hs-leads-inbox above - a single
   pane, no modal detail view to size around. */
#HomeScreenComponents .hs-notifications-board {
    padding: .5rem;
}

#HomeScreenComponents .hs-notifications-inbox {
    height: calc(100vh - 180px);
    overflow-y: auto;
    background-color: var(--panel-bg, #fff);
    padding: .5rem;
}

/* ---- the board ----
   The query container for every responsive stage at the foot of this block. Declared
   here and not on #HomeScreenComponents: container-type makes an element the containing
   block for its position: fixed descendants (§16), and the page's three TelerikWindows
   sit inside the wrapper as siblings of .hs-board.

   Container queries and not @media, because the left nav is fit-content, so viewport
   width says nothing about the width this board actually has (§7). */
#HomeScreenComponents .hs-board {
    container-type: inline-size;
    container-name: homeboard;
}

#HomeScreenComponents .hs-toolbar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .35rem .5rem;
    padding: .4rem .55rem .15rem;
}

#HomeScreenComponents .hs-toolbar-label {
    margin: 0;
    font-size: 11px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: .06em;
    color: var(--font-color-muted);
}

#HomeScreenComponents .hs-grid-picker {
    width: 100%;
    max-width: 20rem;
}

/* ---- panels ----
   §4's chrome. The shared .component is an --accent-3 card with a 35%-black
   shadow, which is a heavier surface than this document's panels. */
#HomeScreenComponents .component {
    background-color: var(--accent-1);
    border: 1px solid var(--accent-4);
    border-radius: 4px;
    box-shadow: var(--panel-shadow);
    color: var(--font-color-2);
    margin: .5rem .25rem 0;
    overflow: hidden;
}

#HomeScreenComponents .hs-panel-title {
    display: flex;
    align-items: center;
    gap: .4rem;
    width: 100%;
    appearance: none;
    background-color: var(--header-bar);
    border: none;
    border-radius: 4px 4px 0 0;
    color: var(--font-color-1);
    font: inherit;
    font-size: 11px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: .06em;
    text-align: left;
    min-height: 29px;
    padding: .25rem .5rem;
    cursor: pointer;
}

    /* A lightened --color-1, hand-mixed because the token is themeable and CSS has no
       "same colour, one step up" that survives a company overriding it. Retune this
       whenever --color-1 changes. */
    #HomeScreenComponents .hs-panel-title:hover {
        background-color: var(--header-bar-hover);
    }

    #HomeScreenComponents .hs-panel-title:focus-visible {
        outline: 2px solid var(--accent-1);
        outline-offset: -3px;
    }

#HomeScreenComponents .hs-panel-name {
    min-width: 0;
    overflow-wrap: break-word;
}

/* The §7 chevron, read for a filled bar. A local copy because the #CustomerComponents
   .cust-chevron one is out of reach behind that id. Sets no colour, so it inherits. */
#HomeScreenComponents .hs-chevron {
    flex: none;
    display: inline-block;
    font-size: 13px;
    line-height: 1;
    transition: transform .15s ease;
}

    #HomeScreenComponents .hs-chevron.is-open {
        transform: rotate(90deg);
    }

/* position: relative for the panel's TelerikLoaderContainer. A panel laid out inline is
   outside this contract and will not track it (§17). */
#HomeScreenComponents .hs-glance-body {
    position: relative;
}

/* .cust-empty from §4, for a location with no configured grids at all: a tab with
   nothing under it reads as a page that failed to load. */
#HomeScreenComponents .cust-empty {
    padding: .25rem .55rem;
    font-size: 11px;
    color: var(--font-color-muted);
}

/* ---- the filter bars ----
   Sort, the amount range and the product filters, over the Action Items and
   Appointments queues. */
#HomeScreenComponents .hs-filterbar {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: .4rem .75rem;
    padding: .4rem .55rem;
    border-bottom: 1px solid var(--hairline);
}

#HomeScreenComponents .hs-field {
    display: flex;
    flex-direction: column;
    gap: .1rem;
    min-width: 0;
    flex: 1 1 12rem;
}

#HomeScreenComponents .hs-sort-dropdown {
    width: 100%;
    max-width: 26rem;
}

#HomeScreenComponents .hs-range {
    display: flex;
    align-items: center;
    gap: .35rem;
    min-width: 0;
}

#HomeScreenComponents .hs-range-input {
    flex: 1 1 5.5rem;
    min-width: 0;
    max-width: 9rem;
}

#HomeScreenComponents .hs-range-sep {
    flex: none;
    font-size: 11px;
    color: var(--font-color-muted);
}

/* §8's control metrics, on the wrapper rather than the inner input: Class lands on
   the wrapper and an unmatched lowercase class lands on the <input>, so styling the
   latter draws a fill and a hairline inside Telerik's own bordered box (§16). */
#HomeScreenComponents .hs-toolbar .k-input,
#HomeScreenComponents .hs-toolbar .k-picker,
#HomeScreenComponents .hs-filterbar .k-input,
#HomeScreenComponents .hs-filterbar .k-picker {
    min-height: 28px;
    border-radius: 4px;
    border: 1px solid var(--accent-4);
    background-color: var(--accent-1);
    background-image: none;
    box-shadow: none;
    font-size: 12px;
    color: var(--font-color-2);
}

    #HomeScreenComponents .hs-toolbar .k-input:focus-within,
    #HomeScreenComponents .hs-toolbar .k-picker:focus-within,
    #HomeScreenComponents .hs-filterbar .k-input:focus-within,
    #HomeScreenComponents .hs-filterbar .k-picker:focus-within {
        outline: 2px solid var(--affordance-color);
        outline-offset: -1px;
        box-shadow: none;
    }

#HomeScreenComponents .hs-filterbar .k-input-inner,
#HomeScreenComponents .hs-toolbar .k-input-inner {
    padding-block: .1rem;
    font-size: 12px;
}

/* ---- the product chips ----
   §8's chip: the status pill's shape (fully rounded, .4rem sides) plus the three things
   that make it a control rather than a label - a fill, a hover border and a focus ring.
   aria-pressed carries the on/off state, which a fill cannot (§16).

   Type is 11px against the customer page's 10px, with padding-block the pill has none of:
   this is the primary filter on a queue worked on a phone, and a 15px-tall target is not
   tappable. Shape and colour are unchanged, so the two still read as one family. */
#HomeScreenComponents .hs-chipset {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .25rem;
    min-width: 0;
    flex: 0 1 auto;
    margin-left: auto;
}

#HomeScreenComponents .hs-chip {
    appearance: none;
    font: inherit;
    font-size: 11px;
    line-height: 1.5;
    min-height: 24px;
    padding: .15rem .5rem;
    border-radius: 12px;
    border: 1px dashed var(--accent-4);
    background-color: transparent;
    color: var(--font-color-muted);
    cursor: pointer;
}

    #HomeScreenComponents .hs-chip.is-on {
        border-style: solid;
        border-color: var(--tint-border);
        background-color: var(--tint-bg);
        color: var(--affordance-color);
    }

    #HomeScreenComponents .hs-chip:hover {
        border-color: var(--affordance-color);
    }

    #HomeScreenComponents .hs-chip:focus-visible {
        outline: 2px solid var(--affordance-color);
        outline-offset: 1px;
    }

/* The reveal for the zero buckets. A text affordance (§8), labelled with what it
   does rather than a bare chevron, and display: none above the stacking breakpoint
   - see the responsive stages. */
#HomeScreenComponents .hs-zero-toggle {
    display: none;
    appearance: none;
    background: none;
    border: none;
    border-radius: 4px;
    padding: .1rem .3rem;
    font: inherit;
    font-size: 11.5px;
    color: var(--affordance-color);
    cursor: pointer;
}

    #HomeScreenComponents .hs-zero-toggle:hover {
        background-color: var(--tint-bg);
    }

    #HomeScreenComponents .hs-zero-toggle:focus-visible {
        outline: 2px solid var(--affordance-color);
        outline-offset: -2px;
    }

/* ---- grids: the flat table treatment ----
   The language of the loans card and the search results (§10): white ground, no border
   of its own because the panel around it is the card, small dark uppercase headings over
   one --accent-4 hairline, --hairline between rows.

   No fill on the heading row: `.k-grid .k-grid-header` fills with --color-1 app-wide,
   which puts a second blue bar 30px under each panel's own. */
#HomeScreenComponents .k-grid,
#HomeScreenComponents .k-grid-content,
#HomeScreenComponents .k-grid-pager,
/* Every element in the header chain, because the blue is not on the one you would guess.
   Besides `.k-grid .k-grid-header`, app.css carries
   `thead.k-table-thead { background-color: var(--color-1) }` - element-qualified, so no
   `.k-grid`-based override reaches it - and the theme adds a third coat
   (`.k-table-thead { background-color: #fafafa }`). Name all of them rather than
   trusting one to be the painted one. */
#HomeScreenComponents .k-grid .k-grid-header,
#HomeScreenComponents .k-grid .k-grid-header-wrap,
#HomeScreenComponents .k-grid .k-grid-header table,
#HomeScreenComponents .k-grid thead,
#HomeScreenComponents .k-grid thead.k-table-thead,
#HomeScreenComponents .k-grid .k-grid-header tr {
    background-color: var(--accent-1);
}

#HomeScreenComponents .k-grid {
    border: none;
    /* Stated even though the width is 0: `border: none` leaves border-color at
       currentColor, and half a dozen Telerik grid elements take `border-color: inherit`
       (.k-grid-header, .k-grid-header-wrap, .k-table-thead, .k-table-row, .k-table-th,
       .k-table-td). Any that ends up with a non-zero width then draws a near-black rule
       through a panel whose whole vocabulary is hairlines. */
    border-color: var(--accent-4);
    font-size: 12px;
    color: var(--font-color-2);
}

#HomeScreenComponents .k-grid .k-grid-header {
    border-bottom: 1px solid var(--accent-4);
}

/* Headings wrap rather than truncate: a bucket heading is the whole meaning of the
   number under it, so two lines beat half a word. */
#HomeScreenComponents .k-grid th,
#HomeScreenComponents .k-grid .k-table-th,
#HomeScreenComponents .k-grid .k-header {
    padding: .25rem .5rem;
    border-left: none;
    border-right: none;
    background-color: transparent;
    font-size: 11px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: .06em;
    color: var(--font-color-2);
    text-align: left;
    white-space: normal;
    vertical-align: bottom;
}

    /* Stated on the descendants too, not just the cell. Telerik wraps heading text in
       .k-cell-inner > .k-link > .k-column-title, and a colour on the th alone reaches
       those only while none of them carries a rule of its own - not a safe assumption
       against a theme. */
    #HomeScreenComponents .k-grid th,
    #HomeScreenComponents .k-grid th *,
    #HomeScreenComponents .k-grid .k-table-th,
    #HomeScreenComponents .k-grid .k-table-th * {
        color: var(--font-color-2);
    }

/* background-color: transparent, not a colour. The Action Items grid marks
   past-due, called and locked records by filling the row (.ai-row-*), and an
   opaque cell would paint over every one of them. */
#HomeScreenComponents .k-grid td,
#HomeScreenComponents .k-grid .k-table-td {
    padding: .35rem .5rem;
    border-left: none;
    border-right: none;
    border-bottom: 1px solid var(--hairline);
    background-color: transparent;
    color: inherit;
    text-align: left;
    vertical-align: top;
    white-space: normal;
    overflow-wrap: break-word;
}

#HomeScreenComponents .k-grid .k-table-row:hover,
#HomeScreenComponents .k-grid tr:hover {
    background-color: var(--row-hover);
}

/* app.css sets .k-grid .k-icon to --font-color-1 for the filled header row it no
   longer has; white pager arrows on a white pager are invisible. */
#HomeScreenComponents .k-grid .k-icon,
#HomeScreenComponents .k-grid .k-svg-icon,
#HomeScreenComponents .k-grid .k-button-icon {
    color: var(--font-color-2);
}

#HomeScreenComponents .k-grid-pager {
    padding: .25rem .5rem;
    border-top: 1px solid var(--hairline);
    border-radius: 0;
    margin: 0;
    font-size: 11px;
    color: var(--font-color-muted);
}

/* An absence reads as an absence rather than as content (§4). */
#HomeScreenComponents .k-grid-norecords,
#HomeScreenComponents .k-grid-norecords td,
#HomeScreenComponents .k-grid-norecords td:hover {
    background-color: var(--accent-1);
    border: none;
    font-size: 11px;
    color: var(--font-color-muted);
}

/* Hides a command button for a customer who is not text opted in. Here rather than in
   Home.razor.css, where a bare `.hidden` compiles to `.hidden[b-xyz]` and never matches -
   the class lands on the button Telerik renders, which carries no scope attribute. */
#HomeScreenComponents .hidden {
    display: none;
}

/* ---- the At a Glance matrix ----
   A zebra stripe, because a row is up to twenty-seven columns wide and the eye slips a
   line between the zone at the left and a bucket at the right. The hairline under each
   cell stays - it is what separates two rows of the same colour.

   Set on the row AND its cells: the cells above are transparent, so a colour on the row
   alone shows only where there is no cell, and a colour on the cells alone leaves the
   row's ground behind the padding. Both Telerik generations of the class are listed
   because which one renders varies by version.

   This block must stay ABOVE the hover rule below it - the two are the same specificity,
   so hover wins by document order alone. */
#HomeScreenComponents .hs-glance-grid .k-table-alt-row,
#HomeScreenComponents .hs-glance-grid .k-alt,
#HomeScreenComponents .hs-glance-grid tr.k-alt,
#HomeScreenComponents .hs-glance-grid .k-table-alt-row > td,
#HomeScreenComponents .hs-glance-grid .k-alt > td {
    background-color: var(--row-alt);
}

/* Darker than --row-alt, so hover always darkens whichever colour the row already is.
   --row-hover's #f7fafd is lighter than the stripe and cannot be used here. */
#HomeScreenComponents .hs-glance-grid .k-table-row:hover,
#HomeScreenComponents .hs-glance-grid tr:hover,
#HomeScreenComponents .hs-glance-grid .k-table-row:hover > td,
#HomeScreenComponents .hs-glance-grid tr:hover > td {
    background-color: var(--tint-strong);
}

#HomeScreenComponents .hs-cell-head {
    font-weight: 600;
}

/* Both shapes of link are listed, and the second is not optional. The zone cell wraps
   its anchor - `<span class="home-grid-link"><a>` - but a figure carries the class ON
   the anchor, because the flex box has to hold the symbol and the digits. A lone
   `.home-grid-link a` silently stops matching every figure. */
#HomeScreenComponents .home-grid-link a,
#HomeScreenComponents a.home-grid-link,
#HomeScreenComponents .cust-row-link {
    color: var(--link-color);
    text-decoration: none;
}

    #HomeScreenComponents .home-grid-link a:hover,
    #HomeScreenComponents a.home-grid-link:hover,
    #HomeScreenComponents .cust-row-link:hover {
        text-decoration: underline;
    }

/* Mark the exception (§6). Most buckets are empty for most zones, so a link colour on
   every one of them makes the blue mean "this is a cell" rather than "there is something
   here". Muted, not hidden: a zero is still an answer. */
#HomeScreenComponents .hs-cell.is-zero,
#HomeScreenComponents .hs-cell.is-zero .home-grid-link a,
#HomeScreenComponents .hs-cell.is-zero a.home-grid-link {
    color: var(--font-color-muted);
}

/* ---- accounting figures ----
   The symbol pinned to the left of its track, the digits flush right, so a column has
   one x for the symbol and one for the decimal point. Track lists arrive from C# as
   `--hs-slots`; see ColumnSlots in Home.razor.cs and §12 for why they are in `ch`. */
#HomeScreenComponents .hs-glance-grid td.hs-cell:not(.hs-cell-head) > .hs-cell-value {
    display: flex;
    align-items: baseline;
    justify-content: flex-end;
    gap: .25rem;
    font-variant-numeric: tabular-nums;
    flex-wrap: wrap;   /* a cell that will not fit wraps rather than overlapping */
}

/* Right-aligned by default: most figures are a bare run of digits with nothing to pin.
   NO `min-width: 0` here - that defeats flexbox's automatic minimum size, and since the
   text is nowrap a shrunk figure draws over its neighbour rather than clipping. */
#HomeScreenComponents .hs-fig {
    display: inline-flex;
    align-items: baseline;
    justify-content: flex-end;
    gap: .25rem;
    white-space: nowrap;
}

/* Grow to fill the track, never shrink below the content. */
#HomeScreenComponents .hs-fig.is-money,
#HomeScreenComponents .hs-fig.is-pct {
    flex: 1 0 auto;
}

#HomeScreenComponents .hs-fig.is-count {
    flex: 0 0 auto;
}

/* Gated on there BEING a symbol: with one child, space-between puts it at the
   start, which left percentages at the wrong end of their track. */
#HomeScreenComponents .hs-fig.is-money:has(.hs-fig-sym) {
    justify-content: space-between;
}

/* en-US renders a negative as "($1,234.56)", and the trailing paren would shift the
   column's decimals by a character. visibility, not display, so the gutter survives and
   a positive is not announced as parenthesised. */
#HomeScreenComponents .hs-fig-paren {
    visibility: hidden;
}

    #HomeScreenComponents .hs-fig.is-neg .hs-fig-paren {
        visibility: visible;
    }

/* One track per figure in a compact section; in a wide one the count takes the first and
   the amounts fill the rest over two rows.

   The selector repeats the base rule's full shape rather than just adding `.is-slotted`:
   the base is (1,4,1) and the short form (1,3,0) loses, which half-applies the grid. */
#HomeScreenComponents .hs-glance-grid td.hs-cell:not(.hs-cell-head) > .hs-cell-value.is-slotted {
    display: grid;
    grid-template-columns: var(--hs-slots);
    column-gap: .7rem;   /* the only thing parting the count from the "$" */

    /* Zeroed on purpose: the base rule's `gap` sets both axes, and leaving the row
       gap at .25rem added 4px to every wide row. */
    row-gap: 0;
    align-items: baseline;
    justify-content: end;
}

    /* The count spans both rows so column 1 is taken in each; without it auto-flow puts
       the third figure under the count. Only where the cell wraps, or a one-row cell
       grows a phantom second row. */
    #HomeScreenComponents .hs-glance-grid .hs-cell-value.is-two-row > .hs-fig:first-child {
        grid-column: 1;
        grid-row: 1 / span 2;
    }

/* The rule marks the column boundary, not the gap between figures inside a cell. It runs
   through the heading row too.

   --accent-4, not --hairline - the latter vanishes against both the white ground and the
   zebra stripe. The rule between table rows stays --hairline. */
#HomeScreenComponents .hs-glance-grid td.hs-cell:not(.hs-cell-head) + td.hs-cell,
#HomeScreenComponents .hs-glance-grid th.hs-th + th.hs-th {
    border-left: 1px solid var(--accent-4);
}

#HomeScreenComponents .hs-cell-blank {
    color: var(--font-color-muted);
}

/* No table-width rule here, deliberately. Every grid on this board is a split-table
   Telerik grid - headings in .k-grid-header, rows in .k-grid-content - and they line up
   only because both get identical explicit column widths from AtAGlanceColumnWidth.
   Sizing a table to its content makes the two diverge. See §12.

   .k-cell-inner is named as well as the th because Telerik puts heading text in
   .k-cell-inner > .k-link > .k-column-title, and that wrapper is a flex box, so
   text-align on the th alone does nothing. */
#HomeScreenComponents .k-grid th.hs-th {
    text-align: right;
}

    #HomeScreenComponents .k-grid th.hs-th .k-cell-inner {
        justify-content: flex-end;
    }

/* Must stay after .hs-th: the zone carries both classes at equal specificity, so
   source order decides. A zone is a name, not a figure. */
#HomeScreenComponents .k-grid th.hs-th-head {
    text-align: left;
}

    #HomeScreenComponents .k-grid th.hs-th-head .k-cell-inner {
        justify-content: flex-start;
    }

/* Shown only once a row stacks and each bucket has to name itself. display: none rather
   than a visually-hidden span, so in table mode the column is named once, not twice. */
#HomeScreenComponents .hs-cell-label,
#HomeScreenComponents .hs-zero-note {
    display: none;
}

/* ---- the frozen zone column ----
   A grid past the column threshold gives every column a fixed width in Home.razor.cs and
   so scrolls sideways, so the first cell of the header and of every row sticks to the
   left edge.

   Always --accent-1 and deliberately not joining the stripe: a frozen column that
   alternates ground reads as two columns. The sticky cell needs an opaque ground of its
   own or the cells scrolling under it show through. Both Telerik generations of the cell
   class are listed; where no scroll container is offered the rule is inert rather than
   broken. */
#HomeScreenComponents .hs-glance-wide .k-grid th:first-child,
#HomeScreenComponents .hs-glance-wide .k-grid .k-table-th:first-child,
#HomeScreenComponents .hs-glance-wide .k-grid td.hs-cell-head {
    position: sticky;
    left: 0;
    z-index: 2;
    background-color: var(--accent-1);
    border-right: 1px solid var(--accent-4);
}

    #HomeScreenComponents .hs-glance-wide .k-grid tr:hover > td.hs-cell-head {
        background-color: var(--row-hover);
    }

/* ============================================================================
   RESPONSIVE STAGES — deliberately last in this block.

   A container query adds no specificity of its own, so a rule inside one and the
   base rule it overrides are both (1,1,0) and the winner is source order alone.
   Written beside the rules they override, every one of these would lose silently.
   ============================================================================ */

/* Both kinds of grid on this page stop being a table below a width, and both do it by
   re-laying the same DOM as the search results (§10) - no second markup path, so the
   pager, the row colours, the stripe and the command buttons keep working.

   The two take different breakpoints because they are different kinds of data. A queue
   row is a record and reads as .cust-row: twelve columns need about 1100px, so it stacks
   at 900px. An At a Glance row scrolls sideways with the zone frozen, which works at any
   width, so it only stacks at 700px where a four-column grid also stops fitting. */
@container homeboard (max-width: 700px) {

    /* Both shapes are listed: a scrollable grid renders its headings in a separate
       table inside .k-grid-header, a non-scrollable one renders a plain thead. */
    #HomeScreenComponents .hs-glance-grid .k-grid-header,
    #HomeScreenComponents .hs-glance-grid thead {
        display: none;
    }

    #HomeScreenComponents .hs-glance-grid table,
    #HomeScreenComponents .hs-glance-grid tbody {
        display: block;
    }

    #HomeScreenComponents .hs-glance-grid colgroup {
        display: none;
    }

    #HomeScreenComponents .hs-glance-grid .k-grid-norecords,
    #HomeScreenComponents .hs-glance-grid .k-grid-norecords td {
        display: block;
        padding: .3rem .55rem;
    }

    #HomeScreenComponents .hs-glance-grid .k-grid-pager {
        flex-wrap: wrap;
        row-gap: .25rem;
    }

    /* ---- At a Glance: one card per zone, one tile per bucket ---- */

    #HomeScreenComponents .hs-zero-toggle {
        display: inline-flex;
    }

    /* The zone name takes the full first line; the buckets reflow beneath it as tiles.
       6.5rem is measured: it holds the widest two-value cell (81px) and the widest
       bucket label (~45px) on one line each, and is the largest track that still gives
       three columns in a 340px card.

       The min() is load-bearing: a bare 6.5rem track cannot shrink below itself, so a
       narrower card would get a horizontal scrollbar rather than a single column (§16). */
    #HomeScreenComponents .hs-glance-grid tr {
        display: grid;
        grid-template-columns: repeat(auto-fill, minmax(min(6.5rem, 100%), 1fr));
        gap: .3rem .5rem;
        padding: .4rem .55rem;
        border-bottom: 1px solid var(--hairline);
    }

    #HomeScreenComponents .hs-glance-grid td.hs-cell {
        display: block;
        min-width: 0;
        padding: 0;
        border: none;
        overflow: visible;
    }

    #HomeScreenComponents .hs-glance-grid td.hs-cell-head {
        grid-column: 1 / -1;
        /* Undo the frozen column: there is nothing to scroll sideways any more, and
           a sticky heading cell inside a grid item would carry its own ground and
           hairline into the middle of a card. */
        position: static;
        border-right: none;
        background-color: transparent;
        font-size: 12.5px;
    }

    #HomeScreenComponents .hs-glance-grid .hs-cell-label {
        display: block;
        font-size: 10px;
        font-weight: 600;
        text-transform: uppercase;
        letter-spacing: .04em;
        color: var(--font-color-muted);
    }

    /* Hidden by default and revealed by the named control in the toolbar, which is
       CustShowMoreComp's bargain (§7): hiding is honest when something on screen says so
       and one tap undoes it.

       The class is on .hs-board and the rule is inside the query, so above this width
       every tile shows whatever the flag says - a wide-screen user can never land with
       data hidden (§7). */
    #HomeScreenComponents .hs-board:not(.hs-show-zeros) .hs-glance-grid td.hs-cell.is-zero {
        display: none;
    }

    /* A zone with nothing in any bucket would otherwise be a name over an empty
       card, which reads as a row that failed to load rather than as an empty one. */
    #HomeScreenComponents .hs-board:not(.hs-show-zeros) .hs-zero-note {
        display: block;
        font-size: 11px;
        font-weight: normal;
        text-transform: none;
        letter-spacing: normal;
        color: var(--font-color-muted);
    }

    /* The zone's own label is not rendered: a zone name is self-describing, and a "ZONE"
       caption over every card is a label on the norm (§6). Same call .cust-row-title
       makes against .cust-attr-label. */
    #HomeScreenComponents .hs-glance-grid td.hs-cell-head .hs-cell-label {
        display: none;
    }

    /* The track list is a table-mode device and a card has no column to line up with, so
       back to a wrapping flex row. Same selector shape as the base rule, so it ties on
       specificity and source order decides. */
    #HomeScreenComponents .hs-glance-grid td.hs-cell:not(.hs-cell-head) > .hs-cell-value.is-slotted {
        display: flex;
        flex-wrap: wrap;
        justify-content: flex-start;
        column-gap: .25rem;
    }

    #HomeScreenComponents .hs-glance-grid .hs-cell-value.is-two-row > .hs-fig:first-child {
        grid-column: auto;
        grid-row: auto;
    }

    /* A 100% basis cannot share a line, so each amount takes a full line of its tile -
       the queue's tr::after trick below. */
    #HomeScreenComponents .hs-glance-grid .hs-fig.is-money,
    #HomeScreenComponents .hs-glance-grid .hs-fig.is-pct {
        flex: 1 1 100%;
    }

    /* A leading edge per tile, not the table's column rule: a tile is not in a column,
       and `+ td.hs-cell` would mark whichever tiles follow another in source order
       rather than the ones sitting side by side. On every tile including the first - it
       reads as a field marker. */
    #HomeScreenComponents .hs-glance-grid td.hs-cell:not(.hs-cell-head) {
        border-left: 1px solid var(--accent-4);
        padding-left: .4rem;
    }
}

/* ---- the queues: one record per row ----
   A wrapping flex row rather than named grid areas: the queue carries eleven fields of
   which several are legitimately blank, so a fixed set of grid areas would leave holes
   at a different place on every record. */
@container homeboard (max-width: 900px) {

    /* Both shapes are listed: a scrollable grid renders its headings in a separate
       table inside .k-grid-header, a non-scrollable one renders a plain thead. */
    #HomeScreenComponents .hs-queue-grid .k-grid-header,
    #HomeScreenComponents .hs-queue-grid thead {
        display: none;
    }

    /* The colgroup is where Telerik puts the column widths. Left in place, each
       row's own tracks resolve against the table's columns instead. */
    #HomeScreenComponents .hs-queue-grid table,
    #HomeScreenComponents .hs-queue-grid tbody {
        display: block;
    }

    #HomeScreenComponents .hs-queue-grid colgroup {
        display: none;
    }

    /* One cell spanning the row. Left to the row rules below, the message is placed
       as though it were a record's first field. */
    #HomeScreenComponents .hs-queue-grid .k-grid-norecords,
    #HomeScreenComponents .hs-queue-grid .k-grid-norecords td {
        display: block;
        padding: .3rem .55rem;
    }

    /* The pager's controls do not fit on one 380px line, and .k-pager is a nowrap flex
       row whose overflow app.css turns back to visible - so unwrapped its items spill
       past the panel's edge rather than being clipped. */
    #HomeScreenComponents .hs-queue-grid .k-grid-pager {
        flex-wrap: wrap;
        row-gap: .25rem;
    }

    #HomeScreenComponents .hs-queue-grid tr {
        display: flex;
        flex-wrap: wrap;
        align-items: baseline;
        column-gap: .3rem;
        row-gap: .1rem;
        padding: .35rem .55rem;
        border-bottom: 1px solid var(--hairline);
    }

    /* Every field is a muted sub-line by default and order: 3 puts it after the two
       that are placed. Two of them then opt out. */
    #HomeScreenComponents .hs-queue-grid td,
    #HomeScreenComponents .hs-queue-grid .k-table-td {
        display: block;
        order: 3;
        flex: 0 1 auto;
        min-width: 0;
        padding: 0;
        border: none;
        font-size: 11px;
        color: var(--font-color-muted);
        overflow: visible;
    }

    /* The customer's name leads the record, as .cust-row-title does. */
    #HomeScreenComponents .hs-queue-grid td:nth-child(2) {
        order: 1;
        flex: 1 1 auto;
        font-size: 12.5px;
        font-weight: 600;
        color: var(--font-color-2);
    }

    /* The two actions close the first line: margin-left: auto consumes its free space,
       which is what makes every remaining field wrap beneath rather than crowding in
       beside them. They keep their own size - a call button stays a finger target. */
    #HomeScreenComponents .hs-queue-grid td.k-command-cell {
        order: 2;
        flex: 0 0 auto;
        display: flex;
        gap: .15rem;
        margin-left: auto;
        text-align: right;
    }

    /* A zero-height line break after the actions, and it is not optional. Flex
       line-filling is decided by each item's hypothetical main size, and growing happens
       afterwards on the line that results (§9) - so no amount of flex-grow stops a short
       field squeezing onto the first line behind the buttons. An item with a 100% basis
       cannot share a line, so it both closes line one and starts the sub-line. ::after
       rather than a real element, because the row is Telerik's markup. */
    #HomeScreenComponents .hs-queue-grid tr::after {
        content: "";
        order: 2;
        flex: 0 0 100%;
        height: 0;
    }

    /* Middots from the third cell on, so the type code that opens the sub-line
       never trails one and neither does the last field. */
    #HomeScreenComponents .hs-queue-grid td:nth-child(n+3):not(.k-command-cell)::before {
        content: "·";
        margin-right: .3rem;
        color: var(--accent-4);
    }

    /* A blank field is dropped rather than left as a gap and a dangling middot: its
       heading is gone at this width, so an empty value says nothing. Two shapes, because
       a column with a Template renders an empty <span> and one without an empty cell.
       Where :has() is unsupported the field stays as a stray separator. */
    #HomeScreenComponents .hs-queue-grid td:empty,
    #HomeScreenComponents .hs-queue-grid td:has(> span:empty) {
        display: none;
    }
}

/* The chevron's rotation honours the reduced-motion preference. After the rule
   that sets the transition, or it loses the specificity tie and fails silently for
   exactly the people who asked for it. */
@media (prefers-reduced-motion: reduce) {
    #HomeScreenComponents .hs-chevron {
        transition: none;
    }
}

/* ============================================================
   LEFT NAV — #left-nav
   The nav's own treatment, on the id `MainNavComp.razor` puts on its
   wrapper. The `.k-drawer-*` rules earlier in this file are shared with the
   workflow step drawer, AppHeader and CustSearchComp, so they are left
   alone — this block restyles the nav alone, and outranks them and the
   Telerik theme without !important.

   `MainNavComp.razor` carries no inline padding or colour: ten repeated
   `style="padding: .25rem .75rem"` attributes and two
   `color: var(--font-color-1)` declarations were removed from it on the
   expectation that this block supplies them. Until it existed, items had no
   padding at all, an expanded parent fell through to
   `.k-drawer-item.k-selected` (--accent-3, i.e. a near-white block with dark
   text — the loudest thing in the app for the least surprising fact), a
   focused item fell through to `.k-drawer-item:focus` (--font-color-2, dark
   text on navy, which reads as a blank row), and a level-0 item's nested
   anchor fell through to Bootstrap's link blue.

   Same vocabulary as everywhere else, read for a dark ground: one tint for
   hover, a stronger tint for selected, no inversions, no fills for
   hierarchy.
   ============================================================ */

#left-nav .navbar-brand {
    margin-right: 0;
}

#left-nav .k-drawer-item {
    margin: 1px .25rem;
    padding: .3rem .5rem;
    border-radius: 4px;
    color: #dbe9f4;
    font-size: 12.5px;
    font-weight: 500;
    line-height: 1.25;
    /* The theme makes the item `display: flex` and never says how to align it, so it
       falls through to `stretch` - and the row's three children have three different
       intrinsic heights. A stretched box does not move the text inside it, so each
       label rides at a different height depending on its line box. Centring the row is
       what lines them up. */
    align-items: center;
    /* The expand chevrons are `position: absolute; right: .25rem` inline, so without a
       containing block here they pin to .k-drawer-container's outer edge - outside the
       item's inset rounded band, reading as detached from the row they belong to. */
    position: relative;
}

    /* An anchor NESTED INSIDE an item takes the item's colour — the one place `inherit`
       is right (§16). An anchor that IS the item (level 1 renders
       `<li><a class="k-drawer-item">`) is matched by the rule above. Do not add
       `inherit` for that case: it would send the anchor to an ancestor's colour. */
    #left-nav .k-drawer-item a {
        color: inherit;
        text-decoration: none;
    }

    /* Icons are nested, so they follow the row rather than staying pure
       white against a #dbe9f4 label. `.k-drawer-item .k-icon *` is forced to
       --font-color-1 further up this file. */
    #left-nav .k-drawer-item .k-icon,
    #left-nav .k-drawer-item .k-icon * {
        color: inherit;
    }

/* Children: indentation and a quieter colour, no fill.

   The indent has to be re-stated here: Telerik indents children with
   `.k-drawer-item.k-level-1 { padding-inline-start: 32px }`, which the padding above
   outranks — so overriding item padding silently flattens the hierarchy. Kept ahead of
   the state rules below, which are the same specificity and win only by order. */
#left-nav .k-drawer-item.k-level-1,
#left-nav .k-drawer-item.level1Class {
    padding-left: 1.6rem;
    color: #b9cde0;
}

#left-nav .k-drawer-item.k-level-2 {
    padding-left: 2.5rem;
}

/* The dark-ground equivalent of --row-hover. It was a full --color-1 fill. */
#left-nav .k-drawer-item:hover,
#left-nav .k-drawer-item.k-hover {
    background-color: rgba(255, 255, 255, .10);
    color: #ffffff;
}

/* The search row is a container, not a destination. Keyed on a class rather
   than `:has(.search-box)` — the row is the only thing that needs the hook,
   and a class cannot fall back to hovering like an item. */
#left-nav .search-row {
    cursor: default;
}

    #left-nav .search-row:hover {
        background-color: transparent;
    }

/* Selected is an expanded parent — the least surprising fact on the screen,
   so it gets a stronger tint and a weight, not an inversion. */
#left-nav .k-drawer-item.k-selected,
#left-nav .k-drawer-item.k-selected:hover {
    background-color: rgba(255, 255, 255, .16);
    color: #ffffff;
    font-weight: 600;
}

/* :focus alone must not recolour the text — see the block header. The ring is
   :focus-visible, so a mouse click does not draw one. */
#left-nav .k-drawer-item:focus,
#left-nav .k-drawer-item.k-focus {
    color: #ffffff;
}

#left-nav .k-drawer-item:focus-visible {
    outline: 2px solid #ffffff;
    outline-offset: -2px;
}

#left-nav .k-drawer-item > .nav-item-link {
    display: flex;
    flex: 1 1 auto;
    align-items: center;
    gap: 0 .5rem;
    min-width: 0;
}

/* Collapsed rail: the icon centres in the 48px wrapper and the side padding
   goes, or a centred icon sits off-centre by its own padding. */
#left-nav .k-drawer-mini .k-drawer-item,
#left-nav .k-drawer-mini .k-drawer-item > .nav-item-link {
    justify-content: center;
}

#left-nav .k-drawer-mini .k-drawer-item {
    padding-left: 0;
    padding-right: 0;
}

/* The collapse toggle is chrome, not a destination. Its parent is a block, so it needs
   a width and `margin-left: auto` rather than a flex parent's alignment.

   The inline padding is the item's .5rem, not a tighter .35rem: the margin puts the
   button's edge 4px from the nav like every item's band, so the padding is what decides
   where the glyph lands, and .5rem puts it on the 12px the icons keep on the left. */
#left-nav .nav-menu-arrow {
    display: flex;
    width: fit-content;
    margin: 1px .25rem 1px auto;
    padding: .2rem .5rem;
    border: 0;
    background: none;
    box-shadow: none;
    color: #94aec7;
}

    #left-nav .nav-menu-arrow.is-mini {
        margin-left: auto;
        margin-right: auto;
    }

    #left-nav .nav-menu-arrow:hover {
        background-color: rgba(255, 255, 255, .10);
        color: #ffffff;
    }

/* Menu search — translucent on the dark ground, filling the row's remaining width, and
   no taller than the label of the item below it.

   `.search-box` is on the WRAPPER (`Class`, not `class` — see `MainNavComp.razor`), so
   the wrapper carries the fill, the hairline and the :focus-within ring and the inner
   input is transparent. With the hook on the input instead, both are drawn inside
   Telerik's own bordered `.k-input` wrapper — two nested boxes.

   §8's 28px is deliberately not used: the field's neighbours here are 12.5px text rows,
   so the height comes from the text instead. */
#left-nav .search-box {
    /* .k-input is `flex: 1; width: 100px` — the fixed basis is what kept the
       field from filling the row. */
    flex: 1 1 auto;
    width: auto;
    min-width: 0;
    /* align-self rather than the row's align-items: the row's other child is an icon the
       theme pads to ~24px, which `stretch` would size the field to. */
    align-self: center;
    height: auto;
    min-height: 0;
    /* The inner input owns the inset, so the wrapper adds none. */
    padding: 0;
    border: 1px solid rgba(255, 255, 255, .35);
    border-radius: 4px;
    background-color: rgba(255, 255, 255, .08);
    box-shadow: none;
    color: #ffffff;
    font-size: 12.5px;
    line-height: 1.25;
}

    #left-nav .search-box:focus-within {
        border-color: #ffffff;
    }

    /* Matches an item's type exactly. `.k-input-md` otherwise gives this 14px type at
       1.43 with 4px of block padding, and app.css fills it --accent-1 — white on white. */
    #left-nav .search-box .k-input-inner {
        height: auto;
        min-height: 0;
        padding: .1rem .35rem;
        border: 0;
        background-color: transparent;
        box-shadow: none;
        color: #ffffff;
        font-size: 12.5px;
        line-height: 1.25;
    }

        #left-nav .search-box .k-input-inner::placeholder {
            color: #94aec7;
            /* Firefox drops placeholder opacity to .54, which on this ground
               is close to invisible. */
            opacity: 1;
        }

/* The breadcrumb over a search result. Muted and small, but not uppercased —
   it is made of real menu names, not a label. */
#left-nav .menu-path {
    color: #94aec7;
    font-size: 10.5px;
}

/* ============================================================
   REPORTS PAGE — #ReportsPage
   The reports index brought onto the language in vergent-lms-design.md:
   one hairline-bordered panel, a quiet tab strip, and one report per
   .cust-row instead of a wall of 300px Telerik cards.

   Scoped to the id on Pages/Reports/Default.razor's wrapper for the two
   reasons in §3. .component, .component-title and .k-tabstrip* are shared
   with ~30 other screens, so an unscoped edit here would leak; and
   ReportIndex/ReportCard/ReportTypeCard live in the shared component
   library, so their markup carries [b-*] isolation attributes that only an
   ID selector outranks without !important.
   ============================================================ */

/* ---- the panel ----
   The contract is a white card, one hairline, a shadow you have to look for. The shared
   .component is an --accent-3 card with a 35%-black shadow that sets color to
   --font-color-1 (white), so none of it can be inherited here. */
#ReportsPage .component {
    background-color: var(--accent-1);
    border: 1px solid var(--accent-4);
    border-radius: 4px;
    box-shadow: var(--panel-shadow);
    overflow: hidden;
    margin: .5rem;
    color: var(--font-color-2);
    font-size: 12px;
}

#ReportsPage .component-title {
    display: flex;
    align-items: center;
    gap: .5rem;
    min-height: 29px;
    padding: .25rem .5rem;
    background-color: var(--header-bar);
    /* .component owns the radius and clips its children */
    border-bottom: 0;
    border-radius: 0;
    color: var(--font-color-1);
    font-size: 11px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: .06em;
}

    /* Bootstrap gives a label a bottom margin, which offsets the title in
       its own bar. */
    #ReportsPage .component-title label {
        margin: 0;
    }

#ReportsPage .component-content-wrapper {
    padding: 0;
    border-radius: 0;
}

/* ---- the tab strip ----
   Same contract as the customer page's tab selector (§9), read for a strip directly
   under a filled title bar: no second filled bar, no divider between items, active
   marked with an underline rather than a raised white block.

   Every selector lists .k-tabstrip-item and .k-item alike. This Telerik version renders
   the former, which is why several app-wide .k-tabstrip rules above are dead; listing
   both survives either markup. */
#ReportsPage .k-tabstrip {
    background-color: transparent;
    border: 0;
}

/* Explicit background, not transparent: this strip is two or three rows deep on a narrow
   window and muted labels have to stay legible across all of it. Telerik's own
   .k-tabstrip-items already wraps and is left alone — pinning it would break the scroll
   buttons if this strip is ever given Scrollable="true". */
#ReportsPage .k-tabstrip-items-wrapper {
    background-color: var(--accent-1);
    border: 0;
    border-bottom: 1px solid var(--accent-4);
}

#ReportsPage .k-tabstrip-item,
#ReportsPage .k-tabstrip-items-wrapper .k-item {
    padding: 0;
    border: 0;
    border-radius: 0;
    background-color: transparent;
    /* The app-wide .tabstrip .k-item rule uses !important, so matching it is
       unavoidable on the colour. */
    color: var(--font-color-muted) !important;
}

    /* Telerik puts no padding on the item itself — type and hit area belong
       to this inner span. */
    #ReportsPage .k-tabstrip-item > .k-link,
    #ReportsPage .k-tabstrip-items-wrapper .k-item > .k-link {
        padding: .3rem .7rem;
        font-size: 11.5px;
        font-weight: 600;
    }

    #ReportsPage .k-tabstrip-item:hover,
    #ReportsPage .k-tabstrip-item.k-hover,
    #ReportsPage .k-tabstrip-items-wrapper .k-item:hover,
    #ReportsPage .k-tabstrip-items-wrapper .k-item.k-hover {
        background-color: var(--row-hover);
        color: var(--font-color-2) !important;
    }

/* An inset shadow rather than a border, so the label does not shift 2px when it becomes
   the selected tab.

   The margin and border are zeroed deliberately: the theme pulls an active item down a
   pixel to merge it with the strip's bottom rule (margin-bottom: -1px), which is right
   for a raised white tab and wrong for an underline — and whether it applies depends on
   which item class this Telerik version renders. */
#ReportsPage .k-active.k-tabstrip-item,
#ReportsPage .k-tabstrip-item.k-active,
#ReportsPage .k-tabstrip-items-wrapper .k-item.k-active {
    margin-bottom: 0;
    border-bottom-width: 0;
    background-color: var(--accent-1);
    color: var(--affordance-color) !important;
    box-shadow: inset 0 -2px 0 var(--affordance-color);
}

/* The rows own their padding, as they do in a panel. */
#ReportsPage .k-tabstrip-content,
#ReportsPage .k-tabstrip > .k-content {
    padding: 0;
    border: 0;
    background-color: var(--accent-1);
}

    #ReportsPage .k-tabstrip-content.k-active,
    #ReportsPage .k-tabstrip > .k-content.k-active {
        background-color: var(--accent-1);
    }

/* ---- rows ----
   The .cust-row contract from §5: one report is one row, and the row itself is the
   affordance. Defined here rather than in the components' .razor.css for the §3 reason —
   a scoped rule would lose to this block's ID selector.

   Each row is an <a>, so the accessibility bundle a clickable <div> needs (role,
   tabindex, @onkeydown) is native, and middle-click and open-in-new-tab keep working. */
#ReportsPage .cust-row {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: center;
    gap: .5rem;
    padding: .25rem .55rem;
    /* Set outright, not inherited: the row is the anchor, so `inherit` would reach past
       Bootstrap's link colour to the panel instead of replacing it (§15). */
    color: var(--font-color-2);
    text-decoration: none;
}

    #ReportsPage .cust-row:hover {
        background-color: var(--row-hover);
        color: var(--font-color-2);
    }

    /* Adjacent-sibling, so there is no rule above the first row or below the
       last. --hairline, not --accent-4: a heavier rule reads as a boxed list. */
    #ReportsPage .cust-row + .cust-row {
        border-top: 1px solid var(--hairline);
    }

    #ReportsPage .cust-row.is-clickable {
        cursor: pointer;
    }

        #ReportsPage .cust-row.is-clickable:focus-visible {
            outline: 2px solid var(--affordance-color);
            outline-offset: -2px;
        }

/* min-width: 0 is required, or a long unbroken report name blows out the
   grid rather than wrapping. */
#ReportsPage .cust-row-main {
    min-width: 0;
    overflow-wrap: break-word;
}

#ReportsPage .cust-row-title {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: .4rem;
    font-size: 12px;
    font-weight: 500;
}

#ReportsPage .cust-row-sub {
    font-size: 11px;
    color: var(--font-color-muted);
}

/* An empty list must say it is empty — a tab with nothing under it reads as
   a tab that failed to load. */
#ReportsPage .cust-empty {
    padding: .25rem .55rem;
    font-size: 11px;
    color: var(--font-color-muted);
}

/* ---- report cards ----
   An individual report stays a card: it is a thing you launch, and the description is
   what tells two similarly named reports apart, so it wants room rather than a truncated
   sub-line.

   Brought onto the language instead: white surface, one --accent-4 hairline, the panels'
   own shadow, and no filled header bar of its own - a --color-1 bar per card repeats the
   panel's title bar a dozen times down the tab (§10). */
#ReportsPage .report-card-grid {
    display: grid;
    /* Same 288px basis as the customer board's columns. The min() is load-bearing: a
       bare 288px track minimum cannot shrink below itself, so a narrow window would get
       a horizontal scrollbar rather than going one-up. */
    grid-template-columns: repeat(auto-fill, minmax(min(288px, 100%), 1fr));
    gap: .5rem;
    padding: .5rem .55rem;
}

#ReportsPage .report-card {
    display: flex;
    flex-direction: column;
    gap: .15rem;
    min-width: 0;
    padding: .4rem .55rem;
    border: 1px solid var(--accent-4);
    border-radius: 4px;
    background-color: var(--accent-1);
    box-shadow: var(--panel-shadow);
    /* Set outright, not inherited: the card is the anchor, so `inherit` would reach past
       Bootstrap's link colour to the panel instead of replacing it (§15). */
    color: var(--font-color-2);
    text-decoration: none;
    cursor: pointer;
}

    /* A card is a control, so unlike a status tag it carries a hover fill, a
       hover border and a focus ring (§8). */
    #ReportsPage .report-card:hover {
        background-color: var(--row-hover);
        border-color: var(--affordance-color);
        color: var(--font-color-2);
    }

    #ReportsPage .report-card:focus-visible {
        outline: 2px solid var(--affordance-color);
        outline-offset: -2px;
    }

/* The name is data, not a label — normal case, not the title bar's uppercase type,
   because all-caps strips the word-shape cues used to pick one report out of a dozen. */
#ReportsPage .report-card-title {
    font-size: 12.5px;
    font-weight: 600;
    overflow-wrap: break-word;
}

#ReportsPage .report-card-desc {
    font-size: 11px;
    color: var(--font-color-muted);
    overflow-wrap: break-word;
}

/* ============================================================================
   CUSTOMER PAGE
   Everything below is scoped to #CustomerComponents on purpose. .component-title,
   .component-header and .component-item are shared with workflow, notes, setup and
   ~30 other screens; scoping keeps the flat customer treatment from leaking into
   them. The ID selector also outranks the Blazor-isolation [b-*] rules on
   .component-header without needing !important.
   ============================================================================ */

/* ---- the ground ----
   #CustomerComponents is itself the .component-container, which fills --accent-2; the
   panel treatment needs the white cards to sit on something darker. The board's own
   padding and the panels' .25rem side margins are what let this show through. */
#CustomerComponents {
    background-color: var(--page-ground);
}

/* ---- panel chrome ---- */
#CustomerComponents .component {
    border-radius: 4px;
    border: 1px solid var(--accent-4);
    box-shadow: var(--panel-shadow);
    background-color: var(--accent-1);
    overflow: hidden;
    /* Keeps a panel from being split across two columns by the reflow. */
    break-inside: avoid;
}

/* ---- panel headers: compact uppercase label, existing icons kept ---- */
#CustomerComponents .component-title,
#CustomerComponents .component-header:not(.header-light) {
    display: flex;
    align-items: center;
    gap: 8px;
    background-color: var(--header-bar);
    color: var(--font-color-1);
    border-bottom: none;
    border-radius: 4px 4px 0 0;
    font-size: 11px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: .06em;
    line-height: 1.2;
    min-height: 29px;
    margin: 0;
    padding: .25rem .5rem;
}

    #CustomerComponents .component-title > label,
    #CustomerComponents .component-header:not(.header-light) > label {
        margin: 0;
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
    }

    #CustomerComponents .component-title .header-buttons {
        display: flex;
        align-items: center;
        gap: 2px;
        margin-left: auto;
    }

        /* float-end on the icon wrappers fights the flex row; neutralise it. */
        #CustomerComponents .component-title .header-buttons .float-end {
            float: none !important;
            display: flex;
            align-items: center;
        }

        /* Every header icon takes the bar's own colour. Without this each panel's icon
           inherits whatever the Telerik theme or a stray scoped rule gives it. */
        #CustomerComponents .component-title .header-buttons .k-icon,
        #CustomerComponents .component-title .header-buttons .k-svg-icon,
        #CustomerComponents .component-title .header-buttons .k-button-icon {
            color: var(--font-color-1);
        }

/* ---- panel content: flat rows, hairline separators, left aligned ---- */
#CustomerComponents .component-item {
    background-color: transparent;
    box-shadow: none;
    border-radius: 0;
    border-bottom: none;
    margin-bottom: 0;
    padding: .2rem;
    text-align: left;
}

    /* No rules between rows, so hover is the only affordance left that shows
       where one record ends and the next begins. */
    #CustomerComponents .component-item:hover {
        background-color: var(--row-hover);
    }

/* ---- the loans card's title bar, which is also its collapse control ----
   A <button> carrying .component-header, so the treatment above dresses it. Only the
   metrics a button brings of its own are reset here.

   These have to live in this file rather than in CustLoanInfoComp.razor.css: the rule
   above is (1,2,0) and a scoped rule is (0,2,0), so a scoped `border: 0` would lose (§3).

   The hover is a white tint laid over the fill, not a translucent white background,
   which would tint the card's white through it. The focus ring is white for the same
   reason a --color-1 ring is invisible on --color-1. */
#CustomerComponents .cust-loans-header {
    width: 100%;
    border: 0;
    font-family: inherit;
    text-align: left;
    cursor: pointer;
}

    #CustomerComponents .cust-loans-header:hover {
        background-image: linear-gradient(rgba(255, 255, 255, .12), rgba(255, 255, 255, .12));
    }

    #CustomerComponents .cust-loans-header:focus-visible {
        outline: 2px solid var(--accent-1);
        outline-offset: -3px;
    }

/* Panels wrap their rows in .p-2; the rows own their padding now. */
#CustomerComponents .component > .p-2 {
    padding: 0 !important;
}

/* ...but the Details / History buttons sat on that wrapper padding, so give the
   footer its own. A hairline separates it from the last row. */
#CustomerComponents .cust-comp-btn-container {
    margin-top: 0;
    padding: .5rem .55rem;
    border-top: 1px solid var(--hairline);
}

/* ---- shared row primitives for the refactored panels ----
   Default shape is: edit affordance | main content | trailing status. Panels that need a
   different split add their own hook class, defined here rather than in a component's
   scoped CSS - the #CustomerComponents ID outranks Blazor's [b-*] isolation rules. */
:is(#CustomerComponents, #WorkflowScreen) .cust-row {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: center;
    gap: .5rem;
    padding: .25rem .55rem;
    color: var(--font-color-2);
    text-align: left;
}

    :is(#CustomerComponents, #WorkflowScreen) .cust-row:hover {
        background-color: var(--row-hover);
    }

/* A record list gets a separator between its rows. Whitespace alone does not hold once a
   row is two lines - a title and a sub-line per record means the gap between two records
   is barely larger than the leading inside one.

   Deliberately --hairline rather than the --accent-4 the loans table uses: these are
   288px cards where the same weight would read as a boxed list.

   The adjacent-sibling selector means no rule above the first row, none below the last,
   and none above the show-more expander - which is a button, not a .cust-row. */
:is(#CustomerComponents, #WorkflowScreen) .cust-row + .cust-row {
    border-top: 1px solid var(--hairline);
}

/* Pointedly NOT extended to .cust-attr. Those rows are named attributes of ONE record -
   Customer Information's name, SIN, DOB - and a rule between them would say they are
   separate records, which is the one thing the separator is there to communicate. */

/* The row itself opens the editor, so the per-row pencil is gone. */
:is(#CustomerComponents, #WorkflowScreen) .cust-row.is-clickable {
    cursor: pointer;
}

    :is(#CustomerComponents, #WorkflowScreen) .cust-row.is-clickable:focus-visible {
        outline: 2px solid var(--affordance-color);
        outline-offset: -2px;
    }

/* No row carries a leading control track. If a panel ever needs one again, define the
   track here rather than in its scoped CSS - an ID-scoped rule outranks the [b-*]
   isolation attributes. */

/* Primary line: label and its identifier side by side, e.g. bank name then masked
   account number. */
:is(#CustomerComponents, #WorkflowScreen) .cust-row-title {
    display: flex;
    align-items: center;
    gap: .4rem;
    flex-wrap: wrap;
    min-width: 0;
}

:is(#CustomerComponents, #WorkflowScreen) .cust-row-main {
    min-width: 0;
    overflow-wrap: break-word;
}

:is(#CustomerComponents, #WorkflowScreen) .cust-row-sub {
    font-size: 11px;
    color: var(--font-color-muted);
}

    /* The legacy globals are the CSS keywords `red` and `green`, a third pair of status
       colours on top of the flags' and the loans card's. This brings the customer page
       onto one vocabulary; the globals are left alone for the ~30 screens that share them.

       .cust-row-sub stays listed on its own: the muted sub-line rule is also (1,1,0) and
       comes first, so a bare class here would tie and lose. */
    #CustomerComponents .customer-warning-color,
    #CustomerComponents .cust-row-sub.customer-warning-color,
    #CustomerComponents .cust-row .customer-warning-color {
        color: var(--warning-color);
    }

    #CustomerComponents .customer-primary-color,
    #CustomerComponents .cust-row-sub.customer-primary-color,
    #CustomerComponents .cust-row .customer-primary-color {
        color: var(--success-color);
    }

:is(#CustomerComponents, #WorkflowScreen) .cust-row-end {
    text-align: right;
    white-space: nowrap;
}

/* Primary is a PRIMARY tag in the row's trailing status - see .cust-flag.is-primary. The
   left edge is reserved for loan status a few hundred pixels above; an attribute of a
   record belongs with the record's other tags, where it survives the row being muted. */

:is(#CustomerComponents, #WorkflowScreen) .cust-row.is-inactive {
    color: var(--font-color-muted);
}

/* ---- empty panels ----
   Muted and small, so an absence reads as an absence rather than as content.

   Deliberately NOT a .component-item: panels that lay their rows out as a grid in scoped
   CSS would drop a one-child .component-item into a 1.25rem track and wrap a character
   per line. A class of its own is immune to whatever grid a panel gives its rows. */
#CustomerComponents .cust-empty {
    padding: .25rem .55rem;
    font-size: 11px;
    color: var(--font-color-muted);
}

/* ---- an empty panel folds onto one line ----
   Four empty panels land in the same column on a typical record, so a full card each
   pushes the panels that do have content off the fold. Laying the panel out as a row puts
   the title bar and its note side by side, which halves the height while the panel still
   names itself, still says it is empty, and keeps its add button in the title bar.

   Keyed on .cust-empty rather than any panel's wrapper class, so every panel using the
   standard empty state gets this. :has() is doing real layout work here; where it is
   unsupported the panel renders as a full card and nothing else depends on it. */
#CustomerComponents .component:has(> .p-2 > .cust-empty),
#CustomerComponents .component:has(> .cust-empty) {
    display: flex;
    align-items: stretch;
}

    /* The bar takes whatever the note does not, and gives up its right-hand corners to it.
       This way round for the sake of the stack: the note is the fixed part, so the
       blue/white seam lines up down a column of empty panels while the bar absorbs the
       difference between "DEPENDENTS" and "ADDITIONAL INFORMATION".

       min-width: 0 so the bar can be squeezed at all; the label inside it already
       ellipsises. In a narrow column the panel name truncates rather than the note
       wrapping. */
    #CustomerComponents .component:has(> .p-2 > .cust-empty) > .component-title,
    #CustomerComponents .component:has(> .cust-empty) > .component-title {
        flex: 1 1 auto;
        min-width: 0;
        border-radius: 4px 0 0 4px;
    }

    /* Sized to the note and not shrinkable, which is what makes the seam land in the same
       place on every panel: all six render the same string
       (workflow_definition_component_step_reference_nodata), so "sized to content" is a
       constant here and holds in any language. */
    #CustomerComponents .component:has(> .p-2 > .cust-empty) > .p-2,
    #CustomerComponents .component:has(> .cust-empty) > .cust-empty {
        display: flex;
        align-items: center;
        flex: 0 0 auto;
    }

    /* Never wrapped. A two line note is both taller than the bar beside it - which undoes
       the point of folding the panel onto one line - and a second width for the same
       sentence, which is the thing this alignment is trying to remove. */
    #CustomerComponents .component:has(> .p-2 > .cust-empty) .cust-empty,
    #CustomerComponents .component:has(> .cust-empty) > .cust-empty {
        white-space: nowrap;
    }

/* ---- attribute rows ----
   The second row shape. .cust-row lists records of one kind; .cust-attr lists named
   attributes of a single record, so it reads label | value instead of title/sub/status.
   Same padding, hover and type scale as .cust-row.

   Deliberately not named .cust-info-grid: the details dialog renders inside
   #CustomerComponents and defines its own, which an ID-scoped rule of that name would
   silently override. */
#CustomerComponents .cust-attr {
    display: grid;
    grid-template-columns: 84px minmax(0, 1fr);
    align-items: baseline;
    gap: 0 .5rem;
    /* .2rem vertically, against .cust-row's .25rem: an attribute row is one short line
       where a record row carries a title and a sub-line, so the two shapes share a type
       scale and a hover, not a box height. The side inset stays .55rem, which is what
       keeps both aligned to the same left edge. */
    padding: .2rem .55rem;
    color: var(--font-color-2);
    text-align: left;
}

    #CustomerComponents .cust-attr:hover {
        background-color: var(--row-hover);
    }

#CustomerComponents .cust-attr-label {
    display: block;
    font-size: 11px;
    font-weight: normal;
    color: var(--font-color-muted);
}

#CustomerComponents .cust-attr-value {
    min-width: 0;
    padding-left: 0;
    overflow-wrap: break-word;
}

/* ---- the inset photo ----
   The customer photo in the corner of Customer Information, floated past the three
   shortest values in the panel.

   A float, deliberately not a block above the rows or a column beside them: this panel is
   first on the board, so any height it gains pushes every panel below it down, and the
   first three values leave the right-hand half of the value track empty anyway. A float
   puts the photo in space the panel already had, at no height cost.

   clamp(72px, 26cqi, 104px) tracks under the measured ceiling of "costs the panel no
   height" at every width. The floor is what is free at a 298px panel (a 1440 laptop's
   four-column board); the cap is where the constraint stops being width and becomes the
   height of the rows beside it, and is also about as large as a thumbnail can be before
   it reads as the subject of the panel rather than a detail of it.

   cqi rather than breakpoints, so there is no width at which the size visibly jumps and
   no list of steps to keep in sync with the board's column count. The container is
   declared on .cust-info-body below. Note the tight width is a desktop one - on a phone
   the board is one column and the panel gets more room, not less. */
#CustomerComponents .cust-photo-inset {
    float: right;
    display: grid;
    place-items: center;
    width: clamp(72px, 26cqi, 104px);
    height: clamp(72px, 26cqi, 104px);
    /* Right and top match the rows' own .55rem/.2rem inset, so the photo lines up with the
       panel edge and the first row rather than floating in its own margin. The top follows
       .cust-attr's vertical padding - move one, move the other. */
    margin: .2rem .55rem .15rem .5rem;
    padding: 0;
    overflow: hidden;
    border: 1px solid var(--tint-border);
    border-radius: 4px;
    background-color: var(--tint-bg);
    cursor: pointer;
    /* The initials CustomerPhoto falls back to inherit their type from this frame; a
       button inherits no font of its own, so without these they drop to the UA's 13px
       Arial. Sized in cqi too, at ~30% of the frame, or a 104px tile carries the same
       lettering as a 72px one. */
    font-size: clamp(20px, 7.5cqi, 30px);
    font-weight: 600;
    color: var(--affordance-color);
}

    #CustomerComponents .cust-photo-inset:hover {
        border-color: var(--affordance-color);
    }

    #CustomerComponents .cust-photo-inset:focus-visible {
        outline: 2px solid var(--affordance-color);
        outline-offset: 1px;
    }

/* The query container the photo above sizes itself against, and the box that contains the
   float.

   The container goes here rather than on .component or the screen wrapper: container-type
   makes an element the containing block for its position: fixed descendants, so declaring
   one high up re-anchors any modal inside it. This body holds only the attribute rows and
   the float.

   flow-root is what contains the float: without it a photo taller than the rows beside it
   escapes the body and is clipped by .component's overflow: hidden. Stated separately
   from container-type, whose layout containment would also do it, because the float still
   needs containing if the query container ever moves. flow-root rather than
   overflow: hidden, which would cut off anything a row paints outside its box. */
#CustomerComponents .cust-info-body {
    display: flow-root;
    container-type: inline-size;
    container-name: custinfo;
}

:is(#CustomerComponents, #WorkflowScreen) .cust-row-link {
    color: var(--link-color);
    text-decoration: none;
    cursor: pointer;
}

    :is(#CustomerComponents, #WorkflowScreen) .cust-row-link:hover {
        text-decoration: underline;
    }

/* Short status markers such as VBT, DNC, DNT, BAD, and account type letters. */
:is(#CustomerComponents, #WorkflowScreen) .cust-flag {
    display: inline-block;
    margin-left: .25rem;
    font-size: 10.5px;
    font-weight: 600;
    letter-spacing: .03em;
}

    :is(#CustomerComponents, #WorkflowScreen) .cust-flag.is-good {
        color: var(--success-color);
    }

    :is(#CustomerComponents, #WorkflowScreen) .cust-flag.is-bad {
        color: var(--warning-color);
    }

    :is(#CustomerComponents, #WorkflowScreen) .cust-flag.is-muted {
        color: var(--font-color-muted);
    }

    /* ---- the spelled-out tag family ----
       One outlined-pill shape, one word inside it, three colours. A word needs no tooltip
       to be understood. The initialled flags that remain (DD, VBT, BAD, DNC, DNT, B, DDA)
       are the ones a teller reads dozens of times a day and already knows; INACTIVE,
       PRIMARY and DISBURSEMENT are not. */
    :is(#CustomerComponents, #WorkflowScreen) .cust-flag.is-inactive,
    :is(#CustomerComponents, #WorkflowScreen) .cust-flag.is-primary,
    :is(#CustomerComponents, #WorkflowScreen) .cust-flag.is-disbursement {
        padding: 0 .25rem;
        border: 1px solid var(--hairline);
        border-radius: 8px;
        text-transform: uppercase;
        font-size: 9.5px;
        font-weight: 600;
        letter-spacing: .04em;
        white-space: nowrap;
    }

    /* Inactive is the only status marked per row - active is the norm and carries no
       badge. Lighter than the other two: it rides along a row whose own text is already
       muted, so it must read as quieter than the record it labels. */
    :is(#CustomerComponents, #WorkflowScreen) .cust-flag.is-inactive {
        color: var(--font-color-muted);
        font-weight: 500;
    }

    /* Primary: worth finding in a list, so the accent rather than muted. Deliberately
       not green - green is loan status and the is-good flags. */
    :is(#CustomerComponents, #WorkflowScreen) .cust-flag.is-primary {
        border-color: var(--tint-border);
        color: var(--affordance-color);
    }

    /* Eligible for disbursement: a capability of the card, and a good one, so it keeps
       the is-good green - but as a word in the same tag shape rather than a bare green
       DISB, which said nothing to anyone who had not been told. */
    :is(#CustomerComponents, #WorkflowScreen) .cust-flag.is-disbursement {
        border-color: var(--good-border);
        color: var(--success-color);
    }

/* ---- the collapse chevron ----
   One glyph, one rotation, for every collapse control on the customer page: a > that
   points right when the section is closed and rotates down when it is open. The chevron
   reports STATE - it points at the content it reveals - rather than naming the action a
   click would perform. Do not mix in the ChevronUp/ChevronDown convention, which points
   the way the section will move; the two are unreadable side by side.

   Colour is deliberately absent: it inherits, so the same class reads dark on the white
   header bar, white in a filled grid header, and --color-1 on a text affordance. */
#CustomerComponents .cust-chevron {
    display: inline-block;
    font-size: 11.5px;
    line-height: 1;
    transition: transform .15s ease;
}

    #CustomerComponents .cust-chevron.is-open {
        transform: rotate(90deg);
    }

    /* The header's control is the one instance with no label beside it, so the same
       11.5px glyph reads as a speck and gets a few pixels.

       Keyed here rather than in CustComp.razor.css: #CustomerComponents outranks the
       [b-*] isolation attribute, so a scoped rule would lose to .cust-chevron above. */
    #CustomerComponents .customer-component-header-toggle .cust-chevron {
        font-size: 15px;
    }

@media (prefers-reduced-motion: reduce) {
    #CustomerComponents .cust-chevron {
        transition: none;
    }
}

/* ============================================================================
   CUSTOMER PAGE - THE PHONE STAGE
   Deliberately last in this block: a media query adds no specificity, so these
   rules and the base rules they override are the same weight and source order
   decides.

   A media query rather than a container query, which is right here alone.
   Everything under §7 responds to the width a panel *has*; the gutters below are
   the page's own chrome measured against the screen, and below the shell's 850px
   breakpoint the left nav is a fixed 45px rail, so the viewport predicts the
   content width exactly.

   The header icons are a second query: a tap target is sized for a finger, which
   is the same size in a 288px panel as in a 500px one and on a touchscreen laptop
   as on a phone. That one keys on the pointer, with a width beside it so a phone
   reporting a fine pointer is not left out. The gutters must not ride along - a
   touchscreen laptop has room for its margins.
   ============================================================================ */

@media (max-width: 40rem) {

    /* ---- give the data the screen ----
       Four nested gutters inset the board from a phone's edges - the board's padding,
       each panel's side margin, the loans card's own, and #CustomerComponents' own
       .component-container margin. On a 390px phone that is 24px of 345px spent letting
       --page-ground show between columns, where below this width there is only one. The
       ground still separates the panels vertically.

       Only the sides go; the top and bottom hold the board off the header and the tab
       strip. Keyed on the id because .component-container is shared with ~30 screens. */
    #CustomerComponents.component-container {
        margin-left: 0;
        margin-right: 0;
    }

    #CustomerComponents .customer-component-board {
        padding-left: 0;
        padding-right: 0;
    }

        #CustomerComponents .customer-component-board .component,
        #CustomerComponents .cust-loans {
            margin-left: 0;
            margin-right: 0;
        }

}

/* ---- panel header icons take a finger ----
   Changelog, details and add are 16px glyphs in whatever box Telerik gives them, which
   for the two rendered as bare divs is the glyph itself - a ~16px target under the 24px
   minimum, on the row that opens every editor on the page. 19px of glyph in a 26px box,
   and the gap goes up with them.

   The bar sheds its vertical padding to pay for it (§9): with padding-block at 0 the
   min-height holds and nothing below a panel moves.

   Keyed on the pointer rather than the viewport - see the block header. */
@media (pointer: coarse), (max-width: 40rem) {
    #CustomerComponents .component-title {
        padding-block: 0;
    }

    #CustomerComponents .component-title .header-buttons {
        gap: .3rem;
    }

        /* The two controls by name, not `> *`: a TelerikTooltip is a direct child of
           .header-buttons at every call site and renders its own box at the root
           component, so `> *` reserves 26px for the placeholder it leaves behind. */
        #CustomerComponents .component-title .header-buttons .float-end,
        #CustomerComponents .component-title .header-buttons .k-button {
            min-width: 26px;
            min-height: 26px;
            display: inline-flex;
            align-items: center;
            justify-content: center;
        }

        #CustomerComponents .component-title .header-buttons .k-icon,
        #CustomerComponents .component-title .header-buttons .k-font-icon,
        #CustomerComponents .component-title .header-buttons .k-svg-icon,
        #CustomerComponents .component-title .header-buttons .k-button-icon {
            font-size: 19px;
            width: 19px;
            height: 19px;
        }
}

/* ============================================================================
   CUSTOMER PAGE - ALERT GRIDS
   The lists inside a standing alert (Info.razor): must-read notes, and the businesses
   a conductor acts for. Both render a TelerikGrid, and the app-wide
   `.k-grid .k-grid-header` fills every grid header with --color-1 - so a card whose
   whole job is to be read quietly opened with a full blue bar, heavier than the panel
   titles beside it.

   Same treatment the details-dialog tables got further down this file: heading text over
   one --accent-4 hairline, --hairline between rows, --row-hover, and no box around a
   cell. Keyed on .info-box so a third alert gets it for free.

   Both Telerik generations of class name are listed - .k-table-th / .k-table-td in 13.x,
   the bare th / td in what the theme still emits for some grid modes. The unused half
   costs nothing, and guessing wrong here is a blue bar in production.
   ============================================================================ */
#CustomerComponents .info-box .k-grid {
    border: none;
    background-color: transparent;
    font-size: 12px;
}

#CustomerComponents .info-box .k-grid .k-grid-header {
    background-color: transparent;
    background-image: none;
    border-bottom: 1px solid var(--accent-4);
    border-radius: 0;
    color: var(--font-color-2);
}

    /* The notes header doubles as the collapse control, so it keeps a pointer and the
       shared chevron; what it loses is the fill and the white text. */
    #CustomerComponents .info-box .k-grid .k-grid-header .k-table-th,
    #CustomerComponents .info-box .k-grid .k-grid-header th {
        border-left: none;
        border-right: none;
        padding: .25rem .55rem;
        color: var(--font-color-2);
        font-size: 11px;
        font-weight: 600;
        text-transform: uppercase;
        letter-spacing: .06em;
    }

        /* A plain Title renders as .k-cell-inner > .k-link > .k-column-title, and that span
           is matched directly by the bare `.k-column-title` global and again by the ink block
           at the end of this file - both white, both for the filled header this one is not.
           The colour on the cell never reaches it. The notes alert hid this because its
           column uses a HeaderTemplate, which replaces the span; the conductor alert beside
           it does not, and its heading was white on white.

           Named rather than `th *`: this has to stay off a GridCheckboxColumn's checkbox,
           whose tick is drawn in currentColor. */
        #CustomerComponents .info-box .k-grid .k-grid-header .k-column-title,
        #CustomerComponents .info-box .k-grid .k-grid-header .k-link,
        #CustomerComponents .info-box .k-grid .k-grid-header .k-cell-inner {
            color: var(--font-color-2);
        }

#CustomerComponents .info-box .k-grid .k-table-td,
#CustomerComponents .info-box .k-grid td {
    border-left: none;
    border-right: none;
    border-bottom: 1px solid var(--hairline);
    padding: .25rem .55rem;
}

#CustomerComponents .info-box .k-grid .k-table-row:hover,
#CustomerComponents .info-box .k-grid tr:hover {
    background-color: var(--row-hover);
}

/* The pager is chrome, not content: it sits on the card's ground with one hairline above
   it, like a panel's footer button row. */
#CustomerComponents .info-box .k-grid .k-pager {
    background-color: transparent;
    border-top: 1px solid var(--hairline);
    font-size: 11px;
}

/* The read checkbox is the .cust-note grid's first column, so the grid owns its spacing.
   Zeroed here because a theme margin would add to the gap horizontally and shift the box
   off the first line vertically - and the input is Telerik's own element, so the
   component's scoped CSS cannot reach it. */
#CustomerComponents .info-box .k-grid .cust-note .k-checkbox {
    margin: 0;
}

/* ============================================================================
   CUSTOMER PAGE - TAB SELECTOR
   CustomerTabs renders as a sibling of CustComp rather than inside it, so nothing
   under #CustomerComponents above reaches it and it kept the stock Telerik look:
   a grey box with a raised white tab and a divider between every item.

   Keyed on #VergentCustomerTabs so it outranks the app-wide .k-tabstrip rules
   further up this file - which are four classes deep - without !important, and so
   no other tab strip in the app is touched.

   The SELECTOR only. .k-tabstrip-content is deliberately left alone: most tabs hold
   an iframe onto a classic .aspx page, and that content is not ours to restyle from
   here.
   ============================================================================ */
/* The whole tab area is a card, framed exactly like .component on the board above it,
   so the page reads as one set of surfaces. It was a grey box with its own radius. */
#VergentCustomerTabs .tabstrip {
    background-color: var(--accent-1);
    border: 1px solid var(--accent-4);
    border-radius: 4px;
    box-shadow: var(--panel-shadow);
}

/* A row of quiet labels, divided from the content by one hairline rather than a filled
   strip with a raised tab. Colour is spent only on the selected item.

   An explicit background rather than transparent: what sits behind the strip differs with
   the layout - white content area on a desktop, the navy page ground once the board
   reflows - and muted grey labels need to stay legible in both. */
#VergentCustomerTabs .k-tabstrip-items-wrapper {
    background-color: var(--accent-1);
    border-bottom: 1px solid var(--accent-4);
    border-radius: 4px 4px 0 0;
}

/* The item is a .k-tabstrip-item in this Telerik version - NOT a .k-item, which is what
   the app-wide rules above target and why several of them are dead. Both are listed so
   this block survives either markup. The item itself has no padding: that sits on an
   inner .k-link, so the type and the hit area are set there. */
#VergentCustomerTabs .k-tabstrip-items-wrapper .k-item,
#VergentCustomerTabs .k-tabstrip-items-wrapper .k-tabstrip-item {
    border: none;
    border-radius: 0;
    background-color: transparent;
    /* !important because the app-wide .tabstrip rule sets the item colour with one. */
    color: var(--font-color-muted) !important;
}

    #VergentCustomerTabs .k-tabstrip-items-wrapper .k-item > .k-link,
    #VergentCustomerTabs .k-tabstrip-items-wrapper .k-tabstrip-item > .k-link {
        padding: .3rem .7rem;
        color: inherit;
        font-size: 11.5px;
        font-weight: 600;
        line-height: 1.4;
    }

    /* No rule between items - spacing separates them, as it does between rows. */
    #VergentCustomerTabs .k-tabstrip-top > .k-tabstrip-items-wrapper .k-item + .k-item,
    #VergentCustomerTabs .k-tabstrip-top > .k-tabstrip-items-wrapper .k-tabstrip-item + .k-tabstrip-item {
        border-right: none;
    }

    #VergentCustomerTabs .k-tabstrip-items-wrapper .k-item:hover,
    #VergentCustomerTabs .k-tabstrip-items-wrapper .k-item.k-hover,
    #VergentCustomerTabs .k-tabstrip-items-wrapper .k-tabstrip-item:hover,
    #VergentCustomerTabs .k-tabstrip-items-wrapper .k-tabstrip-item.k-hover {
        background-color: var(--row-hover);
        color: var(--font-color-2) !important;
    }

    /* Selected: the accent plus a 2px underline drawn on the strip's own hairline,
       replacing the raised white tab. An inset shadow rather than a border, so the
       label does not shift by 2px when it becomes active. */
    #VergentCustomerTabs .k-tabstrip-items-wrapper .k-item.k-active,
    #VergentCustomerTabs .k-active.k-tabstrip-item {
        background-color: transparent;
        border-radius: 0;
        color: var(--affordance-color) !important;
        box-shadow: inset 0 -2px 0 var(--affordance-color);
    }

    #VergentCustomerTabs .k-tabstrip-items-wrapper .k-item:focus-visible,
    #VergentCustomerTabs .k-tabstrip-items-wrapper .k-tabstrip-item:focus-visible,
    #VergentCustomerTabs .k-tabstrip-items-wrapper .k-tabstrip-item > .k-link:focus-visible {
        outline: 2px solid var(--affordance-color);
        outline-offset: -2px;
    }

/* ---- tab content sits flush ----
   Each tab wraps its content in .component, which brings the panel treatment - radius,
   shadow, --accent-3 fill, margins - on top of Telerik's own content padding, giving a
   card inside a card. Worst on the tabs holding a classic .aspx page, which has its own
   edges and header.

   Neutralised here rather than by removing the class in markup, because .component is
   what a future native tab would want to keep. */
#VergentCustomerTabs .k-tabstrip-content,
#VergentCustomerTabs .k-tabstrip > .k-content {
    padding: 0;
    border: none;
}

#VergentCustomerTabs .k-tabstrip-content > .component,
#VergentCustomerTabs .k-tabstrip > .k-content > .component {
    height: auto;
    margin: 0;
    border: none;
    border-radius: 0;
    background-color: transparent;
    box-shadow: none;
    /* .component sets --font-color-1, i.e. white, for text on a filled panel bar. On a
       white tab that is invisible; the tabs that are not an iframe render real text. */
    color: var(--font-color-2);
}

/* An iframe is inline by default, so it sits on a text baseline and leaves a few pixels
   of gap beneath itself - the one strip of background that survives everything above. */
#VergentCustomerTabs iframe.tab {
    display: block;
    border: none;
}

/* ============================================================================
   CUSTOMER SEARCH PAGE
   Keyed on #CustomerSearchPage, the wrapper in Pages/Customer/Search.razor.

   The page renders the shared Navigation/AdvancedSearch component, which is also the
   customer conductor's picker and the eCash embedded search dialog. Both of those are
   still on the older look, so the treatment is keyed on the page wrapper rather than
   written into the component: .component-container, .component-container-title and every
   .k-* selector below are shared with ~30 other screens, and the ID also outranks the
   component's own [b-*] isolation rules without needing !important.

   Everything here is the vocabulary from the customer page above - the .component card,
   the 29px title bar, the 28px hairline control, the loans table's small muted column
   headings - applied to a form and a results grid.
   ============================================================================ */

/* ---- panels: the same card as .component on the customer page ----
   .component-container was a flat --accent-2 rectangle, so the two panels read as grey
   bands on a navy page rather than as cards. */
#CustomerSearchPage .component-container {
    margin: .5rem .25rem;
    background-color: var(--accent-1);
    border: 1px solid var(--accent-4);
    border-radius: 4px;
    box-shadow: var(--panel-shadow);
    overflow: hidden;
    color: var(--font-color-2);
    font-size: 12px;
}

#CustomerSearchPage .component-container-title {
    display: flex;
    align-items: center;
    gap: 8px;
    background-color: var(--header-bar);
    color: var(--font-color-1);
    border-bottom: none;
    border-radius: 4px 4px 0 0;
    font-size: 11px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: .06em;
    line-height: 1.2;
    min-height: 29px;
    margin: 0;
    padding: .25rem .5rem;
}

/* ---- controls ----
   Scoped to .search-panel-body rather than to the page on purpose: the add-customer
   TelerikDialog renders inside this wrapper and hosts CustInfoEditComp, a shared editor
   whose .k-form-label fields must keep their customer-page look. */
#CustomerSearchPage .search-panel-body .k-form-label,
#CustomerSearchPage .search-panel-body .k-label {
    display: block;
    margin: 0 0 2px 0;
    font-size: 11px;
    font-weight: normal;
    line-height: 1.3;
    color: var(--font-color-muted);
}

#CustomerSearchPage .search-panel-body .k-input,
#CustomerSearchPage .search-panel-body .k-picker {
    height: 28px;
    min-height: 28px;
    border: 1px solid var(--accent-4);
    border-radius: 4px;
    background-color: var(--accent-1);
    background-image: none;
    box-shadow: none;
    color: var(--font-color-2);
    font-size: 12px;
}

    /* Focus lands on an inner input, so the ring belongs on the wrapper. */
    #CustomerSearchPage .search-panel-body .k-input:focus-within,
    #CustomerSearchPage .search-panel-body .k-picker:focus-within {
        outline: 2px solid var(--affordance-color);
        outline-offset: -2px;
        border-color: var(--affordance-color);
        box-shadow: none;
    }

    #CustomerSearchPage .search-panel-body .k-input-inner {
        padding: 0 .4rem;
        font-size: 12px;
    }

/* ---- buttons ----
   The 28px white hairline button from the customer header, listed per container rather
   than as a bare .k-button so the grid's pager and command buttons keep their own size. */
#CustomerSearchPage .add-new-button-container .k-button,
#CustomerSearchPage .custom-field-row .k-button,
#CustomerSearchPage .search-form-buttons .k-button,
#CustomerSearchPage .results-actions .k-button {
    height: 28px;
    min-height: 28px;
    margin: 0;
    padding: 0 .6rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border: 1px solid var(--accent-4);
    border-radius: 4px;
    background-color: var(--accent-1);
    background-image: none;
    box-shadow: none;
    color: var(--font-color-2);
    font-size: 12px;
    font-weight: 500;
    line-height: 1;
}

    /* app.css forces .btn .k-button-text to white with !important, so only another
       !important reaches it - the same trade CustComp.razor.css makes for the header. */
    #CustomerSearchPage .add-new-button-container .k-button .k-button-text,
    #CustomerSearchPage .custom-field-row .k-button .k-button-text,
    #CustomerSearchPage .search-form-buttons .k-button .k-button-text,
    #CustomerSearchPage .results-actions .k-button .k-button-text {
        color: var(--font-color-2) !important;
    }

    #CustomerSearchPage .add-new-button-container .k-button:hover,
    #CustomerSearchPage .custom-field-row .k-button:hover,
    #CustomerSearchPage .search-form-buttons .k-button:hover,
    #CustomerSearchPage .results-actions .k-button:hover {
        background-color: var(--accent-2);
        border-color: var(--font-color-muted);
        filter: none;
    }

/* Search is the one exception to the flat button set. A form whose submit is styled
   exactly like Clear beside it has no primary action, and this is the only screen in the
   app where pressing the wrong one of two adjacent buttons discards typing. */
#CustomerSearchPage .search-form-buttons .k-button.search-submit {
    background-color: var(--color-1);
    border-color: var(--color-1);
    color: var(--font-color-1);
}

    #CustomerSearchPage .search-form-buttons .k-button.search-submit .k-button-text {
        color: var(--font-color-1) !important;
    }

    #CustomerSearchPage .search-form-buttons .k-button.search-submit:hover {
        background-color: var(--color-1);
        border-color: var(--color-1);
        filter: brightness(.94);
    }

#CustomerSearchPage .search-panel-body .k-checkbox:focus-visible {
    outline: 2px solid var(--affordance-color);
    outline-offset: 1px;
}

/* ---- results grid ----
   The flat table language from the loans card: white ground, small muted uppercase
   headings over one hairline, hairline row separators, --row-hover. No fill on the header
   row, which would repeat the panel's own title bar 30px above it. */
#CustomerSearchPage .k-grid,
#CustomerSearchPage .k-grid-content,
#CustomerSearchPage .k-grid .k-grid-header,
#CustomerSearchPage .k-grid-pager {
    background-color: var(--accent-1);
}

#CustomerSearchPage .k-grid {
    border: none;
    font-size: 12px;
    color: var(--font-color-2);
}

#CustomerSearchPage .k-grid .k-grid-header {
    border-bottom: 1px solid var(--accent-4);
}

/* 11px, the panel title bar's size, rather than the loans table's 0.7em - which off the
   grid's 12px is 8.4px, legible on a card of eight known columns and not on a results
   table someone scans hundreds of rows on. Weight, case and tracking still separate the
   heading row from the 12px data under it. */
#CustomerSearchPage .k-grid th,
#CustomerSearchPage .k-grid .k-table-th,
#CustomerSearchPage .k-grid .k-header {
    padding: .2rem .5rem;
    border-left: none;
    border-right: none;
    background-color: transparent;
    font-size: 11px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: .06em;
    color: var(--font-color-2);
}

    /* Telerik puts the caption in .k-cell-inner > .k-link > .k-column-title, and that span
       carries rules of its own - the bare `.k-column-title` global and the ink block at the
       end of this file - both white for the filled header this one is not. So the colour
       above stopped at the cell and both grids on this page, results and custom-field, drew
       their headings white on --accent-1.

       Named rather than `th *`, which would also repaint a checkbox column's tick. */
    #CustomerSearchPage .k-grid .k-grid-header .k-column-title,
    #CustomerSearchPage .k-grid .k-grid-header .k-link,
    #CustomerSearchPage .k-grid .k-grid-header .k-cell-inner,
    #CustomerSearchPage .k-grid thead .k-column-title,
    #CustomerSearchPage .k-grid thead .k-link,
    #CustomerSearchPage .k-grid thead .k-cell-inner {
        color: var(--font-color-2);
    }

#CustomerSearchPage .k-grid td,
#CustomerSearchPage .k-grid .k-table-td {
    padding: .25rem .5rem;
    border-left: none;
    border-right: none;
    border-bottom: 1px solid var(--hairline);
    background-color: transparent;
    color: var(--font-color-2);
    vertical-align: middle;
}

/* ---- alternating rows ----
   A zebra stripe ties a row together horizontally across seven columns, so the eye does
   not slip a line between the name and the store. The hairline under each cell stays - it
   is what separates two rows of the same colour.

   Set on the row AND on its cells, for the same reason hover is: the cells above carry
   `background-color: transparent`, so a colour on the row alone shows through only where
   there is no cell, and a colour on the cells alone leaves the row's ground behind the
   padding. Both Telerik generations are listed - `.k-alt` and `.k-table-alt-row` -
   because which one renders varies by version.

   This block must stay ABOVE the hover rule: the two are the same specificity, so hover
   wins on a striped row by document order alone. */
#CustomerSearchPage .k-grid .k-table-alt-row,
#CustomerSearchPage .k-grid .k-alt,
#CustomerSearchPage .k-grid tr.k-alt,
#CustomerSearchPage .k-grid .k-table-alt-row > td,
#CustomerSearchPage .k-grid .k-table-alt-row > .k-table-td,
#CustomerSearchPage .k-grid .k-alt > td,
#CustomerSearchPage .k-grid .k-alt > .k-table-td {
    background-color: var(--row-alt);
}

/* ---- hover ----
   Set on the row AND on its cells. The theme hovers the row (`.k-table-row:hover`) while
   the cells above are transparent, so styling only one leaves the other showing through.

   Darker than --row-alt on purpose, and so darker than the app-wide --row-hover: hover
   has to read as the strongest thing on the row whichever colour the row already is, and
   one direction - hover always darkens - is what makes it legible on both. */
#CustomerSearchPage .k-grid .k-table-row:hover,
#CustomerSearchPage .k-grid .k-table-row.k-hover,
#CustomerSearchPage .k-grid tr:hover,
#CustomerSearchPage .k-grid .k-table-row:hover > td,
#CustomerSearchPage .k-grid .k-table-row:hover > .k-table-td,
#CustomerSearchPage .k-grid tr:hover > td {
    background-color: var(--tint-strong);
}

/* app.css sets .k-grid .k-icon to --font-color-1 for the filled header row; the header
   is white here, so the pager arrows and the delete icon would be invisible. */
#CustomerSearchPage .k-grid .k-icon,
#CustomerSearchPage .k-grid .k-svg-icon,
#CustomerSearchPage .k-grid .k-button-icon {
    color: var(--font-color-2);
}

#CustomerSearchPage .k-grid-pager {
    padding: .25rem .5rem;
    border-top: 1px solid var(--hairline);
    border-radius: 0;
    font-size: 11px;
    color: var(--font-color-muted);
}

#CustomerSearchPage .k-grid-norecords,
#CustomerSearchPage .k-grid-norecords td:hover {
    background-color: var(--accent-1);
    border: none;
    font-size: 11px;
    color: var(--font-color-muted);
}

@container custresults (max-width: 700px) {

    /* Both shapes are listed: a scrollable grid renders a separate header table in
       `.k-grid-header`, a non-scrollable one renders a plain `thead`. */
    #CustomerSearchPage .results-grid .k-grid-header,
    #CustomerSearchPage .results-grid .k-grid thead {
        display: none;
    }

    /* Telerik lays the grid out as a real table whose `colgroup` carries the percentage
       widths. Blocking the table and dropping the colgroup is what lets each row own its
       own tracks; without it the `tr` grid resolves against the table's columns. */
    #CustomerSearchPage .results-grid .k-grid table,
    #CustomerSearchPage .results-grid .k-grid tbody {
        display: block;
    }

    #CustomerSearchPage .results-grid .k-grid colgroup {
        display: none;
    }

    /* Row 1 is the name and, at the trailing edge, the status. Row 2 is the sub-line: SSN,
       type and birthdate at their own widths, the store taking what is left. The name
       spans the three fixed tracks so it is never narrower than they are.

       The hairline moves from the cells to the row: six separately-ruled blocks would draw
       five lines through the middle of one record. */
    #CustomerSearchPage .results-grid .k-grid tr {
        display: grid;
        grid-template-columns: auto auto auto minmax(0, 1fr) auto;
        grid-template-areas:
            "name name name name status"
            "ssn  type dob  store store";
        align-items: baseline;
        column-gap: .35rem;
        row-gap: .1rem;
        padding: .3rem .55rem;
        border-bottom: 1px solid var(--hairline);
    }

    #CustomerSearchPage .results-grid .k-grid td,
    #CustomerSearchPage .results-grid .k-grid .k-table-td {
        display: block;
        min-width: 0;
        padding: 0;
        border: none;
        /* A grid item defaults to min-width: auto, so one unbreakable value - a long
           store name, an email - would push the row out of alignment. */
        overflow-wrap: break-word;
        /* Stated rather than inherited: `.k-table-td` is nowrap with an ellipsis, and only
           a second theme rule lets it wrap at all. A stacked row must not depend on that
           reset still being there. */
        white-space: normal;
        overflow: visible;
    }

    #CustomerSearchPage .results-grid .k-grid td:nth-child(1) {
        grid-area: name;
    }

    #CustomerSearchPage .results-grid .k-grid td:nth-child(2) {
        grid-area: ssn;
    }

    #CustomerSearchPage .results-grid .k-grid td:nth-child(3) {
        grid-area: type;
    }

    #CustomerSearchPage .results-grid .k-grid td:nth-child(4) {
        grid-area: dob;
    }

    #CustomerSearchPage .results-grid .k-grid td:nth-child(5) {
        grid-area: store;
    }

    /* Status rides at the right edge of the first line, as it does on every other list in
       the app. It keeps the grid's 12px rather than dropping to the sub-line's size: it is
       one of the two facts this screen is scanned for, not a detail of the record. */
    #CustomerSearchPage .results-grid .k-grid td:nth-child(6) {
        grid-area: status;
        justify-self: end;
        text-align: right;
        white-space: nowrap;
    }

    /* The SVC / Classic links keep `margin-left: auto` in the table, where it lines them
       up down the name column's right edge. Stacked, that edge is the status's, so they
       trail the name instead and line one ends with the status alone.

       Here rather than in AdvancedSearch.razor.css because it is conditional on the
       stacked row. */
    #CustomerSearchPage .results-grid .search-result-views {
        margin-left: .15rem;
    }

    /* The sub-line is `.cust-row-sub` - 11px and muted, so the name still leads the row. */
    #CustomerSearchPage .results-grid .k-grid td:nth-child(2),
    #CustomerSearchPage .results-grid .k-grid td:nth-child(3),
    #CustomerSearchPage .results-grid .k-grid td:nth-child(4),
    #CustomerSearchPage .results-grid .k-grid td:nth-child(5) {
        font-size: 11px;
        color: var(--font-color-muted);
    }

        /* Middots, not the column rules a table would have given it. Written on the cell
           that follows a separator rather than on the one that precedes it, so the last
           value never trails a dangling dot. */
        #CustomerSearchPage .results-grid .k-grid td:nth-child(3)::before,
        #CustomerSearchPage .results-grid .k-grid td:nth-child(4)::before,
        #CustomerSearchPage .results-grid .k-grid td:nth-child(5)::before {
            content: "·";
            margin-right: .35rem;
        }

    /* One cell spanning the whole row - left to the grid above it, the message would be
       placed into `name` and read as a record with five empty fields beside it. */
    #CustomerSearchPage .results-grid .k-grid .k-grid-norecords {
        display: block;
        padding: .3rem .55rem;
    }

    /* The pager's controls do not fit on one 380px line. `.k-pager` is a nowrap flex row
       whose `overflow: hidden` app.css turns back to `visible` above - so unwrapped its
       items spill past the panel's edge rather than being clipped. */
    #CustomerSearchPage .k-grid-pager {
        flex-wrap: wrap;
        row-gap: .25rem;
    }
}

/* ============================================================================
   CUSTOMER HOVER CARD
   The card shown when a teller hovers a name in the search results
   (AdvancedSearch.razor's TelerikTooltip, Class="customer-hover-card").

   Keyed on the class rather than an ID because a Telerik tooltip renders outside the
   page wrapper entirely - neither #CustomerSearchPage nor the component's own [b-*]
   scoped rules reach its chrome. The class is the only hook there is, and it exists on
   this one tooltip, so nothing else in the app is touched.

   This card is a --color-1 fill with --font-color-1 text, matching the app-wide
   .k-tooltip further up this file rather than the white .component surface it was briefly
   given. The fill is set explicitly rather than left to inherit, so the card does not
   change appearance if the app-wide tooltip is ever retuned.

   The thing to know if you touch it: **a blue ground means the content styles cannot use
   the app's secondary colours.** Every one of them - --font-color-2, --font-color-muted,
   --hairline - is defined for a white panel, and on blue the muted address came out
   near-illegible and the heading's hairline rule vanished. Those four rules therefore
   carry white and translucent-white values in AdvancedSearch.razor.css and are part of
   this card's contract, not incidental. Any new line added to the template needs the same
   treatment; do not reach for a --font-color-* token here.

   Both selector shapes are listed because the Class may sit on the .k-tooltip element or
   on a wrapper depending on the Telerik version; the unused one costs nothing.
   ============================================================================ */
.customer-hover-card.k-tooltip,
.customer-hover-card .k-tooltip {
    max-width: 22rem;
    padding: .5rem;
    background-color: var(--color-1);
    background-image: none;
    border: 1px solid var(--color-1);
    border-radius: 4px;
    box-shadow: var(--overlay-shadow);
    color: var(--font-color-1);
}

/* The callout arrow has no fill of its own: the theme gives each direction
   border-*-color: currentColor and sets .k-callout { color: rgba(0,0,0,.75) }. Recolour
   it to the card's ground or the arrow points at the card in a colour the card is not. */
.customer-hover-card .k-callout,
.customer-hover-card.k-tooltip .k-callout {
    color: var(--affordance-color);
}

/* ============================================================================
   CUSTOMER PHOTO POPOUT
   The customer photo shown full size on hovering the inset photo in Customer Information
   (CustInfoComp.razor's TelerikTooltip, Class="cust-photo-pop"). It hung off the header's
   38px profile circle until the photo moved into the panel; the circle is gone and this
   followed it, which is why the class is not named for either location.

   Keyed on the class for the same reason as the hover card above: a Telerik tooltip
   renders outside the page wrapper, so neither #CustomerComponents nor the component's
   own [b-*] scoped rules reach its chrome. It is also why the popout is a tooltip at all
   rather than a div positioned from the panel - the board is inside a scroll container and
   the panel body declares a container-type for the photo's sizing, so a popout of our own
   would be clipped by the one and anchored to the other.

   The frame is a plain white surface: the photo is the content, and a --color-1 fill
   behind a photograph reads as a coloured border nobody chose. Padding is smaller than
   the hover card's because there is no text here to inset.
   ============================================================================ */
.cust-photo-pop.k-tooltip,
.cust-photo-pop .k-tooltip {
    padding: .25rem;
    background-color: var(--accent-1);
    background-image: none;
    border: 1px solid var(--accent-4);
    border-radius: 4px;
    box-shadow: var(--overlay-shadow);
    color: var(--font-color-2);
    /* The theme caps .k-tooltip's box and hides its overflow; without both of these the
       photo is boxed to a hint's size and cropped inside the frame rather than fitted to
       it. The image's own max-width/max-height below are what bound the popout. */
    max-width: none;
    max-height: none;
    overflow: visible;
}

.cust-photo-pop .k-callout,
.cust-photo-pop.k-tooltip .k-callout {
    color: var(--accent-1);
}

/* Sized to the viewport rather than the image: a customer photo is whatever the branch
   camera produced, so an intrinsic size can be a 3000px portrait. height: auto keeps the
   aspect ratio while both caps apply. */
.cust-photo-pop .cust-photo-pop-image {
    display: block;
    width: auto;
    height: auto;
    max-width: min(26rem, 80vw);
    /* 60vh, not 70: the popout opens below a circle that is itself ~110px down the
       window, so the room available is the viewport less that offset. 70vh left a tall
       portrait running past the bottom on a laptop. */
    max-height: 60vh;
    border-radius: 2px;
    /* object-fit matters even though nothing here crops: with both caps applied to an
       arbitrary camera photo, contain guarantees the whole frame is shown rather than
       filled and centre-cropped, which is what "cut off" looked like. */
    object-fit: contain;
}

/* ============================================================================
   DETAILS DIALOG
   Read-only "… Details" popups opened from a panel header (Bank Accounts is the first
   one over). Paired with a Width on the dialog and NO Height, so the box is as tall as
   what is in it.

   The height cap belongs here rather than on the component: a fixed Height="90vh" makes
   every dialog full height whatever it holds, which is what left five bank accounts
   floating in most of a screen of white. max-height lets a short dialog be short and a
   long one scroll its content instead of the page.
   ============================================================================ */
.details-dialog {
    max-width: 96vw;
}

    .details-dialog .k-dialog-content {
        max-height: 78vh;
        overflow: auto;
        padding: .5rem;
        background-color: var(--accent-1);
        color: var(--font-color-2);
        font-size: 12px;
    }

    /* .component brings --accent-3 and a shadow, which stacks a second card inside the
       dialog's own frame. Flatten it: the dialog is the surface. */
    .details-dialog .k-dialog-content .component {
        margin: 0 0 .5rem 0;
        border: 1px solid var(--accent-4);
        border-radius: 4px;
        box-shadow: none;
        background-color: var(--accent-1);
        color: var(--font-color-2);
        overflow: hidden;
    }

    /* Section headings inside the dialog take the panel title bar's type, so Custom Fields
       reads like a panel header on the board rather than a second dialog title. */
    .details-dialog .k-dialog-content .component-title {
        display: flex;
        align-items: center;
        min-height: 29px;
        margin: 0;
        padding: .25rem .5rem;
        background-color: var(--header-bar);
        color: var(--font-color-1);
        border-bottom: none;
        font-size: 11px;
        font-weight: 600;
        text-transform: uppercase;
        letter-spacing: .06em;
    }

        .details-dialog .k-dialog-content .component-title > label {
            margin: 0;
        }

    /* The custom field rows are .component-item, which is a shadowed --accent-3 pill. In a
       list of label/value pairs that reads as a box per field; flatten to the board's row
       treatment and let the label column do the work. */
    .details-dialog .k-dialog-content .component-item {
        margin-bottom: 0;
        padding: .15rem .3rem;
        border-radius: 0;
        background-color: transparent;
        box-shadow: none;
    }

    .details-dialog .k-dialog-content .cust-field-grid-header {
        border-right: none;
        font-weight: normal;
        font-size: 11px;
        color: var(--font-color-muted);
    }

    .details-dialog .k-dialog-content .cust-field-grid-info {
        padding-left: 0;
    }

    .details-dialog .k-dialog-content .cust-field-sub-header {
        margin-bottom: .15rem;
        font-size: 11px;
        font-weight: 600;
        color: var(--font-color-2);
    }

    /* CustomFieldDetailsComp separates its groups with <br> elements, which is a lot of
       dead vertical space once the grid above is already gapped. */
    .details-dialog .k-dialog-content .cust-field-sub-header + br,
    .details-dialog .k-dialog-content .p-2 > br {
        display: none;
    }

/* ---- the tables inside a details dialog ----
   Every details component grew the same shape independently and the class names never
   converged, so they are listed rather than matched by pattern - a substring selector
   would silently pick up the next one named differently and miss it if it is not.

   Keyed here rather than in each component's scoped CSS so all of them move together. The
   three-class chain also clears the scoped rules it has to beat: those are (0,2,0) and
   the scoped bundle loads after this file, so a tie would go to them. */
.details-dialog .k-dialog-content .component-title-details,
.details-dialog .k-dialog-content .cust-appt-history-header-grid,
.details-dialog .k-dialog-content .cust-phone-history-header-grid {
    background-color: transparent;
    border-bottom: 1px solid var(--accent-4);
    border-radius: 0;
    color: var(--font-color-2);
    font-size: 11px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: .06em;
    padding: .25rem .55rem;
    gap: 0 .75rem;
}

.details-dialog .k-dialog-content .component-item-details,
.details-dialog .k-dialog-content .cust-appt-history-grid,
.details-dialog .k-dialog-content .cust-phone-history-grid {
    background-color: transparent;
    border: none;
    border-radius: 0;
    box-shadow: none;
    margin-bottom: 0;
    padding: .25rem .55rem;
    gap: 0 .75rem;
    font-size: 12px;
    color: var(--font-color-2);
}

    /* Separator between records, as .cust-row has on the board behind the dialog. */
    .details-dialog .k-dialog-content .component-item-details + .component-item-details,
    .details-dialog .k-dialog-content .cust-appt-history-grid + .cust-appt-history-grid,
    .details-dialog .k-dialog-content .cust-phone-history-grid + .cust-phone-history-grid {
        border-top: 1px solid var(--hairline);
    }

    .details-dialog .k-dialog-content .component-item-details:hover,
    .details-dialog .k-dialog-content .cust-appt-history-grid:hover,
    .details-dialog .k-dialog-content .cust-phone-history-grid:hover {
        background-color: var(--row-hover);
    }

/* The column gap separates the cells now, so the vertical rules go. min-width: 0 because
   a grid item defaults to min-width: auto and one unbreakable value would otherwise
   report a wider minimum than its track and knock the row out of alignment. */
.details-dialog .k-dialog-content .component-title-details > div,
.details-dialog .k-dialog-content .component-item-details > div,
.details-dialog .k-dialog-content .cust-appt-history-header-grid-column,
.details-dialog .k-dialog-content .cust-appt-history-header-grid-column-end,
.details-dialog .k-dialog-content .cust-appt-history-grid-column,
.details-dialog .k-dialog-content .cust-appt-history-grid-column-end,
.details-dialog .k-dialog-content .cust-appt-history-grid-notes-column,
.details-dialog .k-dialog-content .cust-phone-history-header-grid-column,
.details-dialog .k-dialog-content .cust-phone-history-header-grid-column-end,
.details-dialog .k-dialog-content .cust-phone-history-grid-column,
.details-dialog .k-dialog-content .cust-phone-history-grid-column-end {
    border-right: none;
    padding: 0;
    min-width: 0;
    overflow-wrap: break-word;
}

/* ---- Customer Information's label/value grid ----
   Not a table: these are named attributes of one record, so they read as .cust-attr does
   on the board, with no divider rule claiming the two columns are separate records. */
.details-dialog .k-dialog-content .cust-info-grid {
    padding: .15rem .3rem;
}

.details-dialog .k-dialog-content .cust-info-grid-header {
    border-right: none;
    font-weight: normal;
    font-size: 11px;
    color: var(--font-color-muted);
}

.details-dialog .k-dialog-content .cust-info-grid-info {
    padding-left: 0;
    min-width: 0;
    overflow-wrap: break-word;
}

/* Custom fields reflow to the width the dialog is given rather than always splitting into
   four - the fixed four columns are what left a lonely tile and a band of white beside it
   in the bank, employer and vehicle dialogs alike. */
.details-dialog .k-dialog-content .custom-field-container {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
    gap: .25rem 1rem;
    padding: .25rem .3rem .5rem .3rem;
}

/* The bordered box per field group; the panel around it is the surface. */
.details-dialog .k-dialog-content .custom-field-details {
    border: none;
    padding: 0;
}

/* ---- and the field's own name/value split ----
   CustomFieldDetailsComp's 1fr/3fr pair is right in the Customer Details dialog where it
   has the whole width. Inside .custom-field-container the width is already divided four
   ways, leaving a ~60px name track, so it stacks instead. Keyed on the container so
   Customer Details keeps its two columns. */
.details-dialog .k-dialog-content .custom-field-container .cust-field-grid {
    grid-template-columns: minmax(0, 1fr);
}

.details-dialog .k-dialog-content .custom-field-container .cust-field-grid-info {
    min-width: 0;
    overflow-wrap: break-word;
}

/* ---- and the phone exception to the 78vh cap ----
   The cap lets a short dialog be short on a desktop. Once the shell makes the box full
   screen on a narrow viewport it does the opposite, holding the body well short of a
   dialog that is already the full height.

   Here rather than with the block that made the dialog full screen, because
   `.details-dialog .k-dialog-content` is (0,2,0) either way and an override written there
   loses the tie on source order. */
@media (max-width: 40rem) {
    .details-dialog .k-dialog-content {
        max-height: none;
    }
}

.changelog {
    --changelog-columns: minmax(0, 1fr) minmax(0, 1.1fr) minmax(0, 1.4fr) 1.75rem;

    min-height: 22rem;
    padding: 0;
    background: none;
    color: var(--font-color-2);
}

.changelog .changelog-header {
    display: grid;
    grid-template-columns: var(--changelog-columns);
    gap: 0 .75rem;
    padding: .25rem .55rem;
    background: none;
    border-bottom: 1px solid var(--accent-4);
    color: var(--font-color-2);
    font-size: 11px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: .06em;
}

.changelog .changelog-transaction + .changelog-transaction {
    border-top: 1px solid var(--hairline);
}

.changelog .changelog-transaction-header {
    display: grid;
    grid-template-columns: var(--changelog-columns);
    align-items: center;
    gap: 0 .75rem;
    padding: .25rem .55rem;
    border-bottom: none;
    color: var(--font-color-2);
    font-size: 12px;
    font-weight: normal;
}

    .changelog .changelog-transaction-header:hover {
        background-color: var(--row-hover);
    }

/* min-width: 0 because a grid item defaults to min-width: auto, and one unbreakable
   value - a long user name, a public id - then reports a wider minimum than its track
   and knocks the row out of alignment with the heading above it. */
.changelog .changelog-header-item {
    min-width: 0;
    overflow-wrap: break-word;
}

/* The chevron owns the last track. Stripped of the .k-button box so the disclosure does
   not make the row taller than the rows it opens. */
.changelog .changelog-transaction-header .changelog-header-item:last-child {
    justify-self: end;
}

.changelog .changelog-transaction-header .k-button {
    padding: 0;
    min-width: 0;
    min-height: 0;
    color: var(--font-color-muted);
}

/* <ol> brings decimal markers and a 40px indent from the browser, neither of them a
   decision anyone made - the numbers count nothing a reader refers back to. The indent
   that replaces them is deliberate: it sets the fields in from the row that owns them. */
.changelog .changelog-transaction-items {
    list-style: none;
    margin: 0;
    padding: .1rem .55rem .35rem 1.1rem;
}

/* Field, old value, arrow, new value as columns rather than four inline spans, so a
   transaction that changed six fields reads down each column instead of as six ragged
   sentences of different lengths. */
.changelog .changelog-transaction-item {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.15fr) .9rem minmax(0, 1.15fr);
    align-items: baseline;
    gap: 0 .5rem;
    padding: .1rem 0;
    font-size: 11px;
}

/* Muted name against ink values - the weighting .cust-attr gives a label and its value
   on the board behind the dialog. Bold on the name was the only thing separating the
   three cells while they were inline. */
.changelog .changelog-field-name {
    color: var(--font-color-muted);
    font-weight: normal;
}

.changelog .changelog-field-name,
.changelog .changelog-field-previous,
.changelog .changelog-field-next {
    min-width: 0;
    overflow-wrap: break-word;
}

/* Which value is which is carried by the colour, not by the arrow: at 11px on a row of
   six fields the ⇒ is easy to miss, and both values otherwise look equally current. */
.changelog .changelog-field-previous {
    /* Right-aligned so the old value butts against the arrow and the pair reads as one
       old-to-new statement. */
    text-align: right;
    color: var(--font-color-muted);
}

.changelog .changelog-field-next {
    color: var(--font-color-2);
}

.changelog .changelog-field-arrow {
    color: var(--font-color-muted);
    text-align: center;
}

.changelog .k-pager {
    background-color: transparent;
    border: none;
    border-top: 1px solid var(--hairline);
    border-radius: 0;
    padding: .25rem 0 0 0;
    font-size: 11px;
}

.changelog .k-pager-info,
.changelog .k-pager-input,
.changelog .k-pager-sizes {
    color: var(--font-color-muted);
}

.changelog .k-pager-numbers .k-link {
    color: var(--font-color-2);
}

    .changelog .k-pager-numbers .k-link.k-selected {
        background-color: var(--header-bar);
        color: var(--font-color-1);
    }

/* ============================================================================
   WORKFLOW QUEUE PAGE
   Route /workflow/queue, and the Workflow tab on the customer page - both render
   WorkflowQueueList, which carries the #WorkflowQueue wrapper. The filter form is
   a sibling with its own #WorkflowQueueFilters wrapper, so each component owns a
   scope and neither depends on being nested inside the other.

   Scoped to an id for the reason in vergent-lms-design.md §3: .component,
   .component-title and .p-2 are shared with ~30 other screens, and an id outranks
   Blazor's [b-*] isolation attributes so a shared component can be restyled here
   without !important.

   The shape is the customer page's, re-used rather than re-invented: one panel
   title bar for the queue, a card per record on the page ground, a muted label
   over ink value for every figure, and status marked only where it is the
   exception. What is new is the disclosure, because a queue item carries a dozen
   fields where a customer panel carries five.
   ============================================================================ */

/* No ground of its own: the cards sit inside the queue's own white panel, so a ground
   behind it only shows as a band around the edges. The card borders and the gap do the
   separating. */

/* The queue's own panel: one navy bar for the list, never one per record. */
#WorkflowQueue .component {
    border-radius: 4px;
    border: 1px solid var(--accent-4);
    box-shadow: var(--panel-shadow);
    background-color: var(--accent-1);
    overflow: visible;
}

#WorkflowQueue .component-title {
    display: flex;
    align-items: center;
    gap: 8px;
    background-color: var(--header-bar);
    color: var(--font-color-1);
    border-bottom: none;
    border-radius: 4px 4px 0 0;
    font-size: 11px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: .06em;
    line-height: 1.2;
    min-height: 29px;
    margin: 0;
    padding: .25rem .5rem;
}

    #WorkflowQueue .component-title > label {
        margin: 0;
        white-space: nowrap;
    }

/* ---- the header's controls ----
   Sort, collapse-all and the filter buttons are all controls over the whole queue, so
   they share one treatment: white ground, hairline border, dark text, 28px tall. Telerik
   renders its own inner elements, so the height has to be set on the wrapper, the
   .k-button and the picker alike. */
#WorkflowQueue .wq-header-controls {
    display: flex;
    align-items: center;
    gap: .4rem;
    margin-left: auto;
    flex-wrap: wrap;
    justify-content: flex-end;
}

#WorkflowQueue .wq-header-label {
    font-size: 10px;
    font-weight: 600;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: rgba(255, 255, 255, .75);
    white-space: nowrap;
}

#WorkflowQueue .wq-header-controls .k-picker,
#WorkflowQueue .wq-header-controls .k-input {
    height: 24px;
    min-height: 24px;
    border-radius: 3px;
    border-color: var(--accent-4);
    background-color: var(--accent-1);
    background-image: none;
    font-size: 11px;
    color: var(--font-color-2);
}

    #WorkflowQueue .wq-header-controls .k-input-inner,
    #WorkflowQueue .wq-header-controls .k-input-value-text {
        font-size: 11px;
        padding-block: 0;
    }

/* Collapse / expand the whole list. A native button, not a TelerikButton: it
   carries aria-expanded, which ButtonBase cannot (§16). */
#WorkflowQueue .wq-headbtn {
    display: inline-flex;
    align-items: center;
    gap: .35rem;
    height: 24px;
    padding: 0 .5rem;
    border: 1px solid var(--accent-4);
    border-radius: 3px;
    background-color: var(--accent-1);
    color: var(--font-color-2);
    font: inherit;
    font-size: 11px;
    font-weight: 400;
    text-transform: none;
    letter-spacing: 0;
    cursor: pointer;
}

    #WorkflowQueue .wq-headbtn:hover {
        border-color: var(--accent-1);
    }

    #WorkflowQueue .wq-headbtn:focus-visible {
        outline: 2px solid var(--accent-1);
        outline-offset: 1px;
    }

    /* The same rotating chevron as the per-card toggle, so one glyph means one
       thing across the screen. */
    #WorkflowQueue .wq-headbtn-chev {
        display: inline-block;
        font-size: 13px;
        line-height: 1;
        color: var(--affordance-color);
        transition: transform .15s ease;
    }

        #WorkflowQueue .wq-headbtn-chev.is-open {
            transform: rotate(90deg);
        }

/* ---- the list ----
   The query container for the two stages at the foot of this block. Declared on the list
   rather than the card so every record resolves the same stage at the same moment, which
   is what keeps the stat columns aligned. container-type makes an element the containing
   block for its position: fixed descendants - nothing in a card is fixed. */
#WorkflowQueue .wq-list {
    container-type: inline-size;
    container-name: wqlist;
}

/* A flex column with a gap, rather than a margin on each card. Telerik decides how it
   lays its template items out and whether it wraps each one, so a margin on the card is
   at the mercy of an item box we do not own - inline-block items collapse it, a wrapper
   with its own overflow hides it. A gap is set by the container, applies between every
   pair whatever the items are, and leaves nothing hanging off the end of the list. */
#WorkflowQueue .k-listview {
    border: none;
    background: transparent;
    padding: 0;
}

/* The ground the cards sit on, and the reason they read as cards at all: white cards on a
   white panel are one continuous block. A step below --hairline, so a card's edge still
   reads against it.

   The padding is here rather than on .wq-list so the ground runs edge to edge under the
   queue's title bar. One consequence to know: the container query measures .wq-list,
   which no longer carries that padding, so the queried width is ~16px wider than the
   width the cards actually get. Both stages have slack for it; a stage added close to a
   real breakpoint should account for it. */
#WorkflowQueue .k-listview-content {
    display: flex;
    flex-direction: column;
    gap: .6rem;
    border: none;
    background-color: var(--page-ground);
    padding: .5rem;
}

/* ---- the card ----
   A bordered card per record on the page ground - the .report-card shape the contract
   reserves for "a thing you launch". Separation comes from the gap and the border, never
   from a filled title bar per card: the queue already has one bar. */
#WorkflowQueue .wq-item {
    background-color: var(--accent-1);
    border: 1px solid var(--accent-4);
    border-left: 3px solid transparent;
    border-radius: 4px;
    box-shadow: var(--panel-shadow);
    overflow: hidden;
}

    #WorkflowQueue .wq-item:hover {
        border-color: #b9c6d4;
    }

    /* The left edge is status and nothing else - not the workflow definition's
       configurable colour, which would put "which workflow" in the one place the rest of
       the app reads as "how urgent". Only the exceptions are marked. */
    #WorkflowQueue .wq-item.is-bad {
        border-left-color: var(--warning-color);
    }

    #WorkflowQueue .wq-item.is-good {
        border-left-color: var(--success-color);
    }

    #WorkflowQueue .wq-item.is-working {
        border-left-color: var(--affordance-color);
    }

/* ---- the head row ----
   Fixed tracks, not auto: fixed is what lines the progress bars, the status tags and the
   actions up as columns down the whole queue. With auto tracks a long status word shunts
   that row's bar out of line with its neighbours.

   136px on the status track is measured - the widest WorkflowStatus display name,
   "Approved for Funding", comes to 133px as a .wq-flag. */
#WorkflowQueue .wq-head {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 92px 136px auto;
    align-items: center;
    gap: 0 .6rem;
    padding: .45rem .65rem .35rem;
}

/* Everything in the head row centres on one y - one answer for pieces of five different
   heights, where a padding nudge per cell stops being right the moment any changes. */
#WorkflowQueue .wq-lead {
    display: flex;
    align-items: center;
    gap: .5rem;
    min-width: 0;
}

#WorkflowQueue .wq-identity {
    display: flex;
    align-items: baseline;
    gap: .4rem;
    flex-wrap: wrap;
    min-width: 0;
}

/* The app's own link blue. The customer name is a second destination - the card opens the
   workflow, the name opens the customer - so it has to read as a link. */
#WorkflowQueue .wq-customer {
    font-size: 12.5px;
    font-weight: 600;
    color: var(--link-color);
    text-decoration: none;
}

    #WorkflowQueue .wq-customer:hover {
        text-decoration: underline;
    }

#WorkflowQueue .wq-definition {
    font-size: 11px;
    color: var(--font-color-muted);
}

/* ---- the disclosure ----
   The chevron reports STATE, never the action: it points right when the band is closed
   and rotates down when it is open, the same idiom as the customer page. A native button
   so it can carry aria-expanded. */
#WorkflowQueue .wq-toggle {
    flex: none;
    display: inline-grid;
    place-items: center;
    width: 18px;
    height: 18px;
    padding: 0;
    border: none;
    background: none;
    color: var(--affordance-color);
    font-size: 18px;
    line-height: 1;
    cursor: pointer;
    transition: transform .15s ease;
}

    #WorkflowQueue .wq-toggle.is-open {
        transform: rotate(90deg);
    }

    #WorkflowQueue .wq-toggle:focus-visible {
        outline: 2px solid var(--affordance-color);
        outline-offset: 1px;
    }

/* ---- the definition's configurable icon ----
   Confined to a 22px chip. The tenant's colour tints the chip; the glyph itself stays
   ink, so contrast holds whatever hue somebody configures. */
#WorkflowQueue .wq-glyph {
    --wq-tint: #cfd9e4;
    flex: none;
    display: inline-grid;
    place-items: center;
    width: 22px;
    height: 22px;
    border-radius: 4px;
    background-color: var(--tint-bg);
    background-color: color-mix(in srgb, var(--wq-tint) 30%, var(--surface-mix));
    box-shadow: inset 0 0 0 1px var(--tint-border);
    box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--wq-tint) 55%, var(--surface-mix));
    color: var(--font-color-2);
}

    /* Same three class names as the action buttons, and for the same reason: the
       icon takes no colour from the chip it sits in unless it is told. */
    #WorkflowQueue .wq-glyph .k-icon,
    #WorkflowQueue .wq-glyph .k-font-icon,
    #WorkflowQueue .wq-glyph .k-svg-icon,
    #WorkflowQueue .wq-glyph .k-button-icon {
        font-size: 14px;
        width: 14px;
        height: 14px;
        color: var(--font-color-2);
        fill: currentColor;
    }

    #WorkflowQueue .wq-glyph svg {
        width: 14px;
        height: 14px;
        fill: currentColor;
    }

/* ---- progress ----
   A slim bar and a count, in a fixed-width cell so the bars share one x. Deliberately not
   one segment per step, which makes a seven-step and a twelve-step workflow different
   objects and neither read as a fraction. */
#WorkflowQueue .wq-steps {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: .35rem;
    font-size: 10.5px;
    color: var(--font-color-muted);
    font-variant-numeric: tabular-nums;
}

#WorkflowQueue .wq-bar {
    flex: none;
    width: 46px;
    height: 4px;
    border-radius: 2px;
    background-color: var(--hairline);
    overflow: hidden;
}

    #WorkflowQueue .wq-bar > i {
        display: block;
        height: 100%;
        background-color: var(--color-1);
    }

#WorkflowQueue .wq-bar.is-bad > i {
    background-color: var(--warning-color);
}

#WorkflowQueue .wq-count {
    flex: none;
    width: 34px;
    text-align: right;
}

/* ---- status ----
   Mark the exception: normal states are a quiet outlined tag, only the failures take red
   and a left edge, so a queue of twelve pulls the eye to the one that has gone wrong.

   The cell is a flex box, not a block with text-align: right. An inline-block wider than
   its track overflows to the right whatever text-align says, pushing the actions out of
   column; flex shrinks it and the ellipsis takes the tail instead. */
#WorkflowQueue .wq-status {
    display: flex;
    justify-content: flex-end;
    align-items: center;
    min-width: 0;
}

#WorkflowQueue .wq-flag {
    display: inline-block;
    max-width: 100%;
    padding: 0 .3rem;
    border: 1px solid var(--hairline);
    border-radius: 8px;
    font-size: 9.5px;
    font-weight: 600;
    letter-spacing: .04em;
    text-transform: uppercase;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    color: var(--font-color-muted);
}

    #WorkflowQueue .wq-flag.is-bad {
        color: var(--warning-color);
        border-color: var(--bad-border);
    }

    #WorkflowQueue .wq-flag.is-good {
        color: var(--success-color);
        border-color: var(--good-border);
    }

    #WorkflowQueue .wq-flag.is-working {
        color: var(--affordance-color);
        border-color: var(--tint-border);
    }

/* ---- actions ----
   Two icons with tooltips rather than two worded buttons in a column of their own: a full
   action column repeated down a list is twenty-four buttons on a screen of twelve. */
#WorkflowQueue .wq-actions {
    display: flex;
    align-items: center;
    gap: .3rem;
}

/* box-sizing because the pair is a <button> and an <a>: a button is border-box by
   UA default and an anchor is not, so the same 24px gave a 24px appointment target
   beside a 25.6px open one - enough to read as two sizes side by side. */
#WorkflowQueue .wq-action {
    display: inline-grid;
    place-items: center;
    box-sizing: border-box;
    width: 24px;
    height: 24px;
    padding: 0;
    border: 1px solid var(--accent-4);
    border-radius: 3px;
    background-color: var(--accent-1);
    color: var(--font-color-2);
    cursor: pointer;
    line-height: 1;
    text-decoration: none;
}

    #WorkflowQueue .wq-action:hover {
        border-color: var(--affordance-color);
        background-color: var(--tint-bg);
    }

    /* ---- the icon has to be told its colour, every time ----
       A Telerik icon does not inherit the colour of the box it sits in: left alone it
       takes whatever the theme gives it, which here is invisible against white. Without
       this the buttons render as empty boxes.

       Three class names, because which one Telerik renders is not a thing to assume: 13.1
       emits .k-svg-icon for most icons, .k-icon for font icons and .k-button-icon inside
       its own buttons. fill: currentColor is what carries it into the SVG. */
    #WorkflowQueue .wq-action .k-icon,
    #WorkflowQueue .wq-action .k-font-icon,
    #WorkflowQueue .wq-action .k-svg-icon,
    #WorkflowQueue .wq-action .k-button-icon {
        font-size: 15px;
        width: 15px;
        height: 15px;
        color: var(--font-color-2);
        fill: currentColor;
    }

    #WorkflowQueue .wq-action svg {
        width: 15px;
        height: 15px;
        fill: currentColor;
    }

    #WorkflowQueue .wq-action:hover .k-icon,
    #WorkflowQueue .wq-action:hover .k-font-icon,
    #WorkflowQueue .wq-action:hover .k-svg-icon,
    #WorkflowQueue .wq-action:hover .k-button-icon {
        color: var(--affordance-color);
    }

    /* A locked workflow is not a button that fails; it is not a button. Quieter,
       but still legible - the icon colour has to be restated here or the rule above
       would keep it at full strength and a locked item would look openable. */
    #WorkflowQueue .wq-action.is-locked {
        cursor: default;
        border-color: var(--hairline);
        background-color: var(--accent-3);
    }

        #WorkflowQueue .wq-action.is-locked:hover {
            border-color: var(--hairline);
            background-color: var(--accent-3);
        }

        #WorkflowQueue .wq-action.is-locked .k-icon,
        #WorkflowQueue .wq-action.is-locked .k-font-icon,
        #WorkflowQueue .wq-action.is-locked .k-svg-icon,
        #WorkflowQueue .wq-action.is-locked .k-button-icon,
        #WorkflowQueue .wq-action.is-locked:hover .k-icon,
        #WorkflowQueue .wq-action.is-locked:hover .k-font-icon,
        #WorkflowQueue .wq-action.is-locked:hover .k-svg-icon,
        #WorkflowQueue .wq-action.is-locked:hover .k-button-icon {
            color: var(--font-color-muted);
        }

/* ---- the detail band ----
   Every field the record carries, one stat each, name beside value. A grid and not a
   wrapping flex row, because a grid gives every card the same track list, so stat N
   starts at the same x down the whole queue and the eye can read a column.

   230px is measured: what the longest value (140px) and the longest label (112px) need
   side by side. Below it auto-fill drops a column rather than squeezing one. */
#WorkflowQueue .wq-reveal {
    padding: 0 .65rem .35rem;
}

/* ---- a record with nothing to show ----
   One line, no rule, no band - otherwise a workflow with no details written yet costs
   more height than the card's own head row. The empty state and the audit line sit at
   either end of one line; neither is urgent enough to earn its own. The rule the audit
   line normally carries goes with the band. */
#WorkflowQueue .wq-reveal.is-empty {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: .75rem;
    padding-top: .1rem;
}

    #WorkflowQueue .wq-reveal.is-empty .wq-meta {
        border-top: none;
        margin-top: 0;
        padding-top: 0;
    }

#WorkflowQueue .wq-empty {
    font-size: 11px;
    font-style: italic;
    color: var(--font-color-muted);
    white-space: nowrap;
}

#WorkflowQueue .wq-band {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
    align-items: start;
    gap: .3rem 1.5rem;
    padding: .5rem 0 .15rem;
    margin-top: .4rem;
    border-top: 1px solid var(--hairline);
}

/* One line each, baseline aligned - a 9px uppercase label beside a 12px value has to sit
   on a shared baseline or the label appears to float above its number. min-width: 0 or a
   grid item refuses to go below its min-content width and the nowrap values blow the
   track out. */
#WorkflowQueue .wq-stat {
    display: flex;
    align-items: baseline;
    gap: .4rem;
    min-width: 0;
}

/* Dark, uppercase and small. The label is the smaller of the two and still reads as the
   header because weight, case and letter-spacing carry it, while the value keeps more
   mass at 12px. Deliberately not muted, which makes these names hard to pick out of a
   dense row. */
#WorkflowQueue .wq-stat-k {
    flex: none;
    font-size: 9px;
    font-weight: 700;
    letter-spacing: .06em;
    line-height: 1.35;
    text-transform: uppercase;
    color: var(--font-color-2);
    white-space: nowrap;
}

#WorkflowQueue .wq-stat-v {
    min-width: 0;
    font-size: 12px;
    line-height: 1.25;
    color: var(--font-color-2);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

    #WorkflowQueue .wq-stat-v a {
        color: var(--link-color);
        text-decoration: none;
    }

        #WorkflowQueue .wq-stat-v a:hover {
            text-decoration: underline;
        }

/* ---- the audit line ----
   Bottom right, under a hairline. The least urgent line on the card, so no fill of its
   own - that would be a third fill in a stack that already has two. */
#WorkflowQueue .wq-meta {
    padding-top: .3rem;
    margin-top: .15rem;
    border-top: 1px solid var(--hairline);
    font-size: 10.5px;
    color: var(--font-color-muted);
    text-align: right;
}

/* Assignment slots keep their own footer, left of the audit line. */
#WorkflowQueue .wq-slots {
    padding-top: .35rem;
}

/* ---- empty and loading states ---- */
#WorkflowQueue .workflow-msg {
    padding: .75rem .65rem;
    color: var(--font-color-muted);
    font-size: 12px;
}

/* ============================================================
   THE FILTER FORM
   Its own scope, because it is a sibling of the queue rather than a child - the
   list carries #WorkflowQueue and the form carries this, so neither depends on
   being nested inside the other.
   ============================================================ */
#WorkflowQueueFilters {
    margin-bottom: .5rem;
}

#WorkflowQueueFilters .component {
    border-radius: 4px;
    border: 1px solid var(--accent-4);
    box-shadow: var(--panel-shadow);
    background-color: var(--accent-1);
    overflow: hidden;
}

#WorkflowQueueFilters .component-title {
    display: flex;
    align-items: center;
    gap: 8px;
    background-color: var(--header-bar);
    color: var(--font-color-1);
    border-bottom: none;
    border-radius: 4px 4px 0 0;
    font-size: 11px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: .06em;
    line-height: 1.2;
    min-height: 29px;
    margin: 0;
    padding: .25rem .5rem;
}

    #WorkflowQueueFilters .component-title > label {
        margin: 0;
    }

/* ---- one field per column, label above control ----
   A filter is a labelled control, not a panel, so it gets the .cust-attr hierarchy - a
   small muted name over the thing you operate - rather than a .component with its own
   navy title bar. */
#WorkflowQueueFilters .wq-filter-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
    gap: .5rem .75rem;
    padding: .55rem .65rem;
}

#WorkflowQueueFilters .wq-filter {
    display: flex;
    flex-direction: column;
    gap: .15rem;
    min-width: 0;
}

#WorkflowQueueFilters .wq-filter-label {
    font-size: 9px;
    font-weight: 700;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--font-color-2);
}

/* One control treatment for every field: 28px tall, hairline border, white ground.
   Telerik sizes a multiselect from its own theme, so the height has to be set on the
   wrapper and the inner input alike - Class lands on the wrapper and a lowercase class on
   the inner input (§16). */
#WorkflowQueueFilters .k-picker,
#WorkflowQueueFilters .k-input,
#WorkflowQueueFilters .k-multiselect {
    min-height: 28px;
    border-radius: 3px;
    border-color: var(--accent-4);
    background-color: var(--accent-1);
    background-image: none;
    font-size: 12px;
    color: var(--font-color-2);
}

    #WorkflowQueueFilters .k-input-inner {
        font-size: 12px;
    }

    #WorkflowQueueFilters .k-input-inner::placeholder {
        color: var(--font-color-muted);
    }

/* The chips a multiselect draws for each choice. */
#WorkflowQueueFilters .k-chip {
    border-radius: 8px;
    font-size: 11px;
    background-color: var(--tint-bg);
    border-color: var(--tint-border);
    color: var(--font-color-2);
}

/* Right aligned, and flex: 1 1 auto is what makes that true rather than merely declared.
   TelerikForm puts FormButtons inside .k-form-buttons, which the theme lays out
   `display: flex; flex-flow: row nowrap` - so without the grow this div sizes to its own
   buttons and its justify-content has no free space to distribute. */
#WorkflowQueueFilters .wq-filter-actions {
    display: flex;
    flex: 1 1 auto;
    justify-content: flex-end;
    gap: .4rem;
    padding: 0 .65rem .55rem;
}

    /* Filter is the one filled button here; Reset is quiet beside it. Same call
       as the search page's single filled action. */
    #WorkflowQueueFilters .wq-filter-actions .k-button {
        height: 28px;
        min-height: 28px;
        border-radius: 3px;
        font-size: 12px;
        padding: 0 .75rem;
    }

/* ============================================================
   RESPONSIVE STAGES - deliberately last in this block.

   A container query adds no specificity of its own, so these rules and the base
   rules they override are both (1,1,0) and the winner is decided by source order
   alone. Declared next to .wq-list they would every one of them lose silently -
   the progress bar would keep justify-content: flex-end and sit at the right of
   its column instead of the left, with nothing in the CSS to say the rule had
   been ignored. Anything overriding a base rule from inside a container query has
   to come after it.

   Container queries and not @media: the left nav is fit-content, so the viewport
   is measuring the wrong thing (§7).
   ============================================================ */

/* Stage one: the fixed right-hand tracks - about 290px in all - stop leaving the customer
   name a usable column. The identity takes the full first line and the controls drop to a
   second, left aligned so they read as a group rather than three things stranded at the
   right edge. */
@container wqlist (max-width: 780px) {
    #WorkflowQueue .wq-head {
        grid-template-columns: minmax(0, 1fr) auto auto;
        row-gap: .4rem;
    }

    #WorkflowQueue .wq-lead {
        grid-column: 1 / -1;
    }

    #WorkflowQueue .wq-steps {
        justify-content: flex-start;
    }

    #WorkflowQueue .wq-status {
        justify-content: flex-start;
    }
}

/* Stage two: phone. The status takes its own row and the band is one stat per
   line. The actions keep their own column so they stay 22px targets rather than
   shrinking into the flow. */
@container wqlist (max-width: 430px) {
    #WorkflowQueue .wq-head {
        grid-template-columns: minmax(0, 1fr) auto;
        row-gap: .35rem;
    }

    #WorkflowQueue .wq-steps {
        grid-column: 1;
        grid-row: 2;
    }

    #WorkflowQueue .wq-status {
        grid-column: 1 / -1;
        grid-row: 3;
    }

    #WorkflowQueue .wq-head,
    #WorkflowQueue .wq-reveal {
        padding-left: .55rem;
        padding-right: .55rem;
    }

    /* No corner left for the audit line to sit in. */
    #WorkflowQueue .wq-meta {
        text-align: left;
    }

    /* ---- the workflow type takes its own line ----
       .wq-identity is a wrapping flex row, so without this the type sits wherever the
       name leaves room - beside it on one record and wrapped on the next, down a queue
       of twelve.

       A 100% basis forces the break: line filling is decided by each item's hypothetical
       main size, so an item that cannot share a line closes the one before it (§16).
       Baseline alignment means nothing once they are on separate lines, so the identity
       aligns start instead. */
    #WorkflowQueue .wq-identity {
        align-items: flex-start;
        row-gap: .1rem;
    }

    #WorkflowQueue .wq-definition {
        flex: 0 0 100%;
    }

    /* ---- an empty band keeps the layout a full one has ----
       .wq-reveal.is-empty puts the "no details" note and the audit line at either end of
       one line, which saves a line on a desktop and collides at 390px.

       So at this width the empty case takes the full one's shape: the section, the
       hairline, then Created / Updated. */
    #WorkflowQueue .wq-reveal.is-empty {
        display: block;
        padding-top: 0;
    }

        #WorkflowQueue .wq-reveal.is-empty .wq-empty {
            display: block;
            padding: .5rem 0 .15rem;
            margin-top: .4rem;
            border-top: 1px solid var(--hairline);
            white-space: normal;
        }

        /* The audit line's own rule comes back with it - the desktop shape had
           moved it onto the note's line. */
        #WorkflowQueue .wq-reveal.is-empty .wq-meta {
            border-top: 1px solid var(--hairline);
            margin-top: .15rem;
            padding-top: .3rem;
        }
}

/* ---- the two actions take a finger ----
   Appointment and Open are 15px glyphs in a 24px box, under the touch minimum and .3rem
   apart at the card's right edge. 18px of glyph in a 30px box, which the head row already
   has the height for, so no card gets taller.

   The one rule in this block that is rightly a media query: everything else responds to
   the width the list has, but a finger does not. Keyed on the pointer, with a width query
   beside it for phones reporting fine. */
@media (pointer: coarse), (max-width: 40rem) {
    #WorkflowQueue .wq-actions {
        gap: .4rem;
    }

    #WorkflowQueue .wq-action {
        width: 30px;
        height: 30px;
    }

        #WorkflowQueue .wq-action .k-icon,
        #WorkflowQueue .wq-action .k-font-icon,
        #WorkflowQueue .wq-action .k-svg-icon,
        #WorkflowQueue .wq-action .k-button-icon {
            font-size: 18px;
            width: 18px;
            height: 18px;
        }

        #WorkflowQueue .wq-action svg {
            width: 18px;
            height: 18px;
        }
}

/* Both rotating chevrons honour the reduced-motion preference. Placed after the rules
   that set the transition, or this loses the specificity tie and fails silently for
   exactly the people who asked for it. */
@media (prefers-reduced-motion: reduce) {
    #WorkflowQueue .wq-toggle,
    #WorkflowQueue .wq-headbtn-chev {
        transition: none;
    }
}

/* ============================================================================
   WORKFLOW EXECUTION SCREEN
   Route /workflow/{id}, and the Workflow tab on the customer page - both render
   WorkflowContainer, which carries the #WorkflowScreen wrapper, so one id covers
   both entry points.

   Scoped to an id for the reason in vergent-lms-design.md §3: .component,
   .component-title, .component-header and .k-card are shared with ~30 other
   screens, and an id outranks Blazor's [b-*] isolation attributes so the shared
   step and header components can be restyled here without !important.

   The shape is the workflow queue's, reused rather than reinvented: one navy
   panel bar for the whole workflow, cards on --page-ground, a quiet bordered
   card per step with a status left edge, a muted audit line under a hairline,
   and status marked only where it is the exception. A teller now opens a step
   from the redesigned queue into the same language they left.

   Three greens went. #237631 was on the container bar; #5ec232 was on every rail
   icon whatever the step's state; #00b050 was in the loan-signing block. Green
   survives only as --success-color on a completed step, which is the one place it
   discriminates. The container bar's own hex was never chosen for this screen at
   all - StepUI passed no HeaderType, the enum default fell through the header's
   ternary, and every step card was picking up the container fill by accident.

   One deliberate departure from the mockup: every filled bar here takes
   --header-bar, not --color-1. The mockup was drawn before :root split the two,
   and :root now states the rule outright - --color-1 is rewritten per company at
   runtime, so anything carrying white text and owing a contrast guarantee must
   use --header-bar. --color-1 keeps its ink role here through
   --affordance-color: rail selection, focus rings, the current chip's border.

   The three container stages and the coarse-pointer block are at the end of this
   block, after every base rule they override: a container query adds no
   specificity, so source order alone decides.
   ============================================================================ */

/* The panel bar. One workflow, one bar - mirroring #WorkflowQueue .component-title
   so the two screens read as one product. NoteListComp's header sits inside the
   notes panel and is also a ComponentContainer, so it converts with it. */
#WorkflowScreen .component-container-header {
    display: flex;
    align-items: center;
    gap: 8px;
    background-color: var(--header-bar);
    color: var(--font-color-1);
    border-bottom: none;
    border-radius: 4px 4px 0 0;
    font-size: 11px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: .06em;
    line-height: 1.2;
    min-height: var(--wf-bar-h, 29px);
    margin: 0;
    padding: .25rem .5rem;
}

    #WorkflowScreen .component-container-header > label,
    #WorkflowScreen .component-container-header .component-header-child-content > label {
        margin: 0;
    }

    /* The bar's own buttons stay white on the fill, at the reveal-toggle metric. The fill
       and the hairline have to be cleared explicitly: the screen-wide `.k-button` rule
       further down paints every button --accent-1 with an --accent-4 border, which on this
       bar rendered two white slabs with white icons inside them. */
    #WorkflowScreen > .workflow-container > .component-container-header button.header-button,
    #WorkflowScreen > .workflow-container > .component-container-header .k-button.header-button {
        display: inline-grid;
        place-items: center;
        width: 20px;
        height: 20px;
        min-height: 0;
        min-width: 0;
        margin: 0;
        padding: 0;
        border: none;
        border-radius: 4px;
        background-color: transparent;
        color: var(--font-color-1);
        font-size: 12px;
    }

        #WorkflowScreen > .workflow-container > .component-container-header button.header-button:hover,
        #WorkflowScreen > .workflow-container > .component-container-header .k-button.header-button:hover {
            background-color: rgba(255, 255, 255, .18);
            border-color: transparent;
            color: var(--font-color-1);
        }

        #WorkflowScreen > .workflow-container > .component-container-header button.header-button:focus-visible,
        #WorkflowScreen > .workflow-container > .component-container-header .k-button.header-button:focus-visible {
            outline: 2px solid var(--font-color-1);
            outline-offset: -2px;
        }

/* Links inside a step's grid take the app's link colour rather than the rgb(2,82,138)
   an unscoped <style> block in Workflow.razor used to force on every grid in the app
   with !important. §2 keeps link colour a literal on purpose. */
#WorkflowScreen .k-grid .k-master-row a {
    color: var(--link-color, #0d6efd);
}

/* ---- the step rail ----
   A quiet white column against the ground the cards sit on, separated by a hairline
   rather than by a fill. max-width and not a fixed 186px: the rail collapses to icons
   when the teller closes it, and a fixed width would hold the gap open with nothing
   in it. */
#WorkflowScreen .workflow-container > .workflow-index {
    background-color: var(--accent-1);
    border-right: 1px solid var(--hairline);
    padding: .5rem .35rem;
    max-width: 186px;
}

#WorkflowScreen .workflow-index-item {
    gap: .35rem;
    min-height: 22px;
    border-radius: 3px;
    padding: .2rem .4rem;
    font-size: 11.5px;
    color: var(--font-color-2);
}

    #WorkflowScreen .workflow-index-item:hover {
        background-color: var(--row-hover);
    }

    #WorkflowScreen .workflow-index-item:focus-visible {
        outline: 2px solid var(--affordance-color);
        outline-offset: -2px;
    }

    /* The selected state used to be hover only, so the rail could never say where the
       teller was - which is the one thing it exists to say. */
    #WorkflowScreen .workflow-index-item.is-current {
        background-color: var(--tint-bg);
        color: var(--affordance-color);
        font-weight: 600;
    }

/* A long authored step name ellipsises rather than widening the rail past its cap. */
#WorkflowScreen .workflow-index-item-text {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* The three marks. */
#WorkflowScreen .workflow-index-item-icon {
    width: 13px;
    height: 13px;
    font-size: 12px;
    line-height: 1;
}

#WorkflowScreen .workflow-index-item-icon-complete {
    color: var(--success-color);
}

#WorkflowScreen .workflow-index-item-icon-skipped {
    color: var(--font-color-muted);
}

    /* Open is a hollow ring in the hairline's own colour, never green: an unreached
       step is the normal state and the normal state carries no colour (§6). Drawn as
       a ring rather than a pale glyph, so it reads as "not yet" and not as a check
       somebody turned the contrast down on. */
    #WorkflowScreen .workflow-index-item-icon-open {
        width: 9px;
        height: 9px;
        margin: 0 2px;
        border-radius: 50%;
        box-shadow: inset 0 0 0 1px var(--accent-4);
        color: transparent;
    }

/* ---- the ground ----
   Cards on --page-ground, the .k-listview-content precedent from the queue. Without
   it a white card on a white column is not a card at all, and the --accent-4 border
   is the only thing marking where a step begins.

   The two column-toggle chevrons that used to hold a 22px gutter open on each side
   are gone: both side columns are permanent on the desktop now, and below the first
   stage the section switch is what chooses between them. */
#WorkflowScreen .workflow-container .workflow {
    background-color: var(--page-ground);
    padding: .5rem;
}

/* Every grid item takes min-width: 0. A grid track sized `auto` or `1fr` still refuses
   to go below its item's min-content width, and this screen is full of things that
   cannot wrap - the rail's horizontal strip, the section switch, a wide step table. One
   of them then widens the whole grid past #WorkflowScreen, and because .content-wrapper
   is overflow-y: auto (which computes overflow-x: auto too) the entire screen scrolls
   sideways: the tabs run off the right edge on a phone, and any scrollIntoView lands the
   teller somewhere in the middle of a horizontal scroll rather than at the top left. */
#WorkflowScreen .workflow-container > .workflow-index,
#WorkflowScreen .workflow-container .workflow,
#WorkflowScreen .workflow-container .wf-switch,
#WorkflowScreen .workflow-pane {
    min-width: 0;
}

#WorkflowScreen .workflow-container .workflow-notes {
    display: flex;
    flex-direction: column;
    gap: .6rem;
    background-color: var(--page-ground);
    padding: .5rem .5rem .5rem 0;
}

#WorkflowScreen .workflow-pane {
    display: flex;
    flex-direction: column;
    gap: .6rem;
    min-width: 0;
}

/* HeaderUI's card carries .component-header too, and a step renders one inside its own
   body - so every step-header rule below is qualified with .header, the class only
   ComponentHeader's bar emits. Without it the step rules tied this one on specificity,
   won on source order, and turned the card into a centred column flex: the band's
   auto-fill grid then sized against an indefinite width, which is one track, and every
   stat stacked. */
#WorkflowScreen .k-card.component-header {
    display: block;
    background-color: var(--accent-1);
    border: 1px solid var(--accent-4);
    border-radius: 4px;
    box-shadow: var(--panel-shadow);
    margin-bottom: .6rem;
    color: var(--font-color-2);
}

    /* The card's header is the only part HeaderUI renders, so it carries the padding and
       loses the fill, the bottom rule and the centring. */
    #WorkflowScreen .k-card.component-header .k-card-header {
        display: block;
        padding: .4rem .55rem;
        border: none;
        background-color: transparent;
        color: var(--font-color-2);
        text-align: left;
    }

    #WorkflowScreen .k-card.component-header .k-card-title {
        margin: 0;
        font-size: inherit;
        font-weight: inherit;
    }

/* The band. Same auto-fill track as #WorkflowQueue .wq-band, so a workflow with four
   fields and one with fourteen both read as the same shape at any width. */
#WorkflowScreen .header-stats {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(min(230px, 100%), 1fr));
    align-items: start;
    gap: .3rem 1.5rem;
    text-align: left;
}

/* .wq-stat's metrics exactly: one line each, baseline aligned, min-width: 0 so a nowrap
   value cannot blow its track out. */
#WorkflowScreen .header-item {
    display: flex;
    align-items: baseline;
    gap: .4rem;
    min-width: 0;
}

#WorkflowScreen .header-item-k {
    flex: none;
    font-size: 9px;
    font-weight: 700;
    letter-spacing: .06em;
    line-height: 1.35;
    text-transform: uppercase;
    color: var(--font-color-2);
    white-space: nowrap;
}

#WorkflowScreen .header-item-v {
    min-width: 0;
    font-size: 12px;
    line-height: 1.25;
    color: var(--font-color-2);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

    #WorkflowScreen .header-item-v a {
        color: var(--link-color);
        text-decoration: none;
    }

        #WorkflowScreen .header-item-v a:hover {
            text-decoration: underline;
        }

/* A value with nothing behind it still holds its column, so the grid stays aligned down
   the band rather than reflowing around the empty ones. */
#WorkflowScreen .header-item-v:empty::before {
    content: "\2014";
    color: var(--font-color-muted);
}

#WorkflowScreen .header-record + .header-record {
    margin-top: .45rem;
    padding-top: .45rem;
    border-top: 1px solid var(--hairline);
}

#WorkflowScreen .cust-empty {
    padding: .25rem 0;
    font-size: 11px;
    color: var(--font-color-muted);
}

/* ---- the customer panels a step embeds ----
   The address, phone, employer, vehicle and reference steps render the same
   CustAddressComp / CustPhoneComp / CustVehiclePropComp panels the customer page does,
   and those were restyled only under #CustomerComponents. Two things came with them.

   .component sets --font-color-1 for the filled panels it predates, and the customer
   page answers that row by row (.cust-row-main, .cust-row-sub). None of those rules are
   in scope here, so every embedded row was white text on the panel's near-white ground -
   the address and the phone number were on the page and unreadable.

   The bar's icons: .component-title itself takes --header-bar-ink from the ink block at
   the end of this file, but the changelog control is a TelerikButton, so the screen-wide
   .k-button rule below dressed it as a 28px --accent-1 pill with dark text - a black icon
   on the blue bar, beside the plain font icons that were correctly white.

   The row layout itself (.cust-row and .cust-flag) is shared by scoping those rules to
   :is(#CustomerComponents, #WorkflowScreen). Without it every .cust-row fell back to
   block flow and a panel of records read as one undivided column of lines. */
#WorkflowScreen .component {
    color: var(--font-color-2);
}

/* The rows carry their own .55rem inset, as they do on the customer page, so the
   wrapper's padding would double it and push the rows off the title's left edge. */
#WorkflowScreen .component > .p-2:has(> .cust-row) {
    padding: 0 !important;
}

#WorkflowScreen .component-title .header-buttons {
    display: flex;
    align-items: center;
    gap: 2px;
    margin-left: auto;
}

    /* float-end on the icon wrappers fights the flex row; neutralise it. */
    #WorkflowScreen .component-title .header-buttons .float-end {
        float: none !important;
        display: flex;
        align-items: center;
    }

/* Any control in a panel bar, wrapped or not, at the reveal-toggle metric and in the
   bar's own ink. */
#WorkflowScreen .component-title .k-button {
    display: inline-grid;
    place-items: center;
    width: 20px;
    height: 20px;
    min-height: 0;
    min-width: 0;
    margin: 0;
    padding: 0;
    border: none;
    border-radius: 4px;
    background-color: transparent;
    color: var(--header-bar-ink);
    font-size: 12px;
}

    #WorkflowScreen .component-title .k-button:hover {
        background-color: rgba(255, 255, 255, .18);
        border-color: transparent;
        color: var(--header-bar-ink);
    }

    #WorkflowScreen .component-title .k-button:focus-visible {
        outline: 2px solid var(--header-bar-ink);
        outline-offset: -2px;
    }

#WorkflowScreen .component-title .k-icon,
#WorkflowScreen .component-title .k-font-icon,
#WorkflowScreen .component-title .k-svg-icon,
#WorkflowScreen .component-title .k-button-icon {
    color: var(--header-bar-ink);
}

/* ---- the step card ----
   The .wq-item shape. Separation comes from the gap, the border and the ground,
   never from a filled title bar per card: the workflow already has one bar. */
#WorkflowScreen .component-step {
    background-color: var(--accent-1);
    border: 1px solid var(--accent-4);
    border-left: 3px solid transparent;
    border-radius: 4px;
    box-shadow: var(--panel-shadow);
    margin-bottom: .6rem;
    overflow: hidden;
}

    #WorkflowScreen .component-step:hover {
        border-color: #b9c6d4;
    }

    /* The left edge is step status and nothing else (§1 rule 5). An open step is
       unmarked. */
    #WorkflowScreen .component-step.is-complete {
        border-left-color: var(--success-color);
    }

    #WorkflowScreen .component-step.is-skipped {
        border-left-color: var(--font-color-muted);
    }

/* ---- the step header ----
   A card header, so no fill of its own (§15 Don't): a --color-1 bar per step repeats
   the panel's title bar a dozen times down the workflow. 26px rather than the bar's
   29px - it is a card's header, not a panel's. */
#WorkflowScreen .component-step .header.component-header {
    display: flex;
    align-items: center;
    gap: .35rem;
    background-color: var(--accent-1);
    color: var(--font-color-2);
    border-bottom: none;
    border-radius: 4px 4px 0 0;
    min-height: 26px;
    padding: .3rem .55rem;
    font-size: 11.5px;
    font-weight: 600;
    text-transform: none;
    letter-spacing: normal;
}

    /* The hairline belongs to an open card - on a collapsed one it would be drawing
       the bottom of nothing. */
    #WorkflowScreen .component-step:not(.collapsed) .header.component-header {
        border-bottom: 1px solid var(--hairline);
    }

    #WorkflowScreen .component-step.collapsed .header.component-header {
        border-radius: 4px;
    }

    #WorkflowScreen .component-step .header.component-header > label,
    #WorkflowScreen .component-step .header.component-header .component-header-child-content > label {
        margin: 0;
        font-weight: 600;
        /* Step names are DB-driven and can be long; the header wraps rather than
           truncates, because a name is what tells two steps apart. */
        overflow-wrap: anywhere;
    }

    #WorkflowScreen .component-step .header.component-header .component-header-child-content {
        display: flex;
        align-items: center;
        flex-wrap: wrap;
        gap: .35rem .5rem;
        min-width: 0;
    }

    /* The header's buttons were white for a blue bar. On a white one they take the
       §8 reveal-toggle metrics and the muted ink the rest of the card's chrome uses. */
    #WorkflowScreen .component-step .header.component-header button.header-button,
    #WorkflowScreen .component-step .header.component-header .k-button.header-button {
        display: inline-grid;
        place-items: center;
        width: 20px;
        height: 20px;
        min-height: 0;
        min-width: 0;
        margin: 0;
        padding: 0;
        border: none;
        border-radius: 4px;
        background-color: transparent;
        color: var(--font-color-muted);
        font-size: 12px;
    }

        #WorkflowScreen .component-step .header.component-header button.header-button:hover,
        #WorkflowScreen .component-step .header.component-header .k-button.header-button:hover {
            background-color: var(--tint-bg);
        }

        #WorkflowScreen .component-step .header.component-header button.header-button:focus-visible,
        #WorkflowScreen .component-step .header.component-header .k-button.header-button:focus-visible {
            outline: 2px solid var(--affordance-color);
            outline-offset: -2px;
        }

    /* The collapse chevron takes the .cust-chevron contract - 11.5px, rotate(90deg)
       when open. The reduced-motion opt-out is at the end of this block, after every
       rule that sets the transition. */
    #WorkflowScreen .component-step .collapse-button .k-icon,
    #WorkflowScreen .component-step .collapse-button .k-font-icon,
    #WorkflowScreen .component-step .collapse-button .k-button-icon {
        font-size: 11.5px;
        line-height: 1;
        color: var(--font-color-muted);
        transition: transform .15s ease;
    }

/* The completed mark, and the only green left on the screen. */
#WorkflowScreen .wf-step-mark {
    display: inline-flex;
    align-items: center;
    margin-left: auto;
    color: var(--success-color);
    font-size: 13px;
}

/* Skipped says so in a word rather than in a colour, on the .cust-flag.is-inactive
   metrics (§6: if a flag needs a tooltip to be understood, it needs a word). */
#WorkflowScreen .wf-flag {
    display: inline-block;
    padding: 0 .25rem;
    border: 1px solid var(--hairline);
    border-radius: 8px;
    font-size: 9.5px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: .04em;
    white-space: nowrap;
}

    #WorkflowScreen .wf-flag.is-muted {
        color: var(--font-color-muted);
    }

#WorkflowScreen .wf-step-skip {
    display: inline-flex;
    align-items: center;
    gap: .35rem;
    margin-left: auto;
}

    /* Once the mark has taken the auto margin the skip control must not take a second
       one, or the two split the free space between them instead of sharing the right
       edge. */
    #WorkflowScreen .wf-step-mark ~ .wf-step-skip,
    #WorkflowScreen .wf-flag ~ .wf-step-skip {
        margin-left: 0;
    }

#WorkflowScreen .wf-step-skip-label {
    font-size: 11px;
    font-weight: 400;
    color: var(--font-color-muted);
    white-space: nowrap;
}

/* ---- the step body ---- */
#WorkflowScreen .component-step .k-card-body {
    padding: .5rem .55rem;
    font-size: 12px;
}

#WorkflowScreen .component-step .k-form-label,
#WorkflowScreen .component-step .k-label {
    display: block;
    margin-bottom: 2px;
    font-size: 11px;
    color: var(--font-color-muted);
}

/* The §8 input contract: 28px, 4px radius, one hairline, 12px, and the focus ring on
   the wrapper because focus lands on an inner element. */
#WorkflowScreen .k-textarea,
#WorkflowScreen .k-input,
#WorkflowScreen .k-picker {
    border-radius: 4px;
    border: 1px solid var(--accent-4);
    background-color: var(--accent-1);
    font-size: 12px;
}

#WorkflowScreen .k-input,
#WorkflowScreen .k-picker {
    min-height: 28px;
}

#WorkflowScreen .component-step .k-textarea .k-input-inner {
    min-height: 44px;
    padding: .25rem .45rem;
}

    #WorkflowScreen .k-textarea:focus-within,
    #WorkflowScreen .k-input:focus-within,
    #WorkflowScreen .k-picker:focus-within {
        outline: 2px solid var(--affordance-color);
        outline-offset: -2px;
        box-shadow: none;
    }

/* The Select-files button already reads as a control, and the drag hint is a sentence.
   A bordered, filled strip drawn around the two of them is a panel inside a panel - the
   card is the section, and this was a second one nested in it. Border and fill dropped;
   the element stays as the flex row that puts the button and the hint on one line, and
   the drop target is unaffected because it is the same element either way. */
#WorkflowScreen .k-dropzone,
#WorkflowScreen .k-upload-dropzone {
    min-height: 0;
    margin-top: .4rem;
    padding: 0;
    border: none;
    background: none;
    font-size: 11px;
    color: var(--font-color-muted);
}

/* Not italic-bold. A hint is the quietest line in the card, so it takes the muted
   sub-line's treatment. */
#WorkflowScreen .k-form-hint {
    margin-top: 3px;
    font-size: 10.5px;
    font-style: normal;
    font-weight: 400;
    color: var(--font-color-muted);
}

    #WorkflowScreen .component-step .k-form-hint b {
        font-weight: 600;
        color: var(--font-color-muted);
    }

/* One button treatment on this screen: white, one hairline, dark text - the §8
   header-button metric. Telerik fills a primary from the theme, and a disabled primary
   is a desaturated slab of it - which is what the Add Note button in the notes panel was
   reading as: a grey box with white text in it rather than a control. Scoped to the whole
   screen and not just the step bodies, because the notes panel is a form too. Header
   buttons are excluded by being more specific, not by being listed here. */
#WorkflowScreen .k-button {
    min-height: 28px;
    height: 28px;
    padding: 0 .75rem;
    border: 1px solid var(--accent-4);
    border-radius: 4px;
    background-color: var(--accent-1);
    background-image: none;
    color: var(--font-color-2);
    font-size: 12px;
    font-weight: 500;
}

    #WorkflowScreen .k-button:hover {
        background-color: var(--tint-bg);
        border-color: #b9c6d4;
        color: var(--font-color-2);
    }

    #WorkflowScreen .k-button:focus-visible {
        outline: 2px solid var(--affordance-color);
        outline-offset: 1px;
    }

    /* app.css carries `.btn .k-button-text { color: var(--font-color-1) !important }`
       app-wide, written for the filled .btn this screen no longer draws - so any button
       still carrying that class (ReferenceStepUI's add-new) put a white label on the white
       fill above. Answered rather than escalated around: the label follows the button's own
       colour, whichever of the states below is in force. */
    #WorkflowScreen .k-button .k-button-text {
        color: inherit !important;
    }

    /* A selected toggle takes the same fill as a selected segment of a group. Telerik's own
       selected ink is a class rule, so it lost to the screen-wide colour above and the
       loan-selection step's None read as black text on the fill. Stated before the disabled
       rules, so a disabled toggle still reads quiet rather than filled. */
    #WorkflowScreen .k-button.k-selected,
    #WorkflowScreen .k-toggle-button.k-selected {
        background-color: var(--header-bar);
        border-color: var(--header-bar);
        color: var(--font-color-1);
    }

        #WorkflowScreen .k-button.k-selected:hover,
        #WorkflowScreen .k-toggle-button.k-selected:hover {
            background-color: var(--header-bar);
            border-color: var(--header-bar);
            color: var(--font-color-1);
        }

    /* A disabled control is quiet, not filled. */
    #WorkflowScreen .k-button:disabled,
    #WorkflowScreen .k-button.k-disabled {
        background-color: var(--accent-1);
        border-color: var(--accent-4);
        color: var(--font-color-muted);
    }

#WorkflowScreen .k-button.k-button-solid-primary {
    background-color: var(--header-bar);
    border-color: var(--header-bar);
    color: var(--font-color-1);
}

    #WorkflowScreen .k-button.k-button-solid-primary:hover {
        background-color: var(--header-bar-hover);
        border-color: var(--header-bar-hover);
        color: var(--font-color-1);
    }

    /* Still quiet when disabled. A desaturated slab of the fill is what the Add Note
       button used to read as, and restoring the fill above brings that back unless the
       disabled state is restated at higher specificity than it. */
    #WorkflowScreen .k-button.k-button-solid-primary:disabled,
    #WorkflowScreen .k-button.k-button-solid-primary.k-disabled {
        background-color: var(--accent-1);
        border-color: var(--accent-4);
        color: var(--font-color-muted);
    }

/* Close is a primary in the markup but it commits nothing - it leaves. Filling it would
   put the same weight on the way out as on the action that finishes the workflow, right
   next to each other in the same bar. */
#WorkflowScreen .workflow-close .k-button {
    background-color: var(--accent-1);
    border-color: var(--accent-4);
    color: var(--font-color-2);
}

    #WorkflowScreen .workflow-close .k-button:hover {
        background-color: var(--tint-bg);
        border-color: #b9c6d4;
        color: var(--font-color-2);
    }

#WorkflowScreen .k-button-group .k-button {
    border-radius: 0;
}

    #WorkflowScreen .k-button-group .k-button:first-child {
        border-start-start-radius: 4px;
        border-end-start-radius: 4px;
    }

    #WorkflowScreen .k-button-group .k-button:last-child {
        border-start-end-radius: 4px;
        border-end-end-radius: 4px;
    }

    #WorkflowScreen .k-button-group .k-button.k-selected {
        background-color: var(--header-bar);
        border-color: var(--header-bar);
        color: var(--font-color-1);
    }

        /* The fill has to survive a hover, or the selected segment turns back into a
           tinted one under the pointer and the group says nothing. */
        #WorkflowScreen .k-button-group .k-button.k-selected:hover {
            background-color: var(--header-bar);
            border-color: var(--header-bar);
            color: var(--font-color-1);
        }

    /* The dropzone's own Select-files button is smaller again - it sits inside an 11px
       strip - and app.css sets .k-upload-button with !important app-wide, so matching it
       here takes !important back. */
    #WorkflowScreen .k-dropzone .k-button,
    #WorkflowScreen .k-upload-dropzone .k-button,
    #WorkflowScreen .k-upload-button {
        background-color: var(--accent-1) !important;
        height: 22px;
        min-height: 22px;
        padding: 0 .5rem;
        font-size: 11px;
    }

/* ---- the card footer ----
   The audit line takes .wq-meta's treatment. It replaces two floated k-card-subtitle
   spans, which is also what lets the two halves share a line without clearing. */
#WorkflowScreen .component-step .k-card-footer {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: .5rem;
    padding: .25rem .55rem;
    border-top: 1px solid var(--hairline);
    background-color: transparent;
    font-size: 11px;
    color: var(--font-color-muted);
}

    #WorkflowScreen .wf-step-audit-when,
    #WorkflowScreen .wf-step-audit-who {
        margin: 0;
        font-size: 11px;
        color: var(--font-color-muted);
    }

    #WorkflowScreen .wf-step-audit-who {
        text-align: right;
    }

/* ---- grids inside a step ----
   The same exemption from the app-wide filled .k-grid-header that #CustomerComponents
   and #HomeScreenComponents already carry. Every element in the header chain is named,
   because the fill is not on the one you would guess: app.css also carries an
   element-qualified `thead.k-table-thead`, which no class-based override reaches (§16).

   This also retints ReferenceStepUI's hand-rolled .component-title-details and
   DecisionEngineProductsOffered's .component-title without touching either file. */
#WorkflowScreen .component-step .k-grid .k-grid-header,
#WorkflowScreen .component-step .k-grid .k-grid-header-wrap,
#WorkflowScreen .component-step .k-grid .k-grid-header table,
#WorkflowScreen .component-step .k-grid thead,
#WorkflowScreen .component-step .k-grid thead.k-table-thead,
#WorkflowScreen .component-step .k-grid .k-grid-header tr {
    background-color: var(--accent-1);
}

#WorkflowScreen .component-step .k-grid {
    border: none;
    /* Stated even though the width is 0: `border: none` leaves border-color at
       currentColor, and half a dozen Telerik grid elements take border-color: inherit. */
    border-color: var(--accent-4);
    font-size: 12px;
    color: var(--font-color-2);
}

    #WorkflowScreen .component-step .k-grid .k-grid-header {
        border-bottom: 1px solid var(--accent-4);
    }

/* Both Telerik class generations, as §9 does - the one rendered depends on the control. */
#WorkflowScreen .component-step .k-grid th,
#WorkflowScreen .component-step .k-grid .k-table-th,
#WorkflowScreen .component-step .k-grid .k-header {
    padding: .25rem .4rem;
    border-left: none;
    border-right: none;
    border-bottom: 1px solid var(--accent-4);
    background-color: transparent;
    font-size: 11px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: .04em;
    white-space: nowrap;
    color: var(--font-color-muted);
}

    /* Telerik wraps the caption in a span of its own, and the ink block at the end of this
       file matches that span directly - `thead.k-table-thead .k-column-title` - so the
       cell's colour above never reaches it. That ink is --header-bar-ink, correct on the
       filled grid headers everywhere else and white on white on this unfilled one. */
    #WorkflowScreen .component-step .k-grid .k-column-title,
    #WorkflowScreen .component-step .k-grid .k-grid-header .k-link,
    #WorkflowScreen .component-step .k-grid .k-grid-header .k-cell-inner {
        color: var(--font-color-muted);
    }

#WorkflowScreen .component-step .k-grid td,
#WorkflowScreen .component-step .k-grid .k-table-td {
    padding: .25rem .4rem;
    border-left: none;
    border-right: none;
    border-bottom: 1px solid var(--hairline);
}

#WorkflowScreen .component-step .k-grid tr:hover td,
#WorkflowScreen .component-step .k-grid .k-table-row:hover .k-table-td {
    background-color: var(--row-hover);
}

/* The one rule that reaches inside a step body, and it earns the exception: without it
   a single wide table - CreditReportReviewStepUI, LoanTermsStepUI - widens the whole
   screen and breaks the layout of every well-behaved step above it. Scoped to the grid
   wrapper rather than edited into 26 files. */
#WorkflowScreen .component-step .k-grid-container,
#WorkflowScreen .component-step .k-grid-content,
#WorkflowScreen .component-step .k-grid > .k-grid-aria-root {
    overflow-x: auto;
}

/* ---- the workflow's bottom bar ----
   It sits inside the steps column rather than spanning the full width, because
   Workflow.razor renders it inside the component that owns the step list. Hoisting it
   to a grid region of its own would mean moving the workflow controller out of that
   component, which is a behaviour change and not a styling one. */
#WorkflowScreen .workflow-bottom {
    background-color: var(--page-ground);
    border-top: 1px solid var(--hairline);
    padding: .5rem .55rem;
}

/* ---- the notes column ---- */
#WorkflowScreen .workflow-notes .component {
    border-radius: 4px;
    border: 1px solid var(--accent-4);
    box-shadow: var(--panel-shadow);
    background-color: var(--accent-1);
    overflow: hidden;
}

#WorkflowScreen .workflow-notes .component-header {
    background-color: var(--header-bar);
    color: var(--font-color-1);
    border-bottom: none;
    border-radius: 4px 4px 0 0;
    font-size: 11px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: .06em;
    min-height: var(--wf-bar-h, 29px);
    padding: .25rem .5rem;
}

#WorkflowScreen .workflow-notes .p-2 {
    padding: .4rem .45rem !important;
}

/* ---- the section switch ----
   A segmented control, not a TelerikTabStrip and not §9's tab-strip treatment. Embedded
   in the customer page this sits under #VergentCustomerTabs' thirteen underlined tabs,
   and a second underlined strip directly beneath reads as one confused navigation - on
   the phone, where it hurts most. §8 already gives the vocabulary that separates a
   control from a label: pill metrics plus a fill, a hover border and a focus ring.

   Hidden by default in WorkflowContainer.razor.css and revealed by the stages below, so
   a wide-screen user can never land in a one-pane state (§7). */
#WorkflowScreen .wf-switch {
    align-items: center;
    flex-wrap: nowrap;
    gap: .25rem;
    padding: .35rem .5rem;
    background-color: var(--accent-1);
    border-bottom: 1px solid var(--hairline);
}

#WorkflowScreen .wf-switch-tab {
    display: inline-flex;
    align-items: center;
    gap: .3rem;
    min-height: 24px;
    padding: .15rem .6rem;
    border: 1px solid var(--accent-4);
    border-radius: 10px;
    background-color: var(--accent-1);
    color: var(--font-color-muted);
    font: inherit;
    font-size: 11.5px;
    font-weight: 600;
    line-height: 1.4;
    white-space: nowrap;
    cursor: pointer;
}

    #WorkflowScreen .wf-switch-tab:hover {
        background-color: var(--tint-bg);
        border-color: #b9c6d4;
    }

    #WorkflowScreen .wf-switch-tab:focus-visible {
        outline: 2px solid var(--affordance-color);
        outline-offset: 1px;
    }

    /* The selected tab is filled, not tinted: it is the only thing on the strip that
       has to be unmistakable at a glance on a phone, and a tint reads as a hover state
       next to two white siblings. --header-bar rather than --color-1 because it holds
       white text (§2). */
    #WorkflowScreen .wf-switch-tab.is-active {
        background-color: var(--header-bar);
        border-color: var(--header-bar);
        color: var(--font-color-1);
    }

/* Only Steps carries a count, and it is a position rather than a total - where am I,
   which is the one thing the rail cannot say once it is reduced to chips. A count on
   Actions would tally buttons, and a notes count is unavailable until the pane has been
   opened, by which point it is no longer needed. */
#WorkflowScreen .wf-switch-label {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
}

#WorkflowScreen .wf-switch-count {
    flex: none;
    font-size: 10px;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    opacity: .78;
}

@container wfscreen (max-width: 1100px) {
    #WorkflowScreen .workflow-container {
        grid-template-columns: auto 1fr;
        grid-template-areas:
            "bar  bar"
            "rail tabs"
            "rail main";
    }

    /* The rail belongs to the Steps pane. With any other section active there is one
       column and no rail. */
    #WorkflowScreen .workflow-container:not([data-section="steps"]) {
        grid-template-columns: 1fr;
        grid-template-areas:
            "bar"
            "tabs"
            "main";
    }

    #WorkflowScreen .wf-switch {
        display: flex;
    }

    /* The column stops being a column and dissolves into the grid, so the switch can
       place its two panes where the steps are rather than below them. */
    #WorkflowScreen .workflow-container .workflow-notes {
        display: contents;
    }

    #WorkflowScreen .workflow,
    #WorkflowScreen .workflow-pane {
        grid-area: main;
    }

    /* Each pane now sits on the ground in its own right, where the notes column used
       to carry it for both of them. */
    #WorkflowScreen .workflow-pane {
        background-color: var(--page-ground);
        padding: .5rem;
    }

    #WorkflowScreen .workflow-container[data-section="steps"] .workflow-pane {
        display: none;
    }

    #WorkflowScreen .workflow-container[data-section="actions"] .workflow,
    #WorkflowScreen .workflow-container[data-section="actions"] > .workflow-index,
    #WorkflowScreen .workflow-container[data-section="actions"] .workflow-pane[data-pane="notes"] {
        display: none;
    }

    #WorkflowScreen .workflow-container[data-section="notes"] .workflow,
    #WorkflowScreen .workflow-container[data-section="notes"] > .workflow-index,
    #WorkflowScreen .workflow-container[data-section="notes"] .workflow-pane[data-pane="actions"] {
        display: none;
    }

    /* Inside a pane, the tab is the heading: a bar reading WORKFLOW ACTIONS directly
       under a selected tab reading Actions is a heading that names its own control.

       Only the Actions pane still needs this. The notes pane lost the panel it used to
       carry - NoteListComp renders its cards straight into the pane now - so there is no
       longer a NOTES bar here to hide, and no borrowed top padding to give back. */
    #WorkflowScreen .wf-pane-heading {
        display: none;
    }

        #WorkflowScreen .wf-pane-heading + * {
            padding-top: .5rem;
        }
}

/* ---- stage 2: tablet portrait ----
   A 186px rail beside a step body no longer leaves either one a usable column, so the
   rail leaves the side and becomes a horizontal strip - same buttons, same marks, same
   selected state, scrolled sideways instead of read down. It still belongs to the Steps
   pane and still hides with it. */
@container wfscreen (max-width: 780px) {
    /* Both selectors restated. Stage 1's :not() rule is (1,2,0) and a plain rule here
       would be (1,1,0), so without this a non-Steps pane would keep stage 1's
       two-column shape. */
    #WorkflowScreen .workflow-container,
    #WorkflowScreen .workflow-container:not([data-section="steps"]) {
        grid-template-columns: 1fr;
        grid-template-areas:
            "bar"
            "tabs"
            "rail"
            "main";
    }

    /* Bar and switch pin as one unit, so any section is one tap away from anywhere in
       a long workflow - which is the whole point of the switch existing. --wf-bar-h and
       not a literal 29px, so the offset follows the bar when a coarse pointer grows it. */
    #WorkflowScreen .component-container-header {
        position: sticky;
        top: 0;
        z-index: 4;
    }

    #WorkflowScreen .wf-switch {
        position: sticky;
        top: var(--wf-bar-h, 29px);
        z-index: 3;
    }

    #WorkflowScreen .workflow-container > .workflow-index {
        max-width: none;
        border-right: 0;
        border-bottom: 1px solid var(--hairline);
        padding: .35rem .5rem;
    }

    #WorkflowScreen .workflow-index {
        position: static;
        display: flex;
        gap: .25rem;
        overflow-x: auto;
        scrollbar-width: thin;
        padding: 0 0 2px;
    }

    #WorkflowScreen .workflow-index li {
        flex: 0 0 auto;
        padding: 0;
    }

    /* The three tabs share the width from here down rather than running off the right
       edge. They are the only navigation on screen at this width, so they get all of it. */
    #WorkflowScreen .wf-switch-tab {
        flex: 1 1 0;
        justify-content: center;
        min-width: 0;
    }

    /* A strip item marks selection with an inset edge rather than a fill - a run of
       filled chips beside the switch reads as a second segmented control. */
    #WorkflowScreen .workflow-index-item {
        max-width: 190px;
    }

        #WorkflowScreen .workflow-index-item.is-current {
            background-color: transparent;
            box-shadow: inset 0 -2px 0 var(--affordance-color);
        }

    /* Children of a step flatten into the strip rather than indenting off it. */
    #WorkflowScreen .workflow-index-children {
        display: flex;
        gap: .25rem;
        padding-left: .25rem;
    }
}

/* ---- stage 3: phone ----
   A step name alone fills a line, so the strip drops to numbered chips and the progress
   count rides in the Steps tab label rather than taking a row of its own. */
@container wfscreen (max-width: 480px) {
    #WorkflowScreen .wf-switch {
        padding: .35rem;
    }

    #WorkflowScreen .wf-switch-tab {
        flex: 1 1 0;
        justify-content: center;
        min-width: 0;
        padding: .15rem .35rem;
    }

    #WorkflowScreen .wf-switch-label {
        overflow: hidden;
        text-overflow: ellipsis;
    }

    /* SortOrder is real ordering information - it already drives the list - so the chip
       says which step it is rather than being an anonymous dot. */
    #WorkflowScreen .workflow-index-item-number {
        display: inline-block;
        font-size: 11px;
        font-weight: 600;
        font-variant-numeric: tabular-nums;
    }

    #WorkflowScreen .workflow-index-item-text {
        display: none;
    }

    #WorkflowScreen .workflow-index-item {
        max-width: none;
        min-width: 34px;
        justify-content: center;
        border: 1px solid var(--hairline);
        border-radius: 4px;
        padding: .25rem .4rem;
    }

        #WorkflowScreen .workflow-index-item.is-current {
            border-color: var(--affordance-color);
            box-shadow: none;
        }

    #WorkflowScreen .workflow-container .workflow {
        padding: .4rem .35rem;
    }

    #WorkflowScreen .workflow-pane {
        padding: .35rem;
    }

    #WorkflowScreen .component-step .header.component-header {
        padding: .35rem .45rem;
    }

    #WorkflowScreen .component-step .k-card-body {
        padding: .45rem;
    }

    #WorkflowScreen .component-step .k-card-footer {
        padding-left: .45rem;
        padding-right: .45rem;
    }

    /* Label over control rather than beside it, and the control takes the width. */
    #WorkflowScreen .k-input,
    #WorkflowScreen .k-picker,
    #WorkflowScreen .k-textarea {
        min-width: 0;
        width: 100%;
    }

    #WorkflowScreen .wf-step-skip {
        flex-wrap: wrap;
        gap: .2rem;
    }

    #WorkflowScreen .k-dropzone,
    #WorkflowScreen .k-upload-dropzone {
        flex-direction: column;
        align-items: stretch;
        gap: .25rem;
        text-align: center;
    }

    /* Finish and Save stay reachable without scrolling to the end of a five-step
       workflow. */
    #WorkflowScreen .workflow-bottom {
        position: sticky;
        bottom: 0;
        z-index: 3;
        border-top: 1px solid var(--accent-4);
        box-shadow: 0 -2px 6px rgba(22, 34, 47, .10);
        padding: .45rem .35rem;
    }

        #WorkflowScreen .workflow-bottom .k-button {
            flex: 1 1 0;
        }
}

/* ---- the coarse-pointer rule ----
   Keyed on the input device and not on width, so a mouse in a small window keeps the
   dense targets and a touchscreen laptop gets the big ones. This does not conflict with
   §7's "no @media for content-width decisions": pointer type is not a width.

   Type size and spacing are deliberately untouched. Information density is the contract
   (§1); target size is not. A 40px control here is not a violation of §8's 28px. */
@media (pointer: coarse) {
    #WorkflowScreen .workflow-container {
        --wf-bar-h: 44px;
    }

    #WorkflowScreen .component-container-header {
        min-height: 44px;
    }

    #WorkflowScreen .component-step .header.component-header {
        min-height: 40px;
        padding: .4rem .55rem;
    }

    #WorkflowScreen .component-step .header.component-header button.header-button,
    #WorkflowScreen .component-step .header.component-header .k-button.header-button,
    #WorkflowScreen > .workflow-container > .component-container-header button.header-button,
    #WorkflowScreen > .workflow-container > .component-container-header .k-button.header-button {
        width: 36px;
        height: 36px;
    }

    #WorkflowScreen .workflow-index-item {
        min-height: 40px;
        padding: .45rem .5rem;
    }

    #WorkflowScreen .wf-switch-tab {
        min-height: 36px;
        border-radius: 18px;
        padding: .15rem .8rem;
    }

    #WorkflowScreen .component-step .k-button,
    #WorkflowScreen .workflow-bottom .k-button {
        height: 40px;
        min-height: 40px;
        padding: 0 1rem;
        font-size: 13px;
    }

    #WorkflowScreen .k-dropzone .k-button,
    #WorkflowScreen .k-upload-dropzone .k-button,
    #WorkflowScreen .k-upload-button {
        height: 36px;
        min-height: 36px;
        font-size: 12px;
    }

    #WorkflowScreen .k-input,
    #WorkflowScreen .k-picker {
        min-height: 40px;
    }

    #WorkflowScreen .component-step .k-textarea .k-input-inner {
        min-height: 72px;
    }

    #WorkflowScreen .component-step .k-grid td,
    #WorkflowScreen .component-step .k-grid .k-table-td {
        padding: .5rem .4rem;
    }

    /* 16px, because below it iOS Safari zooms the page on focus and the teller has to
       pinch back out after every field. The same fix the customer portal's FormField
       primitive already carries. */
    #WorkflowScreen .k-input-inner,
    #WorkflowScreen .k-textarea .k-input-inner,
    #WorkflowScreen textarea,
    #WorkflowScreen input[type="text"] {
        font-size: 16px;
    }
}

/* The collapse chevron honours the reduced-motion preference. Placed after every rule
   that sets the transition, or this loses the specificity tie and fails silently for
   exactly the people who asked for it. */
@media (prefers-reduced-motion: reduce) {
    #WorkflowScreen .component-step .collapse-button .k-icon,
    #WorkflowScreen .component-step .collapse-button .k-font-icon,
    #WorkflowScreen .component-step .collapse-button .k-button-icon {
        transition: none;
    }
}

/* hide built-in tab containers when flagged as empty */
.empty-tabstrip .k-tabstrip-content {
    display: none !important;
}

/* ============================================================================
   LOGIN PAGE  (#LoginPage, Pages/Login.razor)

   A synthesis of three things: the panel language of the customer and home
   boards (white card, --header-bar title bar, hairlines, muted 11px labels),
   the shape of the classic aspx logon page (centred logo over one narrow card
   on a navy ground, generous padding, one full-width action), and this app's
   token vocabulary throughout.

   Two deliberate departures from the rest of the app, both because this screen
   is the opposite of the boards the contract was written for — it is seen once
   a shift, holds two fields, and is the first thing a new user meets:

   1. Controls are 36px, not §8's 28px. Density buys scan speed on a screen
      someone works all day; there is nothing here to scan.
   2. It carries a filled primary button, which §15 otherwise reserves for the
      search page. The rationale there is that a form with one submit and one
      discard needs a primary; this is a form with one submit and nothing else,
      so the same argument applies more strongly, not less.

   The fill is a literal green rather than --color-1: the button carries white text
   and so owes a contrast guarantee, which §2 says --color-1 cannot give. In
   practice no company theme has loaded this early, but this is the one button a
   locked-out user has to be able to see. The green itself is inherited from the
   classic logon page, which is the button operators already know on this screen.
   ============================================================================ */

/* Fixed to the viewport rather than laid out in the page. EmptyLayout wraps @Body in
   `.content.px-4`, so an in-flow login page stops 24px short of each edge and the body's
   --color-3 shows through as a frame against the gradient's lightest part. Taking the page
   out of flow sidesteps the ancestor's padding without altering a shared layout. */
#LoginPage {
    position: fixed;
    inset: 0;
    /* The form must stay reachable when the on-screen keyboard leaves less room than the
       card needs. */
    overflow-y: auto;
    display: flex;
    flex-direction: column;
    align-items: center;
    /* Top-aligned, not centred, to match the classic page's `.login-logo { padding: 8% 0
       0 }`. 4% rather than 8% because this screen carries a language row and a footer line
       the old one did not. The percentage idiom is kept — padding resolves against the
       containing block's WIDTH, so the gap scales with the window instead of stranding a
       fixed rem gap on a large monitor. */
    justify-content: flex-start;
    padding: 4% 1rem 2rem;
    box-sizing: border-box;
    /* The app's own navy pair, standing in for the classic page's #2c4d84 →
       #1B3251 gradient — same effect, no new hexes. */
    background: linear-gradient(to left, var(--color-2), var(--color-3));
}

/* Close the gap above the logo on a phone or on any short viewport. The 4% above is a
   fraction of the WIDTH, so it knows nothing about how much height is left: a short, wide
   window gets the largest offset exactly when it has the least room, and the fields drop
   past the fold — or out from under the caret once an on-screen keyboard takes half the
   viewport. A 1400x600 window would otherwise spend 56px of its 600 on empty ground.

   §15 bans @media for CONTENT-WIDTH decisions because the left nav is `fit-content`. This
   screen has no nav — it is fixed to the viewport — so here the two are the same
   measurement, and the height half of this query is outside that rule entirely. */
@media (max-width: 640px), (max-height: 720px) {
    #LoginPage {
        padding: 1.5rem 1rem 2rem;
    }
}

/* Wider than the card below it, deliberately: the mark is the first thing on the screen
   and carries no detail that needs reading, so it can overhang the panel that does. */
#LoginPage .login-brand {
    width: 100%;
    max-width: 460px;
    margin-bottom: 2rem;
    text-align: center;
}

    #LoginPage .login-brand img {
        display: block;
        width: 100%;
        /* 423, not the 460 the png's box was given: the png padded itself, its mark only
           423x98 inside a 460x130 frame, while this svg is cropped to the ink. Sizing the
           svg's box to the png's MARK is what holds the logo the size it has been. */
        max-width: 423px;
        height: auto;
        margin-left: auto;
        margin-right: auto;
    }

/* 360px card, 16px gutter each side — the classic page's measurements. */
#LoginPage .login-card {
    width: 100%;
    max-width: 360px;
    background-color: var(--accent-1);
    border: 1px solid var(--accent-4);
    border-radius: 4px;
    overflow: hidden;
    box-shadow: 0 1px 2px rgba(22, 34, 47, .06), 0 8px 24px rgba(0, 0, 0, .28);
}

/* The card carries no title bar: it is the only thing on the screen, and a bar reading
   SIGN IN over a button reading Sign In is a heading that names its own control. The
   choice dialog below carries none either, for the same reason. Its `Title` is still set
   and hidden, so it keeps an accessible name. */
#LoginPage .login-card-body {
    padding: 1.5rem;
}

#LoginPage .login-field {
    margin-bottom: .85rem;
}

/* Same treatment as the search panel's field labels. */
#LoginPage .login-label {
    display: block;
    margin: 0 0 3px 0;
    font-size: 11px;
    font-weight: normal;
    line-height: 1.3;
    color: var(--font-color-muted);
}

/* Telerik renders its own inner input, so the height goes on the wrapper and the focus
   ring keys on :focus-within — §8.

   The grey fill is the classic logon page's idea: on a white card a white field is drawn
   only by its hairline, where a filled well reads as somewhere to type. The literal has
   no token because it is the only sunken control surface in the app. */
#LoginPage .k-input,
#LoginPage .k-picker {
    width: 100%;
    height: 36px;
    min-height: 36px;
    border: 1px solid var(--accent-4);
    border-radius: 4px;
    background-color: #efefef;
    background-image: none;
    box-shadow: none;
    color: var(--font-color-2);
    /* 14 rather than 13: at 13px Segoe UI's password bullet is almost entirely
       antialiasing fringe - see the mask note below. The username and the pickers take the
       bump too, which is what keeps the form one size; the labels stay at 13px above. */
    font-size: 14px;
}

    /* Telerik's inner <input> carries its own white in the stock theme, which would sit as a
       white bar inside the well above. */
    #LoginPage .k-input .k-input-inner,
    #LoginPage .k-picker .k-input-inner {
        background-color: transparent;
    }

    #LoginPage .k-input:focus-within,
    #LoginPage .k-picker:focus-within {
        outline: 2px solid var(--color-1);
        outline-offset: -2px;
        border-color: var(--color-1);
    }

    /* Chrome on Windows draws this field with LCD subpixel antialiasing, and a bullet at
       13px is a 4px blob on a fractional advance, so consecutive dots land on different
       subpixel phases and each takes a different orange/blue fringe - coloured speckle
       rather than dots. Three things pull the same way: 14px gives the disc a solid core,
       the tracking separates the dots, and the layer promotion is what actually removes
       the colour - Chrome drops LCD text on a composited layer that is not known-opaque,
       and this input is transparent, so will-change alone gets grayscale dots.

       Scoped to the mask on purpose (Class lands on the wrapper, so login-password in
       Login.razor is the hook), because the username beside it has real text to read and
       keeps the sharper subpixel rendering. */
    #LoginPage .k-input.login-password .k-input-inner {
        letter-spacing: 2px;
        will-change: transform;
    }

#LoginPage .login-actions {
    margin-top: 1.15rem;
}

/* The one green in the app, deliberately: it is the classic logon page's green button. A
   literal rather than a token because it must not follow a company theme — see the note at
   the top of this section about the one button a locked-out user has to be able to see.
   White on #1c7b23 is 5.38:1 and the hover 7.51:1, so that guarantee is met. */
#LoginPage .k-button.login-submit {
    width: 100%;
    height: 38px;
    min-height: 38px;
    padding: 0 .75rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border: 1px solid #1c7b23;
    border-radius: 4px;
    background-color: #1c7b23;
    background-image: none;
    box-shadow: none;
    color: #ffffff;
    font-size: 13px;
    font-weight: 600;
    letter-spacing: .02em;
}

    #LoginPage .k-button.login-submit .k-button-text {
        color: #ffffff !important;
    }

    #LoginPage .k-button.login-submit:hover:not([disabled]) {
        background-color: #16621c;
        border-color: #16621c;
        filter: none;
    }

    #LoginPage .k-button.login-submit[disabled],
    #LoginPage .k-button.login-submit.k-disabled {
        opacity: .6;
    }

/* Errors from the server. A tint rather than a solid fill: the flat language here marks an
   exception, it does not shout. The two literals have no tokens because nothing else in
   the app needs them yet. */
#LoginPage .login-error {
    margin: 0 0 1rem 0;
    padding: .5rem .6rem;
    border: 1px solid #f5c6c0;
    border-radius: 4px;
    background-color: #fdecea;
    color: var(--warning-color);
    font-size: 12px;
    line-height: 1.4;
}

    #LoginPage .login-error p {
        margin: 0;
    }

        #LoginPage .login-error p + p {
            margin-top: .25rem;
        }

/* DataAnnotations messages, under the field they belong to. */
#LoginPage .login-validation {
    display: block;
    margin-top: 2px;
    color: var(--warning-color);
    font-size: 11px;
    line-height: 1.3;
}

#LoginPage .login-foot {
    margin-top: 1.15rem;
    padding-top: .85rem;
    border-top: 1px solid var(--hairline);
}

    /* Same filled well as the fields above it — it is the one other control on the card. */
    #LoginPage .login-foot select {
        width: 100%;
        height: 32px;
        padding: 0 .4rem;
        border: 1px solid var(--accent-4);
        border-radius: 4px;
        background-color: #efefef;
        color: var(--font-color-2);
        font-size: 12px;
    }

#LoginPage .login-powered {
    margin-top: 1.25rem;
    color: #eaeaea;
    font-size: 11px;
    font-style: italic;
    text-align: center;
}

/* The company / store / district prompt. Telerik portals its dialogs into
   TelerikRootComponent, which lives in the layout — OUTSIDE #LoginPage — so an ID-scoped
   rule cannot reach it. Hence a distinctly named class instead of the usual scoping (§3). */

/* Set here rather than as the component's Width parameter, which would land inline and
   beat the app-wide `width: 100%` that full-screens dialogs on a phone. */
.login-choice-dialog {
    width: 22rem;
    max-width: 100%;
}

/* The app makes every dialog full-screen below 40rem. Full width is right here; full
   HEIGHT is not — the prompt is one line, a picker and a button, and stretching that over
   a phone screen leaves the control floating with the action pinned far from it. Height
   goes back to content and the wrapper (already flex/centred) centres it. Radius stays at
   the app's 0 so it reads as the same family of modal. */
@media (max-width: 40rem) {
    .k-dialog-wrapper > .k-dialog.login-choice-dialog {
        height: auto;
        max-height: calc(100dvh - 2rem);
    }
}

/* Telerik's list items ship with `padding: 6px 0` — no horizontal padding — while the
   closed picker's own text is inset 8px. Matching that 8px lines the selected value up
   with the list it came from. Scoped to this popup: the bare metric is shared with every
   dropdown in the app. */
.login-choice-popup .k-list-item {
    padding-left: 8px;
    padding-right: 8px;
}

/* No title bar: it would read SIGN IN over a prompt that already says what to pick.

   Hidden rather than dropping the `Title` parameter, because Telerik points the dialog's
   aria-labelledby at the title element and a referenced element still contributes its text
   while display: none. Dropping Title would leave the dialog unnamed AND the bar empty,
   since it renders either way. */
.login-choice-dialog .k-window-titlebar,
.login-choice-dialog .k-dialog-titlebar {
    display: none;
}

/* The app gives the top radius to the titlebar and the bottom to the content, so with the bar
   gone the body squares off inside a 4px frame. It owns all four corners here. Below 40rem the
   dialog radius is 0 anyway, so this is not repeated there. */
.login-choice-dialog .k-dialog-content {
    border-top-left-radius: 4px;
    border-top-right-radius: 4px;
}

.login-choice-dialog .login-choice-body {
    padding: 1.25rem;
}

.login-choice-dialog .login-choice-prompt {
    display: block;
    margin-bottom: .6rem;
    color: var(--font-color-2);
    font-size: 12px;
}

/* Same filled well and same green action as the card behind it. This dialog is a step in
   the sign in, not a separate screen, so a white picker and a navy button here would read
   as belonging to some other part of the app. */
.login-choice-dialog .k-input,
.login-choice-dialog .k-picker {
    width: 100%;
    height: 36px;
    min-height: 36px;
    border: 1px solid var(--accent-4);
    border-radius: 4px;
    background-color: #efefef;
    font-size: 13px;
}

    .login-choice-dialog .k-input .k-input-inner,
    .login-choice-dialog .k-picker .k-input-inner {
        background-color: transparent;
    }

.login-choice-dialog .k-button.login-submit {
    width: 100%;
    height: 38px;
    min-height: 38px;
    margin-top: .85rem;
    border: 1px solid #1c7b23;
    border-radius: 4px;
    background-color: #1c7b23;
    background-image: none;
    color: #ffffff;
    font-size: 13px;
    font-weight: 600;
}

    .login-choice-dialog .k-button.login-submit .k-button-text {
        color: #ffffff !important;
    }

    .login-choice-dialog .k-button.login-submit:hover:not([disabled]) {
        background-color: #16621c;
        border-color: #16621c;
        filter: none;
    }

/* ============================================================================
   HEADING BAR INK  (--header-bar-ink)
   ----------------------------------------------------------------------------
   One place that states the ink for every surface filled with --header-bar.
   Sixteen rules in this file paint that ground, and one left on a literal `white`
   is a heading label that vanishes when a company saves a pale colour on
   /setup/theme. Defaults to #ffffff, so nothing changes for a company that has
   saved none. ID-scoped selectors are repeated to tie them on specificity and win
   on order. The #HomeScreenComponents and #CustomerSearchPage grid headers are
   deliberately absent - those are unfilled and draw --font-color-2 by design.
   ============================================================================ */

.component-container-title,
.component-container-title a,
.component-title,
.component-title a,
.component-title-details,
.k-dialog-titlebar,
.k-window-titlebar,
.k-grid .k-grid-header .k-header,
.k-grid .k-grid-header .k-column-title,
thead.k-table-thead .k-column-title,
#ReportsPage .component-title,
#WorkflowQueue .component-title,
#WorkflowQueueFilters .component-title,
#HomeScreenComponents .hs-panel-title,
#CustomerComponents .component-title,
#CustomerComponents .component-header:not(.header-light),
#CustomerSearchPage .component-container-title,
.details-dialog .k-dialog-content .component-title {
    color: var(--header-bar-ink);
}

/* Icons in a bar are ink too - a white close X on a pale title bar is the same
   bug as a white label. */
#CustomerComponents .component-title .header-buttons .k-icon,
#CustomerComponents .component-title .header-buttons .k-svg-icon,
#CustomerComponents .component-title .header-buttons .k-button-icon,
.k-window-titlebar .k-button-icon {
    color: var(--header-bar-ink);
}

/* Answers the existing `.k-dialog-titlebar-action { color: white !important }`
   above rather than adding a new escalation. */
.k-dialog-titlebar-action {
    color: var(--header-bar-ink) !important;
}

/* ============================================================================
   THEME PAGE  (#ThemePage, Pages/Setup/Theme.razor)
   ----------------------------------------------------------------------------
   Where a company sets the four themed colour tokens. Two stacked panels: the
   pickers, and a miniature of the customer page that repaints as they change.

   The miniature's colours arrive as inline custom properties on .tp-preview
   (--tp-1 … --tp-bar-ink, from PreviewStyle), never as writes to :root - so an
   admin can drag through a dozen colours and the app around them stays on the
   company's stored theme until Save. That is also why the miniature is hand-built
   markup: a real panel reads --header-bar from :root and would not follow.

     --tp-1  -> the link and the search box border   (--color-1)
     --tp-2  -> the nav rail and the filled button   (--color-2)
     --tp-3  -> the ground the board sits on         (--color-3)
     --tp-bar / --tp-bar-ink -> card headings and the grid heading row

   The panel, intro, row and footer rules below also name #NotificationSetupPage
   and #NotificationSettingsPage (Pages/Notification/CompanySetup.razor and
   Settings.razor), which are built on the same grammar - a change to one of
   those rules restyles all three pages.
   ============================================================================ */

/* Container and layout must be two elements: a container cannot be queried
   against itself, so with container-type and the grid on one div the
   @container rule silently never applies. */
#ThemePage {
    container-type: inline-size;
    container-name: themepage;
}

/* One panel per row, each full width. Side by side put the miniature at half
   width at exactly the moment its whole job is to be looked at. */
#ThemePage .tp-columns {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    align-items: start;
}

/* The base .component is white text on --accent-3, the pre-contract shape. */
#ThemePage .component,
#NotificationSetupPage .component,
#NotificationSettingsPage .component {
    background-color: var(--accent-1);
    border: 1px solid var(--accent-4);
    border-radius: 4px;
    box-shadow: var(--panel-shadow);
    color: var(--font-color-2);
    overflow: hidden;
}

#ThemePage .component-title,
#NotificationSetupPage .component-title,
#NotificationSettingsPage .component-title {
    display: flex;
    align-items: center;
    gap: 8px;
    border-bottom: none;
    border-radius: 4px 4px 0 0;
    font-size: 11px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: .06em;
    line-height: 1.2;
    min-height: 29px;
    margin: 0;
    padding: .25rem .5rem;
}

    #ThemePage .component-title > label,
    #NotificationSetupPage .component-title > label,
    #NotificationSettingsPage .component-title > label {
        margin: 0;
    }

/* Bootstrap's 8px !important on the wrapper; the rows own their spacing. */
#ThemePage .component > .p-2,
#NotificationSetupPage .component > .p-2,
#NotificationSettingsPage .component > .p-2 {
    padding: 0 !important;
}

#ThemePage .tp-intro,
#NotificationSetupPage .tp-intro,
#NotificationSettingsPage .tp-intro {
    margin: 0;
    padding: .4rem .55rem;
    border-bottom: 1px solid var(--hairline);
    font-size: 11.5px;
    color: var(--font-color-muted);
}

/* ---- the picker rows ---- */

#ThemePage .tp-row,
#NotificationSetupPage .tp-row,
#NotificationSettingsPage .tp-row {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: center;
    gap: .5rem;
    padding: .4rem .55rem;
}

    #ThemePage .tp-row + .tp-row,
    #NotificationSetupPage .tp-row + .tp-row,
    #NotificationSettingsPage .tp-row + .tp-row {
        border-top: 1px solid var(--hairline);
    }

    #ThemePage .tp-row:hover,
    #NotificationSetupPage .tp-row:hover,
    #NotificationSettingsPage .tp-row:hover {
        background-color: var(--row-hover);
    }

#ThemePage .tp-row-text,
#NotificationSetupPage .tp-row-text,
#NotificationSettingsPage .tp-row-text {
    display: flex;
    flex-direction: column;
    gap: 1px;
    min-width: 0;
}

#ThemePage .tp-row-label,
#NotificationSetupPage .tp-row-label,
#NotificationSettingsPage .tp-row-label {
    font-size: 12px;
    font-weight: 600;
    color: var(--font-color-2);
}

#ThemePage .tp-row-help,
#NotificationSetupPage .tp-row-help,
#NotificationSettingsPage .tp-row-help {
    font-size: 11px;
    color: var(--font-color-muted);
}

/* Tabular figures so the ratio does not jitter as the picker is dragged. */
#ThemePage .tp-contrast {
    font-size: 11px;
    color: var(--font-color-muted);
    font-variant-numeric: tabular-nums;
}

    #ThemePage .tp-contrast.is-low {
        color: var(--warning-color);
        font-weight: 600;
    }

#ThemePage .tp-contrast-warning {
    font-size: 11px;
    color: var(--warning-color);
}

#ThemePage .tp-row-control,
#NotificationSetupPage .tp-row-control,
#NotificationSettingsPage .tp-row-control {
    display: flex;
    justify-content: flex-end;
}

/* The 28px control metric. The picker comes out of the theme at 24px on
   --accent-3 with a gradient, which reads as a different generation of control
   from every other field. Swatch sizing is global - see .k-colorpicker. */
#ThemePage .tp-row-control .k-colorpicker {
    height: 28px;
    border-radius: 4px;
    border-color: var(--accent-4);
    background-color: var(--accent-1);
    background-image: none;
}

    #ThemePage .tp-row-control .k-colorpicker:focus-within {
        outline: 2px solid var(--affordance-color);
        outline-offset: -1px;
    }

/* Neither button is a filled primary: the app keeps two of those (Search and
   Login), and a settings form with Save and Reset is not one. Save takes the
   affordance colour so the pair still has an order. */
#ThemePage .cust-comp-btn-container,
#NotificationSetupPage .cust-comp-btn-container,
#NotificationSettingsPage .cust-comp-btn-container {
    display: flex;
    justify-content: flex-end;
    gap: .35rem;
    margin: 0;
    padding: .5rem .55rem;
    border-top: 1px solid var(--hairline);
}

#ThemePage .cust-comp-btn-container .k-button,
#NotificationSetupPage .cust-comp-btn-container .k-button,
#NotificationSettingsPage .cust-comp-btn-container .k-button {
    height: 28px;
    min-height: 28px;
    padding: 0 .6rem;
    border: 1px solid var(--accent-4);
    border-radius: 4px;
    background-color: var(--accent-1);
    background-image: none;
    box-shadow: none;
    font-size: 12px;
    font-weight: 500;
    color: var(--font-color-2);
}

    #ThemePage .cust-comp-btn-container .k-button .k-button-text,
    #NotificationSetupPage .cust-comp-btn-container .k-button .k-button-text,
    #NotificationSettingsPage .cust-comp-btn-container .k-button .k-button-text {
        height: 28px;
        line-height: 28px;
        background-color: transparent;
        color: inherit;
    }

    #ThemePage .cust-comp-btn-container .k-button:hover,
    #NotificationSetupPage .cust-comp-btn-container .k-button:hover,
    #NotificationSettingsPage .cust-comp-btn-container .k-button:hover {
        background-color: var(--tint-bg);
        border-color: var(--tint-border);
    }

    #ThemePage .cust-comp-btn-container .tp-save,
    #NotificationSetupPage .cust-comp-btn-container .tp-save,
    #NotificationSettingsPage .cust-comp-btn-container .tp-save,
    #ThemePage .cust-comp-btn-container .tp-save .k-button-text,
    #NotificationSetupPage .cust-comp-btn-container .tp-save .k-button-text,
    #NotificationSettingsPage .cust-comp-btn-container .tp-save .k-button-text {
        color: var(--affordance-color);
        font-weight: 600;
    }

/* ==== Notification pages ====
   #NotificationSetupPage  (company, Pages/Notification/CompanySetup.razor)
   #NotificationSettingsPage (per user, Pages/Notification/Settings.razor)
   Both share #ThemePage's panel, intro, row and footer rules outright (each of those selectors
   above names all three pages), so the setup screens can't drift apart. Only what the theme
   page has no equivalent for lives here: the column heading over the type rows, the
   three-checkbox control cluster and the closing hint (both pages), plus the master-off
   dimming and sub-type filter (company page only). */

/* Fixed-width checkbox columns, shared by the heading and every row's control so the
   heading labels sit over their checkboxes. */
#NotificationSetupPage .ns-checks,
#NotificationSettingsPage .ns-checks {
    display: grid;
    grid-template-columns: repeat(3, 6.5rem);
    justify-items: center;
    align-items: center;
}

#NotificationSetupPage .ns-head,
#NotificationSettingsPage .ns-head {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: center;
    gap: .5rem;
    padding: .3rem .55rem;
    border-top: 1px solid var(--hairline);
    border-bottom: 1px solid var(--hairline);
    font-size: 11px;
    font-weight: 600;
    color: var(--font-color-muted);
}

    #NotificationSetupPage .ns-head .ns-checks span,
    #NotificationSettingsPage .ns-head .ns-checks span {
        text-align: center;
    }

/* With the master switch off the type rows are inert; dim the labels to say so. */
#NotificationSetupPage .ns-off .tp-row-label {
    color: var(--font-color-muted);
}

#NotificationSetupPage .ns-subtypes {
    display: flex;
    align-items: center;
    gap: .5rem;
    margin-top: .3rem;
}

    #NotificationSetupPage .ns-subtypes .tp-row-help {
        flex: none;
    }

    #NotificationSetupPage .ns-subtypes .k-multiselect {
        flex: 1 1 auto;
        min-width: 0;
        border-radius: 4px;
        border-color: var(--accent-4);
        background-color: var(--accent-1);
        background-image: none;
    }

/* The intro strip turned upside down: same type, hairline above instead of below. */
#NotificationSetupPage .ns-hint,
#NotificationSettingsPage .ns-hint {
    border-top: 1px solid var(--hairline);
    border-bottom: none;
}

#NotificationSetupPage .ns-saved,
#NotificationSettingsPage .ns-saved {
    align-self: center;
    font-size: 11px;
    color: var(--font-color-muted);
}

/* ---- the mode toggle (Vergent users only; see ShowModeToggle) ---- */

#ThemePage .tp-mode {
    display: flex;
    align-items: center;
    gap: .5rem;
    padding: .4rem .55rem 0;
}

#ThemePage .tp-mode-label {
    font-size: 11px;
    color: var(--font-color-muted);
}

/* The nav's Color Mode switch, borrowed for its geometry (44x22 track, 18px
   thumb, travel, and the two masked glyphs, which are tinted by the track's
   `color` so a palette override retints them) and repainted, because
   .color-mode-switch is drawn for the navy rail - translucent white fills and a
   white icon, invisible on this panel. Palette only; the id outranks the class
   rules, so no !important. */
#ThemePage .color-mode-switch.k-switch-off .k-switch-track {
    background-color: var(--tint-strong);
    box-shadow: inset 0 0 0 1px var(--accent-4);
    color: var(--font-color-2);
}

    #ThemePage .color-mode-switch.k-switch-off:hover .k-switch-track {
        background-color: var(--tint-border);
    }

/* A fixed slate, not a token: the lane means "dark mode is on", which is chrome
   rather than branding, and every candidate token is either themeable (so
   possibly pale under the white moon) or flips with the page's own mode. */
#ThemePage .color-mode-switch.k-switch-on .k-switch-track {
    background-color: #3a4552;
    box-shadow: inset 0 0 0 1px #3a4552;
    color: #ffffff;
}

    #ThemePage .color-mode-switch.k-switch-on:hover .k-switch-track {
        background-color: #2a3441;
    }

#ThemePage .color-mode-switch:focus-visible .k-switch-track,
#ThemePage .color-mode-switch.k-focus .k-switch-track {
    outline: 2px solid var(--affordance-color);
    outline-offset: -2px;
}

/* ---- the miniature ---- */

/* Two miniatures, side by side while there is room for both. auto-fit rather than a
   container query: the pair self-stacks when 22rem each stops fitting, so there is no
   second breakpoint to keep in step with the board's. */
#ThemePage .tp-screens {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(22rem, 1fr));
    /* stretch, not start: the two frames are a comparison, and one standing taller than
       the other beside it reads as a layout accident. The shorter one gains ground,
       which is --color-3 and worth seeing more of anyway. */
    align-items: stretch;
    gap: .55rem;
    padding: .55rem;
}

#ThemePage .tp-screen {
    display: flex;
    flex-direction: column;
    gap: .25rem;
    min-width: 0;
}

    #ThemePage .tp-screen .tp-preview {
        flex: 1 1 auto;
    }

/* Names the screen. Outside .tp-preview, so it is page chrome and follows the page's
   mode rather than the toggle. */
#ThemePage .tp-screen-label {
    font-size: 11px;
    font-weight: 600;
    color: var(--font-color-muted);
    text-transform: uppercase;
    letter-spacing: .06em;
}

#ThemePage .tp-preview {
    display: flex;
    border: 1px solid var(--accent-4);
    border-radius: 4px;
    overflow: hidden;
    background-color: var(--tp-3);
    /* Enough that ground shows around the cards - that empty area is the only
       place --color-3 is visible. */
    min-height: 9rem;

    /* Literals, not var(--accent-1) and friends, and that is the point: the
       preview draws the mode **it** is set to, not the mode the page is in.
       Reading the global tokens made the toggle a no-op in light mode and, on a
       dark page, drew a dark card for the Light setting. These mirror the light
       :root block; .is-dark below mirrors the DARK MODE block. Names match the
       tokens they copy so that stays findable. */
    --tp-surface: #ffffff;
    --tp-edge: lightgray;
    --tp-rule: #e7ecf2;
    --tp-ink: #000000;
    --tp-ink-muted: #6f7d90;
    /* --row-alt, --tint-bg and --tint-border: the home screen's zebra stripe, and the
       fill and border of an "on" product chip. */
    --tp-alt: #e6ecf4;
    --tp-tint: #e9f1f8;
    --tp-tint-border: #c2d9ea;
    --tp-link: var(--tp-1);
}

    /* --tp-link is the one that is not a surface copy: dark mode sets
       --affordance-color: #7fb2ef, deliberately overriding the company theme,
       because a navy chosen against a white app lands ~1.5:1 on #1a2129. A
       preview still painting --tp-1 here would show a colour the app never uses. */
    #ThemePage .tp-preview.is-dark {
        --tp-surface: #1a2129;
        --tp-edge: #3a4552;
        --tp-rule: #2b3540;
        --tp-ink: #e3e8ee;
        --tp-ink-muted: #98a5b5;
        --tp-alt: #1f2833;
        --tp-tint: #223243;
        --tp-tint-border: #35506d;
        --tp-link: #7fb2ef;
    }

#ThemePage .tp-rail {
    flex: none;
    display: flex;
    flex-direction: column;
    gap: .35rem;
    width: 3rem;
    padding: .35rem;
    background-color: var(--tp-2);
}

/* Translucent white rather than tokens: these stand in for the rail's contents,
   whose only job is to show how much of the frame the rail colour occupies. */
#ThemePage .tp-rail-logo {
    height: 1.1rem;
    border-radius: 2px;
    background-color: rgba(255, 255, 255, .3);
}

#ThemePage .tp-rail-item {
    height: .35rem;
    border-radius: 2px;
    background-color: rgba(255, 255, 255, .28);
}

    #ThemePage .tp-rail-item.is-current {
        background-color: rgba(255, 255, 255, .8);
    }

#ThemePage .tp-main {
    display: flex;
    flex-direction: column;
    flex: 1 1 auto;
    min-width: 0;
}

#ThemePage .tp-topbar {
    flex: none;
    display: flex;
    align-items: center;
    padding: .25rem .3rem;
    background-color: var(--tp-surface);
    border-bottom: 1px solid var(--tp-rule);
}

/* Carries the affordance colour on its border - the app spends --color-1 on
   focus rings and the search action, which a swatch cannot show. */
#ThemePage .tp-search {
    width: 7rem;
    height: 1.1rem;
    border: 1px solid var(--tp-link);
    border-radius: 3px;
    background-color: var(--tp-surface);
}

/* Card-sized tracks, left aligned. 1fr tracks would stretch two cards to ~650px
   on a full-width panel, at which point the miniature reads as a stretched
   diagram rather than a board of cards. Empty tracks are what a real board with
   two panels looks like. */
#ThemePage .tp-board {
    display: grid;
    grid-template-columns: repeat(auto-fill, 18rem);
    justify-content: start;
    align-content: start;
    gap: .35rem;
    padding: .35rem;
    min-width: 0;
}

#ThemePage .tp-card {
    background-color: var(--tp-surface);
    border: 1px solid var(--tp-edge);
    border-radius: 3px;
    overflow: hidden;
    min-width: 0;
}

/* ---- the home screen miniature ----
   Shares the shell, the card and the tokens with the customer one; only what the home
   screen does differently lives here. */

#ThemePage .tp-home {
    display: flex;
    flex-direction: column;
    gap: .35rem;
    padding: .35rem;
    min-width: 0;
}

/* The tab strip is not a filled pill - an active tab is ink plus a 2px underline, both
   --affordance-color, which is where the first colour shows up on this screen.

   It is a white bar, matching the real .hs-tabs (--accent-1, a hairline border, under
   the location bar). Floating it on the ground instead measured as ~1.6:1 for the idle
   label against --color-3, and was wrong about the app as well as unreadable. */
#ThemePage .tp-tabs {
    display: flex;
    gap: .6rem;
    padding: .1rem .3rem 0;
    background-color: var(--tp-surface);
    border: 1px solid var(--tp-edge);
    border-radius: 3px 3px 0 0;
}

#ThemePage .tp-tab {
    padding: .1rem 0 .2rem;
    font-size: 10px;
    font-weight: 600;
    color: var(--tp-ink-muted);
}

    #ThemePage .tp-tab.is-active {
        color: var(--tp-link);
        box-shadow: inset 0 -2px 0 var(--tp-link);
    }

/* Product filters are chips: dashed and muted when off, filled with a solid border and
   affordance-coloured text when on. */
#ThemePage .tp-chipset {
    display: flex;
    flex-wrap: wrap;
    gap: .25rem;
    padding: .2rem .3rem;
}

#ThemePage .tp-chip {
    padding: .05rem .35rem;
    border: 1px dashed var(--tp-edge);
    border-radius: 10px;
    font-size: 9px;
    color: var(--tp-ink-muted);
    white-space: nowrap;
}

    #ThemePage .tp-chip.is-on {
        border-style: solid;
        border-color: var(--tp-tint-border);
        background-color: var(--tp-tint);
        color: var(--tp-link);
    }

#ThemePage .tp-chevron {
    margin-right: .25rem;
    /* Rotated because the panel reads as expanded - the glyph reports state. */
    display: inline-block;
    transform: rotate(90deg);
}

/* The one heading in the app that is deliberately **not** filled: a dense grid draws
   dark ink on the card, so a company's heading colour does not reach it. Showing that
   is the point of having this second miniature. */
#ThemePage .tp-ghead {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    gap: .3rem;
    padding: .2rem .3rem;
    border-bottom: 1px solid var(--tp-edge);
    font-size: 9px;
    font-weight: 600;
    color: var(--tp-ink);
}

#ThemePage .tp-grow {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: center;
    gap: .3rem;
    padding: .25rem .3rem;
}

    /* The zebra stripe, deliberately stronger than a hover: it has to separate every
       other row of a long result set at a glance. */
    #ThemePage .tp-grow.is-alt {
        background-color: var(--tp-alt);
    }

/* Figures line up because they are tabular, which is the whole reason the app asks for
   font-variant-numeric at the root. */
#ThemePage .tp-fig {
    font-size: 10px;
    color: var(--tp-ink);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

#ThemePage .tp-card-title,
#ThemePage .tp-grid-head {
    background-color: var(--tp-bar);
    color: var(--tp-bar-ink);
    font-size: 10px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: .05em;
    line-height: 1.3;
    padding: .2rem .3rem;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

#ThemePage .tp-grid-head {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    gap: .3rem;
    text-transform: none;
    letter-spacing: 0;
}

#ThemePage .tp-attr {
    display: grid;
    grid-template-columns: 3.25rem minmax(0, 1fr);
    gap: .3rem;
    padding: .2rem .3rem;
    font-size: 11px;
    color: var(--tp-ink);
}

    #ThemePage .tp-attr + .tp-attr {
        border-top: 1px solid var(--tp-rule);
    }

#ThemePage .tp-attr-label {
    color: var(--tp-ink-muted);
}

#ThemePage .tp-attr-value {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

#ThemePage .tp-grid-row {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: center;
    gap: .3rem;
    padding: .25rem .3rem;
    border-top: 1px solid var(--tp-rule);
}

/* Stand-in row content, grey on purpose: a themed colour here would say the
   theme paints record text, which it does not. */
#ThemePage .tp-bar-fill {
    height: .3rem;
    border-radius: 2px;
    background-color: var(--tp-rule);
}

    #ThemePage .tp-bar-fill.is-short {
        width: 1.5rem;
    }

#ThemePage .tp-card-foot {
    display: flex;
    justify-content: flex-end;
    padding: .25rem .3rem;
    border-top: 1px solid var(--tp-rule);
}

#ThemePage .tp-link {
    font-size: 10px;
    color: var(--tp-link);
    text-decoration: underline;
}

/* White ink, matching .btn-primary. Only the heading bar's ink is derived; the
   app has never varied the ink on a --color-2 button. */
#ThemePage .tp-button {
    font-size: 10px;
    font-weight: 600;
    padding: .12rem .35rem;
    border-radius: 3px;
    background-color: var(--tp-2);
    color: var(--font-color-1);
}

/* Page chrome, outside .tp-preview, so it follows the page's mode - the
   preview-local tokens are deliberately not in scope here. */
#ThemePage .tp-preview-note {
    margin: 0;
    padding: 0 .55rem .5rem;
    font-size: 11px;
    color: var(--font-color-muted);
}

/* Dark preview only. A rule rather than a colour: it states how the app behaves,
   it is not a warning about a bad choice. */
#ThemePage .tp-preview-note.is-caveat {
    margin: 0 .55rem .5rem;
    padding: .3rem .45rem;
    border-left: 2px solid var(--tint-border);
    background-color: var(--tint-bg);
}

/* One breakpoint, for the miniature only - the panels are one per row at every
   width. An 18rem track cannot fit a phone-width board, and auto-fill overflows
   rather than shrinking a fixed track. */
@container themepage (max-width: 46rem) {
    #ThemePage .tp-board {
        grid-template-columns: minmax(0, 1fr);
    }
}

#CustomerPortalSetup {
    container-type: inline-size;
    container-name: cpssetup;
    position: relative;
}

#CustomerPortalSetup .cps-layout {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    align-items: start;
    gap: .5rem;
    padding-top: .5rem;
}

#CustomerPortalSetup .cps-panels {
    display: flex;
    flex-direction: column;
    gap: .5rem;
    min-width: 0;
}

#CustomerPortalSetup .cps-panel {
    container-type: inline-size;
    container-name: cpspanel;
}

#CustomerPortalSetup .cps-rail {
    align-self: start;
}

#CustomerPortalSetup .cps-tabs .k-tabstrip {
    background-color: transparent;
    border: 0;
}

/* Explicit background rather than transparent: the strip wraps to two rows on a narrow
   window and muted labels have to stay legible across all of it. */
#CustomerPortalSetup .cps-tabs .k-tabstrip-items-wrapper {
    background-color: var(--accent-1);
    border: 0;
    border-bottom: 1px solid var(--accent-4);
}

#CustomerPortalSetup .cps-tabs .k-tabstrip-item,
#CustomerPortalSetup .cps-tabs .k-tabstrip-items-wrapper .k-item {
    padding: 0;
    border: 0;
    border-radius: 0;
    background-color: transparent;
    /* The app-wide .tabstrip .k-item rule uses !important, so matching it is unavoidable
       on the colour. */
    color: var(--font-color-muted) !important;
}

    /* Telerik puts no padding on the item itself - type and hit area belong to this
       inner span. */
    #CustomerPortalSetup .cps-tabs .k-tabstrip-item > .k-link,
    #CustomerPortalSetup .cps-tabs .k-tabstrip-items-wrapper .k-item > .k-link {
        padding: .35rem .7rem;
        font-size: 11.5px;
        font-weight: 600;
    }

    #CustomerPortalSetup .cps-tabs .k-tabstrip-item:hover,
    #CustomerPortalSetup .cps-tabs .k-tabstrip-item.k-hover,
    #CustomerPortalSetup .cps-tabs .k-tabstrip-items-wrapper .k-item:hover,
    #CustomerPortalSetup .cps-tabs .k-tabstrip-items-wrapper .k-item.k-hover {
        background-color: var(--row-hover);
        color: var(--font-color-2) !important;
    }

#CustomerPortalSetup .cps-tabs .k-active.k-tabstrip-item,
#CustomerPortalSetup .cps-tabs .k-tabstrip-item.k-active,
#CustomerPortalSetup .cps-tabs .k-tabstrip-items-wrapper .k-item.k-active {
    margin-bottom: 0;
    border-bottom-width: 0;
    background-color: var(--accent-1);
    color: var(--affordance-color) !important;
    box-shadow: inset 0 -2px 0 var(--affordance-color);
}

/* The pane owns its spacing, as a panel's rows do. */
#CustomerPortalSetup .cps-tabs .k-tabstrip-content,
#CustomerPortalSetup .cps-tabs .k-tabstrip > .k-content {
    padding: 0;
    border: 0;
    background-color: var(--accent-1);
}

    #CustomerPortalSetup .cps-tabs .k-tabstrip-content.k-active,
    #CustomerPortalSetup .cps-tabs .k-tabstrip > .k-content.k-active {
        background-color: var(--accent-1);
    }

/* ---- a tab pane ----
   What a panel body used to be, minus the card and the title bar. */
#CustomerPortalSetup .cps-pane {
    display: flex;
    flex-direction: column;
}

/* The language toggle's own bar, since it lost the title bar it used to sit in. Right
   aligned, on the hairline the rows below start from, so it reads as belonging to the
   pane rather than to the first field. The switch is its only child - it carries the
   language it is set to, which is the whole of what the bar has to say. */
#CustomerPortalSetup .cps-pane-bar {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    padding: .35rem .55rem;
    border-bottom: 1px solid var(--hairline);
}

/* The list page has one panel and no rail, so it gets a plain block. */
#CustomerPortalSetup .cps-single {
    padding-top: .5rem;
}

/* The list's header names the whole page, so it sits a step above the 14px panel bars. */
#CustomerPortalSetup .cps-single .component-header .title {
    font-size: 16px;
}

/* The set name in the list, given customer search's link treatment: the app's link colour,
   no rule until hover. Its own rule rather than a shared class because the three places
   that draw this link cannot reach each other - customer search's .search-result-link is
   scoped inside AdvancedSearch.razor.css and #CustomerComponents / #HomeScreenComponents
   key .cust-row-link on their own screen ids, for the design doc's section 3 reason.

   var(--link-color), not the #0d6efd literal .search-result-link hardcodes: the token is
   that same blue in light mode and lightens to #7fb3ff in dark, which the literal does not.

   None of .search-result-link's overflow trio is copied. That is there because its cell is
   a flex row holding the name plus a "(Ref)" marker plus two view icons and a long name
   used to run underneath them; this cell holds a name and nothing else. */
#CustomerPortalSetup .cps-set-link {
    color: var(--link-color);
    text-decoration: none;
    cursor: pointer;
}

    #CustomerPortalSetup .cps-set-link:hover {
        text-decoration: underline;
    }


/* The base .component is white text on --accent-3, the pre-contract shape. */
#CustomerPortalSetup .component {
    background-color: var(--accent-1);
    border: 1px solid var(--accent-4);
    border-radius: 4px;
    box-shadow: var(--panel-shadow);
    color: var(--font-color-2);
    overflow: hidden;
}

/* Bootstrap's wrapper; the rows own their spacing. Direct child only, and both parents
   it can have: a hand-written panel body sits straight inside .component, a tab pane's
   sits inside .cps-pane. Missing the second one left every pane's rows inset by Bootstrap's
   own .5rem.

   There was a #CustomerPortalSetup .component-title block above this - an 11px uppercase
   bar. Nothing on either of this screen's two pages rendered that class: both use
   <ComponentHeader>, which draws .component-header from the shared library's scoped file
   at 14px sentence case. The rule was the panel editor's own title bar, and it went with
   the bar when the panels became tab panes. */
#CustomerPortalSetup .component > .p-2,
#CustomerPortalSetup .cps-pane > .p-2 {
    padding: 0 !important;
}

#CustomerPortalSetup .cps-intro {
    margin: 0;
    padding: .4rem .55rem;
    border-bottom: 1px solid var(--hairline);
    font-size: 11.5px;
    color: var(--font-color-muted);
}

#CustomerPortalSetup .cps-error {
    margin: .25rem;
    padding: .4rem .55rem;
    border: 1px solid var(--bad-border);
    border-radius: 4px;
    background-color: var(--accent-1);
    font-size: 12px;
    color: var(--warning-color);
}

/* ---- the language toggle, in the panel's own title bar ---- */

/* margin-left: auto pushes it right, the same way .header-buttons does. It sits
   in the bar rather than above the fields because it governs the whole panel,
   and a control on its own row would read as one more field. */

/* ---- sub-headings inside a pane ---- */

/* The messaging panel carries six of these, and each one is the control that opens its
   group - so the heading has to read as a heading and behave as a button. It is not a
   filled bar: one tab strip per card, and six filled bars under it would read as six
   panels.

   A <button> resets to nothing here. The metrics live in app.css rather than a scoped
   file for the design doc's section 3 reason, and the same reason the loans card's
   collapsible title bar does. */
#CustomerPortalSetup .cps-group {
    display: flex;
    align-items: center;
    gap: .4rem;
    width: 100%;
    margin: 0;
    padding: .5rem .55rem .25rem;
    border: 0;
    border-top: 1px solid var(--hairline);
    background-color: transparent;
    font-size: 11px;
    font-weight: 600;
    letter-spacing: .04em;
    text-transform: uppercase;
    text-align: left;
    color: var(--font-color-muted);
    cursor: pointer;
}

#CustomerPortalSetup .cps-group:hover {
    background-color: var(--row-hover);
    color: var(--font-color-2);
}

#CustomerPortalSetup .cps-group:focus-visible {
    outline: 2px solid var(--affordance-color);
    outline-offset: -2px;
}

/* The app's one chevron idiom: 11.5px, rotating 90 degrees when open. */
#CustomerPortalSetup .cps-group-chevron {
    flex: 0 0 auto;
    font-size: 11.5px;
    line-height: 1;
    transition: transform .15s ease;
}

#CustomerPortalSetup .cps-group.is-open .cps-group-chevron {
    transform: rotate(90deg);
}

@media (prefers-reduced-motion: reduce) {
    #CustomerPortalSetup .cps-group-chevron {
        transition: none;
    }
}

#CustomerPortalSetup .cps-group-label {
    flex: 1 1 auto;
    min-width: 0;
}

/* The count is what makes a closed group honest about what it hides - the design doc's
   rule that a collapse is labelled with its contents, not with "show more". Tabular
   figures so six of them stacked line up. */
#CustomerPortalSetup .cps-group-count {
    flex: 0 0 auto;
    font-variant-numeric: tabular-nums;
    font-weight: 400;
    letter-spacing: normal;
}



/* ---- field rows ---- */

/* Both columns are capped, and the slack goes to the right of the pair rather than
   between the two halves of it. Neither cap is arbitrary.

   22rem on the label. It was a 1fr track until linear panels made a panel 70rem wide and
   the label sat 470px from its own input. 22rem does not fit every label - measured in a
   headless browser over all 80 fields in both languages, the widest is the features
   panel's Spanish "Desactivar Obtener efectivo ahora cuando el cliente tiene un caso en
   cobranza" at 426px - and it is not meant to. What matters is the worst case, and the
   worst case is two lines, never three: at a 352px column 153 of the 160 label strings
   stay on one line, and the seven that wrap wrap once. The row is align-items: center, so
   a two-line label keeps its control centred against it.

   On the control, 55% with a 40rem ceiling: the percentage reproduces the old flat 22rem
   at the ~40rem panel a column used to be, so nothing narrower than that changed, and the
   ceiling is there because past it a single-line textbox stops reading as a field and
   starts reading as a paragraph.

   The two sum to less than a wide panel, so a row is a pair on the left with space after
   it. That is deliberate: the row still spans the panel, so its hover band and its rule
   do too, and only the controls stop stretching. */
#CustomerPortalSetup .cps-row {
    display: grid;
    grid-template-columns: minmax(0, 22rem) minmax(0, min(40rem, 55%));
    align-items: center;
    gap: .5rem;
    padding: .4rem .55rem;
}

    /* The one exception to the two-column row, and it earns it: a chooser is two full-height
       boxes, not a control on a line. Beside a 22rem label column it left that column empty
       from the label down to the panel footer, and inside the remaining width every document
       type name truncated. One column, so the label captions the pair from above and the boxes
       take the whole panel. */
    #CustomerPortalSetup .cps-row.is-wide {
        grid-template-columns: minmax(0, 1fr);
        align-items: start;
        gap: .35rem;
    }

    #CustomerPortalSetup .cps-row + .cps-row {
        border-top: 1px solid var(--hairline);
    }

    #CustomerPortalSetup .cps-row:hover {
        background-color: var(--row-hover);
    }

#CustomerPortalSetup .cps-row-text {
    display: flex;
    flex-direction: column;
    gap: 1px;
    min-width: 0;
}

#CustomerPortalSetup .cps-row-label {
    margin: 0;
    font-size: 12px;
    font-weight: 600;
    color: var(--font-color-2);
}

#CustomerPortalSetup .cps-row-help {
    font-size: 11px;
    color: var(--font-color-muted);
}

#CustomerPortalSetup .cps-row-label-line {
    display: flex;
    align-items: center;
    gap: .35rem;
    min-width: 0;
}

#CustomerPortalSetup .cps-help-tip {
    flex: 0 0 auto;
    font-size: 12px;
    color: var(--font-color-muted);
    cursor: help;
}

    #CustomerPortalSetup .cps-help-tip:hover {
        color: var(--affordance-color);
    }

.cps-help-pop.k-tooltip,
.cps-help-pop .k-tooltip {
    max-width: 24rem;
}

.cps-help-pop-text {
    font-size: 12px;
    line-height: 1.45;
    white-space: pre-line;
}

/* Tabular figures so the count does not jitter as it is typed into - the same
   reason the theme page's contrast readout asks for them. */
#CustomerPortalSetup .cps-count {
    font-size: 11px;
    color: var(--font-color-muted);
    font-variant-numeric: tabular-nums;
}

#CustomerPortalSetup .cps-row-control {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    min-width: 0;
}

#CustomerPortalSetup .cps-stack {
    display: flex;
    flex-direction: column;
    gap: .25rem;
}

/* A checkbox and a switch are the two controls that should not stretch to the
   column; everything else fills it so the inputs share one right edge. */
#CustomerPortalSetup .cps-row-control .k-checkbox,
#CustomerPortalSetup .cps-row-control .k-switch,
#CustomerPortalSetup .cps-row-control .k-colorpicker {
    align-self: flex-end;
}

/* The 28px control metric (design doc section 8). Telerik renders its own inner
   elements, so the height is set on the wrapper - `Class` lands there, a bare
   lowercase `class` would land on the inner input instead. */
#CustomerPortalSetup .cps-row-control .k-input,
#CustomerPortalSetup .cps-row-control .k-picker {
    min-height: 28px;
    border-radius: 4px;
    border-color: var(--accent-4);
    background-color: var(--accent-1);
    background-image: none;
    font-size: 12px;
}

#CustomerPortalSetup .cps-row-control .k-input:focus-within,
#CustomerPortalSetup .cps-row-control .k-picker:focus-within {
    outline: 2px solid var(--affordance-color);
    outline-offset: -1px;
}

#CustomerPortalSetup .cps-row-control .k-colorpicker {
    height: 28px;
    border-radius: 4px;
    border-color: var(--accent-4);
    background-color: var(--accent-1);
    background-image: none;
}

/* A textarea has to keep the height its Rows asks for. */
#CustomerPortalSetup .cps-row-control .k-textarea .k-input-inner {
    min-height: 0;
}

#CustomerPortalSetup .cps-html .ProseMirror {
    font-family: var(--font-body);
    font-size: .9rem;
    line-height: 1.5;
}

#CustomerPortalSetup .cps-html .ProseMirror :is(h1, h2, h3, h4, h5, h6) {
    margin: .75em 0 .375em;
    font-weight: 600;
    line-height: 1.25;
}

#CustomerPortalSetup .cps-html .ProseMirror h1 {
    font-size: 1.4em;
}

#CustomerPortalSetup .cps-html .ProseMirror h2 {
    font-size: 1.25em;
}

#CustomerPortalSetup .cps-html .ProseMirror h3 {
    font-size: 1.1em;
}

#CustomerPortalSetup .cps-html .ProseMirror :is(h4, h5, h6) {
    font-size: 1em;
}

#CustomerPortalSetup .cps-html .ProseMirror :is(p, ul, ol) {
    margin: 0 0 .5em;
}

#CustomerPortalSetup .cps-html .ProseMirror :is(ul, ol) {
    padding-inline-start: 1.25em;
}

#CustomerPortalSetup .cps-html .ProseMirror > :first-child {
    margin-top: 0;
}

/* ---- logos ----
   One 28px row per logo instead of four stacked blocks. Telerik's FileSelect draws a
   filled, bordered dropzone, a "drag and drop a file here" hint, and a list row for each
   picked file; with a 64px thumbnail and a hint line under all of it that came to ~180px
   per field, and the branding panel has three of them.

   What is dropped and why:

   - The list row ("images.jpg  x"). The swatch beside the button already says which file
     is loaded, and its remove button only cancels a pick that has not been posted yet -
     which the panel's own Cancel does, for every field at once. FileSelect has no
     parameter to hide it (checked against the 13.1.0 API), so it goes in CSS.

   Verified against the component rendered in a real Blazor app on Telerik 13.1.0, not
   read off the theme's class list: the root is .k-upload, the bar is .k-dropzone with
   .k-upload-button-wrap > button.k-upload-button and a .k-dropzone-hint span beside it,
   and picking a file appends a .k-upload-files list as a sibling of the bar.
   .k-upload-dropzone is NOT rendered by this version - it is listed below as version
   insurance, the same way #WorkflowScreen's dropzone rules list both.
   - The drag-and-drop hint. The drop target is the same element either way, so dropping
     still works; only the sentence about it goes. Same trade #WorkflowScreen's dropzone
     already makes.
   - The dropzone's border and fill, so what is left is a button on the row rather than a
     bordered box inside a bordered row. */
#CustomerPortalSetup .cps-logo {
    display: flex;
    align-items: center;
    gap: .4rem;
    min-width: 0;
}

/* The swatch is 28px, the control metric, so a logo row is exactly as tall as the text
   rows above it. It is confirmation that the right file is loaded, not a place to judge
   the artwork - the miniatures in the preview rail draw the real thing at the size the
   portal draws it. */
#CustomerPortalSetup .cps-logo-preview,
#CustomerPortalSetup .cps-logo-empty {
    flex: 0 0 auto;
    width: 4.5rem;
    height: 28px;
    padding: 2px;
    border: 1px solid var(--accent-4);
    border-radius: 4px;
    background-color: var(--accent-1);
    object-fit: contain;
}

/* Nothing loaded yet: a dashed well, which reads as a slot waiting for something rather
   than as a control, and holds the button's position so it does not move when a file
   lands. */
#CustomerPortalSetup .cps-logo-empty {
    border-style: dashed;
    background-color: var(--tint-strong);
}

#CustomerPortalSetup .cps-logo .k-upload {
    flex: 0 0 auto;
    border: 0;
    background: none;
}

#CustomerPortalSetup .cps-logo .k-dropzone,
#CustomerPortalSetup .cps-logo .k-upload-dropzone {
    min-height: 0;
    padding: 0;
    border: 0;
    background: none;
}

#CustomerPortalSetup .cps-logo .k-dropzone-hint,
#CustomerPortalSetup .cps-logo .k-upload-files {
    display: none;
}

/* The 28px control metric again. app.css sets .k-upload-button's fill with !important
   app-wide, so overriding it takes !important back - the same reason #WorkflowScreen's
   dropzone button does. */
#CustomerPortalSetup .cps-logo .k-upload-button {
    height: 28px;
    min-height: 28px;
    padding: 0 .6rem;
    border: 1px solid var(--accent-4) !important;
    border-radius: 4px;
    background-color: var(--accent-1) !important;
    background-image: none !important;
    color: var(--link-color) !important;
    font-size: 12px;
    font-weight: 600;
}

#CustomerPortalSetup .cps-logo .k-upload-button:hover {
    background-color: var(--row-hover) !important;
}

#CustomerPortalSetup .cps-logo .k-upload-button:focus-visible,
#CustomerPortalSetup .cps-logo .k-upload-button.k-focus {
    outline: 2px solid var(--affordance-color);
    outline-offset: -1px;
}

/* The hint keeps the .cps-row-help treatment it has on every other row, but on the line
   rather than under it. It takes the remaining width so it truncates rather than pushing
   the row wider than its column. */
#CustomerPortalSetup .cps-logo .cps-row-help {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}


/* ---- the document-type chooser ----
   Two boxes and a transfer column between them. The row it sits on is .is-wide, because a
   chooser is not a control on a line: at the 40rem ceiling every type name in the list
   truncated, which is the one thing the left box exists to let someone read.

   The sides are flex items rather than two halves of a grid. Telerik renders the transfer
   buttons inside the primary .k-listbox, not between the two, so the left side is wider
   than its list by the button column and no fixed pair of tracks lines the lists up. */
#CustomerPortalSetup .cps-listbox {
    display: flex;
    align-items: stretch;
    gap: .5rem;
    min-width: 0;
}

#CustomerPortalSetup .cps-listbox-side {
    display: flex;
    flex: 1 1 0;
    flex-direction: column;
    gap: .2rem;
    min-width: 0;
}

/* The caption is the .header-item-k metric: these two words name a box, they are not a
   second field label competing with the row's own. */
#CustomerPortalSetup .cps-listbox-caption {
    font-size: 9px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .06em;
    color: var(--font-color-muted);
}

/* .k-listbox ships width: 10em and height: 200px; both are set on the component instead,
   so all this has to do is stop the flex item from resolving against the fixed width. */
#CustomerPortalSetup .cps-listbox .k-listbox {
    min-width: 0;
}

#CustomerPortalSetup .cps-listbox .k-list-scroller {
    border: 1px solid var(--accent-4);
    border-radius: 4px;
    background-color: var(--accent-1);
}

#CustomerPortalSetup .cps-listbox .k-list-item {
    padding: .2rem .45rem;
    font-size: 12px;
    line-height: 1.35;
    color: var(--font-color-2);
}

    #CustomerPortalSetup .cps-listbox .k-list-item:hover,
    #CustomerPortalSetup .cps-listbox .k-list-item.k-hover {
        background-color: var(--row-hover);
    }

    /* Selection here is a held state, not a saved one - it says which rows the next transfer
       will move - so it takes the filled treatment a selected segment does. */
    #CustomerPortalSetup .cps-listbox .k-list-item.k-selected {
        background-color: var(--header-bar);
        color: var(--header-bar-ink);
    }

/* Centred against the lists rather than pinned to their top: the buttons act on both boxes,
   and against a full-height list a top-aligned column reads as belonging to the left one. */
#CustomerPortalSetup .cps-listbox .k-listbox-actions {
    align-self: center;
    gap: .25rem;
}

    #CustomerPortalSetup .cps-listbox .k-listbox-actions .k-button {
        width: 28px;
        height: 28px;
        min-width: 0;
        padding: 0;
        border: 1px solid var(--accent-4);
        border-radius: 4px;
        background-color: var(--accent-1);
        color: var(--font-color-2);
    }

        #CustomerPortalSetup .cps-listbox .k-listbox-actions .k-button:hover {
            background-color: var(--row-hover);
            border-color: #b9c6d4;
        }

        #CustomerPortalSetup .cps-listbox .k-listbox-actions .k-button:disabled,
        #CustomerPortalSetup .cps-listbox .k-listbox-actions .k-button.k-disabled {
            color: var(--font-color-muted);
        }

/* ---- panel footer ---- */

/* Neither button is a filled primary; the app keeps two of those (Search and
   Sign In) and a settings panel is not one. Save takes the affordance colour so
   the pair still has an order. */
#CustomerPortalSetup .cust-comp-btn-container {
    display: flex;
    justify-content: flex-end;
    gap: .35rem;
    margin: 0;
    padding: .5rem .55rem;
    border-top: 1px solid var(--hairline);
}

#CustomerPortalSetup .cust-comp-btn-container .k-button {
    height: 28px;
    min-height: 28px;
    padding: 0 .6rem;
    border: 1px solid var(--accent-4);
    border-radius: 4px;
    background-color: var(--accent-1);
    background-image: none;
    box-shadow: none;
    font-size: 12px;
    font-weight: 500;
    color: var(--font-color-2);
}

    #CustomerPortalSetup .cust-comp-btn-container .k-button .k-button-text {
        height: 28px;
        line-height: 28px;
        background-color: transparent;
        color: inherit;
    }

    #CustomerPortalSetup .cust-comp-btn-container .k-button:hover {
        background-color: var(--tint-bg);
        border-color: var(--tint-border);
    }

    #CustomerPortalSetup .cust-comp-btn-container .cps-save,
    #CustomerPortalSetup .cust-comp-btn-container .cps-save .k-button-text {
        color: var(--affordance-color);
        font-weight: 600;
    }

/* ---- the list page's grid ---- */

#CustomerPortalSetup .k-grid {
    border: 0;
    font-size: 12px;
}

#CustomerPortalSetup .k-grid .k-table-row:hover {
    background-color: var(--tint-strong);
}

#CustomerPortalSetup .cust-empty {
    padding: .25rem .55rem;
    font-size: 11px;
    color: var(--font-color-muted);
}

/* ---- the panel header's trailing action ----------------------------------
   ComponentHeader gives its ChildContent a width:100% wrapper, so anything put
   inside it sits beside the title rather than at the far edge. Making that
   wrapper the flex row and pushing the action with margin-left:auto is what
   puts the changelog icon in the corner the close button used to hold. */
#CustomerPortalSetup .component-header .component-header-child-content {
    display: flex;
    align-items: center;
    gap: .4rem;
    min-width: 0;
}

#CustomerPortalSetup .cps-header-title {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

#CustomerPortalSetup .cps-header-action {
    margin-left: auto;
    flex: none;
}

/* ---- the borrowed switch --------------------------------------------------
   .language-switch is the app's word-carrying switch, borrowed for its geometry
   (84x22 track, 18px thumb, travel, and a drawn label rather than a masked glyph,
   so the control says what it does). This screen has two of them: one in the
   preview rail's navy ComponentHeader, which needs nothing because that is the
   ground the switch was drawn for, and one in a white .cps-pane-bar, which is
   this rule.

   The repaint is a *fill*, not a new palette. The base rule paints the track
   rgba(255, 255, 255, .14) with a .22 hairline, which over the navy header renders
   as a mid slate; composing the same two mixes over --header-bar explicitly gives
   a white bar the identical colour, so the two toggles on this screen are the same
   control in the same colour rather than two treatments of one control. Derived
   from --header-bar rather than pinned to a hex because that token is rewritten per
   company at runtime (design doc section 2) - a literal would drift off-theme the
   first time a company changed its header.

   Palette only; the id outranks the class rules, so no !important.

   The 84px track was measured against `Español`, which is the longest label it now
   has to hold. A longer word in a future resx would need it re-measured - see the
   design doc's rule on localized text in fixed controls. */
#CustomerPortalSetup .cps-lang-switch.k-switch .k-switch-track {
    background-color: color-mix(in srgb, #ffffff 14%, var(--header-bar));
    box-shadow: inset 0 0 0 1px color-mix(in srgb, #ffffff 22%, var(--header-bar));
    color: var(--font-color-1);
}

#CustomerPortalSetup .cps-lang-switch.k-switch:hover .k-switch-track {
    background-color: color-mix(in srgb, #ffffff 22%, var(--header-bar));
}

/* Without color-mix the bar takes --header-bar flat. Darker than the header's own
   switch by the 14% white, and still white-on-navy, so it reads correctly - it just
   stops being pixel-identical to its twin. */
@supports not (color: color-mix(in srgb, red, blue)) {
    #CustomerPortalSetup .cps-lang-switch.k-switch .k-switch-track {
        background-color: var(--header-bar);
        box-shadow: inset 0 0 0 1px var(--header-bar);
    }

    #CustomerPortalSetup .cps-lang-switch.k-switch:hover .k-switch-track {
        background-color: var(--header-bar);
    }
}

#CustomerPortalSetup .cps-lang-switch:focus-visible .k-switch-track,
#CustomerPortalSetup .cps-lang-switch.k-focus .k-switch-track {
    outline: 2px solid var(--affordance-color);
    outline-offset: -2px;
}

/* 12px, the size every label and input on this screen is set at, rather than the
   11px the nav rail wants. The word in a switch is the value being read, so it
   should not be the smallest type in the panel. Its twin in the rail header keeps
   11px: it sits in a title bar, not among 12px field rows.

   It fits, measured on the real control in a running app rather than worked out from
   the fallback stack: the lane is 52px (84px track less the 8px and 24px insets),
   and in Inter - which is what actually renders now, not the Tahoma the base rule's
   comment measured against - "Español" inks 43.07px at 11px and 46.98px at 12px,
   leaving 5.02px of clearance. 12.5px needs 48.95px and is too tight, so 12px is the
   ceiling here. */
#CustomerPortalSetup .cps-lang-switch.k-switch .k-switch-label-on,
#CustomerPortalSetup .cps-lang-switch.k-switch .k-switch-label-off {
    font-size: 12px;
}


/* ---- the branding miniature ----------------------------------------------
   A small portal home page that repaints as the pickers move, so an admin can
   see a colour doing its job instead of reading a hex. The loan application has
   its own theme and preview in the layout editor, so it is not drawn here.

   The colours arrive as inline custom properties on .cpp-shots (--cpp-primary
   and friends, from PortalBrandingPreview.PaletteStyle), never as writes to
   :root - so dragging a picker repaints this box and nothing else until Save.
   That is also why the miniature is hand-built markup: a real control would
   read the LMS's own tokens and would not follow.

   Their surfaces are literals rather than app tokens on purpose. These are
   pictures of the *customer-facing* apps, which have their own light palette and
   do not follow the LMS user's dark mode; painting them from --accent-1 would
   make them change colour with the wrong app.

   The type is not a scale factor off the real screens. A faithful reduction of a
   1580px-wide application section puts its labels at 5px, so the sizes are set
   for legibility and it is the structure and the colour that are reproduced
   exactly - which is all the pickers are being judged on. */
/* No border of its own: .cps-rail is the card now. The rule was here when the
   miniature was the last block inside the branding panel and needed separating from
   the field rows above it. */
#CustomerPortalSetup .cpp-preview {
    display: flex;
    flex-direction: column;
    gap: .35rem;
    padding: .55rem;
}


/* One home for the palette, inherited by the frame. */
#CustomerPortalSetup .cpp-shots {
    display: flex;
    flex-direction: column;
    gap: .6rem;

    --cpp-page: #f4f6fa;
    --cpp-surface: #ffffff;
    --cpp-edge: #e2e6eb;
    --cpp-ink: #424242;
    --cpp-ink-muted: #666666;
    --cpp-alert: #b00000;
}

#CustomerPortalSetup .cpp-shot {
    display: flex;
    flex-direction: column;
    gap: .2rem;
}

#CustomerPortalSetup .cpp-shot-label {
    font-size: 11px;
    font-weight: 600;
    color: var(--font-color-muted);
}

#CustomerPortalSetup .cpp-frame {
    max-width: 100%;
    border: 1px solid var(--accent-4);
    border-radius: 4px;
    overflow: hidden;
    color: var(--cpp-ink);
    font-size: 10px;
    line-height: 1.25;
}

/* The portal's own content column is 832px against a full-height page, so the frame
   reads as a column rather than a full desktop screen.

   --cpp-dome is where the page-background arc lands. Not a scaled clamp(): the arc
   is only legible where it crosses the gap between two cards, so the value is the
   height that puts it just past the document-request row, which is where the real
   page puts it too. Retune it if the cards above it change height. */
#CustomerPortalSetup .cpp-frame.is-home {
    width: 26rem;
    --cpp-dome: 10.5rem;
}

/* .page-background and its ::before dome, which is the largest thing either colour
   paints and the only place the two are seen against each other. Absolute rather
   than the app's fixed, and isolated so the negative z-index stays inside the frame
   instead of dropping behind the setup panel. */
#CustomerPortalSetup .cpp-stage {
    position: relative;
    isolation: isolate;
    padding: .4rem;
    background-color: var(--cpp-page);
}

#CustomerPortalSetup .cpp-stage::before {
    content: "";
    position: absolute;
    top: 0;
    left: -25%;
    width: 150%;
    height: var(--cpp-dome);
    background: linear-gradient(to right, var(--cpp-primary), var(--cpp-accent));
    /* Opposing corner radii sum past 100% on the bottom edge, so the browser scales
       them into one shallow dome rather than two rounded corners - same expression
       the apps use. */
    border-radius: 0 0 50% 50% / 0 0 100% 100%;
    opacity: .5;
    z-index: -1;
}

/* ---- the header pill ----
   White in both apps. Worth drawing rather than tinting, because "Header Color" is
   the label on the primary picker and this bar is the first place an admin looks
   for it: the brand colour reaches the pill only through the avatar. */
#CustomerPortalSetup .cpp-bar {
    display: flex;
    align-items: center;
    gap: .25rem;
    margin-bottom: .4rem;
    padding: .15rem .3rem;
    border-radius: 6px;
    background-color: var(--cpp-surface);
    box-shadow: 0 1px 3px rgba(0, 0, 0, .12), 0 1px 2px rgba(0, 0, 0, .08);
}

/* flex: 1 1 0, so the two sides take an equal share of whatever the logo leaves and the
   logo lands on the bar's true centre. Content-width sides (flex: 0 0 auto, with the centre
   growing) centre the logo in the *leftover* space instead, which is only the middle when
   the two sides happen to weigh the same - and they never do here: the bar carries two nav
   items against one avatar.

   NOTE: this is the one place the miniature deliberately does not reproduce AppHeader, whose
   .header-left / .header-center / .header-right do exactly the content-width thing described
   above. By its own metrics - two 44px items vs a 44px avatar - the real logo sits about 22px
   right of centre on the portal home in a 600px bar. Worth fixing there too; until it is, this
   is a preview that flatters the header by a few dozen pixels. */
#CustomerPortalSetup .cpp-bar-side {
    display: flex;
    align-items: center;
    gap: .3rem;
    flex: 1 1 0;
    min-width: 0;
}

#CustomerPortalSetup .cpp-bar-side.is-end {
    justify-content: flex-end;
}

/* Content width now, since the sides are the ones that grow. */
#CustomerPortalSetup .cpp-bar-center {
    display: flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    min-width: 0;
}

#CustomerPortalSetup .cpp-nav-item {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 1px;
    padding: .1rem .2rem;
    color: var(--cpp-ink);
}

#CustomerPortalSetup .cpp-nav-text {
    font-size: 7px;
    line-height: 1.1;
}

#CustomerPortalSetup .cpp-icon {
    width: 11px;
    height: 11px;
    flex: 0 0 auto;
}

#CustomerPortalSetup .cpp-logo {
    max-height: 1.15rem;
    max-width: 7rem;
    object-fit: contain;
}

/* Stands in for a logo that has not been uploaded yet. Its own neutral rather than
   currentColor, now that the bar behind it is white in every case. */
#CustomerPortalSetup .cpp-logo-placeholder {
    width: 3.5rem;
    height: 1rem;
    border-radius: 2px;
    background-color: var(--cpp-edge);
}

#CustomerPortalSetup .cpp-avatar {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 1.15rem;
    height: 1.15rem;
    border-radius: 50%;
    background-color: var(--cpp-page);
}

#CustomerPortalSetup .cpp-avatar-glyph {
    width: 11px;
    height: 11px;
    color: var(--cpp-primary);
}

/* ---- cards ---- */
#CustomerPortalSetup .cpp-screen {
    display: flex;
    flex-direction: column;
    gap: .35rem;
    container: cppshot / inline-size;
}

#CustomerPortalSetup .cpp-card {
    padding: .4rem;
    border-radius: 6px;
    background-color: var(--cpp-surface);
    box-shadow: 0 1px 3px rgba(0, 0, 0, .1);
}

#CustomerPortalSetup .cpp-welcome {
    font-size: 15px;
    font-weight: 600;
    text-align: center;
    color: #212529;
}

#CustomerPortalSetup .cpp-marketing {
    margin-top: .15rem;
    text-align: center;
    color: var(--cpp-ink-muted);
}

#CustomerPortalSetup .cpp-card.is-loan {
    overflow: hidden;
}

#CustomerPortalSetup .cpp-actions {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: .3rem;
}

#CustomerPortalSetup .cpp-action {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: center;
    gap: .3rem;
    padding: .35rem .4rem;
    border-radius: 6px;
    background-color: var(--cpp-surface);
    box-shadow: 0 1px 3px rgba(0, 0, 0, .1);
}

#CustomerPortalSetup .cpp-action.is-wide {
    grid-column: 1 / -1;
}

#CustomerPortalSetup .cpp-action-text {
    min-width: 0;
    font-size: 9px;
}

#CustomerPortalSetup .cpp-action-title {
    display: block;
    font-size: 10px;
    font-weight: 600;
}

#CustomerPortalSetup .cpp-action .cpp-btn {
    white-space: normal;
}

@container cppshot (max-width: 22rem) {
    #CustomerPortalSetup .cpp-actions {
        grid-template-columns: minmax(0, 1fr);
    }
}

/* Its own red, not a brand colour: an admin who tints everything still needs to see
   that the past-due banner will not follow. */
#CustomerPortalSetup .cpp-alert {
    margin: -.4rem -.4rem .35rem;
    padding: .3rem;
    background-color: var(--cpp-alert);
    color: #fff;
    text-align: center;
}

#CustomerPortalSetup .cpp-alert-title {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: .25rem;
    font-size: 11px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .02em;
}

#CustomerPortalSetup .cpp-alert-sub {
    margin-top: .1rem;
    font-size: 8px;
    font-weight: 600;
}

#CustomerPortalSetup .cpp-loan-head {
    display: flex;
    align-items: center;
    gap: .35rem;
    padding-bottom: .25rem;
}

#CustomerPortalSetup .cpp-loan-id {
    font-size: 12px;
    font-weight: 700;
}

#CustomerPortalSetup .cpp-loan-due {
    margin-left: auto;
    font-size: 9px;
    color: var(--cpp-ink-muted);
}

#CustomerPortalSetup .cpp-loan-due b {
    font-weight: 600;
    color: var(--cpp-ink);
}

#CustomerPortalSetup .cpp-kebab {
    flex: 0 0 auto;
    width: 9px;
    height: 9px;
    color: var(--cpp-ink-muted);
}

#CustomerPortalSetup .cpp-band {
    display: flex;
    align-items: center;
    gap: .3rem;
    padding: .3rem 0 .35rem;
    border-top: 1px solid lightgray;
    border-bottom: 1px solid lightgray;
}

#CustomerPortalSetup .cpp-band-text {
    flex: 1 1 auto;
    min-width: 0;
}

#CustomerPortalSetup .cpp-band-label {
    display: block;
    font-weight: 600;
}

#CustomerPortalSetup .cpp-band-sub {
    display: block;
    font-size: 9px;
    color: var(--cpp-ink-muted);
}

#CustomerPortalSetup .cpp-figures {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    padding: .35rem 0;
}

#CustomerPortalSetup .cpp-figure {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: .1rem;
    padding: 0 .25rem;
}

#CustomerPortalSetup .cpp-figure + .cpp-figure {
    border-left: 1px solid lightgray;
}

#CustomerPortalSetup .cpp-figure-label {
    font-size: 8px;
    text-align: center;
}

#CustomerPortalSetup .cpp-figure-sub {
    font-size: 8px;
    color: var(--cpp-ink-muted);
    font-variant-numeric: tabular-nums;
}

#CustomerPortalSetup .cpp-chip {
    padding: .05rem .3rem;
    border-radius: 6px;
    font-size: 9px;
    font-weight: 700;
    background-color: #eef0f4;
    color: var(--cpp-ink);
}

#CustomerPortalSetup .cpp-chip.is-on {
    background-color: #e6f2ea;
    color: #2f7d55;
}

#CustomerPortalSetup .cpp-notice {
    display: flex;
    align-items: flex-start;
    gap: .25rem;
    margin-top: .3rem;
    padding: .25rem .35rem;
    border-radius: 6px;
    font-size: 9px;
    text-align: left;
}

#CustomerPortalSetup .cpp-notice.is-good {
    background-color: #e6f2ea;
    color: #2f7d55;
}

#CustomerPortalSetup .cpp-notice.is-warn {
    background-color: #faf1de;
    color: #966212;
}

#CustomerPortalSetup .cpp-loan-actions {
    display: flex;
    flex-wrap: wrap;
    gap: .25rem;
    margin-top: .4rem;
    padding-top: .4rem;
    border-top: 1px solid lightgray;
}

#CustomerPortalSetup .cpp-loan-actions .cpp-btn {
    flex: 1 1 auto;
}

#CustomerPortalSetup .cpp-prev-loans {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: .1rem .15rem;
    font-size: 12px;
    font-weight: 600;
}

#CustomerPortalSetup .cpp-prev-loans .cpp-caret {
    color: var(--cpp-ink-muted);
}

/* Tabular figures so the amounts do not jitter as a picker is dragged beside them. */
#CustomerPortalSetup .cpp-figure-value {
    font-size: 13px;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
}

#CustomerPortalSetup .cpp-caret {
    width: 9px;
    height: 9px;
    color: var(--cpp-ink-muted);
}

/* ---- buttons ---- */
#CustomerPortalSetup .cpp-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: .25rem;
    padding: .25rem .5rem;
    border-radius: 4px;
    font-size: 10px;
    font-weight: 600;
    white-space: nowrap;
}

/* .btn-gradient / .btn-secondary: filled with the accent, but lettered with the
   *primary's* ink. Not a mistake here - nothing in either app consumes
   --accentTextColor, so every filled button takes --primaryTextColor, and a light
   Button colour under a light Header colour really does draw a pale label. The
   preview exists to show that before it ships. */
#CustomerPortalSetup .cpp-btn.is-brand {
    background-color: var(--cpp-accent);
    color: var(--cpp-primary-ink);
}

#CustomerPortalSetup .cpp-btn.is-outline {
    border: 1px solid var(--cpp-primary);
    color: var(--cpp-primary);
    background-color: transparent;
}

#CustomerPortalSetup .cpp-note {
    margin: 0;
    font-size: 11px;
    color: var(--font-color-muted);
}


/* ---- two-column stage ------------------------------------------------------
   The preview rail moves out of the flow and into its own column. Queried on the
   screen (cpssetup), not on a panel: what decides this is whether the page can
   afford both, and a panel's own width is a *result* of the answer.

   The rail's ceiling is 27.6rem, exactly what the home frame needs to be drawn 1:1:
   its 26rem, the preview's .55rem padding each side and the card's .25rem margin
   each side. Its floor is 22rem, where the rail stops earning a column.
   62rem is the smallest page that leaves the panel column clear of the 34rem row
   stage below with the rail at that floor: 62 - 22 - 0.5 = 39.5rem. */
@container cpssetup (min-width: 62rem) {
    #CustomerPortalSetup .cps-layout {
        grid-template-columns: minmax(0, 1fr) clamp(22rem, 30%, 27.6rem);
    }
}

/* ---- wide control stage ----------------------------------------------------
   A checkbox pinned to the right edge of a 25rem-plus control column sits half a
   panel away from the label it answers. Past this width the column's *start* is the
   shared edge instead - which is where every stretched input begins too, so the
   alignment still holds and the small controls stay next to their labels. */
@container cpspanel (min-width: 46rem) {
    #CustomerPortalSetup .cps-row-control .k-checkbox,
    #CustomerPortalSetup .cps-row-control .k-switch,
    #CustomerPortalSetup .cps-row-control .k-colorpicker {
        align-self: flex-start;
    }
}

/* ---- narrow stage ----------------------------------------------------------
   The label column and the control column stop sharing a line.

   34rem was measured against a flat 22rem control and a 1fr label, and the string
   named as deciding it was the messaging panel's "Decline / no offers text line 2
   (with redirect)". Both halves of that are now stale: the tracks above are capped
   and proportional, and re-measuring over all 80 fields in both languages puts the
   widest label in the *features* panel, not messaging (see the row rule for the
   string). Re-measured with the stage neutralised, a two-column row holds at two
   lines down to a 32rem panel and takes its first third line at 30rem - so 34rem is
   now a conservative floor, not the limit. It is kept there on purpose: stacking
   2rem early costs one row of height, stacking late costs a three-line label. */
@container cpspanel (max-width: 34rem) {
    #CustomerPortalSetup .cps-row {
        grid-template-columns: minmax(0, 1fr);
        gap: .25rem;
    }

    #CustomerPortalSetup .cps-row-control .k-checkbox,
    #CustomerPortalSetup .cps-row-control .k-switch,
    #CustomerPortalSetup .cps-row-control .k-colorpicker {
        align-self: flex-start;
    }
}

/* A finger needs a bigger target than a mouse, and the measurement is the input
   device rather than the width (design doc section 8). Type size and spacing are
   untouched; only the hit areas grow. */
@media (pointer: coarse) {
    #CustomerPortalSetup .cps-row-control .k-input,
    #CustomerPortalSetup .cps-row-control .k-picker,
    #CustomerPortalSetup .cust-comp-btn-container .k-button,
    #CustomerPortalSetup .cust-comp-btn-container .k-button .k-button-text {
        min-height: 40px;
    }

    #CustomerPortalSetup .cust-comp-btn-container .k-button,
    #CustomerPortalSetup .cust-comp-btn-container .k-button .k-button-text {
        height: 40px;
        line-height: 40px;
    }

    /* Below 16px, iOS Safari zooms the page on focus and the user has to pinch
       back out after every field. */
    #CustomerPortalSetup .cps-row-control .k-input-inner,
    #CustomerPortalSetup .cps-row-control textarea {
        font-size: 16px;
    }
}

/* ---- Loan application configuration list -----------------------------------
   Drawn as the customer portal configuration list (#CustomerPortalSetup .cps-single),
   so the two setup lists read as one family. Its own ID rather than borrowing that
   one, because the component lives in the shared library and its markup should not
   depend on another screen's hooks. */
#LoanApplicationConfigurations .lac-single {
    padding-top: .5rem;
}

#LoanApplicationConfigurations .component-header .title {
    font-size: 16px;
}

#LoanApplicationConfigurations .component {
    background-color: var(--accent-1);
    border: 1px solid var(--accent-4);
    border-radius: 4px;
    box-shadow: var(--panel-shadow);
    color: var(--font-color-2);
    overflow: hidden;
}

#LoanApplicationConfigurations .component > .p-2 {
    padding: 0 !important;
}

#LoanApplicationConfigurations .lac-intro {
    margin: 0;
    padding: .4rem .55rem;
    border-bottom: 1px solid var(--hairline);
    font-size: 11.5px;
    color: var(--font-color-muted);
}

#LoanApplicationConfigurations .lac-config-link {
    color: var(--link-color);
    text-decoration: none;
    cursor: pointer;
}

    #LoanApplicationConfigurations .lac-config-link:hover {
        text-decoration: underline;
    }

#LoanApplicationConfigurations .cust-empty {
    padding: .25rem .55rem;
    font-size: 11px;
    color: var(--font-color-muted);
}
/* ============================================================================
   DARK MODE
   ----------------------------------------------------------------------------
   Opt-in, per user, from the profile menu in the left nav (Color Mode). The
   preference is saved server-side as "Color Mode" = Dark/Light and re-applied on
   load by UserService; `switchColorMode` in wwwroot/js/general.js sits between the
   two and only stamps `data-color-mode="dark"` on <html>. Everything below is what
   that stamp means.

   It used to write eleven custom properties onto :root's style attribute instead,
   which aged badly: the redesigned screens carry a token vocabulary the switch
   never heard of (--page-ground, --hairline, --row-alt, --row-hover, --tint-*,
   --link-color), so their grounds stayed light while --font-color-2 went pale.
   Moving it into the stylesheet buys three things: a token added to :root is one
   dark mode can answer, in the same place its light value lives; rules can reach
   Telerik's baked-in surfaces where an inline property never could (this app ships
   a compiled kendo theme with no --kendo-* colour variables); and
   `color-scheme: dark` becomes possible, which darkens the scrollbars, the
   browser-drawn form controls and the autofill tint in one declaration.

   `:root[data-color-mode="dark"]` is (0,2,0), so it beats the
   `:root { --color-1: … }` block UserService injects per company
   (vergent-lms-design.md §2) for any token it names. That matters for exactly one
   - see --affordance-color below; everything else a company themes is left alone
   so the shell stays branded in either mode.

   The iframe postMessage stays where it was: /classic ASPX pages and the customer
   tabs run their own colour mode. Nothing here reaches into them.
   ========================================================================= */

:root[data-color-mode="dark"] {
    /* Native UI - scrollbars, date pickers, autofill, form controls the browser
       draws itself. Without this they stay light no matter what the CSS says. */
    color-scheme: dark;

    /* ---- surfaces, darkest first ----
       Four steps, cool rather than neutral so they sit with the navy chrome: the ground a
       board sits on, the panel, the card, the button hover. The steps are deliberately
       small - on a dense screen the hairline borders do the separating. */
    --page-ground: #10161d;
    --accent-1: #1a2129;
    --accent-3: #1e2630;
    --accent-2: #2a3441;
    --accent-4: #3a4552;
    --background-color: #12181f;

    /* Lines and row states. --row-alt has to survive a long result set, so it
       keeps §2's "clearly stronger than hover" relationship. */
    --hairline: #2b3540;
    --row-hover: #232c36;
    --row-alt: #1f2833;

    /* ---- ink ----
       #e3e8ee on the panel is 12.8:1, the muted grey 6.9:1 - both hold at the
       11px the row primitives use, which is why neither is any dimmer. */
    --font-color-2: #e3e8ee;
    --font-color-muted: #98a5b5;

    /* ---- accents ----
       --header-bar lifts one step: at #0a2f4e a title bar and the near-black ground
       differ mostly in hue and the bars stop reading as bars. White on this is 11.2:1.

       --affordance-color is the one token overriding a company's theme (see the block
       comment): it is ink, the theme value is chosen against a white app, and a saved
       navy lands around 1.5:1 here. This blue is 7.4:1. */
    --header-bar: #143551;
    --header-bar-hover: #1b4a72;
    --affordance-color: #7fb2ef;
    --link-color: #7fb3ff;

    /* The tint family, inverted: a tint on white becomes a lift off the panel,
       and the hover keeps its direction so hovering a striped row still darkens
       it (HOME SCREEN / SEARCH blocks). */
    --tint-bg: #223243;
    --tint-border: #35506d;
    --tint-strong: #2c3b4c;
    --good-border: #2f5c46;
    --bad-border: #6d3833;
    --surface-mix: #1a2129;

    /* Status. Both lightened until they clear 4.5:1 on the panel - the light mode
       hexes are 2.6:1 and 3.1:1 there, and these two are the whole point of §6's
       colour budget, so they cannot be the least legible thing on the screen. */
    --success-color: #4fbd85;
    --warning-color: #f2796f;

    --selected-1: rgba(127, 178, 239, .25);
    --progressbar-chunk-color: #3a4552;


    /* A 6% black shadow is invisible on a dark ground and a board flattens into
       one field. Same geometry, enough alpha to read. */
    --panel-shadow: 0 1px 2px rgba(0, 0, 0, .45);
    --overlay-shadow: 0 6px 20px rgba(0, 0, 0, .55);
}

/* ---- the inherited near-black ----
   Bootstrap gives <body> #212529 and the kendo theme gives .k-form / .k-content #424242,
   both inherited by anything that sets no colour of its own. The redesigned screens name
   their colours, but a legacy screen - or one Telerik control sitting in a form - falls
   through. Naming the containers fixes the class, not one control. */
:root[data-color-mode="dark"] body,
:root[data-color-mode="dark"] .k-form,
:root[data-color-mode="dark"] .k-content,
:root[data-color-mode="dark"] .k-block,
:root[data-color-mode="dark"] .k-panel {
    color: var(--font-color-2);
}

/* ---- the customer header ----
   .header-light takes --accent-1, so it turns dark with the panels and the three things
   written against "this bar is white" have to follow.

   The name is the third: CustHeaderSummaryComp draws it in --color-2, the only place in
   the app a chrome colour is used as ink, which lands at 1.5:1 on a dark panel. In dark
   mode it is body ink at heading weight - not the affordance blue, since this is a
   heading and not a link. */
:root[data-color-mode="dark"] .header.header-light {
    box-shadow: 0 1px 3px rgba(0, 0, 0, .5);
}

    :root[data-color-mode="dark"] .cust-header-name {
        color: var(--font-color-2);
    }

    /* No ::deep here: Blazor compiles that pseudo away, so it only means anything in a
       .razor.css. In app.css it is an unknown selector and the browser drops the whole
       rule - hence the light rule this mirrors living in ComponentHeader.razor.css. */
    :root[data-color-mode="dark"] .header.header-light button.header-button:hover {
        background-color: rgba(255, 255, 255, .12);
    }

/* ---- comm preference chips ----
   The chip pair is the one control whose on state is a filled tint one step stronger than
   --tint-bg (§8), so it carries its own hexes in CustComPrefComp.razor.css rather than
   the token. Restated here for the §3 reason: this is ID-scoped and the component's
   scoped rule would lose to it anyway. */
:root[data-color-mode="dark"] #CustomerComponents .comm-pref-chip {
    background-color: var(--accent-1);
    border-color: var(--accent-4);
    color: var(--font-color-muted);
}

    :root[data-color-mode="dark"] #CustomerComponents .comm-pref-chip.is-in {
        background-color: #24405e;
        border-color: #3f6a9e;
        color: var(--font-color-2);
    }

/* ---- the legacy iframe ----
   .lms-iframe is hard-coded white because classic pages assume it. switchColorMode posts
   the mode change to every iframe and they repaint themselves, so the frame has to move
   with them or a dark classic page sits in a white box while it loads. */
:root[data-color-mode="dark"] .lms-iframe {
    background-color: var(--accent-1);
}

/* ============================================================================
   DARK MODE - TELERIK
   ----------------------------------------------------------------------------
   The theme in wwwroot/css/telerik/Vergent-Theme.css is a compiled kendo-default
   v6.4 with its colours baked in - 44 --kendo-* variables in the whole file and
   not one of them a colour - so every Telerik surface has to be named here. Below
   is the set that appears on the screens staff use. Anything not here still paints
   light, and that is the first thing to check when a control looks wrong.
   ========================================================================= */

/* ---- inputs and pickers ---- */
:root[data-color-mode="dark"] .k-input,
:root[data-color-mode="dark"] .k-picker,
:root[data-color-mode="dark"] .k-textbox,
:root[data-color-mode="dark"] .k-textarea,
:root[data-color-mode="dark"] .k-dropdownlist,
:root[data-color-mode="dark"] .k-combobox,
:root[data-color-mode="dark"] .k-multiselect,
:root[data-color-mode="dark"] .k-datepicker,
:root[data-color-mode="dark"] .k-datetimepicker,
:root[data-color-mode="dark"] .k-timepicker,
:root[data-color-mode="dark"] .k-numerictextbox {
    background-color: var(--accent-3);
    background-image: none;
    border-color: var(--accent-4);
    color: var(--font-color-2);
}

:root[data-color-mode="dark"] .k-input-inner,
:root[data-color-mode="dark"] .k-input-value-text,
:root[data-color-mode="dark"] .k-picker .k-input-inner {
    color: var(--font-color-2);
}

:root[data-color-mode="dark"] .k-input-inner::placeholder {
    color: var(--font-color-muted);
    opacity: 1;
}

:root[data-color-mode="dark"] .k-input-button,
:root[data-color-mode="dark"] .k-select {
    background-color: transparent;
    background-image: none;
    border-color: var(--accent-4);
    color: var(--font-color-2);
}

/* ---- popups: dropdown lists, menus, the calendar ----
   .k-animation-container is the wrapper Telerik appends to <body> for every
   popup, so it sits outside whatever ID block styles the screen underneath. */
:root[data-color-mode="dark"] .k-popup,
:root[data-color-mode="dark"] .k-list-container,
:root[data-color-mode="dark"] .k-menu-popup,
:root[data-color-mode="dark"] .k-calendar,
:root[data-color-mode="dark"] .k-calendar-header,
:root[data-color-mode="dark"] .k-datetime-container,
:root[data-color-mode="dark"] .k-time-container,
:root[data-color-mode="dark"] .k-animation-container .k-child-animation-container > * {
    background-color: var(--accent-1);
    border-color: var(--accent-4);
    color: var(--font-color-2);
}

:root[data-color-mode="dark"] .k-list,
:root[data-color-mode="dark"] .k-list-content,
:root[data-color-mode="dark"] .k-list-item,
:root[data-color-mode="dark"] .k-list-optionlabel,
:root[data-color-mode="dark"] .k-menu-item,
:root[data-color-mode="dark"] .k-calendar-td,
:root[data-color-mode="dark"] .k-calendar .k-link {
    background-color: transparent;
    color: var(--font-color-2);
}

:root[data-color-mode="dark"] .k-list-item:hover,
:root[data-color-mode="dark"] .k-list-item.k-hover,
:root[data-color-mode="dark"] .k-list-optionlabel:hover,
:root[data-color-mode="dark"] .k-menu-item:hover,
:root[data-color-mode="dark"] .k-calendar-td:hover .k-link {
    background-color: var(--row-hover);
    color: var(--font-color-2);
}

:root[data-color-mode="dark"] .k-list-item.k-selected,
:root[data-color-mode="dark"] .k-list-item.k-selected:hover,
:root[data-color-mode="dark"] .k-calendar .k-selected .k-link {
    background-color: var(--header-bar);
    color: var(--font-color-1);
}

/* ---- grids ----
   The heading row and the ID-scoped treatments already run on tokens; what is left is the
   chrome - wrapper, pager, cell borders, and the two Telerik states (.k-hover, .k-alt)
   the redesigned grids do not spell out themselves. */
:root[data-color-mode="dark"] .k-grid,
:root[data-color-mode="dark"] .k-grid-header,
:root[data-color-mode="dark"] .k-grid-content,
:root[data-color-mode="dark"] .k-grid-footer,
:root[data-color-mode="dark"] .k-grid-toolbar,
:root[data-color-mode="dark"] .k-pager {
    background-color: var(--accent-1);
    border-color: var(--accent-4);
    color: var(--font-color-2);
}

:root[data-color-mode="dark"] .k-grid td,
:root[data-color-mode="dark"] .k-grid th,
:root[data-color-mode="dark"] .k-grid .k-table-td,
:root[data-color-mode="dark"] .k-grid .k-table-th {
    border-color: var(--hairline);
}

:root[data-color-mode="dark"] .k-grid .k-table-row,
:root[data-color-mode="dark"] .k-grid tr {
    background-color: transparent;
}

:root[data-color-mode="dark"] .k-grid .k-table-alt-row,
:root[data-color-mode="dark"] .k-grid tr.k-alt {
    background-color: var(--row-alt);
}

:root[data-color-mode="dark"] .k-grid .k-table-row.k-hover,
:root[data-color-mode="dark"] .k-grid .k-table-row:hover {
    background-color: var(--tint-strong);
}

/* ---- dialogs, windows, tooltips, notifications ---- */
:root[data-color-mode="dark"] .k-dialog,
:root[data-color-mode="dark"] .k-window,
:root[data-color-mode="dark"] .k-dialog-content,
:root[data-color-mode="dark"] .k-window-content,
:root[data-color-mode="dark"] .k-dialog-actions,
:root[data-color-mode="dark"] .k-window-actions,
:root[data-color-mode="dark"] .k-actionsheet,
:root[data-color-mode="dark"] .k-notification,
:root[data-color-mode="dark"] .k-card,
:root[data-color-mode="dark"] .k-card-body {
    background-color: var(--accent-1);
    border-color: var(--accent-4);
    color: var(--font-color-2);
}

:root[data-color-mode="dark"] .k-overlay {
    background-color: rgba(0, 0, 0, .6);
}

/* The tooltip is a raised surface, not a panel: one step up so it reads off the
   panel it points at. The callout arrow takes currentColor (see the TOOLTIPS
   block), so it follows without a second rule. */
:root[data-color-mode="dark"] .k-tooltip {
    background-color: var(--accent-2);
    border-color: var(--accent-4);
    color: var(--font-color-2);
}

/* ---- tabs, panel bars, tree views ---- */
:root[data-color-mode="dark"] .k-tabstrip,
:root[data-color-mode="dark"] .k-tabstrip-content,
:root[data-color-mode="dark"] .k-tabstrip > .k-content,
:root[data-color-mode="dark"] .k-tabstrip-items-wrapper,
:root[data-color-mode="dark"] .k-panelbar,
:root[data-color-mode="dark"] .k-panelbar > .k-panelbar-item,
:root[data-color-mode="dark"] .k-treeview,
:root[data-color-mode="dark"] .k-toolbar,
:root[data-color-mode="dark"] .k-upload,
:root[data-color-mode="dark"] .k-upload-files {
    background-color: var(--accent-1);
    border-color: var(--accent-4);
    color: var(--font-color-2);
}

:root[data-color-mode="dark"] .k-tabstrip-items .k-item {
    background-color: transparent;
    color: var(--font-color-muted);
    border-color: var(--accent-4);
}

:root[data-color-mode="dark"] .k-tabstrip-items .k-item.k-active {
    background-color: var(--accent-1);
    color: var(--font-color-2);
}

/* ---- buttons ----
   Only the base (unthemed) button: the primary and solid-colour variants carry
   their own fills and read as well on a dark ground as a light one. */
:root[data-color-mode="dark"] .k-button-solid-base,
:root[data-color-mode="dark"] .k-button.k-button-solid-base {
    background-color: var(--accent-3);
    background-image: none;
    border-color: var(--accent-4);
    color: var(--font-color-2);
}

    :root[data-color-mode="dark"] .k-button-solid-base:hover,
    :root[data-color-mode="dark"] .k-button.k-button-solid-base:hover {
        background-color: var(--accent-2);
        color: var(--font-color-2);
    }

:root[data-color-mode="dark"] .k-checkbox,
:root[data-color-mode="dark"] .k-radio {
    background-color: var(--accent-3);
    border-color: var(--accent-4);
}

/* The loading veil takes the panel colour rather than the theme's white. */
:root[data-color-mode="dark"] .k-loading-mask .k-loading-color {
    background-color: var(--accent-1);
}
