/* ============================================================================
   KSA JOBS PORTAL — GLASSMORPHISM DESIGN SYSTEM  (ksa-glass.css)
   ----------------------------------------------------------------------------
   Brand colors (STRICT — the only two brand colors allowed):
     Primary : #444097   Accent : #eb3335
   Typography: Poppins (webfont) -> Footlight MT -> system sans-serif.
   Theming   : light (default) / dark via  html[data-ksa-theme="dark"].
   Controlled by production/js/ksa-theme.js (toggle + localStorage persistence).

   HOW FUTURE MODULES ADOPT THIS SYSTEM
   Include two lines in the page <head> (paths relative to the page):
     <link href="css/ksa-glass.css" rel="stylesheet" />
     <script src="js/ksa-theme.js" defer></script>
   Then wrap content panels in class "x_panel" or "ksa-glass".
   Never hard-code colors — use the CSS variables below.
   ========================================================================== */

@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;500;600;700;800&display=swap');

/* ---------------------------------------------------------------------------
   1. DESIGN TOKENS (CSS custom properties)
   ------------------------------------------------------------------------- */
:root {
  /* Brand */
  --ksa-primary:        #444097;
  --ksa-primary-600:    #37347c;   /* darker shade of primary  */
  --ksa-primary-300:    #6f6bc0;   /* lighter tint of primary  */
  --ksa-primary-100:    #e9e8f6;   /* faint tint of primary    */
  --ksa-accent:         #eb3335;
  --ksa-accent-600:     #c4272a;   /* darker shade of accent   */
  --ksa-accent-100:     #fdeaea;   /* faint tint of accent     */

  /* Typography */
  --ksa-font: 'Poppins', 'Footlight MT', 'Segoe UI', Arial, sans-serif;

  /* Light theme surfaces */
  --ksa-bg-page:        linear-gradient(135deg, #eef0fb 0%, #f6f5fc 45%, #fdf0f0 100%);
  --ksa-bg-page-solid:  #f2f2fa;
  --ksa-text:           #232244;
  --ksa-text-soft:      #55547a;
  --ksa-text-inverse:   #ffffff;

  /* Glass tokens */
  --ksa-glass-bg:       rgba(255, 255, 255, 0.60);
  --ksa-glass-bg-strong:rgba(255, 255, 255, 0.78);
  --ksa-glass-border:   rgba(68, 64, 151, 0.18);
  --ksa-glass-blur:     14px;
  --ksa-glass-shadow:   0 8px 32px rgba(68, 64, 151, 0.14);
  --ksa-glass-radius:   14px;

  /* Sidebar */
  --ksa-side-bg:        linear-gradient(180deg, rgba(68,64,151,0.94) 0%, rgba(55,52,124,0.94) 100%);
  --ksa-side-text:      #eceaf8;
  --ksa-side-active:    rgba(255,255,255,0.16);

  /* Controls */
  --ksa-input-bg:       rgba(255,255,255,0.72);
  --ksa-input-border:   rgba(68, 64, 151, 0.28);
  --ksa-focus-ring:     0 0 0 3px rgba(68, 64, 151, 0.25);
  --ksa-table-stripe:   rgba(68, 64, 151, 0.05);
  --ksa-table-head:     rgba(68, 64, 151, 0.10);
}

html[data-ksa-theme="dark"] {
  --ksa-bg-page:        linear-gradient(135deg, #14132b 0%, #1b1a38 55%, #2a1424 100%);
  --ksa-bg-page-solid:  #16152e;
  --ksa-text:           #eceaf8;
  --ksa-text-soft:      #b9b7d8;
  --ksa-text-inverse:   #ffffff;

  --ksa-glass-bg:       rgba(38, 36, 84, 0.48);
  --ksa-glass-bg-strong:rgba(38, 36, 84, 0.70);
  --ksa-glass-border:   rgba(151, 148, 219, 0.22);
  --ksa-glass-shadow:   0 8px 32px rgba(0, 0, 0, 0.45);

  --ksa-side-bg:        linear-gradient(180deg, rgba(24,23,52,0.92) 0%, rgba(30,28,66,0.92) 100%);
  --ksa-side-text:      #d9d7f0;
  --ksa-side-active:    rgba(111,107,192,0.28);

  --ksa-input-bg:       rgba(20, 19, 43, 0.65);
  --ksa-input-border:   rgba(151, 148, 219, 0.35);
  --ksa-focus-ring:     0 0 0 3px rgba(111, 107, 192, 0.45);
  --ksa-table-stripe:   rgba(111, 107, 192, 0.08);
  --ksa-table-head:     rgba(111, 107, 192, 0.16);
}

/* ---------------------------------------------------------------------------
   2. BASE / TYPOGRAPHY
   ------------------------------------------------------------------------- */
html, body {
  font-family: var(--ksa-font) !important;
  color: var(--ksa-text);
  background: var(--ksa-bg-page) fixed !important;
  min-height: 100vh;
}
body { font-size: 14px; line-height: 1.6; }

h1, h2, h3, h4, h5, h6 {
  font-family: var(--ksa-font) !important;
  color: var(--ksa-text);
  font-weight: 600;
  letter-spacing: .2px;
}
h1 { font-size: 26px; } h2 { font-size: 22px; } h3 { font-size: 19px; }
h4 { font-size: 16px; } h5 { font-size: 14px; }

label, .col-form-label {
  font-weight: 500;
  color: var(--ksa-text-soft);
  font-size: 13px;
}
a { color: var(--ksa-primary); transition: color .18s ease; }
a:hover, a:focus { color: var(--ksa-accent); text-decoration: none; }
small, .small { font-size: 12px; color: var(--ksa-text-soft); }

/* Visible focus for accessibility */
a:focus-visible, button:focus-visible, input:focus-visible,
select:focus-visible, textarea:focus-visible, [tabindex]:focus-visible {
  outline: 2px solid var(--ksa-accent) !important;
  outline-offset: 2px;
}

/* ---------------------------------------------------------------------------
   3. GLASS SURFACES — panels, cards, modals
   Gentelella containers are re-skinned; use .ksa-glass on anything new.
   ------------------------------------------------------------------------- */
.ksa-glass,
.x_panel,
.panel, .card,
.modal-content,
.login_content form,
.jumbotron,
.well {
  background: var(--ksa-glass-bg) !important;
  -webkit-backdrop-filter: blur(var(--ksa-glass-blur));
  backdrop-filter: blur(var(--ksa-glass-blur));
  border: 1px solid var(--ksa-glass-border) !important;
  border-radius: var(--ksa-glass-radius) !important;
  box-shadow: var(--ksa-glass-shadow);
  color: var(--ksa-text);
}
.x_panel { padding: 18px 20px; margin-bottom: 18px; }
.x_title {
  border-bottom: 1px solid var(--ksa-glass-border) !important;
  padding-bottom: 10px; margin-bottom: 14px;
}
.x_title h2, .x_title h3 { color: var(--ksa-primary); font-weight: 600; }
html[data-ksa-theme="dark"] .x_title h2,
html[data-ksa-theme="dark"] .x_title h3 { color: var(--ksa-primary-300); }

/* Section headings used across profile pages */
.auto-style2, .auto-style3 { font-family: var(--ksa-font) !important; }

/* ---------------------------------------------------------------------------
   4. HEADER / TOP NAVIGATION
   ------------------------------------------------------------------------- */
.top_nav .nav_menu {
  background: var(--ksa-glass-bg-strong) !important;
  -webkit-backdrop-filter: blur(var(--ksa-glass-blur));
  backdrop-filter: blur(var(--ksa-glass-blur));
  border-bottom: 1px solid var(--ksa-glass-border);
  box-shadow: 0 2px 18px rgba(68,64,151,.10);
  color: var(--ksa-text);
}
/* NOTE: do NOT include .fa/.glyphicon here — a wildcard font-family replaces the
   icon font and glyphs render as empty boxes (see §27). */
.top_nav .nav_menu, .top_nav .nav_menu *:not(.fa):not(.glyphicon) { font-family: var(--ksa-font); }
.top_nav .navbar-right li, .top_nav .navbar-right strong { color: var(--ksa-text) !important; }
.ksa-agency-name { font-size: 20px; font-weight: 700; color: var(--ksa-primary); }
html[data-ksa-theme="dark"] .ksa-agency-name { color: var(--ksa-primary-300); }
.ksa-agency-tagline { font-size: 12px; color: var(--ksa-text-soft); font-weight: 400; }

.ksa-nav-actions a {
  display: inline-block; margin-left: 12px; font-weight: 600;
  color: var(--ksa-primary) !important; font-size: 13px;
}
.ksa-nav-actions a:hover { color: var(--ksa-accent) !important; }

/* ---------------------------------------------------------------------------
   5. SIDEBAR  (production/js/user_menu.ascx — structure preserved)
   ------------------------------------------------------------------------- */
.left_col, .main_menu_side, #sidebar-menu {
  background: transparent;
}
#sidebar-menu.main_menu {
  background: var(--ksa-side-bg) !important;
  -webkit-backdrop-filter: blur(var(--ksa-glass-blur));
  backdrop-filter: blur(var(--ksa-glass-blur));
  border: 1px solid var(--ksa-glass-border);
  border-radius: var(--ksa-glass-radius);
  box-shadow: var(--ksa-glass-shadow);
  /* Tightened up (was 14px 10px 20px / 10px 6px) so more items fit before
     the user needs to scroll to reach the rest. */
  padding: 8px 8px 12px;
  margin: 6px 6px;
}

/* Sidebar header: platform title only (logo removed - it made this header
   tall enough to crowd/overflow the top navbar). */
.ksa-side-header { text-align: center; padding: 10px 8px; border-bottom: 1px solid rgba(255,255,255,.14); margin-bottom: 12px; }
.ksa-side-title  {
  display: block; font-size: 15px; font-weight: 700; letter-spacing: .4px;
  color: var(--ksa-text-inverse) !important; text-transform: uppercase; line-height: 1.35;
}
.ksa-side-title:hover { color: #ffd7d7 !important; }

/* Menu items — names/order untouched, visuals modernized. Styled like
   .ksa-dash-cards (flex row, icon in its own badge) instead of a plain
   text link, for the same look across every sidebar entry. */
#sidebar-menu .nav.side-menu > li > a,
#sidebar-menu .nav.child_menu > li > a {
  color: var(--ksa-side-text) !important;
  font-family: var(--ksa-font);
  font-size: 13.5px; font-weight: 500;
  border-radius: 8px;
  /* Tightened up (was 10px 12px / 2px 4px) so more items fit before the
     user needs to scroll to reach the rest. */
  padding: 7px 10px;
  margin: 1px 3px;
  display: flex; align-items: center;
  position: relative;
  background: transparent;
  transition: background .2s ease, color .2s ease, padding-left .2s ease;
}
#sidebar-menu .nav.side-menu > li > a:hover,
#sidebar-menu .nav.child_menu > li > a:hover {
  background: var(--ksa-side-active);
  color: #ffffff !important;
  padding-left: 18px;
}
#sidebar-menu .nav.side-menu > li.current-page > a,
#sidebar-menu .nav.child_menu > li.current-page > a,
#sidebar-menu li a.ksa-active {
  background: var(--ksa-accent) !important;
  color: #ffffff !important;
  box-shadow: 0 4px 14px rgba(235,51,53,.35);
}
#sidebar-menu li a.ksa-active::before {
  content: ""; position: absolute; left: -4px; top: 20%; height: 60%; width: 4px;
  border-radius: 4px; background: #ffffff;
}
#sidebar-menu .fa-chevron-down {
  /* was float:right - doesn't apply inside the flex row above, use auto margin instead */
  margin-left: auto; float: none; font-size: 10px;
  transition: transform .25s ease;
}
#sidebar-menu li.active > a > .fa-chevron-down { transform: rotate(180deg); }

/* "My Profile" submenu items (.ksa-profile-cards, in user_menu.ascx) get the
   full two-line ksa-dash-cards treatment - bold title + description - not
   just an icon and a single line like other submenu entries. */
#sidebar-menu .ksa-profile-cards > li > a {
  align-items: center;
  min-height: 0;
}
#sidebar-menu .ksa-profile-cards > li > a > span {
  display: flex; flex-direction: column; gap: 1px;
  min-width: 0;
}
#sidebar-menu .ksa-profile-cards > li > a > span > b {
  font-size: 12.5px; font-weight: 600;
  white-space: normal; line-height: 1.25;
}
#sidebar-menu .ksa-profile-cards > li > a > span > span {
  font-size: 10px; font-weight: 400; opacity: .7;
  white-space: normal; line-height: 1.25;
}

/* Child menus: smooth open feel + indentation guides. Open by default (base
   custom.css has display:none) - ksa-theme.js seeds .active on load so the
   old jQuery accordion's own click-to-toggle still works from there, this
   just avoids a flash-of-collapsed-content before that script runs.
   height/max-height/overflow forced here because custom.js's slideUp/slideDown
   leaves a cached inline pixel height behind after animating - once "My
   Profile" grew taller (2-line card items), that stale height came up short
   and clipped the last few entries. Forcing auto height means the toggle
   snaps open/closed instead of sliding, but nothing gets clipped regardless
   of content height. */
#sidebar-menu .nav.child_menu {
  display: block;
  height: auto !important;
  max-height: none !important;
  overflow: visible !important;
  background: rgba(0,0,0,.14); border-radius: 8px;
  /* Tightened up (was 2px 6px 6px / 4px 2px) so more items fit before the
     user needs to scroll to reach the rest. */
  margin: 1px 4px 4px;
  padding: 2px 2px;
}
#sidebar-menu .nav.child_menu li {
  border-left: 2px solid rgba(255,255,255,.12); margin-left: 8px;
  /* Gentelella indents every nesting level by 36px (padding-left, custom.css
     ~1341). The menu here nests two child levels, so 72px of the column went
     to pure indent and labels word-broke when the sidebar was resized narrow.
     The guide line above already conveys depth; a small indent is enough. */
  padding-left: 14px !important;
}
#sidebar-menu .nav.child_menu li:hover { border-left-color: var(--ksa-accent); }

/* Sidebar section slot for FUTURE MODULES:
   <div class="menu_section" data-module="moduleName"> ... same ul.nav.side-menu markup ... */
.menu_section + .menu_section { border-top: 1px dashed rgba(255,255,255,.18); margin-top: 12px; padding-top: 10px; }

/* ---------------------------------------------------------------------------
   6. FORMS
   ------------------------------------------------------------------------- */
.form-control, input[type="text"], input[type="password"], input[type="email"],
input[type="number"], input[type="date"], select, textarea {
  font-family: var(--ksa-font) !important;
  background: var(--ksa-input-bg) !important;
  border: 1px solid var(--ksa-input-border) !important;
  border-radius: 9px !important;
  color: var(--ksa-text) !important;
  min-height: 36px;
  padding: 6px 12px;
  /* Without this, "width:100%" + this padding/border renders wider than the
     container on pages that don't load Bootstrap's own border-box reset
     (e.g. loginPage.aspx) - the field then overflows past its wrapper. */
  box-sizing: border-box;
  transition: border-color .18s ease, box-shadow .18s ease;
}
.form-control:focus, input:focus, select:focus, textarea:focus {
  border-color: var(--ksa-primary) !important;
  box-shadow: var(--ksa-focus-ring) !important;
}
::placeholder { color: var(--ksa-text-soft); opacity: .75; }
input[disabled], input[readonly], select[disabled], .aspNetDisabled {
  opacity: .55; cursor: not-allowed;
}
.form-group.row { margin-bottom: 12px; align-items: center; }

/* Inline validation hint (used by ksa-theme.js) */
.ksa-field-error { color: var(--ksa-accent); font-size: 12px; font-weight: 500; margin-top: 3px; display: block; }
input.ksa-invalid, select.ksa-invalid { border-color: var(--ksa-accent) !important; box-shadow: 0 0 0 3px rgba(235,51,53,.18) !important; }

/* ---------------------------------------------------------------------------
   6b. FILE INPUTS (asp:FileUpload renders as a plain, unstyled native
   <input type="file"> - browser-default grey "Choose File"/"Browse" chrome
   that clashes with the rest of the UI). Applied globally here (this file is
   loaded on every page) rather than per-page, since ~15 .aspx files use
   asp:FileUpload. The control itself gets the same chrome as .form-control;
   the native browse button portion is restyled via ::file-selector-button
   (Chrome/Edge/Firefox) with the legacy ::-webkit-file-upload-button kept as
   a fallback for older WebKit/Blink - both are targeted so the button always
   matches the app's .btn-primary gradient instead of OS chrome. The input
   stays a fully functional native file field; only its cosmetic chrome and
   the button's own appearance are touched.
   ------------------------------------------------------------------------- */
