/* ============================================================================
   admin.css   -   PHASE 1: keep the shared helpers alive through a reskin

   Seventeen of the twenty-two admin pages have an empty Page_Load. They are
   entirely JavaScript against Api/*.ashx, and every one of them calls into the
   ALA helpers in Scripts/app.js:

       ALA.toast        -> #alaToastHost > .ala-toast
       ALA.busy         -> #alaBusy > .ala-spin
       ALA.confirm      -> #alaConfirm.ala-modal-backdrop > .ala-modal
       ALA.markInvalid  -> .field.invalid > .err
       ALA.renderPager  -> .pager > button, .pinfo

   Every one of those class names is styled in Content/site.css and nowhere else.
   The moment Admin.master stops loading site.css, all seventeen pages lose their
   toasts, their loading overlay, their confirmations, their field errors and
   their paging - and they lose them SILENTLY. The element is still created and
   appended; it just has no position, no background and no colour.

   That is the exact bug that bit the applicant login twice and the wizard modal
   once. Fixing it seventeen times after the fact is the expensive way. This file
   is the cheap way: define the same contract once, in the new palette, so the
   reskin in Phase 3 changes how the admin area looks without changing whether it
   works.

   Nothing in Scripts/app.js changes. Nothing in the seventeen pages changes.

   Load AFTER bootstrap and app.min.css so these win where they overlap.
   ============================================================================ */

:root {
    --ad-navy:   #12243D;   /* admin sidebar - deliberately not the applicant blue */
    --ad-ink:    #1E2D50;
    --ad-muted:  #6B7A90;
    --ad-line:   #E4E9F2;
    --ad-ok:     #1E7F4F;
    --ad-err:    #C0392B;
    --ad-warn:   #8A6100;
    --ad-accent: #0B4EA2;

    /* ------------------------------------------------------------------
       COMPATIBILITY ALIASES

       Every admin page carries its own <style> block, and those blocks were
       written against the APPLICANT palette in Content/site.css - var(--line),
       var(--red), var(--r) and so on. Admin.master does not load site.css, so
       all of those resolved to nothing: CSS variables fail silently, which is
       why affected panels rendered with no border, square corners and default
       colours instead of erroring visibly.

       Twenty-one pages were written that way. Defining the names here once, in
       admin values, fixes them all and lets a page keep using whichever
       vocabulary its author reached for. These are ALIASES, not a second
       palette - each maps onto the --ad-* value above it, so the admin area
       still has one source of truth and cannot drift from the applicant theme.
       ------------------------------------------------------------------ */
    --line:      var(--ad-line);      /* #E4E9F2 - hairlines, card borders   */
    --muted:     var(--ad-muted);     /* #6B7A90 - secondary text            */
    --ink:       var(--ad-ink);       /* #1E2D50 - primary text              */
    --black:     var(--ad-navy);      /* #12243D - headings, dark fills      */
    --red:       var(--ad-accent);    /* #0B4EA2 - the admin accent          */
    --red-deep:  var(--ad-navy);      /* deeper accent for hovers            */
    --royal:     var(--ad-accent);
    --danger:    var(--ad-err);       /* #C0392B                             */
    --paper:     #F7F9FC;             /* page-tint fills                     */
    --gold-soft: #FFF6E0;             /* soft highlight banner               */
    --red-soft:  #EAF1FA;
    --ok:        var(--ad-ok);
    --warn:      var(--ad-warn);
    --r:         8px;                 /* admin corners; applicant side is 6px */
}

/* ===== sidebar identity card ====================================== */
/* Margin is small on purpose: at 12px each side the card read as a floating
   tile in a wide gutter. 8px lets it fill the column while still reading as an
   inset panel rather than a full-bleed band. */
.dl-idcard {
    background: var(--dl-blue-card);
    border: 1px solid rgba(255, 255, 255, .10);
    border-radius: 10px;
    padding: 18px 12px 16px;
    margin: 12px 10px 8px;
    text-align: center;
    /* The sidebar's inner wrapper is a flex column with align-items:start, so a
       child sizes to its content unless told otherwise. Every margin reduction
       so far was treating a symptom. */
    align-self: stretch;
}

    .dl-idcard img {
        width: 92px;
        height: 92px;
        border-radius: 50%;
        object-fit: cover;
        border: 4px solid rgba(255, 255, 255, .90);
        background: #001738;
    }

    .dl-idcard .dl-id {
        margin-top: 12px;
        font-size: 13px;
        font-weight: 700;
        letter-spacing: .04em;
        color: #ffffff;
        overflow-wrap: anywhere;
    }

    .dl-idcard .dl-sub {
        margin-top: 3px;
        font-size: 11px;
        color: rgba(255, 255, 255, .66);
    }
    /* Square, per house style - no pill radii on status chips anywhere. */
    .dl-idcard .dl-status {
        display: inline-block;
        margin-top: 10px;
        padding: 4px 14px;
        border-radius: 0;
        font-size: 10px;
        font-weight: 700;
        letter-spacing: .08em;
        text-transform: uppercase;
        background: rgba(44, 198, 224, .18);
        color: #7FDCEE;
    }

        .dl-idcard .dl-status.ok {
            background: #1877D2;
            color: #ffffff;
        }


/* ===== toast ======================================================
   Bottom centre, stacked, above everything. Bottom rather than top because the
   admin pages put their action buttons at the top of a card, and a toast that
   covers the button you just pressed is worse than useless. */
#alaToastHost {
    position: fixed;
    left: 50%;
    bottom: 22px;
    transform: translateX(-50%);
    z-index: 5200;
    display: flex;
    flex-direction: column;
    gap: 8px;
    align-items: center;
    pointer-events: none;
    width: max-content;
    max-width: calc(100vw - 32px);
}
.ala-toast {
    background: var(--ad-ink);
    color: #fff;
    border: 1px solid transparent;
    border-radius: 8px;
    padding: 12px 18px;
    font-size: .88rem;
    font-weight: 500;
    line-height: 1.4;
    box-shadow: 0 10px 30px rgba(4, 18, 38, .30);
    pointer-events: auto;
    max-width: 460px;
    overflow-wrap: anywhere;
}
/* The whole toast carries the outcome, not a 4px stripe on a dark slab -
   a thin coloured edge is easy to miss and reads as decoration. Light
   background with dark text of the same hue stays legible and does not
   shout. */
