/*
    KOREPART brand layer.

    The palette lives in the template SCSS (theme/scss/variables/variables.scss) and is compiled
    into app-assets/css. This file carries only what does not belong in the vendor stylesheet.

    Colours come from the logo package: #122620 brand green, #2F5D4A second green, #8FA79B pale
    green, #F3F6F4 light background. Type is Inter, the family the logo is drawn in.
*/

h1, h2, h3, h4, h5, h6,
.hp-brand-font,
.hp-authentication-page h1,
.hp-authentication-page h2,
.btn {
    font-family: "Inter", sans-serif;
    letter-spacing: 0.01em;
}

/* Figures line up in columns and 1 / 7 stay distinguishable in a VIN. */
table,
.hp-table,
.hp-amount,
input[type="number"] {
    font-variant-numeric: tabular-nums;
    font-feature-settings: "tnum" 1;
}

/* The second green as a solid button. */
.btn-brand {
    background-color: #2f5d4a;
    border-color: #2f5d4a;
    color: #122620;
}

.btn-brand:hover,
.btn-brand:focus {
    background-color: #2f5d4a;
    border-color: #2f5d4a;
    color: #ffffff;
}

/* The sign-in screen keeps the page light; the brand green carries the type. */
.hp-authentication-page h1 {
    color: #122620;
}

/*
    Frozen columns.

    The registry is wider than any screen, and scrolling right used to carry the VIN off the
    left edge — leaving a row of numbers with nothing to say which car they belong to. The
    identity columns (selection, photo, VIN) stay pinned to the left, the actions stay pinned
    to the right, and only the middle travels.

    Widths are pinned with min/max rather than width alone: once a table is wider than its
    container the browser falls back to min-content widths, and the sticky offsets below
    would no longer line up with the columns they belong to.

    Sticky cells need an opaque background of their own — the scrolled content passes
    underneath them.
*/
.hp-table-frozen {
    /* Sticky cells and collapsed borders do not agree in every browser. */
    border-collapse: separate;
    border-spacing: 0;

    /* The pinned block, as widths the offsets below are built from. A table without a
       selection column (the dealer's, which has nothing to select) zeroes the first one
       instead of repeating every offset. */
    --hp-freeze-select: 40px;
    --hp-freeze-photo: 64px;
}

.hp-table-frozen.hp-table-no-select {
    --hp-freeze-select: 0px;
}

.hp-table-frozen .hp-col-freeze,
.hp-table-frozen .hp-col-actions {
    position: sticky;
    z-index: 2;
    background-color: #ffffff;
}

/* The header keeps the template's own tint, or the pinned cells would read as a second row. */
.hp-table-frozen thead .hp-col-freeze,
.hp-table-frozen thead .hp-col-actions {
    z-index: 3;
    background-color: #f3f6f4;
}

body.dark .hp-table-frozen thead .hp-col-freeze,
body.dark .hp-table-frozen thead .hp-col-actions {
    background-color: #1f1f1f;
}

body.dark .hp-table-frozen .hp-col-freeze,
body.dark .hp-table-frozen .hp-col-actions {
    background-color: #141414;
}

.hp-table-frozen .hp-col-select {
    left: 0;
    width: var(--hp-freeze-select);
    min-width: var(--hp-freeze-select);
    max-width: var(--hp-freeze-select);
}

.hp-table-frozen .hp-col-photo {
    left: var(--hp-freeze-select);
    width: var(--hp-freeze-photo);
    min-width: var(--hp-freeze-photo);
    max-width: var(--hp-freeze-photo);
}

.hp-table-frozen .hp-col-vin {
    left: calc(var(--hp-freeze-select) + var(--hp-freeze-photo));
    width: 184px;
    min-width: 184px;
    max-width: 184px;
    white-space: nowrap;
}

.hp-table-frozen .hp-col-actions {
    right: 0;
    white-space: nowrap;
}