input[type="file"] {
  font-family: var(--ksa-font) !important;
  color: var(--ksa-text-soft) !important;
  background: var(--ksa-input-bg) !important;
  border: 1px solid var(--ksa-input-border) !important;
  border-radius: 9px !important;
  padding: 5px 10px !important;
  min-height: 36px;
  box-sizing: border-box;
  cursor: pointer;
}
input[type="file"]:focus {
  outline: none;
  border-color: var(--ksa-primary) !important;
  box-shadow: var(--ksa-focus-ring) !important;
}
input[type="file"][disabled] { opacity: .55; cursor: not-allowed; }

/* NOTE: ::file-selector-button and ::-webkit-file-upload-button are kept in
   SEPARATE rules throughout (never comma-grouped) - a browser that doesn't
   recognise one of the two pseudo-elements can drop an entire grouped
   selector list, which would silently kill the other, supported one too. */
input[type="file"]::file-selector-button {
  font-family: var(--ksa-font);
  font-weight: 600;
  letter-spacing: .3px;
  color: #fff;
  background: linear-gradient(135deg, var(--ksa-primary) 0%, var(--ksa-primary-600) 100%);
  border: none;
  border-radius: 8px;
  padding: 7px 16px;
  margin-right: 12px;
  cursor: pointer;
  box-shadow: 0 4px 14px rgba(68,64,151,.35);
  transition: transform .15s ease, box-shadow .15s ease, background .2s ease;
}
input[type="file"]::-webkit-file-upload-button {
  font-family: var(--ksa-font);
  font-weight: 600;
  letter-spacing: .3px;
  color: #fff;
  background: linear-gradient(135deg, var(--ksa-primary) 0%, var(--ksa-primary-600) 100%);
  border: none;
  border-radius: 8px;
  padding: 7px 16px;
  margin-right: 12px;
  cursor: pointer;
  box-shadow: 0 4px 14px rgba(68,64,151,.35);
  transition: transform .15s ease, box-shadow .15s ease, background .2s ease;
}
input[type="file"]:hover::file-selector-button {
  box-shadow: 0 6px 20px rgba(68,64,151,.45);
  transform: translateY(-1px);
}
input[type="file"]:hover::-webkit-file-upload-button {
  box-shadow: 0 6px 20px rgba(68,64,151,.45);
  transform: translateY(-1px);
}
input[type="file"]:active::file-selector-button {
  transform: translateY(0);
}
input[type="file"]:active::-webkit-file-upload-button {
  transform: translateY(0);
}
input[type="file"][disabled]::file-selector-button {
  cursor: not-allowed;
}
input[type="file"][disabled]::-webkit-file-upload-button {
  cursor: not-allowed;
}

/* ---------------------------------------------------------------------------
   7. BUTTONS — mapped onto existing Bootstrap/Gentelella classes so no page
      markup change is required. Primary actions = #444097, destructive/
      attention = #eb3335. No other brand colors.
   ------------------------------------------------------------------------- */
.btn { font-family: var(--ksa-font) !important; font-weight: 600; border-radius: 10px !important;
  letter-spacing: .3px; transition: transform .15s ease, box-shadow .15s ease, background .2s ease;
  border: none !important; padding: 8px 18px; }
.btn:hover { transform: translateY(-1px); }
.btn:active { transform: translateY(0); }

.btn-success, .btn-primary, .btn-info, .btn-default[type="submit"] {
  background: linear-gradient(135deg, var(--ksa-primary) 0%, var(--ksa-primary-600) 100%) !important;
  color: #fff !important;
  box-shadow: 0 4px 14px rgba(68,64,151,.35);
}
.btn-success:hover, .btn-primary:hover, .btn-info:hover {
  box-shadow: 0 6px 20px rgba(68,64,151,.45);
}
.btn-danger, .btn-warning {
  background: linear-gradient(135deg, var(--ksa-accent) 0%, var(--ksa-accent-600) 100%) !important;
  color: #fff !important;
  box-shadow: 0 4px 14px rgba(235,51,53,.35);
}
.btn-default:not([type="submit"]) {
  background: var(--ksa-glass-bg-strong) !important;
  color: var(--ksa-primary) !important;
  border: 1px solid var(--ksa-input-border) !important;
}

/* ---- normalised buttons (see normaliseButtons() in ksa-theme.js) ----------
   Every real button gets .btn.ksa-btn plus one role. These roles are declared
   with explicit colour AND background so they can never end up relying on an
   inherited value - which is how the old inline-styled buttons became white
   text on a white background in dark mode. */
.ksa-btn { cursor: pointer; -webkit-appearance: none; appearance: none;
  line-height: 1.35; text-align: center; }
.ksa-btn:disabled, .ksa-btn[disabled] { opacity: .55; cursor: not-allowed; transform: none; }

/* accent = leaving / destructive (Exit, Cancel, Delete) */
.ksa-btn-accent {
  background: linear-gradient(135deg, var(--ksa-accent) 0%, var(--ksa-accent-600) 100%) !important;
  color: #fff !important;
  box-shadow: 0 4px 14px rgba(235,51,53,.30);
}
.ksa-btn-accent:hover { box-shadow: 0 6px 20px rgba(235,51,53,.42); color: #fff !important; }

/* quiet = secondary actions with no stated role (was the unstyled grey button) */
.ksa-btn-quiet {
  background: var(--ksa-glass-bg-strong) !important;
  color: var(--ksa-primary) !important;
  border: 1px solid var(--ksa-input-border) !important;
  box-shadow: none;
}
.ksa-btn-quiet:hover {
  color: var(--ksa-accent) !important;
  border-color: var(--ksa-accent) !important;
}
html[data-ksa-theme="dark"] .ksa-btn-quiet { color: var(--ksa-primary-300) !important; }
html[data-ksa-theme="dark"] .ksa-btn-quiet:hover { color: var(--ksa-accent) !important; }

/* Belt-and-braces: any submit/button inside the content area that somehow still
   carries no role at all must never fall back to the browser's grey chrome. */
.right_col input[type="submit"]:not([class*="btn"]),
.right_col input[type="button"]:not([class*="btn"]),
.right_col button:not([class*="btn"]):not(.ksa-theme-toggle):not(#ksaHamburger) {
  font-family: var(--ksa-font) !important; font-weight: 600;
  border-radius: 10px; padding: 8px 18px;
  background: var(--ksa-glass-bg-strong); color: var(--ksa-primary);
  border: 1px solid var(--ksa-input-border); cursor: pointer;
}

/* ---------------------------------------------------------------------------
   8. TABLES / GRIDVIEWS (asp:GridView & DataGrid render as plain <table>)
   ------------------------------------------------------------------------- */
table { font-family: var(--ksa-font); color: var(--ksa-text); }
.x_panel table, table.table, .ksa-glass table {
  width: 100%; border-collapse: separate; border-spacing: 0;
  background: transparent !important; border-radius: 10px; overflow: hidden;
}
.x_panel table th, table.table th, .x_panel table tr:first-child td[bgcolor],
.x_panel table .ksa-th {
  background: var(--ksa-table-head) !important;
  color: var(--ksa-text) !important;
  font-weight: 600; font-size: 12.5px; letter-spacing: .4px;
  padding: 10px 12px; border-bottom: 1px solid var(--ksa-glass-border);
}
.x_panel table td, table.table td { padding: 9px 12px; border-bottom: 1px solid var(--ksa-glass-border); font-size: 13px; }
.x_panel table tr:nth-child(even) td { background: var(--ksa-table-stripe); }
.x_panel table tr:hover td { background: var(--ksa-primary-100); }
html[data-ksa-theme="dark"] .x_panel table tr:hover td { background: rgba(111,107,192,.15); }

/* Status pills — apply class ksa-pill / ksa-pill-accent in markup or via JS */
.ksa-pill { display: inline-block; padding: 3px 12px; border-radius: 999px;
  background: var(--ksa-primary-100); color: var(--ksa-primary); font-size: 12px; font-weight: 600; }
.ksa-pill-accent { background: var(--ksa-accent-100); color: var(--ksa-accent-600); }
html[data-ksa-theme="dark"] .ksa-pill { background: rgba(111,107,192,.22); color: #cfcdf0; }
html[data-ksa-theme="dark"] .ksa-pill-accent { background: rgba(235,51,53,.22); color: #ffb3b4; }

/* ---------------------------------------------------------------------------
   9. THEME TOGGLE + LOADING OVERLAY + EMPTY STATES (injected by ksa-theme.js)
   ------------------------------------------------------------------------- */
.ksa-theme-toggle {
  position: fixed; top: 14px; right: 16px; z-index: 9999;
  width: 42px; height: 42px; border-radius: 50%;
  background: var(--ksa-glass-bg-strong); color: var(--ksa-primary);
  -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px);
  border: 1px solid var(--ksa-glass-border); cursor: pointer;
  font-size: 18px; line-height: 40px; text-align: center;
  box-shadow: var(--ksa-glass-shadow);
  transition: transform .2s ease;
}
.ksa-theme-toggle:hover { transform: rotate(20deg) scale(1.06); }
html[data-ksa-theme="dark"] .ksa-theme-toggle { color: #ffd98a; }

.ksa-loading-overlay {
  position: fixed; inset: 0; z-index: 99999; display: none;
  background: rgba(20,19,43,.35); -webkit-backdrop-filter: blur(4px); backdrop-filter: blur(4px);
  align-items: center; justify-content: center;
}
.ksa-loading-overlay.ksa-show { display: flex; }
.ksa-spinner {
  width: 52px; height: 52px; border-radius: 50%;
  border: 4px solid rgba(255,255,255,.35); border-top-color: var(--ksa-accent);
  animation: ksa-spin .8s linear infinite;
}
@keyframes ksa-spin { to { transform: rotate(360deg); } }

.ksa-empty { text-align: center; padding: 34px 10px; color: var(--ksa-text-soft); }
.ksa-empty .fa { font-size: 34px; color: var(--ksa-primary-300); display: block; margin-bottom: 10px; }

/* ---------------------------------------------------------------------------
   9b. PAGE TRANSITIONS
   Every navigation is a full page load (no client-side router), so this is
   the whole trick: fade every arriving page in via a plain CSS animation
   (fires automatically on load, no JS needed - nothing to flash before it
   runs), and briefly fade the page out before ksa-theme.js (pageTransitions)
   follows a plain navigation link or submits a form. Covers the sidebar menu
   automatically too, mobile included, since those are just <a href> links.
   ------------------------------------------------------------------------- */
@keyframes ksaPageIn { from { opacity: 0; } to { opacity: 1; } }
body { animation: ksaPageIn .3s ease; }

/* NOTE: the old html.ksa-page-out fade-out is deliberately gone. Fading the
   page out required delaying the navigation by 150ms on EVERY click, which is
   pure added latency on a Web Forms app where each click is already a server
   round-trip. Feedback is now painted instantly instead (progress bar + pending
   row below) while the browser navigates immediately. */

/* Top progress bar: appears the instant a navigation starts, so the wait reads
   as "loading" rather than "nothing happened". Indeterminate on purpose - we
   cannot know the server's real progress. */
#ksaProgress {
  position: fixed; top: 0; left: 0; right: 0; height: 3px;
  z-index: 10000; pointer-events: none;
  opacity: 0; transition: opacity .12s ease;
}
#ksaProgress.ksa-run { opacity: 1; }
#ksaProgress.ksa-run::before {
  content: ""; position: absolute; top: 0; bottom: 0; left: 0;
  width: 40%; border-radius: 0 3px 3px 0;
  background: linear-gradient(90deg, var(--ksa-primary), var(--ksa-accent));
  animation: ksaProgSlide 1.1s cubic-bezier(.4, 0, .2, 1) infinite;
}
@keyframes ksaProgSlide {
  0%   { left: -40%; width: 40%; }
  60%  { left: 60%;  width: 45%; }
  100% { left: 100%; width: 30%; }
}

/* The clicked menu row acknowledges the click straight away */
#sidebar-menu a.ksa-pending {
  background: var(--ksa-primary-050, rgba(68,64,151,.10)) !important;
  position: relative;
}
#sidebar-menu a.ksa-pending::after {
  content: ""; position: absolute; right: 10px; top: 50%;
  width: 12px; height: 12px; margin-top: -6px;
  border: 2px solid var(--ksa-primary-300);
  border-top-color: transparent; border-radius: 50%;
  animation: ksaSpin .6s linear infinite;
}
@keyframes ksaSpin { to { transform: rotate(360deg); } }

@media (prefers-reduced-motion: reduce) {
  body { animation: none; }
  #ksaProgress.ksa-run::before,
  #sidebar-menu a.ksa-pending::after { animation: none; }
}

/* ---------------------------------------------------------------------------
   10. FOOTER
   ------------------------------------------------------------------------- */
footer {
  background: var(--ksa-glass-bg);
  -webkit-backdrop-filter: blur(var(--ksa-glass-blur)); backdrop-filter: blur(var(--ksa-glass-blur));
  border-top: 1px solid var(--ksa-glass-border);
  color: var(--ksa-text-soft); font-size: 12.5px;
  padding: 12px 0; margin-top: 26px; border-radius: 12px 12px 0 0;
}

/* ---------------------------------------------------------------------------
   11. RESPONSIVE — mobile & tablet
   ------------------------------------------------------------------------- */
img { max-width: 100%; height: auto; }

/* Menu button (injected by ksa-theme.js). It now sits INSIDE the navbar rather
   than floating over the page at position:fixed - as a floating button it
   overlapped the navbar content on small screens and read as a stray artifact
   rather than the menu control. */
.ksa-hamburger {
  display: none; align-items: center; justify-content: center;
  width: 40px; height: 40px; flex: 0 0 auto;
  margin: 0 6px 0 4px;
  border-radius: 11px; border: 1px solid var(--ksa-glass-border);
  background: var(--ksa-glass-bg-strong); color: var(--ksa-primary);
  font-size: 17px; line-height: 1; cursor: pointer;
}
.ksa-hamburger:hover { color: var(--ksa-accent); border-color: var(--ksa-accent); }
.ksa-hamburger i { font-family: FontAwesome !important; }
html[data-ksa-theme="dark"] .ksa-hamburger { color: var(--ksa-primary-300); }

@media (max-width: 991px) {
  .ksa-hamburger { display: inline-flex; }

  /* Sidebar becomes off-canvas.
     CRITICAL: target ONLY the outer column. The markup nests a second
     .left_col inside the first:
         <div class="col-md-3 left_col">        <- the actual column
           <div class="left_col scroll-view">   <- inner wrapper, SAME class
     The old selector `.left_col, .col-md-3.left_col` matched BOTH, so the inner
     wrapper was also pushed off-screen with translateX(-105%) - while the
     "open" rule only un-translated the outer one. The result: the burger
     toggled the class correctly and the column did slide in, but its contents
     stayed translated 105% away, so nothing appeared on screen. Using the
     child-safe selector (and explicitly neutralising the inner wrapper) is what
     makes the menu actually show up. */
  /* THE OVERRIDE THAT BROKE THE BURGER — build/css/custom.css line ~1043:
         @media (max-width: 991px) {
           .nav-md .container.body .col-md-3.left_col { display: none; }
         }
     Gentelella simply DELETES the sidebar from the layout on small screens
     (the template assumes a desktop-only admin). <body class="nav-md">, so this
     always applied. No amount of transform/translate could ever reveal it:
     a display:none element is not rendered, so it cannot slide in — which is
     exactly why the burger appeared to do nothing at all.
     Their selector also carries `.nav-md` (3 classes + 2 elements), so a rule
     without it LOSES on specificity even when declared later. Both fixes are
     therefore required: match their specificity, and force display back. */
  body.nav-md .container.body .col-md-3.left_col,
  body.nav-sm .container.body .col-md-3.left_col,
  .container.body .col-md-3.left_col {
    display: flex !important;            /* beats custom.css display:none */
    position: fixed !important; top: 0; left: 0; bottom: 0; z-index: 9998;
    width: 270px !important; max-width: 82vw; min-height: 0;
    overflow-y: auto; overflow-x: auto;  /* horizontal scroll for long names */
    overscroll-behavior: contain;
    -webkit-overflow-scrolling: touch;
    transform: translateX(-105%);
    transition: transform .28s ease;
    background: var(--ksa-bg-page-solid);
  }
  /* the inner wrapper must never carry its own offset */
  body .container.body .col-md-3.left_col .left_col {
    position: static !important;
    transform: none !important;
    width: 100% !important; max-width: 100%;
    background: transparent;
    display: flex !important;
  }
  /* Open state must also out-specify .nav-md */
  body.ksa-sidebar-open.nav-md .container.body .col-md-3.left_col,
  body.ksa-sidebar-open.nav-sm .container.body .col-md-3.left_col,
  body.ksa-sidebar-open .container.body .col-md-3.left_col {
    transform: translateX(0) !important;
  }
  body.ksa-sidebar-open::after {
    content: ""; position: fixed; inset: 0; z-index: 9997;
    background: rgba(0,0,0,.45);
  }

  .right_col { margin-left: 0 !important; padding: 8px !important; }
  .top_nav .nav_menu { height: auto !important; padding-bottom: 8px; }

  /* Tables scroll instead of breaking layout */
  .x_panel { overflow-x: auto; }
  .x_panel table { min-width: 560px; }

  /* Form rows stack */
  .form-group.row > label, .form-group.row > div { width: 100% !important; max-width: 100%; flex: 0 0 100%; }
  .col-form-label { margin-bottom: 2px; }
  .btn { width: 100%; margin-bottom: 8px; }
}

