/* ==========================================================================
   Swarnim Admin Central
   --------------------------------------------------------------------------
   Rewritten after the first version was judged unreadable: "everything is too
   mixed, what is the use of what". Three rules came out of that, and they are
   what the rest of this file enforces.

   1. GROUPING BEFORE DECORATION. Eleven equal-weight menu items and ten
      identical tiles do not tell you what anything is for. Navigation is
      grouped and labelled; tiles are split into "act on this" and "this is
      just a number".

   2. ONE MEANING PER COLOUR. Red means someone is waiting past a deadline.
      Amber means we are waiting on somebody else. Green means settled. Navy
      is neutral. Gold is Swarnim's brand and is used for emphasis, never for
      status. A colour that means two things means nothing.

   3. IF IT CANNOT BE CLICKED IT IS NOT A BUTTON. The previous action bars were
      mostly disabled buttons, which taught the reader to ignore the whole bar.

   Sections
     01 Tokens
     02 Reset and base
     03 App bar
     04 Sidebar navigation
     05 Page frame, headings, breadcrumb
     06 Action bar
     07 Buttons and form controls
     08 Cards, FastTabs, FactBox
     09 Cues (role centre)
     10 Data grids
     11 Filters and paging
     12 Pills and status
     13 Banners, callouts, notices
     14 Key/value lists
     15 Settings, toggles, reference
     16 Approvals, handover, media
     17 Login
     18 Utilities
     19 Responsive
     20 Print
   ========================================================================== */

/* ==========================================================================
   01 TOKENS
   ========================================================================== */

:root {
    /* Brand - shared with the mobile app so the two read as one product. */
    --navy:        #0d2031;
    --navy-mid:    #1a2f4a;
    --navy-soft:   #24405f;
    --gold:        #b8912a;
    --gold-bright: #d4af37;

    /* Surfaces. Deliberately few: page, raised, sunken. Everything sits on
       one of these three, which is what stops a screen looking "mixed". */
    --page:        #eef1f4;
    --surface:     #ffffff;
    --sunken:      #f6f8fa;
    /* The SAME navy as the app bar, not a shade off it.
       These two surfaces meet along the whole left edge of every page, and
       #16283c against #0d2031 reads as a rendering fault rather than as depth -
       the sidebar looked like it had a lighter panel behind it. One navy for
       the whole chrome, which is also what the app does. */
    --sidebar:     #0d2031;

    /* Ink. The old palette hit 3:1 against white; these clear AA. */
    --ink:         #16212e;
    --ink-2:       #46586c;
    --ink-3:       #6a7c90;
    --ink-on-dark: #f2f5f8;
    --ink-on-dark-2: #9db0c6;

    --border:      #d2dae2;
    --border-soft: #e6ecf1;

    /* Status. One meaning each - see rule 2 at the top of this file. */
    --danger:      #b3261e;
    --danger-bg:   #fdecea;
    --warn:        #9a6700;
    --warn-bg:     #fff6dd;
    --ok:          #1a7a43;
    --ok-bg:       #e7f5ec;
    --info:        #1f5c9e;
    --info-bg:     #e8f1fa;

    --radius:      6px;
    --radius-sm:   4px;

    /* One shadow, used sparingly. Several depths is another kind of mixing. */
    --shadow:      0 1px 2px rgba(16, 33, 51, .06), 0 1px 8px rgba(16, 33, 51, .05);

    --sidebar-w:   236px;
    --bar-h:       52px;
}

/* ==========================================================================
   02 RESET AND BASE
   ========================================================================== */

*, *::before, *::after { box-sizing: border-box; }

/* NOT height:100% - that makes body a fixed-height box, and position:sticky
   then has nothing to stick inside. The app bar detached mid-scroll last time. */
html { -webkit-text-size-adjust: 100%; }

body {
    margin: 0;
    background: var(--page);
    color: var(--ink);

    /* 14px, not 12. The old portal was legible on a 27-inch monitor and
       nowhere else, and a site office runs on whatever laptop is in the room. */
    font: 14px/1.5 "Segoe UI", system-ui, -apple-system, "Helvetica Neue", Arial, sans-serif;
}

/* ==========================================================================
   INTERFACE SCALE
   ==========================================================================
   Everything 10% larger. Asked for as document.body.style.zoom = "110%";
   done in CSS so it applies from the first paint rather than after a script
   runs, which would otherwise show the page at 100% and then jump.

   zoom, not transform: scale(). A transform would scale the painted result
   and leave the layout at its old size, so the page would overflow its own
   scrollbars and fixed elements would land in the wrong place. zoom changes
   the layout size, which is what "make it bigger" has to mean.

   One consequence, handled in admin.js: getBoundingClientRect() reports
   post-zoom coordinates, while a px value set on a fixed child of <body> is
   scaled BY the zoom - so anything positioned from measured coordinates has
   to divide by this factor. The search dropdown does.
   ========================================================================== */