/*
    The seam that tells the reader a pinned block is covering something, not simply sitting
    next to it. It appears only while there is really something hidden on that side — the
    classes are set by the script on the list page — so a table that fits on screen shows no
    stray divider.
*/
.hp-scrolled-x .hp-table-frozen .hp-col-vin {
    box-shadow: 2px 0 4px rgba(18, 38, 32, 0.10);
}

.hp-scrollable-x .hp-table-frozen .hp-col-actions {
    box-shadow: -2px 0 4px rgba(18, 38, 32, 0.10);
}

body.dark .hp-scrolled-x .hp-table-frozen .hp-col-vin {
    box-shadow: 2px 0 4px rgba(0, 0, 0, 0.45);
}

body.dark .hp-scrollable-x .hp-table-frozen .hp-col-actions {
    box-shadow: -2px 0 4px rgba(0, 0, 0, 0.45);
}

/* Borders come back per cell, since the table no longer collapses them. */
.hp-table-frozen > :not(caption) > * > * {
    border-bottom: 1px solid var(--bs-border-color, rgba(18, 38, 32, 0.08));
}

/*
    Compact registry table.

    Twelve columns have to live inside the template's content width. Rather than pushing the
    page wider — which spreads the columns apart and makes a row hard to follow across the
    screen — the cells are tightened and text is allowed to wrap. A row grows downwards
    instead of the table growing sideways.

    Only the values that lose their meaning when broken stay on one line: a VIN, a container
    number, an amount, the action buttons.
*/
.hp-table-compact {
    font-size: 13px;
}

.hp-table-compact > :not(caption) > * > * {
    padding: 0.625rem 0.5rem;
}

/*
    Header labels line up.

    Left alone, a narrow column wraps its sort arrow onto a second line, the row grows, and
    the cells that still fit on one line get centred inside it — so half the headers sat
    lower than the other half. Headers stay on one line and rest on the same baseline; the
    columns they belong to are a few pixels wider for it, which costs nothing in a table that
    scrolls sideways anyway.
*/
.hp-table-compact thead th {
    font-size: 12px;
    line-height: 1.35;
    white-space: nowrap;
    vertical-align: bottom;
}

.hp-table-compact .hp-col-vin,
.hp-table-compact .hp-nowrap {
    white-space: nowrap;
}

/* Narrower than the default frozen block: the width is scarce here. */
.hp-table-frozen.hp-table-compact {
    --hp-freeze-select: 34px;
    --hp-freeze-photo: 56px;
}

.hp-table-frozen.hp-table-compact.hp-table-no-select {
    --hp-freeze-select: 0px;
}

.hp-table-frozen.hp-table-compact .hp-col-vin {
    width: 152px;
    min-width: 152px;
    max-width: 152px;
}

/* Columns that read better narrow than spread out. */
.hp-table-compact .hp-col-year {
    width: 64px;
    /* Wide enough that the sort arrow stays on the same line as the label. */
    white-space: nowrap;
}

.hp-table-compact .hp-col-status {
    width: 100px;
}

.hp-table-compact .hp-col-actions {
    width: 96px;
}

/*
    Photo gallery.

    The arrows sit on the picture itself, in both places a photo is shown: on the detail
    page, where flipping through the car should not require opening anything, and inside the
    viewer, where the picture fills the dialog and buttons under it would be far from the eye.

    The viewer's image is bounded by the viewport, not by its own pixels — a photo straight
    from a phone is several thousand pixels wide and would otherwise open far larger than the
    screen.
*/
.hp-gallery-nav {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    display: flex;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 36px;
    padding: 0;
    border: 0;
    border-radius: 50%;
    background-color: rgba(18, 38, 32, 0.55);
    color: #ffffff;
    font-size: 22px;
    line-height: 1;
    z-index: 2;
    transition: background-color 0.2s ease;
}