@media (min-width: 992px) and (max-width: 1199px) {
  .right_col { padding: 10px 14px !important; }
}

/* Respect users who prefer less motion */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .01ms !important; transition-duration: .01ms !important; }
}

/* ===========================================================================
   12. PASS 2 — LAYOUT ENGINE (sidebar/content contract)
   Desktop: fixed 270px sidebar column; content offsets by exactly 270px and
   reflows when the sidebar is collapsed (body.nav-sm via navbar hamburger).
   Mobile (<992px): sidebar is off-canvas (body.ksa-sidebar-open).
   ------------------------------------------------------------------------- */
@media (min-width: 992px) {
  .container.body .col-md-3.left_col {
    position: fixed; top: 0; left: 0; bottom: 0;
    width: 270px !important; max-width: 270px; height: 100vh;
    z-index: 1000; padding: 0; float: none;
    background: transparent;
    transform: translateX(0);
    transition: transform .28s ease;
    overflow-y: scroll;
    /* was overflow-x:hidden — that is what suppressed the requested left-right
       scroll on the sidebar, so long menu labels were simply cut off with no
       way to reach them. */
    overflow-x: auto;
    overscroll-behavior: contain;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: thin;
    scrollbar-color: var(--ksa-primary-300) transparent;
  }
  .container.body .col-md-3.left_col::-webkit-scrollbar { width: 8px; }
  .container.body .col-md-3.left_col::-webkit-scrollbar-thumb { background: var(--ksa-primary-300); border-radius: 99px; }
  .container.body .col-md-3.left_col::-webkit-scrollbar-track { background: transparent; }
  .container.body .right_col {
    margin-left: 270px !important; width: auto !important;
    float: none !important; min-height: 100vh;
    padding: 0 22px 22px !important;
  }
  body.nav-sm .container.body .col-md-3.left_col { transform: translateX(-110%); }
  body.nav-sm .container.body .right_col { margin-left: 0 !important; }
}

/* Sidebar internals. Scrolling now happens on .col-md-3.left_col itself
   (overflow-y:auto, set above/below), not nested inside #sidebar-menu - so
   this no longer clips: it just lets its content be as tall as it needs to
   be, and the outer column scrolls the whole thing as one unit. */
.left_col .left_col.scroll-view { display: flex; flex-direction: column; overflow: visible; background: transparent; }
#sidebar-menu.main_menu {
  flex: 1 1 auto; min-height: 0;
  display: flex; flex-direction: column;
  overflow: hidden;
  margin: 10px 8px 12px;
}
#sidebar-menu .menu_section { display: flex; flex-direction: column; flex: 1 1 auto; min-height: 0; }
.ksa-side-header { flex: 0 0 auto; }
#sidebar-menu ul.nav.side-menu {
  flex: 1 1 auto; min-height: 0;
  /* overflow-x must stay visible here: the SCROLLING happens on the column and
     on #sidebar-menu (see §16b). Clipping it here re-truncated long labels even
     after the column was allowed to scroll horizontally. */
  overflow-y: auto; overflow-x: visible;
  padding-right: 2px;
  scrollbar-width: thin;
  scrollbar-color: var(--ksa-primary-300) transparent;
}
#sidebar-menu ul.nav.side-menu::-webkit-scrollbar { width: 6px; }
#sidebar-menu ul.nav.side-menu::-webkit-scrollbar-track { background: transparent; }
#sidebar-menu ul.nav.side-menu::-webkit-scrollbar-thumb { background: var(--ksa-primary-300); border-radius: 99px; }
#sidebar-menu ul.nav.side-menu::-webkit-scrollbar-thumb:hover { background: var(--ksa-accent); }

/* The four legacy sidebar-footer buttons (settings/fullscreen/lock/power): removed */
.sidebar-footer { display: none !important; }

/* Gentelella profile block leftover */
.profile.clearfix { display: none; }

/* ===========================================================================
   13. PASS 2 — MODERN NAVBAR (hamburger left, logo center, user chip right)
   ------------------------------------------------------------------------- */
.top_nav { position: relative; z-index: 900; }
.top_nav .nav_menu.ksa-navbar {
  display: flex; align-items: center; justify-content: space-between;
  min-height: 64px; height: auto !important; padding: 8px 18px;
  border-radius: 0 0 14px 14px;
}
.ksa-nav-burger {
  flex: 0 0 auto; width: 42px; height: 42px; border-radius: 12px;
  display: flex; align-items: center; justify-content: center;
  color: var(--ksa-primary); font-size: 18px; cursor: pointer;
  border: 1px solid var(--ksa-glass-border); background: transparent;
  transition: background .2s ease;
}
.ksa-nav-burger:hover { background: var(--ksa-primary-100); }
html[data-ksa-theme="dark"] .ksa-nav-burger { color: var(--ksa-primary-300); }
html[data-ksa-theme="dark"] .ksa-nav-burger:hover { background: rgba(111,107,192,.2); }

/* .ksa-side-header (title block) now lives at the far left of the navbar
   instead of above the sidebar (see top_navigation.ascx / top_navigationLogin.ascx).
   Doubled-up class selector so this reliably beats the later .ksa-side-header
   re-definitions (§5, §16) that still assume a dark sidebar background. */
.ksa-navbar .ksa-navbar-brand-slot.ksa-navbar-brand-slot {
  flex: 0 0 auto;
  width: var(--ksa-side-w);
  margin: 0; padding: 0 16px 0 4px;
  background: none; border: none; border-radius: 0;
  text-align: left;
  box-sizing: border-box;
}
/* Legacy navbar (top_navigationLogin.ascx) has no flexbox row, so float instead. */
.top_nav .nav_menu:not(.ksa-navbar) .ksa-navbar-brand-slot-legacy {
  float: left;
  width: var(--ksa-side-w);
  padding: 0 12px;
  box-sizing: border-box;
  text-align: left;
  background: none; border: none;
}
/* Both slots: .ksa-side-title/.ksa-side-subtitle were authored white/pink
   (!important) for the dark sidebar background - against the navbar's light
   glass background that's invisible, so override with the brand color here. */
.ksa-navbar-brand-slot .ksa-side-title,
.ksa-navbar-brand-slot-legacy .ksa-side-title {
  font-size: 13px; line-height: 1.25;
  color: var(--ksa-primary) !important;
}
.ksa-navbar-brand-slot .ksa-side-subtitle,
.ksa-navbar-brand-slot-legacy .ksa-side-subtitle {
  font-size: 9.5px;
  color: var(--ksa-primary) !important;
}
html[data-ksa-theme="dark"] .ksa-navbar-brand-slot .ksa-side-title,
html[data-ksa-theme="dark"] .ksa-navbar-brand-slot-legacy .ksa-side-title,
html[data-ksa-theme="dark"] .ksa-navbar-brand-slot .ksa-side-subtitle,
html[data-ksa-theme="dark"] .ksa-navbar-brand-slot-legacy .ksa-side-subtitle {
  color: var(--ksa-primary-300) !important;
}
/* Below the off-canvas sidebar breakpoint, width:var(--ksa-side-w) (270px+)
   would badly crowd/overflow a phone-width navbar for no benefit - the
   "match the sidebar column" purpose only applies when that column is
   actually visible alongside content. The centered KSA logo already
   provides branding here, so just hide it rather than trying to shrink it. */
@media (max-width: 991px) {
  .ksa-navbar-brand-slot, .ksa-navbar-brand-slot-legacy { display: none !important; }
}

.ksa-nav-brand {
  position: absolute; left: 50%; transform: translateX(-50%);
  display: flex; align-items: center; gap: 12px; text-align: center;
}
.ksa-nav-brand img { height: 46px; width: auto; }
.ksa-nav-brand .ksa-agency-name { font-size: 16px; line-height: 1.2; }
.ksa-nav-brand .ksa-agency-tagline { font-size: 11px; }
@media (max-width: 767px) { .ksa-nav-brand .ksa-brand-text { display: none; } }

/* User chip + dropdown */
.ksa-user-wrap { position: relative; flex: 0 0 auto; margin-left: auto; }
.ksa-user-chip {
  display: flex; align-items: center; gap: 10px;
  padding: 6px 14px 6px 8px; border-radius: 999px; cursor: pointer;
  border: 1px solid var(--ksa-glass-border);
  background: var(--ksa-glass-bg);
  transition: box-shadow .2s ease, background .2s ease;
  max-width: 260px;
}
.ksa-user-chip:hover { box-shadow: 0 4px 14px rgba(68,64,151,.25); }
.ksa-avatar {
  width: 34px; height: 34px; border-radius: 50%; flex: 0 0 auto;
  display: flex; align-items: center; justify-content: center;
  background: linear-gradient(135deg, var(--ksa-primary), var(--ksa-primary-600));
  color: #fff; font-size: 15px;
}
.ksa-user-name {
  font-weight: 600; font-size: 13px; color: var(--ksa-text);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.ksa-user-chip .fa-chevron-down { font-size: 10px; color: var(--ksa-text-soft); transition: transform .25s ease; }
.ksa-user-wrap.open .ksa-user-chip .fa-chevron-down { transform: rotate(180deg); }

/* Phone: avatar only, no username text/chevron - same breakpoint the navbar
   brand text already hides at. The name had no width cap of its own (only
   the whole chip did, at up to 260px), so on a narrow phone it was
   crowding/pushing on everything else in the navbar instead of just
   showing the compact icon a mobile chip is supposed to be. */
@media (max-width: 767px) {
  .ksa-user-name, .ksa-user-chip .fa-chevron-down { display: none; }
  .ksa-user-chip { padding: 4px; gap: 0; max-width: none; }
}

.ksa-user-menu {
  position: absolute; right: 0; top: calc(100% + 10px); min-width: 220px;
  background: var(--ksa-glass-bg-strong);
  -webkit-backdrop-filter: blur(16px); backdrop-filter: blur(16px);
  border: 1px solid var(--ksa-glass-border); border-radius: 14px;
  box-shadow: var(--ksa-glass-shadow); padding: 8px; z-index: 1200;
  opacity: 0; visibility: hidden; transform: translateY(-8px);
  transition: opacity .2s ease, transform .2s ease, visibility .2s;
}
.ksa-user-wrap.open .ksa-user-menu { opacity: 1; visibility: visible; transform: translateY(0); }
.ksa-user-menu a, .ksa-user-menu button {
  display: flex; align-items: center; gap: 10px; width: 100%;
  padding: 10px 12px; border-radius: 10px; border: none; background: none;
  font-family: var(--ksa-font); font-size: 13px; font-weight: 500;
  color: var(--ksa-text) !important; cursor: pointer; text-align: left;
  transition: background .15s ease;
}
.ksa-user-menu a:hover, .ksa-user-menu button:hover { background: var(--ksa-primary-100); color: var(--ksa-primary) !important; }
html[data-ksa-theme="dark"] .ksa-user-menu a:hover,
html[data-ksa-theme="dark"] .ksa-user-menu button:hover { background: rgba(111,107,192,.22); }
.ksa-user-menu .fa { width: 16px; text-align: center; color: var(--ksa-primary); }
html[data-ksa-theme="dark"] .ksa-user-menu .fa { color: var(--ksa-primary-300); }
.ksa-user-menu .ksa-menu-danger, .ksa-user-menu .ksa-menu-danger .fa { color: var(--ksa-accent) !important; }
.ksa-user-menu .ksa-menu-danger:hover { background: var(--ksa-accent-100); }
.ksa-user-menu hr { border: none; border-top: 1px solid var(--ksa-glass-border); margin: 6px 4px; }

/* ===========================================================================
   14. PASS 2 — THEME COVERAGE (legacy backgrounds must follow dark/light)
   ------------------------------------------------------------------------- */
.container.body, .main_container, .right_col, .x_content, .form-horizontal {
  background: transparent !important;
  color: var(--ksa-text);
}
td[bgcolor], tr[bgcolor], th[bgcolor], table[bgcolor] { background-color: transparent !important; }
.x_panel table td { background: transparent !important; color: var(--ksa-text) !important; }
.x_panel table th { color: var(--ksa-text) !important; }
.x_panel table tr:nth-child(even) td { background: var(--ksa-table-stripe) !important; }
.x_panel table tr:hover td { background: var(--ksa-primary-100) !important; }
html[data-ksa-theme="dark"] .x_panel table tr:hover td { background: rgba(111,107,192,.15) !important; }

html[data-ksa-theme="dark"] .right_col h1, html[data-ksa-theme="dark"] .right_col h2,
html[data-ksa-theme="dark"] .right_col h3, html[data-ksa-theme="dark"] .right_col h4,
html[data-ksa-theme="dark"] .right_col h5, html[data-ksa-theme="dark"] .right_col p,
html[data-ksa-theme="dark"] .right_col li, html[data-ksa-theme="dark"] .right_col td,
html[data-ksa-theme="dark"] .right_col label, html[data-ksa-theme="dark"] .right_col legend,
html[data-ksa-theme="dark"] .right_col [class*="auto-style"] {
  color: var(--ksa-text) !important;
}
html[data-ksa-theme="dark"] .right_col .btn,
html[data-ksa-theme="dark"] .right_col .btn * { color: #fff !important; }

/* ===========================================================================
   15. PASS 2 — FORM RHYTHM + MODERN DATE INPUTS
   ------------------------------------------------------------------------- */
.right_col .form-group.row { margin: 0 0 14px 0; padding: 2px 0; display: flex; flex-wrap: wrap; align-items: center; }
.right_col .form-group.row > label, .right_col .form-group.row > .col-form-label { padding-right: 14px; margin-bottom: 0; }
.right_col fieldset, .ksa-form-section {
  border: 1px solid var(--ksa-glass-border); border-radius: 12px;
  padding: 16px 18px; margin-bottom: 18px;
  background: var(--ksa-glass-bg);
}
.right_col .btn + .btn { margin-left: 10px; }
@media (max-width: 991px) { .right_col .btn + .btn { margin-left: 0; } }

input.ksa-date, input[type="date"] {
  font-family: var(--ksa-font) !important;
  min-height: 38px; max-width: 220px;
  color-scheme: light;
}
html[data-ksa-theme="dark"] input.ksa-date, html[data-ksa-theme="dark"] input[type="date"] { color-scheme: dark; }
input[type="date"]::-webkit-calendar-picker-indicator { cursor: pointer; opacity: .7; }
input[type="date"]::-webkit-calendar-picker-indicator:hover { opacity: 1; }

/* Conditional sections (JS-driven): hidden rows collapse */
.ksa-cond-hidden { display: none !important; }

/* ===========================================================================
   16. PASS 2.1 — SIDEBAR SCROLL REWORK (overrides parts of §5/§12)
   Structure: .scroll-view is a 100vh flex column → pinned .ksa-side-header on
   top, #sidebar-menu below is ONE simple scrollbox (vertical + horizontal).
   ------------------------------------------------------------------------- */
.left_col .left_col.scroll-view {
  display: flex !important; flex-direction: column;
  min-height: 100vh; overflow: visible; background: transparent;
  /* The COLUMN (.col-md-3.left_col) is display:flex via Gentelella custom.css,
     which makes this wrapper a FLEX ITEM. Its default min-width:auto means
     "never shrink below my content's min-content width", so the menu refused
     to narrow with the column when the sidebar was resized smaller. */
  min-width: 0; width: 100%;
}
@media (max-width: 991px) { .left_col .left_col.scroll-view { min-height: 100%; } }

/* Pinned header (now a sibling of #sidebar-menu, not inside it) */
.ksa-side-header {
  flex: 0 0 auto;
  margin: 10px 8px 0;
  padding: 12px 8px 14px;
  background: var(--ksa-side-bg);
  border: 1px solid var(--ksa-glass-border); border-bottom: none;
  border-radius: 14px 14px 0 0;
  text-align: center;
}

/* The menu itself: single scroll container, both axes */
#sidebar-menu.main_menu {
  display: block !important;
  flex: 1 1 auto; min-height: 0;
  overflow-y: auto !important; overflow-x: auto !important;
  margin: 0 8px 14px !important;
  border-radius: 0 0 14px 14px !important;
  border-top: none !important;
  padding: 8px 6px 16px;
  scrollbar-width: thin;
  scrollbar-color: var(--ksa-primary-300) transparent;
}
#sidebar-menu.main_menu::-webkit-scrollbar { width: 6px; height: 6px; }
#sidebar-menu.main_menu::-webkit-scrollbar-track { background: transparent; }
#sidebar-menu.main_menu::-webkit-scrollbar-thumb { background: var(--ksa-primary-300); border-radius: 99px; }
#sidebar-menu.main_menu::-webkit-scrollbar-thumb:hover { background: var(--ksa-accent); }

/* Undo the earlier nested-flex attempt (§12) — plain block flow inside */
#sidebar-menu .menu_section { display: block !important; }
#sidebar-menu ul.nav.side-menu {
  display: block !important; overflow: visible !important;
  flex: none !important;
  /* Was min-width:max-content ("long labels extend → horizontal scroll").
     That pinned the whole menu to the widest label (~565px) regardless of the
     column width, so dragging #ksaSideResizer visibly moved ONLY the content
     pane while the menu stayed put and the handle rode over it. The menu must
     track the column for the resize to feel connected; long labels wrap. */
  min-width: 0;
  padding-right: 8px;
}

