/* mil-lib components. Consumes tokens.css only — NO raw hex here by design. */

body.mil-bg {
    background-color: var(--mil-bg);
    background-image: var(--mil-bg-image);
    color: var(--mil-text);
    min-height: 100vh;
    font-family: var(--mil-font-sans);
    font-size: var(--mil-fs-base);
}

.mil-topbar {
    height: 4px;
    background: linear-gradient(90deg, var(--mil-accent-strong), var(--mil-accent), var(--mil-accent-strong));
}

/* ---- App chrome: dark topbar + horizontal menubar (mil-vms convention) ---- */
.mil-appbar {
    position: sticky;              /* frozen at the very top of every page. Sticky
                                      (not fixed) keeps it in flow, so content below
                                      is never hidden under it. */
    top: 0;
    z-index: 1040;
    background: var(--mil-chrome-bg);
    border-bottom: 3px solid var(--mil-accent);
    color: var(--mil-chrome-text);
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0 var(--mil-space-5);
    min-height: 52px;
    gap: var(--mil-space-3);
    flex-wrap: wrap;
}

.mil-appbar .insignia {
    width: 38px;
    height: 38px;
    border-radius: 50%;
    overflow: hidden;
    padding: 3px;
    background: var(--mil-accent);
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
}

.mil-appbar .insignia img {
    width: 100%;
    height: 100%;
    object-fit: contain;
}

.mil-appbar .brand {
    display: inline-flex;
    flex-direction: column;
    align-items: stretch;          /* both lines take the block's width, so the
                                      justified stretch fills edge-to-edge */
    min-width: 0;                  /* allow ellipsis inside the flex row */
    max-width: min(46vw, 460px);   /* never crowd the nav; long names ellipsis */
    font-weight: 700;
    text-transform: uppercase;
    line-height: 1.15;
    letter-spacing: 0.04em;
}

/* Each lockup line: single-line, left-aligned to the crest, clipped cleanly if
   it can't fit. brandfit.js sets the letter-spacing that width-matches them. */