.hp-gallery-nav:hover,
.hp-gallery-nav:focus {
    background-color: rgba(18, 38, 32, 0.85);
    color: #ffffff;
}

.hp-gallery-nav-prev {
    left: 8px;
}

.hp-gallery-nav-next {
    right: 8px;
}

.hp-gallery-counter {
    position: absolute;
    right: 8px;
    bottom: 8px;
    padding: 2px 8px;
    border-radius: 12px;
    background-color: rgba(18, 38, 32, 0.55);
    color: #ffffff;
    font-size: 12px;
    line-height: 1.6;
}

.hp-viewer-image {
    max-width: 100%;
    max-height: 78vh;
    width: auto;
    object-fit: contain;
}

/*
    Brand logo.

    Sized here rather than through the template's .hp-logo: that rule lives in a stylesheet
    the sign-in and error layouts do not load, so the logo rendered there at its natural
    size — several hundred pixels tall.
*/
.hp-brand-logo {
    height: 48px;
    width: auto;
    max-width: 100%;
}

/* The sign-in screen is where the brand is actually looked at, so it gets more room. */
.hp-brand-logo-lg {
    height: 64px;
}

@media screen and (max-width: 575px) {
    .hp-brand-logo {
        height: 36px;
    }

    .hp-brand-logo-lg {
        height: 44px;
    }
}

/*
    Menu: the second green for hover and the section the user is in, underlined in it.
*/
.hp-horizontal-menu > ul > li > a:hover,
.hp-horizontal-menu > ul > li > a:focus {
    background: transparent;
    color: #2f5d4a;
}

.hp-horizontal-menu > ul > li > a:hover > i,
.hp-horizontal-menu > ul > li > a:focus > i {
    color: #2f5d4a;
}

.hp-horizontal-menu > ul > li > a.active {
    position: relative;
    background: transparent;
    color: #2f5d4a;
    font-weight: 500;
}

/* The mark under the section the user is in. */
.hp-horizontal-menu > ul > li > a.active::after {
    content: "";
    position: absolute;
    left: 12px;
    right: 12px;
    bottom: -6px;
    height: 2px;
    border-radius: 2px;
    background-color: #2f5d4a;
}

/* The drawer has no room for an underline; the colour alone marks the section. */
.offcanvas .hp-mobile-sidebar a:hover,
.offcanvas a.hp-p1-body:hover,
.offcanvas a.hp-p1-body.active {
    color: #2f5d4a;
}

.offcanvas a.hp-p1-body.active {
    font-weight: 500;
}

/*
    Empty validation summaries.

    The summary tag helper renders its box whether or not it has anything to say, and ours
    carries .alert-danger — so every form opened cleanly showed a red bar with nothing in it.
    Hidden while it holds no errors; jQuery swaps the class to validation-summary-errors the
    moment there is something to report, in the same place, so nothing is lost.
*/
.validation-summary-valid {
    display: none;
}

/*
    Page canvas.

    A green-grey a clear step behind the white cards, so the panels stand on the page
    instead of melting into it — with a white canvas, white bar and white cards the screen
    was one sheet of white.

    Light mode only — in the dark theme the same element carries the dark surface.
*/
body:not(.dark) main {
    background-color: #e9efeb !important;
}

/*
    Table toolbar.

    Reload, Export, Columns, Filters and Clear belong together, so they are drawn as one
    strip with hairlines between them instead of five separate buttons floating in a row.
    No overflow:hidden on the strip — the Columns menu has to escape it.
*/
.hp-toolbar {
    display: inline-flex;
    align-items: stretch;
    border: 1px solid #d8e2dc;
    border-radius: 8px;
    background-color: #ffffff;
}

.hp-toolbar > * + * {
    border-left: 1px solid #d8e2dc;
}

.hp-toolbar .btn {
    border-radius: 0;
    padding: 8px 14px;
    white-space: nowrap;
}