/* Menu text wraps to the column width (see min-width note above) */
#sidebar-menu .nav.side-menu a,
#sidebar-menu .nav.child_menu a { white-space: normal; overflow-wrap: break-word; }

/* ------- Kill Gentelella teal/cyan indicators; brand red only ------------ */
.nav.side-menu > li.current-page,
.nav.side-menu > li.active,
#sidebar-menu .nav.side-menu > li.current-page,
#sidebar-menu .nav.side-menu > li.active {
  border-right: none !important; border-left: none !important;
  background: transparent;
}
#sidebar-menu .nav.side-menu > li.active > a {
  box-shadow: inset 3px 0 0 var(--ksa-accent);
}
/* Gentelella child-menu tree bullets/lines (slate blue) → red bullets, soft lines */
#sidebar-menu li::before { background: var(--ksa-accent) !important; }
#sidebar-menu li::after { border-left: 1px solid rgba(255,255,255,.18) !important; }
#sidebar-menu .nav.child_menu li { border-left-color: rgba(255,255,255,.14); }
#sidebar-menu .nav.child_menu li:hover,
#sidebar-menu .nav.child_menu li.current-page { border-left-color: var(--ksa-accent) !important; }

/* ------- Icon badges, matching .ksa-card's .ic (was plain grayscale icons) --
   Excludes the expand/collapse chevron, which stays a small plain arrow. ---- */
#sidebar-menu a .fa:not(.fa-chevron-down) {
  width: 28px; height: 28px; min-width: 28px;
  border-radius: 9px;
  display: inline-flex; align-items: center; justify-content: center;
  background: linear-gradient(135deg, var(--ksa-primary), var(--ksa-primary-600));
  color: #ffffff !important;
  opacity: 1; filter: none;
  margin-right: 10px;
  font-size: 13px;
  text-align: center;
}
#sidebar-menu a.ksa-active .fa:not(.fa-chevron-down),
#sidebar-menu .nav.side-menu > li.current-page > a .fa:not(.fa-chevron-down),
#sidebar-menu .nav.child_menu > li.current-page > a .fa:not(.fa-chevron-down) {
  background: #ffffff;
  color: var(--ksa-accent) !important;
}

/* ------- Hamburger removed ------------------------------------------------ */
.ksa-nav-burger, .nav.toggle, #menu_toggle { display: none !important; }
/* (mobile keeps the floating opener injected by ksa-theme.js below 992px) */

/* ===========================================================================
   17. PASS 2.2 — BRAND REFINEMENTS
   Sidebar title on two lines; navbar shows KSA logo + Republic of Kenya coat
   of arms (1.5x previous size) instead of text.
   ------------------------------------------------------------------------- */
.ksa-side-title { line-height: 1.4; }
.ksa-side-subtitle {
  display: block;
  font-size: 12px; font-weight: 600; letter-spacing: 1.2px;
  color: #ffd7d7 !important; text-transform: uppercase;
  margin-top: 2px;
}

.ksa-nav-brand { gap: 16px; }
.ksa-nav-brand img { height: 70px; width: auto; }
.ksa-nav-brand img.ksa-coat { height: 64px; }
@media (max-width: 767px) {
  .ksa-nav-brand img { height: 48px; }
  .ksa-nav-brand img.ksa-coat { height: 44px; }
}

/* ===========================================================================
   18. PASS 2.3 — APP SHELL
   The page itself NEVER scrolls (body.ksa-shell is added by ksa-theme.js on
   pages that have the sidebar+content skeleton). The content region between
   the sticky navbar and the pinned footer is the ONE scroll area; tables get
   their own inner scrollers (§19). Sidebar width is user-resizable via the
   drag handle (--ksa-side-w, persisted in localStorage).
   ------------------------------------------------------------------------- */
:root { --ksa-side-w: 270px; }

body.ksa-shell { overflow: hidden; height: 100vh; }

/* NOTE: the sidebar width and the content offset are handled by the GRID SHELL
   (section 18b: grid-template-columns: var(--ksa-side-w) 1fr). The old
   `margin-left: var(--ksa-side-w)` here was applied ON TOP of the grid column,
   shifting the whole content area left by an extra sidebar width. Removed. */

body.ksa-shell .container.body .right_col {
  height: 100vh;
  overflow-y: auto;
  overflow-x: auto;              /* squeezed content scrolls left-right */
  -webkit-overflow-scrolling: touch;
  padding: 0 22px 86px !important;   /* room for the pinned footer */
  scrollbar-width: thin;
  scrollbar-color: var(--ksa-primary-300) transparent;
}
body.ksa-shell .container.body .right_col::-webkit-scrollbar { width: 8px; height: 8px; }
body.ksa-shell .container.body .right_col::-webkit-scrollbar-thumb { background: var(--ksa-primary-300); border-radius: 99px; }
body.ksa-shell .container.body .right_col::-webkit-scrollbar-track { background: transparent; }

/* Navbar: always visible at the top of the content region */
body.ksa-shell .top_nav {
  position: sticky; top: 0; z-index: 950;
  margin: 0 -22px 16px;
}
body.ksa-shell .top_nav .nav_menu.ksa-navbar { border-radius: 0; }

/* ===========================================================================
   18b. PASS 2.4 — GRID SHELL: NAVBAR ABOVE SIDEBAR+CONTENT
   §18 above put the sidebar (position:fixed, top:0) and the navbar (sticky
   *inside* .right_col, so only spanning its width) side by side at the same
   y=0 - the navbar never actually sat above the sidebar. This turns
   .main_container into a 2-row grid: the navbar spans full width on row 1,
   sidebar + content share row 2 underneath it.
   ------------------------------------------------------------------------- */
@media (min-width: 992px) {
  body.ksa-shell .container.body .main_container {
    display: grid;
    /* tracks --ksa-side-w so the drag handle (#ksaSideResizer) actually resizes
       the sidebar: the column width is the variable the handle updates. */
    grid-template-columns: var(--ksa-side-w) minmax(0, 1fr);
    grid-template-rows: auto 1fr;
    grid-template-areas: "nav nav" "side content";
    height: 100vh;
  }
  body.ksa-shell .container.body .top_nav {
    grid-area: nav;
    margin: 0;
  }
  body.ksa-shell .container.body .col-md-3.left_col {
    grid-area: side;
    position: relative !important; top: auto; left: auto; bottom: auto;
    width: 100% !important; max-width: none; height: 100%;
    z-index: auto;
  }
  body.ksa-shell .container.body .right_col {
    grid-area: content;
    margin-left: 0 !important; width: auto !important; height: 100%;
  }
}

/* Footer: pinned to the bottom, content never slides under it unreadably */
body.ksa-shell footer {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 940;
  margin: 0 !important; border-radius: 0;
  background: var(--ksa-glass-bg-strong);
  padding: 10px 0;
}
@media (max-width: 991px) {
  body.ksa-shell footer { left: 0; }
}

/* Sidebar resize handle (injected by ksa-theme.js, desktop only)
   ---------------------------------------------------------------------------
   It must NOT live inside the sidebar column: that column is a scrollbox
   (overflow-y:auto / overflow-x:hidden, §12), and the handle used to be pushed
   out to margin-left:100% - i.e. horizontally outside the content box, exactly
   where overflow-x:hidden clips it. The handle was therefore present in the
   DOM but invisible and impossible to grab, which is why resizing "stopped
   working". Fixed by taking it out of flow entirely: position:fixed against
   the viewport, sitting on the seam at x = --ksa-side-w. Nothing clips a
   fixed-position element, and it no longer scrolls with the menu either. */
#ksaSideResizer {
  position: fixed; top: 0; bottom: 0;
  left: calc(var(--ksa-side-w) - 5px);
  width: 11px; height: 100vh;
  cursor: col-resize; z-index: 1002;
  /* At rest the seam line is INVISIBLE (owner preference) - the mid-height
     grip pill (::after below) is the only resting affordance. The full seam
     line still appears on hover/drag/keyboard focus as feedback. */
  background: transparent;
  transition: background .15s ease;
}
/* Collapsed sidebar (navbar toggle) has no seam to drag */
body.nav-sm #ksaSideResizer { display: none; }
/* Mobile: the sidebar is off-canvas, so there is no seam either */
@media (max-width: 991px) { #ksaSideResizer { display: none; } }
#ksaSideResizer:hover, body.ksa-resizing #ksaSideResizer {
  background: linear-gradient(to right,
              transparent 0, transparent 3px,
              var(--ksa-accent) 3px, var(--ksa-accent) 7px,
              transparent 7px, transparent 100%);
}
#ksaSideResizer:focus-visible {
  outline: none;
  background: linear-gradient(to right,
              transparent 0, transparent 3px,
              var(--ksa-accent) 3px, var(--ksa-accent) 7px,
              transparent 7px, transparent 100%);
}
/* Always-visible grip dots at mid-height: the affordance that tells the user
   this edge can be dragged. */
#ksaSideResizer::after {
  content: ""; position: absolute; top: 50%; left: 50%;
  transform: translate(-50%, -50%);
  width: 5px; height: 42px; border-radius: 99px;
  background: var(--ksa-primary-300); opacity: .6;
  box-shadow: 0 0 0 1px var(--ksa-glass-bg-strong);
  transition: opacity .15s ease, background .15s ease;
}
#ksaSideResizer:hover::after, body.ksa-resizing #ksaSideResizer::after {
  background: var(--ksa-accent); opacity: 1;
}
body.ksa-resizing { user-select: none; cursor: col-resize; }
body.ksa-resizing .right_col { pointer-events: none; }

/* Page titles follow the KSA brand */
.right_col h1, .right_col h2, .right_col h3, .right_col h4,
.right_col .x_title h2, .right_col [class*="auto-style"] h3 {
  color: var(--ksa-primary) !important;
}
html[data-ksa-theme="dark"] .right_col h1, html[data-ksa-theme="dark"] .right_col h2,
html[data-ksa-theme="dark"] .right_col h3, html[data-ksa-theme="dark"] .right_col h4 {
  color: var(--ksa-primary-300) !important;
}

/* ===========================================================================
   19. PASS 2.3 — EXCEL-GRID TABLES
   Every DataGrid/GridView is wrapped by ksa-theme.js in .ksa-table-scroll:
   its own scroll area (both axes), spreadsheet-style cell grid, sticky
   brand-colored header row.
   ------------------------------------------------------------------------- */
:root {
  --ksa-grid-line: rgba(68, 64, 151, 0.18);
  --ksa-cell-bg:   rgba(255, 255, 255, 0.66);
}
html[data-ksa-theme="dark"] {
  --ksa-grid-line: rgba(151, 148, 219, 0.22);
  --ksa-cell-bg:   rgba(24, 23, 52, 0.55);
}

.ksa-table-scroll {
  max-height: 58vh;
  overflow: auto;
  border: 1px solid var(--ksa-glass-border);
  border-radius: 12px;
  background: var(--ksa-glass-bg);
  margin: 6px 0 18px;
  scrollbar-width: thin;
  scrollbar-color: var(--ksa-primary-300) transparent;
}
.ksa-table-scroll::-webkit-scrollbar { width: 8px; height: 8px; }
.ksa-table-scroll::-webkit-scrollbar-thumb { background: var(--ksa-primary-300); border-radius: 99px; }
.ksa-table-scroll::-webkit-scrollbar-thumb:hover { background: var(--ksa-accent); }
.ksa-table-scroll::-webkit-scrollbar-track { background: transparent; }
.ksa-table-scroll::-webkit-scrollbar-corner { background: transparent; }

.ksa-table-scroll table {
  border-collapse: separate !important; border-spacing: 0 !important;
  min-width: 100%; width: auto !important; margin: 0 !important;
  background: transparent !important; border: none !important;
}

/* The spreadsheet cells. Wraps instead of forcing nowrap - a handful of long
   labels used to force the whole table (and its horizontal scrollbar) far
   wider than the data actually needed. A capped max-width keeps any single
   very long cell from stretching its column indefinitely. */
.ksa-table-scroll table td, .ksa-table-scroll table th {
  border: none !important;
  border-right: 1px solid var(--ksa-grid-line) !important;
  border-bottom: 1px solid var(--ksa-grid-line) !important;
  background: var(--ksa-cell-bg) !important;
  color: var(--ksa-text) !important;
  padding: 8px 14px !important;
  font-size: 13px !important;
  white-space: normal;
  word-break: break-word;
  max-width: 260px;
  vertical-align: middle;
}
/* Short/fixed-format columns (dates, ##, status) read better on one line -
   opt back into nowrap for these specifically instead of the whole table. */
.ksa-table-scroll table td:first-child,
.ksa-table-scroll table th:first-child {
  white-space: nowrap; max-width: none;
}
.ksa-table-scroll table tr td:first-child, .ksa-table-scroll table tr th:first-child { border-left: none !important; }

/* Neutralize the generic striping inside Excel-grid tables (uniform cells) */
.x_panel .ksa-table-scroll table tr:nth-child(even) td,
.ksa-table-scroll table tr:nth-child(even) td { background: var(--ksa-cell-bg) !important; }

/* Sticky brand header row */
.ksa-table-scroll table thead td, .ksa-table-scroll table thead th {
  position: sticky; top: 0; z-index: 3;
  background: var(--ksa-primary) !important;
  color: #ffffff !important;
  font-weight: 600 !important; font-size: 12.5px !important;
  text-transform: none; letter-spacing: .4px;
  border-right: 1px solid rgba(255,255,255,.25) !important;
  border-bottom: 2px solid var(--ksa-accent) !important;
}
.ksa-table-scroll table thead a { color: #ffffff !important; text-decoration: underline; }

/* Row hover = Excel row highlight */
.x_panel .ksa-table-scroll table tbody tr:hover td,
.ksa-table-scroll table tbody tr:hover td { background: var(--ksa-primary-100) !important; }
html[data-ksa-theme="dark"] .ksa-table-scroll table tbody tr:hover td,
html[data-ksa-theme="dark"] .x_panel .ksa-table-scroll table tbody tr:hover td { background: rgba(111,107,192,.20) !important; }

/* Links & action buttons inside cells */
.ksa-table-scroll table td a { color: var(--ksa-primary); font-weight: 600; }
.ksa-table-scroll table td a:hover { color: var(--ksa-accent); }
html[data-ksa-theme="dark"] .ksa-table-scroll table td a { color: var(--ksa-primary-300); }

/* Mobile: tighter cells and a shorter cap so a table doesn't eat the whole
   screen, and a slimmer scrollbar area since touch scrolling doesn't need
   a visible drag handle the way a mouse does. */
@media (max-width: 767px) {
  .ksa-table-scroll { max-height: 46vh; }
  .ksa-table-scroll table td, .ksa-table-scroll table th {
    padding: 6px 10px !important;
    font-size: 12px !important;
    max-width: 160px;
  }
}

/* ===========================================================================
   20. PASS 2.4 — SIDEBAR ENDS AT FOOTER TOP + ALWAYS-VISIBLE MENU SCROLLBAR
   ------------------------------------------------------------------------- */
:root { --ksa-footer-h: 48px; }

@media (min-width: 992px) {
  body.ksa-shell .container.body .col-md-3.left_col {
    /* Grid cell (§18b) already starts below the navbar, so this is relative
       to that cell's height, not the full viewport. Small gap so it stops
       just short of the footer instead of touching it. */
    height: calc(100% - var(--ksa-footer-h) - 8px) !important;
    bottom: auto;
  }
}
.left_col .left_col.scroll-view { min-height: 100% !important; }

/* Footer spans the full width beneath sidebar AND content, fixed height */
body.ksa-shell footer {
  left: 0 !important;
  height: var(--ksa-footer-h);
  display: flex; align-items: center; justify-content: center;
  padding: 0 !important;
}

/* (scrolling moved to .col-md-3.left_col itself - see §21b below) */

/* User chip: make sure avatar + chevron icons render and align */
.ksa-user-chip .fa, .ksa-user-menu .fa { font-size: 14px; }

/* ===========================================================================
   21. PASS 2.6 — SIDEBAR STRETCHES TO THE FOOTER (was: hard-capped at 78%
   of the viewport - superseded, that cap and the menu box's height below it
   both assumed the old ~170px sidebar header, which has since moved into the
   navbar (§16b/user_menu.ascx). With it gone, that 170px subtraction just
   made the menu box artificially short. §20 already sizes the sidebar column
   to stretch to just above the footer; the menu box now fills whatever's
   left of that via flex (§16's "sidebar scroll rework"), no hardcoded
   height needed, so it can't come up short/"collapsed" on a fresh load. */
.left_col .left_col.scroll-view {
  min-height: 100% !important; max-height: none !important;
}
#sidebar-menu.main_menu {
  /* Scrolling moved to .col-md-3.left_col itself (the outer column) instead
     of nested here - this just grows to fit its content now. */
  flex: 1 1 auto !important;
  min-height: 0 !important;
  max-height: none !important;
  height: auto !important;
  overflow: visible !important;
}