.mil-appbar .brand [data-fit] {
    display: block;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.mil-appbar .brand small {
    font-size: var(--mil-fs-xs);
    color: var(--mil-chrome-muted);
    letter-spacing: var(--mil-tracking);
    font-weight: 600;
    margin-top: 2px;
}

.mil-appbar-right {
    display: flex;
    align-items: center;
    gap: var(--mil-space-4);
    margin-left: auto;
}

.mil-appbar-right .who { text-align: right; line-height: 1.1; }
.mil-appbar-right .who .nm { font-size: var(--mil-fs-sm); }

.mil-iconbtn {
    background: none;
    border: 1px solid var(--mil-chrome-border);
    color: var(--mil-chrome-text);
    border-radius: var(--mil-radius);
    width: 34px;
    height: 34px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    text-decoration: none;
}

.mil-iconbtn:hover { background: var(--mil-chrome-hover); color: var(--mil-chrome-text); }

.mil-menubar {
    position: sticky;                          /* frozen directly below the topbar */
    /* Cascaded overlap: each frozen layer pins a few px INTO the layer above it
       (which has a higher z-index and hides the overlap), so sub-pixel rounding
       at non-100% browser zoom can never open a seam that a scrolling row peeks
       through. --sticky-overlap is the per-seam margin; layer N subtracts N×. */
    top: calc(var(--shell-topbar-h, 52px) - var(--sticky-overlap, 4px));
    z-index: 1030;
    background: var(--mil-chrome-2);
    display: flex;
    align-items: center;
    padding: 0 var(--mil-space-5);
    gap: 2px;
    flex-wrap: wrap;
}

/* Top-level links and dropdown toggles — NOT the items inside a dropdown
   (those are styled separately below). */
.mil-menubar > a,
.mil-menubar > .dropdown > a {
    color: var(--mil-chrome-muted);
    text-decoration: none;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    font-size: var(--mil-fs-sm);
    font-weight: 600;
    padding: 12px var(--mil-space-4);
    display: inline-flex;
    align-items: center;
    gap: 6px;
    white-space: nowrap;
}
.mil-menubar > a i,
.mil-menubar > .dropdown > a i { color: var(--mil-accent); }
.mil-menubar > a:hover,
.mil-menubar > .dropdown > a:hover { background: var(--mil-accent); color: var(--mil-accent-contrast); }
.mil-menubar > a:hover i,
.mil-menubar > .dropdown > a:hover i { color: var(--mil-accent-contrast); }
.mil-menubar > a.active,
.mil-menubar > .dropdown > a.active { background: var(--mil-accent); color: var(--mil-accent-contrast); }
.mil-menubar > a.active i,
.mil-menubar > .dropdown > a.active i { color: var(--mil-accent-contrast); }

/* Push a node (the Admin gear) to the right edge of the bar. */
.mil-menubar .mil-push { margin-left: auto; }

/* Grouped dropdown menus — dark chrome in BOTH themes so they match the bar,
   never Bootstrap's default light panel. Items read as a quieter submenu (not a
   second row of shouting uppercase buttons). */
.mil-menubar .dropdown-toggle::after { margin-left: 6px; opacity: 0.75; vertical-align: middle; }
.mil-menubar .dropdown-menu {
    background: var(--mil-chrome-bg);
    border: 1px solid var(--mil-chrome-border);
    border-radius: 0 0 var(--mil-radius) var(--mil-radius);
    padding: 4px;
    margin-top: 0;
    min-width: 12rem;
    box-shadow: var(--mil-shadow);
}
.mil-menubar .dropdown-item {
    color: var(--mil-chrome-text);
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 9px 12px;
    font-size: var(--mil-fs-sm);
    font-weight: 500;
    letter-spacing: 0.02em;
    text-transform: none;
    border-radius: var(--mil-radius-sm);
}
.mil-menubar .dropdown-item i { color: var(--mil-accent); font-size: 1rem; }
.mil-menubar .dropdown-item:hover,
.mil-menubar .dropdown-item:focus,
.mil-menubar .dropdown-item.active { background: var(--mil-accent); color: var(--mil-accent-contrast); }
.mil-menubar .dropdown-item:hover i,
.mil-menubar .dropdown-item:focus i,
.mil-menubar .dropdown-item.active i { color: var(--mil-accent-contrast); }

/* Below desktop the few top items simply wrap — no horizontal scroll, so the
   dropdown menus are never clipped. Desktop (>=992px) is untouched. */
@media (max-width: 991.98px) {
    .mil-menubar { padding-left: var(--mil-space-3); padding-right: var(--mil-space-3); }
}

/* ---- Brand wordmark ---- */
.mil-brand {
    letter-spacing: 0.35em;
    text-transform: uppercase;
    font-weight: 700;
}

.mil-brand .dot { color: var(--mil-accent); }

.mil-tagline {
    letter-spacing: var(--mil-tracking-wide);
    text-transform: uppercase;
    font-size: 0.72rem;
    color: var(--mil-muted);
}

/* ---- Cards / surfaces ---- */
.mil-card {
    background: var(--mil-surface);
    border: 1px solid var(--mil-border);
    border-radius: var(--mil-radius);
    box-shadow: var(--mil-shadow);
    color: var(--mil-text);
}

.mil-card-accent { border-top: 3px solid var(--mil-accent); }

.mil-label {
    text-transform: uppercase;
    letter-spacing: var(--mil-tracking);
    font-size: 0.72rem;
    color: var(--mil-muted);
}

.mil-section-title {
    color: var(--mil-accent);
    text-transform: uppercase;
    letter-spacing: 0.05em;
    font-weight: 700;
    font-size: var(--mil-fs-sm);
}

/* ---- Inputs ---- */
.form-control.mil-input,
.form-select.mil-input {
    background: var(--mil-surface-2);
    border: 1px solid var(--mil-border);
    color: var(--mil-text);
}

.form-control.mil-input:focus,
.form-select.mil-input:focus {
    background: var(--mil-surface-2);
    color: var(--mil-text);
    border-color: var(--mil-accent);
    box-shadow: 0 0 0 0.2rem var(--mil-focus-ring);
}

/* ---- Buttons ---- */
.btn-mil {
    background: var(--mil-accent);
    border: 1px solid var(--mil-accent);
    color: var(--mil-accent-contrast);
    text-transform: uppercase;
    letter-spacing: var(--mil-tracking);
    font-weight: 600;
}

.btn-mil:hover,
.btn-mil:focus {
    background: var(--mil-accent-strong);
    border-color: var(--mil-accent-strong);
    color: var(--mil-accent-contrast);
}

/* ---- Notices / chips / badges ---- */
.mil-notice {
    border: 1px dashed var(--mil-border);
    color: var(--mil-muted);
    text-transform: uppercase;
    letter-spacing: var(--mil-tracking);
    font-size: 0.7rem;
}

.mil-badge-role {
    background: var(--mil-accent);
    color: var(--mil-accent-contrast);
    letter-spacing: 0.1em;
    text-transform: uppercase;
}

.mil-chip {
    background: var(--mil-surface-2);
    border: 1px solid var(--mil-border);
    color: var(--mil-text);
    border-radius: var(--mil-radius-sm);
    padding: 0.3rem 0.6rem;
    font-size: 0.8rem;
}

.mil-chip .tick { color: var(--mil-success); }

.mil-footer {
    color: var(--mil-muted);
    letter-spacing: 0.1em;
    font-size: 0.7rem;
    text-transform: uppercase;
}

a.mil-link { color: var(--mil-muted); text-decoration: none; }
a.mil-link:hover { color: var(--mil-accent); }

/* Let Bootstrap's dark/light components track our surface tokens. */
[data-bs-theme] {
    --bs-body-bg: var(--mil-bg);
    --bs-body-color: var(--mil-text);
    --bs-border-color: var(--mil-border);
    --bs-primary: var(--mil-accent);
}

.table { --bs-table-bg: var(--mil-surface); --bs-table-color: var(--mil-text); }
.card { background: var(--mil-surface); border-color: var(--mil-border); }

/* Bootstrap 5 pagination, tokenised so it matches the app surface in both themes.
   (Pagination itself is switched on via Paginator::useBootstrapFive().) */
.pagination {
    --bs-pagination-color: var(--mil-text);
    --bs-pagination-bg: var(--mil-surface);
    --bs-pagination-border-color: var(--mil-border);
    --bs-pagination-hover-color: var(--mil-accent);
    --bs-pagination-hover-bg: var(--mil-surface-2);
    --bs-pagination-hover-border-color: var(--mil-border);
    --bs-pagination-focus-color: var(--mil-accent);
    --bs-pagination-focus-bg: var(--mil-surface-2);
    --bs-pagination-focus-box-shadow: 0 0 0 0.2rem var(--mil-focus-ring);
    --bs-pagination-active-color: var(--mil-accent-contrast);
    --bs-pagination-active-bg: var(--mil-accent);
    --bs-pagination-active-border-color: var(--mil-accent);
    --bs-pagination-disabled-color: var(--mil-muted);
    --bs-pagination-disabled-bg: var(--mil-surface);
    --bs-pagination-disabled-border-color: var(--mil-border);
}

/* Base guard: an inline SVG with no explicit dimensions can never blow up the
   layout (the old Tailwind-pagination overflow). Charts set width+height
   attributes, so they're excluded. */
svg:not([width]):not([height]) { max-width: 1.5rem; max-height: 1.5rem; }

/* =========================================================================
   Dashboard — a dense operations console. Tokens only; colour carries meaning.
   ========================================================================= */
.dash-head { display: flex; flex-wrap: wrap; justify-content: space-between;
    align-items: flex-end; gap: var(--mil-space-2); margin-bottom: var(--mil-space-5); }
.dash-head h1 { font-size: 1.5rem; margin: 0; font-weight: 700; }
.dash-meta { color: var(--mil-muted); font-size: var(--mil-fs-sm); text-align: right; }

/* Quick actions — a compact command row of links to existing routes. One row on
   desktop; wraps on mobile. Restrained: bordered tiles with an accent icon that
   fill on hover, matching the mil chrome (no soft consumer buttons). */
.dash-quick { display: flex; flex-wrap: wrap; gap: var(--mil-space-2); margin-bottom: var(--mil-space-5); }
.dash-quick a { display: inline-flex; align-items: center; gap: 8px;
    padding: 9px var(--mil-space-4); background: var(--mil-surface);
    border: 1px solid var(--mil-border); border-radius: var(--mil-radius);
    color: var(--mil-text); text-decoration: none; font-size: var(--mil-fs-sm);
    font-weight: 600; text-transform: uppercase; letter-spacing: 0.05em;
    transition: background .12s, border-color .12s, color .12s; }
.dash-quick a i { color: var(--mil-accent); font-size: 1rem; }
.dash-quick a:hover { background: var(--mil-accent); border-color: var(--mil-accent);
    color: var(--mil-accent-contrast); }
.dash-quick a:hover i { color: var(--mil-accent-contrast); }

/* Section label + rule, so blocks read as one system. */
.dash-section { display: flex; align-items: center; gap: var(--mil-space-3);
    margin: var(--mil-space-5) 0 var(--mil-space-3); }
.dash-section:first-of-type { margin-top: 0; }
.dash-section .mil-label { white-space: nowrap; }
.dash-section .rule { flex: 1; height: 1px; background: var(--mil-border); }

/* Card row — flex, so it fits however many cards it's given: 5 across on a
   normal desktop, growing to fill the row when there are 3–4 (a lean/COUNTER
   view), wrapping to 3 then 2 as the viewport narrows. No hardcoded column
   count. The 168px basis is the point where 5 still fit at the lg container and
   4 no longer crowd the tablet width. */
.dash-cards { display: flex; flex-wrap: wrap; gap: var(--mil-space-3); align-items: stretch; }
.dash-cards > .dash-stat { flex: 1 1 168px; }

/* Stat card — compact, left tone-rule, quiet hover. Height is left to `auto` so
   align-items: stretch equalises every card in a line to the tallest (a card
   with a subtitle, or a subtitle that wraps to two lines). An explicit height
   here — even 100% — suppresses stretch and each card sizes to its own content,
   leaving the row bottoms ragged. Content stays top-aligned; the extra height is
   empty space at the foot of the shorter cards. */
.dash-stat { display: block; background: var(--mil-surface); border: 1px solid var(--mil-border);
    border-left: 3px solid var(--mil-accent); border-radius: var(--mil-radius);
    padding: var(--mil-space-3); color: var(--mil-text);
    text-decoration: none; transition: border-color .12s, transform .12s; }
a.dash-stat:hover { border-left-color: var(--mil-accent); transform: translateY(-1px);
    box-shadow: var(--mil-shadow-sm); }
.dash-stat .l { text-transform: uppercase; letter-spacing: var(--mil-tracking);
    font-size: 0.66rem; color: var(--mil-muted); display: flex; align-items: center;
    gap: 6px; margin-bottom: 2px; }
.dash-stat .k { font-size: 1.5rem; font-weight: 700; line-height: 1.05; font-variant-numeric: tabular-nums; }
.dash-stat .s { font-size: var(--mil-fs-sm); color: var(--mil-muted); margin-top: 2px; }
/* Semantic figure colour: the big number carries meaning — attention (danger),
   caution (warning), healthy (success) — via text-tuned tokens legible on the
   card surface in both themes. Neutral counts keep the default text colour. The
   left tone-rule and label icon stay on the saturated status tokens. */
.dash-stat.tone-danger { border-left-color: var(--mil-danger); }
.dash-stat.tone-danger .k { color: var(--mil-fg-danger); }
.dash-stat.tone-danger .l i { color: var(--mil-danger); }
.dash-stat.tone-warning { border-left-color: var(--mil-warning); }
.dash-stat.tone-warning .k { color: var(--mil-fg-warning); }
.dash-stat.tone-warning .l i { color: var(--mil-warning); }
.dash-stat.tone-success { border-left-color: var(--mil-success); }
.dash-stat.tone-success .k { color: var(--mil-fg-success); }
.dash-stat.tone-success .l i { color: var(--mil-success); }
.dash-stat .l i { color: var(--mil-accent); }

/* Alert band — the one thing that shouts, and only when it must. */
.dash-alert { border: 1px solid var(--mil-border); border-left: 3px solid var(--mil-danger);
    background: var(--mil-surface); border-radius: var(--mil-radius);
    padding: var(--mil-space-3) var(--mil-space-4); margin-bottom: var(--mil-space-5);
    display: flex; flex-wrap: wrap; align-items: center; gap: var(--mil-space-2) var(--mil-space-5); }
.dash-alert .hd { text-transform: uppercase; letter-spacing: var(--mil-tracking);
    font-size: 0.66rem; color: var(--mil-muted); display: flex; align-items: center; gap: 6px; }
.dash-alert a { text-decoration: none; color: var(--mil-text); font-size: 0.95rem; }
.dash-alert a:hover { text-decoration: underline; }
.dash-alert .n-danger { color: var(--mil-danger); font-weight: 700; }
.dash-alert .n-warning { color: var(--mil-warning); font-weight: 700; }

/* Panels + charts. */
.dash-panel { background: var(--mil-surface); border: 1px solid var(--mil-border);
    border-radius: var(--mil-radius); }
.dash-panel .hd { padding: var(--mil-space-3) var(--mil-space-4);
    border-bottom: 1px solid var(--mil-border); }
.dash-panel .bd { padding: var(--mil-space-3) var(--mil-space-4); }
.mil-chart { width: 100%; min-height: 60px; }
/* The chart SVG is drawn at an explicit pixel width by mil-charts; cap it to the
   container so a narrow (phone) viewport can never be pushed wider than the
   screen. Inert on desktop, where the SVG already fits. Scales proportionally
   via its viewBox. */
.mil-chart svg { max-width: 100%; height: auto; }

.dash-feed { width: 100%; border-collapse: collapse; }
.dash-feed td { padding: 8px var(--mil-space-4); border-top: 1px solid var(--mil-border); font-size: 0.9rem; }
.dash-feed tr:first-child td { border-top: 0; }
.dash-feed .verb { font-size: 0.62rem; text-transform: uppercase; letter-spacing: .08em;
    font-weight: 700; padding: 2px 7px; border-radius: var(--mil-radius-sm); border: 1px solid currentColor; }
.dash-feed .who { color: var(--mil-muted); font-size: var(--mil-fs-sm); }
.dash-sys li { display: flex; justify-content: space-between; padding: 7px 0;
    border-bottom: 1px solid var(--mil-border); font-size: 0.9rem; }
.dash-sys li:last-child { border-bottom: 0; }
.dash-sys .lbl { color: var(--mil-muted); }

/* =========================================================================
   Circulation counter — the mode banner after each scan. Colour carries the
   action: green issue, blue return, amber pending, red block. Tokens only.
   ========================================================================= */
.circ-mode { display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
    background: var(--mil-surface); border: 1px solid var(--mil-border);
    border-left: 4px solid var(--mil-accent); border-radius: var(--mil-radius);
    padding: var(--mil-space-3) var(--mil-space-4); margin-bottom: var(--mil-space-4);
    font-size: 0.95rem; }
.circ-mode .tag { font-weight: 700; text-transform: uppercase; letter-spacing: 0.06em;
    font-size: 0.8rem; display: inline-flex; align-items: center; gap: 6px; }
.circ-mode.issue { border-left-color: var(--mil-success); }
.circ-mode.issue .tag { color: var(--mil-fg-success); }
.circ-mode.return { border-left-color: var(--mil-info); }
.circ-mode.return .tag { color: var(--mil-info); }
.circ-mode.member { border-left-color: var(--mil-accent); }
.circ-mode.member .tag { color: var(--mil-accent); }
.circ-mode.warning { border-left-color: var(--mil-warning); }
.circ-mode.warning .tag { color: var(--mil-fg-warning); }
.circ-mode.error { border-left-color: var(--mil-danger); }
.circ-mode.error .tag { color: var(--mil-fg-danger); }

/* Operator-first counter layout — centred column, the scan box dominates and
   sits high (upper-middle) so it's the first thing the eye lands on. Everything
   else is subordinate. Tokens only; works in both themes; responsive. */
.circ-counter {
    max-width: 800px;
    margin-inline: auto;
    padding-top: clamp(var(--mil-space-4), 5vh, 56px);
}
.scan-box { padding: var(--mil-space-5); }
.scan-box .scan-title {
    color: var(--mil-accent);
    text-transform: uppercase;
    letter-spacing: var(--mil-tracking);
    font-weight: 700;
    font-size: 1rem;
    margin-bottom: var(--mil-space-3);
    display: flex;
    align-items: center;
    gap: var(--mil-space-2);
}
.scan-row { display: flex; gap: var(--mil-space-3); align-items: stretch; }
.scan-input-xl {
    font-size: 1.7rem;
    height: 68px;
    padding: 0 var(--mil-space-4);
    letter-spacing: 0.03em;
    flex: 1 1 auto;
    min-width: 0;
}
.scan-btn-xl {
    height: 68px;
    padding-inline: var(--mil-space-5);
    font-size: 1.05rem;
    white-space: nowrap;
    display: inline-flex;
    align-items: center;
    gap: var(--mil-space-2);
}
/* How-to — a slim, unobtrusive toggle that carries no card weight when closed. */
.howto-toggle {
    display: inline-flex; align-items: center; gap: var(--mil-space-2);
    background: none; border: 0; cursor: pointer;
    color: var(--mil-muted);
    text-transform: uppercase; letter-spacing: var(--mil-tracking);
    font-size: 0.72rem; padding: var(--mil-space-2) 0;
}
.howto-toggle:hover { color: var(--mil-text); }
.howto-toggle .bi-chevron-down { transition: transform 0.15s ease; }
.howto-toggle[aria-expanded="true"] .bi-chevron-down { transform: rotate(180deg); }

@media (max-width: 575.98px) {
    .circ-counter { padding-top: var(--mil-space-4); }
    .scan-row { flex-direction: column; }
    .scan-btn-xl { width: 100%; justify-content: center; }
    .scan-input-xl { font-size: 1.35rem; height: 60px; }
}

/* Appbar user menu — the who badge is now a dropdown toggle. */
.mil-appbar-right .who {
    background: none; border: 0; cursor: pointer; color: var(--mil-chrome-text);
    display: inline-flex; flex-direction: column; align-items: flex-end;
    text-align: right; line-height: 1.1; padding: 2px 0;
}
.mil-appbar-right .who.dropdown-toggle::after {
    position: absolute; content: none;
}
.mil-appbar-right .who .nm { font-size: var(--mil-fs-sm); }
.mil-usermenu {
    background: var(--mil-chrome-bg); border: 1px solid var(--mil-chrome-border);
    border-radius: var(--mil-radius); padding: 4px; min-width: 12rem; box-shadow: var(--mil-shadow);
}
.mil-usermenu .dropdown-item {
    color: var(--mil-chrome-text); display: flex; align-items: center; gap: 8px;
    padding: 9px 12px; font-size: var(--mil-fs-sm); border-radius: var(--mil-radius-sm);
}
.mil-usermenu .dropdown-item i { color: var(--mil-accent); }
.mil-usermenu .dropdown-item:hover,
.mil-usermenu .dropdown-item:focus { background: var(--mil-accent); color: var(--mil-accent-contrast); }
.mil-usermenu .dropdown-item:hover i,
.mil-usermenu .dropdown-item:focus i { color: var(--mil-accent-contrast); }

/* =========================================================================
   Sticky list scaffolding — a pinned search/toolbar with the table header
   pinned directly beneath it, both frozen against the WINDOW scroll. Generic
   and reusable across paginated lists (catalogue first). Tokens only, both
   themes. The appbar/menubar are normal-flow, so top offsets start at 0.
   ========================================================================= */

/* Per-seam overlap margin for the frozen stack. 4px comfortably absorbs the
   sub-pixel rounding that browser zoom (roughly 80%–150%) introduces at each
   seam; raise it if a client runs even more extreme zoom. */
:root { --sticky-overlap: 4px; }

/* Page-title + action buttons row, frozen directly below the nav shell and
   above the search bar. Solid page-surface background so rows can't show through.
   --shell-h (topbar + nav) is measured at runtime by stickylist.js. */
.sticky-actionbar {
    position: sticky;
    top: calc(var(--shell-h, 0px) - 2 * var(--sticky-overlap, 4px));
    z-index: 25;
    background: var(--mil-bg);
}

/* The search/filter card, frozen directly below the action row. mil-card paints
   a solid surface so scrolled rows can't show through. --sticky-action-h is the
   measured action-row height. */
.sticky-toolbar {
    position: sticky;
    top: calc(var(--shell-h, 0px) + var(--sticky-action-h, 0px) - 3 * var(--sticky-overlap, 4px));
    z-index: 20;
    background: var(--mil-surface);
}

/* The responsive wrapper must NOT be a vertical scroll container, or a sticky
   thead attaches to it (which never scrolls) instead of the window. So we drop
   overflow on desktop and only re-enable horizontal scroll on narrow screens —
   where the sticky header then degrades gracefully rather than breaking. */
.sticky-table-wrap { overflow: visible; }

/* Distinct header surface (subtle, tinted) + frozen directly below the toolbar.
   --sticky-toolbar-h is measured at runtime (stickylist.js); falls back to 0. */
.sticky-table thead th {
    position: sticky;
    /* Deepest frozen layer. The cascade shifts it up 4×overlap, but relative to
       the (also-shifted) search bar above it the net overlap is exactly one
       --sticky-overlap (4px) — small enough that the default cell padding keeps
       the caption clear of the hidden zone, yet enough that zoom-rounding can
       never open the header/row seam. */
    top: calc(var(--shell-h, 0px) + var(--sticky-action-h, 0px) + var(--sticky-toolbar-h, 0px) - 4 * var(--sticky-overlap, 4px));
    z-index: 10;
    background: var(--mil-surface-2);
    border-bottom: 1px solid var(--mil-border);
}

@media (max-width: 767.98px) {
    .sticky-table-wrap { overflow-x: auto; }
}