.ala-toast.ok  { background: #E7F7EE; border: 1px solid #9BDCBB; border-left: 1px solid #9BDCBB;
                 color: #0E5132; box-shadow: 0 8px 22px rgba(14, 81, 50, .16); }
.ala-toast.err { background: #FDECEC; border: 1px solid #F2B5B5; border-left: 1px solid #F2B5B5;
                 color: #8B1F1F; box-shadow: 0 8px 22px rgba(139, 31, 31, .16); }


/* ===== busy overlay ===============================================
   app.js appends #alaBusy once and toggles .open. Without the display:none
   default it would sit over the page permanently from first load. */
#alaBusy {
    position: fixed;
    inset: 0;
    background: rgba(244, 246, 249, .74);
    z-index: 5100;
    display: none;
    align-items: center;
    justify-content: center;
}
#alaBusy.open { display: flex; }
.ala-spin {
    width: 42px;
    height: 42px;
    border: 4px solid var(--ad-line);
    border-top-color: var(--ad-accent);
    border-radius: 50%;
    animation: ala 700ms linear infinite;
}
/* The keyframes are named "ala" in site.css and app.js references that name
   indirectly through the class. Redeclared here so the spinner still turns when
   site.css is gone. */
@keyframes ala { to { transform: rotate(360deg); } }

/* ===== confirm dialog =============================================
   app.js builds this markup itself and toggles .open, so the class names are
   fixed - they cannot be swapped for Bootstrap's modal without editing the
   shared helper, which the applicant pages also use. */
.ala-modal-backdrop {
    display: none;
    position: fixed;
    inset: 0;
    z-index: 5300;
    background: rgba(4, 18, 38, .55);
    align-items: center;
    justify-content: center;
    padding: 18px;
}
.ala-modal-backdrop.open { display: flex; }
/* Fallback for very short viewports - if the capped modal still cannot fit,
   the backdrop itself scrolls rather than trapping the footer off-screen. */
.ala-modal-backdrop { overflow-y: auto; }
.ala-modal {
    background: #fff;
    border-radius: 10px;
    width: 100%;
    max-width: 460px;
    box-shadow: 0 18px 48px rgba(0, 0, 0, .28);
    overflow: hidden;
    /* Without these a tall modal grows past the viewport and "overflow: hidden"
       clips the footer, so Save and Cancel end up off-screen and unreachable -
       exactly what happened to the shortlist template editor with its twelve-row
       SQL box. Capping the height and making the modal a flex column keeps the
       header and footer pinned while only the body scrolls. The applicant
       stylesheet has had this since it was written; the admin copy lost it.
       36px is the backdrop's 18px padding, top and bottom. */
    max-height: calc(100vh - 36px);
    display: flex;
    flex-direction: column;
}
.ala-modal-head, .ala-modal-foot { flex: 0 0 auto; }
.ala-modal-head {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 15px 18px;
    border-bottom: 1px solid var(--ad-line);
}
.ala-modal-head h3 {
    margin: 0;
    font-size: .98rem;
    font-weight: 700;
    color: var(--ad-ink);
}
.ala-modal-x {
    margin-left: auto;
    background: none;
    border: 0;
    font-size: 22px;
    line-height: 1;
    color: var(--ad-muted);
    cursor: pointer;
    padding: 0 2px;
}
.ala-modal-body {
    padding: 16px 18px; font-size: .89rem; color: #22303F;
    flex: 1 1 auto;
    overflow-y: auto;
    /* iOS clips scrollable flex children without this. */
    -webkit-overflow-scrolling: touch;
    min-height: 0;
}
.ala-modal-foot {
    padding: 12px 18px;
    border-top: 1px solid var(--ad-line);
    display: flex;
    gap: 9px;
    justify-content: flex-end;
}

/* ===== the buttons the confirm dialog uses ========================
   app.js hard-codes .btn-ala and .btn-ala-ghost on its Cancel and Continue
   buttons. Those are site.css classes. Without them here the dialog renders two
   lines of plain blue text where its buttons should be - which is exactly how
   "Raise a ticket" looked on the help desk. */
.btn-ala, .btn-ala-ghost, .btn-ala-outline {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 7px;
    font: 600 .88rem/1 inherit;
    padding: 10px 16px;
    border-radius: 7px;
    border: 1px solid transparent;
    cursor: pointer;
    text-decoration: none;
    white-space: nowrap;
}
.btn-ala { background: var(--ad-accent); border-color: var(--ad-accent); color: #fff; }
.btn-ala:hover { background: #09407F; border-color: #09407F; color: #fff; }
.btn-ala-ghost { background: #fff; border-color: var(--ad-line); color: var(--ad-ink); }
.btn-ala-ghost:hover { background: #F4F7FB; color: var(--ad-ink); }
.btn-ala-outline { background: transparent; border-color: var(--ad-accent); color: var(--ad-accent); }
.btn-ala-outline:hover { background: #EEF3FA; }
.btn-ala.btn-sm, .btn-ala-ghost.btn-sm, .btn-ala-outline.btn-sm {
    padding: 7px 12px;
    font-size: .82rem;
}
.btn-ala[disabled], .btn-ala-ghost[disabled] { opacity: .55; cursor: default; }

/* ===== field errors ===============================================
   ALA.markInvalid walks up to .field, toggles .invalid on it and writes into a
   .err inside it. Both class names have to survive, and .err must stay hidden
   until .invalid is set or every field would show its message at rest. */
.field { margin-bottom: 14px; }
.field > label {
    display: block;
    font-size: .8rem;
    font-weight: 600;
    color: var(--ad-ink);
    margin-bottom: 4px;
}
.field > label .req { color: var(--ad-err); }
.field .hint { display: block; font-size: .76rem; color: var(--ad-muted); margin-top: 4px; }
.field .err  { display: none; font-size: .78rem; color: var(--ad-err); margin-top: 4px; }

.field.invalid .form-control,
.field.invalid .form-select,
.field.invalid input[type=text],
.field.invalid input[type=password],
.field.invalid input[type=number],
.field.invalid input[type=date],
.field.invalid select,
.field.invalid textarea {
    border-color: var(--ad-err);
    box-shadow: 0 0 0 .18rem rgba(192, 57, 43, .12);
}
.field.invalid .err { display: block; }

/* ===== pager ======================================================
   ALA.renderPager emits <span class="pinfo"> plus bare <button> elements inside
   the host, with .on for the current page. It does not use Bootstrap's
   pagination markup, so Bootstrap's pagination CSS never reaches it. */
.pager {
    display: flex;
    gap: 6px;
    align-items: center;
    justify-content: center;
    flex-wrap: wrap;
    margin-top: 16px;
    padding-top: 14px;
    border-top: 1px dashed #DDE5EF;
}
.pager .pinfo {
    font-size: .78rem;
    color: var(--ad-muted);
    margin-right: auto;
}
.pager button {
    min-width: 36px;
    height: 36px;
    padding: 0 10px;
    border: 1px solid var(--ad-line);
    background: #fff;
    border-radius: 7px;
    font-size: .82rem;
    font-weight: 600;
    color: var(--ad-ink);
    cursor: pointer;
}
.pager button:hover:not([disabled]) { background: #F4F7FB; }
.pager button.on {
    background: var(--ad-accent);
    border-color: var(--ad-accent);
    color: #fff;
    font-weight: 700;
}
.pager button[disabled] { opacity: .45; cursor: default; }

@media screen and (max-width: 575.98px) {
    /* The record count is the first thing to go - the buttons are what get used. */
    .pager .pinfo { width: 100%; margin: 0 0 8px; text-align: center; }
}

/* ===== change-password dialog =====================================
   ALA.changePassword builds its own modal (#alaPwd) with an eye toggle inside
   each field. It reuses .ala-modal-* above, so only the password wrapper and the
   toggle need adding.

   Found by checking every selector app.js emits against this file rather than by
   reading the pages - none of the seventeen mentions #alaPwd, because the helper
   creates it at runtime. It would have shipped unstyled and only surfaced when a
   member of staff tried to change their password. */
.pwd-wrap { position: relative; }
.pwd-wrap .form-control,
.pwd-wrap input { padding-right: 42px; }
.pwd-eye {
    position: absolute;
    right: 5px;
    top: 50%;
    transform: translateY(-50%);
    width: 30px;
    height: 30px;
    padding: 5px;
    background: none;
    border: 0;
    color: var(--ad-muted);
    cursor: pointer;
}
.pwd-eye svg { width: 100%; height: 100%; display: block; }
/* app.js toggles .showing on the button itself, not on the wrapper. */
.pwd-eye .i-off { display: none; }
.pwd-eye.showing .i-on { display: none; }
.pwd-eye.showing .i-off { display: block; }

/* ============================================================================
   PHASE 3: shell
   ============================================================================ */

/* ===== sidebar: deliberately NOT the applicant blue ================
   Staff move between both portals in the same session. An admin who believes
   they are on the applicant side can delete a record; the colour is the cheapest
   guard against that, so the two must not be mistakable at a glance. */
html[data-startbar="delta-admin"] .startbar { background-color: #12243D; }
/* The template gives .brand a fixed height (var(--bs-topbar-height)) but no
   centring of its own. Without these the logo sat at the top of that box and
   spilled past it into the menu below - the applicant sidebar has the same three
   rules, which is why it does not. */
html[data-startbar="delta-admin"] .startbar .brand {
    background-color: #0B1828;
    display: flex;
    align-items: center;
    padding: 0 14px;
    overflow: hidden;
}
html[data-startbar="delta-admin"] .startbar .brand .logo {
    display: flex;
    align-items: center;
    width: 100%;
    height: 100%;
}

/* The nav started immediately under the brand. The applicant sidebar has an
   identity card holding it 12px clear; there is none here, so the gap is
   explicit - otherwise the first menu label sits against the logo. */
html[data-startbar="delta-admin"] .startbar .startbar-menu .startbar-collapse {
    padding-top: 14px;
}

html[data-startbar="delta-admin"] .startbar .startbar-menu .navbar-nav .nav-item .nav-link,
html[data-startbar="delta-admin"] .startbar .startbar-menu .navbar-nav .nav-item .nav-link span {
    color: rgba(255, 255, 255, .86);
}
html[data-startbar="delta-admin"] .startbar .startbar-menu .navbar-nav .nav-item .nav-link .menu-icon {
    color: rgba(255, 255, 255, .68);
}
/* :not(.active) - hovering the current item otherwise paints a translucent layer
   over its solid background and the two together read as a second highlight. */
html[data-startbar="delta-admin"] .startbar .startbar-menu .navbar-nav .nav-item .nav-link:not(.active):hover,
html[data-startbar="delta-admin"] .startbar .startbar-menu .navbar-nav .nav-item .nav-link:not(.active):hover span,
html[data-startbar="delta-admin"] .startbar .startbar-menu .navbar-nav .nav-item .nav-link:not(.active):hover .menu-icon {
    color: #fff;
    background-color: rgba(255, 255, 255, .06);
    box-shadow: none !important;
}
html[data-startbar="delta-admin"] .startbar .startbar-menu .navbar-nav .nav-item .nav-link.active,
html[data-startbar="delta-admin"] .startbar .startbar-menu .navbar-nav .nav-item .nav-link.active span,
html[data-startbar="delta-admin"] .startbar .startbar-menu .navbar-nav .nav-item .nav-link.active .menu-icon {
    color: #fff !important;
    background-color: #1D3A5F;
    border: 0 !important;
    border-radius: 6px;
    box-shadow: none !important;
}
/* The template draws its own 4px bar through ::before, purple, on active AND
   hover. Reuse it recoloured, active only. */
html[data-startbar="delta-admin"] .startbar .startbar-menu .navbar-nav .nav-item .nav-link::before,
html[data-startbar="delta-admin"] .startbar .startbar-menu .navbar-nav .nav-item .nav-link:hover::before {
    background-color: transparent !important;
    border-color: transparent !important;
}
html[data-startbar="delta-admin"] .startbar .startbar-menu .navbar-nav .nav-item .nav-link.active::before {
    background-color: #F0B429 !important;
    border-color: #F0B429 !important;
}
html[data-startbar="delta-admin"] .startbar .menu-label {
    color: rgba(255, 255, 255, .46);
    letter-spacing: .10em;
    font-size: 10.5px;
    text-transform: uppercase;
}

.ad-brand { display: flex; align-items: center; gap: 10px; }
.ad-brand img { height: 32px; width: auto; flex: none; }
.ad-brand-tx { display: flex; flex-direction: column; line-height: 1.15; }
.ad-brand-tx b { color: #fff; font-size: 13px; font-weight: 700; white-space: nowrap; }
.ad-brand-tx i {
    color: rgba(255, 255, 255, .55); font-size: 9.5px; font-style: normal;
    letter-spacing: .06em; text-transform: uppercase; white-space: nowrap;
}

/* Pinned sign out. Absolute against .startbar, which the template already fixes -
   nothing on .startbar-menu or .startbar-collapse is overridden, because the
   template sizes the scroller with explicit heights and replacing those with flex
   changes the scrollbar. */
.startbar-signout {
    position: absolute; left: 0; right: 0; bottom: 0;
    padding: 12px; z-index: 2;
    background: #12243D;
    border-top: 1px solid rgba(255, 255, 255, .10);
}
html[data-startbar="delta-admin"] .startbar .startbar-menu .startbar-collapse { padding-bottom: 76px; }
.signout-btn {
    display: flex; align-items: center; justify-content: center; gap: 10px;
    padding: 11px 14px; border-radius: 8px;
    background: transparent;
    border: 1px solid rgba(255, 255, 255, .16);
    color: #F1808A !important;
    font-size: 13px; font-weight: 600; text-decoration: none;
}
.signout-btn i { font-size: 17px; }
.signout-btn:hover {
    background: rgba(255, 255, 255, .06);
    border-color: rgba(241, 128, 138, .45);
    color: #FF9AA2 !important;
}

.ad-page-title { font-size: 1.05rem; font-weight: 700; color: var(--ad-ink); margin: 0; }
/* Square, per house style. A standing reminder of which portal this is. */
.ad-envchip {
    display: inline-block; padding: 4px 11px; border-radius: 0;
    background: #12243D; color: #fff;
    font-size: 10.5px; font-weight: 700; letter-spacing: .09em; text-transform: uppercase;
}

/* Drawer overlay: the template shows it below 1199.98px but app.js only collapses
   below 992px, leaving a scrim with no click handler between the two. */
@media (min-width: 992px) { .startbar-overlay { display: none !important; } }
@media screen and (max-width: 991.98px) {
    body[data-sidebar-size="collapsed"] .topbar { background-color: #12243D; border-bottom-color: rgba(255,255,255,.10); }
    body[data-sidebar-size="collapsed"] .topbar .ad-page-title,
    body[data-sidebar-size="collapsed"] .topbar .mobile-menu-btn,
    body[data-sidebar-size="collapsed"] .topbar .mobile-menu-btn i { color: #fff !important; }
    /* .nav-icon has a pale background; a white glyph on it is invisible. */
    body[data-sidebar-size="collapsed"] .topbar .mobile-menu-btn.nav-icon {
        background-color: rgba(255,255,255,.16) !important;
    }
}


/* ===== list utilities =============================================
   The dashboard's breakdown and gate cards use these. They also exist in
   delta.css, but that is the APPLICANT theme and the admin master does not load
   it - pulling in a whole second theme for four rules would mean two files to
   keep in step every time either changes. Defined here instead.

   Dashed separators, matching the applicant portal, so the two feel related
   without sharing a stylesheet. */
.dl-row { display: flex; align-items: center; gap: 12px; padding: 9px 0; }
.dl-row + .dl-row { border-top: 1px dashed #DDE5EF; }
.dl-row .tx { flex: 1; min-width: 0; }
.dl-row .tx b { display: block; font-size: .85rem; color: var(--ad-ink); }
.dl-row .tx span { display: block; font-size: .76rem; color: var(--ad-muted); }
.dl-row .ac { flex: none; }

.dl-dotted > li + li { border-top: 1px dashed #DDE5EF; padding-top: 8px; }
.dl-dotted > li { padding-bottom: 2px; }

/* Square, per house style - no pill radii on status chips. */
.dl-chip {
    display: inline-block; padding: 4px 10px; border-radius: 0;
    font-size: .72rem; font-weight: 700; letter-spacing: .03em;
    background: #EEF3FA; color: var(--ad-ink); margin: 0 6px 6px 0;
}
.dl-chip.ok   { background: #DFF3E7; color: var(--ad-ok); }
.dl-chip.warn { background: #FDF0D5; color: var(--ad-warn); }
.dl-chip.bad  { background: #FDECEC; color: var(--ad-err); }
.dl-chip.mb-0 { margin-bottom: 0; }

@media screen and (max-width: 575.98px) {
    /* Same decision as the applicant side: the row stays on one line rather than
       stacking a full-width button under every label. Kept as a media query so the
       intent is on the record - this is a choice about these lists, not an
       oversight. */
    .dl-row { flex-wrap: nowrap; }
    .dl-row .ac { width: auto; flex: none; }
    .dl-row .ac .btn { width: auto; white-space: nowrap; }
    .dl-row .tx { min-width: 0; }
    .dl-row .tx b { overflow-wrap: anywhere; }
}

/* ===== sidebar groups ==============================================
   Collapsible sections rather than one flat list. Twenty-two destinations under
   six headings is navigable; twenty-two in a row is a wall.

   The group holding the current page renders open from the server, so it never
   opens a beat after load and never leaves you on a page whose own entry is
   hidden because a script did not run. */
.sb-one .nav-link { font-weight: 600; }

html[data-startbar="delta-admin"] .grp { margin: 2px 0; }
html[data-startbar="delta-admin"] .grp-h {
    display: flex; align-items: center; gap: 11px;
    width: 100%; padding: 9px 14px;
    background: none; border: 0; border-radius: 6px;
    color: rgba(255, 255, 255, .86);
    font-size: 13.5px; font-weight: 600; text-align: left; cursor: pointer;
}
html[data-startbar="delta-admin"] .grp-h .ic { font-size: 17px; opacity: .72; flex: none; }
html[data-startbar="delta-admin"] .grp-h span { flex: 1; min-width: 0; }
html[data-startbar="delta-admin"] .grp-h .chev {
    font-size: 15px; opacity: .6; flex: none;
    transition: transform .18s ease;
}
/* Bootstrap leaves aria-expanded on the button; rotate from that rather than
   tracking a second class that could drift out of step with the collapse. */
html[data-startbar="delta-admin"] .grp-h[aria-expanded="true"] .chev { transform: rotate(180deg); }
html[data-startbar="delta-admin"] .grp-h:hover { background: rgba(255, 255, 255, .06); color: #fff; }
/* A shut group whose page you are on would hide the highlight entirely, so the
   header itself carries a mark when its contents are active. */
html[data-startbar="delta-admin"] .grp.open > .grp-h { color: #fff; }
html[data-startbar="delta-admin"] .grp.open > .grp-h .ic { opacity: 1; color: #F0B429; }

html[data-startbar="delta-admin"] .grp-b { list-style: none; margin: 2px 0 4px; padding: 0 0 0 12px; }
html[data-startbar="delta-admin"] .grp-b li { position: relative; }
/* A hairline down the left of the sub-items ties them to their header. */
html[data-startbar="delta-admin"] .grp-b::before { content: none; }
html[data-startbar="delta-admin"] .grp-b .nav-link {
    display: flex; align-items: center; gap: 8px;
    padding: 7px 12px 7px 22px;
    font-size: 12.8px; font-weight: 500;
    color: rgba(255, 255, 255, .72);
    border-radius: 6px;
    position: relative;
}
html[data-startbar="delta-admin"] .grp-b .nav-link::after {
    content: ""; position: absolute; left: 9px; top: 50%;
    width: 4px; height: 4px; border-radius: 50%;
    background: rgba(255, 255, 255, .30); transform: translateY(-50%);
}
html[data-startbar="delta-admin"] .grp-b .nav-link:hover {
    color: #fff; background: rgba(255, 255, 255, .06);
}
html[data-startbar="delta-admin"] .grp-b .nav-link.active {
    color: #fff; background: #1D3A5F; font-weight: 600;
}
html[data-startbar="delta-admin"] .grp-b .nav-link.active::after { background: #F0B429; }

/* Count badge. Square, per house style. */
.grp-b .cnt {
    margin-left: auto; flex: none;
    min-width: 22px; text-align: center;
    padding: 1px 6px; border-radius: 0;
    background: rgba(255, 255, 255, .14);
    color: #fff; font-size: 10.5px; font-weight: 700;
}
.grp-b .nav-link.active .cnt { background: rgba(255, 255, 255, .24); }

/* ===== admin identity strip ========================================
   The five headline figures sit INSIDE this panel. Outside it the panel was a
   heading on a tinted ground doing nothing; the crest and the wash exist to be
   the backdrop those numbers stand on.

   Crest sized and placed as on the applicant dashboard: bled off the right at
   full panel height, under a left-to-right wash so the text stays clear of it. */
.ad-strip {
    background-color: #F4F6F9;
    background-image: url("../../Images/delta-logo.png");
    background-repeat: no-repeat;
    background-position: right -30px center;
    background-size: auto 190%;
    border: 1px solid var(--ad-line);
    border-radius: 10px;
    padding: 20px 22px;
    margin-bottom: 1.5rem;
    position: relative;
    overflow: hidden;
}
.ad-strip::after {
    content: ""; position: absolute; inset: 0; border-radius: 10px;
    background: linear-gradient(90deg, #F4F6F9 55%, rgba(244, 246, 249, .82) 100%);
    pointer-events: none;
}
.ad-strip > * { position: relative; z-index: 1; }

.ad-strip-head h4 { margin: 0 0 3px; font-size: 1.15rem; font-weight: 800; color: var(--ad-ink); }
.ad-strip-head .sub { font-size: .84rem; color: var(--ad-muted); margin-bottom: 16px; }

/* Five equal tiles on one row, wrapping to two or three on narrow screens.
   Panels on the panel rather than full cards - a card inside a card reads as a
   mistake, and these are figures, not sections. */
.ad-tiles { display: flex; gap: 12px; flex-wrap: wrap; }
.ad-tile {
    flex: 1 1 150px; min-width: 0;
    background: rgba(255, 255, 255, .82);
    border: 1px solid #E4E9F2;
    border-radius: 8px;
    padding: 12px 14px;
    backdrop-filter: blur(2px);
}
.ad-tile .k {
    display: block; font-size: .68rem; letter-spacing: .07em;
    text-transform: uppercase; color: var(--ad-muted); font-weight: 700;
}
.ad-tile b { display: block; font-size: 1.25rem; color: var(--ad-ink); line-height: 1.2; margin-top: 3px; }
.ad-tile .n { display: block; font-size: .72rem; color: var(--ad-muted); margin-top: 2px; }

@media screen and (max-width: 575.98px) {
    .ad-strip { background-position: right -40px center; background-size: auto 150%; }
    .ad-strip::after { background: linear-gradient(90deg, #F4F6F9 42%, rgba(244,246,249,.86) 100%); }
    .ad-tile { flex: 1 1 45%; }
}

/* ===== recruitment funnel ==========================================
   Narrower and shorter than the first attempt, and centred rather than spanning
   the card - a funnel that fills a 1400px screen stops reading as a funnel and
   starts reading as six stripes.

   The taper is fixed rather than scaled to the counts. Scaling sounds more
   honest but reads worse: a stage that drops to 2% becomes a sliver too thin to
   hold its own label, and the count printed inside says that exactly.

   IT STAYS A FUNNEL ON MOBILE. The earlier version flattened to full-width
   blocks below 576px, which threw away the one thing the shape was for. The
   bands narrow and the type shrinks instead. */
.fnl { max-width: 540px; margin: 0 auto; padding: 2px 0; }
.fnl-row { display: flex; align-items: center; gap: 10px; }

.fnl-band {
    flex: 1; min-width: 0;
    background: #2E6FC4;
    color: #fff;
    text-align: center;
    padding: 9px 14px;
    margin: 0 auto;
    /* The diagonal is a fixed inset, so every band has the same slope and the
       stack reads as one continuous funnel rather than six unrelated shapes. */
    clip-path: polygon(0 0, 100% 0, calc(100% - 22px) 100%, 22px 100%);
}
.fnl-band b { display: block; font-size: 1.05rem; font-weight: 800; line-height: 1.15; }
.fnl-band span {
    display: block; font-size: .66rem; letter-spacing: .04em;
    opacity: .9; margin-top: 0; line-height: 1.3;
}

/* Percentages, so the taper holds at any width. */
.fnl-row:nth-child(1) .fnl-band { width: 100%; background: #3D7DCE; }
.fnl-row:nth-child(2) .fnl-band { width: 86%;  background: #3372C4; }
.fnl-row:nth-child(3) .fnl-band { width: 72%;  background: #2A67B9; }
.fnl-row:nth-child(4) .fnl-band { width: 58%;  background: #215CAE; }
.fnl-row:nth-child(5) .fnl-band { width: 44%;  background: #1851A3; }
.fnl-row:nth-child(6) .fnl-band { width: 32%;  background: #0F4698; }

.fnl-side {
    flex: none; width: 46px; text-align: right;
    font-size: .76rem; font-weight: 700; color: var(--ad-muted);
}

@media screen and (max-width: 575.98px) {
    .fnl { max-width: none; }
    .fnl-row { gap: 6px; }
    .fnl-band {
        padding: 7px 8px;
        /* Shallower diagonal - a 22px inset on a 300px screen eats the label. */
        clip-path: polygon(0 0, 100% 0, calc(100% - 12px) 100%, 12px 100%);
    }
    .fnl-band b { font-size: .92rem; }
    .fnl-band span { font-size: .58rem; }
    /* The last band still has to hold a word, so the taper is gentler. */
    .fnl-row:nth-child(1) .fnl-band { width: 100%; }
    .fnl-row:nth-child(2) .fnl-band { width: 90%; }
    .fnl-row:nth-child(3) .fnl-band { width: 80%; }
    .fnl-row:nth-child(4) .fnl-band { width: 70%; }
    .fnl-row:nth-child(5) .fnl-band { width: 60%; }
    .fnl-row:nth-child(6) .fnl-band { width: 50%; }
    .fnl-side { width: 34px; font-size: .68rem; }
}

/* ===== bulk NIN verification =======================================
   Moved here from the old dashboard, where it had no styling of its own because
   it inherited from site.css. */
.nv-controls { display: flex; gap: 14px; align-items: flex-end; flex-wrap: wrap; }
.nv-pending {
    padding: 8px 14px; border: 1px solid var(--ad-line); border-radius: 8px;
    background: #F4F7FB; min-width: 150px;
}
.nv-pending .k {
    display: block; font-size: .66rem; letter-spacing: .07em;
    text-transform: uppercase; color: var(--ad-muted); font-weight: 700;
}
.nv-pending b { display: block; font-size: 1.15rem; color: var(--ad-ink); }

.nv-bar { height: 8px; border-radius: 4px; background: #EEF2F7; overflow: hidden; }
.nv-bar i { display: block; height: 100%; background: #0B4EA2; transition: width .25s ease; }

.nv-stats { display: flex; gap: 22px; flex-wrap: wrap; margin-top: 12px; }
.nv-stats .k {
    display: block; font-size: .66rem; letter-spacing: .07em;
    text-transform: uppercase; color: var(--ad-muted); font-weight: 700;
}
.nv-stats b { display: block; font-size: 1.1rem; color: var(--ad-ink); }
.nv-stats b.ok  { color: var(--ad-ok); }
.nv-stats b.bad { color: var(--ad-err); }

/* Failures only, and scrollable - a long run should not push the controls off
   the screen while it is still running. */
.nv-log { margin-top: 16px; border: 1px solid var(--ad-line); border-radius: 8px; overflow: hidden; }
.nv-log-h {
    background: #FDECEC; color: #7F1D1D; padding: 8px 14px;
    font-size: .74rem; font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
}
.nv-log > div:last-child { max-height: 280px; overflow-y: auto; }
.nv-log-row {
    display: grid; grid-template-columns: 130px 1fr 1.2fr; gap: 12px;
    padding: 7px 14px; font-size: .8rem; border-top: 1px dashed #DDE5EF;
}
.nv-log-row:first-child { border-top: 0; }
.nv-log-row .no { font-weight: 700; color: #0B4EA2; }
.nv-log-row .nm { color: var(--ad-ink); }
.nv-log-row .ms { color: var(--ad-muted); }
@media screen and (max-width: 767.98px) {
    .nv-log-row { grid-template-columns: 1fr; gap: 2px; }
    .nv-controls { gap: 10px; }
    .nv-pending { width: 100%; }
}

/* ============================================================================
   PHASE 5: the twenty remaining admin pages
   ============================================================================

   Those pages carry roughly 1,200 lines of markup between them, written against
   Content/site.css. Rewriting all of it would mean touching nineteen files,
   every server-control ID in them, and every piece of JavaScript that reaches
   into that markup - for a purely visual result.

   Twenty-five class names account for all of it, and every one is shared: card-ala
   appears on fifteen pages, dt on ten, tag on nine. So the classes are redefined
   here in the new palette instead. The markup does not change, the control IDs do
   not change, the JavaScript does not change, and all twenty pages arrive at the
   same look at once.

   Where a class collides with Bootstrap the local rule wins, because admin.css
   loads last.
   ============================================================================ */

/* ===== surfaces ==================================================== */
.card-ala {
    background: #fff;
    border: 1px solid var(--ad-line);
    border-radius: 10px;
    box-shadow: 0 1px 2px rgba(18, 36, 61, .04);
    margin-bottom: 1.5rem;
}
.card-ala > .card-head,
.card-ala > .card-header {
    display: flex; align-items: center; justify-content: space-between;
    gap: 12px; flex-wrap: wrap;
    padding: 14px 18px;
    border-bottom: 1px solid var(--ad-line);
}
.card-ala .card-title {
    margin: 0; font-size: .98rem; font-weight: 700; color: var(--ad-ink);
}
.card-ala > .card-body { padding: 18px; }

/* ===== data tables ================================================= */
/* Horizontal scroll rather than squeezing: these carry a dozen columns and a
   crushed table is harder to read than one you have to scroll. */
.dt-wrap { overflow-x: auto; border-radius: 8px; }
.dt {
    width: 100%;
    border-collapse: collapse;
    font-size: .84rem;
    background: #fff;
}
.dt thead th {
    background: #F4F6F9;
    color: var(--ad-muted);
    text-align: left;
    font-size: .68rem;
    letter-spacing: .07em;
    text-transform: uppercase;
    font-weight: 700;
    padding: 10px 12px;
    white-space: nowrap;
    border-bottom: 1px solid var(--ad-line);
}
.dt tbody td {
    padding: 9px 12px;
    border-bottom: 1px dashed #DDE5EF;
    vertical-align: middle;
    color: #22303F;
}
.dt tbody tr:last-child td { border-bottom: 0; }
.dt tbody tr:hover { background: #F7FAFD; }
.dt td a { color: var(--ad-accent); font-weight: 600; text-decoration: none; }
.dt td a:hover { text-decoration: underline; }

/* ===== status tags ================================================= */
/* Square, per house style - no pill radii anywhere in this project. */
.tag {
    display: inline-block;
    padding: 3px 9px;
    border-radius: 0;
    font-size: .68rem;
    font-weight: 700;
    letter-spacing: .06em;
    text-transform: uppercase;
    background: #EEF3FA;
    color: var(--ad-ink);
    white-space: nowrap;
}
.tag-muted  { background: #EEF2F7; color: var(--ad-muted); }
.tag-ok     { background: #DFF3E7; color: var(--ad-ok); }
.tag-gold   { background: #FDF0D5; color: var(--ad-warn); }
.tag-red,
.tag-danger { background: #FDECEC; color: var(--ad-err); }
.tag-dark   { background: #12243D; color: #fff; }

/* ===== layout helpers ============================================== */
.wrap { width: 100%; }
.grid { display: grid; grid-template-columns: repeat(12, 1fr); gap: 0 16px; }
.grid > .col6  { grid-column: span 6; }
.grid > .col12 { grid-column: span 12; }
.grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 0 18px; }
.inline-fields { display: flex; gap: 12px; flex-wrap: wrap; align-items: flex-end; }
.inline-fields > * { min-width: 0; }
.filter-bar {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
    gap: 10px;
    margin-bottom: 16px;
}
.mt-2x { margin-top: 22px; }
.txt-muted { color: var(--ad-muted); }

@media screen and (max-width: 767.98px) {
    .grid > .col6 { grid-column: span 12; }
    .grid-2 { grid-template-columns: 1fr; }
}

/* ===== notices ===================================================== */
.notice {
    padding: 12px 15px;
    border-radius: 8px;
    font-size: .86rem;
    font-weight: 500;
    margin-bottom: 16px;
    background: #EEF3FA;
    border: 1px solid #D8E2EE;
    color: var(--ad-ink);
}
.notice-ok  { background: #DFF3E7; border-color: #C4DFCC; color: #14532D; }
.notice-err { background: #FDECEC; border-color: #F3C9C9; color: #7F1D1D; }

/* ===== detail lists ================================================ */
/* Label above value on a phone, side by side once there is room - a fixed label
   column truncates names at 360px. */
/* ---- applicant detail: label left, value right ----
   Was label above value, which on a card this wide left the whole right-hand half
   empty and made a short list of fields fill a long column. Side by side puts the
   values in a line you can run your eye down, and a dotted rule between rows keeps
   a label tied to its own value once the pairs are close together.

   Grid rather than float: dt and dd are separate elements, and a grid keeps them on
   one row without either needing to know the other's width. */
.review-dl { margin: 0; }

/* dlRow() wraps each pair in a <div>, so the grid goes on THAT, not on the <dl>.
   Putting it on the list would have laid out the wrappers as grid items and left
   the dt and dd stacked inside each one - the same result as before, achieved more
   expensively. Worth checking what the markup actually is before styling it. */
.review-dl > div {
    display: grid;
    grid-template-columns: minmax(110px, auto) 1fr;
    align-items: baseline;
    column-gap: 18px;
    padding: 9px 0;
}
/* Between rows, not above the first - a line under the card header reads as a
   second header. */
.review-dl > div + div { border-top: 1px dashed var(--ad-line, #E4EBF3); }

.review-dl dt {
    font-size: .68rem; letter-spacing: .07em; text-transform: uppercase;
    color: var(--ad-muted); font-weight: 700; margin: 0;
}
.review-dl dd {
    margin: 0; font-size: .88rem; color: var(--ad-ink); font-weight: 600;
    overflow-wrap: anywhere; min-width: 0;
    text-align: right;
}

@media screen and (max-width: 480px) {
    /* At this width a long label beside a long value leaves each about ten
       characters. Stack, value still right so the column reads. */
    .review-dl > div { grid-template-columns: 1fr; row-gap: 2px; }
}
.kv { display: grid; grid-template-columns: auto 1fr; gap: 6px 14px; font-size: .86rem; }
.kv > span:nth-child(odd) { color: var(--ad-muted); }
.kv > span:nth-child(even) { font-weight: 600; color: var(--ad-ink); }

/* ===== misc ======================================================== */
.chip {
    display: inline-block; padding: 4px 10px; border-radius: 0;
    background: #EEF3FA; color: var(--ad-ink);
    font-size: .74rem; font-weight: 600; margin: 0 6px 6px 0;
}
.bar { height: 6px; border-radius: 3px; background: #EEF2F7; overflow: hidden; }
.bar > i, .bar > span { display: block; height: 100%; background: var(--ad-accent); }
.btn-ala-dark {
    display: inline-flex; align-items: center; justify-content: center; gap: 7px;
    padding: 10px 16px; border-radius: 7px;
    background: #12243D; border: 1px solid #12243D; color: #fff;
    font: 600 .88rem/1 inherit; cursor: pointer; text-decoration: none;
}
.btn-ala-dark:hover { background: #0B1828; color: #fff; }

/* ===== admin sign-in ===============================================
   Split screen, in the admin slate rather than the applicant blue - the two
   doors should not look the same, for the same reason the two sidebars do not.

   The panel is the first thing to go below 992px: on a phone it is decoration
   standing between a member of staff and the only control on the page. */
.ad-auth { min-height: 100vh; display: grid; grid-template-columns: 1fr 1fr; }
.ad-auth-left {
    display: flex; align-items: center; justify-content: center;
    padding: 34px 24px; background: #fff;
}
.ad-auth-form { width: 100%; max-width: 400px; }
.ad-auth-card {
    border: 1px solid var(--ad-line);
    border-radius: 14px;
    padding: 24px 22px;
}

.ad-auth-right {
    background: linear-gradient(160deg, #0B1828 0%, #12243D 55%, #1D3A5F 100%);
    display: flex; align-items: center; justify-content: center;
    padding: 40px; position: relative; overflow: hidden;
}
.ad-auth-right::after {
    content: ""; position: absolute; right: -90px; bottom: -90px;
    width: 360px; height: 360px; border-radius: 50%;
    background: rgba(255, 255, 255, .04);
}
.ad-auth-promo { max-width: 420px; color: #fff; position: relative; z-index: 1; }
.ad-auth-promo img { width: 86px; height: auto; margin-bottom: 20px; }
.ad-auth-promo h2 { font-size: 1.55rem; font-weight: 800; margin: 0 0 8px; }
.ad-auth-promo > p { font-size: .88rem; color: rgba(255, 255, 255, .70); margin: 0 0 20px; }
.ad-auth-promo ul { list-style: none; padding: 0; margin: 0; }
.ad-auth-promo li {
    display: flex; gap: 11px; align-items: flex-start; padding: 8px 0;
    font-size: .85rem; color: rgba(255, 255, 255, .86);
}
.ad-auth-promo li i { color: #F0B429; font-size: 17px; flex: none; }
.ad-auth-note {
    margin: 22px 0 0; padding-top: 14px;
    border-top: 1px solid rgba(255, 255, 255, .12);
    font-size: .8rem; color: rgba(255, 255, 255, .6);
}
.ad-auth-note a { color: #7FDCEE; }

@media screen and (max-width: 991.98px) {
    .ad-auth { grid-template-columns: 1fr; }
    .ad-auth-right { display: none; }
}

/* A tile that is itself a link. Inherits colour so the figure does not turn
   link-blue, and lifts slightly so it reads as clickable without a chevron. */
a.ad-tile-link { text-decoration: none; color: inherit; display: block; transition: .15s ease; }
a.ad-tile-link:hover {
    color: inherit;
    border-color: #B9CBE4;
    box-shadow: 0 2px 10px rgba(18, 36, 61, .08);
    transform: translateY(-1px);
}

/* ===== recruitment timeline (admin) ================================
   Same markup as the applicant portal and the home page - only the neutrals
   differ, because the admin area uses its own ink and line colours. */
.tl-strip { display: flex; align-items: flex-start; }
.tl-item { flex: 1; text-align: center; position: relative; padding: 0 4px; min-width: 0; }
.tl-item .bar {
    position: absolute; top: 21px; left: -50%; right: 50%;
    height: 2px; background: var(--ad-line); z-index: 0;
}
.tl-item:first-child .bar { display: none; }
.tl-item.done .bar, .tl-item.now .bar { background: var(--ad-ok); }
.tl-dot {
    position: relative; z-index: 1;
    width: 42px; height: 42px; margin: 0 auto; border-radius: 50%;
    display: flex; align-items: center; justify-content: center;
    background: #EDF1F6; color: #8DA0B8;
    border: 3px solid #fff; box-shadow: 0 0 0 1px var(--ad-line);
}
.tl-dot svg { width: 18px; height: 18px; }
.tl-item.done .tl-dot { background: var(--ad-ok); color: #fff; box-shadow: 0 0 0 1px var(--ad-ok); }
.tl-item.now  .tl-dot { background: var(--ad-accent); color: #fff; box-shadow: 0 0 0 4px rgba(11,78,162,.16); }
.tl-item h6 { margin: 9px 0 1px; font-size: .78rem; font-weight: 700; color: var(--ad-ink); line-height: 1.25; }
.tl-item .dt { display: block; font-size: .72rem; color: var(--ad-muted); }
.tl-item .st { display: block; font-size: .68rem; font-weight: 600; color: #9AA9BC; }
.tl-item.done .st { color: var(--ad-ok); }
.tl-item.now  .st { color: var(--ad-accent); }

@media screen and (max-width: 767.98px) {
    .tl-strip { flex-direction: column; }
    .tl-item {
        display: grid; grid-template-columns: 42px 1fr; gap: 12px;
        text-align: left; padding: 0 0 16px;
    }
    .tl-item .bar { top: 42px; bottom: -16px; left: 20px; right: auto; width: 2px; height: auto; }
    .tl-item:first-child .bar { display: block; }
    .tl-item:last-child .bar { display: none; }
    .tl-item h6 { margin-top: 2px; }
}

/* ===== numbered sidebar steps =======================================
   The CBT group is a dependency chain, so its links are numbered and split
   under two sub-headings. Scoped to the admin startbar like every other
   sidebar rule, and no :has() - .grp-b .nav-link is already flex with an
   8px gap, so the badge sits inline without needing parent selectors that
   older browsers on ministry desktops may not support.

   .grp-step is a label, not a link. Numbered links suppress the bullet dot
   that ::after normally draws: the number is the marker. */
html[data-startbar="delta-admin"] .grp-b .grp-step {
    list-style: none;
    font-size: .64rem; font-weight: 800; letter-spacing: .09em; text-transform: uppercase;
    color: rgba(255, 255, 255, .38);
    padding: 12px 0 4px 22px; margin: 0;
}
html[data-startbar="delta-admin"] .grp-b .nav-link .stp {
    display: inline-flex; align-items: center; justify-content: center;
    width: 18px; height: 18px; flex: 0 0 auto;
    border-radius: 5px; background: rgba(255, 255, 255, .14);
    font-size: .66rem; font-weight: 800; line-height: 1;
}
html[data-startbar="delta-admin"] .grp-b .nav-link:hover .stp { background: rgba(255, 255, 255, .26); }
html[data-startbar="delta-admin"] .grp-b .nav-link.active .stp { background: #F0B429; color: #12243D; }
/* the number replaces the bullet */
html[data-startbar="delta-admin"] .grp-b .nav-link:has(.stp)::after { content: none; }