/* ---- Faded logo watermark on every page ---------------------------------- */
body { background: transparent !important; }
html {
  background: var(--ksa-bg-page) fixed !important;
}
body::after {
  content: "";
  position: fixed; inset: 0; z-index: -1;
  background: url("../../images/KSA-Logo-New2.png?v=20260804090000") no-repeat center center;
  background-size: min(46vw, 520px) auto;
  opacity: 0.06;
  pointer-events: none;
}
html[data-ksa-theme="dark"] body::after { opacity: 0.08; }

/* ===========================================================================
   22. PASS 2.5 — SHARED QUICK-LINK CARDS + DASHBOARD HERO
   (same card language as the landing page, now reusable on any page)
   ------------------------------------------------------------------------- */
.ksa-card {
  display: flex; align-items: center; gap: 14px;
  padding: 16px 18px; text-decoration: none !important;
  transition: transform .2s ease, box-shadow .2s ease;
}
.ksa-card:hover { transform: translateY(-4px); box-shadow: 0 14px 34px rgba(68,64,151,.22); }
.ksa-card .ic {
  width: 44px; height: 44px; border-radius: 13px; flex: 0 0 auto;
  display: flex; align-items: center; justify-content: center; font-size: 18px;
  background: linear-gradient(135deg, var(--ksa-primary), var(--ksa-primary-600)); color: #fff;
}
.ksa-card.accent .ic { background: linear-gradient(135deg, var(--ksa-accent), var(--ksa-accent-600)); }
.ksa-card b { display: block; font-size: 14px; color: var(--ksa-text); }
.ksa-card span { font-size: 12px; color: var(--ksa-text-soft); }

.ksa-dash-hero {
  display: flex; align-items: center; gap: 22px;
  padding: 26px 28px; margin-bottom: 20px;
}
.ksa-dash-hero .ksa-dash-photo {
  flex: 0 0 auto; width: 110px; height: 110px; border-radius: 18px;
  border: 2px dashed var(--ksa-primary-300);
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  color: var(--ksa-text-soft); font-size: 11px; gap: 6px; text-align: center;
  background: var(--ksa-glass-bg);
}
.ksa-dash-hero .ksa-dash-photo .fa { font-size: 26px; color: var(--ksa-primary-300); }
.ksa-dash-hero h2 { margin: 0 0 6px; font-size: 22px; font-weight: 700; }
.ksa-dash-hero p { margin: 0; color: var(--ksa-text-soft); font-size: 13.5px; max-width: 640px; }
.ksa-dash-hero .ksa-dash-kicker {
  display: inline-block; font-size: 11px; font-weight: 700; letter-spacing: 1.4px;
  text-transform: uppercase; color: var(--ksa-accent); margin-bottom: 4px;
}
.ksa-dash-cards {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 14px; margin-bottom: 22px;
  /* Report pages nest this inside a WebForms <form>/x_content stack whose
     width is otherwise auto/shrink-to-fit - without a definite width here,
     auto-fit can't compute how many 220px tracks fit and collapses to a
     single narrow column pinned wherever the shrink-wrapped box lands. */
  width: 100%; box-sizing: border-box; float: none; justify-items: stretch;
}
.ksa-dash-cards > .ksa-card { min-width: 0; }
@media (max-width: 767px) {
  .ksa-dash-hero { flex-direction: column; text-align: center; }
}

/* .ksa-dash-cards, relocated into the sidebar menu (#sidebar-menu) by the
   inline script at the bottom of DefaultNav.aspx - compact single-column
   cards sized to fit the sidebar's width instead of the wide dashboard grid
   above, with its own scroll so it doesn't fight the sidebar's height cap. */
#sidebar-menu .ksa-dash-cards {
  display: flex; flex-direction: column; gap: 4px;
  margin: 2px 4px 6px; padding-bottom: 6px;
  border-bottom: 1px solid rgba(255,255,255,.14);
}
#sidebar-menu .ksa-dash-cards .ksa-card {
  padding: 6px 10px; gap: 10px;
}
#sidebar-menu .ksa-dash-cards .ksa-card .ic {
  width: 30px; height: 30px; font-size: 13px; border-radius: 9px;
}
#sidebar-menu .ksa-dash-cards .ksa-card b { font-size: 12px; }
#sidebar-menu .ksa-dash-cards .ksa-card span span { font-size: 10.5px; }

/* ===========================================================================
   23. PASS 2.6 — STACKING ORDER: sidebar always above the navbar
   ------------------------------------------------------------------------- */
.container.body .col-md-3.left_col,
body.ksa-shell .container.body .col-md-3.left_col {
  z-index: 2000 !important;
}
body.ksa-shell .top_nav, .top_nav { z-index: 950 !important; }
/* user dropdown stays above the navbar but below nothing it overlaps */
.ksa-user-menu { z-index: 1900; }

/* ===========================================================================
   24. PASS 2.7 — NAVBAR-ON-TOP LAYOUT (navbar full width above the sidebar;
   sidebar starts below the navbar). Overrides earlier §12/§13/§18/§23.
   Navbar sections: name LEFT, logos CENTER, user dropdown RIGHT.
   --ksa-nav-h is the fixed navbar height the sidebar & content offset by.
   ------------------------------------------------------------------------- */
/* Navbar grew from 76px to 112px so the 1.5x logos (90px) fit with breathing room. */
:root { --ksa-nav-h: 112px; }

/* --- Navbar: the GRID SHELL (section 18b) places this in row 1 spanning the full
   width, so it must NOT be position:fixed here — that removed it from the grid
   and let the sidebar/content slide underneath it. Desktop = grid-placed;
   below 992px (no grid) it falls back to fixed so it stays visible. --- */
.top_nav {
  position: relative;
  height: var(--ksa-nav-h); z-index: 950;
}
@media (max-width: 991px) {
  .top_nav { position: fixed; top: 0; left: 0; right: 0; z-index: 3000; }
}
.top_nav .nav_menu.ksa-navbar {
  height: var(--ksa-nav-h) !important; min-height: var(--ksa-nav-h);
  display: flex; align-items: center; justify-content: space-between;
  gap: 16px; padding: 0 22px; border-radius: 0;
}

/* Name on the left */
.ksa-nav-name { flex: 0 0 auto; display: flex; flex-direction: column; line-height: 1.2; }
.ksa-nav-name-main { font-size: 17px; font-weight: 700; color: var(--ksa-primary); }
html[data-ksa-theme="dark"] .ksa-nav-name-main { color: var(--ksa-primary-300); }
.ksa-nav-name-sub {
  font-size: 11px; font-weight: 600; letter-spacing: 1.2px; text-transform: uppercase;
  color: var(--ksa-accent);
}

/* Logos centered (absolute so they stay dead-center regardless of side widths) */
.ksa-nav-brand {
  position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);
  display: flex; align-items: center; gap: 18px; margin: 0;
}
/* 1.5x the previous 60/56px (owner request). This block is last in the cascade,
   so these are the heights that actually render — the earlier 46px and 70px
   rules are overridden. */
.ksa-nav-brand img { height: 90px; width: auto; }
.ksa-nav-brand img.ksa-coat { height: 84px; }

/* User chip pinned right */
.ksa-user-wrap { flex: 0 0 auto; margin-left: auto; }

@media (max-width: 767px) {
  :root { --ksa-nav-h: 92px; }
  .ksa-nav-name-sub { display: none; }
  .ksa-nav-brand img { height: 63px; }
  .ksa-nav-brand img.ksa-coat { height: 60px; }
  .ksa-user-name { display: none; }
}

/* --- Sidebar: starts BELOW the navbar --- */
/* Desktop: the grid shell (18b) sizes and places the sidebar cell; overriding
   top/height here fought it. Only the stacking order is set. */
@media (min-width: 992px) {
  body.ksa-shell .container.body .col-md-3.left_col,
  .container.body .col-md-3.left_col {
    z-index: 5;
  }
}

/* Sidebar menu box fills the capped column and scrolls internally */
#sidebar-menu.main_menu {
  height: 100% !important; max-height: 100% !important; min-height: 0 !important;
  margin: 8px !important;
  overflow-y: scroll !important; overflow-x: auto !important;
}
.left_col .left_col.scroll-view { height: 100% !important; }

/* --- Content: on desktop the GRID SHELL (18b) already positions this in the
   "content" cell. Do NOT add margin-left/margin-top here — that double-counted
   the sidebar width and navbar height and pushed the layout off to the left.
   Only padding is set. Mobile (no grid) keeps the navbar offset. --- */
@media (min-width: 992px) {
  body.ksa-shell .container.body .right_col,
  .container.body .right_col {
    padding: 18px 22px calc(var(--ksa-footer-h) + 14px) !important;
  }
}
@media (max-width: 991px) {
  body.ksa-shell .container.body .right_col,
  .container.body .right_col {
    margin-left: 0 !important;
    margin-top: var(--ksa-nav-h) !important;
    height: calc(100vh - var(--ksa-nav-h)) !important;
    padding-bottom: calc(var(--ksa-footer-h) + 14px) !important;
  }
  .container.body .col-md-3.left_col { top: var(--ksa-nav-h) !important; }
}

/* The navbar is no longer sticky-inside-content; neutralize the old rule */
body.ksa-shell .top_nav { margin: 0 !important; }

/* Footer stays pinned bottom, full width */
body.ksa-shell footer {
  position: fixed; left: 0; right: 0; bottom: 0;
  height: var(--ksa-footer-h); z-index: 940;
}

/* ===========================================================================
   25. PASS 2.7 — REGISTER PAGE: ensure action buttons are fully visible
   The submit/action row could be clipped at the bottom of the scroll area.
   ------------------------------------------------------------------------- */
.right_col .form-actions,
.right_col .ln_solid + div,
.right_col .btn { position: relative; z-index: 1; }
.right_col { scroll-padding-bottom: 80px; }
/* Give the last content block breathing room above the pinned footer */
.right_col > .x_panel:last-child,
.right_col form > .x_panel:last-child { margin-bottom: 28px; }
.right_col .btn { margin-bottom: 6px; }

/* Register/profile action row: clear the pinned footer, button never clipped */
.right_col .ksa-form-actions { padding-bottom: 24px; margin-bottom: 40px; }
.right_col .ksa-form-actions .btn { min-width: 120px; padding: 9px 26px; }
.right_col fieldset:last-child, .right_col form:last-child { margin-bottom: 46px; }

/* ===========================================================================
   26. NOTICES & CONTENT SECTIONS (shared — landing page + dashboard)
   ------------------------------------------------------------------------- */
.ksa-sec { padding: 22px 24px; margin-bottom: 18px; }
.ksa-sec h3 {
  display: flex; align-items: center; gap: 10px; margin: 0 0 12px;
  font-size: 18px; color: var(--ksa-primary) !important;
}
html[data-ksa-theme="dark"] .ksa-sec h3 { color: var(--ksa-primary-300) !important; }
.ksa-sec-num {
  font-size: 12px; font-weight: 800; letter-spacing: 1px;
  background: var(--ksa-accent); color: #fff; padding: 3px 9px; border-radius: 7px;
}
.ksa-sec p { font-size: 13.5px; color: var(--ksa-text-soft); margin: 0 0 10px; line-height: 1.65; }
.ksa-sec p strong { color: var(--ksa-text); }
.ksa-sec cite {
  display: block; font-size: 11.5px; font-style: normal; font-weight: 600;
  color: var(--ksa-primary); margin-top: 8px;
}
html[data-ksa-theme="dark"] .ksa-sec cite { color: var(--ksa-primary-300); }

.ksa-notice {
  padding: 15px 17px; border-radius: 12px; margin-bottom: 12px;
  background: var(--ksa-glass-bg); border: 1px solid var(--ksa-glass-border);
  border-left: 4px solid var(--ksa-primary);
}
.ksa-notice.danger { border-left-color: var(--ksa-accent); }
.ksa-notice h4 {
  display: flex; align-items: center; gap: 9px; margin: 0 0 7px;
  font-size: 14.5px; color: var(--ksa-text) !important;
}
.ksa-notice h4 .fa { color: var(--ksa-primary); }
.ksa-notice.danger h4 .fa { color: var(--ksa-accent); }
.ksa-notice p { font-size: 12.5px; margin-bottom: 7px; color: var(--ksa-text-soft); line-height: 1.6; }
.ksa-notice p:last-child { margin-bottom: 0; }
.ksa-notice a { font-weight: 600; }

/* ===========================================================================
   27. ICON FONT PROTECTION (fixes navbar/dropdown icons rendering as boxes)
   Broad `font-family: var(--ksa-font)` rules (e.g. `.top_nav .nav_menu *`)
   were overriding FontAwesome's own font on <i> elements, so glyphs fell back
   to Poppins and showed as empty boxes. Restore the icon font everywhere.
   ------------------------------------------------------------------------- */
.fa,
i.fa, span.fa,
.top_nav .nav_menu .fa,
.ksa-user-menu .fa, .ksa-user-chip .fa,
.ksa-navbar .fa, .btn .fa, .ksa-card .fa, .ksa-notice .fa, .ksa-sec .fa,
.ksa-mini .fa, .ksa-need .fa, #sidebar-menu .fa {
  font-family: FontAwesome !important;
  font-weight: normal !important;
  font-style: normal !important;
  -webkit-font-smoothing: antialiased;
}
/* Glyphicons (used by some legacy Gentelella markup) */
.glyphicon { font-family: 'Glyphicons Halflings' !important; font-weight: normal !important; font-style: normal !important; }

/* ===========================================================================
   28. LOGIN / REGISTER CARD FIELD CONTAINMENT
   Inputs were overflowing their card because Bootstrap columns + explicit
   widths + padding exceeded the card's content box.
   ------------------------------------------------------------------------- */
.ksa-login-card, .ksa-glass { box-sizing: border-box; }
.ksa-login-card *, .ksa-login-card *::before, .ksa-login-card *::after { box-sizing: border-box; }
.ksa-login-card .form-control,
.ksa-login-card input[type="text"],
.ksa-login-card input[type="password"] {
  width: 100% !important; max-width: 100% !important; display: block;
}
.ksa-login-card .ksa-field { max-width: 100%; overflow: visible; }

/* Register/profile forms: keep every control inside its column & card */
.right_col .x_panel, .right_col fieldset { box-sizing: border-box; overflow-x: hidden; }
.right_col .form-control,
.right_col input[type="text"], .right_col input[type="password"],
.right_col input[type="email"], .right_col input[type="number"],
.right_col select, .right_col textarea {
  max-width: 100% !important;
  box-sizing: border-box;
}
/* Legacy inline Width="0px"/fixed widths on server controls must not overflow */
.right_col [style*="width"], .right_col [width] { max-width: 100% !important; }
.right_col .form-group.row { margin-left: 0 !important; margin-right: 0 !important; }
.right_col .form-group.row > [class*="col-"] { padding-left: 8px; padding-right: 8px; min-width: 0; }