.hp-toolbar > *:first-child .btn,
.hp-toolbar > .btn:first-child {
    border-top-left-radius: 7px;
    border-bottom-left-radius: 7px;
}

.hp-toolbar > *:last-child .btn,
.hp-toolbar > .btn:last-child {
    border-top-right-radius: 7px;
    border-bottom-right-radius: 7px;
}

.hp-toolbar .btn:hover,
.hp-toolbar .btn:focus {
    background-color: #f3f6f4;
}

body.dark .hp-toolbar {
    border-color: #2f2f2f;
    background-color: #141414;
}

body.dark .hp-toolbar > * + * {
    border-left-color: #2f2f2f;
}

body.dark .hp-toolbar .btn:hover,
body.dark .hp-toolbar .btn:focus {
    background-color: #1f1f1f;
}

/* Narrow screens: the strip wraps as a block instead of overflowing the card. */
@media screen and (max-width: 575px) {
    .hp-toolbar {
        flex-wrap: wrap;
    }
}

/*
    Header and footer as their own surfaces.

    The header was transparent, so it took the colour of the page and the menu appeared to
    float over nothing. Header and footer are the same white the cards use, separated from
    the canvas by a hairline — the eye reads three clear layers: white chrome, green-grey
    page, white cards.

    Light mode only; the dark theme has its own surfaces for these.
*/
body:not(.dark) .hp-main-layout > header {
    background-color: #ffffff;
    border-bottom: 1px solid #dde6e1;
    /* The template rounds the header; as a full-width band it should meet both edges. */
    border-radius: 0;
}

body:not(.dark) .hp-main-layout > footer {
    background-color: #ffffff !important;
    border-top: 1px solid #dde6e1;
}

/* Cards get a hairline a shade darker than the canvas, so their edges stay crisp. */
body:not(.dark) .hp-bg-color-black-0 {
    border: 1px solid #dde6e1;
}

/*
    Row action menu — see row-menu.js for why it is not a Bootstrap dropdown.
*/
.hp-row-menu {
    position: relative;
    display: inline-block;
}

.hp-row-menu-items {
    position: fixed;
    z-index: 1080;
    min-width: 180px;
    padding: 6px 0;
    border: 1px solid #e3ebe6;
    border-radius: 8px;
    background-color: #ffffff;
    box-shadow: 0 8px 24px rgba(18, 38, 32, 0.12);
}

.hp-row-menu-items[hidden] {
    display: none;
}

.hp-row-menu-items a,
.hp-row-menu-items button {
    display: flex;
    align-items: center;
    gap: 8px;
    width: 100%;
    padding: 8px 14px;
    border: 0;
    background: none;
    text-align: left;
    font-size: 13px;
    color: #4f6359;
    white-space: nowrap;
}

.hp-row-menu-items a:hover,
.hp-row-menu-items button:hover {
    background-color: #f3f6f4;
    color: #122620;
}

.hp-row-menu-items .hp-row-menu-danger {
    color: #ff0022;
}

.hp-row-menu-items .hp-row-menu-danger:hover {
    background-color: #ffe7ea;
    color: #ff0022;
}

.hp-row-menu-items .divider {
    height: 1px;
    margin: 6px 0;
    background-color: #eaf1ed;
}

body.dark .hp-row-menu-items {
    border-color: #2f2f2f;
    background-color: #1f1f1f;
}

body.dark .hp-row-menu-items a:hover,
body.dark .hp-row-menu-items button:hover {
    background-color: #2a2a2a;
    color: #ffffff;
}

/*
    Header height.

    The template fixes it at 112px with 32px of padding underneath — room for a page title
    that used to sit inside the bar. Ours does not: the bar carries only the logo and the
    menu, so the space below them was empty. Now it wraps its contents.
*/
.hp-main-layout > header {
    height: auto;
    padding-top: 12px;
    padding-bottom: 12px;
}

