/* =====================================================================
   AIDIP UI — bespoke house design system (NO Bootstrap).
   Implements exactly the class vocabulary the app uses, with a premium
   slate + indigo enterprise aesthetic. Typography: Inter.
   Behaviour (modals, dropdowns, tabs) is React-controlled — CSS only here.
   ===================================================================== */
@import url('https://fonts.googleapis.com/css2?family=Titillium+Web:wght@400;600;700&family=Open+Sans:wght@400;600&display=swap');

/* Design tokens adapted from the sibling IBIS Nexus product's design system (nexus-theme.css) for
   visual parity across our two IBIS products — steel-blue accent, dark-navy top bar, flat/dense
   enterprise surfaces. Token NAMES are kept as AIDIP's own so every rule below (and every className
   in every page) keeps working unchanged; only the palette/radius/shadow/font VALUES moved. */
:root {
  --primary: #5980a6;        /* Nexus --accent (steel blue) */
  --primary-d: #597ea3;      /* Nexus --accent-2 (hover/pressed) */
  --primary-dd: #416180;     /* Nexus --accent-ink (darker — body-copy links) */
  --primary-soft: #edf1f5;   /* Nexus --rail-item-active */
  --topbar: #1d2d3d;         /* Nexus --topbar-bg (deep steel-navy) */
  --bg: #f2f2f3;             /* Nexus --canvas */
  --surface: #ffffff;
  --border: #e3e7eb;         /* Nexus --rail-border */
  --border-2: #cdd3da;
  --text: #1d1f20;           /* Nexus --text-primary */
  --heading: #2c455d;        /* Nexus --brand-2 */
  --muted: #5a6673;          /* Nexus --text-secondary */

  --success: #2f7a52; --success-bg: #e7f4ee; --success-fg: #2f7a52;   /* Nexus --ok */
  --danger: #b23b3b;  --danger-bg: #f7e3e1;  --danger-fg: #b23b3b;    /* Nexus --danger */
  --warning: #a35a1f; --warning-bg: #f6ead9; --warning-fg: #a35a1f;   /* Nexus --warn */
  --info: #1d63b3;    --info-bg: #e6eef6;    --info-fg: #1d63b3;      /* Nexus --info */

  --radius: 4px;
  --radius-sm: 2px;
  --shadow-sm: 0 1px 2px rgba(29, 31, 32, 0.08);
  --shadow: 0 2px 8px rgba(29, 31, 32, 0.12);
  --shadow-lg: 0 8px 24px rgba(29, 31, 32, 0.2);

  --font: 'Titillium Web', 'Open Sans', 'Lucida Grande', Verdana, Arial, Helvetica, sans-serif;
  --font-heading: 'Titillium Web', 'Open Sans', 'Lucida Grande', Verdana, Arial, Helvetica, sans-serif;
  --mono: Consolas, 'Cascadia Mono', ui-monospace, Menlo, monospace;
}

*, *::before, *::after { box-sizing: border-box; }
/* Blazor mounts at #app (React used #root). Without a height here the shell can't clamp to the viewport,
   so long list pages scroll the whole window instead of scrolling the table internally. */
html, body, #app { margin: 0; height: 100%; }