body { zoom: 110%; }

a { color: var(--info); text-decoration: none; }
a:hover { text-decoration: underline; }

:focus-visible {
    outline: 2px solid var(--gold-bright);
    outline-offset: 2px;
    border-radius: 2px;
}

h1, h2, h3, p { margin: 0; }

/* ==========================================================================
   03 APP BAR
   ========================================================================== */

.app-bar {
    position: sticky;
    top: 0;
    z-index: 40;
    height: var(--bar-h);
    display: flex;
    align-items: center;
    gap: 16px;
    padding: 0 16px;
    background: var(--navy);
    color: var(--ink-on-dark);
}

.app-bar__brand {
    display: flex;
    align-items: center;
    gap: 10px;
    color: var(--ink-on-dark);
    font-weight: 600;
    font-size: 14.5px;
    white-space: nowrap;
}
.app-bar__brand:hover { text-decoration: none; }

/* Height-constrained, width auto: the mark must never be stretched, and the
   bar is the fixed dimension. */
.app-bar__logo {
    /* Cropped to the Devanagari wordmark only. The full lock-up put "GROUP" at
       about four pixels tall, which is worse than leaving it out. */
    height: 26px;
    width: auto;
    display: block;
}

/* "Admin Central" separated from the mark by a rule, so the product name reads
   as a label on the brand rather than part of it. */