/*
    The gap under the bar belonged to the header's own padding, which is why the page title
    ended up against it once that padding went. It belongs to the page anyway: every screen
    needs the same air below the bar, whatever the header is doing.

    The same is true at the other end: with only a hairline between the page and the footer,
    the last thing on a screen — a card, or a row of buttons that ends the form — sat
    directly on the footer line. The bottom is the wider of the two because the footer is a
    band rather than a bar: it needs to read as a separate strip, not as the end of the page.
*/
.hp-main-layout-content {
    padding-top: 28px;
    padding-bottom: 40px;
}

/*
    Password fields — the eye sits inside the field, see password-toggle.js.
*/
.hp-password-field {
    position: relative;
}

.hp-password-field .form-control {
    /* Room for the button, so a long password does not run underneath it. */
    padding-right: 42px;
}

.hp-password-toggle {
    position: absolute;
    top: 50%;
    right: 6px;
    transform: translateY(-50%);
    display: flex;
    align-items: center;
    justify-content: center;
    width: 30px;
    height: 30px;
    padding: 0;
    border: 0;
    border-radius: 6px;
    background: none;
    color: #8fa79b;
    font-size: 16px;
}

.hp-password-toggle:hover,
.hp-password-toggle:focus {
    background-color: #f3f6f4;
    color: #122620;
}

body.dark .hp-password-toggle:hover,
body.dark .hp-password-toggle:focus {
    background-color: #2a2a2a;
    color: #ffffff;
}

/*
    Pagination.

    The words stay — "Previous" and "Next" say plainly what they do. What made the block look
    oversized was the template's 16px of margin on each side of every link, which spread four
    items into a band the width of half the card.
*/
.pagination .page-link {
    margin: 0 3px;
    padding: 6px 12px;
}

/*
    Column guides.

    Twenty-odd columns of names, numbers and dates run together without something to follow
    downwards. The lines are deliberately lighter than the row borders: the row is still the
    thing being read, the columns are only kept apart.
*/
.hp-table-compact > :not(caption) > * > *:not(:last-child) {
    border-right: 1px solid rgba(18, 38, 32, 0.05);
}

body.dark .hp-table-compact > :not(caption) > * > *:not(:last-child) {
    border-right-color: rgba(255, 255, 255, 0.06);
}

