/* ═══════════════════════════════════════════════════════════════
   PayrollManagementSystem — Shared Application Styles
   Design tokens, page shells, table patterns, form patterns,
   badge variants, action buttons. Loaded globally via _Layout.
   ═══════════════════════════════════════════════════════════════ */

/* ── Design Tokens ─────────────────────────────────────────── */
:root {
    --color-brand:        #2a4365;
    --color-brand-dark:   #1a365d;
    --color-brand-light:  #ebf4ff;
    --color-success:      #38a169;
    --color-danger:       #e53e3e;
    --color-warning:      #d69e2e;
    --color-info:         #3182ce;
    --color-muted:        #718096;
    --color-surface:      #ffffff;
    --color-bg:           #f4f6fa;
    --color-border:       #e2e8f0;
    --color-text:         #2d3748;
    --color-text-light:   #718096;
    --radius-sm:          6px;
    --radius-md:          10px;
    --radius-lg:          14px;
    --shadow-sm:          0 1px 3px rgba(0,0,0,0.08);
    --shadow-md:          0 4px 12px rgba(0,0,0,0.10);
    --shadow-lg:          0 8px 24px rgba(0,0,0,0.12);
}

/* ── Page Shell ─────────────────────────────────────────────── */
.page-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 1.25rem;
    flex-wrap: wrap;
    gap: 0.75rem;
}
.page-header-left h4,
.page-header-left h5 {
    font-weight: 700;
    color: var(--color-text);
    margin-bottom: 0;
}
.page-header-left .page-subtitle {
    font-size: 0.78rem;
    color: var(--color-text-light);
    margin-top: 2px;
}
.page-actions { display: flex; gap: 0.5rem; flex-wrap: wrap; align-items: center; }

/* ── Breadcrumb ─────────────────────────────────────────────── */
.page-breadcrumb {
    font-size: 0.75rem;
    color: var(--color-muted);
    margin-bottom: 1.25rem;
    display: flex;
    align-items: center;
    gap: 0.35rem;
}
.page-breadcrumb a { color: var(--color-info); text-decoration: none; }
.page-breadcrumb a:hover { text-decoration: underline; }
.page-breadcrumb .sep { color: #cbd5e0; }
.page-breadcrumb .current { color: var(--color-text); font-weight: 500; }

/* ── Cards ──────────────────────────────────────────────────── */
.pms-card {
    background: var(--color-surface);
    border-radius: var(--radius-md);
    border: 1px solid var(--color-border);
    box-shadow: var(--shadow-sm);
    overflow: hidden;
}
.pms-card-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0.75rem 1.1rem;
    border-bottom: 1px solid var(--color-border);
    background: #f8fafc;
}
.pms-card-header-title {
    font-size: 0.78rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.07em;
    color: var(--color-muted);
    display: flex;
    align-items: center;
    gap: 0.4rem;
}
.pms-card-body { padding: 1.1rem; }

/* ── KPI Cards ──────────────────────────────────────────────── */
/* KPI cards share the dashboard tile's skin (spine, radius, shadow, tabular figures) so every
   summary strip in the app reads as one family without each screen being rewritten. */
.kpi-card {
    position: relative;
    background: var(--color-surface);
    border-radius: var(--radius-md);
    border: 1px solid var(--color-border);
    box-shadow: var(--shadow-sm);
    padding: 0.9rem 1rem 0.9rem 1.15rem;
    display: flex;
    align-items: center;
    gap: 0.85rem;
    overflow: hidden;
    transition: transform 0.15s, box-shadow 0.15s;
}
.kpi-card::before { content: ""; position: absolute; top: 0; bottom: 0; left: 0; width: 4px; background: var(--color-border); }
.kpi-card:hover { transform: translateY(-2px); box-shadow: var(--shadow-md); }
.kpi-icon {
    width: 36px; height: 36px; border-radius: 9px;
    display: flex; align-items: center; justify-content: center;
    font-size: 1.05rem; flex-shrink: 0;
}
.kpi-label  { font-size: 0.62rem; font-weight: 800; text-transform: uppercase; letter-spacing: 0.09em; color: var(--color-muted); }
.kpi-value  { font-size: 1.6rem; font-weight: 700; line-height: 1.1; color: var(--color-text); font-variant-numeric: tabular-nums; letter-spacing: -0.01em; }
.kpi-sub    { font-size: 0.7rem; color: var(--color-muted); margin-top: 2px; }

/* ── Filter Bar ─────────────────────────────────────────────── */
.filter-bar {
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    padding: 0.6rem 0.75rem;
    margin-bottom: 0.75rem;
    box-shadow: none;
}
.validation-summary-valid { display: none; }
.field-validation-valid { display: none; }
.filter-bar-form {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem;
}
.filter-bar-form .form-control,
.filter-bar-form .form-select {
    width: auto;
    flex: 0 1 auto;
    height: 36px;
    font-size: 0.875rem;
}
.filter-bar .filter-label {
    font-size: 0.7rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.07em;
    color: var(--color-muted);
    margin-bottom: 0.6rem;
    display: flex;
    align-items: center;
    gap: 0.35rem;
}

/* ── Links ──────────────────────────────────────────────────────
   Nothing styled a plain link, so every one fell back to Bootstrap's #0d6efd — a blue that appears
   nowhere else in this palette, which is why an ordinary link read as foreign against the navy.
   Brand colour, and an underline that is quiet until you point at it. Anything already dressed as a
   button, badge, tab or chip is left alone, as are links inside alerts, which have their own colour
   against a coloured ground. */
/* Links inside the page body take the brand colour - EXCEPT anything that paints its own.
   That exception list grew one component at a time (receipts, segment toggles, document cards...)
   and each addition was discovered the same way: a link rendered invisible against its own
   background, because this rule's specificity - one class plus a dozen :not()s - beats any
   component's own colour. `.link-own-colour` is the general hook: put it on a link that supplies its
   own colour and this rule stands aside, with no further edits here. Prefer it to a new :not(). */
.page-content a:not([class*="btn"]):not([class*="pms-badge"]):not([class*="setup-"]):not([class*="dt-"]):not(.emp-tab):not(.nav-link):not(.page-link):not(.alert-link):not(.pms-receipt):not(.seg > a):not(.doc-link):not(.link-own-colour) {
    color: var(--color-brand);
    text-decoration-color: rgba(42, 67, 101, 0.3);
    text-underline-offset: 2px;
}
.page-content a:not([class*="btn"]):not([class*="pms-badge"]):not([class*="setup-"]):not([class*="dt-"]):not(.emp-tab):not(.nav-link):not(.page-link):not(.alert-link):not(.pms-receipt):not(.seg > a):not(.doc-link):not(.link-own-colour):hover {
    color: var(--color-brand-dark);
    text-decoration-color: currentColor;
}

/* ── Tables ─────────────────────────────────────────────────── */
.pms-table-wrap {
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-sm);
    overflow: visible;
}
/* Horizontal scroll on narrow screens — applied only when the wrapper
   actually holds a table. Card-style usages of .pms-table-wrap keep
   overflow:visible so sticky side panels etc. inside them still work.
   Dropdown menus inside these scroll containers are repositioned with
   Popper's fixed strategy by site.js so they are not clipped. */
.pms-table-wrap:has(> .pms-table),
.pms-table-wrap:has(> table) {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
}
/* Same protection for tables placed directly inside a .pms-card */
.pms-card:has(> .pms-table),
.pms-card:has(> table) {
    overflow-x: auto;
}
/* Keep the thead corners clipped inside the rounded card */
.pms-table thead tr:first-child th:first-child { border-top-left-radius: var(--radius-md); }
.pms-table thead tr:first-child th:last-child  { border-top-right-radius: var(--radius-md); }
.pms-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 0.875rem;
}
/* A row-selection checkbox sits alone in a narrow column with nothing beside it, and Bootstrap's
   default border (rgba(0,0,0,.25)) all but disappears there. Bigger, and a border you can actually
   see, so a selectable row reads as selectable. */