/* ===========================================================================
   29. DARK MODE — NEUTRALIZE GENTELELLA'S HARDCODED LIGHT SURFACES
   build/css/custom.min.css hardcodes white/near-white backgrounds and dark
   text on many components (.x_panel{background:#fff}, .dashboard_graph,
   .input-group-addon, .ln_solid, .dropdown-menu, .tile-stats, .well, …).
   In dark mode those stayed light while our text turned light → unreadable
   forms. Re-theme them from tokens. Applies to BOTH themes where sensible.
   ------------------------------------------------------------------------- */

/* --- Panels / content wrappers: glass in both themes --- */
.x_panel, .dashboard_graph, .tile-stats, .sidebar-widget,
.pricing, .pricing_footer, .profile_view, .compose, .markup, .well {
  background: var(--ksa-glass-bg) !important;
  border-color: var(--ksa-glass-border) !important;
  color: var(--ksa-text) !important;
}
.x_content, .x_title { background: transparent !important; color: var(--ksa-text); }

/* --- Dividers --- */
.ln_solid, .divider-dashed, hr {
  background: transparent !important;
  border-top-color: var(--ksa-glass-border) !important;
  color: transparent;
}

/* --- Inputs, addons, selects (the register/profile form fields) --- */
.form-control, .input-group-addon, .input-mini, .tagsinput,
.select2-selection, .select2-selection--single, .select2-selection--multiple,
.select2-search__field, .bootstrap-datetimepicker-widget,
select, textarea, input[type="text"], input[type="password"],
input[type="email"], input[type="number"], input[type="date"], input[type="tel"] {
  background: var(--ksa-input-bg) !important;
  background-color: var(--ksa-input-bg) !important;
  border-color: var(--ksa-input-border) !important;
  color: var(--ksa-text) !important;
}
.input-group-addon { color: var(--ksa-text-soft) !important; }
.form-control::placeholder { color: var(--ksa-text-soft) !important; opacity: .8; }
.form-control:-ms-input-placeholder { color: var(--ksa-text-soft) !important; }

/* Select2 / dropdown popovers */
.dropdown-menu, .select2-dropdown, .select2-results__option,
.daterangepicker, .show-calendar, .fc-state-default {
  background: var(--ksa-glass-bg-strong) !important;
  color: var(--ksa-text) !important;
  border-color: var(--ksa-glass-border) !important;
}
.select2-results__option--highlighted { background: var(--ksa-primary) !important; color: #fff !important; }

/* Native select option list (dark mode needs an explicit solid colour) */
html[data-ksa-theme="dark"] select option,
html[data-ksa-theme="dark"] optgroup {
  background-color: #1b1a38 !important;
  color: var(--ksa-text) !important;
}

/* --- Text elements inside forms that Gentelella colours dark --- */
.x_panel h1, .x_panel h2, .x_panel h3, .x_panel h4, .x_panel h5,
.x_panel p, .x_panel span, .x_panel label, .x_panel legend, .x_panel li,
fieldset legend, .col-form-label, .control-label {
  color: var(--ksa-text) !important;
}
.x_panel label, .col-form-label, .control-label { color: var(--ksa-text-soft) !important; }
.x_panel .required, .required { color: var(--ksa-accent) !important; }

/* Legacy pages set inline colours like style="color:black" — override in dark */
html[data-ksa-theme="dark"] [style*="color:black"],
html[data-ksa-theme="dark"] [style*="color: black"],
html[data-ksa-theme="dark"] [style*="color:#000"],
html[data-ksa-theme="dark"] [style*="color:Black"] {
  color: var(--ksa-text) !important;
}
html[data-ksa-theme="dark"] [style*="background-color:white"],
html[data-ksa-theme="dark"] [style*="background:white"],
html[data-ksa-theme="dark"] [style*="background-color:#fff"],
html[data-ksa-theme="dark"] [style*="background:#fff"] {
  background: var(--ksa-glass-bg) !important;
}

/* Avatars / image frames shouldn't be white blocks in dark mode */
html[data-ksa-theme="dark"] .avatar, html[data-ksa-theme="dark"] .profile_img,
html[data-ksa-theme="dark"] .img-preview {
  background: var(--ksa-glass-bg) !important;
}

/* Checkbox/radio (iCheck) labels */
.icheckbox_flat-green, .iradio_flat-green { filter: none; }
html[data-ksa-theme="dark"] .checkbox label, html[data-ksa-theme="dark"] .radio label { color: var(--ksa-text) !important; }

/* ===========================================================================
   33. CONDITIONAL-HIDE MUST BEAT THE FORM GRID (fixes boolean toggles)
   .ksa-cond-hidden was declared in section 11, BEFORE the form-grid rules in
   sections 30/32 that set `display: grid !important` / `display: block !important`
   on .form-group.row. Equal specificity + both !important => the LATER rule won,
   so fields the Yes/No toggles had hidden became visible again.
   These rules are declared last so hiding always wins, whatever the element is.
   ------------------------------------------------------------------------- */
.ksa-cond-hidden,
.right_col .ksa-cond-hidden,
.right_col .form-group.row.ksa-cond-hidden,
.right_col .form-group.row > .ksa-cond-hidden,
.right_col .form-group.row > div[class*="col-"].ksa-cond-hidden,
.right_col .form-group.row > label.ksa-cond-hidden,
.right_col .form-group.row > .col-form-label.ksa-cond-hidden,
section .ksa-cond-hidden {
  display: none !important;
  visibility: hidden !important;   /* belt-and-braces if a later display rule appears */
}
/* A hidden grid cell must not leave an empty column behind */
.right_col .form-group.row > .ksa-cond-hidden { grid-column: unset !important; }

/* ===========================================================================
   34. MERGED FROM origin/main (Joshua) — mobile sidebar stacking fix
   Kept because it fixes a real bug: on mobile the off-canvas drawer sat BELOW
   the dark overlay backdrop (z-index 9997) and so appeared not to open.
   Our desktop rule (sidebar above navbar) is retained above; on mobile the
   drawer must beat the overlay.
   ------------------------------------------------------------------------- */
/* §18b's grid puts the sidebar and navbar in separate, non-overlapping rows,
   so forcing the sidebar above the navbar (this section, above) is no longer
   needed there - and actively lets the sidebar visually bleed over the
   navbar's row if anything in it overflows its own grid cell. */
/* NOTE (merge): the original rule here set `z-index: auto` on the desktop
   sidebar. That was correct for origin/main's grid shell, but this branch keeps
   the FIXED-position sidebar, where `auto` drops it out of its stacking context
   and the content area slides underneath it. Restored to sit above the content
   and below the navbar. */
@media (min-width: 992px) {
  body.ksa-shell .container.body .col-md-3.left_col { z-index: 2000 !important; }
}
/* Mobile off-canvas drawer: z-index:2000 above is BELOW the sidebar-open
   overlay backdrop (z-index:9997, see §11), so the sliding-in sidebar was
   rendering underneath that dark overlay - invisible, reading as "nothing
   opened". Needs to be above the overlay here, not just reset to auto. */
@media (max-width: 991px) {
  .container.body .col-md-3.left_col,
  body.ksa-shell .container.body .col-md-3.left_col { z-index: 9998 !important; }
}
/* ===========================================================================
   35. CONDITIONAL HIDING MUST NOT LEAVE HOLES IN THE FORM GRID
   Scope: the profile/personal-details style forms only (.right_col).
   §30 lays each .form-group.row out as a fixed 4-column grid. When a toggle
   hides SOME cells in a row, the remaining label/field pairs stayed pinned to
   their original columns, leaving blank gaps and mis-pairing labels with the
   wrong inputs. Rows that contain conditional cells now flow automatically so
   the surviving pairs close up, while rows with nothing hidden keep the exact
   symmetric layout established in §30.
   ------------------------------------------------------------------------- */
@media (min-width: 992px) {
  /* Auto-flow rows: visible label/field pairs pack from the left with no holes. */
  .right_col .form-group.row:has(> .ksa-cond-hidden) {
    grid-template-columns: repeat(auto-fit, minmax(0, auto)) !important;
    grid-auto-columns: max-content;
    grid-auto-flow: row dense;
    justify-content: start;
    column-gap: 12px;
  }
  /* Labels in such rows sit next to their own field instead of a fixed column. */
  .right_col .form-group.row:has(> .ksa-cond-hidden) > label,
  .right_col .form-group.row:has(> .ksa-cond-hidden) > .col-form-label {
    text-align: left !important;
    white-space: nowrap;
    padding-right: 4px !important;
  }
  /* A row where EVERYTHING conditional is hidden collapses entirely, so no
     empty padded strip is left behind between visible rows. */
  .right_col .form-group.row.ksa-row-empty { display: none !important; }
}

/* ===========================================================================
   36. SIDEBAR ITEM DESCRIPTIONS (stacked UNDER the menu label)
   ksa-theme.js menuDescriptions() wraps the existing label text in
   .ksa-menu-label and appends .ksa-menu-desc, so each entry reads:
        [icon]  Label
                Description
   The link must allow wrapping for this: the earlier `white-space: nowrap`
   (needed for single-line menus) is overridden for items that have a
   description, otherwise the description stays glued beside the label.
   ------------------------------------------------------------------------- */
#sidebar-menu a.ksa-has-desc {
  display: flex !important;
  flex-wrap: wrap;
  align-items: baseline;
  white-space: normal !important;      /* beats the nowrap rule above */
  padding-top: 9px !important;
  padding-bottom: 9px !important;
  line-height: 1.32;
}
/* Icon stays on the first line, fixed width, so both lines align to one gutter */
#sidebar-menu a.ksa-has-desc > .fa {
  flex: 0 0 18px;
  margin-right: 8px;
}
/* Label: takes the rest of the first line */
#sidebar-menu a.ksa-has-desc > .ksa-menu-label {
  flex: 1 1 auto;
  min-width: 0;
  font-size: 13.5px;
  font-weight: 500;
  white-space: normal;
}
/* Description: forced onto its OWN line, indented to the label's gutter */
#sidebar-menu a.ksa-has-desc > .ksa-menu-desc {
  flex: 0 0 100%;
  display: block;
  margin: 3px 0 0 26px;                /* 18px icon + 8px gap */
  font-size: 10.5px;
  font-weight: 400;
  line-height: 1.35;
  color: rgba(255, 255, 255, .55);
  white-space: normal;
}
/* Child-menu items have no icon — no indent needed */
#sidebar-menu .nav.child_menu a.ksa-has-desc > .ksa-menu-desc { margin-left: 0; }
#sidebar-menu a.ksa-has-desc:hover > .ksa-menu-desc { color: rgba(255, 255, 255, .8); }
#sidebar-menu a.ksa-active.ksa-has-desc > .ksa-menu-desc { color: rgba(255, 255, 255, .9); }

/* ===========================================================================
   37. FORM SECTIONS (grouped Personal Details / profile forms)
   Built by ksa-theme.js groupFormSections(): each titled section is a glass
   card with a collapsible header, containing that section's .form-group rows.
   ------------------------------------------------------------------------- */
.ksa-form-section {
  padding: 0 !important;
  overflow: hidden;
  margin: 0 0 16px 0 !important;
}
.ksa-form-section-head {
  display: flex !important; align-items: center; gap: 11px;
  margin: 0 !important; padding: 14px 20px !important;
  font-size: 15.5px; font-weight: 600;
  color: var(--ksa-primary) !important;
  cursor: pointer; user-select: none;
  border-bottom: 1px solid transparent;
  transition: background .18s ease, border-color .18s ease;
}
html[data-ksa-theme="dark"] .ksa-form-section-head { color: var(--ksa-primary-300) !important; }
.ksa-form-section.ksa-open > .ksa-form-section-head { border-bottom-color: var(--ksa-glass-border); }
.ksa-form-section-head:hover { background: var(--ksa-primary-100); }
html[data-ksa-theme="dark"] .ksa-form-section-head:hover { background: rgba(111,107,192,.16); }
.ksa-form-section-head:focus-visible { outline: 2px solid var(--ksa-accent); outline-offset: -3px; }
.ksa-form-section-head > .fa:first-child {
  flex: 0 0 auto; font-size: 14px;
  width: 30px; height: 30px; border-radius: 9px;
  display: inline-flex; align-items: center; justify-content: center;
  background: linear-gradient(135deg, var(--ksa-primary), var(--ksa-primary-600));
  color: #fff;
}
.ksa-form-section-head > span { flex: 1 1 auto; }
.ksa-form-section-chev {
  flex: 0 0 auto; font-size: 12px; color: var(--ksa-text-soft);
  transition: transform .28s ease;
}
.ksa-form-section.ksa-open > .ksa-form-section-head .ksa-form-section-chev { transform: rotate(180deg); }

.ksa-form-section-body { padding: 16px 20px 18px; }
.ksa-form-section:not(.ksa-open) > .ksa-form-section-body { display: none !important; }
.ksa-form-section-body > .form-group.row:last-child { margin-bottom: 0 !important; }
/* the legacy fieldset wrapper adds a second border inside a section — flatten it */
.ksa-form-section-body fieldset { border: none !important; padding: 0 !important; background: transparent !important; }

/* ===========================================================================
   40. SECTION PADDING + UNIFORM SECTION TITLES + NO NESTED CONTAINER
   ------------------------------------------------------------------------- */
/* Fields were touching the bottom edge of the section card */
.ksa-form-section-body {
  padding: 18px 22px 24px !important;
}
.ksa-form-section-body > .ksa-fgrid:last-child,
.ksa-form-section-body > .form-group:last-child { margin-bottom: 0 !important; }
.ksa-form-section-body > .ksa-fgrid { margin-bottom: 14px !important; }

/* The last section carried its own <fieldset>, drawing a second box inside the
   card. Flatten every nested wrapper so all sections look identical. */
.ksa-form-section-body fieldset,
.ksa-form-section-body .x_panel,
.ksa-form-section-body .x_content,
.ksa-form-section-body .well {
  border: none !important;
  background: none !important;
  box-shadow: none !important;
  padding: 0 !important;
  margin: 0 !important;
  border-radius: 0 !important;
  backdrop-filter: none !important;
  -webkit-backdrop-filter: none !important;
}

/* SECTION 1/2/3 headings inside the cards: identical font, weight and colour */
.ksa-form-section-body h4,
.ksa-form-section-body h4.auto-style1,
.ksa-form-section-body .auto-style1 {
  font-family: var(--ksa-font) !important;
  font-size: 14px !important;
  font-weight: 700 !important;
  letter-spacing: .3px !important;
  text-transform: none !important;
  color: var(--ksa-primary) !important;
  margin: 18px 0 10px !important;
  padding: 0 0 6px !important;
  border-bottom: 1px solid var(--ksa-glass-border);
}
html[data-ksa-theme="dark"] .ksa-form-section-body h4,
html[data-ksa-theme="dark"] .ksa-form-section-body .auto-style1 {
  color: var(--ksa-primary-300) !important;
}
.ksa-form-section-body > h4:first-child { margin-top: 0 !important; }
/* the groove <hr> the legacy markup put under those headings is redundant now */
.ksa-form-section-body hr[style*="groove"] { display: none !important; }

/* ===========================================================================
   38. FIELD LAYOUT — one flex unit per field, driven by CONTAINER QUERIES
   ---------------------------------------------------------------------------
   Structure from buildFieldGrid():
       .ksa-fgrid          the row — a flex track of units
         .ksa-fitem        a UNIT: label + control together, NO visible box
           .ksa-flabel     the description
           .ksa-fctl       the control

   WHY CONTAINER QUERIES, not caption-length maths or viewport breakpoints
   ---------------------------------------------------------------------------
   The previous rules chose "label beside" vs "label above" from the caption's
   CHARACTER COUNT (<=28 chars -> beside). Two problems, both visible on screen:
     1. It looked arbitrary. Adjacent fields were laid out differently because
        one caption happened to be a word longer, so no two rows lined up - the
        "scattered" appearance, and the arithmetic-feeling rule that was
        explicitly rejected.
     2. A character count is a guess about available space, made without ever
        measuring the space. It cannot be right when the space changes.

   And the space here changes constantly: the sidebar is user-resizable, so the
   content pane's width is not a function of the viewport at all. Viewport media
   queries are therefore also wrong - a field can be cramped on a wide monitor
   simply because the sidebar was dragged out.

   Container queries fix both: each unit is asked to lay itself out from THE
   ACTUAL WIDTH OF ITS OWN CONTAINER. Dragging the sidebar reflows the fields
   live, with no JS measuring and no reload; mobile then needs no special case,
   because a narrow phone and a squeezed pane are the same condition.

   THE RULES (what the user asked for, in order of precedence)
     - label and control are ONE unit, always: same flex parent, never split
     - label sits BESIDE the control - it is never placed on top of it, at any
       width above the narrow floor
     - the label is never squeezed: it gets a comfortable minimum (11em) and
       wraps its own text rather than being compressed or truncated
     - the control is never inflated to fill leftover space: it is capped, so a
       short input does not stretch across the pane
     - ONLY below a genuinely narrow container (~380px) does the label move
       above the control - the single agreed exception, where side-by-side
       would crush the label to a few characters per line
   ------------------------------------------------------------------------- */