/*
    Cards on narrow screens (specification 2.12).

    One site, one set of markup: the phone gets the same page as the desktop, laid out
    differently. A registry row is twenty-odd columns wide, and no amount of sideways
    scrolling makes that readable on a phone — the reader loses which row they are on the
    moment the identifying columns leave the screen. Below the breakpoint each row becomes a
    card instead: the picture, the VIN and the actions across the top, then one line per
    value with its own label.

    The labels come from the header cells (see table-cards.js), so a column added to the
    table is labelled here without a second list to maintain.

    The breakpoint is Bootstrap's md line. Above it a table still reads as a table, and
    turning a laptop into a column of cards would waste the width it has.
*/
@media screen and (max-width: 767.98px) {
    /* The row menu opens downwards out of a card, so nothing may clip it any more. */
    .hp-cards {
        overflow: visible;
    }

    .hp-cards table,
    .hp-cards tbody,
    .hp-cards tr,
    .hp-cards td {
        display: block;
        width: auto;
    }

    /* The header is what the labels were taken from; on screen it has nothing left to do. */
    .hp-cards thead {
        display: none;
    }

    .hp-cards tbody tr {
        display: flex;
        flex-wrap: wrap;
        align-items: center;
        gap: 0 8px;
        padding: 12px;
        margin-bottom: 12px;
        border: 1px solid rgba(18, 38, 32, 0.10);
        border-radius: 8px;
        background-color: #ffffff;
    }

    body.dark .hp-cards tbody tr {
        border-color: rgba(255, 255, 255, 0.12);
        background-color: #141414;
    }

    /*
        Every cell that is not part of the card's head takes a line of its own: the label it
        was given on the left, the value on the right.
    */
    .hp-cards tbody td {
        /* After the head of the card, whatever the column order in the table is. */
        order: 1;
        flex: 0 0 100%;
        display: flex;
        align-items: baseline;
        justify-content: space-between;
        gap: 16px;
        padding: 6px 0;
        text-align: right;
        border-right: 0;
        border-bottom: 1px solid rgba(18, 38, 32, 0.06);
    }

    body.dark .hp-cards tbody td {
        border-bottom-color: rgba(255, 255, 255, 0.08);
    }

    .hp-cards tbody td:last-child {
        border-bottom: 0;
    }

    /*
        Values wrap here, whatever they are.

        On a wide table a container number or a date is kept on one line so it stays
        readable across the columns. In a card there are no columns to cross, and one long
        value that refuses to break makes the whole document wider than the phone — every
        other line on the page then sits cut off at the right edge, which is exactly what
        the card view was meant to end.
    */
    .hp-cards tbody td,
    .hp-cards .hp-table-compact .hp-nowrap {
        min-width: 0;
        white-space: normal;
        overflow-wrap: anywhere;
    }

    .hp-cards tbody td[data-label]::before {
        content: attr(data-label);
        flex: 0 0 auto;
        text-align: left;
        font-size: 12px;
        color: rgba(18, 38, 32, 0.6);
    }

    body.dark .hp-cards tbody td[data-label]::before {
        color: rgba(255, 255, 255, 0.6);
    }

    /*
        The head of the card: what the row is, and what can be done to it. These sit on one
        line and are the only cells whose width is their content's — the pinned widths they
        carry on wide screens would otherwise hold a card open at 184px of VIN and nothing
        else.

        A registry row is headed by its VIN; any other table names the cell that heads its
        card with hp-col-title.
    */
    .hp-cards tbody td.hp-col-select,
    .hp-cards tbody td.hp-col-photo,
    .hp-cards tbody td.hp-col-vin,
    .hp-cards tbody td.hp-col-title,
    .hp-cards tbody td.hp-col-actions {
        /* The head of the card comes first even though the actions cell is last in the row. */
        order: 0;
        flex: 0 0 auto;
        width: auto;
        min-width: 0;
        max-width: none;
        padding: 0 0 8px 0;
        border-bottom: 0;
        /* Sticky belongs to the scrolling table; here it would pin cells inside a card. */
        position: static;
        box-shadow: none;
    }

    .hp-cards tbody td.hp-col-vin,
    .hp-cards tbody td.hp-col-title {
        /* Takes what is left rather than what it needs: sized to its content, a seventeen
           character VIN fills the line and pushes the actions button onto one of its own. */
        flex: 1 1 0;
        min-width: 0;
        font-size: 15px;
        font-weight: 600;
        text-align: left;
    }

    /* Pushed to the far end of the line, whether or not the table has a selection column. */
    .hp-cards tbody td.hp-col-actions {
        margin-left: auto;
    }

    /* A card is read at arm's length, not leaned into. */
    .hp-cards .hp-table-compact {
        font-size: 14px;
    }

    /*
        The sort list, standing in for the header links that are no longer on screen.
        Built by table-cards.js; laid out here so it matches the toolbar above it.
    */
    .hp-cards-sort {
        display: flex;
        align-items: center;
        gap: 8px;
        margin-bottom: 16px;
    }

    .hp-cards-sort label {
        white-space: nowrap;
    }

    .hp-cards-sort select {
        flex: 1 1 auto;
    }
}

/* Above the breakpoint the table sorts from its own headers and the list is redundant. */
@media screen and (min-width: 768px) {
    .hp-cards-sort {
        display: none;
    }
}