.app-bar__product {
    padding-left: 12px;
    border-left: 1px solid var(--dividerDark, #2a4361);
    color: var(--ink-on-dark-2);
    font-size: 13px;
    font-weight: 500;
    letter-spacing: .02em;
}

.app-bar__mark {
    display: grid;
    place-items: center;
    width: 26px;
    height: 26px;
    border: 1.5px solid var(--gold-bright);
    border-radius: 50%;
    color: var(--gold-bright);
    font-weight: 700;
    font-size: 13px;
}

.app-bar__env {
    padding: 3px 8px;
    border: 1px solid rgba(212, 175, 55, .45);
    border-radius: 3px;
    color: var(--gold-bright);
    font-size: 10px;
    font-weight: 700;
    letter-spacing: .08em;
    text-transform: uppercase;
}

/* Centred in the bar, not left-aligned after the logo.

   flex:1 alone only made it fill the slack, so it sat wherever the brand
   block left it and moved every time the environment badge changed width.
   Auto margins on both sides centre it against the BAR rather than against
   whatever is next to it, so it stays put. */
.app-bar__search {
    flex: 0 1 460px;
    margin-left: auto;
    margin-right: auto;
    max-width: 460px;
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 0 12px;
    height: 32px;
    background: rgba(255, 255, 255, .1);
    border: 1px solid transparent;
    border-radius: var(--radius-sm);
    color: var(--ink-on-dark-2);
}
.app-bar__search:focus-within {
    background: rgba(255, 255, 255, .16);
    border-color: rgba(212, 175, 55, .5);
}
.app-bar__search input {
    flex: 1;
    background: none;
    border: 0;
    outline: 0;
    color: var(--ink-on-dark);
    font: inherit;
    font-size: 13px;
}
.app-bar__search input::placeholder { color: var(--ink-on-dark-2); }

.app-bar__actions { display: flex; gap: 4px; margin-left: auto; }

.app-bar__user { display: flex; align-items: center; gap: 10px; }
.app-bar__user-name { font-size: 13px; font-weight: 600; }
.app-bar__user-role { font-size: 11px; color: var(--ink-on-dark-2); }

.avatar {
    display: grid;
    place-items: center;
    width: 30px;
    height: 30px;
    border-radius: 50%;
    background: var(--navy-soft);
    color: var(--gold-bright);
    font-size: 11.5px;
    font-weight: 700;
}

.icon-btn {
    display: grid;
    place-items: center;
    width: 30px;
    height: 30px;
    background: none;
    border: 0;
    border-radius: var(--radius-sm);
    color: var(--ink-on-dark-2);
    font-size: 14px;
    cursor: pointer;
}
.icon-btn:hover { background: rgba(255, 255, 255, .12); color: var(--ink-on-dark); }

/* ==========================================================================
   04 SIDEBAR NAVIGATION

   The single biggest change. Eleven flat items across the top made the reader
   scan every word to find anything; grouped and labelled, most of the list can
   be ignored at a glance. Groups are by WHAT YOU CAME TO DO, not by table.
   ========================================================================== */

.shell {
    display: grid;
    grid-template-columns: var(--sidebar-w) minmax(0, 1fr);
    min-height: calc(100vh - var(--bar-h));
}

.side {
    background: var(--sidebar);
    padding: 14px 0 32px;
    position: sticky;
    top: var(--bar-h);
    height: calc(100vh - var(--bar-h));
    overflow-y: auto;
}

.side__group + .side__group { margin-top: 18px; }

.side__title {
    padding: 0 18px 6px;
    color: #7f95ad;
    font-size: 10px;
    font-weight: 700;
    letter-spacing: .1em;
    text-transform: uppercase;
}

.side__item {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 8px 18px;
    color: #c6d4e2;
    font-size: 13.5px;
    border-left: 3px solid transparent;
}
.side__item:hover {
    background: rgba(255, 255, 255, .06);
    color: #fff;
    text-decoration: none;
}

.side__item--active {
    background: rgba(212, 175, 55, .12);
    border-left-color: var(--gold-bright);
    color: #fff;
    font-weight: 600;
}

/* A menu item that goes nowhere yet. Shown, because hiding it makes the
   product look smaller than the plan, but obviously not ready. */
.side__item--soon {
    color: #64798f;
    cursor: default;
    pointer-events: none;
}
/* ==========================================================================
   SITEMAP ICONS
   ==========================================================================
   One fixed 18px box per row, whatever the icon's own viewBox says, so every
   LABEL starts on the same x. Ragged label starts are the thing that makes an
   icon rail look bolted on, and these icons come from three different grids
   (24, 512 and 1024).

   The icon is dimmer than its label and brightens with it on hover and on the
   active row: at this size an icon is a landmark you aim at, not something you
   read, so it should not compete with the word next to it.
   ========================================================================== */

.side__icon {
    flex: 0 0 18px;
    width: 18px;
    height: 18px;
    opacity: .62;

    /* fill, not just color - and this is what made the Complaints icon black.
       Its paths carry no fill attribute of their own: the source SVG set
       fill="#ffffff" on the root <svg> element, which is the one part not kept
       when the icon body was extracted into _NavIcon. With nothing declaring a
       fill, the path took the initial value, which is black, and setting
       `color` could not reach it because nothing referred to currentColor.
       The outline icons are unaffected: every one of them declares
       fill="none" on the path itself, and an inline attribute beats this. */
    fill: currentColor;

    /* The icons inherit their colour from the row - every fill and stroke in
       them is currentColor - so there is nothing to restate here. */
}

/* The Complaints icon is the exception, and it earns one.

   Nine of the ten icons are thin outlines; this one is a solid filled shield.
   At the same 62% opacity a filled shape carries far more ink than an outline
   of the same size, so it read as the one dark, heavy row in the rail. Full
   white puts it back in line with its neighbours - matching apparent weight,
   not matching the opacity number. */
.side__item .side__icon--solid { opacity: 1; color: #fff; }

.side__item:hover .side__icon { opacity: .9; }
.side__item--active .side__icon { opacity: 1; }
.side__item--soon .side__icon { opacity: .35; }

/* The label takes the leftover width so a long one truncates instead of
   pushing the count badge out of the rail. */
.side__label { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.side__item--soon::after {
    content: "soon";
    margin-left: auto;
    font-size: 9.5px;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: #5b708a;
}

/* Count against a menu item - only shown when it is non-zero and worth
   acting on, so a badge always means "there is work here". */
.side__count {
    margin-left: auto;
    min-width: 20px;
    padding: 1px 6px;
    border-radius: 10px;
    background: var(--danger);
    color: #fff;
    font-size: 10.5px;
    font-weight: 700;
    text-align: center;
}
.side__count--calm { background: rgba(255, 255, 255, .16); color: #d7e3ef; }

/* ==========================================================================
   05 PAGE FRAME
   ========================================================================== */

.page {
    padding: 14px 26px 40px;

    /* Full width, no reading-measure cap.
       A 1500px cap is right for a page of prose and wrong for this portal: the
       work here is wide tables, three-column records and a process bar with
       seven stages, all of which were being squeezed into the middle of a
       large monitor with empty gutters either side. Individual prose blocks
       still cap themselves (see .page__purpose) - the WORKSPACE does not. */
    max-width: none;
    min-width: 0;
}

.breadcrumb {
    display: flex;
    gap: 6px;
    margin-bottom: 4px;
    color: var(--ink-3);
    font-size: 12px;
}
.breadcrumb span + span::before { content: "›"; margin-right: 6px; }

.page__head {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    gap: 20px;
    margin-bottom: 4px;
}

.page__title {
    font-size: 24px;
    font-weight: 600;
    letter-spacing: -.01em;
    color: var(--ink);
}

.page__subtitle {
    margin-top: 3px;
    color: var(--ink-2);
    font-size: 13px;
}

/* One sentence saying what the page is for. The old portal assumed you knew. */
.page__purpose {
    max-width: 78ch;
    margin: 10px 0 0;
    color: var(--ink-2);
    font-size: 13px;
}

/* ==========================================================================
   06 ACTION BAR
   ========================================================================== */

.action-bar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
    margin: 16px 0 18px;
}

.action-sep {
    width: 1px;
    height: 22px;
    background: var(--border);
    margin: 0 4px;
}

.spacer { flex: 1; }

/* ==========================================================================
   07 BUTTONS AND FORM CONTROLS
   ========================================================================== */

.action {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    padding: 7px 14px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    color: var(--ink);
    font: inherit;
    font-size: 13px;
    font-weight: 500;
    line-height: 1.2;
    cursor: pointer;
    white-space: nowrap;
}
.action:hover { background: var(--sunken); border-color: #b9c5d1; text-decoration: none; }
.action:active { background: #eaeff4; }

.action--primary {
    background: var(--navy);
    border-color: var(--navy);
    color: #fff;
}
.action--primary:hover { background: var(--navy-mid); border-color: var(--navy-mid); }

.action--danger { color: var(--danger); border-color: #e6b8b5; }
.action--danger:hover { background: var(--danger-bg); }

.action--tiny { padding: 4px 9px; font-size: 12px; }

.action[disabled], .action:disabled {
    opacity: .45;
    cursor: not-allowed;
}

.action__icon { font-size: 13px; line-height: 1; }

.btn-block { width: 100%; justify-content: center; }

.field {
    padding: 7px 10px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    color: var(--ink);
    font: inherit;
    font-size: 13px;
    min-width: 0;
}
.field:focus { outline: 0; border-color: var(--navy-soft); box-shadow: 0 0 0 3px rgba(36, 64, 95, .12); }
.field::placeholder { color: var(--ink-3); }
.field--narrow { max-width: 150px; }

select.field { padding-right: 26px; }
textarea.field { resize: vertical; min-height: 70px; line-height: 1.5; }

.form-row {
    display: flex;
    flex-direction: column;
    gap: 5px;
    margin-bottom: 14px;
}
.form-row > label,
.form-row > .setting__key {
    color: var(--ink-2);
    font-size: 12px;
    font-weight: 600;
}

.inline-form { display: inline-flex; align-items: center; gap: 8px; }

/* ==========================================================================
   08 CARDS, FASTTABS, FACTBOX
   ========================================================================== */

.list-shell,
.fasttab,
.factbox,
.callout,
.approval,
.setting,
.handover {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
}

.list-shell { overflow: hidden; }

.fasttab { margin-bottom: 14px; overflow: hidden; }

.fasttab > summary {
    padding: 12px 18px;
    background: var(--sunken);
    border-bottom: 1px solid var(--border-soft);
    color: var(--ink);
    font-size: 13.5px;
    font-weight: 600;
    cursor: pointer;
    list-style: none;
}
.fasttab > summary::-webkit-details-marker { display: none; }
.fasttab > summary::before {
    content: "▸";
    display: inline-block;
    width: 14px;
    color: var(--ink-3);
    transition: transform .12s ease;
}
.fasttab[open] > summary::before { transform: rotate(90deg); }

.fasttab__body {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
    gap: 0 32px;
    padding: 14px 18px;
}
.fasttab__body--single { display: block; }

.fasttab__footer {
    padding: 14px 18px;
    border-top: 1px solid var(--border-soft);
    background: var(--sunken);
}

/* Two-column detail layout: content, then a narrow column of facts. */
.with-factbox {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 300px;
    gap: 18px;
    align-items: start;
}

.factbox { overflow: hidden; }

.factbox__title {
    padding: 10px 14px;
    background: var(--sunken);
    border-bottom: 1px solid var(--border-soft);
    font-size: 12px;
    font-weight: 700;
    letter-spacing: .04em;
    text-transform: uppercase;
    color: var(--ink-2);
}

.factbox__body { padding: 12px 14px; }

.stack-sm { display: flex; flex-direction: column; gap: 10px; }

/* ==========================================================================
   09 CUES

   Split in two, which is the other half of the fix. "Needs attention" is work
   somebody must do; "the estate" is background. They used to look identical,
   so a zero and a 1,350 carried the same visual weight.
   ========================================================================== */

.cue-group { margin-bottom: 22px; }

.cue-group__title {
    margin-bottom: 3px;
    font-size: 15px;
    font-weight: 600;
    color: var(--ink);
}

.cue-group__hint {
    margin-bottom: 12px;
    color: var(--ink-2);
    font-size: 12.5px;
}

.cues {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(206px, 1fr));
    gap: 12px;
}

/* An actionable cue: a whole card is the link, so the target is the number
   AND its label AND the reason, not a 12px word. */
.cue {
    display: block;
    padding: 14px 16px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-top: 3px solid var(--border);
    border-radius: var(--radius);
    color: var(--ink);
}
a.cue:hover {
    border-color: #b9c5d1;
    box-shadow: var(--shadow);
    text-decoration: none;
}

.cue__value {
    display: block;
    font-size: 30px;
    font-weight: 700;
    line-height: 1.05;
    letter-spacing: -.02em;
}

.cue__label {
    display: block;
    margin-top: 4px;
    font-size: 13px;
    font-weight: 600;
    color: var(--ink);
}

.cue__hint {
    display: block;
    margin-top: 2px;
    font-size: 11.5px;
    line-height: 1.4;
    color: var(--ink-3);
}

.cue--danger { border-top-color: var(--danger); }
.cue--danger .cue__value { color: var(--danger); }

.cue--warn { border-top-color: var(--warn); }
.cue--warn .cue__value { color: var(--warn); }

.cue--ok { border-top-color: var(--ok); }
.cue--info { border-top-color: var(--info); }

/* Nothing to do. Worth saying out loud rather than showing six zeros. */
.cue-clear {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 16px 18px;
    background: var(--ok-bg);
    border: 1px solid #bfe0cc;
    border-radius: var(--radius);
    color: #156135;
    font-size: 13.5px;
}
.cue-clear strong { font-weight: 600; }

/* Reference numbers: quieter, smaller, no top rule, not clickable-looking. */
.cues--quiet { grid-template-columns: repeat(auto-fill, minmax(158px, 1fr)); }
.cues--quiet .cue {
    padding: 12px 14px;
    background: var(--sunken);
    border-top-width: 1px;
    border-top-color: var(--border);
}
.cues--quiet .cue__value { font-size: 21px; font-weight: 600; color: var(--ink-2); }
.cues--quiet .cue__label { font-size: 12px; font-weight: 500; color: var(--ink-2); }
.cues--quiet .cue__hint { font-size: 11px; }

/* ==========================================================================
   10 DATA GRIDS
   ========================================================================== */

.grid-scroll { overflow-x: auto; }

.grid {
    width: 100%;
    border-collapse: collapse;
    font-size: 13px;
}

.grid thead th {
    position: sticky;
    top: 0;
    z-index: 1;
    padding: 9px 12px;
    background: var(--sunken);
    border-bottom: 1px solid var(--border);
    color: var(--ink-2);
    font-size: 11.5px;
    font-weight: 700;
    letter-spacing: .03em;
    text-transform: uppercase;
    text-align: left;
    white-space: nowrap;
}

.grid tbody td {
    padding: 9px 12px;
    border-bottom: 1px solid var(--border-soft);
    vertical-align: top;
}

.grid tbody tr:hover td { background: #f9fbfd; }
.grid tbody tr:last-child td { border-bottom: 0; }

.grid .num { text-align: right; font-variant-numeric: tabular-nums; }
.grid .wrap { white-space: normal; min-width: 190px; }

/* The identifier column: the thing you click to open the record. */
.grid__link, .link-cell {
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    color: var(--info);
}

/* A second line under a cell - the context that used to need its own column. */
.grid__meta {
    display: block;
    margin-top: 2px;
    color: var(--ink-3);
    font-size: 11.5px;
}

.grid__empty, .empty {
    padding: 34px 16px;
    text-align: center;
    color: var(--ink-3);
    font-size: 13px;
}

.grid-footer {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 10px 14px;
    border-top: 1px solid var(--border-soft);
    background: var(--sunken);
    color: var(--ink-3);
    font-size: 12px;
}

.sla-breached, .text-danger { color: var(--danger); font-weight: 600; }

/* ==========================================================================
   11 FILTERS AND PAGING
   ========================================================================== */

.filter-bar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
    padding: 12px 14px;
    border-bottom: 1px solid var(--border);
    background: var(--surface);
}

.filter-bar__label {
    color: var(--ink-3);
    font-size: 11px;
    font-weight: 700;
    letter-spacing: .06em;
    text-transform: uppercase;
}

/* Search is the filter people actually use; give it the room. */
.filter-bar .field[type="search"] { flex: 1 1 240px; max-width: 320px; }

/* A checkbox filter reads as a switch, not as a form field in a wall of them. */
.filter-chip {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 6px 11px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 14px;
    color: var(--ink-2);
    font-size: 12.5px;
    cursor: pointer;
    user-select: none;
}
.filter-chip:hover { background: var(--sunken); }
.filter-chip input { margin: 0; accent-color: var(--navy); }
.filter-chip:has(input:checked) {
    background: var(--navy);
    border-color: var(--navy);
    color: #fff;
}

.pager {
    display: flex;
    align-items: center;
    gap: 4px;
}

.pager__step, .pager__page {
    display: inline-grid;
    place-items: center;
    min-width: 30px;
    height: 28px;
    padding: 0 8px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    color: var(--ink-2);
    font-size: 12.5px;
}
.pager__step:hover, .pager__page:hover { background: var(--sunken); text-decoration: none; }

.pager__page[aria-current="page"] {
    background: var(--navy);
    border-color: var(--navy);
    color: #fff;
    font-weight: 600;
}

.pager__step[aria-disabled="true"] { opacity: .4; pointer-events: none; }

/* ==========================================================================
   12 PILLS AND STATUS
   ========================================================================== */

.pill {
    display: inline-block;
    padding: 3px 9px;
    border-radius: 11px;
    font-size: 11.5px;
    font-weight: 600;
    white-space: nowrap;
    border: 1px solid transparent;
}

.pill--open      { background: var(--danger-bg); color: var(--danger); border-color: #f0c9c6; }
.pill--progress  { background: var(--info-bg);   color: var(--info);   border-color: #c5dcf1; }
.pill--verify    { background: var(--warn-bg);   color: var(--warn);   border-color: #ecd9a4; }
.pill--resolved  { background: var(--ok-bg);     color: var(--ok);     border-color: #bfe0cc; }
.pill--cancelled { background: #eef1f4;          color: var(--ink-3);  border-color: var(--border); }

/* ==========================================================================
   13 BANNERS, CALLOUTS, NOTICES
   ========================================================================== */

.notice, .alert {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    padding: 11px 14px;
    margin-bottom: 16px;
    border: 1px solid var(--border);
    border-left: 3px solid var(--ink-3);
    border-radius: var(--radius-sm);
    background: var(--surface);
    font-size: 13px;
}

.notice--ok    { background: var(--ok-bg);     border-color: #bfe0cc; border-left-color: var(--ok);     color: #14572f; }
.notice--error { background: var(--danger-bg); border-color: #f0c9c6; border-left-color: var(--danger); color: #8c1d18; }
.alert         { background: var(--danger-bg); border-color: #f0c9c6; border-left-color: var(--danger); color: #8c1d18; }

.notice__hint { display: block; margin-top: 2px; font-size: 12px; opacity: .85; }

.callout {
    padding: 14px 16px;
    border-left: 3px solid var(--gold);
    font-size: 13px;
    color: var(--ink-2);
    line-height: 1.55;
}

.hint {
    color: var(--ink-3);
    font-size: 12px;
    line-height: 1.5;
}

/* ==========================================================================
   14 KEY / VALUE LISTS
   ========================================================================== */

.kv {
    display: flex;
    justify-content: space-between;
    gap: 16px;
    padding: 6px 0;
    border-bottom: 1px solid var(--border-soft);
    font-size: 13px;
}
.kv:last-child { border-bottom: 0; }

.kv__k { color: var(--ink-3); flex: 0 0 auto; }
.kv__v { color: var(--ink); text-align: right; font-weight: 500; }

/* ==========================================================================
   15 SETTINGS, TOGGLES, REFERENCE
   ========================================================================== */

.setting { padding: 0; margin-bottom: 12px; overflow: hidden; }

.setting__row {
    display: flex;
    align-items: center;
    gap: 16px;
    padding: 12px 16px;
    border-bottom: 1px solid var(--border-soft);
}
.setting__row:last-child { border-bottom: 0; }

.setting__text { flex: 1; min-width: 0; display: block; }
.setting__key { font-size: 13px; font-weight: 600; color: var(--ink); }
.setting__key { display: block; }
.setting__desc { display: block; margin-top: 2px; color: var(--ink-3); font-size: 12px; line-height: 1.5; max-width: 70ch; }
.setting__desc code { font-size: 11px; opacity: .8; }

.toggle {
    position: relative;
    display: inline-block;
    width: 38px;
    height: 21px;
    flex: 0 0 auto;
}
.toggle input { position: absolute; opacity: 0; width: 100%; height: 100%; margin: 0; cursor: pointer; }

.toggle__track {
    position: absolute;
    inset: 0;
    background: #c3cdd8;
    border-radius: 11px;
    transition: background .14s ease;
    pointer-events: none;
}
.toggle__thumb {
    position: absolute;
    top: 2px;
    left: 2px;
    width: 17px;
    height: 17px;
    background: #fff;
    border-radius: 50%;
    box-shadow: 0 1px 2px rgba(0, 0, 0, .25);
    transition: transform .14s ease;
    pointer-events: none;
}
.toggle input:checked ~ .toggle__track { background: var(--ok); }
.toggle input:checked ~ .toggle__thumb { transform: translateX(17px); }

.secret {
    font-family: "Cascadia Mono", Consolas, "SF Mono", ui-monospace, monospace;
    font-size: 18px;
    font-weight: 700;
    letter-spacing: .16em;
    color: var(--ink);
}

/* ==========================================================================
   16 APPROVALS, HANDOVER, MEDIA
   ========================================================================== */

.approval { margin-bottom: 14px; overflow: hidden; }

.approval__head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 12px 16px;
    background: var(--sunken);
    border-bottom: 1px solid var(--border-soft);
    font-weight: 600;
    font-size: 13.5px;
}

.approval__body { padding: 14px 16px; }

.approval__reason {
    padding: 11px 13px;
    background: var(--warn-bg);
    border-left: 3px solid var(--warn);
    border-radius: var(--radius-sm);
    font-size: 13px;
    line-height: 1.55;
}

.approval__proof { margin-top: 12px; }

.approval__foot {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 12px 16px;
    background: var(--sunken);
    border-top: 1px solid var(--border-soft);
}

.media-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
    gap: 10px;
    padding: 14px 18px;
}
/* Video needs more width than a photo thumbnail to be usable. */
.media-grid--video { grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); }

.media-tile {
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    overflow: hidden;
    background: var(--sunken);
}
.media-tile img, .media-tile video { display: block; width: 100%; }

.handover { padding: 20px 22px; max-width: 560px; }
.handover__eyebrow {
    color: var(--ink-3);
    font-size: 11px;
    font-weight: 700;
    letter-spacing: .08em;
    text-transform: uppercase;
}
.handover__head { margin: 6px 0 14px; font-size: 20px; font-weight: 600; }
.handover__unit { font-size: 15px; font-weight: 600; }
.handover__customer { color: var(--ink-2); font-size: 13px; }
.handover__label { color: var(--ink-3); font-size: 11.5px; font-weight: 600; }
.handover__creds {
    margin: 14px 0;
    padding: 14px 16px;
    background: var(--sunken);
    border: 1px dashed var(--border);
    border-radius: var(--radius-sm);
}
.handover__note { color: var(--ink-3); font-size: 12px; line-height: 1.55; }
.handover__actions { display: flex; gap: 8px; margin-top: 16px; }

/* ==========================================================================
   17 LOGIN
   ========================================================================== */

.login-shell {
    min-height: 100vh;
    display: grid;
    place-items: center;
    padding: 24px;
    background: var(--navy);
}

.login-card {
    width: 100%;
    max-width: 380px;
    background: var(--surface);
    border-radius: 10px;
    overflow: hidden;
    box-shadow: 0 12px 40px rgba(0, 0, 0, .35);
}

/* The form keeps the padding; the brand band goes edge to edge above it. */
.login-card__body { padding: 26px 32px 30px; }

/* A navy band, not a logo dropped on white. The artwork's "GROUP" and
   "TRUST BUILD GROW" are white type - on a white card they disappear. */
.login-card__brand {
    padding: 26px 24px 22px;
    background: var(--navy);
    text-align: center;
}

.login-card__logo {
    display: block;
    width: 178px;
    max-width: 100%;
    margin: 0 auto;
}

.login-card__mark {
    display: grid;
    place-items: center;
    width: 52px;
    height: 52px;
    margin: 0 auto 12px;
    border: 2px solid var(--gold);
    border-radius: 50%;
    color: var(--gold);
    font-size: 24px;
    font-weight: 700;
}

.login-card__word {
    display: block;
    font-size: 15px;
    font-weight: 700;
    letter-spacing: .3em;
    color: var(--ink);
}
.login-card__sub { display: block; margin-top: 4px; color: var(--ink-3); font-size: 12.5px; }

/* The login form's fields are the full width of the card, not the compact
   inline width used inside filter bars. */
.login-card .field { width: 100%; padding: 9px 11px; font-size: 14px; }
.login-card .form-row { margin-bottom: 16px; }
.login-card .action { margin-top: 4px; padding: 10px 14px; font-size: 14px; }

/* ==========================================================================
   18 UTILITIES
   ========================================================================== */

.row { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.muted { color: var(--ink-3); }
.strong { font-weight: 600; }

/* ==========================================================================
   19 RESPONSIVE

   The sidebar collapses to a horizontal strip rather than a hamburger: a site
   office on a laptop should not need two taps to reach Complaints.
   ========================================================================== */

@media (max-width: 1180px) {
    .with-factbox { grid-template-columns: minmax(0, 1fr); }
}

@media (max-width: 900px) {
    .shell { grid-template-columns: minmax(0, 1fr); }

    .side {
        position: static;
        height: auto;
        display: flex;
        gap: 2px;
        overflow-x: auto;
        padding: 8px 10px;
    }
    .side__title { display: none; }
    .side__group { display: flex; gap: 2px; }
    .side__group + .side__group {
        margin: 0 0 0 8px;
        padding-left: 8px;
        border-left: 1px solid rgba(255, 255, 255, .12);
    }
    .side__item {
        border-left: 0;
        border-bottom: 2px solid transparent;
        border-radius: var(--radius-sm);
        padding: 6px 11px;
        white-space: nowrap;
        font-size: 13px;
    }
    .side__item--active { border-left: 0; border-bottom-color: var(--gold-bright); }

    .app-bar__search, .app-bar__user-role { display: none; }
    .page { padding: 16px 14px 40px; }
    .page__title { font-size: 20px; }
}

/* ==========================================================================
   20 PRINT
   Printing a slip should produce the slip, not the whole portal.
   ========================================================================== */

@media print {
    .app-bar, .side, .action-bar, .breadcrumb, .filter-bar, .grid-footer { display: none !important; }
    .shell { grid-template-columns: 1fr; }
    body { background: #fff; }
    .page { padding: 0; max-width: none; }
    .handover, .list-shell, .fasttab, .factbox { border: 0; box-shadow: none; }
}


/* ============================================================ page size ==
   Row-count choice in the grid footer. Deliberately quiet: it is a preference,
   not a filter, and it sits next to the row range it changes. */
.page-size { display: inline-flex; align-items: center; gap: 2px; }
.page-size__label { color: var(--ink-3); margin-right: 6px; }
.page-size__opt {
    display: inline-block; min-width: 30px; text-align: center;
    padding: 2px 6px; border-radius: 3px; color: var(--ink-2);
    text-decoration: none; border: 1px solid transparent;
}
.page-size__opt:hover { background: var(--sunken); }
.page-size__opt--current {
    background: var(--navy); color: #fff; border-color: var(--navy); font-weight: 600;
}

/* ========================================================== searchable ==
   A <select> upgraded into a type-to-filter picker by wwwroot/js/admin.js.
   The native control stays in the DOM and stays the thing that submits - it is
   hidden rather than removed, so a failed script leaves a working form. */
.sfield { position: relative; }
.sfield__native { position: absolute; opacity: 0; pointer-events: none; width: 1px; height: 1px; }
.sfield__input { width: 100%; }
.sfield__list {
    /* position and coordinates are set by admin.js, which switches this to
       fixed so a <dialog>'s own overflow cannot clip it. The values here are
       the starting point before the script runs. z-index clears the modal
       chrome, which a dialog paints in the browser's top layer. */
    position: absolute; z-index: 200; left: 0; right: 0; top: calc(100% + 2px);
    max-height: 280px; overflow-y: auto;
    background: #fff; border: 1px solid var(--border);
    border-radius: var(--radius); box-shadow: 0 8px 24px rgba(13, 32, 49, .14);
}
.sfield__opt {
    display: flex; justify-content: space-between; gap: 12px; align-items: baseline;
    padding: 7px 10px; cursor: pointer; border-bottom: 1px solid var(--border-soft);
}
.sfield__opt:last-child { border-bottom: 0; }
.sfield__opt:hover, .sfield__opt--active { background: var(--sunken); }
.sfield__opt--current { font-weight: 600; }
.sfield__hint { color: var(--ink-3); font-size: 11px; white-space: nowrap; }
.sfield__none { padding: 10px; color: var(--ink-3); }