/* ---- the row: flexible track of units ---- */
.ksa-fgrid {
  display: flex !important;
  flex-wrap: wrap;
  align-items: flex-start;
  gap: 14px 28px;
  margin: 0 0 16px 0 !important;
  padding: 0 !important;
  width: 100%;
}

/* ---- a unit: label + control, side by side, invisible container ----
   Each unit declares itself a query container so its children can respond to
   ITS width (not the page's). `inline-size` = width-only containment, which is
   the cheap variant and all we need. */
.ksa-fitem {
  container-type: inline-size;
  container-name: ksafield;
  display: flex;
  flex-direction: row;          /* label BESIDE control - the default, always */
  align-items: baseline;        /* text baselines align across the unit */
  column-gap: 12px;
  flex: 1 1 clamp(300px, 34%, 460px);  /* 1-3 per row depending on real space */
  min-width: 0;
  background: none !important;
  border: none !important;
  border-radius: 0 !important;
  box-shadow: none !important;
  padding: 0 !important;
  margin: 0 !important;
}

/* description: a comfortable fixed share, never compressed.
   flex-basis 11em + max 42% keeps captions readable and, because every unit
   uses the SAME basis, the controls line up in a visual column - which is what
   makes a form read as organised rather than scattered. */
.ksa-fgrid .ksa-flabel {
  flex: 0 1 11em;
  max-width: 42%;
  margin: 0 !important;
  padding: 0 !important;
  background: none !important;
  border: none !important;
  font-size: 12.7px;
  font-weight: 500;
  line-height: 1.5;
  color: var(--ksa-text-soft) !important;
  white-space: normal;          /* wraps its own text: never truncated */
  overflow-wrap: break-word;
  hyphens: none;
  text-align: left !important;
}

/* the control: takes the rest, but capped so it is not inflated */
.ksa-fgrid > .ksa-fitem > .ksa-fctl {
  flex: 1 1 auto;
  min-width: 0;
  max-width: 24em;
}

/* ---- textareas and choice groups own a full row ----
   A Yes/No group beside its question reads as a sentence rather than a control,
   and a textarea beside a label has nowhere to grow - so these two kinds (the
   only things JS still classifies) span the row. The label stays BESIDE the
   control for choices; the textarea is the one place the label sits above,
   because a multi-line box next to a single label leaves the label stranded. */
.ksa-fitem-choice { flex: 1 1 100%; align-items: flex-start; }
.ksa-fitem-choice > .ksa-fctl { max-width: none; }
.ksa-fitem-area {
  flex: 1 1 100%;
  flex-direction: column;
  align-items: stretch;
  row-gap: 6px;
}
.ksa-fitem-area > .ksa-flabel { flex: 0 0 auto; max-width: 100%; }
.ksa-fitem-area > .ksa-fctl   { max-width: 100%; }

/* ---- THE ONE NARROW EXCEPTION -------------------------------------------
   Below ~380px of ACTUAL container width, side by side would leave the label a
   few characters per line. Only here does it move above the control. Note this
   is keyed to the container, so it triggers on a squeezed pane too - not just
   on a phone. */
@container ksafield (max-width: 380px) {
  .ksa-fitem {
    flex-direction: column;
    align-items: stretch;
    row-gap: 5px;
  }
  .ksa-fgrid .ksa-flabel { flex: 0 0 auto; max-width: 100%; }
  .ksa-fgrid > .ksa-fitem > .ksa-fctl { max-width: 100%; }
}

/* Fallback for engines without container queries: keep side-by-side, and let
   the viewport handle the narrow case (see the max-width:600px block in §38b).
   Modern Chrome/Edge/Firefox/Safari all support @container; this only matters
   for older builds, where the layout degrades to the previous behaviour rather
   than breaking. */
@supports not (container-type: inline-size) {
  .ksa-fitem { flex: 1 1 340px; }
}

/* ---- the control itself ---- */
.ksa-fgrid .ksa-fctl { min-width: 0; width: 100%; }
.ksa-fgrid .ksa-fctl > div[class*="col-"] {
  width: 100% !important; max-width: 100% !important;
  flex: none !important; float: none !important;
  padding: 0 !important; margin: 0 !important; min-width: 0;
}
.ksa-fgrid .ksa-fctl input[type="text"],
.ksa-fgrid .ksa-fctl input[type="password"],
.ksa-fgrid .ksa-fctl input[type="email"],
.ksa-fgrid .ksa-fctl input[type="number"],
.ksa-fgrid .ksa-fctl input[type="tel"],
.ksa-fgrid .ksa-fctl input[type="date"],
.ksa-fgrid .ksa-fctl select,
.ksa-fgrid .ksa-fctl textarea,
.ksa-fgrid .ksa-fctl .form-control {
  width: 100% !important; max-width: 100% !important; min-width: 0 !important;
  box-sizing: border-box;
  margin: 0 !important;
  padding: 6px 11px !important;
  font-size: 13px;
  background: var(--ksa-input-bg) !important;
  border: 1px solid var(--ksa-input-border) !important;
  border-radius: 8px !important;
}
/* Single-line controls keep the fixed 36px height. Textareas are deliberately
   EXCLUDED: a `height: … !important` here beat the inline height the browser
   writes while you drag the resize grip, so the field snapped back and the
   resize handle looked broken. */
.ksa-fgrid .ksa-fctl input[type="text"],
.ksa-fgrid .ksa-fctl input[type="password"],
.ksa-fgrid .ksa-fctl input[type="email"],
.ksa-fgrid .ksa-fctl input[type="number"],
.ksa-fgrid .ksa-fctl input[type="tel"],
.ksa-fgrid .ksa-fctl input[type="date"],
.ksa-fgrid .ksa-fctl select {
  height: 36px !important; min-height: 36px !important;
}
/* Textarea: draggable. min-height (no !important) is a floor the drag can beat. */
.ksa-fgrid .ksa-fctl textarea {
  min-height: 74px;
  resize: vertical;
}
.ksa-fgrid .ksa-fctl input:focus,
.ksa-fgrid .ksa-fctl select:focus,
.ksa-fgrid .ksa-fctl textarea:focus {
  border-color: var(--ksa-primary) !important;
  box-shadow: var(--ksa-focus-ring) !important;
}

/* Yes/No groups: options sit under their question, inline with each other */
.ksa-fitem-choice > .ksa-fctl table {
  width: auto !important; border: none !important; background: none !important; margin: 0 !important;
}
.ksa-fitem-choice > .ksa-fctl table td {
  border: none !important; background: none !important;
  padding: 0 22px 0 0 !important; white-space: nowrap;
}
.ksa-fgrid .ksa-fctl input[type="radio"],
.ksa-fgrid .ksa-fctl input[type="checkbox"] {
  width: auto !important; height: auto !important; min-height: 0 !important;
  padding: 0 !important; margin: 0 6px 0 0 !important;
  background: none !important; border: none !important; vertical-align: middle;
}
.ksa-fgrid .ksa-fctl label {
  font-size: 12.7px; margin: 0 2px 0 0; vertical-align: middle;
  color: var(--ksa-text) !important;
}

/* conditional hide removes the whole unit so the row closes up */
.ksa-fitem.ksa-cond-hidden { display: none !important; }
/* legacy empty spacer columns (flagged in buildFieldGrid) claim no space */
.ksa-fitem.ksa-fitem-spacer { display: none !important; }
/* Truly empty filler units only. This used to also require an input/select/
   textarea/table, which wrongly hid read-only fields whose value is rendered
   into a <span> by the server (e.g. "Request ID:", "Organisation Advertising:"
   on the advert form) - those have a caption and a real value but no form
   control, and they disappeared. Now a unit is only dropped when it has no
   control AND no caption text at all. */
.ksa-fitem:not(:has(input, select, textarea, table, span, a, label:not(.ksa-flabel))) {
  display: none !important;
}

/* §38b — narrow VIEWPORT fallback.
   The container query above is the primary mechanism and already covers a
   squeezed pane. This stays as a floor for engines without @container support
   and for genuinely tiny phones, so the label/control never end up side by side
   in a few-characters-wide column. */
@media (max-width: 600px) {
  .ksa-fgrid { gap: 12px 0; }
  .ksa-fitem {
    flex: 1 1 100% !important;
    max-width: 100%;
    flex-direction: column;
    align-items: stretch;
    row-gap: 5px;
  }
  .ksa-fgrid .ksa-flabel { flex: 0 0 auto; max-width: 100%; }
  .ksa-fgrid > .ksa-fitem > .ksa-fctl { max-width: 100%; }
}

/* rows deliberately untouched (notices, data grids, Save/Exit) */
.ksa-fgrid-skip { display: block !important; }
.ksa-fgrid-skip > div[class*="col-"] { max-width: 100%; }

/* ===========================================================================
   ADMIN PORTAL — LOGIN CARD FIELD CONTAINMENT
   The admin login/registration pages do NOT load Bootstrap, so the browser
   default `box-sizing: content-box` applies: `width: 100%` plus horizontal
   padding made every input wider than the card, pushing the fields past its
   edge. Force border-box for the card and everything in it.
   ------------------------------------------------------------------------- */
.ksa-login-wrap, .ksa-login-wrap *,
.ksa-login-card, .ksa-login-card *,
.ksa-login-card *::before, .ksa-login-card *::after {
  box-sizing: border-box !important;
}
.ksa-login-card {
  overflow: hidden;                 /* nothing may escape the card */
}
.ksa-login-card .ksa-field { max-width: 100%; }
.ksa-login-card .ksa-field input,
.ksa-login-card input[type="text"],
.ksa-login-card input[type="password"],
.ksa-login-card .form-control {
  display: block;
  width: 100% !important;
  max-width: 100% !important;
  min-width: 0 !important;
  box-sizing: border-box !important;
}
.ksa-login-card .btn { max-width: 100%; box-sizing: border-box !important; }

/* Inline guidance under a field (e.g. which document to attach). Deliberately
   quiet: it explains a requirement without competing with the label. */
.ksa-field-hint {
  display: block; margin-top: 5px;
  font-size: 11.8px; line-height: 1.45;
  color: var(--ksa-text-soft);
}
.ksa-field-hint strong { color: var(--ksa-primary); font-weight: 600; }
html[data-ksa-theme="dark"] .ksa-field-hint strong { color: var(--ksa-primary-300); }

/* ===========================================================================
   30. TEXTAREA RESIZE (owner request #9)
   The resize grip is native browser behaviour, but it only "sticks" if no
   stylesheet rule with !important overrides the inline height the browser
   writes during the drag. The form-grid block above stopped locking textarea
   heights; this block guarantees the grip exists on EVERY textarea site-wide,
   including legacy pages that never opt into .ksa-fgrid and raw
   <textarea runat="server"> controls carrying an inline Height="100px".
   ------------------------------------------------------------------------- */
textarea,
textarea.form-control,
.right_col textarea,
.ksa-fctl textarea {
  resize: vertical;          /* drag grip, vertical only (matches Bootstrap) */
  overflow: auto;
}
/* Never cap a textarea by height — that is what the user drags. Width stays
   bounded so long legacy Width="900px" values cannot overflow the shell. */
.right_col textarea, .ksa-fgrid .ksa-fctl textarea { max-height: none !important; }

/* ===========================================================================
   31. IN-APP NOTIFICATIONS (owner request #4)
   Replaces the browser's native alert() dialog. Two surfaces, both rendered
   inside the app: a toast stack (top-right, auto-dismiss) and a centred
   acknowledgement dialog for errors/warnings and for messages that must be
   read before the page navigates. Built by ksa-theme.js (window.ksaNotify).
   ------------------------------------------------------------------------- */