/*
    Switch and its label.

    The template does not style the checkbox at all — it hides it and draws the switch as
    two pseudo-elements on the label, which is itself a flex row: the pill is ::before, the
    words are the text node next to it. Nothing separated the two, so they touched.

    The gap therefore belongs to the label, not to the box around it. Rules aimed at the
    input do nothing here, because the input is display:none.
*/
.form-switch .form-check-label {
    gap: 10px;
    align-items: center;
}

/*
    Searchable dropdowns (assets/js/searchable-select.js).

    The control and the menu borrow the template's form-select, form-control and
    dropdown-menu, so both themes already look right; this caps the menu's height and lays
    the real select, invisible, over the button.
*/
.hp-search-select {
    position: relative;
}

.hp-search-select > .form-select {
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
}

/* Still there for the form, validation and the browser's "please select" bubble; clicks
   pass through it to the button underneath. */
.hp-search-select > .hp-search-select-native {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    opacity: 0;
    pointer-events: none;
}

.hp-search-select-placeholder {
    color: var(--bs-secondary-color, #5f716a);
}

/* Placed by the script against the window (see there); only the padding is fixed. */
.hp-search-select-menu {
    position: fixed;
    padding: 8px;
}

/* The dark theme turns dropdown text white but leaves the menu's surface to a utility
   class; without this the items are white on white. Same surface as the cards. */
body.dark .hp-search-select-menu {
    background-color: #141414;
}

.hp-search-select-menu .form-control:not(.d-none) + .hp-search-select-list {
    margin-top: 8px;
}

.hp-search-select-list {
    max-height: 240px;
    overflow-y: auto;
    outline: none;
}

.hp-search-select-list .dropdown-item {
    border-radius: 6px;
    white-space: normal;
}

.hp-search-select-list .hp-search-select-focus:not(.active) {
    background-color: #f3f6f4;
}

body.dark .hp-search-select-list .hp-search-select-focus:not(.active) {
    background-color: #1f1f1f;
}

/* ------------------------------------------------------------------------------------------
   KOREPART screens
   ------------------------------------------------------------------------------------------ */

/* Status and payment badges: text on a pale tint of itself, colours set per badge. */
.kp-badge {
    display: inline-block;
    padding: 4px 8px;
    border-radius: 6px;
    font-size: 12px;
    line-height: 14px;
    font-weight: 500;
    white-space: nowrap;
}

/* Dashboard status tiles: a whole tile is the link to the filtered list. */
.kp-stat {
    display: block;
    height: 100%;
    padding: 18px 20px;
    border-radius: 10px;
    background-color: #ffffff;
    border: 1px solid #e3ebe6;
    color: inherit;
    transition: border-color .15s ease, box-shadow .15s ease;
}

.kp-stat:hover {
    border-color: #8fa79b;
    box-shadow: 0 4px 14px rgba(18, 38, 32, 0.08);
    color: inherit;
}

.kp-stat-value {
    font-size: 26px;
    line-height: 32px;
    font-weight: 600;
    color: #122620;
}

.kp-stat-dot {
    display: inline-block;
    width: 8px;
    height: 8px;
    border-radius: 50%;
    margin-right: 6px;
}

/* The brand band at the top of the dashboard — the second green, so it does not merge
   with the bar in the logo green right above it. */
.kp-hero {
    background: linear-gradient(135deg, #2f5d4a 0%, #244a3b 100%);
    color: #ffffff;
    border-radius: 12px;
    padding: 24px 28px;
}

.kp-hero .kp-hero-label {
    color: #c5d6cd;
    font-size: 12px;
    text-transform: uppercase;
    letter-spacing: .08em;
}

.kp-hero .kp-hero-value {
    font-size: 28px;
    line-height: 34px;
    font-weight: 600;
    color: #ffffff;
}

/* Status trail on the request card. */
.kp-timeline {
    list-style: none;
    margin: 0;
    padding: 0 0 0 18px;
    border-left: 2px solid #e3ebe6;
}

.kp-timeline li {
    position: relative;
    padding: 0 0 18px 12px;
}

.kp-timeline li::before {
    content: "";
    position: absolute;
    left: -25px;
    top: 4px;
    width: 12px;
    height: 12px;
    border-radius: 50%;
    background: #ffffff;
    border: 2px solid #2f5d4a;
}

.kp-timeline li:first-child::before {
    background: #2f5d4a;
}

.kp-timeline li.kp-back::before {
    border-color: #b3261e;
}

/* Label / value pairs on the cards. */
.kp-facts {
    display: grid;
    grid-template-columns: minmax(120px, 38%) 1fr;
    gap: 10px 16px;
    margin: 0;
}

.kp-facts dt {
    font-weight: 400;
    color: #5f716a;
    font-size: 13px;
}

.kp-facts dd {
    margin: 0;
    font-weight: 500;
    overflow-wrap: anywhere;
}

/* Calculator: the result column stays in view while the inputs are edited. */
.kp-calc-result {
    position: sticky;
    top: 16px;
}

.kp-calc-line {
    display: flex;
    justify-content: space-between;
    gap: 12px;
    padding: 8px 0;
    border-bottom: 1px dashed #d8e2dc;
    font-variant-numeric: tabular-nums;
}

.kp-calc-line:last-child {
    border-bottom: 0;
}

.kp-calc-final {
    background: #122620;
    color: #ffffff;
    border-radius: 10px;
    padding: 16px 20px;
}

.kp-calc-final .kp-calc-price {
    font-size: 34px;
    line-height: 40px;
    font-weight: 700;
}

.kp-customer-text {
    white-space: pre-wrap;
    font-family: "Inter", sans-serif;
    background: #f3f6f4;
    border: 1px solid #d8e2dc;
    border-radius: 8px;
    padding: 12px 14px;
    margin: 0;
}

/* Photo grid for attachments. */
.kp-files {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
    gap: 12px;
}

.kp-file {
    position: relative;
    border: 1px solid #e3ebe6;
    border-radius: 8px;
    overflow: hidden;
    background: #f3f6f4;
}

.kp-file img {
    display: block;
    width: 100%;
    height: 110px;
    object-fit: cover;
}

.kp-file .kp-file-doc {
    display: flex;
    align-items: center;
    justify-content: center;
    height: 110px;
    font-size: 36px;
    color: #2f5d4a;
}

.kp-file .kp-file-meta {
    padding: 6px 8px;
    font-size: 11px;
    line-height: 14px;
    background: #ffffff;
}

.kp-file form {
    position: absolute;
    top: 4px;
    right: 4px;
}

.kp-file form .btn {
    background: rgba(255, 255, 255, 0.9);
    padding: 2px 6px;
    line-height: 1;
}

/* Suggestions from the part archive, under the new-request form. */
.kp-suggestion {
    border: 1px solid #d8e2dc;
    border-radius: 8px;
    padding: 10px 12px;
    background: #ffffff;
    cursor: pointer;
}

.kp-suggestion:hover {
    border-color: #2f5d4a;
    background: #f3f6f4;
}

.kp-suggestion code {
    color: #122620;
    font-weight: 600;
    font-size: 14px;
}

.kp-found {
    border-left: 4px solid #2f5d4a;
    background: #eaf1ed;
    border-radius: 6px;
    padding: 10px 14px;
}

/* A row that has been waiting too long. */
.kp-late {
    color: #b3261e;
    font-weight: 600;
}

.kp-muted {
    color: #5f716a;
}

.kp-section-title {
    font-size: 12px;
    text-transform: uppercase;
    letter-spacing: .06em;
    color: #5f716a;
    margin-bottom: 12px;
}

.kp-bar {
    height: 8px;
    border-radius: 4px;
    background: #e3ebe6;
    overflow: hidden;
}

.kp-bar > span {
    display: block;
    height: 100%;
    background: #2f5d4a;
}