body {
  font-family: var(--font);
  font-size: 0.6875rem;
  line-height: 1.5;
  color: var(--text);
  background-color: var(--bg);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

/* Heading scale matches Nexus's dense convention (h1 1.2rem against an 11px body) rather than
   AIDIP's earlier much larger display-style headings. */
h1, h2, h3, h4, h5, h6, .h1 { margin: 0 0 0.2rem; font-family: var(--font-heading); color: var(--heading); font-weight: 600; line-height: 1.25; letter-spacing: -0.01em; }
/* The page-intro subtitle (a muted <p> right under the page's h1/h2) shouldn't reserve a full paragraph
   gap — keep the header block compact so more of the viewport goes to content. */
h1 + p, h2 + p { margin-top: 0; margin-bottom: 0.5rem; }
h1, .h1 { font-size: 1.05rem; } h2 { font-size: 1rem; } h3 { font-size: 0.9rem; }
h4 { font-size: 0.85rem; } h5 { font-size: 0.8rem; } h6 { font-size: 0.75rem; }
p { margin: 0 0 1rem; }
a { color: var(--primary); text-decoration: none; }
a:hover { color: var(--primary-d); text-decoration: underline; }
hr { border: 0; border-top: 1px solid var(--border); margin: 1rem 0; opacity: 1; }
code, .font-monospace { font-family: var(--mono); font-size: 0.85em; }
small, .small { font-size: 0.625rem; }
label { display: inline-block; }
button { font-family: inherit; }
img { vertical-align: middle; }
.img-fluid { max-width: 100%; height: auto; }

/* ---------- Typography utilities ---------- */
.fs-1 { font-size: 2.25rem !important; } .fs-3 { font-size: 1.5rem !important; } .fs-4 { font-size: 1.3rem !important; }
.fw-normal { font-weight: 400 !important; } .fw-semibold { font-weight: 600 !important; } .fw-bold { font-weight: 700 !important; }
.fst-italic { font-style: italic !important; }
.text-center { text-align: center !important; } .text-start { text-align: left !important; } .text-end { text-align: right !important; }
.text-nowrap { white-space: nowrap !important; } .text-wrap { white-space: normal !important; }
.text-truncate { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.text-uppercase { text-transform: uppercase !important; }
.text-decoration-none { text-decoration: none !important; }
.text-muted { color: var(--muted) !important; }
.text-dark { color: var(--heading) !important; } .text-white { color: #fff !important; }
.text-primary { color: var(--primary) !important; } .text-danger { color: var(--danger) !important; }
.text-success { color: var(--success-fg) !important; } .text-warning { color: var(--warning-fg) !important; }

/* ---------- Backgrounds ---------- */
.bg-white { background-color: #fff !important; } .bg-light { background-color: #f8fafc !important; }
.bg-body-tertiary { background-color: var(--bg) !important; }
.bg-primary { background-color: var(--topbar) !important; }
.bg-primary-subtle { background-color: var(--primary-soft) !important; }
.bg-opacity-75 { --bg-opacity: 0.75; }

/* ---------- Spacing ---------- */
.m-0{margin:0!important}.m-2{margin:.5rem!important}
.mt-1{margin-top:.25rem!important}.mt-2{margin-top:.5rem!important}
.mb-0{margin-bottom:0!important}.mb-1{margin-bottom:.25rem!important}.mb-2{margin-bottom:.5rem!important}.mb-3{margin-bottom:1rem!important}.mb-4{margin-bottom:1.5rem!important}
.me-1{margin-right:.25rem!important}.me-3{margin-right:1rem!important}
.ms-2{margin-left:.5rem!important}.ms-3{margin-left:1rem!important}.ms-auto{margin-left:auto!important}
.mx-1{margin-left:.25rem!important;margin-right:.25rem!important}
.p-0{padding:0!important}.p-2{padding:.5rem!important}.p-3{padding:1rem!important}.p-4{padding:1.5rem!important}.p-5{padding:3rem!important}
.px-1{padding-left:.25rem!important;padding-right:.25rem!important}.px-2{padding-left:.5rem!important;padding-right:.5rem!important}.px-3{padding-left:1rem!important;padding-right:1rem!important}
.py-0{padding-top:0!important;padding-bottom:0!important}.py-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}

/* ---------- Display / flex ---------- */
.d-none{display:none!important}.d-block{display:block!important}.d-inline-block{display:inline-block!important}.d-flex{display:flex!important}
.flex-row{flex-direction:row!important}.flex-column{flex-direction:column!important}.flex-wrap{flex-wrap:wrap!important}
.flex-grow-1{flex-grow:1!important}.flex-shrink-0{flex-shrink:0!important}
.align-items-center{align-items:center!important}.align-items-end{align-items:flex-end!important}
.justify-content-center{justify-content:center!important}.justify-content-between{justify-content:space-between!important}.justify-content-end{justify-content:flex-end!important}
.align-middle{vertical-align:middle!important}
.gap-1{gap:.25rem!important}.gap-2{gap:.5rem!important}.gap-3{gap:1rem!important}

/* ---------- Sizing / position ---------- */
.w-100{width:100%!important}.h-100{height:100%!important}.vh-100{height:100vh!important}
.position-relative{position:relative!important}.position-absolute{position:absolute!important}
.top-0{top:0!important}.start-0{left:0!important}.end-0{right:0!important}.start-100{left:100%!important}
.translate-middle{transform:translate(-50%,-50%)!important}
.overflow-auto{overflow:auto!important}.overflow-hidden{overflow:hidden!important}

/* ---------- Borders / radius / shadow ---------- */
.border{border:1px solid var(--border)!important}.border-0{border:0!important}
.border-2{border-width:2px!important}.border-top{border-top:1px solid var(--border)!important}.border-bottom{border-bottom:1px solid var(--border)!important}
.border-dashed{border-style:dashed!important}
.rounded{border-radius:var(--radius-sm)!important}.rounded-top{border-top-left-radius:var(--radius-sm)!important;border-top-right-radius:var(--radius-sm)!important}
.rounded-circle{border-radius:50%!important}.rounded-pill{border-radius:50rem!important}
.shadow-sm{box-shadow:var(--shadow-sm)!important}.shadow{box-shadow:var(--shadow)!important}

/* ---------- Grid (flex 12-col) ---------- */
.row{--gx:1.5rem;--gy:0;display:flex;flex-wrap:wrap;margin-top:calc(-1*var(--gy));margin-right:calc(-.5*var(--gx));margin-left:calc(-.5*var(--gx))}
.row>*{box-sizing:border-box;flex-shrink:0;width:100%;max-width:100%;padding-right:calc(.5*var(--gx));padding-left:calc(.5*var(--gx));margin-top:var(--gy)}
.g-0{--gx:0;--gy:0}.g-1{--gx:.25rem;--gy:.25rem}.g-2{--gx:.5rem;--gy:.5rem}.g-3{--gx:1rem;--gy:1rem}
.col{flex:1 0 0%}
.col-1{width:8.3333%}.col-2{width:16.6667%}.col-3{width:25%}.col-4{width:33.3333%}.col-5{width:41.6667%}.col-6{width:50%}.col-7{width:58.3333%}.col-8{width:66.6667%}.col-9{width:75%}.col-10{width:83.3333%}.col-11{width:91.6667%}.col-12{width:100%}
@media (min-width:768px){.col-md-1{width:8.3333%}.col-md-2{width:16.6667%}.col-md-3{width:25%}.col-md-4{width:33.3333%}.col-md-5{width:41.6667%}.col-md-6{width:50%}.col-md-7{width:58.3333%}.col-md-8{width:66.6667%}.col-md-9{width:75%}.col-md-10{width:83.3333%}.col-md-12{width:100%}}
@media (min-width:992px){.col-lg-2{width:16.6667%}.col-lg-3{width:25%}.col-lg-4{width:33.3333%}.col-lg-5{width:41.6667%}.col-lg-6{width:50%}.col-lg-7{width:58.3333%}.col-lg-8{width:66.6667%}.col-lg-9{width:75%}.col-lg-12{width:100%}}
@media (min-width:1200px){.col-xl-2{width:16.6667%}.col-xl-3{width:25%}.col-xl-4{width:33.3333%}.col-xl-6{width:50%}}
@media (min-width:1400px){.col-xxl-3{width:25%}.col-xxl-4{width:33.3333%}}
/* Bare fractional columns (col-3/col-4/col-6 with no responsive suffix — common in modal forms) stay at
   their desktop fraction on phones, so e.g. a col-3 select renders at ~25% width. Stack them full-width
   below 576px; a col-md-*/col-lg-* on the same element still takes over at its own breakpoint. */
@media (max-width:575.98px){
  .col-1,.col-2,.col-3,.col-4,.col-5,.col-6,.col-7,.col-8,.col-9,.col-10,.col-11{width:100%}
}
/* Utility: hide non-essential toolbar bits (page-size, "Page X of Y") on phones so dense card-header
   toolbars don't wrap to 3 lines. */
@media (max-width:575.98px){ .hide-phone{display:none!important} }
/* IbisSplit (Review Workbench) is a horizontal drag-split on desktop; on phones a ~34% column beside the
   editor is unusable, so stack the two panes vertically and hide the gutter. */
@media (max-width:767.98px){
  /* The split must GROW to its stacked content and let .app-content scroll the whole workbench. On desktop
     each pane scrolls inside a fixed-height split (overflow:hidden), but once stacked that same clip hides
     everything below the document pane — the header fields, the tabs and the entire lines table become
     unreachable. Override flex/height/overflow so the panes size to content and the page scrolls normally. */
  .ibis-split{flex-direction:column!important;flex:0 0 auto!important;height:auto!important;overflow:visible!important}
  .ibis-split>.ibis-split__pane{flex:0 0 auto!important;width:100%!important;height:auto!important;min-width:0}
  .ibis-split>.ibis-split__pane:first-of-type{min-height:24vh;max-height:44vh;overflow:auto}
  .ibis-split>.ibis-gutter{display:none}
}

/* ---------- Top bar ---------- */
.navbar{display:flex;align-items:center;justify-content:space-between;padding:.5rem 1rem}
.navbar-brand{font-weight:700;letter-spacing:.01em;font-size:1.15rem;color:#fff;text-decoration:none}
.navbar-brand:hover{color:#fff;text-decoration:none}
.app-topbar{background:var(--topbar)!important;color:#fff;box-shadow:0 1px 12px rgba(2,6,23,.18)}
.app-topbar .btn-outline-light{--btn-color:#e2e8f0;--btn-border:rgba(255,255,255,.22);--btn-hover-bg:rgba(255,255,255,.12);--btn-hover-color:#fff;--btn-hover-border:rgba(255,255,255,.3)}

/* ---------- Sidebar ---------- */
.app-sidebar{background:var(--surface)!important;border-right:1px solid var(--border)}
.nav{display:flex;flex-wrap:wrap;list-style:none;margin:0;padding:0}
.nav-item{list-style:none}
.nav-link{display:block;padding:.5rem .75rem;color:#334155;text-decoration:none;border-radius:var(--radius-sm);transition:background-color .12s,color .12s;cursor:pointer}
.nav-link:hover{text-decoration:none}
.app-sidebar .nav-link{font-weight:500}
.app-sidebar .nav-link:hover{background:#f1f5f9;color:var(--heading)}
.app-sidebar .nav-link.active{background:var(--primary-soft)!important;color:var(--primary-d)!important;font-weight:600;box-shadow:inset 3px 0 0 var(--primary)}
.app-sidebar .nav-link .bi{font-size:1.05rem}
.nav-pills{flex-direction:column;gap:.25rem}
/* Tabs */
.nav-tabs{border-bottom:1px solid var(--border);gap:.25rem}
.nav-tabs .nav-link{border:1px solid transparent;border-radius:var(--radius-sm) var(--radius-sm) 0 0;color:var(--muted);margin-bottom:-1px;padding:.45rem .85rem}
.nav-tabs .nav-link:hover{color:var(--heading);background:#f8fafc}
.nav-tabs .nav-link.active{color:var(--primary-d);background:#fff;border-color:var(--border) var(--border) #fff;font-weight:600}

/* ---------- Cards ---------- */
/* No border/shadow (Nexus convention): the canvas (--bg) and surface (--surface) tones are already
   distinct enough for a panel to read as separate from the page without needing its own hairline. */
.card{position:relative;display:flex;flex-direction:column;min-width:0;background:var(--surface);border:none;border-radius:var(--radius);box-shadow:none}
.card-header{padding:.5rem .85rem;background:var(--surface);border-bottom:1px solid var(--border);font-weight:600;color:var(--heading);border-radius:var(--radius) var(--radius) 0 0;display:flex;align-items:center;justify-content:space-between}
.card-body{flex:1 1 auto;padding:.75rem .85rem;position:relative}

/* ---------- Buttons ---------- */
.btn{--btn-bg:transparent;--btn-color:var(--text);--btn-border:transparent;--btn-hover-bg:transparent;--btn-hover-color:var(--text);--btn-hover-border:transparent;
  display:inline-flex;align-items:center;justify-content:center;gap:.35rem;font-weight:600;font-size:.6875rem;line-height:1.4;
  padding:.28rem .7rem;border:1px solid var(--btn-border);border-radius:var(--radius-sm);background:var(--btn-bg);color:var(--btn-color);
  cursor:pointer;text-decoration:none;transition:background-color .12s,border-color .12s,color .12s,box-shadow .12s;white-space:nowrap;user-select:none}
.btn:hover{background:var(--btn-hover-bg);color:var(--btn-hover-color);border-color:var(--btn-hover-border);text-decoration:none}
.btn:focus-visible{outline:none;box-shadow:0 0 0 .2rem rgba(89,128,166,.3)}
.btn:disabled,.btn.disabled{opacity:.55;pointer-events:none}
.btn-sm{padding:.25rem .6rem;font-size:.6875rem;border-radius:6px}
.btn-primary{--btn-bg:var(--primary);--btn-color:#fff;--btn-border:var(--primary);--btn-hover-bg:var(--primary-d);--btn-hover-color:#fff;--btn-hover-border:var(--primary-d)}
.btn-secondary{--btn-bg:#64748b;--btn-color:#fff;--btn-border:#64748b;--btn-hover-bg:#475569;--btn-hover-color:#fff;--btn-hover-border:#475569}
.btn-success{--btn-bg:var(--success);--btn-color:#fff;--btn-border:var(--success);--btn-hover-bg:#15803d;--btn-hover-color:#fff;--btn-hover-border:#15803d}
.btn-link{--btn-color:var(--primary);--btn-hover-color:var(--primary-d);background:transparent;border-color:transparent;padding:.25rem .35rem}
.btn-link:hover{text-decoration:underline}
.btn-outline-primary{--btn-color:var(--primary);--btn-border:var(--primary);--btn-hover-bg:var(--primary);--btn-hover-color:#fff;--btn-hover-border:var(--primary)}
.btn-outline-secondary{--btn-color:#475569;--btn-border:var(--border-2);--btn-hover-bg:#f1f5f9;--btn-hover-color:#0f172a;--btn-hover-border:#cbd5e1}
.btn-outline-success{--btn-color:var(--success-fg);--btn-border:#86efac;--btn-hover-bg:var(--success);--btn-hover-color:#fff;--btn-hover-border:var(--success)}
.btn-outline-danger{--btn-color:var(--danger-fg);--btn-border:#fca5a5;--btn-hover-bg:var(--danger);--btn-hover-color:#fff;--btn-hover-border:var(--danger)}
.btn-outline-warning{--btn-color:var(--warning-fg);--btn-border:#fcd34d;--btn-hover-bg:var(--warning);--btn-hover-color:#fff;--btn-hover-border:var(--warning)}
.btn-outline-light{--btn-color:#e2e8f0;--btn-border:rgba(255,255,255,.22);--btn-hover-bg:rgba(255,255,255,.12);--btn-hover-color:#fff;--btn-hover-border:rgba(255,255,255,.3)}
.btn-group{display:inline-flex}
.btn-group>.btn{border-radius:0}
.btn-group>.btn:first-child{border-top-left-radius:6px;border-bottom-left-radius:6px}
.btn-group>.btn:last-child{border-top-right-radius:6px;border-bottom-right-radius:6px}
.btn-group>.btn:not(:first-child){margin-left:-1px}
.btn-group>.btn:hover{z-index:1}
.btn-close{width:.85rem;height:.85rem;padding:.35rem;border:0;border-radius:6px;background:transparent url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='%231f2a37' d='M.293.293a1 1 0 0 1 1.414 0L8 6.586 14.293.293a1 1 0 1 1 1.414 1.414L9.414 8l6.293 6.293a1 1 0 0 1-1.414 1.414L8 9.414l-6.293 6.293a1 1 0 0 1-1.414-1.414L6.586 8 .293 1.707a1 1 0 0 1 0-1.414z'/%3e%3c/svg%3e") center/.85rem no-repeat;cursor:pointer;opacity:.6;box-sizing:content-box}
.btn-close:hover{opacity:1;background-color:#f1f5f9}

/* ---------- Forms ---------- */
.form-label{display:inline-block;margin-bottom:.35rem;font-weight:500;color:#374151;font-size:.6875rem}
.form-text{margin-top:.25rem;font-size:.625rem;color:var(--muted)}
.form-control,.form-select{display:block;width:100%;padding:.45rem .7rem;font-size:.6875rem;line-height:1.5;color:var(--text);background:#fff;border:1px solid var(--border-2);border-radius:var(--radius-sm);transition:border-color .12s,box-shadow .12s;appearance:none}
.form-control::placeholder{color:#9aa4b2}
.form-control:focus,.form-select:focus{border-color:#a8c0d6;outline:0;box-shadow:0 0 0 .2rem rgba(89,128,166,.2)}
.form-control:disabled,.form-select:disabled{background:#f1f5f9;opacity:1}
.form-control-sm,.form-select-sm{padding:.25rem .55rem;font-size:.6875rem;border-radius:6px}
.form-select{padding-right:2rem;background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%236b7280' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right .6rem center;background-size:14px}
.input-group{display:flex;align-items:stretch;width:100%}
.input-group>.form-control,.input-group>.form-select{position:relative;flex:1 1 auto;width:1%;min-width:0}
.input-group>:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0;margin-left:-1px}
.input-group>:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}
.input-group-text{display:flex;align-items:center;padding:.45rem .7rem;font-size:.6875rem;color:var(--muted);background:#f8fafc;border:1px solid var(--border-2);border-radius:var(--radius-sm)}
.input-group-sm>.form-control,.input-group-sm>.form-select,.input-group-sm>.input-group-text,.input-group-sm>.btn{padding:.25rem .55rem;font-size:.6875rem}
.form-check{display:block;min-height:1.4rem;padding-left:1.6em;margin-bottom:.25rem;position:relative}
/* Base checkbox/radio: flows inline so it works standalone (e.g. in flex rows / table cells). */
.form-check-input{width:1.1em;height:1.1em;margin:0;vertical-align:middle;background:#fff;border:1px solid var(--border-2);border-radius:.25em;appearance:none;cursor:pointer;flex:0 0 auto;transition:background-color .12s,border-color .12s}
/* Inside a .form-check wrapper, keep the original absolute (label-padding) layout. */
.form-check .form-check-input{position:absolute;left:0;top:.15em}
.form-check-input:checked{background:var(--primary);border-color:var(--primary);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='m3 8 3 3 7-7'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:center;background-size:75%}
.form-check-input:focus{outline:0;box-shadow:0 0 0 .2rem rgba(89,128,166,.2)}
.form-check-label{cursor:pointer;font-size:.6875rem}
.form-switch{padding-left:2.6em}
.form-switch .form-check-input{position:absolute;left:0;top:.1em;width:2.2em;height:1.2em;border-radius:2em;background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3ccircle r='6' fill='%23cbd5e1' cx='8' cy='8'/%3e%3c/svg%3e");background-position:left center;background-repeat:no-repeat;background-size:contain;transition:background-position .15s,background-color .15s}
.form-switch .form-check-input:checked{background-color:var(--primary);border-color:var(--primary);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3ccircle r='6' fill='%23fff' cx='8' cy='8'/%3e%3c/svg%3e");background-position:right center}

/* ---------- Tables ---------- */
.table-responsive{overflow-x:auto}
/* Browser-native row virtualization for data grids: skip rendering/layout of off-screen rows in long
   lists (cheap, no JS). contain-intrinsic-size reserves an estimated row height so the scrollbar is stable. */
.ibis-grid > table > tbody > tr{content-visibility:auto;contain-intrinsic-size:auto 2.2rem}
.table{width:100%;margin-bottom:0;color:var(--text);border-collapse:collapse;vertical-align:middle}
.table>thead>tr>th{padding:.6rem .75rem;text-align:left;background:#f8fafc;color:#64748b;text-transform:uppercase;font-size:.625rem;letter-spacing:.04em;font-weight:600;border-bottom:1px solid var(--border);position:sticky;top:0;z-index:2}
.table>tbody>tr>td{padding:.6rem .75rem;border-top:1px solid #eef1f6;vertical-align:middle;font-size:.6875rem}
.table-sm>thead>tr>th,.table-sm>tbody>tr>td{padding:.4rem .6rem}
/* Row action buttons (Save/Delete/Edit…) stay on ONE line — a narrow fixed-width actions column
   otherwise wraps a 2nd/3rd button underneath. The table already scrolls horizontally if needed. */
.ibis-grid td.ibis-actions{white-space:nowrap}
/* Sticky identity column(s) (IbisColumn.StickyLeftPx) — pins e.g. "#" + the row's identifying text field to
   the left edge of a horizontally-scrolling grid, so scrolling right through many data columns never loses
   track of which row you're looking at. `left` is set per-column inline (offset must match the rendered width
   of any sticky column(s) before it); everything else lives here. A solid background is required — without
   one the scrolled-past columns behind would show through a "transparent" sticky cell. z-index:3 on sticky
   header cells beats the plain sticky-top header (z-index:2 above) so the top-left corner cell renders over
   both a scrolled column AND a scrolled row. */
.ibis-grid td.ibis-sticky-col,.ibis-grid th.ibis-sticky-col{position:sticky;background:#fff}
.ibis-grid thead th.ibis-sticky-col{z-index:3;background:#f8fafc}
.ibis-grid tbody td.ibis-sticky-col{box-shadow:2px 0 4px -2px rgba(16,24,40,.15)}
.ibis-grid tr:hover td.ibis-sticky-col{background:#f8fafc}
/* Rows awaiting the accountability confirmation sign-off, tinted amber so they stand out as "pending". */
.ibis-grid tr.row-pending-confirm>td{background:#fff7ed}
.ibis-grid tr.row-pending-confirm:hover>td{background:#ffedd5}
.ibis-grid-card.row-pending-confirm{border-left:3px solid #d97706;background:#fff7ed}
/* Master-data type-ahead picker (upload header lookup fields, e.g. Stockist) */
.master-picker{position:relative}
.master-picker__menu{position:absolute;z-index:30;top:100%;left:0;right:0;margin-top:2px;background:#fff;border:1px solid var(--border);border-radius:8px;box-shadow:0 6px 20px rgba(16,24,40,.12);max-height:240px;overflow-y:auto}
.master-picker__item{display:flex;align-items:center;justify-content:space-between;gap:.5rem;width:100%;text-align:left;background:none;border:0;padding:.35rem .6rem;font-size:.8rem;color:var(--text);cursor:pointer}
.master-picker__item:hover{background:#f1f5f9}
.master-picker__code{color:var(--muted);font-size:.72rem;flex-shrink:0}
.master-picker__hint{padding:.4rem .6rem;font-size:.78rem;color:var(--muted)}
/* An <input>/<select> has essentially no intrinsic minimum width, so a table column left flexible
   (no explicit th width — e.g. an inline-editable "Name" column) gets crushed to a few px once
   sibling columns claim their fixed pixel widths, instead of the table overflowing into its
   .table-responsive scroll area the way a same-width text column would. Floors it at a usable size
   so the table grows and scrolls horizontally instead of rendering an unreadable sliver of a field. */
.table td .form-control,.table td .form-select{min-width:90px}
.table-hover>tbody>tr:hover>td{background:#f7f9fc}

/* "Only the grid scrolls" (Nexus convention) — a grid with no explicit maxHeight (IbisGrid's own
   default; see IbisGrid.tsx's fillHeight) fills whatever room is left in the viewport and scrolls
   internally, instead of growing to its full row count and pushing the whole page into a page-level
   scroll. Scoped to .ibis-grid--fill via :has() so this applies automatically to every plain
   <IbisGrid/> with zero per-page markup changes; a page that already manages its own height (e.g.
   Review Workbench's multi-pane layout, which passes an explicit maxHeight) never gets this class
   and is untouched. .app-content keeps its own overflow-y:auto as a fallback — if the content above
   the grid is already taller than the viewport, the page scrolls rather than clipping it. */
.app-content:has(.ibis-grid--fill){display:flex;flex-direction:column}
.app-content:has(.ibis-grid--fill)>*{flex-shrink:0}
.app-content:has(.ibis-grid--fill)>.card:has(.ibis-grid--fill){flex:1 1 auto;min-height:0;display:flex;flex-direction:column}
.card:has(>.card-body .ibis-grid--fill)>.card-body{flex:1 1 auto;min-height:0;display:flex;flex-direction:column}
.card-body:has(>.ibis-grid--fill)>*:not(.ibis-grid--fill){flex-shrink:0}
.ibis-grid--fill{flex:1 1 auto;min-height:160px;overflow-y:auto}
/* The viewport-fill layout above is for a SINGLE grid page. When a page stacks 2+ grid cards (Matching:
   Needs attention + Pending; Territories: 4 sections), each fill grid claims flex:1 + min-height and the
   cards overlap. Detect "a fill grid inside a card that follows another card" and fall back to normal
   flow — the content pane scrolls and every fill grid sizes to its own content. (Written WITHOUT nesting
   :has() inside :has(), which browsers don't support.) */
.app-content:has(.card ~ .card .ibis-grid--fill){display:block}
/* Bound each grid and KEEP its overflow:auto (from .table-responsive/.ibis-grid--fill) so a wide table
   scrolls horizontally INSIDE its own box instead of overflow:visible spilling out and dragging the whole
   page sideways. max-height (not flex:1) is what stops the stacked cards overlapping. */
.app-content:has(.card ~ .card .ibis-grid--fill) .ibis-grid--fill{flex:none;min-height:0;max-height:72vh}

/* Generic "fill the rest of the viewport, no page scroll" primitive for a page that manages its own
   internal layout entirely (e.g. Review Workbench's multi-pane split view, which needs an exact
   height budget for its own panes/scroll areas rather than growing with content). Unlike
   .ibis-grid--fill above, this has no overflow fallback on .app-content — the page itself is
   responsible for scrolling its own long content in the right place, exactly as it already did with
   its previous hardcoded `calc(100vh - 90px)` height (now computed correctly via flex instead of a
   magic number that drifted stale whenever the shell's own chrome height changed). */
.app-content:has(.page-fill){display:flex;flex-direction:column;overflow:hidden}
.app-content:has(.page-fill)>*{flex-shrink:0}
.app-content:has(.page-fill)>.page-fill{flex:1 1 auto;min-height:0}
.cursor-pointer{cursor:pointer}
.ibis-gutter{flex:0 0 8px;cursor:col-resize;position:relative;align-self:stretch;background:transparent}
.ibis-gutter::before{content:"";position:absolute;left:3px;top:0;bottom:0;width:2px;border-radius:2px;background:var(--border);transition:background .12s}
.ibis-gutter:hover::before,.ibis-gutter.dragging::before{background:var(--primary)}
.ibis-gutter.dragging::before{box-shadow:0 0 0 1px rgba(89,128,166,.35)}
/* IbisSplit's Vertical orientation (top/bottom panes, e.g. Review Workbench's grid-over-document layout) —
   same gutter, rotated: a horizontal bar you drag up/down instead of a vertical one you drag left/right. */
.ibis-split--vertical{flex-direction:column}
.ibis-split--vertical>.ibis-split__pane{width:100%;min-height:0}
.ibis-gutter--horizontal{flex:0 0 8px;cursor:row-resize;align-self:stretch}
.ibis-gutter--horizontal::before{left:0;right:0;top:3px;bottom:auto;width:auto;height:2px}
.table>tbody>tr.is-selected>td{background:var(--primary-soft);box-shadow:inset 3px 0 0 var(--primary)}
.table>tbody>tr.is-selected:hover>td{background:#e2e8ed}
.table-light>tr>th,thead.table-light>tr>th{background:#f8fafc}

/* ---------- Badges ---------- */
.badge{display:inline-flex;align-items:center;gap:.25rem;padding:.35em .6em;font-size:.625rem;font-weight:600;line-height:1;border-radius:6px;letter-spacing:.01em;white-space:nowrap}
.text-bg-success{background:var(--success-bg);color:var(--success-fg)}
.text-bg-danger{background:var(--danger-bg);color:var(--danger-fg)}
.text-bg-warning{background:var(--warning-bg);color:var(--warning-fg)}
.text-bg-info{background:var(--info-bg);color:var(--info-fg)}
.text-bg-primary{background:var(--primary-soft);color:var(--primary-d)}
.text-bg-secondary{background:#eef1f6;color:#475569}
.text-bg-light{background:#f1f5f9;color:#475569;border:1px solid var(--border)}
.text-bg-dark{background:#1e293b;color:#fff}

/* ---------- Alerts ---------- */
.alert{padding:.7rem 1rem;border:1px solid transparent;border-radius:var(--radius-sm);margin-bottom:1rem;font-size:.6875rem}
.alert-success{background:var(--success-bg);border-color:var(--success-bg);color:var(--success-fg)}
.alert-danger{background:var(--danger-bg);border-color:var(--danger-bg);color:var(--danger-fg)}
.alert-warning{background:var(--warning-bg);border-color:var(--warning-bg);color:var(--warning-fg)}
.alert-info{background:var(--info-bg);border-color:var(--info-bg);color:var(--info-fg)}

/* ---------- Spinner ---------- */
@keyframes spin{to{transform:rotate(360deg)}}
.spinner-border{display:inline-block;width:1.5rem;height:1.5rem;vertical-align:-.125em;border:.2em solid currentColor;border-right-color:transparent;border-radius:50%;animation:spin .75s linear infinite}
.spinner-border-sm{width:1rem;height:1rem;border-width:.15em}
.text-primary.spinner-border{color:var(--primary)}

/* ---------- Progress ---------- */
.progress{display:flex;height:1rem;overflow:hidden;background:#e9edf3;border-radius:50rem;font-size:.7rem}
.progress-bar{display:flex;align-items:center;justify-content:center;background:var(--primary);color:#fff;transition:width .3s ease}

/* ---------- List group ---------- */
.list-group{display:flex;flex-direction:column;border-radius:var(--radius-sm);list-style:none;margin:0;padding:0}
.list-group-item{padding:.6rem .9rem;background:#fff;border:1px solid var(--border)}
.list-group-item+.list-group-item{border-top-width:0}
.list-group-flush .list-group-item{border-right:0;border-left:0;border-radius:0}
.list-group-item-action{cursor:pointer;text-align:inherit;width:100%}
.list-group-item-action:hover{background:#f7f9fc}

/* ---------- Dropdown ---------- */
.dropdown-menu{position:absolute;z-index:1000;display:none;min-width:12rem;padding:.4rem;margin:.25rem 0 0;background:#fff;border:1px solid var(--border);border-radius:var(--radius-sm);box-shadow:var(--shadow)}
.dropdown-menu.show{display:block}
.dropdown-item{display:block;width:100%;padding:.45rem .6rem;color:var(--text);text-decoration:none;background:transparent;border:0;border-radius:6px;text-align:left;cursor:pointer;font-size:.6875rem}
.dropdown-item:hover{background:#f1f5f9;color:var(--heading)}

/* ---------- Modal (React-controlled) ---------- */
.modal{position:fixed;inset:0;z-index:1055;display:none;overflow:auto}
.modal.d-block{display:block!important}
.modal-dialog{position:relative;width:auto;max-width:560px;margin:1.75rem auto;pointer-events:none}
.modal-sm{max-width:360px}.modal-lg{max-width:820px}.modal-xl{max-width:1140px}
.modal-dialog-scrollable .modal-content{max-height:calc(100vh - 3.5rem);overflow:hidden}
.modal-dialog-scrollable .modal-body{overflow-y:auto}
.modal-content{position:relative;display:flex;flex-direction:column;pointer-events:auto;background:#fff;border-radius:var(--radius);box-shadow:var(--shadow-lg)}
.modal-header{display:flex;align-items:center;justify-content:space-between;padding:.85rem 1.1rem;border-bottom:1px solid var(--border)}
.modal-title{margin:0;font-size:1.05rem;font-weight:600}
.modal-body{position:relative;flex:1 1 auto;padding:1.1rem}
.modal-footer{display:flex;align-items:center;justify-content:flex-end;gap:.5rem;padding:.85rem 1.1rem;border-top:1px solid var(--border)}
.modal-backdrop{position:fixed;inset:0;z-index:1050;background:#0f172a}
.modal-backdrop.show{opacity:.5}

/* ---------- Misc ---------- */
.vr{display:inline-block;align-self:stretch;width:1px;min-height:1em;background:var(--border);opacity:1}
.show{}

/* ---------- Completions (dynamic classes) ---------- */
.me-2{margin-right:.5rem!important}
.p-1{padding:.25rem!important}
.px-0{padding-left:0!important;padding-right:0!important}
.bg-success{background-color:var(--success)!important}
.bg-danger{background-color:var(--danger)!important}
.bg-warning{background-color:var(--warning)!important}
.bg-info{background-color:var(--info)!important}
.bg-secondary{background-color:#64748b!important}
.bg-dark{background-color:#1e293b!important}
.bg-white.bg-opacity-75{background-color:rgba(255,255,255,.75)!important}
.border-primary{border-color:var(--primary)!important}
.border-secondary-subtle{border-color:var(--border)!important}
.border-sm{border-width:1px!important}
.btn-danger{--btn-bg:var(--danger);--btn-color:#fff;--btn-border:var(--danger);--btn-hover-bg:#b91c1c;--btn-hover-color:#fff;--btn-hover-border:#b91c1c}
.btn-outline-info{--btn-color:var(--info-fg);--btn-border:#7dd3fc;--btn-hover-bg:var(--info);--btn-hover-color:#fff;--btn-hover-border:var(--info)}

/* ---------- Status bar ---------- */
/* Slim, read-only footer fixed to the bottom of the shell (Nexus convention) — present on every
   screen, nothing in it is clickable, never duplicates what the topbar/ribbon already show. */
.statusbar{flex-shrink:0;height:24px;background:#f8fafc;border-top:1px solid var(--border);color:var(--muted);font-size:.625rem;display:flex;align-items:center;gap:.75rem;padding:0 .7rem}
.statusbar-context{flex-shrink:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.statusbar-system{margin-left:auto;flex-shrink:0;display:flex;align-items:center;gap:.6rem;white-space:nowrap;text-transform:uppercase;letter-spacing:.04em;font-size:.6rem}

/* ---------- Responsive display utilities ---------- */
@media (max-width:575.98px){
  .d-sm-none{display:none!important}
}
@media (min-width:576px){
  .d-none.d-sm-inline{display:inline!important}
  .d-none.d-sm-block{display:block!important}
  .d-none.d-sm-flex{display:flex!important}
}

/* ---------- Mobile shell (off-canvas sidebar + density) ---------- */
.app-sidebar-backdrop{position:absolute;inset:0;z-index:1044;background:rgba(15,23,42,.45);backdrop-filter:saturate(120%) blur(1px)}

@media (max-width:767.98px){
  /* Sidebar becomes a slide-in drawer that overlays content instead of taking flow width. */
  .app-sidebar--drawer{position:absolute;top:0;left:0;bottom:0;z-index:1045;width:240px!important;
    box-shadow:var(--shadow-lg);transform:translateX(-100%);transition:transform .2s ease}
  .app-sidebar--drawer.is-open{transform:translateX(0)}

  /* Tighter content padding and smaller page headings so phones aren't dominated by chrome. */
  .app-content{padding:.5rem!important}
  h1,.h1{font-size:1.1rem}
  h2{font-size:1rem}
  h3{font-size:.9rem}

  /* Topbar: drop the username text and shrink the brand so the bar never overflows. */
  .topbar-username{display:none}
  .navbar-brand{font-size:1rem}
  .app-topbar{padding-left:.6rem;padding-right:.6rem}

  /* Full-bleed modals on small screens. */
  .modal-dialog{margin:.5rem;max-width:none}
  .modal-lg,.modal-xl{max-width:none}

  /* The status bar is chrome, not content — on a phone that space is worth more given to the page. */
  .statusbar{display:none}

  /* Data grids: a table with 6+ columns is unreadable at 375px wide, so IbisGrid switches to one
     card per row (title + right-aligned actions + label/value pairs) below the tablet breakpoint. */
  .ibis-grid--cards{display:flex;flex-direction:column;gap:.6rem}
  .ibis-grid-card{position:relative;background:var(--surface);border:1px solid var(--border);border-radius:var(--radius);box-shadow:var(--shadow-sm);padding:.7rem .85rem}
  .ibis-grid-card.is-selected{border-color:var(--primary);box-shadow:0 0 0 1px var(--primary)}
  .ibis-grid-card__actions{display:flex;justify-content:flex-end;flex-wrap:wrap;gap:.35rem;margin-bottom:.5rem;padding-bottom:.5rem;border-bottom:1px solid var(--border)}
  .ibis-grid-card__title{font-weight:600;color:var(--heading);font-size:.75rem;margin-bottom:.4rem;word-break:break-word}
  .ibis-grid-card__fields{display:flex;flex-direction:column;gap:.4rem;margin:0}
  .ibis-grid-card__field{display:flex;justify-content:space-between;align-items:baseline;gap:.75rem}
  .ibis-grid-card__field dt{flex:0 0 auto;color:var(--muted);text-transform:uppercase;font-size:.6rem;font-weight:600;letter-spacing:.03em}
  .ibis-grid-card__field dd{margin:0;text-align:right;min-width:0;flex:1 1 auto;overflow:hidden;word-break:break-word}
  /* Cell renderers set their own max-width (tuned for a table column) which is meaningless here — force
     any block-ish child (link/button showing a filename etc.) to truncate to the card's own width instead. */
  .ibis-grid-card__field dd>.btn,.ibis-grid-card__field dd>a,.ibis-grid-card__field dd>button{
    display:block;width:100%;max-width:100%!important;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;text-align:right}
  .ibis-grid-card__empty{background:var(--surface);border:1px solid var(--border);border-radius:var(--radius)}
}

/* Very small phones: also hide the "Logout" word, keep the icon. */
@media (max-width:400px){
  .topbar-logout-label{display:none}
}

/* ---------- Scrollbars ---------- */
*::-webkit-scrollbar{width:10px;height:10px}
*::-webkit-scrollbar-thumb{background:#cbd5e1;border-radius:8px;border:2px solid transparent;background-clip:content-box}
*::-webkit-scrollbar-thumb:hover{background:#94a3b8;background-clip:content-box}
*::-webkit-scrollbar-track{background:transparent}