.ksa-toast-host {
  position: fixed; top: calc(var(--ksa-nav-h, 112px) + 12px); right: 18px;
  /* Above .ksa-loading-overlay (99999): a server-rendered message arriving
     with a postback must never be hidden behind the submit spinner. */
  z-index: 100010;
  display: flex; flex-direction: column; gap: 10px;
  width: min(380px, calc(100vw - 36px));
  pointer-events: none;                /* clicks pass through the empty stack */
}
.ksa-toast {
  pointer-events: auto;
  display: flex; align-items: flex-start; gap: 10px;
  padding: 12px 12px 12px 14px;
  border-radius: 12px;
  border: 1px solid var(--ksa-input-border, #dcdce6);
  border-left: 4px solid var(--ksa-primary, #444097);
  background: var(--ksa-surface, #fff);
  color: var(--ksa-text, #23233f);
  box-shadow: 0 12px 30px rgba(20, 20, 50, .18);
  font-size: 13.5px; line-height: 1.5;
  opacity: 0; transform: translateX(14px);
  transition: opacity .22s ease, transform .22s ease;
}
.ksa-toast.ksa-in { opacity: 1; transform: translateX(0); }
.ksa-toast-icon { font-size: 16px; line-height: 1.35; flex: 0 0 auto; }
.ksa-toast-body { flex: 1 1 auto; word-break: break-word; }
.ksa-toast-x {
  flex: 0 0 auto; border: 0; background: transparent; cursor: pointer;
  font-size: 20px; line-height: 1; padding: 0 2px; color: var(--ksa-text-soft, #6b6b85);
  opacity: .7;
}
.ksa-toast-x:hover { opacity: 1; }

.ksa-toast-success { border-left-color: #1e8e5a; }
.ksa-toast-success .ksa-toast-icon { color: #1e8e5a; }
.ksa-toast-error   { border-left-color: #c0392b; }
.ksa-toast-error   .ksa-toast-icon { color: #c0392b; }
.ksa-toast-warning { border-left-color: #d38b04; }
.ksa-toast-warning .ksa-toast-icon { color: #d38b04; }
.ksa-toast-info    { border-left-color: var(--ksa-primary, #444097); }
.ksa-toast-info    .ksa-toast-icon { color: var(--ksa-primary, #444097); }

/* --- acknowledgement / confirm dialog --- */
.ksa-note-backdrop {
  /* Above .ksa-loading-overlay (99999) - see note on .ksa-toast-host. */
  position: fixed; inset: 0; z-index: 100020;
  display: flex; align-items: center; justify-content: center;
  padding: 20px;
  background: rgba(18, 18, 40, .48);
  opacity: 0; transition: opacity .18s ease;
}
.ksa-note-backdrop.ksa-in { opacity: 1; }
body.ksa-note-open { overflow: hidden; }   /* page can't scroll behind it */

.ksa-note {
  width: min(460px, 100%);
  background: var(--ksa-surface, #fff);
  color: var(--ksa-text, #23233f);
  border-radius: 16px;
  box-shadow: 0 26px 70px rgba(10, 10, 35, .38);
  overflow: hidden;
  transform: translateY(-10px) scale(.98);
  transition: transform .2s ease;
}
.ksa-note-backdrop.ksa-in .ksa-note { transform: translateY(0) scale(1); }

.ksa-note-head {
  display: flex; align-items: center; gap: 10px;
  padding: 15px 20px;
  font-size: 15px; font-weight: 700;
  border-bottom: 1px solid var(--ksa-input-border, #e6e6ef);
}
.ksa-note-head i { font-size: 18px; }
.ksa-note-body {
  padding: 18px 20px;
  font-size: 14px; line-height: 1.6;
  word-break: break-word;
  max-height: 55vh; overflow-y: auto;
}
.ksa-note-foot {
  display: flex; justify-content: flex-end; gap: 10px;
  padding: 0 20px 18px;
}
.ksa-note-btn {
  min-width: 104px;
  padding: 9px 18px;
  border: 0; border-radius: 9px;
  background: var(--ksa-primary, #444097); color: #fff;
  font-size: 13.5px; font-weight: 600; cursor: pointer;
  transition: filter .15s ease;
}
.ksa-note-btn:hover { filter: brightness(1.08); }
.ksa-note-btn:focus-visible { outline: 3px solid rgba(68, 64, 151, .45); outline-offset: 2px; }
.ksa-note-btn-ghost {
  background: transparent; color: var(--ksa-text-soft, #6b6b85);
  border: 1px solid var(--ksa-input-border, #dcdce6);
}

.ksa-note-error   .ksa-note-head { color: #c0392b; }
.ksa-note-warning .ksa-note-head { color: #b87503; }
.ksa-note-success .ksa-note-head { color: #1e8e5a; }
.ksa-note-info    .ksa-note-head { color: var(--ksa-primary, #444097); }
.ksa-note-error   .ksa-note-btn { background: #c0392b; }
.ksa-note-error   .ksa-note-btn:focus-visible { outline-color: rgba(192, 57, 43, .45); }

/* Dark theme: the surface vars already flip, these are the literals above. */
html[data-ksa-theme="dark"] .ksa-toast,
html[data-ksa-theme="dark"] .ksa-note {
  background: var(--ksa-surface-2, #1e1e33);
  border-color: var(--ksa-input-border, #3a3a55);
}
html[data-ksa-theme="dark"] .ksa-note-backdrop { background: rgba(4, 4, 14, .66); }

@media (max-width: 767px) {
  .ksa-toast-host {
    top: auto; bottom: 14px; left: 12px; right: 12px;
    width: auto;
  }
  .ksa-note-foot { flex-direction: column-reverse; }
  .ksa-note-btn { width: 100%; }
}
/* Users who prefer reduced motion get no slide/scale transitions. */
@media (prefers-reduced-motion: reduce) {
  .ksa-toast, .ksa-note, .ksa-note-backdrop { transition: none; }
  .ksa-toast { transform: none; }
}

/* ===========================================================================
   32. RESIZABLE TABLE COLUMNS (owner request #12)
   ksa-theme.js adds .ksa-col-resizable to each grid and injects a .ksa-col-grip
   into every header cell but the last. table-layout:fixed is what makes an
   explicit column width actually hold instead of being re-flowed by content.
   ------------------------------------------------------------------------- */
.ksa-table-scroll table.ksa-col-resizable { table-layout: fixed; }

.ksa-table-scroll table.ksa-col-resizable th.ksa-col-host { position: relative; }

.ksa-col-grip {
  position: absolute; top: 0; right: -3px; bottom: 0;
  width: 8px;
  cursor: col-resize;
  z-index: 3;
  /* A faint rule so the divider is discoverable without shouting. */
  background: linear-gradient(to right,
              transparent 0, transparent 3px,
              rgba(255, 255, 255, .34) 3px, rgba(255, 255, 255, .34) 5px,
              transparent 5px);
  opacity: 0; transition: opacity .15s ease;
}
.ksa-table-scroll table.ksa-col-resizable th.ksa-col-host:hover .ksa-col-grip,
body.ksa-col-resizing .ksa-col-grip { opacity: 1; }

/* While dragging: no text selection anywhere, col-resize cursor everywhere. */
body.ksa-col-resizing { user-select: none; cursor: col-resize; }
body.ksa-col-resizing * { cursor: col-resize !important; }

/* With table-layout:fixed the cells must clip rather than force a reflow.
   Hovering a truncated cell still shows the full value via its title. */
.ksa-table-scroll table.ksa-col-resizable td,
.ksa-table-scroll table.ksa-col-resizable th {
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* EXCEPT action cells. table-layout:fixed sizes a column from its header text,
   and an "Action" header is narrow enough that a second icon button lands past
   the edge - where the ellipsis above renders it as a bare "..." instead of the
   delete icon. Icons are not text and must never be traded for an ellipsis, so
   these cells size to their buttons and clip nothing. */
.ksa-table-scroll table.ksa-col-resizable td.ksa-act-cell,
.ksa-table-scroll table.ksa-col-resizable th.ksa-act-col {
  overflow: visible; text-overflow: clip;
  white-space: nowrap;
}
/* The column width is decided by the header cell under fixed layout, so the
   min-width has to live there as well as on the body cells. */
.ksa-table-scroll table.ksa-col-resizable th.ksa-act-col,
.ksa-table-scroll table.ksa-col-resizable td.ksa-act-cell {
  min-width: max-content;    /* never narrower than the buttons themselves */
}
/* Keep the grip usable on an action header despite overflow:visible. */
.ksa-table-scroll table.ksa-col-resizable th.ksa-act-col.ksa-col-host {
  position: relative;
}
.ksa-table-scroll table.ksa-col-resizable td.ksa-act-cell > a,
.ksa-table-scroll table.ksa-col-resizable td.ksa-act-cell > a > img {
  display: inline-block; vertical-align: middle;
}
/* A real gap between the icons, replacing the &nbsp;&nbsp; spacers that the
   ellipsis was eating into. */
.ksa-table-scroll table.ksa-col-resizable td.ksa-act-cell > a + a { margin-left: 10px; }
/* Touch devices get a wider, always-visible target. */
@media (hover: none) and (pointer: coarse) {
  .ksa-col-grip { width: 16px; right: -7px; opacity: .8; }
}

/* ===========================================================================
   33. DOCUMENT PREVIEW VIEWER (owner request #1)
   In-app viewer for uploaded attachments. Intentionally has no download or
   "open in new tab" affordance — the requirement is preview WITHOUT download,
   so a reviewer can read a document before approving it.
   ------------------------------------------------------------------------- */
.ksa-prev-backdrop { z-index: 4200; }

.ksa-prev {
  width: min(1000px, 100%);
  height: min(88vh, 900px);
  display: flex; flex-direction: column;
  background: var(--ksa-surface, #fff);
  border-radius: 16px;
  box-shadow: 0 26px 70px rgba(10, 10, 35, .42);
  overflow: hidden;
  transform: translateY(-10px) scale(.985);
  transition: transform .2s ease;
}
.ksa-note-backdrop.ksa-in .ksa-prev { transform: translateY(0) scale(1); }

.ksa-prev-head {
  flex: 0 0 auto;
  display: flex; align-items: center; gap: 12px;
  padding: 13px 16px 13px 20px;
  border-bottom: 1px solid var(--ksa-input-border, #e6e6ef);
  background: var(--ksa-surface-2, #f7f7fb);
}
.ksa-prev-title {
  flex: 1 1 auto; min-width: 0;
  font-size: 14.5px; font-weight: 700; color: var(--ksa-text, #23233f);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.ksa-prev-title .fa { color: var(--ksa-primary, #444097); margin-right: 4px; }
.ksa-prev-hint {
  flex: 0 0 auto;
  padding: 3px 10px; border-radius: 999px;
  font-size: 10.5px; font-weight: 700; letter-spacing: .7px; text-transform: uppercase;
  background: var(--ksa-primary-100, #ecebf7); color: var(--ksa-primary, #444097);
}
html[data-ksa-theme="dark"] .ksa-prev-hint {
  background: rgba(111, 107, 192, .22); color: var(--ksa-primary-300, #b6b3e6);
}
.ksa-prev-x {
  flex: 0 0 auto; border: 0; background: transparent; cursor: pointer;
  font-size: 26px; line-height: 1; padding: 0 4px;
  color: var(--ksa-text-soft, #6b6b85); opacity: .75;
}
.ksa-prev-x:hover { opacity: 1; color: #c0392b; }

.ksa-prev-body { flex: 1 1 auto; position: relative; background: #55555f; min-height: 0; }
.ksa-prev-frame { width: 100%; height: 100%; border: 0; display: block; }
.ksa-prev-load {
  position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: center;
  color: #fff; font-size: 13.5px; letter-spacing: .3px;
}

/* The trigger link inside a grid row. */
.ksa-prev-link { cursor: pointer; white-space: nowrap; }
.ksa-prev-link .fa { margin-right: 4px; }

@media (max-width: 767px) {
  .ksa-prev { height: 92vh; border-radius: 12px; }
  .ksa-prev-hint { display: none; }
}
@media (prefers-reduced-motion: reduce) {
  .ksa-prev { transition: none; }
}

/* Save/Update/Exit button row on the Add Designation / Add Course forms:
   the offset column's own left padding was getting flattened by the
   `.right_col .form-group.row > [class*="col-"] { padding-left: 8px }`
   rule above, so the buttons sat flush against the offset's edge instead
   of having breathing room. Force it here so nothing upstream can zero
   it out again. */
.right_col .form-group.row > .ksa-save-row { padding-left: 24px !important; }
.ksa-save-btn { margin-right: 10px !important; }

/* ---------------------------------------------------------------------------
   39. INDENT CAPTURE — one field per row (DraftIndentAddNew.aspx)
   These fields (Cadre, Job Scale, Highest Award, Advert Type, Number of
   Vacancies, Contract Duration, Experience required?, Years of Experience,
   For Serving Officers Only?) used to share a row two-at-a-time and were
   rendering with the dropdown/input collapsed to a sliver next to its label:
   the shared container-query field-grid engine (buildFieldGrid() /
   ksa-glass.css §38) and generic ".form-control"/select rules were both
   sizing the same elements and fighting each other.
   Fix: each field now gets its OWN row in the markup, buildFieldGrid() skips
   any row carrying .ksa-indent-solo-row (see ksa-theme.js buildFieldGrid),
   and the row/label/field get their own classes below — never shared with
   .ksa-fgrid/.ksa-fctl/.ksa-flabel — so nothing else on the page can
   override or collide with them. */
.ksa-indent-solo-row {
  display: flex !important;
  flex-wrap: wrap;
  align-items: center;
  column-gap: 14px;
  row-gap: 6px;
  width: 100%;
}
.ksa-indent-solo-label {
  flex: 0 0 auto;
  width: auto !important;
  max-width: 100%;
  margin: 0 !important;
  padding-right: 0 !important;
}
.ksa-indent-solo-field {
  flex: 1 1 auto;
  min-width: 160px;
  max-width: 420px;
  width: auto !important;
}
.ksa-indent-select,
.ksa-indent-input {
  display: block !important;
  width: 100% !important;
  max-width: 100% !important;
  min-width: 0 !important;
  box-sizing: border-box !important;
  height: 36px !important;
  min-height: 36px !important;
  padding: 6px 12px !important;
}
@media (max-width: 600px) {
  .ksa-indent-solo-row { flex-direction: column; align-items: stretch; }
  .ksa-indent-solo-label, .ksa-indent-solo-field { flex: 1 1 100%; max-width: 100%; }
}

/* Code columns while a row is in edit mode (Cadres.aspx). The three code cells
   become Labels that the job-family/cadre dropdowns rewrite, so they are styled
   to read as values rather than as form inputs. */
.ksa-code-cell {
  display: inline-block;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 12.5px; font-weight: 700;
  color: var(--ksa-text, #23233f);
  padding: 2px 7px; border-radius: 4px;
  background: rgba(127, 127, 160, .14);
  min-width: 1.5em; text-align: center;
}

/* ===========================================================================
   40. SHORTLISTING SCREEN — button rows, grids, mobile
   (ShortListAllApplicants.aspx; the utilities are generic and safe to reuse)

   FOUR faults, and the first fix attempt here only addressed the first three -
   the page still looked exactly like the bug report afterwards, because #4 is
   JavaScript, not CSS, and nothing in this file could touch it:

     1. Buttons wrapped in .input-group-btn while NOT inside an .input-group.
        Bootstrap's rule only makes sense welded to an input, so standalone it
        gave the two buttons different heights and glued them together (the
        uneven "Search"/"Shortlist" pair).
     2. Fixed pixel widths on inputs (Width="100px"/"120px", height="23px")
        fighting .form-control's width:100%, collapsing fields to stubs.
     3. GridView Width="570px" clamping wide tables, so columns were crushed
        instead of scrolling.
     4. buildFieldGrid() in ksa-theme.js (§4b) rewrites EVERY ".form-group.row"
        at runtime into its own container-query layout (.ksa-fgrid/.ksa-fitem/
        .ksa-flabel/.ksa-fctl - see §38) and REMOVES the .row class in the
        process. It assumes one caption followed by the field column(s) that
        belong to it, so a row shaped [label][input][buttons][hint] - exactly
        the Step 1/2/Long-List rows here - collapsed into a SINGLE unit with
        three stacked columns inside .ksa-fctl (max-width:24em). That is the
        actual mechanism behind the screenshot: "ID No:" stranded above a
        stretched input, buttons dropped onto their own line, hint text
        stacked below. No CSS aimed at ".form-group.row" can fix this, because
        by the time the browser paints, that class is gone - the DOM itself
        has been restructured. The real fix is marking those four rows
        ksa-fgrid-optout in the markup (ksa-theme.js honours it in
        buildFieldGrid) so they keep plain Bootstrap .row/.col-* flex layout
        instead of being folded into the field grid at all.

   Sizing for the OPTED-OUT rows still comes from .form-control and the two
   utilities below; this section's mobile rules target exactly those rows.
   ------------------------------------------------------------------------- */

/* A plain horizontal button group that WRAPS instead of overflowing. Replaces
   the misused .input-group-btn. `span` is the element used in the markup, so
   display:flex has to be declared explicitly. */
.ksa-btn-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
}
/* Kill the legacy inline/utility margins that used to space these buttons -
   the flex `gap` now owns the spacing, so margins would double it. */
.ksa-btn-row > .btn { margin: 0; }

/* Let a GridView size to its content inside .ksa-table-scroll rather than being
   clamped. min-width keeps columns legible (they scroll rather than squash);
   width:auto overrides the ASP.NET-emitted inline width attribute. */
.ksa-grid {
  width: auto !important;
  min-width: 100%;
  border-collapse: collapse;
}

/* ---- Mobile / narrow screens ------------------------------------------------
   The Bootstrap-3-era markup on this page uses only col-md and col-sm, so below
   768px the columns collapse to full width with no vertical rhythm and the
   label sits hard against its control. These rules restore spacing and make
   every control full-width and comfortably tappable. */
@media (max-width: 767px) {
  /* Each label/field pair becomes its own stacked block. */
  .ksa-form-section-body .form-group.row,
  .ksa-sec .form-group.row {
    margin-left: 0;
    margin-right: 0;
    row-gap: 6px;
  }
  .ksa-form-section-body .form-group.row > [class*="col-"],
  .ksa-sec .form-group.row > [class*="col-"] {
    padding-left: 0;
    padding-right: 0;
    margin-bottom: 10px;
  }
  .ksa-form-section-body .form-group.row > .col-form-label,
  .ksa-sec .form-group.row > .col-form-label {
    padding-left: 0;
    margin-bottom: 2px;
    font-weight: 600;
  }

  /* Full-width, finger-friendly controls. 16px font stops iOS Safari zooming
     the whole page when a field receives focus. */
  .ksa-form-section-body .form-control,
  .ksa-sec .form-control {
    width: 100% !important;
    max-width: 100%;
    font-size: 16px;
  }

  /* Buttons go full-width and stack, so they are never a half-tappable sliver. */
  .ksa-btn-row { flex-direction: column; align-items: stretch; width: 100%; }
  .ksa-btn-row > .btn { width: 100%; }

  /* The file input is the widest offender - it must not push the page sideways. */
  .ksa-sec input[type="file"] { max-width: 100%; }

  /* More of the short viewport for the table, and never let the PAGE scroll
     sideways because of it. */
  .ksa-table-scroll { max-height: 70vh; }
  .ksa-grid { font-size: 12.5px; }
}

/* Very narrow phones: reclaim the horizontal padding the glass cards spend. */
@media (max-width: 480px) {
  .ksa-sec { padding: 16px 14px; }
  .ksa-form-section-body { padding-left: 14px; padding-right: 14px; }
}

/* ===========================================================================
   KSA report charts (js/ksa-report-charts.js)
   Responsive grid of chart panels + the "no data" placeholder a chart falls
   back to when every value in its series is zero.
   ========================================================================= */
.ksa-chart-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
  gap: 18px;
  margin-bottom: 22px;
  width: 100%; box-sizing: border-box; float: none; justify-items: stretch;
}
.ksa-chart-grid > * { min-width: 0; }
.ksa-chart-grid .ksa-chart-panel { margin-bottom: 0; }
.ksa-chart-panel {
  padding: 16px 18px;
  border-radius: 14px;
}
.ksa-chart-box { height: 280px; position: relative; }
.ksa-chart-box--tall { height: 360px; }
.ksa-chart-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  height: 100%;
  min-height: 200px;
  text-align: center;
  font-size: 13px;
  line-height: 1.6;
  opacity: .7;
}
/* A chart that spans the full width of the grid (funnels, long county lists). */
.ksa-chart-grid .ksa-chart-span { grid-column: 1 / -1; }

@media print {
  .ksa-chart-grid { grid-template-columns: 1fr 1fr; gap: 10px; }
  .ksa-chart-panel { page-break-inside: avoid; }
  .ksa-chart-box { height: 240px; }
}