.pms-table .pms-check {
    width: 1.05rem;
    height: 1.05rem;
    margin-top: 0;
    border: 1.5px solid #94a3b8;
    cursor: pointer;
}
.pms-table .pms-check:hover { border-color: var(--color-brand); }
.pms-table .pms-check:checked { background-color: var(--color-brand); border-color: var(--color-brand); }
.pms-table thead th {
    background: #f8fafc;
    color: var(--color-muted);
    font-size: 0.7rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.07em;
    padding: 0.6rem 0.9rem;
    border-bottom: 1px solid var(--color-border);
    white-space: nowrap;
}
.pms-table tbody td {
    padding: 0.7rem 0.9rem;
    border-bottom: 1px solid #f1f5f9;
    color: var(--color-text);
    vertical-align: middle;
}
.pms-table tbody tr:last-child td { border-bottom: none; }
.pms-table tbody tr:hover td { background: #f8fafc; }
.pms-table tbody tr[data-href] { cursor: pointer; }
.pms-table tbody tr[data-href]:hover td { background: #eef2ff; }
.pms-table .td-actions { white-space: nowrap; text-align: right; }

/* Row state tints — Bootstrap's table-danger/table-warning only work on .table,
   so .pms-table gets its own equivalents. */
.pms-table tbody tr.row-danger td        { background: #fff5f5; }
.pms-table tbody tr.row-danger:hover td  { background: #ffe9e9; }
.pms-table tbody tr.row-warning td       { background: #fffbeb; }
.pms-table tbody tr.row-warning:hover td { background: #fdf3d3; }
.pms-table tbody tr.row-success td       { background: #f0fff4; }
.pms-table tbody tr.row-success:hover td { background: #e2f8e9; }

/* ── Stacked card mode for tables on phones ──────────────────
   Opt-in per table: <table class="pms-table pms-table-stack">
   plus data-label="Column name" on each td. Cell roles:
     .td-primary    → card title (tap toggles hidden details)
     .td-stack-more → hidden on phones until the row is expanded
     .td-actions    → rendered as the card footer
   Desktop rendering is completely unchanged; below 768px each
   row becomes a vertical card readable top-to-bottom. */
@media (max-width: 767.98px) {
    .pms-table.pms-table-stack thead { display: none; }
    .pms-table.pms-table-stack tfoot { display: none; }
    .pms-table.pms-table-stack,
    .pms-table.pms-table-stack tbody,
    .pms-table.pms-table-stack tbody tr,
    .pms-table.pms-table-stack tbody td { display: block; width: 100%; }

    /* An inline min-width (set so the table stays readable on desktop) survives the switch to
       display:block and holds the card stack open at its desktop width, so the phone gets a
       sideways-scrolling table instead of cards — the stack silently does nothing. Most stacked
       tables never set one and work by luck rather than design; neutralise it here so the opt-in
       class is sufficient on its own and no view has to remember. */
    .pms-table.pms-table-stack { min-width: 0 !important; }

    /* The outer panel chrome disappears on phones — cards sit directly
       on the page background instead of "cards inside a panel".
       (!important beats Bootstrap's .shadow-sm utility.) */
    .pms-table-wrap:has(> .pms-table-stack),
    .card:has(> .pms-table-stack) {
        background: transparent;
        border: none;
        box-shadow: none !important;
        overflow: visible;
    }
    .pms-table-wrap:has(> .pms-table-stack) > .pms-pagination {
        background: var(--color-surface);
        border: 1px solid var(--color-border);
        border-radius: var(--radius-md);
        box-shadow: var(--shadow-sm);
        margin-top: 0.25rem;
    }

    .pms-table.pms-table-stack tbody tr {
        display: flex;
        flex-direction: column;
        border: 1px solid var(--color-border);
        border-left: 3px solid #4e8ef7;
        border-radius: var(--radius-md);
        background: var(--color-surface);
        box-shadow: 0 1px 3px rgba(15,23,42,0.06), 0 4px 14px rgba(15,23,42,0.05);
        margin: 0 0 0.85rem;
        width: auto;
        overflow: hidden;
    }
    /* Accent follows row state */
    .pms-table.pms-table-stack tbody tr.row-danger   { border-left-color: var(--color-danger); }
    .pms-table.pms-table-stack tbody tr.row-warning  { border-left-color: var(--color-warning); }
    .pms-table.pms-table-stack tbody tr.row-inactive { border-left-color: #cbd5e0; }
    /* Title always first, actions always last, whatever the column order */
    .pms-table.pms-table-stack td.td-primary { order: -1; }
    .pms-table.pms-table-stack td.td-actions { order: 99; }
    .pms-table.pms-table-stack tbody tr:hover td { background: inherit; }
    .pms-table.pms-table-stack tbody td {
        display: flex;
        justify-content: space-between;
        align-items: baseline;
        gap: 1rem;
        border-bottom: 1px solid #f4f6fa;
        padding: 0.55rem 1rem;
        text-align: right;
        white-space: normal;
    }
    .pms-table.pms-table-stack tbody td::before {
        content: attr(data-label);
        font-size: 0.66rem;
        font-weight: 700;
        text-transform: uppercase;
        letter-spacing: 0.07em;
        color: #94a3b8;
        text-align: left;
        flex-shrink: 0;
        padding-top: 2px;
    }
    .pms-table.pms-table-stack tbody td:not([data-label])::before { content: none; }
    .pms-table.pms-table-stack tbody tr td:last-child { border-bottom: none; }
    /* Card title bar — brand accent strip + soft tinted background.
       display:block (not flex) so multi-line content (name + code + email)
       stacks naturally; the expand chevron is absolutely positioned. */
    .pms-table.pms-table-stack td.td-primary {
        display: block;
        position: relative;
        text-align: left;
        background: linear-gradient(180deg, #f6f9ff 0%, #eef4fd 100%);
        border-bottom: 1px solid var(--color-border);
        font-weight: 700;
        font-size: 0.95rem;
        color: var(--color-brand);
        padding: 0.7rem 1rem;
    }
    .pms-table.pms-table-stack tbody tr:has(td.td-stack-more) td.td-primary { padding-right: 2.6rem; }
    /* Mobile-only status chip in the title bar (add .stack-status.d-md-none to a badge) */
    .pms-table.pms-table-stack td.td-primary .stack-status {
        float: right;
        margin-left: 0.5rem;
        font-size: 0.6rem;
        padding: 0.15rem 0.45rem;
    }
    /* Actions footer — larger touch targets, comfortable spacing */
    .pms-table.pms-table-stack td.td-actions {
        justify-content: flex-end;
        align-items: center;
        flex-wrap: wrap;
        gap: 0.45rem;
        background: #fafbfd;
        border-top: 1px solid var(--color-border);
        padding: 0.6rem 1rem;
    }
    .pms-table.pms-table-stack td.td-actions .btn-action {
        padding: 0.45rem 0.8rem;
        font-size: 0.8rem;
    }
    .pms-table.pms-table-stack td.td-stack-more { display: none; }
    .pms-table.pms-table-stack tr.stack-expanded td.td-stack-more { display: flex; }
    /* chevron hint when a row has hidden details */
    .pms-table.pms-table-stack tbody tr:has(td.td-stack-more) td.td-primary::after {
        content: "▾";
        position: absolute;
        right: 0.8rem;
        top: 50%;
        width: 1.35rem;
        height: 1.35rem;
        display: inline-flex;
        align-items: center;
        justify-content: center;
        border-radius: 50%;
        background: rgba(78,142,247,0.12);
        color: #4e8ef7;
        font-size: 0.8rem;
        font-weight: 400;
        transform: translateY(-50%);
        transition: transform 0.15s;
    }
    .pms-table.pms-table-stack tbody tr.stack-expanded:has(td.td-stack-more) td.td-primary::after {
        transform: translateY(-50%) rotate(180deg);
    }
    /* full-width informational rows (empty states etc.) */
    .pms-table.pms-table-stack tbody td[colspan] { display: block; text-align: center; }

    /* ── Compact variant: add .pms-stack-compact to the table ──
       Detail cells pack TWO per row with the label above the value,
       and a Select checkbox cell joins the title bar — much denser
       than the default one-line-per-column layout. */
    .pms-table.pms-stack-compact tbody tr {
        flex-direction: row;
        flex-wrap: wrap;
        position: relative;
    }
    .pms-table.pms-stack-compact tbody td {
        flex-direction: row;
        align-items: baseline;
        justify-content: flex-start;
        text-align: left;
        gap: 0.6rem;
        flex: 1 1 100%;
        width: auto;
        min-width: 0;
        word-break: break-word;
        border-bottom: 1px solid #f4f6fa;
        padding: 0.45rem 1rem;
    }
    .pms-table.pms-stack-compact tbody td::before { padding-top: 0; min-width: 5.2rem; }
    .pms-table.pms-stack-compact td.td-primary { padding-top: 0.55rem; padding-bottom: 0.55rem; }
    .pms-table.pms-stack-compact td.td-actions { padding-top: 0.45rem; padding-bottom: 0.45rem; }
    .pms-table.pms-stack-compact td.td-primary,
    .pms-table.pms-stack-compact td.td-actions,
    .pms-table.pms-stack-compact td.td-stack-full,
    .pms-table.pms-stack-compact tbody td[colspan] { flex: 1 1 100%; width: auto; }
    .pms-table.pms-stack-compact td.td-actions { flex-direction: row; }

    /* Compact mode never expands: secondary (.td-stack-more) cells stay
       hidden on phones — their data lives on the record's details page.
       No chevron, no rail; cards are pure at-a-glance rows. */
    .pms-table.pms-stack-compact td.td-stack-more { display: none !important; }
    .pms-table.pms-stack-compact tbody tr:has(td.td-stack-more) td.td-primary { padding-right: 1rem; }
    .pms-table.pms-stack-compact tbody tr:has(td.td-stack-more) td.td-primary::after { content: none; }

    /* Navigation variant: add .pms-stack-nav when rows navigate (data-href).
       The whole card is tappable and shows a right-edge "go" rail. */
    .pms-table.pms-stack-nav tbody tr[data-href] { padding-right: 1.7rem; }
    .pms-table.pms-stack-nav tbody tr[data-href]::after {
        content: "›";
        position: absolute;
        right: 0.55rem;
        top: 50%;
        transform: translateY(-50%);
        color: #94a3b8;
        font-size: 1.25rem;
        font-weight: 600;
    }
    /* Navigation cards: the whole card is the action — hide the button
       footer on phones (everything lives on the details page it opens). */
    .pms-table.pms-stack-nav td.td-actions { display: none; }
    /* Select checkbox joins the title bar instead of taking its own row */
    .pms-table.pms-stack-compact td[data-label="Select"] {
        order: -1;
        width: auto;
        flex: 0 0 auto;
        flex-direction: row;
        align-items: center;
        background: linear-gradient(180deg, #f6f9ff 0%, #eef4fd 100%);
        border-bottom: 1px solid var(--color-border);
        padding: 0.7rem 0 0.7rem 1rem;
    }
    .pms-table.pms-stack-compact td[data-label="Select"]::before { content: none; }
    .pms-table.pms-stack-compact tbody tr:has(td[data-label="Select"]) td.td-primary {
        border-left: none;
        width: auto;
        flex: 1 1 0;
        min-width: 0;
    }

    /* ── Actions-footer variant: add .pms-stack-actions to a stacked table ──
       Keeps each row's action buttons as a tap-friendly footer on phones so
       users can act directly, instead of the card only opening the details
       page. Composes with .pms-stack-nav (overrides its "hide the footer" rule
       and drops the floating go-rail) and .pms-stack-compact. The card body
       stays tappable wherever the view wires row navigation (tr[data-href]);
       taps on the footer buttons are excluded from that navigation. */
    .pms-table.pms-stack-actions td.td-actions {
        display: flex;
        justify-content: flex-end;
        flex-wrap: wrap;
        align-items: center;
        gap: 0.45rem;
        background: #fafbfd;
        border-top: 1px solid var(--color-border);
        padding: 0.6rem 1rem;
    }
    .pms-table.pms-stack-actions td.td-actions .btn-action { padding: 0.45rem 0.8rem; font-size: 0.8rem; }
    .pms-table.pms-stack-actions tbody tr[data-href] { padding-right: 0; }
    .pms-table.pms-stack-actions tbody tr[data-href]::after { content: none; }
}

/* Sticky-header utility for tall grids — put on the .pms-table-wrap */
.pms-table-sticky { max-height: 65vh; overflow-y: auto; }
.pms-table-sticky .pms-table thead th,
.pms-table-sticky table thead th {
    position: sticky;
    top: 0;
    z-index: 5;
    box-shadow: 0 1px 0 var(--color-border);
}

/* ── Sticky decision bar ────────────────────────────────────────
   For review-then-commit screens where the thing being reviewed is long: a
   267-person enrolment preview put its Enrol button below the whole list, so
   confirming meant scrolling past everything you had already read. The decision
   should not be a scroll away from what it is about. Sits under the 60px topbar. */
.pms-actionbar-sticky {
    position: sticky;
    top: 60px;
    z-index: 1035;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: 10px;
    box-shadow: 0 4px 14px rgba(26, 54, 93, 0.10);
    padding: 0.6rem 0.85rem;
    margin-bottom: 1rem;
}

@media (max-width: 767.98px) {
    /* Pinned on a phone the bar would cost most of the viewport, and the list
       below it is the point. It scrolls with the page instead. */
    .pms-actionbar-sticky { position: static; box-shadow: none; }
}

/* ── Insurance contract tile ────────────────────────────────────
   The contracts landing page. The old tile was a generic card with three
   centred numbers under it, which on a new workspace read as "0 0 0" with
   nothing saying why, and on a busy one gave a 267-life contract the same
   visual weight as an empty draft.

   So: one figure is the headline, everything else earns its place. Counts
   that are zero are simply absent rather than displayed as nothing; the ones
   that are not zero are chips you can click straight through to the tab that
   deals with them. A spine down the left carries the status as colour, so a
   draft is distinguishable from live at a glance across a wall of them. */
.ins-tile {
    position: relative;
    display: flex;
    flex-direction: column;
    height: 100%;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-sm);
    overflow: hidden;
    transition: box-shadow .15s ease, transform .15s ease, border-color .15s ease;
}

.ins-tile:hover {
    box-shadow: var(--shadow-md);
    transform: translateY(-2px);
    border-color: #cbd5e0;
}

/* The spine. Colour is the only thing distinguishing a live contract from a
   draft at a distance, so it is never the only signal — the badge says it too. */
.ins-tile::before {
    content: "";
    position: absolute;
    top: 0; bottom: 0; left: 0;
    width: 4px;
    background: var(--ins-accent, var(--color-border));
}

.ins-tile-live   { --ins-accent: var(--color-success); }
.ins-tile-draft  { --ins-accent: var(--color-warning); }
.ins-tile-closed { --ins-accent: var(--color-muted); }
.ins-tile-info   { --ins-accent: var(--color-brand); }
.ins-tile-danger { --ins-accent: var(--color-danger); }
/* The tile whose filter is applied to the list below it. */
.ins-tile-active { border-color: var(--color-brand); box-shadow: 0 0 0 2px var(--color-brand-light), var(--shadow-sm); }
/* Portal palette. The admin home stays restrained (a control room); the employee's own page
   carries colour in the figure and the icon, the way its old cards did. Each class sets the
   spine, the hero number and the icon chip together so a tile is never half-coloured. */
.ins-tile-vivid .ins-tile-hero-n { color: var(--ins-accent); }
.ins-tile-vivid .ins-tile-ico    { background: var(--ins-tint, var(--color-brand-light)); color: var(--ins-accent); }
.ins-tile-blue   { --ins-accent:#4e8ef7; --ins-tint:#ebf4ff; }
.ins-tile-green  { --ins-accent:#48bb78; --ins-tint:#f0fff4; }
.ins-tile-orange { --ins-accent:#ed8936; --ins-tint:#fffaf0; }
.ins-tile-red    { --ins-accent:#e53e3e; --ins-tint:#fff5f5; }
.ins-tile-teal   { --ins-accent:#38b2ac; --ins-tint:#f0fdfa; }
.ins-tile-purple { --ins-accent:#9f7aea; --ins-tint:#f5f3ff; }
.ins-tile-indigo { --ins-accent:#6366f1; --ins-tint:#eef2ff; }
.ins-tile-amber  { --ins-accent:#d69e2e; --ins-tint:#fffbeb; }

.ins-tile-head { display: flex; align-items: flex-start; gap: 0.65rem; padding: 0.9rem 1rem 0.65rem 1.2rem; }

.ins-tile-ico {
    flex: none;
    width: 36px; height: 36px;
    border-radius: 9px;
    display: flex; align-items: center; justify-content: center;
    background: var(--color-brand-light);
    color: var(--color-brand);
    font-size: 1.05rem;
}

.ins-tile-name {
    font-weight: 700;
    font-size: 0.95rem;
    line-height: 1.25;
    color: var(--color-text);
    text-decoration: none;
    /* Contract names run long ("Group health (IPD), priced by age band"). Two
       lines, then ellipsis, so one wordy contract cannot make its tile taller
       than every other tile in the row. */
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}
a.ins-tile-name:hover { color: var(--color-brand); text-decoration: underline; }

.ins-tile-meta { font-size: 0.72rem; color: var(--color-muted); margin-top: 0.2rem; line-height: 1.45; }

.ins-tile-hero { padding: 0.15rem 1rem 0.7rem 1.2rem; display: flex; align-items: baseline; gap: 0.45rem; flex-wrap: wrap; }
.ins-tile-hero-n { font-size: 2rem; font-weight: 700; line-height: 1; color: var(--color-text); }
.ins-tile-hero-l { font-size: 0.78rem; color: var(--color-muted); }

.ins-tile-note { padding: 0.15rem 1rem 0.8rem 1.2rem; font-size: 0.78rem; color: var(--color-muted); }

.ins-tile-chips { display: flex; flex-wrap: wrap; gap: 0.35rem; padding: 0 1rem 0.85rem 1.2rem; }
/* Every chip goes somewhere: a count of things needing attention that you
   cannot click is a count you have to go and find by hand. */
a.ins-tile-chip { text-decoration: none; }
a.ins-tile-chip:hover { filter: brightness(0.94); }

.ins-tile-cost { border-top: 1px dashed var(--color-border); padding: 0.65rem 1rem 0.7rem 1.2rem; }
.ins-tile-cost-total { display: flex; justify-content: space-between; align-items: baseline; gap: 0.5rem; }
.ins-tile-cost-total .lbl { font-size: 0.72rem; color: var(--color-muted); text-transform: uppercase; letter-spacing: .03em; }
.ins-tile-cost-total .val { font-size: 1.05rem; font-weight: 700; color: var(--color-text); }
.ins-tile-cost-sub { font-size: 0.7rem; color: var(--color-muted); margin-top: 0.2rem; }

/* Pushed to the bottom so tiles in a row line their buttons up whatever they
   carry above — a contract with no cost block is short, and it used to show. */
.ins-tile-foot {
    margin-top: auto;
    border-top: 1px solid var(--color-border);
    background: #f8fafc;
    padding: 0.6rem 1rem 0.6rem 1.2rem;
    display: flex; align-items: center; gap: 0.4rem; flex-wrap: wrap;
}

@media (prefers-reduced-motion: reduce) {
    .ins-tile { transition: none; }
    .ins-tile:hover { transform: none; }
}

/* ── Action Buttons ─────────────────────────────────────────── */
.btn-action {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    font-size: 0.78rem;
    font-weight: 600;
    padding: 0.3rem 0.7rem;
    border-radius: var(--radius-sm);
    border: 1px solid transparent;
    cursor: pointer;
    text-decoration: none;
    transition: background 0.15s, color 0.15s, border-color 0.15s;
    white-space: nowrap;
}
.btn-action-primary  { background:#ebf4ff; color:#2a4365; border-color:#bee3f8; }
.btn-action-primary:hover  { background:#bee3f8; color:#1a365d; }
.btn-action-success  { background:#f0fff4; color:#276749; border-color:#9ae6b4; }
.btn-action-success:hover  { background:#9ae6b4; color:#1c4532; }
.btn-action-danger   { background:#fff5f5; color:#c53030; border-color:#feb2b2; }
.btn-action-danger:hover   { background:#feb2b2; color:#9b2c2c; }
.btn-action-warning  { background:#fffbeb; color:#92400e; border-color:#fde68a; }
.btn-action-warning:hover  { background:#fde68a; color:#78350f; }
.btn-action-secondary{ background:#f7fafc; color:#4a5568; border-color:#e2e8f0; }
.btn-action-secondary:hover{ background:#e2e8f0; color:#2d3748; }
/* Aliases used in older views */
.btn-action-edit { background:#ebf4ff; color:#2a4365; border-color:#bee3f8; }
.btn-action-edit:hover { background:#bee3f8; color:#1a365d; }
.btn-action-view { background:#f7fafc; color:#4a5568; border-color:#e2e8f0; }
.btn-action-view:hover { background:#e2e8f0; color:#2d3748; }
.btn-action-delete { background:#fff5f5; color:#c53030; border-color:#feb2b2; }
.btn-action-delete:hover { background:#feb2b2; color:#9b2c2c; }

/* ── Primary CTA Buttons ────────────────────────────────────── */
.btn-pms-primary {
    background: var(--color-brand);
    color: #fff;
    border: none;
    border-radius: var(--radius-sm);
    padding: 0.45rem 1.1rem;
    font-size: 0.85rem;
    font-weight: 600;
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    cursor: pointer;
    text-decoration: none;
    transition: background 0.15s;
}
.btn-pms-primary:hover { background: var(--color-brand-dark); color: #fff; }
.btn-pms-success {
    background: var(--color-success);
    color: #fff;
    border: none;
    border-radius: var(--radius-sm);
    padding: 0.45rem 1.1rem;
    font-size: 0.85rem;
    font-weight: 600;
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    cursor: pointer;
    text-decoration: none;
    transition: background 0.15s;
}
.btn-pms-success:hover { background: #276749; color: #fff; }
.btn-pms-danger {
    background: var(--color-danger);
    color: #fff;
    border: none;
    border-radius: var(--radius-sm);
    padding: 0.45rem 1.1rem;
    font-size: 0.85rem;
    font-weight: 600;
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    cursor: pointer;
    text-decoration: none;
    transition: background 0.15s;
}
.btn-pms-danger:hover { background: #c53030; color: #fff; }
/* The sibling three views already asked for and none of them got: an action that is consequential
   but not destructive — merging a duplicate, accepting somebody without the usual proof. Without
   this rule those buttons rendered as bare browser buttons in the middle of a styled page. */
.btn-pms-warning {
    background: var(--color-warning);
    color: #fff;
    border: none;
    border-radius: var(--radius-sm);
    padding: 0.45rem 1.1rem;
    font-size: 0.85rem;
    font-weight: 600;
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    cursor: pointer;
    text-decoration: none;
    transition: background 0.15s;
}
.btn-pms-warning:hover { background: #b7791f; color: #fff; }
.btn-pms-outline {
    background: transparent;
    color: var(--color-brand);
    border: 1.5px solid var(--color-brand);
    border-radius: var(--radius-sm);
    padding: 0.42rem 1rem;
    font-size: 0.85rem;
    font-weight: 600;
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    cursor: pointer;
    text-decoration: none;
    transition: background 0.15s, color 0.15s;
}
.btn-pms-outline:hover { background: var(--color-brand); color: #fff; }
.btn-pms-secondary {
    background: var(--color-surface);
    color: var(--color-text);
    border: 1.5px solid var(--color-border);
    border-radius: var(--radius-sm);
    padding: 0.42rem 1rem;
    font-size: 0.85rem;
    font-weight: 600;
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    cursor: pointer;
    text-decoration: none;
    transition: background 0.15s, border-color 0.15s;
}
.btn-pms-secondary:hover { background: #f1f5f9; border-color: #c3cdd9; color: var(--color-text); text-decoration: none; }
/* btn-sm is Bootstrap's and only sizes a .btn (it sets --bs-btn-* variables that .btn consumes), so on
   these classes it was a silent no-op: a "small" CTA beside form-control-sm inputs rendered at full
   ~35px height. Sized here so the two-class request means what its authors meant. */
/* Every variant, not just two. 74 buttons across the app were written with btn-sm and rendered full
   size anyway because the rule named only primary and secondary — the markup was asking for a small
   button and being ignored, which is a good part of why sizes looked arbitrary from screen to screen. */
.btn-pms-primary.btn-sm,
.btn-pms-secondary.btn-sm,
.btn-pms-warning.btn-sm,
.btn-pms-success.btn-sm,
.btn-pms-danger.btn-sm,
.btn-pms-outline.btn-sm,
.btn-pms-ghost.btn-sm { padding: 0.28rem 0.7rem; font-size: 0.78rem; }
.btn-pms-ghost {
    background: transparent;
    color: var(--color-muted);
    border: 1px solid transparent;
    border-radius: var(--radius-sm);
    padding: 0.42rem 1rem;
    font-size: 0.85rem;
    font-weight: 500;
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    cursor: pointer;
    text-decoration: none;
    transition: background 0.15s, color 0.15s;
}
.btn-pms-ghost:hover { background: #f1f5f9; color: var(--color-text); text-decoration: none; }

/* ── Stat Cards ─────────────────────────────────────────────── */
.pms-stat-card {
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    padding: 1rem 1.2rem;
    display: flex;
    align-items: center;
    gap: 0.9rem;
    box-shadow: var(--shadow-sm);
}
.pms-stat-icon {
    width: 42px; height: 42px;
    border-radius: var(--radius-sm);
    display: flex; align-items: center; justify-content: center;
    flex-shrink: 0;
    font-size: 1.15rem;
}
.pms-stat-body { flex: 1; min-width: 0; }
.pms-stat-value { font-size: 1.35rem; font-weight: 700; line-height: 1.2; color: var(--color-text); }
.pms-stat-label { font-size: 0.75rem; color: var(--color-muted); font-weight: 500; margin-top: 0.1rem; }
.pms-stat-sub   { font-size: 0.7rem;  color: var(--color-muted); margin-top: 0.15rem; }

/* ── Badges ─────────────────────────────────────────────────── */
.pms-badge {
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
    font-size: 0.68rem;
    font-weight: 700;
    padding: 0.2rem 0.55rem;
    border-radius: 20px;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    white-space: nowrap;
}
.pms-badge-success  { background:#f0fff4; color:#276749; }
.pms-badge-danger   { background:#fff5f5; color:#c53030; }
.row-inactive td    { opacity:.65; }
.row-inactive:hover td { opacity:.85; }
.pms-badge-warning  { background:#fffbeb; color:#92400e; }
.pms-badge-info     { background:#ebf8ff; color:#2b6cb0; }
.pms-badge-neutral  { background:#f7fafc; color:#4a5568; border:1px solid #e2e8f0; }
.pms-badge-primary  { background:#ebf4ff; color:#2a4365; }

/* ── Form Shell ─────────────────────────────────────────────── */
.form-shell {
    max-width: 640px;
}
.form-shell-wide {
    max-width: 900px;
}
/* Employee Create/Edit: each tab is a stack of sections; a section is one flowing grid of fields.
   The legend reuses .form-section-title; the rule between sections keeps long tabs scannable. */
.emp-section { margin: 0 0 1.25rem; padding: 0; border: 0; min-width: 0; }
.emp-section + .emp-section { border-top: 1px solid var(--color-border, #e5e9ef); padding-top: 1rem; }
.emp-section > legend { float: none; width: auto; padding: 0; margin-bottom: .75rem; }
.emp-section .form-label { margin-bottom: .3rem; }
.emp-section .form-text { font-size: .78rem; }

/* The employee record's shell: its header plus one row of section tabs (Overview, Job, Pay, Performance,
   Documents, Activity), identical on every page about that person. The tabs share the form-tab look but
   scroll sideways on a phone instead of wrapping into a second row. */
.emp-tabs.emp-shell-tabs {
    flex-wrap: nowrap; overflow-x: auto; overflow-y: hidden; scrollbar-width: thin; margin-top: -0.5rem;
    /* A scroll container clips at its padding box, so the tabs cannot overlap a real border the way the
       form tabs do (that overlap read as overflow and drew a scrollbar on every screen). The divider is an
       inset shadow under the tabs instead, and the active tab's own border covers it. */
    border-bottom: 0; box-shadow: inset 0 -2px 0 var(--color-border);
}
.emp-shell-tabs .emp-tab { flex: none; margin-bottom: 0; }

/* Tiles that carry words rather than numbers (the Job tab's Today strip). */
.kpi-value-text { font-size: 1.05rem; line-height: 1.25; white-space: normal; overflow-wrap: anywhere; }

/* ── History, shared by the Pay, Job, Performance and Targets tabs: a table whose first column is a
   timeline rail. Green filled dot = the entry in force today, grey = older, red dashed = voided. Each
   tab keeps its own columns; the rail, the badges, the quietened voided row and the one action column
   are the same everywhere. Rows carry is-first / is-last so the rail starts and ends at a dot. ── */
.hist-table { font-size: .88rem; margin-bottom: 0; }
.hist-table th, .hist-table td { vertical-align: top; }
.hist-table td { padding-top: .6rem; padding-bottom: .6rem; }
.hist-table .hist-rail { position: relative; width: 1.6rem; min-width: 1.6rem; padding: 0; }
.hist-table .hist-rail::before { content: ""; position: absolute; left: 50%; top: 0; bottom: 0; width: 2px; margin-left: -1px; background: var(--color-border); }
.hist-table tr.is-first .hist-rail::before { top: .95rem; }
.hist-table tr.is-last .hist-rail::before { bottom: calc(100% - .95rem); }
.hist-table tr.is-first.is-last .hist-rail::before { display: none; }
.hist-table .hist-rail::after { content: ""; position: absolute; left: 50%; top: .62rem; width: .72rem; height: .72rem; margin-left: -.36rem; border-radius: 50%; background: #fff; border: 2px solid #adb5bd; box-sizing: border-box; }
.hist-table tr.is-current .hist-rail::after { background: #198754; border-color: #198754; box-shadow: 0 0 0 3px rgba(25, 135, 84, .18); }
.hist-table tr.is-void .hist-rail::after { border-color: #dc3545; border-style: dashed; }
.hist-table tr.is-void td:not(.hist-rail) { background: var(--color-bg, #f4f6fa); color: var(--color-muted); }
.hist-table thead .hist-rail::before, .hist-table thead .hist-rail::after { display: none; }
.hist-table .hist-when { white-space: nowrap; font-weight: 600; width: 8rem; }
.hist-table .hist-kind { width: 9.5rem; }
.hist-table .hist-amt { width: 9rem; text-align: right; white-space: nowrap; font-variant-numeric: tabular-nums; }
.hist-table .hist-rec { width: 9.5rem; max-width: 9.5rem; }
.hist-table .hist-act { width: 4.5rem; text-align: right; }
.hist-field { display: block; font-size: .64rem; font-weight: 800; letter-spacing: .07em; text-transform: uppercase; color: var(--color-muted); }
.hist-line { line-height: 1.35; }
.hist-line + .hist-line { margin-top: .35rem; }
/* The row that opens beneath an entry for its void form: no dot, no rail. */
.hist-table tr.hist-expand td { background: #fff8f8; border-top: 0; }
.hist-table tr.hist-expand .hist-rail::before, .hist-table tr.hist-expand .hist-rail::after { display: none; }

.form-section-title {
    font-size: 0.7rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--color-muted);
    margin-bottom: 0.75rem;
    padding-bottom: 0.4rem;
    border-bottom: 1px solid var(--color-border);
}
.form-footer {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    padding-top: 1rem;
    border-top: 1px solid var(--color-border);
    margin-top: 1.25rem;
}

/* ── Delete Confirmation Shell ──────────────────────────────── */
.delete-shell {
    max-width: 540px;
    margin: 0 auto;
    text-align: left;
}
.delete-shell .delete-icon-wrap {
    width: 56px; height: 56px;
    border-radius: 50%;
    background: #fff5f5;
    display: flex; align-items: center; justify-content: center;
    font-size: 1.6rem;
    color: var(--color-danger);
    margin-bottom: 1rem;
}
.delete-shell .delete-detail-row {
    display: flex;
    align-items: center;
    padding: 0.5rem 0;
    border-bottom: 1px solid var(--color-border);
    font-size: 0.875rem;
}
.delete-shell .delete-detail-row:last-child { border-bottom: none; }
.delete-shell .delete-detail-label { width: 140px; color: var(--color-muted); font-size: 0.75rem; font-weight: 600; text-transform: uppercase; letter-spacing: 0.05em; flex-shrink: 0; }

/* ── Empty State ────────────────────────────────────────────── */
.empty-state {
    text-align: center;
    padding: 3rem 1rem;
    color: var(--color-muted);
}
.empty-state i { font-size: 2.5rem; opacity: 0.35; display: block; margin-bottom: 0.75rem; }
.empty-state p { font-size: 0.875rem; margin: 0; }

/* ── Pagination ─────────────────────────────────────────────── */
.pms-pagination {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0.65rem 0.9rem;
    border-top: 1px solid var(--color-border);
    font-size: 0.78rem;
    color: var(--color-muted);
    flex-wrap: wrap;
    gap: 0.5rem;
}
.pms-pagination .page-links { display: flex; gap: 0.25rem; }
.pms-pagination .page-links a,
.pms-pagination .page-links span {
    display: inline-flex; align-items: center; justify-content: center;
    width: 28px; height: 28px; border-radius: var(--radius-sm);
    font-size: 0.78rem; font-weight: 600; text-decoration: none;
    border: 1px solid var(--color-border); color: var(--color-text);
    transition: background 0.12s;
}
.pms-pagination .page-links a:hover { background: var(--color-brand-light); }
.pms-pagination .page-links span.active { background: var(--color-brand); color: #fff; border-color: var(--color-brand); }
.pms-pagination .page-links span.disabled { opacity: 0.4; pointer-events: none; }

/* ── Alert overrides ────────────────────────────────────────── */
.alert { border-radius: var(--radius-md); font-size: 0.875rem; }
.alert i { margin-right: 0.35rem; }

/* ── Detail View ────────────────────────────────────────────── */
.detail-grid { display: grid; grid-template-columns: 160px 1fr; gap: 0.6rem 1rem; }
.detail-grid .dl-label { font-size: 0.72rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.05em; color: var(--color-muted); padding-top: 2px; }
.detail-grid .dl-value { font-size: 0.875rem; color: var(--color-text); font-weight: 500; }

/* detail-row pattern (used in card-section detail views) */
.detail-row { display: flex; align-items: baseline; gap: 0.75rem; padding: 0.55rem 1rem; border-bottom: 1px solid #f1f5f9; }
.detail-row:last-child { border-bottom: none; }
.detail-label { min-width: 160px; flex-shrink: 0; font-size: 0.7rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.06em; color: var(--color-muted); padding-top: 1px; }
.detail-value { font-size: 0.875rem; color: var(--color-text); font-weight: 500; word-break: break-word; }
.detail-value.fw-500 { font-weight: 600; }

/* card-section header (replaces inline-style section headers) */
.card-section-header {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.7rem 1rem;
    border-bottom: 1px solid var(--color-border);
    font-size: 0.72rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--color-muted);
    background: #f8fafc;
}

/* ── Employee Tab Navigation ────────────────────────────────── */
/* ── Tabs: ONE look, whatever the mechanism ─────────────────────────────────────
   The app grew four tab strips independently and they disagreed about everything
   that matters, including what "selected" looks like. Three different active
   colours were in play:

     .emp-tab.active        var(--color-primary)  -- a token defined NOWHERE, so
                                                     it rendered as inherited grey
     .loan-tab-nav .active  var(--bs-primary)     -- bright Bootstrap blue
     .pf-tab-btn.active     #1D9E75               -- the marketing green

   plus Bootstrap's own .nav-tabs, restyled in modern-saas.css as a filled navy
   folder tab at 1.05rem.

   They are unified on the UNDERLINE tab: it is the current SaaS convention, it
   recedes instead of competing with the content and with the navy primary
   buttons, it takes count badges without looking heavy, and it survives wrapping
   to a second row, which filled folder tabs do not.

   LOOK ONLY — no mechanism is touched. .nav-tabs keeps data-bs-toggle and its
   client-side panes (the payroll workspace is a big view and a round trip per tab
   would make it slower); .emp-tabs stays real links with real URLs. This file
   loads after modern-saas.css, so these win on equal specificity.

   Deliberately NOT included: .bulk-tab on the public landing page and .pfnav-tab
   in the platform console. Both live on dark chrome with their own design
   language, and dragging them into the app's light palette would look worse, not
   more consistent. */

.emp-tabs,
.nav-tabs,
.pf-tabs,
.loan-tab-nav .nav {
    display: flex;
    gap: 0.25rem;
    border-bottom: 2px solid var(--color-border);
    margin-bottom: 1.5rem;
    flex-wrap: wrap;
    /* .pf-tabs came as a segmented control on a grey tray. */
    background: none;
    padding: 0;
    border-radius: 0;
}

.emp-tabs .emp-tab,
.nav-tabs .nav-link,
.pf-tabs .pf-tab-btn,
.loan-tab-nav .nav-link {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.55rem 1.1rem;
    font-size: 0.85rem;
    font-weight: 600;
    color: var(--color-muted);
    background: none;
    border: none;
    border-bottom: 2px solid transparent;
    margin-bottom: -2px;
    margin-right: 0;
    cursor: pointer;
    border-radius: var(--radius-sm) var(--radius-sm) 0 0;
    box-shadow: none;
    transition: color 0.15s, border-color 0.15s, background 0.15s;
    white-space: nowrap;
    /* Tabs may be <a> as well as <button>: no link underline, ever. */
    text-decoration: none;
    /* .pf-tab-btn stretched each tab to fill the tray. */
    flex: none;
    min-width: 0;
}

.emp-tabs .emp-tab:hover,
.nav-tabs .nav-link:hover,
.pf-tabs .pf-tab-btn:hover,
.loan-tab-nav .nav-link:hover {
    color: var(--color-text);
    background: #f1f5f9;
    /* Bootstrap puts a full box-border on .nav-link:hover. */
    border-color: transparent;
    border-bottom-color: var(--color-border);
}

.emp-tabs .emp-tab.active,
.nav-tabs .nav-link.active,
.nav-tabs .nav-item.show .nav-link,
.pf-tabs .pf-tab-btn.active,
.loan-tab-nav .nav-link.active {
    color: var(--color-brand);
    background: var(--color-brand-light);
    border-color: transparent;
    border-bottom-color: var(--color-brand);
    box-shadow: none;
    font-weight: 600;
}

.emp-tabs .emp-tab i,
.nav-tabs .nav-link i,
.pf-tabs .pf-tab-btn i,
.loan-tab-nav .nav-link i { font-size: 0.85rem; }

/* A count on a tab is information, not decoration: keep it readable but never
   let it out-shout the label it belongs to. */
.emp-tabs .emp-tab .badge,
.nav-tabs .nav-link .badge,
.pf-tabs .pf-tab-btn .badge { font-size: 0.68rem; font-weight: 600; }
/* An UNCOLOURED count is a quiet pill that takes the brand colour when its tab is selected. */
.emp-tabs .emp-tab .badge:not([class*="bg-"]),
.nav-tabs .nav-link .badge:not([class*="bg-"]),
.pf-tabs .pf-tab-btn .badge:not([class*="bg-"]) { background: var(--color-bg); color: var(--color-muted); border: 1px solid var(--color-border); }
.emp-tabs .emp-tab.active .badge:not([class*="bg-"]),
.nav-tabs .nav-link.active .badge:not([class*="bg-"]),
.pf-tabs .pf-tab-btn.active .badge:not([class*="bg-"]) { background: var(--color-brand); color: #fff; border-color: var(--color-brand); }
/* A COLOURED count means something (danger, warning, success) and keeps its colour selected or not —
   with text that can be read on it. Bootstrap's bg-* utilities are !important, so the text is too. */
.nav-tabs .nav-link .badge[class*="bg-"], .emp-tabs .emp-tab .badge[class*="bg-"], .pf-tabs .pf-tab-btn .badge[class*="bg-"] { border: 0; color: #fff !important; }
.nav-tabs .nav-link .badge.bg-warning, .emp-tabs .emp-tab .badge.bg-warning, .pf-tabs .pf-tab-btn .badge.bg-warning,
.nav-tabs .nav-link .badge.bg-info, .emp-tabs .emp-tab .badge.bg-info,
.nav-tabs .nav-link .badge.bg-light, .emp-tabs .emp-tab .badge.bg-light { color: #1f2937 !important; }
.nav-tabs .nav-link .badge.bg-light, .emp-tabs .emp-tab .badge.bg-light { border: 1px solid var(--color-border); }

/* The attendance-style tab strip (.att-tabs / a.att-tab): Attendance, Leave, the work calendar, My Team, My
   Attendance and My Leave. Same underline tab, same selected look as above. Until 2026-10-05 it carried its own
   module accent (teal for Attendance, violet for Leave) and no background, so its selected tab read differently
   from every other tab in the app (owner's review). Mechanism unchanged: real links with ?tab=, the shared tab
   script, lazy panels. It scrolls sideways on a phone, so the divider is an inset shadow as on the employee shell
   (a scroll container clips a real border). Colours carry !important because the global link rule above, one
   class and a dozen :not()s, out-specifies any component rule. */
.att-tabs {
    display: flex; gap: 0.25rem; flex-wrap: nowrap; overflow-x: auto; overflow-y: hidden;
    border-bottom: 0; box-shadow: inset 0 -2px 0 var(--color-border); margin-bottom: 1rem;
    scrollbar-width: thin; -webkit-overflow-scrolling: touch;
}
.att-tabs a.att-tab,
.att-tabs a.att-tab:visited {
    display: inline-flex; align-items: center; gap: 0.4rem; flex: none; white-space: nowrap;
    padding: 0.55rem 1.1rem; margin: 0; border: 0; border-bottom: 2px solid transparent;
    border-radius: var(--radius-sm) var(--radius-sm) 0 0; background: none;
    color: var(--color-muted) !important; font-size: 0.85rem; font-weight: 600; text-decoration: none;
    transition: color 0.15s, border-color 0.15s, background 0.15s;
}
.att-tabs a.att-tab:hover { color: var(--color-text) !important; background: #f1f5f9; border-bottom-color: var(--color-border); }
.att-tabs a.att-tab.on,
.att-tabs a.att-tab.on:hover { color: var(--color-brand) !important; background: var(--color-brand-light); border-bottom-color: var(--color-brand); }
.att-tabs a.att-tab:focus-visible { outline: 2px solid var(--color-brand); outline-offset: -2px; }
.att-tabs a.att-tab i { font-size: 0.85rem; }
/* Counts: a quiet pill that takes the brand colour on the selected tab, as .badge does above; an amber count
   (.has: something to look at) keeps its colour selected or not. */
.att-tab-count {
    min-width: 1.45rem; padding: 0 0.45rem; border-radius: 999px; font-size: 0.68rem; font-weight: 600; line-height: 1.3rem;
    text-align: center; background: var(--color-bg); color: var(--color-muted); border: 1px solid var(--color-border);
}
.att-tab-count.has { background: #fef3c7; color: #92400e; border-color: #fde68a; }
.att-tabs a.att-tab.on .att-tab-count:not(.has) { background: var(--color-brand); color: #fff; border-color: var(--color-brand); }

/* Section strips: the row of pills under a module's title. Attendance (.att-nav: Register, Day, Punctuality,
   Insights...) and Leave (.lv-nav: Overview, Requests, Calendar...). They stay pills, so moving between a module's
   pages reads differently from the tabs inside a page. The selected pill is coloured exactly like a selected tab:
   brand text on the light brand tint with a brand edge, never a solid module colour (teal, violet) as before.
   Colours carry !important for the same reason as above. */
.att-nav,
.lv-nav { display: flex; gap: 0.35rem; overflow-x: auto; padding-bottom: 2px; scrollbar-width: thin; -webkit-overflow-scrolling: touch; }
a.att-nav-item, a.att-nav-item:visited,
a.lv-nav-item, a.lv-nav-item:visited {
    display: inline-flex; align-items: center; gap: 0.4rem; flex: none; white-space: nowrap;
    padding: 0.42rem 0.8rem; border: 1px solid var(--color-border); border-radius: 999px;
    background: var(--color-surface); color: var(--color-muted) !important;
    font-size: 0.82rem; font-weight: 600; text-decoration: none;
    transition: color 0.15s, border-color 0.15s, background 0.15s;
}
a.att-nav-item:hover, a.lv-nav-item:hover { color: var(--color-text) !important; background: #f1f5f9; }
a.att-nav-item.on, a.att-nav-item.on:hover,
a.lv-nav-item.on, a.lv-nav-item.on:hover { color: var(--color-brand) !important; background: var(--color-brand-light); border-color: var(--color-brand); }
.att-nav-count,
.lv-nav-count { background: #d69e2e; color: #fff; border-radius: 999px; font-size: 0.68rem; padding: 0 0.4rem; line-height: 1.35rem; min-width: 1.35rem; text-align: center; }

.emp-tab-content .emp-tab-pane { display: none; }
.emp-tab-content .emp-tab-pane.active { display: block; animation: fadeInTab 0.15s ease; }
@keyframes fadeInTab { from { opacity: 0; transform: translateY(4px); } to { opacity: 1; transform: none; } }

/* form-shell-tabs — full-width shell for tabbed employee forms */
.form-shell-tabs { max-width: 1100px; }

/* ── Responsive tweaks ──────────────────────────────────────── */
@media (max-width: 576px) {
    .page-header { flex-direction: column; align-items: flex-start; }
    .filter-bar .row > div { margin-bottom: 0.5rem; }
    .detail-grid { grid-template-columns: 1fr; }
    .detail-grid .dl-label { margin-bottom: 0; }
}
@media (max-width: 767.98px) {
    /* Filter controls stop fighting fixed widths on phones */
    .filter-bar-form .form-control,
    .filter-bar-form .form-select {
        flex: 1 1 45%;
        min-width: 0 !important;
        max-width: 100% !important;
        width: auto !important;
    }
    .filter-bar-form .btn-pms-primary,
    .filter-bar-form .btn-pms-secondary,
    .filter-bar-form .btn-pms-ghost { flex: 0 0 auto; }
    .page-content { padding: 1rem 0.75rem; }
    main { padding: 1rem 0.85rem; }
}

/* Keyboard access for clickable rows */
.pms-table tbody tr[data-href]:focus-visible {
    outline: 2px solid #4e8ef7;
    outline-offset: -2px;
}

/* ── Utility font weights (referenced app-wide, previously undefined) ── */
.fw-500 { font-weight: 500 !important; }
.fw-600 { font-weight: 600 !important; }
.fw-700 { font-weight: 700 !important; }
.fw-800 { font-weight: 800 !important; }

/* ── Legacy pagination markup (EarningType/DeductionType/TaxSlab/Role
      indexes + Activity) — previously unstyled phantom classes ── */
.pms-pagination-controls { display: flex; gap: 0.25rem; align-items: center; flex-wrap: wrap; }
.pms-pagination-info { font-size: 0.78rem; color: var(--color-muted); }
.pms-page-btn {
    display: inline-flex; align-items: center; justify-content: center;
    min-width: 28px; height: 28px; padding: 0 0.45rem;
    border-radius: var(--radius-sm);
    font-size: 0.78rem; font-weight: 600; text-decoration: none;
    border: 1px solid var(--color-border); color: var(--color-text);
    background: var(--color-surface);
    transition: background 0.12s;
}
.pms-page-btn:hover { background: var(--color-brand-light); color: var(--color-brand); }
.pms-page-btn.active { background: var(--color-brand); color: #fff; border-color: var(--color-brand); }
.pms-page-btn.disabled, .pms-page-btn[disabled] { opacity: 0.4; pointer-events: none; }

/* ── Badge aliases used by Compensation/BulkApply preview ── */
.pms-badge.badge-active   { background: #f0fff4; color: #276749; }
.pms-badge.badge-inactive { background: #f7fafc; color: #4a5568; border: 1px solid #e2e8f0; }

/* ── Toast notifications ────────────────────────────────────── */
.pms-toast-wrap {
    position: fixed;
    top: 72px;
    right: 1rem;
    z-index: 2100;
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    max-width: min(380px, calc(100vw - 2rem));
}
.pms-toast {
    display: flex;
    align-items: flex-start;
    gap: 0.6rem;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-left: 3px solid var(--color-info);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-lg);
    padding: 0.7rem 0.9rem;
    font-size: 0.875rem;
    color: var(--color-text);
    opacity: 0;
    transform: translateX(12px);
    transition: opacity 0.2s, transform 0.2s;
}
.pms-toast.visible { opacity: 1; transform: none; }
.pms-toast > i { font-size: 1rem; flex-shrink: 0; margin-top: 1px; }
.pms-toast-success { border-left-color: var(--color-success); }
.pms-toast-success > i { color: var(--color-success); }
.pms-toast-danger  { border-left-color: var(--color-danger); }
.pms-toast-danger > i { color: var(--color-danger); }
.pms-toast-warning { border-left-color: var(--color-warning); }
.pms-toast-warning > i { color: var(--color-warning); }
.pms-toast-info    { border-left-color: var(--color-info); }
.pms-toast-info > i { color: var(--color-info); }
.pms-toast-msg { flex: 1; word-break: break-word; }
.pms-toast-close {
    background: none; border: none;
    color: var(--color-muted);
    font-size: 1.1rem; line-height: 1;
    cursor: pointer; padding: 0; flex-shrink: 0;
}
.pms-toast-close:hover { color: var(--color-text); }

/* ── Shared UX runtime: confirm dialog + progress overlay ───── */
.pms-modal-backdrop {
    position: fixed;
    inset: 0;
    z-index: 2000;
    background: rgba(15, 23, 42, 0.55);
    backdrop-filter: blur(3px);
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 1rem;
    opacity: 0;
    transition: opacity 0.15s ease;
}
.pms-modal-backdrop.visible { opacity: 1; }
.pms-modal {
    background: var(--color-surface);
    border-radius: var(--radius-lg);
    padding: 1.75rem 2rem;
    width: 100%;
    max-width: 440px;
    box-shadow: 0 20px 60px rgba(0,0,0,0.30);
    text-align: center;
    transform: translateY(10px) scale(0.98);
    transition: transform 0.15s ease;
}
.pms-modal-backdrop.visible .pms-modal { transform: none; }
.pms-modal-icon {
    width: 56px; height: 56px;
    border-radius: var(--radius-lg);
    background: var(--color-brand-light);
    color: var(--color-brand);
    display: flex; align-items: center; justify-content: center;
    font-size: 1.5rem;
    margin: 0 auto 1rem;
}
.pms-modal-icon-danger  { background: #fff5f5; color: var(--color-danger); }
.pms-modal-icon-warning { background: #fffbeb; color: var(--color-warning); }
.pms-modal-title {
    font-weight: 700;
    color: var(--color-text);
    margin-bottom: 0.5rem;
    font-size: 1.05rem;
}
.pms-modal-message {
    font-size: 0.875rem;
    color: var(--color-text-light);
    white-space: pre-line;
    text-align: left;
    margin-bottom: 1.25rem;
}
.pms-modal-message:empty { display: none; }
.pms-modal-actions {
    display: flex;
    gap: 0.6rem;
    justify-content: center;
}
.pms-modal-actions > * { min-width: 110px; justify-content: center; }
.pms-progress-spinner { margin-bottom: 1rem; }
.pms-progress-spinner .spinner-border { width: 2.6rem; height: 2.6rem; border-width: 0.28em; }
.pms-progress-foot {
    font-size: 0.75rem;
    color: var(--color-muted);
    border-top: 1px solid var(--color-border);
    padding-top: 0.75rem;
    margin-top: 0.25rem;
}
.pms-btn-busy { opacity: 0.75; pointer-events: none; }
.pms-btn-spinner { margin-right: 0.45rem; width: 0.9rem; height: 0.9rem; border-width: 0.14em; vertical-align: -0.1em; }
@media (prefers-reduced-motion: reduce) {
    .pms-modal-backdrop, .pms-modal { transition: none; }
}

/* ── Payslip Web View ───────────────────────────────────────── */
.payslip-container {
    max-width: 860px;
    margin: 0 auto;
    font-size: 0.875rem;
}
.payslip-header {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    gap: 1.5rem;
    background: #fff;
    border: 1px solid #e6eef8;
    border-radius: var(--radius-md);
    padding: 1.25rem 1.5rem;
    margin-bottom: 0.75rem;
}
.payslip-brand .company-logo { max-width: 220px; margin-bottom: 0.5rem; display: block; }
.payslip-brand .company-name { font-size: 1.05rem; font-weight: 700; color: #0b5ed7; margin-bottom: 0.2rem; }
.payslip-brand .company-address { font-size: 0.75rem; color: var(--color-muted); max-width: 460px; line-height: 1.4; }
.payslip-meta { text-align: right; flex-shrink: 0; }
.payslip-meta .meta-label { font-size: 0.7rem; font-weight: 600; text-transform: uppercase; letter-spacing: 0.05em; color: var(--color-muted); }
.payslip-meta .meta-value { font-size: 0.9rem; font-weight: 700; color: var(--color-text); margin-bottom: 0.6rem; }

.payslip-info {
    background: #fff;
    border: 1px solid #e6eef8;
    border-radius: var(--radius-md);
    padding: 1rem 1.5rem;
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 1rem 1.25rem;
    margin-bottom: 0.75rem;
}
.payslip-info .info-label { font-size: 0.7rem; font-weight: 600; text-transform: uppercase; letter-spacing: 0.05em; color: var(--color-muted); margin-bottom: 0.15rem; }
.payslip-info .info-value { font-size: 0.875rem; font-weight: 600; color: var(--color-text); }

.payslip-ed {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 0.75rem;
    margin-bottom: 0.75rem;
}
.payslip-panel {
    background: #fff;
    border: 1px solid #eef2f7;
    border-radius: var(--radius-md);
    overflow: hidden;
}
.payslip-panel-title {
    font-size: 0.75rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--color-muted);
    padding: 0.65rem 1rem;
    background: #f8fafc;
    border-bottom: 1px solid #eef2f7;
}
.payslip-panel table { width: 100%; border-collapse: collapse; }
.payslip-panel table th { font-size: 0.7rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.05em; color: var(--color-muted); padding: 0.5rem 1rem; border-bottom: 1px solid #eef2f7; background: #f8fafc; }
.payslip-panel table td { padding: 0.55rem 1rem; border-bottom: 1px solid #f1f5f9; color: var(--color-text); font-size: 0.85rem; }
.payslip-panel table tr:last-child td { border-bottom: none; }
.payslip-panel table tfoot td { font-weight: 700; background: #f8fafc; border-top: 1px solid #e6eef8; font-size: 0.875rem; }

.payslip-netpay {
    background: #fff;
    border: 1px solid #e6eef8;
    border-radius: var(--radius-md);
    padding: 1rem 1.5rem;
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 1rem;
}
.payslip-netpay .note { font-size: 0.78rem; color: var(--color-muted); font-style: italic; }
.payslip-netpay .net-label { font-size: 0.7rem; font-weight: 600; text-transform: uppercase; letter-spacing: 0.05em; color: var(--color-muted); margin-bottom: 0.2rem; text-align: right; }
.payslip-netpay .net-amount { font-size: 1.6rem; font-weight: 800; color: #0b5ed7; letter-spacing: -0.02em; }

@media print {
    .no-print { display: none !important; }
    .payslip-container { max-width: 100%; }
}
@media (max-width: 600px) {
    .payslip-info { grid-template-columns: repeat(2, 1fr); }
    .payslip-ed { grid-template-columns: 1fr; }
    .payslip-header { flex-direction: column; }
    .payslip-meta { text-align: left; }
}

/* ── Receipt evidence in claims grids ────────────────────────
   Thumbnails instead of a paperclip: an approver has to see the receipt
   without leaving the queue. Images open in the lightbox below; PDFs open
   in a new tab (the download endpoint sends X-Frame-Options: DENY). */
.pms-receipts { display: flex; flex-wrap: wrap; gap: 4px; align-items: center; }
.pms-receipt {
    display: inline-flex; align-items: center; justify-content: center;
    width: 38px; height: 38px; border-radius: var(--radius-sm, 6px);
    border: 1px solid var(--color-border); background: #f8fafc;
    overflow: hidden; cursor: zoom-in; flex-shrink: 0;
    transition: border-color .12s ease, transform .12s ease;
}
.pms-receipt:hover { border-color: #4e8ef7; transform: translateY(-1px); }
.pms-receipt img { width: 100%; height: 100%; object-fit: cover; display: block; }
.pms-receipt-file {
    flex-direction: column; gap: 0; cursor: pointer;
    color: var(--color-danger, #dc2626); text-decoration: none; font-size: .95rem; line-height: 1;
}
.pms-receipt-file span { font-size: .55rem; font-weight: 700; letter-spacing: .04em; margin-top: 2px; }

.pms-lightbox {
    position: fixed; inset: 0; z-index: 2000;
    background: rgba(15, 23, 42, .82);
    display: flex; align-items: center; justify-content: center;
    padding: 1.25rem; overscroll-behavior: contain;
}
.pms-lightbox img {
    max-width: 100%; max-height: 82vh; border-radius: 8px;
    box-shadow: 0 20px 60px rgba(0, 0, 0, .45); background: #fff;
}
.pms-lightbox-bar {
    position: absolute; top: 0; left: 0; right: 0;
    display: flex; justify-content: space-between; align-items: center; gap: 1rem;
    padding: .75rem 1rem; color: #fff; font-size: .85rem;
}
.pms-lightbox-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pms-lightbox-actions { display: flex; gap: .5rem; flex-shrink: 0; }
.pms-lightbox-actions a, .pms-lightbox-actions button {
    background: rgba(255, 255, 255, .14); color: #fff; border: none;
    border-radius: 6px; padding: .3rem .6rem; font-size: .8rem; cursor: pointer;
    text-decoration: none; line-height: 1.4;
}
.pms-lightbox-actions a:hover, .pms-lightbox-actions button:hover { background: rgba(255, 255, 255, .28); }

/* On phones the stacked card puts the receipt on its own row — give it room to breathe. */
@media (max-width: 767.98px) {
    .pms-table.pms-table-stack tbody td .pms-receipts { justify-content: flex-end; }
    .pms-receipt { width: 46px; height: 46px; }
}


/* ── Choice cards ─────────────────────────────────────────────────────────────
   A list of mutually-exclusive options presented as cards rather than a radio
   group — picking an insurance template, for instance. The template chooser
   shipped with inline styles and NO hover state at all, so nothing moved as the
   pointer crossed the options and the cards read as prose rather than as things
   you press.

   Border WIDTH never changes between states, only its colour, so hovering or
   selecting cannot nudge the layout by a pixel. */
.choice-card {
    display: block;
    padding: 0.9rem 1rem;
    margin-bottom: 0.6rem;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    text-decoration: none;
    cursor: pointer;
    transition: border-color .15s ease, box-shadow .15s ease, transform .15s ease, background-color .15s ease;
}

.choice-card:hover {
    border-color: var(--color-brand);
    background: var(--color-brand-light);
    box-shadow: var(--shadow-md);
    transform: translateY(-2px);
}

/* Keyboard users get the same affordance as the mouse — these are anchors, so
   they are tabbed through whether or not anybody thought about it. */
.choice-card:focus-visible {
    outline: none;
    border-color: var(--color-brand);
    box-shadow: 0 0 0 3px rgba(42, 67, 101, 0.25);
}

.choice-card.is-selected {
    border-color: var(--color-brand);
    background: var(--color-brand-light);
    box-shadow: inset 3px 0 0 var(--color-brand);
}

/* The chosen one says so, rather than leaving a slightly different background to
   carry the whole message on its own. */
.choice-card-title { display: flex; align-items: center; gap: .5rem; font-weight: 600; color: var(--color-text); }
.choice-card-title .choice-card-mark { margin-left: auto; flex: none; color: var(--color-brand); opacity: 0; transition: opacity .15s ease; }
.choice-card:hover .choice-card-mark { opacity: .35; }
.choice-card.is-selected .choice-card-mark,
.choice-card.is-selected:hover .choice-card-mark { opacity: 1; }


/* ── The "add one" panel on the contract setup stages ──────────────────────────
   These forms used to render inline, with the same field layout as the saved
   rows above them, so the last thing on the stage looked like another entry that
   already existed. They are closed until asked for now; when open, this makes
   them read as a form rather than as one more row — dashed edge, tinted ground,
   set in from the list it belongs to. */
.setup-addform {
    margin-top: .5rem;
    padding: .85rem;
    background: var(--color-brand-light);
    border: 1px dashed var(--color-brand);
    border-radius: var(--radius-md);
}

/* ── Dashboard grid (admin home + employee portal) ─────────────────────────────────────────
   One continuous grid. Bootstrap rows may stay in the markup (they carry Razor conditionals) but
   render as display:contents, so every tile is a direct grid item and nothing forces a line break
   at a section boundary. Dense flow lets a double-width tile pack without stranding a hole beside
   it. Fixed columns, not masonry, so a tile is in the same place tomorrow as it is today. */
.hd-grid { display:grid; grid-template-columns:repeat(4, minmax(0,1fr)); gap:1rem; grid-auto-flow:dense; align-items:stretch; margin-top:.25rem; }
.hd-grid > .row { display:contents; }
.hd-grid > .row > *, .hd-grid > [class*="col-"] { width:auto; max-width:none; flex:none; padding:0; margin:0; }
.hd-grid .col-xl-6 { grid-column:span 2; }
.hd-grid .hd-span4 { grid-column:1 / -1; }
.hd-grid .hd-span2 { grid-column:span 2; }
@media (max-width:640px) { .hd-grid .hd-span2 { grid-column:1 / -1; } }
/* Name-over-code cell used by every uplifted listing. */
.who { line-height:1.2; }
.who .name { font-weight:600; color:var(--color-text); }
.who .code { font-size:.74rem; color:var(--color-muted); }
.hd-grid .ins-tile { height:100%; }
@media (max-width: 1199.98px) { .hd-grid { grid-template-columns:repeat(2, minmax(0,1fr)); } }
@media (max-width: 767.98px)  { .hd-grid { grid-template-columns:1fr; } .hd-grid .col-xl-6 { grid-column:span 1; } }
.hd-eyebrow { display:block; font-size:.6rem; font-weight:800; letter-spacing:.09em; text-transform:uppercase; color:var(--color-muted); margin-bottom:.15rem; }
.hd-list a { display:flex; justify-content:space-between; gap:.5rem; font-size:.8rem; padding:.28rem 0; text-decoration:none; color:var(--color-text); border-bottom:1px dashed var(--color-border); }
.hd-list a:last-child { border-bottom:0; }
.hd-list a:hover .k { color:var(--color-brand); text-decoration:underline; }
.hd-list .n { font-weight:700; white-space:nowrap; }
/* A row that is information, not a destination: same rhythm as a link row, nothing to hover. */
.hd-list .kv { display:flex; justify-content:space-between; gap:.5rem; font-size:.8rem; padding:.28rem 0; color:var(--color-text); border-bottom:1px dashed var(--color-border); }
.hd-list .kv:last-child { border-bottom:0; }
.hd-sub { display:flex; justify-content:space-between; align-items:baseline; font-size:.7rem; font-weight:800; letter-spacing:.06em; text-transform:uppercase; color:var(--color-muted); margin-bottom:.35rem; }
.hd-sub .amt { font-size:.8rem; letter-spacing:0; text-transform:none; color:var(--color-text); }
.hd-bar { height:5px; border-radius:99px; background:var(--color-bg); overflow:hidden; margin:.15rem 0 .45rem; }
.hd-bar > div { height:100%; width:0; border-radius:99px; transition:width .7s cubic-bezier(.4,0,.2,1); }
.hd-kv { display:flex; justify-content:space-between; gap:.5rem; font-size:.78rem; }
.hd-kv .k { display:flex; align-items:center; gap:.4rem; min-width:0; }
.hd-kv .dot { width:8px; height:8px; border-radius:50%; flex-shrink:0; display:inline-block; }
.hd-kv .n { white-space:nowrap; color:var(--color-muted); }

/* ── List screens: one filter bar and one toggle chip, shared by Loans, PF register, Claims… ── */
.list-filters { display:flex; flex-wrap:wrap; gap:.5rem; align-items:center; background:var(--color-surface); border:1px solid var(--color-border); border-radius:var(--radius-md); padding:.6rem .75rem; margin-bottom:.75rem; }
.list-filters .search { position:relative; flex:1 1 260px; max-width:420px; }
.list-filters .search i { position:absolute; left:.7rem; top:50%; transform:translateY(-50%); color:var(--color-muted); }
.list-filters .search input { padding-left:2rem; }
.list-filters .form-control, .list-filters .form-select { height:36px; font-size:.875rem; }
/* TomSelect replaces a .js-searchable select with its own wrapper, which ignores the select's width. */
.list-filters .ts-wrapper { flex:0 1 280px; max-width:280px; min-width:200px; }
.list-filters .ts-wrapper .ts-control { min-height:36px; padding:.3rem .6rem; font-size:.875rem; }
.chip-toggle { position:relative; display:inline-flex; align-items:center; gap:.4rem; height:36px; padding:0 .8rem; border:1px solid var(--color-border); border-radius:99px; font-size:.82rem; font-weight:600; color:var(--color-text); background:var(--color-surface); cursor:pointer; margin:0; user-select:none; }
.chip-toggle:hover { border-color:var(--color-brand); color:var(--color-brand); }
.chip-toggle.on { background:var(--color-warning); border-color:var(--color-warning); color:#fff; }
.chip-toggle input { position:absolute; opacity:0; pointer-events:none; }
/* ── Applied-filter chips: every list says what it is narrowed by, one chip per filter, its × removing that
   filter alone (site.js renderFilterChips, or rendered by the page). The house badge palette (a light tint with
   dark text), not white on the brand colour: an extension that darkens pages inverts hard-coded white and leaves
   the chip unreadable; hover turns the tint to the danger tint so the × reads as "remove". ── */
.applied-row, .loan-applied { display:flex; flex-wrap:wrap; gap:.35rem; align-items:center; flex-basis:100%; width:100%; padding-top:.5rem; border-top:1px dashed var(--color-border); }
.applied-row .applied-label, .loan-applied .applied-label { color:var(--color-text); font-size:.8rem; }
.applied-chip { display:inline-flex; align-items:center; gap:.2rem; padding:.15rem .55rem; border-radius:99px; background:var(--color-brand-light); color:var(--color-brand); border:1px solid var(--color-brand); font-size:.78rem; font-weight:600; text-decoration:none; cursor:pointer; font-family:inherit; line-height:1.4; }
.applied-chip:hover { background:#fff5f5; color:var(--color-danger); border-color:var(--color-danger); }

/* ── Tab row with tools: the tabs on the left, the controls that act on the active tab on the right,
   one underline under both. .emp-tabs keeps its own look; only its border moves up to the row. ── */
.tab-row { display:flex; align-items:flex-end; gap:.75rem; flex-wrap:wrap; border-bottom:2px solid var(--color-border); margin-bottom:.9rem; }
.tab-row .emp-tabs { border-bottom:0; margin-bottom:-2px; flex:1 1 auto; }
.tab-row-tools { display:flex; align-items:center; gap:.5rem; flex-wrap:nowrap; margin-left:auto; padding-bottom:.45rem; }
/* Bootstrap's select is width:100%, which in a flex row pushes everything else onto a new line. */
.tab-row-tools .form-select { width:auto; height:32px; font-size:.8rem; padding-top:.2rem; padding-bottom:.2rem; }
/* A two-state choice reads faster as two buttons than as a dropdown. */
.seg { display:inline-flex; height:32px; border:1px solid var(--color-border); border-radius:var(--radius-md); overflow:hidden; background:var(--color-surface); }
.seg a { display:inline-flex; align-items:center; gap:.3rem; padding:0 .7rem; font-size:.78rem; font-weight:600; color:var(--color-muted); text-decoration:none; border-right:1px solid var(--color-border); white-space:nowrap; }
.seg a:last-child { border-right:0; }
.seg a:hover { color:var(--color-brand); background:var(--color-bg); }
.seg a.active { background:var(--color-brand); color:#fff; }

/* ── "View as employee" preview bar ─────────────────────────── */
/* Amber on purpose: it is the one bar on a self-service page that means "this is not your own
   data". Deeper orange while a preview is actually on, so the state reads from across the room. */
.preview-bar { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem .9rem; padding: .55rem .9rem; margin-bottom: 1rem;
    background: #fffbeb; border: 1px solid #fde68a; border-left: 4px solid #d97706; border-radius: var(--radius-md); }
.preview-bar.is-previewing { background: #fff7ed; border-color: #fdba74; border-left-color: #c2410c; }
.preview-bar-head { display: flex; align-items: center; gap: .55rem; min-width: 0; }
.preview-bar-head > i { color: #b45309; font-size: 1.15rem; }
.preview-bar-title { font-size: .72rem; font-weight: 700; text-transform: uppercase; letter-spacing: .07em; color: #92400e; white-space: nowrap; line-height: 1.2; }
.preview-bar-hint { font-size: .74rem; color: #a16207; line-height: 1.2; }
.preview-bar-picker { flex: 1 1 260px; max-width: 460px; min-width: 0; }
.preview-bar .ts-wrapper.form-select-sm .ts-control { min-height: 34px; }
.preview-bar-state { display: flex; align-items: center; flex-wrap: wrap; gap: .5rem; margin-left: auto; font-size: .8rem; color: #a16207; }
.preview-bar-state .btn-pms-ghost { white-space: nowrap; }
.preview-chip { display: inline-flex; align-items: center; gap: .4rem; padding: .25rem .65rem; border-radius: 999px; background: #c2410c; color: #fff; font-size: .76rem; font-weight: 600; white-space: nowrap; }
.preview-chip .code { opacity: .8; font-weight: 500; font-variant-numeric: tabular-nums; }
/* Two-line options: the name, then code · job title · department in small muted type. */
.pb-opt { display: flex; flex-direction: column; line-height: 1.25; padding: .1rem 0; }
.pb-opt-name { font-weight: 600; font-size: .875rem; }
.pb-opt-sub { font-size: .72rem; color: var(--color-muted); }
.pb-opt-left .pb-opt-name { color: var(--color-muted); font-weight: 500; }
.pb-opt-self { font-style: italic; color: var(--color-muted); font-size: .85rem; }
.pb-item-code { font-size: .74rem; color: var(--color-muted); margin-left: .35rem; } /* the item is a flex box: no whitespace gap */
.ts-dropdown .optgroup-header { font-size: .66rem; font-weight: 700; text-transform: uppercase; letter-spacing: .06em; color: var(--color-muted); }
.ts-dropdown .no-results { padding: .5rem .75rem; color: var(--color-muted); font-size: .85rem; }
@media (max-width: 575.98px) {
    .preview-bar-picker { flex-basis: 100%; max-width: none; }
    .preview-bar-state { margin-left: 0; }
}

/* ── Section label ──────────────────────────────────────────── */
/* The small-caps heading over a group of tiles — the same voice as .pms-card-header-title, for
   sections that are not cards. */
.pms-section-label { display: flex; align-items: center; gap: .4rem; margin: .25rem 0 .6rem; font-size: .72rem; font-weight: 700; text-transform: uppercase; letter-spacing: .07em; color: var(--color-muted); }

/* ── Tax credit: affordability on the approval card, relief by period ── */
/* The approval card is the review for a tax credit; this strip answers the one question the form
   cannot — can it be relieved before the year ends? Amber only when part of it cannot. */
.tax-aff { border: 1px solid var(--color-border); border-radius: 8px; padding: .6rem .8rem; background: var(--color-bg); font-size: .8rem; }
.tax-aff-warn { border-color: #f3c66f; background: #fff8e8; }
.tax-aff-title { font-weight: 600; font-size: .78rem; margin-bottom: .4rem; }
.tax-aff-warn .tax-aff-title { color: #8a5a00; }
.tax-aff-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(128px, 1fr)); gap: .4rem .9rem; }
.tax-aff-grid .k { display: block; font-size: .66rem; text-transform: uppercase; letter-spacing: .06em; color: var(--color-muted); }
.tax-aff-grid .v { display: block; font-weight: 700; font-size: .95rem; font-variant-numeric: tabular-nums; line-height: 1.25; }
.tax-aff-grid .v.warn { color: #8a5a00; }
.tax-aff-grid .s { display: block; font-size: .68rem; color: var(--color-muted); }
.tax-aff-foot { font-size: .74rem; color: var(--color-muted); margin-top: .4rem; }
/* Under "Applied" on both tax-credit listings: which payslips carried the relief. */
.relief-toggle { display: inline-block; font-size: .7rem; color: var(--color-info); text-decoration: none; margin-top: .1rem; }
.relief-toggle:hover { text-decoration: underline; }
.relief-toggle::after { content: " \25BE"; }
.relief-toggle[aria-expanded="true"]::after { content: " \25B4"; }
.relief-list { margin-top: .3rem; font-size: .72rem; font-variant-numeric: tabular-nums; min-width: 150px; }
.relief-list > div { display: flex; justify-content: space-between; gap: .75rem; padding: .12rem 0; border-top: 1px dashed var(--color-border); }
.relief-list > div:first-child { border-top: 0; }
.relief-list .t { font-weight: 600; }
.relief-note { display: block; font-size: .68rem; color: var(--color-muted); }

/* ── Employee filter: the shared remote picker inside a listing's filter bar ── */
/* Same option rendering as the "View as employee" picker (.pb-opt*), so a person looks the same on
   every screen that offers them. It reads as a text box: the search icon overlays Tom Select's
   control as it did the input, and the theme's dropdown caret — a background-image on the WRAPPER
   (.ts-wrapper.single), with right padding reserved through --ts-pr-caret — is removed, because the
   list opens on click regardless. Positioned here, not only under .list-filters, because the same
   control also serves inside plain flex forms (snapshots, a run's salary slips) and as a form field
   (the tax-credit create modal); the flex basis is ignored where the parent is not a flex box. */
.emp-filter { position: relative; flex: 1 1 260px; min-width: 0; }
.emp-filter > i.bi-search { position: absolute; left: .7rem; top: 50%; transform: translateY(-50%); color: var(--color-muted); z-index: 2; pointer-events: none; }
.emp-filter .ts-wrapper { flex: 1 1 auto; max-width: none; min-width: 0; width: 100%; }
.emp-filter .ts-wrapper.single { background-image: none !important; --ts-pr-caret: .75rem; }
.emp-filter .ts-control { padding-left: 2rem !important; padding-right: .75rem !important; min-height: 36px; background-image: none !important; }
.emp-filter .ts-wrapper.single .ts-control, .emp-filter .ts-wrapper.single .ts-control input { cursor: text; }
.emp-filter .ts-dropdown { z-index: 1055; }
.emp-filter .ts-control > div { display: inline-flex; align-items: baseline; gap: .35rem; }
.list-filters .emp-filter { flex: 1 1 300px; max-width: 420px; }
/* A family member in the dependants grid: named, and said whose. */
.pb-opt-dep .pb-opt-name { color: #6d28d9; }
.ts-dropdown .pb-opt-create { font-size: .82rem; color: var(--color-info); }

/* ── Payment batch selection ───────────────────────────────────
   The tick box on a payable row is the whole point of the page, so it is bigger than a form
   check and reads as a control rather than a dot. Shared by the settlement and claims batch pages. */
.pay-check { width: 1.3rem; height: 1.3rem; margin: 0; cursor: pointer; border: 1.5px solid #6b7a90; }
.pay-check:not(:disabled):hover { border-color: var(--color-primary, #1f5f7a); box-shadow: 0 0 0 3px rgba(31,95,122,.12); }
.pay-check:disabled { cursor: not-allowed; opacity: .45; }

