/* =============================================================================
   BIZHEART — AURORA
   bizheart-aurora.css

   Version:  0.1.0  (pilot)
   Date:     September 2026
   Status:   Pilot — Sales Staff app only

   What this is:
     The Aurora redesign, applied as a layer ON TOP of bizcore.css. It is linked
     only from emxml_siteSalesStaff.xml, so every other app is untouched and
     still looks exactly as it did.

   Why a layer and not a rewrite:
     bizcore.css has 1,107 var() references against ~100 design tokens. Almost
     all of the look therefore comes from the token values rather than from the
     rules. Redefining the tokens moves the whole app at once, and only the
     handful of components whose STRUCTURE changes need a rule of their own.
     That keeps this file small enough to read, and means nothing can go
     unstyled — anything not named here still gets its bizcore.css rule, only
     with Aurora's colours, radii and type.

   Load order (in the site file's <links>):
     1. bizcore.css            — structure and every component
     2. bizheart-icons.css     — Lucide icon mapping
     3. bizheart-aurora.css    — THIS FILE, last so it wins

   Table of contents:
     1.  Type
     2.  Tokens — light
     3.  Tokens — dark
     4.  Base
     5.  Shell — header
     6.  Shell — sidebar
     7.  Shell — footer
     8.  Page container
     9.  Buttons
     10. Badges
     11. Form controls
     12. Tables
     13. Cards and panels
     14. KPI cards
     15. Tabs
     16. Modals
     17. Lists, feeds and split panes
     18. Responsive
     19. Accessibility
============================================================================= */


/* =============================================================================
   1. TYPE
   The face is loaded by a <link> in the site file, not @import, so it does not
   block the first paint.
============================================================================= */

:root {
  --aurora-sans: "Plus Jakarta Sans", "Segoe UI", system-ui, -apple-system, sans-serif;
}


/* =============================================================================
   2. TOKENS — LIGHT
   Every value bizcore.css already reads. Nothing here is new vocabulary.
============================================================================= */

:root {

  /* ── Brand ramp — indigo rather than the old Meridian blue ─────────────── */
  --brand-900: #2B2A75;
  --brand-800: #3730A3;
  --brand-700: #4338CA;
  --brand-600: #4F46E5;
  --brand-500: #4F46E5;
  --brand-400: #6366F1;
  --brand-300: #A5A0F5;
  --brand-100: #E0DEFB;
  --brand-50:  #EEEDFD;

  --c-primary:        #4F46E5;
  --c-primary-hover:  #3730A3;
  --c-primary-light:  #EEEDFD;
  --c-primary-xlight: #F7F7FE;
  --color-primary:    #4F46E5;

  /* ── Neutrals — cooler and slightly violet, so they sit with the indigo ── */
  --slate-600: #545A76;
  --slate-500: #6E7490;
  --slate-400: #8A90AB;
  --slate-200: #E6E7F2;
  --slate-100: #EFF0F7;
  --slate-50:  #F5F6FB;

  --neutral-900: #1A1E33;
  --neutral-700: #3A3F58;
  --neutral-500: #6E7490;
  --neutral-400: #8A90AB;
  --neutral-200: #E6E7F2;
  --neutral-100: #EFF0F7;
  --neutral-50:  #F5F6FB;
  /* NOT an ink colour despite the name — bizcore.css uses --neutral-1 as the tab
     bar track, the grey badge background and the ghost button hover. Setting it
     dark turns the tab bar black in light mode. */
  --neutral-1:   #EFF0F7;

  /* ── Semantic ──────────────────────────────────────────────────────────── */
  --success:     #0E9F6E;
  --success-bg:  #E4F6EF;
  --c-success:   #0E9F6E;
  --c-success-bg:#E4F6EF;

  --warning:     #B45309;
  --warning-bg:  #FDF0E0;
  --c-warning:   #B45309;
  --c-warning-bg:#FDF0E0;
  --color-warning:    #B45309;
  --color-warning-bg: #FDF0E0;
  --c-amber:     #D97706;

  --error:       #C2410C;
  --error-bg:    #FDECE6;
  --c-error:     #C2410C;
  --c-error-bg:  #FDECE6;

  --info:        #4F46E5;
  --info-bg:     #EEEDFD;
  --c-info:      #4F46E5;
  --c-info-bg:   #EEEDFD;

  --c-teal:       #0E7C66;
  --c-teal-dark:  #0B5F4E;
  --c-teal-light: #E3F3EF;
  --teal-700: #0B5F4E;
  --teal-600: #0E7C66;
  --teal-100: #E3F3EF;

  /* ── Shell ─────────────────────────────────────────────────────────────── */
  --header-bg:         #FFFFFF;   /* Aurora's header is white, not brand */
  --sidebar-bg:        #FFFFFF;
  --sidebar-border:    #E6E7F2;
  --page-bg:           #F5F6FB;
  --card-bg:           #FFFFFF;
  --card-border:       #E6E7F2;
  --surface:           #FFFFFF;
  --surface-raised:    #FFFFFF;
  --bg:                #F5F6FB;
  --bg-2:              #EFF0F7;

  --text-primary:   #1A1E33;
  --text-secondary: #3A3F58;
  --text-muted:     #6E7490;
  --text-1: #1A1E33;
  --text-2: #3A3F58;
  --text-3: #6E7490;

  --border:            #E6E7F2;
  --sp-border:         #E6E7F2;
  --row-stripe:        #FAFAFD;
  --stripe:            #FAFAFD;
  --active-nav-bg:     #EEEDFD;
  --active-nav-border: #4F46E5;

  --sp-ink:         #1A1E33;
  --sp-text-faint:  #8A90AB;
  --sp-accent:      #4F46E5;
  --sp-accent-ink:  #FFFFFF;
  --sp-good:        #0E9F6E;
  --sp-critical:    #C2410C;

  /* ── Elevation — softer, tinted towards the ink rather than pure black ─── */
  --shadow-1: 0 1px 2px rgba(20, 26, 51, .06);
  --shadow-2: 0 2px 6px rgba(20, 26, 51, .08), 0 8px 24px -12px rgba(20, 26, 51, .18);
  --shadow-3: 0 2px 6px rgba(20, 26, 51, .10), 0 24px 56px -14px rgba(20, 26, 51, .34);
  --sh1: 0 1px 2px rgba(20, 26, 51, .06);
  --sh2: 0 2px 6px rgba(20, 26, 51, .08), 0 8px 24px -12px rgba(20, 26, 51, .18);

  /* ── Radius — the single biggest change in feel ─────────────────────────── */
  --radius-sm: 8px;
  --radius:    10px;
  --radius-md: 12px;
  --radius-lg: 16px;
  --radius-xl: 22px;

  --transition:      140ms cubic-bezier(.2, 0, .2, 1);
  --transition-slow: 240ms cubic-bezier(.2, 0, .2, 1);

  --font-heading: var(--aurora-sans);
}


/* =============================================================================
   3. TOKENS — DARK
   bizcore.css already switches on [data-theme="dark"]; these are the Aurora
   values for the same tokens, so the user's appearance setting keeps working.
============================================================================= */

[data-theme="dark"] {
  --header-bg:      #161B31;
  --sidebar-bg:     #12162A;
  --sidebar-border: #262C47;
  --page-bg:        #0E1224;
  --card-bg:        #161B31;
  --card-border:    #262C47;
  --surface:        #161B31;
  --surface-raised: #1C2240;
  --bg:             #0E1224;
  --bg-2:           #12162A;

  --text-primary:   #E8EAF4;
  --text-secondary: #B9BEDA;
  --text-muted:     #8A90AB;
  --text-1: #E8EAF4;
  --text-2: #B9BEDA;
  --text-3: #8A90AB;

  --border:      #262C47;
  --sp-border:   #262C47;
  --row-stripe:  #1A1F3A;
  --stripe:      #1A1F3A;

  --active-nav-bg:     #252A52;
  --active-nav-border: #A5A0F5;
  --neutral-1:         #1A1F3A;   /* tab bar track, dark */

  --brand-500: #7C79F0;
  --c-primary: #7C79F0;
  --c-primary-hover:  #9A97F5;
  --c-primary-light:  #252A52;
  --c-primary-xlight: #1C2240;

  --success:    #34D399;
  --success-bg: #123A2E;
  --warning:    #FBBF24;
  --warning-bg: #3A2A10;
  --error:      #FB8A5C;
  --error-bg:   #3B1D12;
  --c-success: #34D399; --c-success-bg: #123A2E;
  --c-warning: #FBBF24; --c-warning-bg: #3A2A10;
  --c-error:   #FB8A5C; --c-error-bg:   #3B1D12;
  --info: #7C79F0; --info-bg: #252A52;
  --c-info: #7C79F0; --c-info-bg: #252A52;

  --shadow-1: 0 1px 2px rgba(0, 0, 0, .40);
  --shadow-2: 0 2px 6px rgba(0, 0, 0, .45), 0 8px 24px -12px rgba(0, 0, 0, .60);
  --shadow-3: 0 2px 6px rgba(0, 0, 0, .50), 0 24px 56px -14px rgba(0, 0, 0, .70);
}


/* =============================================================================
   3b. ACCENT THEMES
   bizcore.css offers four accents from login_accounts.ui_theme, written to
   <html data-accent>. Those rules are `[data-accent="x"]`, the same specificity
   as `:root` — so Aurora's own :root, loading later, silently beat them and every
   accent came out indigo. `html[data-accent=...]` is one step more specific, which
   puts the user's choice back in charge.

   Aurora keeps the header white in every accent — the accent drives the primary
   colour, the active nav pill and the info tint instead of repainting the bar.
============================================================================= */

html[data-accent="teal"] {
  --brand-900: #0A4438; --brand-800: #0B5F4E; --brand-700: #0D6E5A;
  --brand-600: #0E7C66; --brand-500: #0E7C66; --brand-400: #14947B;
  --brand-300: #7FC9B8; --brand-100: #CDEBE3; --brand-50: #E3F3EF;
  --c-primary: #0E7C66; --c-primary-hover: #0B5F4E;
  --c-primary-light: #E3F3EF; --c-primary-xlight: #F4FAF8;
  --color-primary: #0E7C66;
  --info: #0E7C66; --info-bg: #E3F3EF; --c-info: #0E7C66; --c-info-bg: #E3F3EF;
  --active-nav-bg: #E3F3EF; --active-nav-border: #0E7C66;
  --sp-accent: #0E7C66;
}

html[data-accent="heart"] {
  --brand-900: #7C2D12; --brand-800: #9A3412; --brand-700: #AB3D12;
  --brand-600: #C2410C; --brand-500: #C2410C; --brand-400: #DA4A1C;
  --brand-300: #F0A184; --brand-100: #FBDACD; --brand-50: #FDECE6;
  --c-primary: #C2410C; --c-primary-hover: #9A3412;
  --c-primary-light: #FDECE6; --c-primary-xlight: #FEF7F4;
  --color-primary: #C2410C;
  --info: #C2410C; --info-bg: #FDECE6; --c-info: #C2410C; --c-info-bg: #FDECE6;
  --active-nav-bg: #FDECE6; --active-nav-border: #C2410C;
  --sp-accent: #C2410C;
}

html[data-accent="violet"] {
  --brand-900: #4C1D95; --brand-800: #5B21B6; --brand-700: #6D28D9;
  --brand-600: #7C3AED; --brand-500: #7C3AED; --brand-400: #8B5CF6;
  --brand-300: #C4B5FD; --brand-100: #E7DEFB; --brand-50: #F3EEFE;
  --c-primary: #7C3AED; --c-primary-hover: #5B21B6;
  --c-primary-light: #F3EEFE; --c-primary-xlight: #FAF7FE;
  --color-primary: #7C3AED;
  --info: #7C3AED; --info-bg: #F3EEFE; --c-info: #7C3AED; --c-info-bg: #F3EEFE;
  --active-nav-bg: #F3EEFE; --active-nav-border: #7C3AED;
  --sp-accent: #7C3AED;
}

html[data-accent="graphite"] {
  --brand-900: #1A1E33; --brand-800: #2B3148; --brand-700: #3A4059;
  --brand-600: #475569; --brand-500: #475569; --brand-400: #64748B;
  --brand-300: #B2B8C8; --brand-100: #DDE0E8; --brand-50: #EEF0F3;
  --c-primary: #475569; --c-primary-hover: #2B3148;
  --c-primary-light: #EEF0F3; --c-primary-xlight: #F7F8FA;
  --color-primary: #475569;
  --info: #475569; --info-bg: #EEF0F3; --c-info: #475569; --c-info-bg: #EEF0F3;
  --active-nav-bg: #EEF0F3; --active-nav-border: #475569;
  --sp-accent: #475569;
}

/* The picker's own dots are painted from the old palette in bizcore.css, so the
   "Bizheart Blue" swatch showed #1E40AF while choosing it applied Aurora's indigo.
   Repaint each dot with the colour it actually produces. */
.appearance-swatch[data-choice="blue"]     { --swatch: #4F46E5; }
.appearance-swatch[data-choice="teal"]     { --swatch: #0E7C66; }
.appearance-swatch[data-choice="heart"]    { --swatch: #C2410C; }
.appearance-swatch[data-choice="violet"]   { --swatch: #7C3AED; }
.appearance-swatch[data-choice="graphite"] { --swatch: #475569; }

/* Dark mode keeps the accent but lifts it off the dark ground */
[data-theme="dark"][data-accent="teal"]     { --c-primary: #3FBFA2; --c-primary-light: #123A33; --brand-500: #3FBFA2; }
[data-theme="dark"][data-accent="heart"]    { --c-primary: #F1794A; --c-primary-light: #3B1D12; --brand-500: #F1794A; }
[data-theme="dark"][data-accent="violet"]   { --c-primary: #A78BFA; --c-primary-light: #2B1E52; --brand-500: #A78BFA; }
[data-theme="dark"][data-accent="graphite"] { --c-primary: #94A3B8; --c-primary-light: #262C47; --brand-500: #94A3B8; }


/* =============================================================================
   4. BASE
============================================================================= */

body {
  font-family: var(--aurora-sans);
  -webkit-font-smoothing: antialiased;
  background: var(--page-bg);
  color: var(--text-primary);
}

h1, h2, h3, h4, .pg-title, .card-title, .ct, .modal-title {
  font-family: var(--aurora-sans);
  letter-spacing: -.02em;
}

/* Figures line up in columns and read as one number, not as digits */
.num,
.data-table td,
.dt td,
.lt td,
.kpi-val,
.fv {
  font-variant-numeric: tabular-nums;
}


/* =============================================================================
   5. SHELL — HEADER
   The one place bizcore.css assumes a dark brand bar, so every child that
   inherited white text needs its Aurora colour stating.
============================================================================= */

.header {
  background: var(--header-bg);
  border-bottom: 1px solid var(--border);
  box-shadow: none;
}

.header .logo-text {
  color: var(--text-primary);
  font-weight: 800;
  letter-spacing: -.02em;
}

.header-btn,
.header-hamburger {
  color: var(--text-secondary);
  border-radius: var(--radius-sm);
}

.header-btn:hover,
.header-hamburger:hover {
  background: var(--bg-2);
  color: var(--text-primary);
}

.header-hamburger .bar { background: var(--text-secondary); }

.header-search__input {
  background: var(--bg-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-xl);
  color: var(--text-primary);
}

.header-search__input:focus {
  background: var(--card-bg);
  border-color: var(--c-primary);
  outline: 2px solid var(--c-primary-light);
}

.header-search__panel {
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-2);
  border: 1px solid var(--border);
}

.header-search__icon { color: var(--text-muted); }

/* Module app links in the header. The permanent app rail replaces these in
   phase two; until then they simply stop looking like a navbar. */
.header-nav-item {
  color: var(--text-secondary);
  border-radius: var(--radius-xl);
  font-weight: 600;
}

.header-nav-item:hover { background: var(--bg-2); color: var(--text-primary); }
.header-nav-item.active { background: var(--c-primary-light); color: var(--brand-800); }

.app-switch,
.header-portal-type {
  color: var(--c-primary);
  font-weight: 700;
}

.header-company { color: var(--text-secondary); }

.user-menu {
  border: 1px solid var(--border);
  border-radius: var(--radius-xl);
  background: var(--card-bg);
}

.user-menu:hover { border-color: var(--slate-400); }
.user-name { color: var(--text-primary); font-weight: 600; }

.user-avatar {
  background: var(--text-primary);
  color: #FFFFFF;
  font-weight: 700;
  border-radius: var(--radius-xl);
}

.notif-badge {
  background: #DA4A1C;   /* the brand mark's own orange, so it always cuts through */
  color: #FFFFFF;
  font-weight: 700;
  border-radius: 10px;
}

.dropdown-menu {
  border-radius: var(--radius-lg);
  border: 1px solid var(--border);
  box-shadow: var(--shadow-2);
  padding: 6px;
}

.dropdown-item { border-radius: var(--radius-sm); }
.dropdown-item:hover { background: var(--bg-2); }
.dropdown-item--danger { color: var(--c-error); }
.dropdown-divider { background: var(--border); }
.dropdown-username { color: var(--text-primary); font-weight: 700; }
.dropdown-userrole { color: var(--text-muted); }

.appearance-swatch { border-radius: var(--radius-xl); }
.appearance-mode  { border-radius: var(--radius-sm); }


/* =============================================================================
   6. SHELL — SIDEBAR
============================================================================= */

.sidebar {
  background: var(--sidebar-bg);
  border-right: 1px solid var(--sidebar-border);
}

.sidebar-section {
  font-size: 9.5px;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--text-muted);
  font-weight: 700;
}

.nav-item {
  border-radius: var(--radius-sm);
  margin: 1px 10px;
  border-left: 0;                 /* Aurora marks the active item with a pill */
  color: var(--text-secondary);
  font-weight: 500;
  transition: background var(--transition), color var(--transition);
}

.nav-item:hover { background: var(--bg-2); color: var(--text-primary); }

.nav-item.active,
.nav-item.on {
  background: var(--active-nav-bg);
  color: var(--brand-800);
  font-weight: 700;
  border-left: 0;
}

.nav-icon { opacity: 1; }


/* =============================================================================
   7. SHELL — FOOTER
============================================================================= */

.footer {
  background: var(--card-bg);
  border-top: 1px solid var(--border);
  color: var(--text-muted);
  font-size: 11.5px;
}

.footer a { color: var(--text-secondary); font-weight: 600; text-decoration: none; }
.footer a:hover { color: var(--text-primary); }


/* =============================================================================
   8. PAGE CONTAINER
============================================================================= */

/* Page padding was coming from three places at once:
     .main      16px on phones, 24px 48px above 1281px  (bizcore.css)
     .pg-body   20px 24px                               (bizcore.css)
     #page1a    0 20px 20px, inline in most modules
   Aurora keeps it in one place — .pg-body — and keeps it small. */
.main { padding: 0; }
.pg-body { padding: 10px 12px; }

@media (min-width: 1281px) {
  .main { padding: 0; }          /* beats bizcore's 24px 48px on wide screens */
}

/* page1a carries an inline padding of 0 20px 20px in most modules, so it can only
   be overridden with !important. Removing the side padding lines the tab bar and
   the panels up with the page header above them. */
#page1a { padding: 0 0 16px !important; }

.pg-hdr {
  border-bottom: 1px solid var(--border);
  border-radius: var(--radius-lg) var(--radius-lg) 0 0;
  padding: 14px 18px;
}

/* A row of figures above a list (PT1's invoice page). .cards already lays them out; this
   only gives the row its gap under the heading and lets one card carry a warning colour
   without becoming a different kind of card. */
.bh-countrow { margin-bottom: var(--space-4, 16px); }

.bh-count--warn {
  background: var(--c-warning-bg, #FDF3EE);
  border-color: var(--c-warning, #F3C4AE);
}
.bh-count--warn .kpi,
.bh-count--warn .text-sm { color: var(--c-warning, #9A3412); }

/* SETTINGS: AN INDEX, AND ONE SECTION AT A TIME (the S2 artboard, 27 Sep 2026).

   Left, the sections of the page under their own headings; right, the one you picked.
   The panes are one form shown and hidden, not separate pages, so Save posts every field
   whichever section is open - which is why the index is a .tbar driven by bcTabPanes
   rather than anything new. */
.bh-setpage {
  display: grid;
  grid-template-columns: 216px minmax(0, 1fr);
  align-items: stretch;
}

.bh-setindex {
  border-right: 1px solid var(--border);
  padding: 14px 10px;
  background: var(--row-stripe, transparent);
}

/* The index is a tab bar in everything but looks: a column, no strip, no underline. */
.bh-setindex .tbar {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-height: 0;
  border: 0;
  padding: 0;
  background: none;
}

/* The entries are .tb, because bcTabPanes finds its buttons by that class and rewrites
   className as it switches - an .ix class would be wiped on the first click and the
   highlight would never move. The index look comes from the bar around them. */
.bh-setindex .tb {
  display: block;
  width: 100%;
  text-align: left;
  padding: 9px 12px;
  border: 0;
  border-radius: 9px;
  background: transparent;
  font-family: inherit;
  font-size: 13px;
  font-weight: 500;
  color: var(--text-secondary);
  cursor: pointer;
}
.bh-setindex .tb:hover { background: var(--slate-100); color: var(--text-primary); }
.bh-setindex .tb.on {
  background: var(--active-nav-bg);
  color: var(--active-nav-border);
  font-weight: 700;
}

.bh-setindex__rule { border-top: 1px solid var(--border); margin: 10px 4px; }
.bh-setindex__group {
  margin: 0 12px 6px;
  font-size: 10.5px;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--text-muted);
  font-weight: 700;
}

.bh-setbody { padding: 18px 20px 0; min-width: 0; }
.bh-setbody .table td { padding: 8px 0; vertical-align: top; }
.bh-setbody .table td:last-child { padding-left: 16px; }

/* One per editable section, at its foot and sticky to the bottom of the pane. It saves
   the whole form, not just that section - but it belongs to a section, which is why the
   reference list has none. */
.bh-setsave {
  position: sticky;
  bottom: 0;
  margin: 16px -20px 0;
  padding: 12px 20px;
  border-top: 1px solid var(--border);
  background: var(--card-bg);
  text-align: right;
}

@media (max-width: 900px) {
  /* Stacked: the index becomes a row of chips above the section it chooses. */
  .bh-setpage { grid-template-columns: minmax(0, 1fr); }
  .bh-setindex {
    border-right: 0;
    border-bottom: 1px solid var(--border);
    padding: 10px;
  }
  .bh-setindex .tbar { flex-direction: row; flex-wrap: wrap; }
  .bh-setindex .tb { width: auto; }
  .bh-setindex__rule { display: none; }
  .bh-setindex__group { margin: 0 8px; align-self: center; }
}

/* A1: THE SIGN-IN SPLIT SCREEN (Khalid, 27 Sep 2026).

   A dark panel that says what this is, and the form beside it. The panel is chrome - it
   is in the site layout, so the sign-in, the emailed code, forgot password and set
   password all get it and none of them carries its own logo or footer any more.

   On a phone the panel goes entirely rather than stacking: somebody signing in on their
   phone does not need to be sold the product, and a screen of pitch above the password
   box is a screen to scroll past. */
.bh-auth {
  min-height: 100vh;
  min-height: 100dvh;
  display: grid;
  grid-template-columns: minmax(0, 540px) minmax(0, 1fr);
  background: var(--card-bg);
}

.bh-auth__brand {
  background: #141A33;
  color: #FFFFFF;
  padding: 48px 52px;
  display: flex;
  flex-direction: column;
  gap: 40px;
}

.bh-auth__mark { display: flex; align-items: center; gap: 11px; }
.bh-auth__mark span { font-size: 21px; font-weight: 800; letter-spacing: -.02em; }

.bh-auth__pitch { flex: 1 1 auto; display: flex; flex-direction: column; justify-content: center; }
.bh-auth__pitch h1 {
  margin: 0;
  font-size: 34px;
  font-weight: 800;
  letter-spacing: -.035em;
  line-height: 1.2;
  max-width: 11ch;
}
.bh-auth__pitch p {
  margin: 16px 0 32px;
  font-size: 14.5px;
  line-height: 1.6;
  max-width: 44ch;
  color: #A5ABC9;
}

.bh-auth__points { margin: 0; padding: 0; list-style: none; display: flex; flex-direction: column; gap: 13px; }
.bh-auth__points li {
  display: flex;
  align-items: center;
  gap: 11px;
  font-size: 13.5px;
  color: #C7C9E8;
}
/* The tick is drawn rather than written, so the list needs no markup per row. */
.bh-auth__points li::before {
  content: "";
  flex: 0 0 auto;
  width: 17px;
  height: 17px;
  background: var(--brand-500, #4F46E5);
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.4' stroke-linecap='round'%3E%3Cpath d='m5 12.5 4.5 4.5L19 7'/%3E%3C/svg%3E") center / contain no-repeat;
          mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.4' stroke-linecap='round'%3E%3Cpath d='m5 12.5 4.5 4.5L19 7'/%3E%3C/svg%3E") center / contain no-repeat;
}

.bh-auth__legal { margin: 0; font-size: 11.5px; color: #6B739B; }
.bh-auth__legal a { color: inherit; font-weight: 600; text-decoration: none; }
.bh-auth__legal a:hover { color: #FFFFFF; }

.bh-auth__pane {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 40px 24px;
  min-width: 0;
}
.bh-auth__card { width: 100%; max-width: 380px; }

.bh-auth__title { margin: 0; font-size: 26px; font-weight: 800; letter-spacing: -.03em; }
.bh-auth__sub { margin: 7px 0 28px; font-size: 13.5px; color: var(--text-muted); }

/* The form itself: taller boxes than a record form, because this is the one screen where
   the fields ARE the page. */
.bh-auth__card .form-group { margin-bottom: 16px; }
.bh-auth__card label { display: block; font-size: 12.5px; font-weight: 700; margin-bottom: 7px; }
.bh-auth__card .form-control { height: 46px; border-radius: 10px; font-size: 14px; }
.bh-auth__card .btn-p { height: 48px; border-radius: 10px; font-size: 14.5px; font-weight: 700; }

/* A2: THE CODE STEP, AND THE PASSWORD PAGES (Khalid, 27 Sep 2026).

   Not the split: a card in the middle of a quiet page, with the mark above it and the
   legal line below. A1 is the door and has room to say what the product is; by the time
   somebody is entering a code they are already through it, and a panel of pitch beside
   the box would be in the way.

   Same markup as A1 - the shell does not know which page it is showing. A block that
   wants this shape says so by drawing a .bh-authcard, and the brand panel dissolves into
   the three rows around it. */
.bh-auth:has(.bh-authcard) {
  grid-template-columns: minmax(0, 1fr);
  grid-template-rows: auto minmax(0, 1fr) auto;
  background: var(--page-bg);
  gap: 22px;
}
.bh-auth:has(.bh-authcard) .bh-auth__brand { display: contents; }
.bh-auth:has(.bh-authcard) .bh-auth__pitch { display: none; }

.bh-auth:has(.bh-authcard) .bh-auth__mark {
  grid-row: 1;
  justify-self: center;
  padding: 40px 24px 0;
  color: var(--text-primary);
}
.bh-auth:has(.bh-authcard) .bh-auth__pane { grid-row: 2; padding: 0 24px; }
.bh-auth:has(.bh-authcard) .bh-auth__legal {
  grid-row: 3;
  justify-self: center;
  padding: 0 24px 40px;
  color: var(--text-muted);
}
.bh-auth:has(.bh-authcard) .bh-auth__legal a:hover { color: var(--text-primary); }
.bh-auth:has(.bh-authcard) .bh-auth__card { max-width: 430px; }

.bh-authcard {
  background: var(--card-bg);
  border-radius: 18px;
  box-shadow: 0 2px 4px rgba(20, 26, 51, .05), 0 20px 48px -16px rgba(20, 26, 51, .25);
  padding: 34px 36px;
}

/* The chip above the heading says what kind of page this is without a word. */
.bh-authcard__icon {
  width: 46px;
  height: 46px;
  border-radius: 14px;
  background: var(--active-nav-bg);
  color: var(--brand-500);
  display: flex;
  align-items: center;
  justify-content: center;
  margin-bottom: 18px;
  font-size: 20px;
}

/* SIX BOXES, ONE VALUE. The boxes are for the person; the form still posts one bh_code,
   because the processor and the emailed code are both six digits in a row and neither
   should have to know how the screen collected them. */
.bh-code {
  display: flex;
  gap: 9px;
  border: 0;
  padding: 0;
  margin: 0 0 20px;
}
.bh-code legend {
  font-size: 12.5px;
  font-weight: 700;
  color: var(--text-secondary);
  padding: 0 0 9px;
}
.bh-code input {
  width: 52px;
  height: 60px;
  min-width: 0;
  flex: 1 1 0;
  border: 1px solid var(--input-border, var(--border));
  border-radius: 11px;
  background: var(--card-bg);
  text-align: center;
  font-size: 24px;
  font-weight: 800;
  color: var(--text-primary);
  font-family: inherit;
}
.bh-code input:focus {
  border-color: var(--brand-500);
  outline: 2px solid var(--active-nav-bg);
}

/* Trust this device. A checkbox that sets a second factor aside deserves to read as a
   sentence rather than as a form field, so the whole line is the target. */
.bh-trust {
  display: flex;
  align-items: center;
  gap: 9px;
  margin-bottom: 22px;
  font-size: 13px;
  color: var(--text-secondary);
  cursor: pointer;
}
.bh-trust input { width: 16px; height: 16px; flex: 0 0 auto; }

/* Resend on one side, start again on the other: two different sizes of decision. */
.bh-authcard__foot {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: 20px;
  font-size: 12.5px;
}
.bh-authcard__foot a { font-weight: 700; text-decoration: none; }
.bh-authcard__foot a:last-child { margin-left: auto; color: var(--text-muted); }
/* "in 42 seconds" sits with the link it is about, not at the other end of the row. */
.bh-authcard__foot span { color: var(--text-muted); }

@media (max-width: 560px) {
  .bh-authcard { padding: 26px 20px; }
  .bh-code { gap: 6px; }
  .bh-code input { height: 54px; font-size: 20px; }
}

@media (max-width: 900px) {
  .bh-auth { grid-template-columns: minmax(0, 1fr); }
  /* A1 only: an A2 page has no panel to hide, and its mark is the page's only one. */
  .bh-auth:not(:has(.bh-authcard)) .bh-auth__brand { display: none; }
  /* The mark has to come back somewhere, or the page says nothing about whose it is. */
  .bh-auth:not(:has(.bh-authcard)) .bh-auth__card::before {
    content: "Bizheart";
    display: block;
    margin-bottom: 22px;
    font-size: 21px;
    font-weight: 800;
    letter-spacing: -.02em;
    color: var(--text-primary);
  }
}

/* THE PAGE IS ONE CARD (Khalid, 27 Sep 2026).

   .pg-hdr is already drawn as the top of a card - a hairline under it and rounded top
   corners. The split below it then drew its own top corners and its own top border
   against that hairline, so a page read as a heading card with a second card tucked
   under it, and on the pages with a tab strip between them the split's border cut across
   the tabs.

   Only when the split really is the next thing on the page: a split with something else
   above it keeps its own top. */
.pg-hdr + #page1a > .bh-split,
.pg-hdr + #page1a > .bh-split__wrap > .bh-split,
.pg-hdr + div:not([class]) > .bh-split,
.pg-hdr + .tbar + #page1a > .bh-split {
  border-top: 0;
  border-top-left-radius: 0;
  border-top-right-radius: 0;
}

/* A tab strip between the heading and the split is part of the same card: it keeps the
   sides, loses any rounding, and the hairline under it belongs to the split below.

   flex: 0 0 auto is the important one. A page with a split open turns every wrapper down
   to the split into a flex column so the rail can scroll inside it, and a flex item
   shrinks by default - so the tab strip was squeezed shorter than its own tabs, which
   clipped the underline off the open one and pushed the row hard against the card's top
   edge (Khalid, 27 Sep 2026). It sizes to its tabs and the split takes what is left. */
.pg-hdr + .tbar:has(~ #page1a > .bh-split) {
  flex: 0 0 auto;
  border-left: 1px solid var(--border);
  border-right: 1px solid var(--border);
  border-radius: 0;
  background: var(--card-bg);
  margin: 0;
  /* min-height, not padding: the modules set padding inline on this strip, and an inline
     style wins. The tabs sit on the bottom edge so the open one's underline lands on the
     hairline, with the room above coming from the strip itself. */
  min-height: 42px;
  align-items: flex-end;
}

.pg-title {
  font-size: 23px;
  font-weight: 800;
  letter-spacing: -.025em;
  color: var(--text-primary);
}

.a-bar { gap: var(--space-2); }

.breadcrumb, .bc { color: var(--text-muted); font-size: 12px; }
.breadcrumb a, .bc a { color: var(--text-muted); text-decoration: none; }
.breadcrumb a:hover, .bc a:hover { color: var(--text-primary); }


/* =============================================================================
   9. BUTTONS
============================================================================= */

.btn {
  border-radius: var(--radius-sm);
  font-family: var(--aurora-sans);
  font-weight: 700;
  letter-spacing: 0;
  transition: background var(--transition), border-color var(--transition), color var(--transition);
}

.btn-p, .btn-primary {
  background: var(--c-primary);
  border-color: var(--c-primary);
  color: #FFFFFF;
  box-shadow: none;
}

.btn-p:hover, .btn-primary:hover {
  background: var(--c-primary-hover);
  border-color: var(--c-primary-hover);
}

.btn-g, .btn-ghost {
  background: var(--card-bg);
  border: 1px solid var(--border);
  color: var(--text-secondary);
  font-weight: 600;
}

.btn-g:hover, .btn-ghost:hover {
  border-color: var(--slate-400);
  background: var(--card-bg);
  color: var(--text-primary);
}

.btn-s, .btn-success { background: var(--success); border-color: var(--success); color: #FFFFFF; }
.btn-d, .btn-danger  { background: var(--c-error); border-color: var(--c-error); color: #FFFFFF; }

.btn-sm { border-radius: var(--radius-sm); font-size: 12.5px; }

.btn:focus-visible,
.nav-item:focus-visible,
.header-btn:focus-visible {
  outline: 2px solid var(--c-primary);
  outline-offset: 2px;
}


/* =============================================================================
   10. BADGES
============================================================================= */

.bd, .badge {
  border-radius: var(--radius-xl);
  font-weight: 700;
  font-size: 11.5px;
  letter-spacing: 0;
  padding: 3px 9px;
}

.bd-b, .badge-blue   { background: var(--c-info-bg);    color: var(--brand-800); }
.bd-g, .badge-green  { background: var(--c-success-bg); color: #065F46; }
.bd-a, .badge-amber  { background: var(--c-warning-bg); color: #8A4321; }
.bd-r, .badge-red    { background: var(--c-error-bg);   color: #9A3412; }
.bd-t, .badge-teal   { background: var(--c-teal-light); color: var(--c-teal-dark); }
.bd-n, .badge-grey   { background: var(--bg-2);         color: var(--text-secondary); }

[data-theme="dark"] .bd-g { color: #6EE7B7; }
[data-theme="dark"] .bd-a { color: #FCD34D; }
[data-theme="dark"] .bd-r { color: #FCA5A5; }
[data-theme="dark"] .bd-b { color: #C7C4FA; }


/* =============================================================================
   11. FORM CONTROLS
============================================================================= */

.form-input,
.form-select,
.form-textarea,
.form-control,
input[type="text"],
input[type="email"],
input[type="password"],
input[type="search"],
input[type="date"],
input[type="number"],
select,
textarea {
  border: 1px solid #D9DBEB;
  border-radius: var(--radius-sm);
  background: var(--card-bg);
  color: var(--text-primary);
  font-family: var(--aurora-sans);
  transition: border-color var(--transition), box-shadow var(--transition);
}

.form-input:focus,
.form-select:focus,
.form-textarea:focus,
.form-control:focus,
input:focus,
select:focus,
textarea:focus {
  border-color: var(--c-primary);
  outline: 2px solid var(--c-primary-light);
  outline-offset: 0;
}

.form-input::placeholder,
.form-textarea::placeholder,
input::placeholder,
textarea::placeholder { color: var(--slate-400); }

[data-theme="dark"] .form-input,
[data-theme="dark"] .form-select,
[data-theme="dark"] .form-textarea,
[data-theme="dark"] .form-control,
[data-theme="dark"] input,
[data-theme="dark"] select,
[data-theme="dark"] textarea { border-color: #333A5C; }

label { color: var(--text-secondary); font-weight: 700; }


/* =============================================================================
   12. TABLES
============================================================================= */

.table-wrap {
  border-radius: var(--radius-md);
  border: 1px solid var(--border);
  /* overflow-x, not overflow: this was `hidden`, which is what bizcore.css sets
     overflow-x: auto FOR - a table wider than the page. Narrow the window and the
     last columns were simply cut off with no way to reach them (Khalid, 27 Sep 2026).
     The box still clips to the radius. */
  overflow-x: auto;
  background: var(--card-bg);
}

.data-table, .dt, .lt, .table {
  border-collapse: collapse;
  width: 100%;
}

.data-table th, .dt th, .lt th, .table th {
  background: var(--row-stripe);
  border-bottom: 1px solid var(--border);
  color: var(--text-muted);
  font-size: 10.5px;
  letter-spacing: .06em;
  text-transform: uppercase;
  font-weight: 700;
  text-align: left;
}

.data-table td, .dt td, .lt td, .table td {
  border-bottom: 1px solid var(--slate-100);
  color: var(--text-secondary);
  font-size: 13px;
}

.data-table tbody tr:hover,
.dt tbody tr:hover,
.lt tbody tr:hover { background: var(--c-primary-xlight); }

.data-table tbody tr:last-child td,
.dt tbody tr:last-child td,
.lt tbody tr:last-child td { border-bottom: 0; }

.table-empty {
  color: var(--text-muted);
  font-size: 13px;
  text-align: center;
  padding: var(--space-8) var(--space-4);
}


/* =============================================================================
   13. CARDS AND PANELS
============================================================================= */

/* bizcore.css gives every .card `animation: fadeInUp 300ms ease 200ms both`.
   The `both` fill mode holds the from-state during the delay, so a card is
   invisible for 200ms and then fades for 300ms - half a second of blank. On first
   page load that reads as an intro; on a tab switch it reads as the app being slow,
   because showing a hidden element restarts CSS animations. Panels that contain no
   .card (the My Quotes strip) appeared instantly, which is what gave it away.
   Aurora shows content immediately. */
.card,
.kpi-card { animation: none; }

.card, .dc, .panel {
  background: var(--card-bg);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-1);
}

.ch, .card-header, .dc-hdr {
  border-bottom: 1px solid var(--slate-100);
  background: transparent;
  border-radius: var(--radius-lg) var(--radius-lg) 0 0;
}

.ct, .card-title, .dc-hdr {
  font-size: 15px;
  font-weight: 700;
  color: var(--text-primary);
  letter-spacing: -.01em;
}

.cf, .card-footer {
  border-top: 1px solid var(--slate-100);
  background: var(--row-stripe);
  border-radius: 0 0 var(--radius-lg) var(--radius-lg);
}

/* A CARD BODY HAS A GUTTER (Khalid, 27 Sep 2026).

   bizcore.css gives .csb scrolling and no padding at all, so text in one sat hard
   against the card's left edge while the header above it was indented - Single Sign-On,
   Rules and External Interfaces all read as if the words had slipped out of the card.
   About ninety blocks had noticed and set their own padding inline; the rest had not.

   Written as a custom property rather than as a padding value, so that a rule with more
   of a claim on the body - a record pane, a dashboard row - still sets its own, and an
   inline padding on the block still wins outright.

   A body whose content is ONE full-width thing keeps its edges: a table brings its own
   cell padding and insetting it would put a double gutter down the first column, a
   notice feed and an empty state draw their own, and a strip of cards has its own gap. */
.csb { padding: var(--bh-csb-pad, 14px 20px); }
.csb:has(> .table-wrap),
.csb:has(> table),
.csb:has(> .bc-notice-feed),
.csb:has(> .bc-empty),
.csb:has(> .table-empty),
.csb:has(> .cards),
.csb:has(> .kpi-grid),
.csb:has(> .nf-list),
.csb:has(> .bc-cal-list) { --bh-csb-pad: 0; }

/* Field grids on detail screens */
.fl {
  font-size: 10.5px;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--text-muted);
  font-weight: 700;
}

.fv { font-size: 13.5px; font-weight: 600; color: var(--text-primary); }
.fv-lg { font-size: 19px; font-weight: 800; letter-spacing: -.02em; }

.detail-row { border-bottom: 1px solid var(--slate-100); }


/* =============================================================================
   14. KPI CARDS
============================================================================= */

.kpi {
  background: var(--card-bg);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  border-top: 1px solid var(--border);   /* Aurora drops the coloured top edge */
  box-shadow: var(--shadow-1);
}

.kpi-lbl {
  font-size: 12px;
  font-weight: 600;
  color: var(--text-muted);
  letter-spacing: 0;
  text-transform: none;
}

.kpi-val {
  font-size: 27px;
  font-weight: 800;
  letter-spacing: -.03em;
  color: var(--text-primary);
}

.kpi-ico { border-radius: var(--radius-md); }
.kpi-foot { font-size: 11.5px; color: var(--text-muted); }
.kpi-trend { font-weight: 700; }
.kpi-trend--up   { color: var(--success); }
.kpi-trend--down { color: var(--c-error); }

/* bizcore.css drives both the top stripe and the icon chip from two custom
   properties set per variant, hardcoded to the old Meridian colours. Overriding
   them here moves the KPI accents onto the Aurora palette in one place. */
.kpi--blue  { --kpi-accent: #4F46E5; --kpi-icon-bg: #EEEDFD; }
.kpi--teal  { --kpi-accent: #0E7C66; --kpi-icon-bg: #E3F3EF; }
.kpi--green { --kpi-accent: #0E9F6E; --kpi-icon-bg: #E4F6EF; }
.kpi--amber { --kpi-accent: #B45309; --kpi-icon-bg: #FDF0E0; }
.kpi--red   { --kpi-accent: #C2410C; --kpi-icon-bg: #FDECE6; }

/* The dashboard's KPI strip used four arbitrary hues - blue, amber, green, teal -
   one per card, which meant nothing and ignored the user's chosen accent. In this
   app they appear once each, only here, so they are decoration rather than signal.
   They now follow the accent, and the theme reaches the top of the dashboard.
   Red is left alone: a red KPI is saying something. */
/* The KPI row fills the width whatever it holds. bizcore fixes it at four columns, so a
   dashboard with three - the Manager's - left a quarter of the row empty and the cards
   stopped short of the edge. auto-fit collapses the tracks that have nothing in them, so
   three KPIs make three equal columns and four still make four (found 25 Sep 2026; it
   predates this redesign). */
.kpi-grid { grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); }

.kpi-grid .kpi {
  --kpi-accent: var(--c-primary);
  --kpi-icon-bg: var(--c-primary-light);
}
.kpi-grid .kpi--red {
  --kpi-accent: var(--c-error);
  --kpi-icon-bg: var(--c-error-bg);
}

/* Dashboard panels are a fixed 480px tall in bizcore.css, which leaves a lot of
   empty card when a panel has two rows in it. 360 is tighter without changing how
   the scrolling body works — .csb relies on the card having a definite height. */
.card--h-lg { height: 360px; }

/* Tabbed cards.
   .csb — the scrolling body — is `flex: 1; height: 0`, which only works inside a
   flex column that has a definite height. A tab pane is a plain block, so height:0
   does nothing but clip: the My Quotes buttons rendered as a few pixels of their top
   edge, and the Manager desk card's work feed held 5,204px of notices in a box 0px tall.
   Give each pane a definite height and make the chain flex all the way down, and .csb
   then fills the pane and scrolls properly. */
#dashTabPanes,
#taskTabPanes,
#mgrDeskPanes { min-height: 420px; }

#dashTabPanes > div,
#taskTabPanes > div,
#mgrDeskPanes > div {
  height: 420px;
  display: flex;
  flex-direction: column;
  min-height: 0;
}

/* The pane already sits inside a card, so the card it wraps loses its own edge */
#dashTabPanes > div > .card,
#taskTabPanes > div > .card,
#mgrDeskPanes > div > .card {
  display: flex;
  flex-direction: column;
  flex: 1;
  min-height: 0;
  margin: 0;
  border: 0;
  border-radius: 0;
  box-shadow: none;
}

#dashTabPanes .csb,
#taskTabPanes .csb { min-height: 0; }

/* The quote strip's buttons hold three lines each - label, count, value - but
   .btn is a flex ROW, so they came out side by side on one squashed line.
   Stack them and let the button size to its content. */
#paneTaskQuotes .btn {
  flex-direction: column;
  align-items: stretch;
  justify-content: center;
  height: auto;
  min-height: 64px;
  gap: 2px;
  line-height: 1.3;
}


/* =============================================================================
   15. TABS
============================================================================= */

/* Aurora's tabs are underlined, not pills, so the bizcore track behind them goes.
   The strip that wraps the tab bar supplies the surface instead. */
.tbar {
  background: transparent;
  padding: 0;
  border: 0;
  border-radius: 0;
  gap: 2px;
}

/* Modules wrap their tab bar in an unclassed div carrying the background and the
   bottom border. Treat that strip and the panel under it as one component: square
   top corners so it meets the page header cleanly, and no seam between the two.

   .bh-recstage is excluded because it matches this shape by accident - it is the lead's
   stage bar, a section INSIDE a record panel with the record's own gutter, not a page
   level tab strip. Without the exclusion this rule outranks the record gutter by one
   element and the stage bar sat 6px left of every other section. */
div:has(> .tbar):not(.ch):not(.bh-recstage) {
  padding: 6px 14px 0 !important;
  border: 1px solid var(--border);
  border-bottom: 0;
  border-radius: 0;
  background: var(--card-bg);
}

/* A tab bar used as a card header (the dashboard's tabbed panel) needs no border
   or background of its own — the card already provides both. */
.ch:has(> .tbar) {
  padding: 4px 12px 0;
  display: block;
}

div:has(> .tbar) + .card,
div:has(> .tbar) + .dc,
div:has(> .tbar) + .table-wrap {
  margin-top: 0;
  border-top: 0;
  border-top-left-radius: 0;
  border-top-right-radius: 0;
}

.tb {
  border: 0;
  background: transparent;
  border-bottom: 2px solid transparent;
  border-radius: 0;
  color: var(--text-muted);
  font-family: var(--aurora-sans);
  font-weight: 600;
  font-size: 13px;
}

.tb:hover { color: var(--text-primary); background: transparent; }

.tb.on, .tb.active {
  color: var(--c-primary);
  border-bottom-color: var(--c-primary);
  font-weight: 700;
  background: transparent;
}

.tc {
  background: var(--bg-2);
  color: var(--text-secondary);
  border-radius: 10px;
  font-size: 11px;
  font-weight: 700;
}

.tb.on .tc, .tb.active .tc { background: var(--c-primary-light); color: var(--brand-800); }


/* =============================================================================
   16. MODALS
============================================================================= */

.modal-overlay { background: rgba(20, 24, 44, .55); }

.modal {
  border-radius: var(--radius-lg);
  border: 0;
  box-shadow: var(--shadow-3);
}

.modal-header {
  border-bottom: 1px solid var(--slate-100);
  padding: 20px 24px 16px;
}

.modal-title {
  font-size: 18px;
  font-weight: 800;
  letter-spacing: -.02em;
  color: var(--text-primary);
}

.modal-close {
  border-radius: var(--radius-sm);
  color: var(--text-muted);
  background: transparent;
  border: 0;
}

.modal-close:hover { background: var(--bg-2); color: var(--text-primary); }

.modal-body { padding: 20px 24px; }

.modal-footer {
  border-top: 1px solid var(--slate-100);
  background: var(--row-stripe);
  border-radius: 0 0 var(--radius-lg) var(--radius-lg);
  padding: 16px 24px;
}


/* =============================================================================
   17. LISTS, FEEDS AND SPLIT PANES
============================================================================= */

/* =============================================================================
   LEADS SPLIT VIEW (P5)
   emxml_blkSalesLeadsSplit.xml composes the existing list and detail blocks side
   by side. The list block is unchanged, so it arrives at full width with eight
   columns - these rules narrow it to the ones that identify a lead. Everything
   hidden here is still present in the full-width list, one click away.
============================================================================= */

/* The height chain: each wrapper between the page shell and the split passes its height
   down, and only on a page that has a split. Without it the card is as tall as its
   contents and a three row queue leaves a stub floating on the page. */
/* ...and only while a record is OPEN. The chain ends in overflow: hidden, which is
   right for a rail that scrolls inside a card of page height, and wrong for everything
   else: with the record closed the list is a full-width table again, and it was cut off
   at the height the split used to be with no scrollbar on any of these (Khalid,
   27 Sep 2026). Closed, every wrapper goes back to growing and the PAGE scrolls. */
.main:has(.bh-split:not(.bh-split--closed)) {
  display: flex;
  flex-direction: column;
}
.pg-shell:has(.bh-split:not(.bh-split--closed)) {
  flex: 1 1 auto;
  min-height: 0;
}
.pg-body:has(.bh-split:not(.bh-split--closed)) {
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
#page1:has(.bh-split:not(.bh-split--closed)),
#page1a:has(.bh-split:not(.bh-split--closed)) {
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  flex-direction: column;
}

/* ONE card, per the R1 artboard - not two cards with a gap between them. The rail and
   the record are columns inside a single bordered, rounded box, separated by a hairline
   rather than by empty page. Built as two cards it looked like two unrelated panels, and
   with only three rows in the queue each one stopped where its content stopped, leaving
   short stubs floating on the page (Khalid, 25 Sep 2026).

   The card is the height of the page area whatever is in it, which is what stops the
   stub. The modules do not agree on what sits between .pg-shell and the split - Customer
   Service has .pg-body > #page1 > #page1a, Warehouse Pick & Pack has no .pg-body at all
   - so the rule below keys on the ids themselves with :has(), and each one only becomes
   a height-passing flex column when it actually contains a split. min-height is a floor
   for any module shaped differently again. */
/* Two readings side by side inside one card - the aged-balance pair on the Manager
   dashboard, the pipeline pair on the CRM report. Its own name, because both of those
   were written as .bh-split and inherited the record view's 420px floor, its 380px rail
   column and, worst, the height chain that stops the page scrolling (27 Sep 2026). */
.bh-pair {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 16px;
  align-items: start;
}

.bh-split {
  display: grid;
  grid-template-columns: minmax(0, 380px) minmax(0, 1fr);
  /* min-content, not 0: with a 0 minimum the record row collapsed to nothing whenever
     the rail was the shorter of the two, and the record rendered its card into a pane of
     zero height (27 Sep 2026). */
  grid-template-rows: auto minmax(min-content, 1fr);
  grid-template-areas:
    "tabs tabs"
    "list detail";
  flex: 1 1 auto;
  min-height: 420px;
  background: var(--card-bg);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg, 14px);
  overflow: hidden;
}

/* The hairline between the rail and the record, and the strip the tabs sit on. The
   border goes on whatever lands in the list area - see the grid-area rules below - so
   it is declared with them rather than here. */
/* Named past .bh-split so it beats div:has(> .tbar):not(.ch):not(.bh-recstage) further
   up, which is more specific than a plain .bh-split__list selector and sets
   border-bottom: 0 with a border on the other three sides. Inside the card the strip
   wants the opposite: no sides, and a line underneath. Its padding is !important there,
   so this restates it the same way. */
.bh-split .bh-split__list div:has(> .tbar):not(.ch) {
  grid-area: tabs;
  width: 100%;
  display: flex;
  align-items: center;
  border: 0;
  border-bottom: 1px solid var(--border);
  padding: 0 14px !important;
  background: none;
}

/* A primary action the list block carries (Warehouse's "Start picking ORD-0071") gets a
   strip of its own ABOVE the tabs. It used to be given grid-area: tabs along with the
   search bar, which put it straight on top of the tab bar and hid it completely. */
/* A primary action the list block carries (Warehouse's "Start picking ORD-0071") sits
   at the far end of the TAB ROW, not in a strip of its own. Given its own full width row
   it read as a banner across the page, and left a second empty row above the tabs.
   Both land in the same grid cell; the tabs are aligned to the start and this to the
   end, so they share the row without overlapping. */
.bh-split:not(.bh-split--closed) .bh-split__list > div > .a-bar,
.bh-split:not(.bh-split--closed) .bh-split__list > .a-bar {
  grid-area: tabs;
  justify-self: end;
  align-self: center;
  /* !important because the block sets margin-bottom inline (var(--space-4)). */
  margin: 0 !important;
  padding: 6px 14px;
  border: 0;
  background: none;
  display: flex;
  align-items: center;
  gap: 8px;
}

/* A list with no tabs at all - Customer Service customers, whose .a-bar IS its switcher
   - keeps that bar at the start of the row and the hairline under it. */
.bh-split:not(:has(.tbar)) .bh-split__list > div > .a-bar,
.bh-split:not(:has(.tbar)) .bh-split__list > .a-bar {
  justify-self: stretch;
  padding: 10px 14px;
  border-bottom: 1px solid var(--border);
}

/* The tab bar runs the full width ABOVE the split rather than being squeezed into the
   330px rail beside the record (Khalid, 25 Sep 2026). Quotes has seven status tabs and
   they simply did not fit - the bar was cut off mid-word and had to be scrolled, which
   is worse than no tabs at all. Lifting it means the switcher is always fully visible
   and the rail only has to carry the table.

   display:contents dissolves the list block's own wrappers so its two parts - the tab
   bar and the table - become grid items of the split itself, which is what lets them
   land in different rows. The parts are then placed by WHAT THEY ARE rather than by
   position, because the two list blocks are not shaped the same: Quotes wraps its table
   in an overflow-x div, Leads has the table as a direct child and a stage card between.
   A list block that changes shape later still lands correctly. */
.bh-split:not(.bh-split--closed) .bh-split__list,
.bh-split:not(.bh-split--closed) .bh-split__list > div { display: contents; }

/* One level deeper as well, for a list block that groups its parts in a plain <div>
   before the card - the bins list wraps everything below the "no location uses bins"
   notice so the whole group can be hidden with one token. That wrapper was a grid item
   of its own: it took the rail column in row ONE, and the record, placed in row two,
   opened underneath the list instead of beside it (Khalid, 27 Sep 2026).

   Classless only, and only a wrapper that holds nothing but other boxes. A div with a
   class is a real part of the page - a .card, a .cards strip, a .table-wrap - and
   dissolving those would scatter their children into the grid. The same goes for a
   classless div wrapping the table or the tab bar: THOSE are what the grid-area rules
   name, and display:contents makes a grid-area do nothing, so dissolving one dropped its
   table back into auto-placement and pushed the record a full list below the fold
   (Finance invoices, caught 27 Sep 2026).

   And because an inline style beats a stylesheet, a wrapper carrying style="display:none"
   from its token stays hidden. */
.bh-split:not(.bh-split--closed) .bh-split__list > div > div:not([class]):not(:has(> table)):not(:has(> .tbar)):not(:has(> .a-bar)) { display: contents; }

/* The location picker is how you choose which set of bins you are looking at, so it
   cannot go with the count cards - it stays, in the strip above the rail. */
.bh-split:not(.bh-split--closed) .bh-split__list .card:has(.bh-toolbar) {
  display: block;
  grid-area: tabs;
  margin: 0 !important;
  border: 0;
  border-bottom: 1px solid var(--border);
  border-radius: 0;
  background: none;
}
/* .csb's height is a flex BASIS, and this card is no longer a flex column, so the 0 lands
   as a real height and the picker spills out of a 17px strip. See bizcore.css. */
.bh-split:not(.bh-split--closed) .bh-split__list .card:has(.bh-toolbar) > .csb {
  padding: 8px 14px;
  height: auto;
  flex: none;
  overflow: visible;
}


/* Direct children only: the warehouse stock list puts its row buttons in a
   <td class="a-bar">, and a bare .a-bar would have named that too. The Customer Service
   customer search is an .a-bar as well and lands in the same strip, which is right - it
   is that list's switcher. */

/* Both table classes, because the list blocks do not agree on one: the sales lists are
   .lt and the message list is .data-table. Keyed on .lt alone, the message table was not
   placed at all - it landed in the tabs row by auto-placement and pushed the
   conversation into the row below, so the two columns started at different heights. */
.bh-split:not(.bh-split--closed) .bh-split__list div:has(> table.lt),
.bh-split:not(.bh-split--closed) .bh-split__list div:has(> table.data-table),
.bh-split:not(.bh-split--closed) .bh-split__list > div > table.lt,
.bh-split:not(.bh-split--closed) .bh-split__list > div > table.data-table,
.bh-split:not(.bh-split--closed) .bh-split__list > table.lt,
.bh-split:not(.bh-split--closed) .bh-split__list > table.data-table { grid-area: list; }

.bh-split__detail {
  grid-area: detail;
  overflow-x: hidden;
  overflow-y: auto;
}

/* THE RAIL IS A LIST OF CARDS, NOT A NARROW TABLE (Khalid, 25 Sep 2026; the R1 artboard
   shows it this way). Eight columns squeezed into 380px meant hiding most of them and
   still reading badly. As two lines per row - what it is, what it is worth, and a quiet
   line of detail under it - nothing has to be dropped to fit, and the rail stops looking
   like a table with its ends cut off.

   The table keeps its markup: only the display roles change, so the same block still
   renders as a full-width table when it is not in a split. Which cell is the title,
   which is the figure and which is the meta line is per page, further down. */
.bh-split:not(.bh-split--closed) .bh-split__list .lt,
.bh-split:not(.bh-split--closed) .bh-split__list .lt tbody,
.bh-split:not(.bh-split--closed) .bh-split__list .data-table,
.bh-split:not(.bh-split--closed) .bh-split__list .data-table tbody { display: block; }

.bh-split:not(.bh-split--closed) .bh-split__list .lt thead,
.bh-split:not(.bh-split--closed) .bh-split__list .data-table thead { display: none; }

.bh-split:not(.bh-split--closed) .bh-split__list .lt tbody tr,
.bh-split:not(.bh-split--closed) .bh-split__list .data-table tbody tr {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: baseline;
  column-gap: 10px;
  row-gap: 3px;
  padding: 11px 14px;
  border-bottom: 1px solid var(--border);
  border-left: 3px solid transparent;
}

.bh-split:not(.bh-split--closed) .bh-split__list .lt tbody td,
.bh-split:not(.bh-split--closed) .bh-split__list .data-table tbody td {
  display: block;
  padding: 0;
  border: 0;
  /* The table's zebra stripe is painted on the cells. In card mode the cells no longer
     fill the row, so the stripe showed as a grey slab floating beside the text instead
     of as a band. The cards are separated by hairlines, the way the artboard does it. */
  background: none;
  grid-column: 1 / -1;
  font-size: 11.5px;
  line-height: 1.35;
  color: var(--text-muted);
  white-space: normal;
}

/* Line one: the name, and the figure that belongs beside it. */
.bh-split:not(.bh-split--closed) .bh-split__list .bh-ttl {
  grid-column: 1;
  grid-row: 1;
  font-size: 13px;
  font-weight: 700;
  color: var(--text-primary);
}
.bh-split:not(.bh-split--closed) .bh-split__list .bh-fig {
  grid-column: 2;
  grid-row: 1;
  font-size: 13px;
  font-weight: 700;
  color: var(--text-primary);
  text-align: right;
  white-space: nowrap;
}
/* Line two, and anything after it. */
.bh-split:not(.bh-split--closed) .bh-split__list .bh-meta { grid-row: 2; }

/* The open row, marked on the left edge the way the artboard does it rather than by
   filling the whole row. */
.bh-split:not(.bh-split--closed) .bh-split__list .lt tbody tr.is-open,
.bh-split:not(.bh-split--closed) .bh-split__list .data-table tbody tr.is-open {
  background: var(--c-primary-xlight);
  border-left-color: var(--c-primary);
}
.bh-split:not(.bh-split--closed) .bh-split__list .lt tbody tr:nth-child(even),
.bh-split:not(.bh-split--closed) .bh-split__list .data-table tbody tr:nth-child(even) { background: none; }

/* The hairline between rail and record. It goes on the element that lands in the list
   area, which the grid-area rules above name. */
.bh-split:not(.bh-split--closed) .bh-split__list div:has(> table.lt),
.bh-split:not(.bh-split--closed) .bh-split__list div:has(> table.data-table),
.bh-split:not(.bh-split--closed) .bh-split__list > div > table.lt,
.bh-split:not(.bh-split--closed) .bh-split__list > div > table.data-table,
.bh-split:not(.bh-split--closed) .bh-split__list > table.lt,
.bh-split:not(.bh-split--closed) .bh-split__list > table.data-table {
  border-right: 1px solid var(--border);
  overflow-y: auto;
}

/* The count cards summarise the full list, not a 360px rail - the numbers are back the
   moment the record is closed. */
.bh-split:not(.bh-split--closed) .bh-split__list .card { display: none; }

/* ...unless the list IS a tabbed card, which Inventory's batches rail is: three lists
   behind tabs. It stays, it goes in the rail column, and its tab bar stays inside it
   rather than being lifted out - the tabs switch the rail, not the page. Without this
   the rule above hid the whole rail and the record took the full width (27 Sep 2026). */
.bh-split:not(.bh-split--closed) .bh-split__list .card.bh-rtabs {
  display: flex;
  flex-direction: column;
  grid-area: list;
  min-width: 0;
  overflow: hidden;
}
.bh-split:not(.bh-split--closed) .bh-split__list .card.bh-rtabs [id$="Panes"] {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
}
/* Its tabs are narrower than a full-width bar, so they wrap rather than overflow. */
.bh-split:not(.bh-split--closed) .bh-split__list .card.bh-rtabs > .ch .tbar { flex-wrap: wrap; min-height: 0; }
.bh-split:not(.bh-split--closed) .bh-split__list .card.bh-rtabs > .ch .tbar .tb { padding: 8px 10px; font-size: 12px; }

/* The rail carries the same table the full-width list does, so its cells are tightened
   to fit rather than the table being allowed to overflow and clip its last column. */
.bh-split:not(.bh-split--closed) .bh-split__list .lt { font-size: 12px; }
.bh-split:not(.bh-split--closed) .bh-split__list .lt td { padding: 9px 10px; }
.bh-split:not(.bh-split--closed) .bh-split__list .lt th { padding: 8px 10px; font-size: 10px; }
.bh-split:not(.bh-split--closed) .bh-split__list .lt .text-sm { font-size: 11px; }

/* WHICH CELL PLAYS WHICH PART, per page. The rail is a list of cards now, so this says
   what goes on line one (the name, and the figure beside it) and what goes on the quiet
   line under it - it is no longer a list of columns to hide. Every cell not named here
   is hidden IN THE RAIL ONLY; all of them are still in the full-width list, which Close
   returns to, and in the record itself.

   Scoped through .bh-split__list so a .lt table inside the record is untouched. */

/* Leads: 1 Company/Contact  3 Est. Value  |  2 Stage  4 Last activity */
.bh-split--leads:not(.bh-split--closed) .bh-split__list .lt tbody td:nth-child(1) { grid-column: 1; grid-row: 1; font-size: 13px; font-weight: 700; color: var(--text-primary); }
.bh-split--leads:not(.bh-split--closed) .bh-split__list .lt tbody td:nth-child(3) { grid-column: 2; grid-row: 1; font-size: 13px; font-weight: 700; color: var(--text-primary); text-align: right; white-space: nowrap; }
.bh-split--leads:not(.bh-split--closed) .bh-split__list .lt tbody td:nth-child(2) { grid-column: 1; grid-row: 2; }
.bh-split--leads:not(.bh-split--closed) .bh-split__list .lt tbody td:nth-child(4) { grid-column: 2; grid-row: 2; text-align: right; white-space: nowrap; }
.bh-split--leads:not(.bh-split--closed) .bh-split__list .lt tbody td:not(:nth-child(1), :nth-child(2), :nth-child(3), :nth-child(4)) { display: none; }

/* Quotes: 2 Company/Contact  3 Value  |  1 Reference  4 Status */
.bh-split--quotes:not(.bh-split--closed) .bh-split__list .lt tbody td:nth-child(2) { grid-column: 1; grid-row: 1; font-size: 13px; font-weight: 700; color: var(--text-primary); }
.bh-split--quotes:not(.bh-split--closed) .bh-split__list .lt tbody td:nth-child(3) { grid-column: 2; grid-row: 1; font-size: 13px; font-weight: 700; color: var(--text-primary); text-align: right; white-space: nowrap; }
.bh-split--quotes:not(.bh-split--closed) .bh-split__list .lt tbody td:nth-child(1) { grid-column: 1; grid-row: 2; }
.bh-split--quotes:not(.bh-split--closed) .bh-split__list .lt tbody td:nth-child(4) { grid-column: 2; grid-row: 2; text-align: right; white-space: nowrap; }
.bh-split--quotes:not(.bh-split--closed) .bh-split__list .lt tbody td:not(:nth-child(1), :nth-child(2), :nth-child(3), :nth-child(4)) { display: none; }

/* Orders (Sales): 2 Company/Contact  3 Order value  |  1 Reference  4 Status */
.bh-split--orders:not(.bh-split--closed) .bh-split__list .lt tbody td:nth-child(2) { grid-column: 1; grid-row: 1; font-size: 13px; font-weight: 700; color: var(--text-primary); }
.bh-split--orders:not(.bh-split--closed) .bh-split__list .lt tbody td:nth-child(3) { grid-column: 2; grid-row: 1; font-size: 13px; font-weight: 700; color: var(--text-primary); text-align: right; white-space: nowrap; }
.bh-split--orders:not(.bh-split--closed) .bh-split__list .lt tbody td:nth-child(1) { grid-column: 1; grid-row: 2; }
.bh-split--orders:not(.bh-split--closed) .bh-split__list .lt tbody td:nth-child(4) { grid-column: 2; grid-row: 2; text-align: right; white-space: nowrap; }
.bh-split--orders:not(.bh-split--closed) .bh-split__list .lt tbody td:not(:nth-child(1), :nth-child(2), :nth-child(3), :nth-child(4)) { display: none; }

/* Cases: 3 Subject  5 Priority  |  1 Reference  2 Customer */
.bh-split--cases:not(.bh-split--closed) .bh-split__list .lt tbody td:nth-child(3) { grid-column: 1; grid-row: 1; font-size: 13px; font-weight: 700; color: var(--text-primary); }
.bh-split--cases:not(.bh-split--closed) .bh-split__list .lt tbody td:nth-child(5) { grid-column: 2; grid-row: 1; font-size: 13px; font-weight: 700; color: var(--text-primary); text-align: right; white-space: nowrap; }
.bh-split--cases:not(.bh-split--closed) .bh-split__list .lt tbody td:nth-child(1) { grid-column: 1; grid-row: 2; }
.bh-split--cases:not(.bh-split--closed) .bh-split__list .lt tbody td:nth-child(2) { grid-column: 2; grid-row: 2; text-align: right; white-space: nowrap; }
.bh-split--cases:not(.bh-split--closed) .bh-split__list .lt tbody td:not(:nth-child(1), :nth-child(2), :nth-child(3), :nth-child(5)) { display: none; }

/* Customers: 1 Company  5 Open cases  |  2 Type */
.bh-split--cscustomers:not(.bh-split--closed) .bh-split__list .lt tbody td:nth-child(1) { grid-column: 1; grid-row: 1; font-size: 13px; font-weight: 700; color: var(--text-primary); }
.bh-split--cscustomers:not(.bh-split--closed) .bh-split__list .lt tbody td:nth-child(5) { grid-column: 2; grid-row: 1; font-size: 13px; font-weight: 700; color: var(--text-primary); text-align: right; white-space: nowrap; }
.bh-split--cscustomers:not(.bh-split--closed) .bh-split__list .lt tbody td:nth-child(2) { grid-column: 1; grid-row: 2; }
.bh-split--cscustomers:not(.bh-split--closed) .bh-split__list .lt tbody td:not(:nth-child(1), :nth-child(2), :nth-child(5)) { display: none; }

/* Orders (CS): 2 Company/Contact  3 Value  |  1 Reference  4 Status */
.bh-split--csorders:not(.bh-split--closed) .bh-split__list .lt tbody td:nth-child(2) { grid-column: 1; grid-row: 1; font-size: 13px; font-weight: 700; color: var(--text-primary); }
.bh-split--csorders:not(.bh-split--closed) .bh-split__list .lt tbody td:nth-child(3) { grid-column: 2; grid-row: 1; font-size: 13px; font-weight: 700; color: var(--text-primary); text-align: right; white-space: nowrap; }
.bh-split--csorders:not(.bh-split--closed) .bh-split__list .lt tbody td:nth-child(1) { grid-column: 1; grid-row: 2; }
.bh-split--csorders:not(.bh-split--closed) .bh-split__list .lt tbody td:nth-child(4) { grid-column: 2; grid-row: 2; text-align: right; white-space: nowrap; }
.bh-split--csorders:not(.bh-split--closed) .bh-split__list .lt tbody td:not(:nth-child(1), :nth-child(2), :nth-child(3), :nth-child(4)) { display: none; }

/* Invoices: 2 Customer  3 Amount inc VAT  |  1 Reference  5 Status */
.bh-split--csinvoices:not(.bh-split--closed) .bh-split__list .lt tbody td:nth-child(2) { grid-column: 1; grid-row: 1; font-size: 13px; font-weight: 700; color: var(--text-primary); }
.bh-split--csinvoices:not(.bh-split--closed) .bh-split__list .lt tbody td:nth-child(3) { grid-column: 2; grid-row: 1; font-size: 13px; font-weight: 700; color: var(--text-primary); text-align: right; white-space: nowrap; }
.bh-split--csinvoices:not(.bh-split--closed) .bh-split__list .lt tbody td:nth-child(1) { grid-column: 1; grid-row: 2; }
.bh-split--csinvoices:not(.bh-split--closed) .bh-split__list .lt tbody td:nth-child(5) { grid-column: 2; grid-row: 2; text-align: right; white-space: nowrap; }
.bh-split--csinvoices:not(.bh-split--closed) .bh-split__list .lt tbody td:not(:nth-child(1), :nth-child(2), :nth-child(3), :nth-child(5)) { display: none; }

/* Returns: 3 Subject  4 Status  |  1 Reference  2 Customer */
.bh-split--csreturns:not(.bh-split--closed) .bh-split__list .lt tbody td:nth-child(3) { grid-column: 1; grid-row: 1; font-size: 13px; font-weight: 700; color: var(--text-primary); }
.bh-split--csreturns:not(.bh-split--closed) .bh-split__list .lt tbody td:nth-child(4) { grid-column: 2; grid-row: 1; font-size: 13px; font-weight: 700; color: var(--text-primary); text-align: right; white-space: nowrap; }
.bh-split--csreturns:not(.bh-split--closed) .bh-split__list .lt tbody td:nth-child(1) { grid-column: 1; grid-row: 2; }
.bh-split--csreturns:not(.bh-split--closed) .bh-split__list .lt tbody td:nth-child(2) { grid-column: 2; grid-row: 2; text-align: right; white-space: nowrap; }
.bh-split--csreturns:not(.bh-split--closed) .bh-split__list .lt tbody td:not(:nth-child(1), :nth-child(2), :nth-child(3), :nth-child(4)) { display: none; }

/* Stock: 2 Product  7 Available  |  1 SKU  4 Location */
.bh-split--wsstock:not(.bh-split--closed) .bh-split__list .lt tbody td:nth-child(2) { grid-column: 1; grid-row: 1; font-size: 13px; font-weight: 700; color: var(--text-primary); }
.bh-split--wsstock:not(.bh-split--closed) .bh-split__list .lt tbody td:nth-child(7) { grid-column: 2; grid-row: 1; font-size: 13px; font-weight: 700; color: var(--text-primary); text-align: right; white-space: nowrap; }
.bh-split--wsstock:not(.bh-split--closed) .bh-split__list .lt tbody td:nth-child(1) { grid-column: 1; grid-row: 2; }
.bh-split--wsstock:not(.bh-split--closed) .bh-split__list .lt tbody td:nth-child(4) { grid-column: 2; grid-row: 2; text-align: right; white-space: nowrap; }
.bh-split--wsstock:not(.bh-split--closed) .bh-split__list .lt tbody td:not(:nth-child(1), :nth-child(2), :nth-child(4), :nth-child(7)) { display: none; }

/* Pick queue: 2 Customer  3 Lines  |  1 Order ref  5 Status */
.bh-split--wspick:not(.bh-split--closed) .bh-split__list .lt tbody td:nth-child(2) { grid-column: 1; grid-row: 1; font-size: 13px; font-weight: 700; color: var(--text-primary); }
.bh-split--wspick:not(.bh-split--closed) .bh-split__list .lt tbody td:nth-child(3) { grid-column: 2; grid-row: 1; font-size: 13px; font-weight: 700; color: var(--text-primary); text-align: right; white-space: nowrap; }
.bh-split--wspick:not(.bh-split--closed) .bh-split__list .lt tbody td:nth-child(1) { grid-column: 1; grid-row: 2; }
.bh-split--wspick:not(.bh-split--closed) .bh-split__list .lt tbody td:nth-child(5) { grid-column: 2; grid-row: 2; text-align: right; white-space: nowrap; }
.bh-split--wspick:not(.bh-split--closed) .bh-split__list .lt tbody td:not(:nth-child(1), :nth-child(2), :nth-child(3), :nth-child(5)) { display: none; }


/* The three shared modules use .data-table rather than .lt, so they need their own
   set - same three parts, same rule. */
/* Messages: 1 Who  4 When  |  2 About  3 Note */
.bh-split--msgs:not(.bh-split--closed) .bh-split__list .data-table tbody td:nth-child(1) { grid-column: 1; grid-row: 1; font-size: 13px; font-weight: 700; color: var(--text-primary); }
.bh-split--msgs:not(.bh-split--closed) .bh-split__list .data-table tbody td:nth-child(4) { grid-column: 2; grid-row: 1; font-size: 12px; font-weight: 600; color: var(--text-muted); text-align: right; white-space: nowrap; }
.bh-split--msgs:not(.bh-split--closed) .bh-split__list .data-table tbody td:nth-child(2) { grid-column: 1; grid-row: 2; }
.bh-split--msgs:not(.bh-split--closed) .bh-split__list .data-table tbody td:nth-child(3) { grid-column: 1 / -1; grid-row: 3; }
.bh-split--msgs:not(.bh-split--closed) .bh-split__list .data-table tbody td:not(:nth-child(1), :nth-child(2), :nth-child(3), :nth-child(4)) { display: none; }

/* Projects: 1 Project  6 Budget  |  2 Manager  7 Status */
.bh-split--projs:not(.bh-split--closed) .bh-split__list .data-table tbody td:nth-child(1) { grid-column: 1; grid-row: 1; font-size: 13px; font-weight: 700; color: var(--text-primary); }
.bh-split--projs:not(.bh-split--closed) .bh-split__list .data-table tbody td:nth-child(6) { grid-column: 2; grid-row: 1; font-size: 12px; font-weight: 600; color: var(--text-muted); text-align: right; white-space: nowrap; }
.bh-split--projs:not(.bh-split--closed) .bh-split__list .data-table tbody td:nth-child(2) { grid-column: 1; grid-row: 2; }
.bh-split--projs:not(.bh-split--closed) .bh-split__list .data-table tbody td:nth-child(7) { grid-column: 1 / -1; grid-row: 3; }
.bh-split--projs:not(.bh-split--closed) .bh-split__list .data-table tbody td:not(:nth-child(1), :nth-child(2), :nth-child(6), :nth-child(7)) { display: none; }

/* Tasks: 1 Task  4 Due  |  2 For  7 Status */
.bh-split--tasks:not(.bh-split--closed) .bh-split__list .data-table tbody td:nth-child(1) { grid-column: 1; grid-row: 1; font-size: 13px; font-weight: 700; color: var(--text-primary); }
.bh-split--tasks:not(.bh-split--closed) .bh-split__list .data-table tbody td:nth-child(4) { grid-column: 2; grid-row: 1; font-size: 12px; font-weight: 600; color: var(--text-muted); text-align: right; white-space: nowrap; }
.bh-split--tasks:not(.bh-split--closed) .bh-split__list .data-table tbody td:nth-child(2) { grid-column: 1; grid-row: 2; }
.bh-split--tasks:not(.bh-split--closed) .bh-split__list .data-table tbody td:nth-child(7) { grid-column: 1 / -1; grid-row: 3; }
.bh-split--tasks:not(.bh-split--closed) .bh-split__list .data-table tbody td:not(:nth-child(1), :nth-child(2), :nth-child(4), :nth-child(7)) { display: none; }

/* ===========================================================================
   PRODUCTS RAIL - the two-level category / product nav

   Rewritten 25 Sep 2026 after I deleted the original by accident: a bulk edit that
   replaced the per-page column rules cut from the column comment to the row-cursor rule,
   and this section sat between the two. bizheart-aurora.css is untracked, so there was
   no earlier copy to restore - it is rebuilt from the markup in
   emxml_blkSalesProductsNav.xml.

   Products is the one split whose rail is not a table: it is a list of categories that
   open in place to show their products, so it has its own element (.bh-split__nav) and
   has to be named into the list column itself. Without that it auto-placed into the new
   action row and the whole rail lost its styling.
============================================================================ */

.bh-split--products { grid-template-columns: minmax(0, 34%) minmax(0, 1fr); }

.bh-split__nav {
  grid-area: list;
  overflow-y: auto;
  border-right: 1px solid var(--border);
}

.pn { display: flex; flex-direction: column; }

/* A category. Clicking it opens its products underneath. */
.pn-cat {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 11px 14px;
  border-bottom: 1px solid var(--border);
  border-left: 3px solid transparent;
  cursor: pointer;
  font-size: 13px;
  font-weight: 700;
  color: var(--text-primary);
}
.pn-cat:hover { background: var(--c-primary-xlight); }
.pn-cat.is-open {
  background: var(--c-primary-xlight);
  border-left-color: var(--c-primary);
}

.pn-ico {
  width: 22px;
  display: inline-flex;
  justify-content: center;
  color: var(--c-primary);
  font-size: 13px;
}
.pn-name { flex: 1 1 auto; min-width: 0; }
.pn-count {
  font-size: 11px;
  font-weight: 700;
  color: var(--text-muted);
  background: var(--row-stripe, #F5F6FB);
  border-radius: 10px;
  padding: 1px 8px;
}

/* A product inside the open category - indented, so the two levels read apart. */
.pn-prod {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: baseline;
  column-gap: 10px;
  row-gap: 2px;
  padding: 9px 14px 9px 36px;
  border-bottom: 1px solid var(--border);
  border-left: 3px solid transparent;
  cursor: pointer;
}
.pn-prod:hover { background: var(--c-primary-xlight); }
.pn-prod.is-open {
  background: var(--c-primary-xlight);
  border-left-color: var(--c-primary);
}

.pn-prod-name {
  grid-column: 1;
  grid-row: 1;
  font-size: 12.5px;
  font-weight: 600;
  color: var(--text-primary);
}
.pn-price {
  grid-column: 2;
  grid-row: 1;
  font-size: 12.5px;
  font-weight: 700;
  color: var(--text-primary);
  white-space: nowrap;
}
.pn-stock {
  grid-column: 1 / -1;
  grid-row: 2;
  font-size: 11.5px;
  color: var(--text-muted);
}
.pn-stock.is-low  { color: var(--c-warn, #B45309); font-weight: 600; }
.pn-stock.is-none { color: var(--c-danger, #B91C1C); font-weight: 600; }

/* Nothing picked yet - said quietly, in the middle of the record column. */
.bh-emptycol {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100%;
  min-height: 180px;
  padding: 28px 20px;
  color: var(--text-muted);
  font-size: 13px;
}

/* ===========================================================================
   INSIDE THE RECORD - the R1 header and field strip (Khalid, 25 Sep 2026)
============================================================================ */

/* The record's header line: reference left, then the badges and Close together at the
   right end. They used to be spread across the width, which read as three unrelated
   things rather than "this is the record, and here is the way out of it". */
.bh-split__detail .ap-dhdr {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 14px 20px 0;
  margin: 0;
}
.ap-dhdr__end {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: 8px;
  flex-shrink: 0;
}

/* The buttons under it had no room above them - they sat straight on the header. */
.bh-split__detail .ap-dhdr + .a-bar {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  padding: 14px 20px;
  margin: 0;
}

/* The record's fields as a row, the way R1 lays them out: label above value, flowing
   across as many columns as fit and wrapping onto the next line.

   It was three across and everything after that full width, which on Stock left SKU /
   Category / In stock on one line and then Allocated, Available and Reorder point on a
   line each with nothing beside them.

   A <dl> is a flat run of dt/dd, so each pair is put in the same column by its position
   and 'dense' packing lets the value drop under its own label instead of chasing the
   cursor to the end. A field whose content is prose rather than a value carries .wide
   and takes the whole row. */
.bh-split__detail .detail-list {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  grid-auto-flow: row dense;
  gap: 4px 18px;
  margin: 0;
}
.bh-split__detail .detail-list dt:nth-of-type(4n+1),
.bh-split__detail .detail-list dd:nth-of-type(4n+1) { grid-column: 1; }
.bh-split__detail .detail-list dt:nth-of-type(4n+2),
.bh-split__detail .detail-list dd:nth-of-type(4n+2) { grid-column: 2; }
.bh-split__detail .detail-list dt:nth-of-type(4n+3),
.bh-split__detail .detail-list dd:nth-of-type(4n+3) { grid-column: 3; }
.bh-split__detail .detail-list dt:nth-of-type(4n),
.bh-split__detail .detail-list dd:nth-of-type(4n) { grid-column: 4; }
.bh-split__detail .detail-list dt.wide,
.bh-split__detail .detail-list dd.wide { grid-column: 1 / -1; }

/* bizcore.css gives every dt and dd in a .detail-list a bottom border, and exempts the
   last one. That is why Reorder Point had no line under it while the other five did -
   it is the last dd. Inside a split there are no lines at all, so both are cleared here
   rather than left to a rule that treats one field differently from the rest. */
.bh-split__detail .detail-list dt,
.bh-split__detail .detail-list dd { border-bottom: 0; }

.bh-split__detail .detail-list dt {
  font-size: 10.5px;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--text-muted);
  font-weight: 700;
  margin: 12px 0 0;
}
/* No rule under the value. The R1 field strip is label above value and nothing else;
   a line under each one turned a tidy strip into a grid of boxes, and on the last row
   it stopped halfway across because that row has fewer fields than the one above. */
.bh-split__detail .detail-list dd {
  font-size: 13px;
  font-weight: 600;
  color: var(--text-primary);
  margin: 0;
  padding-bottom: 2px;
}
.bh-split__detail .detail-list dd.wide { font-weight: 400; line-height: 1.5; }

@media (max-width: 767px) {
  /* Two across on a phone; the cycle has to be restated to match. */
  .bh-split__detail .detail-list { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .bh-split__detail .detail-list dt:nth-of-type(odd),
  .bh-split__detail .detail-list dd:nth-of-type(odd) { grid-column: 1; }
  .bh-split__detail .detail-list dt:nth-of-type(even),
  .bh-split__detail .detail-list dd:nth-of-type(even) { grid-column: 2; }
}

/* The full-width list keeps its own action bar under the tabs. It sat straight on the
   tab bar with nothing above it and the button pinned to the left of a full width row,
   which read as a banner. Even padding centres it in its row, and it goes to the right
   end where a primary action belongs. (In the split it shares the tab row instead - see
   the .bh-split rules above.) */
.tbar + .a-bar,
div:has(> .tbar) + .a-bar {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 8px;
  /* Horizontal padding too: Pick & Pack has no .pg-body, so nothing else gives this
     module a side gutter and the button sat flush against the right edge. */
  padding: 14px 20px;
}


/* The three warehouse queues, same three parts as the rest. */
/* Despatch: 1 Order ref  3 Order date  |  2 Customer  4 Carrier */
.bh-split--wsdesp:not(.bh-split--closed) .bh-split__list .lt tbody td:nth-child(1) { grid-column: 1; grid-row: 1; font-size: 13px; font-weight: 700; color: var(--text-primary); }
.bh-split--wsdesp:not(.bh-split--closed) .bh-split__list .lt tbody td:nth-child(3) { grid-column: 2; grid-row: 1; font-size: 12px; font-weight: 600; color: var(--text-muted); text-align: right; white-space: nowrap; }
.bh-split--wsdesp:not(.bh-split--closed) .bh-split__list .lt tbody td:nth-child(2) { grid-column: 1; grid-row: 2; }
.bh-split--wsdesp:not(.bh-split--closed) .bh-split__list .lt tbody td:nth-child(4) { grid-column: 2; grid-row: 2; text-align: right; white-space: nowrap; }
.bh-split--wsdesp:not(.bh-split--closed) .bh-split__list .lt tbody td:not(:nth-child(1), :nth-child(2), :nth-child(3), :nth-child(4)) { display: none; }

/* Goods In: 1 Supplier  4 Lines  |  2 PO reference  5 Status */
.bh-split--wsgoods:not(.bh-split--closed) .bh-split__list .lt tbody td:nth-child(1) { grid-column: 1; grid-row: 1; font-size: 13px; font-weight: 700; color: var(--text-primary); }
.bh-split--wsgoods:not(.bh-split--closed) .bh-split__list .lt tbody td:nth-child(4) { grid-column: 2; grid-row: 1; font-size: 12px; font-weight: 600; color: var(--text-muted); text-align: right; white-space: nowrap; }
.bh-split--wsgoods:not(.bh-split--closed) .bh-split__list .lt tbody td:nth-child(2) { grid-column: 1; grid-row: 2; }
.bh-split--wsgoods:not(.bh-split--closed) .bh-split__list .lt tbody td:nth-child(5) { grid-column: 2; grid-row: 2; text-align: right; white-space: nowrap; }
.bh-split--wsgoods:not(.bh-split--closed) .bh-split__list .lt tbody td:not(:nth-child(1), :nth-child(2), :nth-child(4), :nth-child(5)) { display: none; }

/* Returns: 1 Return ref  4 Return method  |  2 Customer  5 Status */
.bh-split--wsret:not(.bh-split--closed) .bh-split__list .lt tbody td:nth-child(1) { grid-column: 1; grid-row: 1; font-size: 13px; font-weight: 700; color: var(--text-primary); }
.bh-split--wsret:not(.bh-split--closed) .bh-split__list .lt tbody td:nth-child(4) { grid-column: 2; grid-row: 1; font-size: 12px; font-weight: 600; color: var(--text-muted); text-align: right; white-space: nowrap; }
.bh-split--wsret:not(.bh-split--closed) .bh-split__list .lt tbody td:nth-child(2) { grid-column: 1; grid-row: 2; }
.bh-split--wsret:not(.bh-split--closed) .bh-split__list .lt tbody td:nth-child(5) { grid-column: 2; grid-row: 2; text-align: right; white-space: nowrap; }
.bh-split--wsret:not(.bh-split--closed) .bh-split__list .lt tbody td:not(:nth-child(1), :nth-child(2), :nth-child(4), :nth-child(5)) { display: none; }


/* Finance Staff. */
/* Invoices: 1 Reference  7 Gross  |  2 Customer  10 Status */
.bh-split--fsinv:not(.bh-split--closed) .bh-split__list .lt tbody td:nth-child(1) { grid-column: 1; grid-row: 1; font-size: 13px; font-weight: 700; color: var(--text-primary); }
.bh-split--fsinv:not(.bh-split--closed) .bh-split__list .lt tbody td:nth-child(7) { grid-column: 2; grid-row: 1; font-size: 13px; font-weight: 700; color: var(--text-primary); text-align: right; white-space: nowrap; }
.bh-split--fsinv:not(.bh-split--closed) .bh-split__list .lt tbody td:nth-child(2) { grid-column: 1; grid-row: 2; }
.bh-split--fsinv:not(.bh-split--closed) .bh-split__list .lt tbody td:nth-child(10) { grid-column: 2; grid-row: 2; text-align: right; white-space: nowrap; }
.bh-split--fsinv:not(.bh-split--closed) .bh-split__list .lt tbody td:not(:nth-child(1), :nth-child(2), :nth-child(7), :nth-child(10)) { display: none; }

/* Purchase invoices: 2 Supplier  5 Gross  |  1 Reference  7 Status */
.bh-split--fspi:not(.bh-split--closed) .bh-split__list .lt tbody td:nth-child(2) { grid-column: 1; grid-row: 1; font-size: 13px; font-weight: 700; color: var(--text-primary); }
.bh-split--fspi:not(.bh-split--closed) .bh-split__list .lt tbody td:nth-child(5) { grid-column: 2; grid-row: 1; font-size: 13px; font-weight: 700; color: var(--text-primary); text-align: right; white-space: nowrap; }
.bh-split--fspi:not(.bh-split--closed) .bh-split__list .lt tbody td:nth-child(1) { grid-column: 1; grid-row: 2; }
.bh-split--fspi:not(.bh-split--closed) .bh-split__list .lt tbody td:nth-child(7) { grid-column: 2; grid-row: 2; text-align: right; white-space: nowrap; }
.bh-split--fspi:not(.bh-split--closed) .bh-split__list .lt tbody td:not(:nth-child(1), :nth-child(2), :nth-child(5), :nth-child(7)) { display: none; }

/* Credit notes: 2 Customer  5 Amount  |  1 Reference  6 Status */
.bh-split--fscn:not(.bh-split--closed) .bh-split__list .lt tbody td:nth-child(2) { grid-column: 1; grid-row: 1; font-size: 13px; font-weight: 700; color: var(--text-primary); }
.bh-split--fscn:not(.bh-split--closed) .bh-split__list .lt tbody td:nth-child(5) { grid-column: 2; grid-row: 1; font-size: 13px; font-weight: 700; color: var(--text-primary); text-align: right; white-space: nowrap; }
.bh-split--fscn:not(.bh-split--closed) .bh-split__list .lt tbody td:nth-child(1) { grid-column: 1; grid-row: 2; }
.bh-split--fscn:not(.bh-split--closed) .bh-split__list .lt tbody td:nth-child(6) { grid-column: 2; grid-row: 2; text-align: right; white-space: nowrap; }
.bh-split--fscn:not(.bh-split--closed) .bh-split__list .lt tbody td:not(:nth-child(1), :nth-child(2), :nth-child(5), :nth-child(6)) { display: none; }

/* Expenses: 2 Employee  3 Claimed  |  1 Submitted  5 Status */
.bh-split--fsexp:not(.bh-split--closed) .bh-split__list .lt tbody td:nth-child(2) { grid-column: 1; grid-row: 1; font-size: 13px; font-weight: 700; color: var(--text-primary); }
.bh-split--fsexp:not(.bh-split--closed) .bh-split__list .lt tbody td:nth-child(3) { grid-column: 2; grid-row: 1; font-size: 13px; font-weight: 700; color: var(--text-primary); text-align: right; white-space: nowrap; }
.bh-split--fsexp:not(.bh-split--closed) .bh-split__list .lt tbody td:nth-child(1) { grid-column: 1; grid-row: 2; }
.bh-split--fsexp:not(.bh-split--closed) .bh-split__list .lt tbody td:nth-child(5) { grid-column: 2; grid-row: 2; text-align: right; white-space: nowrap; }
.bh-split--fsexp:not(.bh-split--closed) .bh-split__list .lt tbody td:not(:nth-child(1), :nth-child(2), :nth-child(3), :nth-child(5)) { display: none; }


/* Sales Manager. */
/* SM Leads: 1 Contact  4 Close date  |  2 Stage  3 Assigned to */
.bh-split--smlead:not(.bh-split--closed) .bh-split__list .lt tbody td:nth-child(1) { grid-column: 1; grid-row: 1; font-size: 13px; font-weight: 700; color: var(--text-primary); }
.bh-split--smlead:not(.bh-split--closed) .bh-split__list .lt tbody td:nth-child(4) { grid-column: 2; grid-row: 1; font-size: 12px; font-weight: 600; color: var(--text-muted); text-align: right; white-space: nowrap; }
.bh-split--smlead:not(.bh-split--closed) .bh-split__list .lt tbody td:nth-child(2) { grid-column: 1; grid-row: 2; }
.bh-split--smlead:not(.bh-split--closed) .bh-split__list .lt tbody td:nth-child(3) { grid-column: 2; grid-row: 2; text-align: right; white-space: nowrap; }
.bh-split--smlead:not(.bh-split--closed) .bh-split__list .lt tbody td:not(:nth-child(1), :nth-child(2), :nth-child(3), :nth-child(4)) { display: none; }

/* SM Quotes: 1 Reference  4 Date  |  2 Customer  5 Status */
.bh-split--smquote:not(.bh-split--closed) .bh-split__list .lt tbody td:nth-child(1) { grid-column: 1; grid-row: 1; font-size: 13px; font-weight: 700; color: var(--text-primary); }
.bh-split--smquote:not(.bh-split--closed) .bh-split__list .lt tbody td:nth-child(4) { grid-column: 2; grid-row: 1; font-size: 12px; font-weight: 600; color: var(--text-muted); text-align: right; white-space: nowrap; }
.bh-split--smquote:not(.bh-split--closed) .bh-split__list .lt tbody td:nth-child(2) { grid-column: 1; grid-row: 2; }
.bh-split--smquote:not(.bh-split--closed) .bh-split__list .lt tbody td:nth-child(5) { grid-column: 2; grid-row: 2; text-align: right; white-space: nowrap; }
.bh-split--smquote:not(.bh-split--closed) .bh-split__list .lt tbody td:not(:nth-child(1), :nth-child(2), :nth-child(4), :nth-child(5)) { display: none; }


/* Admin Staff. */
/* Purchase requests: 1 Reference  4 Submitted  |  2 Requester  6 Status */
.bh-split--aspr:not(.bh-split--closed) .bh-split__list .lt tbody td:nth-child(1) { grid-column: 1; grid-row: 1; font-size: 13px; font-weight: 700; color: var(--text-primary); }
.bh-split--aspr:not(.bh-split--closed) .bh-split__list .lt tbody td:nth-child(4) { grid-column: 2; grid-row: 1; font-size: 12px; font-weight: 600; color: var(--text-muted); text-align: right; white-space: nowrap; }
.bh-split--aspr:not(.bh-split--closed) .bh-split__list .lt tbody td:nth-child(2) { grid-column: 1; grid-row: 2; }
.bh-split--aspr:not(.bh-split--closed) .bh-split__list .lt tbody td:nth-child(6) { grid-column: 2; grid-row: 2; text-align: right; white-space: nowrap; }
.bh-split--aspr:not(.bh-split--closed) .bh-split__list .lt tbody td:not(:nth-child(1), :nth-child(2), :nth-child(4), :nth-child(6)) { display: none; }

/* Admin Staff documents: 1 Title  5 Status  |  2 Type  7 Uploaded */
.bh-split--asdoc:not(.bh-split--closed) .bh-split__list .lt tbody td:nth-child(1) { grid-column: 1; grid-row: 1; font-size: 13px; font-weight: 700; color: var(--text-primary); }
.bh-split--asdoc:not(.bh-split--closed) .bh-split__list .lt tbody td:nth-child(5) { grid-column: 2; grid-row: 1; font-size: 12px; font-weight: 600; color: var(--text-muted); text-align: right; white-space: nowrap; }
.bh-split--asdoc:not(.bh-split--closed) .bh-split__list .lt tbody td:nth-child(2) { grid-column: 1; grid-row: 2; }
.bh-split--asdoc:not(.bh-split--closed) .bh-split__list .lt tbody td:nth-child(7) { grid-column: 2; grid-row: 2; text-align: right; white-space: nowrap; }
.bh-split--asdoc:not(.bh-split--closed) .bh-split__list .lt tbody td:not(:nth-child(1), :nth-child(2), :nth-child(5), :nth-child(7)) { display: none; }

/* Admin Staff external interfaces: 1 Service  3 In use/Off  |  2 Sign-in */
.bh-split--asext:not(.bh-split--closed) .bh-split__list .lt tbody td:nth-child(1) { grid-column: 1; grid-row: 1; font-size: 13px; font-weight: 700; color: var(--text-primary); }
.bh-split--asext:not(.bh-split--closed) .bh-split__list .lt tbody td:nth-child(3) { grid-column: 2; grid-row: 1; text-align: right; white-space: nowrap; }
.bh-split--asext:not(.bh-split--closed) .bh-split__list .lt tbody td:nth-child(2) { grid-column: 1 / -1; grid-row: 2; }

/* Admin Staff rules: 1 Rule  3 On/Off  |  2 When */
.bh-split--asrule:not(.bh-split--closed) .bh-split__list .lt tbody td:nth-child(1) { grid-column: 1; grid-row: 1; font-size: 13px; font-weight: 700; color: var(--text-primary); }
.bh-split--asrule:not(.bh-split--closed) .bh-split__list .lt tbody td:nth-child(3) { grid-column: 2; grid-row: 1; text-align: right; white-space: nowrap; }
.bh-split--asrule:not(.bh-split--closed) .bh-split__list .lt tbody td:nth-child(2) { grid-column: 1 / -1; grid-row: 2; }

/* The two portals. Customer invoices: 1 Ref  5 Balance  |  2 Date  6 Status */
.bh-split--cpinv:not(.bh-split--closed) .bh-split__list .lt tbody td:nth-child(1) { grid-column: 1; grid-row: 1; font-size: 13px; font-weight: 700; color: var(--text-primary); }
.bh-split--cpinv:not(.bh-split--closed) .bh-split__list .lt tbody td:nth-child(5) { grid-column: 2; grid-row: 1; font-size: 13px; font-weight: 700; color: var(--text-primary); text-align: right; white-space: nowrap; }
.bh-split--cpinv:not(.bh-split--closed) .bh-split__list .lt tbody td:nth-child(2) { grid-column: 1; grid-row: 2; }
.bh-split--cpinv:not(.bh-split--closed) .bh-split__list .lt tbody td:nth-child(6) { grid-column: 2; grid-row: 2; text-align: right; white-space: nowrap; }
.bh-split--cpinv:not(.bh-split--closed) .bh-split__list .lt tbody td:not(:nth-child(1), :nth-child(2), :nth-child(5), :nth-child(6)) { display: none; }

/* Customer orders: 1 Ref  4 Value  |  2 Date  5 Status */
.bh-split--cpord:not(.bh-split--closed) .bh-split__list .lt tbody td:nth-child(1) { grid-column: 1; grid-row: 1; font-size: 13px; font-weight: 700; color: var(--text-primary); }
.bh-split--cpord:not(.bh-split--closed) .bh-split__list .lt tbody td:nth-child(4) { grid-column: 2; grid-row: 1; font-size: 13px; font-weight: 700; color: var(--text-primary); text-align: right; white-space: nowrap; }
.bh-split--cpord:not(.bh-split--closed) .bh-split__list .lt tbody td:nth-child(2) { grid-column: 1; grid-row: 2; }
.bh-split--cpord:not(.bh-split--closed) .bh-split__list .lt tbody td:nth-child(5) { grid-column: 2; grid-row: 2; text-align: right; white-space: nowrap; }
.bh-split--cpord:not(.bh-split--closed) .bh-split__list .lt tbody td:not(:nth-child(1), :nth-child(2), :nth-child(4), :nth-child(5)) { display: none; }

/* Customer cases: 2 Subject  4 Status  |  1 Ref  6 Last activity */
.bh-split--cpcase:not(.bh-split--closed) .bh-split__list .lt tbody td:nth-child(2) { grid-column: 1; grid-row: 1; font-size: 13px; font-weight: 700; color: var(--text-primary); }
.bh-split--cpcase:not(.bh-split--closed) .bh-split__list .lt tbody td:nth-child(4) { grid-column: 2; grid-row: 1; text-align: right; white-space: nowrap; }
.bh-split--cpcase:not(.bh-split--closed) .bh-split__list .lt tbody td:nth-child(1) { grid-column: 1; grid-row: 2; }
.bh-split--cpcase:not(.bh-split--closed) .bh-split__list .lt tbody td:nth-child(6) { grid-column: 2; grid-row: 2; text-align: right; white-space: nowrap; }
.bh-split--cpcase:not(.bh-split--closed) .bh-split__list .lt tbody td:not(:nth-child(1), :nth-child(2), :nth-child(4), :nth-child(6)) { display: none; }

/* Supplier invoices: 1 Ref  5 Amount  |  2 PO ref  6 Status */
.bh-split--spinv:not(.bh-split--closed) .bh-split__list .lt tbody td:nth-child(1) { grid-column: 1; grid-row: 1; font-size: 13px; font-weight: 700; color: var(--text-primary); }
.bh-split--spinv:not(.bh-split--closed) .bh-split__list .lt tbody td:nth-child(5) { grid-column: 2; grid-row: 1; font-size: 13px; font-weight: 700; color: var(--text-primary); text-align: right; white-space: nowrap; }
.bh-split--spinv:not(.bh-split--closed) .bh-split__list .lt tbody td:nth-child(2) { grid-column: 1; grid-row: 2; }
.bh-split--spinv:not(.bh-split--closed) .bh-split__list .lt tbody td:nth-child(6) { grid-column: 2; grid-row: 2; text-align: right; white-space: nowrap; }
.bh-split--spinv:not(.bh-split--closed) .bh-split__list .lt tbody td:not(:nth-child(1), :nth-child(2), :nth-child(5), :nth-child(6)) { display: none; }

/* Supplier orders: 1 PO ref  3 Value  |  2 PO date  5 Status */
.bh-split--spord:not(.bh-split--closed) .bh-split__list .lt tbody td:nth-child(1) { grid-column: 1; grid-row: 1; font-size: 13px; font-weight: 700; color: var(--text-primary); }
.bh-split--spord:not(.bh-split--closed) .bh-split__list .lt tbody td:nth-child(3) { grid-column: 2; grid-row: 1; font-size: 13px; font-weight: 700; color: var(--text-primary); text-align: right; white-space: nowrap; }
.bh-split--spord:not(.bh-split--closed) .bh-split__list .lt tbody td:nth-child(2) { grid-column: 1; grid-row: 2; }
.bh-split--spord:not(.bh-split--closed) .bh-split__list .lt tbody td:nth-child(5) { grid-column: 2; grid-row: 2; text-align: right; white-space: nowrap; }
.bh-split--spord:not(.bh-split--closed) .bh-split__list .lt tbody td:not(:nth-child(1), :nth-child(2), :nth-child(3), :nth-child(5)) { display: none; }

/* Admin Staff orders: 1 Order ref  3 Value  |  2 Customer  7 Processing */
.bh-split--asord:not(.bh-split--closed) .bh-split__list .lt tbody td:nth-child(1) { grid-column: 1; grid-row: 1; font-size: 13px; font-weight: 700; color: var(--text-primary); }
.bh-split--asord:not(.bh-split--closed) .bh-split__list .lt tbody td:nth-child(3) { grid-column: 2; grid-row: 1; font-size: 13px; font-weight: 700; color: var(--text-primary); text-align: right; white-space: nowrap; }
.bh-split--asord:not(.bh-split--closed) .bh-split__list .lt tbody td:nth-child(2) { grid-column: 1; grid-row: 2; }
.bh-split--asord:not(.bh-split--closed) .bh-split__list .lt tbody td:nth-child(7) { grid-column: 2; grid-row: 2; text-align: right; white-space: nowrap; }
.bh-split--asord:not(.bh-split--closed) .bh-split__list .lt tbody td:not(:nth-child(1), :nth-child(2), :nth-child(3), :nth-child(7)) { display: none; }

/* Suppliers: 1 Supplier  3 Open POs  |  2 Payment terms  5 Status */
.bh-split--assup:not(.bh-split--closed) .bh-split__list .lt tbody td:nth-child(1) { grid-column: 1; grid-row: 1; font-size: 13px; font-weight: 700; color: var(--text-primary); }
.bh-split--assup:not(.bh-split--closed) .bh-split__list .lt tbody td:nth-child(3) { grid-column: 2; grid-row: 1; font-size: 12px; font-weight: 600; color: var(--text-muted); text-align: right; white-space: nowrap; }
.bh-split--assup:not(.bh-split--closed) .bh-split__list .lt tbody td:nth-child(2) { grid-column: 1; grid-row: 2; }
.bh-split--assup:not(.bh-split--closed) .bh-split__list .lt tbody td:nth-child(5) { grid-column: 2; grid-row: 2; text-align: right; white-space: nowrap; }
.bh-split--assup:not(.bh-split--closed) .bh-split__list .lt tbody td:not(:nth-child(1), :nth-child(2), :nth-child(3), :nth-child(5)) { display: none; }

/* Employees: 1 Name  5 Leave remaining  |  2 Job title  3 Contract */
.bh-split--asemp:not(.bh-split--closed) .bh-split__list .lt tbody td:nth-child(1) { grid-column: 1; grid-row: 1; font-size: 13px; font-weight: 700; color: var(--text-primary); }
.bh-split--asemp:not(.bh-split--closed) .bh-split__list .lt tbody td:nth-child(5) { grid-column: 2; grid-row: 1; font-size: 12px; font-weight: 600; color: var(--text-muted); text-align: right; white-space: nowrap; }
.bh-split--asemp:not(.bh-split--closed) .bh-split__list .lt tbody td:nth-child(2) { grid-column: 1; grid-row: 2; }
.bh-split--asemp:not(.bh-split--closed) .bh-split__list .lt tbody td:nth-child(3) { grid-column: 2; grid-row: 2; text-align: right; white-space: nowrap; }
.bh-split--asemp:not(.bh-split--closed) .bh-split__list .lt tbody td:not(:nth-child(1), :nth-child(2), :nth-child(3), :nth-child(5)) { display: none; }

/* HR Employees: 2 Name  6 Status  |  3 Department  4 Role. .data-table here rather than
   .lt - the list had that class before the split and both are carried by the rules above.
   The Actions column (7) drops out with everything else: in a rail a button beside a card
   that is itself the target is just a smaller second target. */
.bh-split--hremp:not(.bh-split--closed) .bh-split__list .data-table tbody td:nth-child(2) { grid-column: 1; grid-row: 1; font-size: 13px; font-weight: 700; color: var(--text-primary); }
.bh-split--hremp:not(.bh-split--closed) .bh-split__list .data-table tbody td:nth-child(6) { grid-column: 2; grid-row: 1; text-align: right; white-space: nowrap; }
.bh-split--hremp:not(.bh-split--closed) .bh-split__list .data-table tbody td:nth-child(3) { grid-column: 1; grid-row: 2; }
.bh-split--hremp:not(.bh-split--closed) .bh-split__list .data-table tbody td:nth-child(4) { grid-column: 2; grid-row: 2; text-align: right; white-space: nowrap; }
.bh-split--hremp:not(.bh-split--closed) .bh-split__list .data-table tbody td:not(:nth-child(2), :nth-child(3), :nth-child(4), :nth-child(6)) { display: none; }

/* HR Leave: 1 Employee  6 Status  |  2 Type  3 From. The Actions column drops out with
   everything else - Approve and Reject are on the record open beside the list. */
.bh-split--hrlv:not(.bh-split--closed) .bh-split__list .data-table tbody td:nth-child(1) { grid-column: 1; grid-row: 1; font-size: 13px; font-weight: 700; color: var(--text-primary); }
.bh-split--hrlv:not(.bh-split--closed) .bh-split__list .data-table tbody td:nth-child(6) { grid-column: 2; grid-row: 1; text-align: right; white-space: nowrap; }
.bh-split--hrlv:not(.bh-split--closed) .bh-split__list .data-table tbody td:nth-child(2) { grid-column: 1; grid-row: 2; }
.bh-split--hrlv:not(.bh-split--closed) .bh-split__list .data-table tbody td:nth-child(3) { grid-column: 2; grid-row: 2; text-align: right; white-space: nowrap; }
.bh-split--hrlv:not(.bh-split--closed) .bh-split__list .data-table tbody td:not(:nth-child(1), :nth-child(2), :nth-child(3), :nth-child(6)) { display: none; }

/* HR System Access: 1 Username  5 Status  |  2 Name  3 Role */
.bh-split--hracc:not(.bh-split--closed) .bh-split__list .data-table tbody td:nth-child(1) { grid-column: 1; grid-row: 1; font-size: 13px; font-weight: 700; color: var(--text-primary); }
.bh-split--hracc:not(.bh-split--closed) .bh-split__list .data-table tbody td:nth-child(5) { grid-column: 2; grid-row: 1; text-align: right; white-space: nowrap; }
.bh-split--hracc:not(.bh-split--closed) .bh-split__list .data-table tbody td:nth-child(2) { grid-column: 1; grid-row: 2; }
.bh-split--hracc:not(.bh-split--closed) .bh-split__list .data-table tbody td:nth-child(3) { grid-column: 2; grid-row: 2; text-align: right; white-space: nowrap; }
.bh-split--hracc:not(.bh-split--closed) .bh-split__list .data-table tbody td:not(:nth-child(1), :nth-child(2), :nth-child(3), :nth-child(5)) { display: none; }

/* The ledger's brought-forward line. It is not a posting - no date, no reference, nothing to
   open - so it reads as a heading for the column of figures under it rather than as the first
   row of them (27 Sep 2026). */
.lt tbody tr.lt-bf > td {
  background: var(--slate-50, #f8fafc);
  font-weight: 600;
  color: var(--text-muted);
  border-bottom: 1px solid var(--slate-200, #e2e8f0);
}
.lt tbody tr.lt-bf:hover > td { background: var(--slate-50, #f8fafc); }

/* ===========================================================================
   A DASHBOARD CARD THAT HOLDS SEVERAL PANES (Khalid, 25 Sep 2026)

   The Sales Manager dashboard was four stacked rows of uneven height: a tall Won / Lost
   pair (both card--h-lg for two short lists), then two cards pinned at 420px. Panels
   that belong together are one card with tabs now, which makes the rows the same height
   as each other and halves how far the page scrolls.

   A pane's block still brings its own .card - they are used standalone elsewhere - so
   inside here that card gives up its border, radius and fixed height and becomes just
   the pane's contents.
============================================================================ */

.bh-dashcard { margin-bottom: var(--space-5, 20px); }

/* A dashboard laid out as two rows of two, sized so the whole page is on screen without
   scrolling (Khalid, 26 Sep 2026). The height is what is left after the header, the page
   title, the KPI strip, the gap between the rows and the footer - split between the two
   rows. Below that the cards fall back to a fixed height and the page scrolls, which is
   the right way round: a laptop should not be made to squeeze four lists into 200px. */
/* As many equal columns as the row has cards. Team Plans is a card of its own now
   (emxml_blkTaskDash.xml), so a row that carries the Tasks card carries two - and for a
   login with nobody reporting to them the Team card is display:none, which takes it out
   of the grid entirely rather than leaving a gap. auto-fit does both without the
   dashboard having to say how many it has. */
.dash-split.bh-dashrow {
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  margin-bottom: var(--space-4, 16px);
}

/* A grid cell whose card comes from the block inside it, so the cell itself carries no
   chrome and just passes the height down. */
.bh-dashcell { display: flex; flex-direction: column; min-width: 0; }
.bh-dashcell > div,
.bh-dashcell > .card {
  flex: 1 1 auto;
  min-height: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
}

/* A card one level further down still stretches. The rule above reaches the cell's DIRECT
   child only, so a block that wraps its card in a plain div - which is the ordinary way to
   write a block - put the card out of reach: it kept its own height, the .csb under it
   computed to 0 against a table hundreds of pixels tall, and the card's overflow:hidden
   clipped the lot. The panel then showed its heading and nothing else while the KPI beside
   it counted the very rows that were sitting in the table.

   The three Inventory dashboard panels have been fixed properly - their card is the block's
   root now - but this is here so the next block written that way simply works (Khalid,
   29 Sep 2026; it had gone wrong this way before). */
.bh-dashcell > div > .card {
  flex: 1 1 auto;
  min-height: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
}
.bh-dashrow > .bh-dashcell > div > .card > .csb { flex: 1 1 auto; min-height: 0; }

/* A TABBED card in a dashboard cell. Its .csb is not the card's child - the panes wrapper and
   the pane sit between them - so the card's height stops at the wrapper and the .csb measures
   itself against nothing: Won/Lost came out 335px tall inside a 260px card and the card's
   overflow:hidden ate the bottom of the list, unreachable because there was nothing to
   scroll. #dashTabPanes, #taskTabPanes and #mgrDeskPanes are handled by name further up, at a
   fixed 420px; a dash cell is 260 and flexible, so this passes the height down instead of
   naming ids - the next tabbed card needs no CSS at all (Khalid, 29 Sep 2026).

   :has(.tbar) keeps it to tabbed cards. A plain card's .csb is already the card's own child
   and must not have its .table-wrap turned into a flex item. */
.bh-dashrow .bh-dashcell .card:has(> .ch .tbar) > div:not(.ch),
.bh-dashrow .bh-dashcell .card:has(> .ch .tbar) > div:not(.ch) > div {
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  flex-direction: column;
}

/* The three named pane wrappers are 420px tall by the rules further up, which is right on a
   page that scrolls. In a dashboard ROW the row decides the height - 260 when the window is
   short - and 420 does not fit in it: the tasks card on the HR dashboard came out 367px of
   body inside a 244px card, clipped by the card's overflow:hidden with nothing to scroll,
   while the same card on Manager was fine only because that row happened to be 472 tall.
   Inside a row the pane takes the row's height instead (Khalid, 29 Sep 2026). */
.bh-dashrow #dashTabPanes,
.bh-dashrow #taskTabPanes,
.bh-dashrow #mgrDeskPanes {
  min-height: 0;
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
}
.bh-dashrow #dashTabPanes > div,
.bh-dashrow #taskTabPanes > div,
.bh-dashrow #mgrDeskPanes > div {
  height: auto;
  flex: 1 1 auto;
  min-height: 0;
}

.bh-dashrow > .bh-dashcard,
.bh-dashrow > .bh-dashcell,
.bh-dashrow > .bc-taskdash {
  height: max(260px, calc((100vh - 400px) / 2));
  display: flex;
  flex-direction: column;
  margin-bottom: 0;
}

/* The scrolling body of each card takes whatever the card has left, rather than the
   card growing to fit its list. */
.bh-dashrow > .bh-dashcard > .csb,
.bh-dashrow > .bh-dashcard > [id$="Panes"] > .csb,
.bh-dashrow > .bh-dashcell .csb,
.bh-dashrow > .bc-taskdash .csb {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
}
.bh-dashrow > .bh-dashcard > [id$="Panes"] {
  flex: 1 1 auto;
  min-height: 0;
}

/* The shared Tasks card brings its own card wrapper; in the grid it IS the card. */
.bh-dashrow > .bc-taskdash > .card {
  flex: 1 1 auto;
  min-height: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
}

@media (max-width: 900px) {
  /* Stacked, so a fixed height would only crop things. The card bodies have to give up
     flex: 1 as well: in a column of auto height that resolves to nothing, and the first
     three cards collapsed to about 60px each - the header and no list. They size to
     their content here, with a cap so one long list cannot own the whole page. */
  .bh-dashrow > .bh-dashcard,
  .bh-dashrow > .bh-dashcell,
  .bh-dashrow > .bc-taskdash { height: auto; }
  .bh-dashrow > .bh-dashcard > .csb,
  .bh-dashrow > .bh-dashcard > [id$="Panes"],
  .bh-dashrow > .bh-dashcard > [id$="Panes"] > .csb,
  .bh-dashrow > .bh-dashcell .csb,
  .bh-dashrow > .bc-taskdash .csb {
    flex: 0 1 auto;
    /* bizcore sets height: 0 on .csb so it can be a flex:1 pane. With the card back to
       auto height that zero is simply the height, and min-height does not undo it -
       the card rendered as its header and nothing else. */
    height: auto;
    max-height: 60vh;
  }
}

.bh-dashcard .card {
  border: 0;
  border-radius: 0;
  box-shadow: none;
  margin: 0;
  /* The blocks set height:420px inline; in a pane the card is whatever its pane is. */
  height: auto !important;
}

/* A pane's own card header is redundant - the tab already names it. */
.bh-dashcard .card > .ch { display: none; }

/* One height for every pane, so switching tabs does not move the page under you. */
.bh-dashcard [id$="Panes"] > div { min-height: 340px; }
.bh-dashcard .card-body-scroll,
.bh-dashcard .csb {
  max-height: 340px;
  overflow-y: auto;
}

/* The total under a pipeline stage heading: the figure the column is about, so it is
   given the same gutter as the heading above it and enough weight to be read as a total
   rather than as a caption. */
.bh-stagetotal {
  padding: 8px 14px;
  font-size: 14px;
  font-weight: 700;
  color: var(--text-primary);
}

/* A record's field grid. bizcore.css pins .fg to two columns, so a record with four
   short fields used two lines and half the width for no reason (Khalid, 27 Sep 2026).

   The minimum track is the larger of 180px and a quarter of the row (less the three
   gaps), so it fits at most four across and drops to three, two or one as the pane
   narrows - no breakpoints, and the same rule works in a 380px rail and a 1300px
   full-width record. */
.fg {
  grid-template-columns: repeat(auto-fit, minmax(max(180px, calc(25% - 12px)), 1fr));
  gap: 14px 16px;
}

/* A field holding prose rather than a value takes the whole row: squeezed into a
   quarter it wraps to six lines and pushes everything beside it out of line. */
.fg > .fg-wide { grid-column: 1 / -1; }

/* The same four-up strip, for the records that write their fields as a two column
   label/value table instead. One pair per LINE meant a record with eight short fields
   ran eight lines deep and used a third of the width. Only tables whose every row is a
   label and a value carry this class, so totals and line tables are untouched.

   table -> grid, tbody -> contents, and each row becomes a column of its own with the
   label above the value. */
table.fg-table {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(max(180px, calc(25% - 12px)), 1fr));
  gap: 12px 16px;
  width: 100%;
}
table.fg-table > tbody { display: contents; }
table.fg-table tr {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}
table.fg-table td {
  display: block;
  padding: 0;
  border: 0;
  min-width: 0;
}
table.fg-table td:first-child {
  font-size: 10.5px;
  letter-spacing: .06em;
  text-transform: uppercase;
  font-weight: 700;
  color: var(--text-muted);
  width: auto;
}
table.fg-table td:last-child {
  font-size: 13px;
  font-weight: 600;
  color: var(--text-primary);
  overflow-wrap: anywhere;
}

/* A row whose value is prose - a note, an address - takes the whole line. */
table.fg-table tr.fg-wide { grid-column: 1 / -1; }

/* A toolbar above a list: a field label beside its control, not a heading over a box
   that stretches the width of the card (Khalid, 27 Sep 2026). */
.bh-toolbar {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 10px;
}
.bh-toolbar__label {
  font-size: 10.5px;
  letter-spacing: .06em;
  text-transform: uppercase;
  font-weight: 700;
  color: var(--text-muted);
  margin: 0;
}
.bh-toolbar__field {
  width: auto;
  min-width: 200px;
  max-width: 320px;
  margin-right: 6px;
}

/* The Inventory batches rail holds THREE lists behind tabs and they do not share a
   column order, so each pane names its own parts rather than one set of positions
   standing for all three (27 Sep 2026). */

/* Expiring Soon: 1 Product 2 Batch 3 Location 4 In stock 5 Expires 6 Days left 7 Action */
.bh-split:not(.bh-split--closed) .bh-split__list #invBatchPaneExp .lt tbody td:nth-child(1) { grid-column: 1; grid-row: 1; font-size: 13px; font-weight: 700; color: var(--text-primary); }
.bh-split:not(.bh-split--closed) .bh-split__list #invBatchPaneExp .lt tbody td:nth-child(4) { grid-column: 2; grid-row: 1; font-size: 13px; font-weight: 700; color: var(--text-primary); text-align: right; white-space: nowrap; }
.bh-split:not(.bh-split--closed) .bh-split__list #invBatchPaneExp .lt tbody td:nth-child(2) { grid-column: 1; grid-row: 2; }
.bh-split:not(.bh-split--closed) .bh-split__list #invBatchPaneExp .lt tbody td:nth-child(6) { grid-column: 2; grid-row: 2; text-align: right; white-space: nowrap; }
.bh-split:not(.bh-split--closed) .bh-split__list #invBatchPaneExp .lt tbody td:not(:nth-child(1), :nth-child(2), :nth-child(4), :nth-child(6)) { display: none; }

/* Batches: 1 Product 2 SKU 3 Batch 4 Location 5 In stock 6 State 7 Expires 8 Received 9 Action */
.bh-split:not(.bh-split--closed) .bh-split__list #invBatchPaneAll .lt tbody td:nth-child(1) { grid-column: 1; grid-row: 1; font-size: 13px; font-weight: 700; color: var(--text-primary); }
.bh-split:not(.bh-split--closed) .bh-split__list #invBatchPaneAll .lt tbody td:nth-child(5) { grid-column: 2; grid-row: 1; font-size: 13px; font-weight: 700; color: var(--text-primary); text-align: right; white-space: nowrap; }
.bh-split:not(.bh-split--closed) .bh-split__list #invBatchPaneAll .lt tbody td:nth-child(3) { grid-column: 1; grid-row: 2; }
.bh-split:not(.bh-split--closed) .bh-split__list #invBatchPaneAll .lt tbody td:nth-child(6) { grid-column: 2; grid-row: 2; text-align: right; white-space: nowrap; }
.bh-split:not(.bh-split--closed) .bh-split__list #invBatchPaneAll .lt tbody td:not(:nth-child(1), :nth-child(3), :nth-child(5), :nth-child(6)) { display: none; }

/* Serials: 1 Product 2 Serial 3 Status 4 Location 5 Order 6 Customer */
.bh-split:not(.bh-split--closed) .bh-split__list #invBatchPaneSer .lt tbody td:nth-child(1) { grid-column: 1; grid-row: 1; font-size: 13px; font-weight: 700; color: var(--text-primary); }
.bh-split:not(.bh-split--closed) .bh-split__list #invBatchPaneSer .lt tbody td:nth-child(3) { grid-column: 2; grid-row: 1; font-size: 13px; font-weight: 700; color: var(--text-primary); text-align: right; white-space: nowrap; }
.bh-split:not(.bh-split--closed) .bh-split__list #invBatchPaneSer .lt tbody td:nth-child(2) { grid-column: 1; grid-row: 2; }
.bh-split:not(.bh-split--closed) .bh-split__list #invBatchPaneSer .lt tbody td:nth-child(4) { grid-column: 2; grid-row: 2; text-align: right; white-space: nowrap; }
.bh-split:not(.bh-split--closed) .bh-split__list #invBatchPaneSer .lt tbody td:not(:nth-child(1), :nth-child(2), :nth-child(3), :nth-child(4)) { display: none; }

/* ===========================================================================
   .csb INSIDE A TAB PANE (Khalid, 27 Sep 2026 - this one hid real data)

   bizcore.css sets `.csb { flex: 1; height: 0 }` so a card body can fill a card that has
   a height. That works only while .csb is a DIRECT flex child of the card. Putting the
   lists behind tabs adds a pane wrapper between them, and the height: 0 then stops being
   a flex basis and simply becomes the height: the card collapsed to its tab bar, the
   table inside stayed 1208px tall and was clipped away by the card's overflow, and every
   list on Inventory's Bins, Batches and dashboard looked empty while the rows were
   sitting in the DOM all along.

   Inside a pane the body sizes to its content. Where it needs to scroll - the rail of a
   split, a dashboard card - the rules for those give it a height to scroll within.
============================================================================ */

.bh-rtabs [id$="Panes"] .csb,
.bh-dashcard [id$="Panes"] .csb,
.bh-dashcell [id$="Panes"] .csb {
  flex: 0 1 auto;
  height: auto;
  min-height: 0;
}

/* The card must not clip what it now contains. */
.bh-rtabs { overflow: visible; }

/* In a split rail the tabbed card DOES have a height, so its panes scroll within it. */
.bh-split:not(.bh-split--closed) .bh-split__list .card.bh-rtabs { overflow: hidden; }
.bh-split:not(.bh-split--closed) .bh-split__list .card.bh-rtabs [id$="Panes"] .csb {
  height: auto;
  max-height: none;
  overflow: visible;
}

/* A split closed from the page rather than by a re-render: the record goes and the list
   takes the width back, keeping its tab and its scroll position (27 Sep 2026). */
/* Named twice so it beats the two-column .bh-split rule further down the sheet. */
.bh-split.bh-split--closed { grid-template-columns: minmax(0, 1fr); }
.bh-split--closed .bh-split__detail { display: none; }
.bh-split--closed .card.bh-rtabs { grid-area: list; }
/* ...and it is a plain card again, so it grows with its list and lets the page scroll.
   .bh-split is flex: 1 1 auto so it can fill the viewport beside a record; left that
   way with the record gone it was squeezed back to the height it had, and overflow:
   hidden cut off everything below - the list simply stopped, with no scrollbar anywhere
   (Khalid, 27 Sep 2026). */
.bh-split--closed { flex: 0 0 auto; min-height: 0; }
/* Nothing to undo below this: every rule that makes a list look like a rail is written
   :not(.bh-split--closed), so with the class on, the table simply is a table again.
   Undoing them one by one did not work - the per-page rules that hide columns are more
   specific than any blanket reset, so a closed list came back with cells missing and its
   values under the wrong headings (Khalid, 27 Sep 2026). */

/* A heading part-way down a record - "Recent Moves" under the bin's own stock. It was
   a bare <h4> inside the card body, so it sat hard against the left edge with no room
   above it (Khalid, 27 Sep 2026). Same gutter and weight as the card's own header. */
.bh-subhead {
  padding: 16px 20px 10px;
  border-top: 1px solid var(--border);
  min-height: 46px;
  display: flex;
  align-items: center;
}
.bh-subhead .ct { margin: 0; font-size: 13px; font-weight: 700; }

/* Inventory bins rail: 1 Code 2 Zone 3 Type 4 Sequence ... - the code and what is in it
   are what you pick from. */
.bh-split--invbin:not(.bh-split--closed) .bh-split__list #invBinPaneBins .lt tbody td:nth-child(1) { grid-column: 1; grid-row: 1; font-size: 13px; font-weight: 700; color: var(--text-primary); }
.bh-split--invbin:not(.bh-split--closed) .bh-split__list #invBinPaneBins .lt tbody td:nth-child(2) { grid-column: 1; grid-row: 2; }
/* and nothing else: a bin row has eight cells, and left to stack they made a card the
   height of a small page (Khalid, 27 Sep 2026). */
.bh-split--invbin:not(.bh-split--closed) .bh-split__list #invBinPaneBins .lt tbody td:nth-child(7) { grid-column: 2; grid-row: 1; font-size: 12px; font-weight: 600; color: var(--text-muted); text-align: right; white-space: nowrap; }
.bh-split--invbin:not(.bh-split--closed) .bh-split__list #invBinPaneBins .lt tbody td:not(:nth-child(1)):not(:nth-child(2)):not(:nth-child(7)) { display: none; }

/* A row opens its record, so it should look like it does. This was a list of the seven
   per-list class names, which meant every app converted after it had to remember to add
   its own. A row that opens a record carries the onclick that opens it, so that is the
   thing to match - the classes are still on the rows, nothing else needs them. */
.lt tbody tr[onclick],
.data-table tbody tr[onclick] { cursor: pointer; }
.lt tbody tr[onclick]:hover,
.data-table tbody tr[onclick]:hover { background: var(--c-primary-xlight); }

/* The row whose record is open beside the list. A left bar rather than a wash, so it
   still reads as selected against the hover colour and against the striping the list
   already has. The marker comes from the row's own SQL, so it survives a re-render. */
.lt tr.is-open > td,
.data-table tr.is-open > td {
  background: var(--c-primary-xlight);
  font-weight: 600;
}
.lt tr.is-open > td:first-child,
.data-table tr.is-open > td:first-child {
  box-shadow: inset 3px 0 0 0 var(--c-primary);
}
/* ...but not in the rail, where the row is a card and its own border-left carries the
   mark. The first cell there is the reference on the second line, so this drew a short
   bar beside it that looked like a stray text cursor. */
.bh-split:not(.bh-split--closed) .bh-split__list .lt tr.is-open > td:first-child,
.bh-split:not(.bh-split--closed) .bh-split__list .data-table tr.is-open > td:first-child { box-shadow: none; }
.lt tr.is-open:hover > td,
.data-table tr.is-open:hover > td { background: var(--c-primary-xlight); }

@media (max-width: 900px) {
  /* No room for two columns - the record takes the page, Close returns to the list.
     The action strip and the tab bar keep their own rows; only the rail goes. Named
     twice over to beat the display:contents above, which is the same specificity and
     comes first. */
  .bh-split {
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: auto auto minmax(0, 1fr);
    grid-template-areas:
      "action"
      "tabs"
      "detail";
  }
  /* :not(.bh-split--closed) is not decoration. Every rail rule above is written that
     way, and a :not() counts towards specificity, so a plain .bh-split .bh-split__list
     lost to them: on a phone bins and batches showed the LIST and the record nowhere
     (Khalid, 27 Sep 2026). Matching their specificity and coming later wins it back -
     and a split closed from the page now gets its list back on a phone too, which is
     the whole point of closing one. */
  .bh-split:not(.bh-split--closed) .bh-split__list,
  .bh-split:not(.bh-split--closed) .bh-split__list > div { display: none; }
  /* ...except the parts that were lifted out of it, which are the page's own controls
     and not part of the rail. */
  .bh-split:not(.bh-split--closed) .bh-split__list > div:has(> .tbar),
  .bh-split:not(.bh-split--closed) .bh-split__list > div > .a-bar,
  .bh-split:not(.bh-split--closed) .bh-split__list > .a-bar { display: flex; }

  /* Closed: one row, the list, no record. The three-row template above names no "list"
     area, so without this the list falls to auto-placement and lands in the strip meant
     for the action bar. */
  .bh-split--closed {
    grid-template-rows: auto;
    grid-template-areas: "list";
  }

  /* Nothing is beside anything here, so the PAGE scrolls and the split is whatever its
     contents are. Kept at viewport height it clipped a long record the same way it
     clipped a long list, and a pane that scrolls inside a page that does not is the
     worst of both on a phone. The height chain that feeds it goes with it. */
  .bh-split {
    flex: 0 0 auto;
    min-height: 0;
  }
  .bh-split__detail { overflow-y: visible; }
  .pg-shell:has(.bh-split:not(.bh-split--closed)) { flex: 0 0 auto; }
  .pg-body:has(.bh-split:not(.bh-split--closed)) {
    display: block;
    overflow: visible;
  }
  #page1:has(.bh-split:not(.bh-split--closed)),
  #page1a:has(.bh-split:not(.bh-split--closed)) {
    display: block;
    flex: 0 0 auto;
  }
}

/* ===========================================================================
   RECORD PANELS - joined rather than scattered (Khalid, 25 Sep 2026)

   Six separate cards with a gap and a radius each wasted a lot of vertical space and
   read as six unrelated things. Inside a record the sections belong together, so the
   record's own wrapper becomes ONE panel and the cards inside it give up their borders,
   radius and margins - hairline rules mark the joins instead. Radius survives only on
   the outermost corners, via overflow:hidden on the wrapper, so the record still reads
   as a card rather than a bare slab; set --bh-record-radius: 0 to go fully square.

   Written against the wrapper rather than against each card because the two detail
   blocks nest differently - Quotes has its sections one level down, Leads two.

   .bh-panel is the same treatment for a page that is all panels and no record - the
   Targets page uses it - so metric pages and record pages are joined up the same way
   from one definition rather than two that can drift apart.
============================================================================ */

.bh-panel { --bh-record-radius: 14px; }

/* In a split the record is a PANE of the one card, not a card of its own: no border and
   no radius, or you get the card-inside-a-card look that made the two halves read as
   separate panels with a gap between them. .bh-panel keeps its chrome - it is used
   standalone on the Targets page. */
.bh-split__detail { --bh-record-radius: 0; }

.bh-panel {
  background: var(--card-bg);
  border: 1px solid var(--border);
  border-radius: var(--bh-record-radius);
  overflow: hidden;
}

.bh-split__detail > div {
  background: var(--card-bg);
  border: 0;
  border-radius: 0;
}

/* The record used to open with a bar carrying nothing but Close, which pushed its whole
   header a row lower than the first row of the rail beside it. Close belongs on the
   record's own header line (Khalid, 25 Sep 2026), so the bar loses its chrome and its
   height and the header starts level with the rail. */
.bh-split__detail .bh-dtbar {
  padding: 0 !important;
  border: 0 !important;
  background: none !important;
  min-height: 0;
}
.bh-split__detail .bh-dtbar:has(> .bh-close:only-child) { display: none; }

/* Every card inside the record gives up its own chrome, the tabbed panel included -
   it is a section of this panel like any other, not a card sitting on top of it. */
.bh-split__detail .card,
.bh-panel .card {
  border: 0;
  border-radius: 0;
  box-shadow: none;
  margin: 0 !important;
  background: transparent;
}

/* Hairlines where two sections meet, vertically and across the two-up row. */
.bh-split__detail .card + .card,
.bh-panel .card + .card,
.bh-split__detail div[style*="grid-template-columns"] + .card,
.bh-panel div[style*="grid-template-columns"] + .card { border-top: 1px solid var(--border); }

.bh-split__detail div[style*="grid-template-columns"],
.bh-panel div[style*="grid-template-columns"] {
  gap: 0 !important;
  padding: 0 !important;
}

/* One row of sections above another. The rule above only covers a card following a row;
   where a ROW follows a ROW - the Targets page is three across, then two across - the
   hairline has to go on the cards of the second row instead. */
.bh-split__detail div[style*="grid-template-columns"] + div[style*="grid-template-columns"] > .card,
.bh-panel div[style*="grid-template-columns"] + div[style*="grid-template-columns"] > .card {
  border-top: 1px solid var(--border);
}
.bh-split__detail div[style*="grid-template-columns"] > .card + .card,
.bh-panel div[style*="grid-template-columns"] > .card + .card {
  border-top: 0;
  border-left: 1px solid var(--border);
}

.bh-split__detail .ap-dhdr,
.bh-split__detail .bh-rechdr { border-bottom: 1px solid var(--border); }
.bh-split__detail .bh-rechdr { padding-top: 16px; }

/* The stage bar is a section in its own right, between the header and the details, so
   it takes the gutter too.

   It is a segmented CONTROL, not a heading, so its box starts at the gutter and its
   label sits inside that - the same as the action buttons above it, whose text is also
   inset by their own padding. The tab bar on the Tasks / Notes card is pulled out
   instead, because there the tabs stand in for a section heading and should line up
   with the other headings. */
.bh-split__detail .bh-recstage { padding: 12px 20px; border-bottom: 1px solid var(--border); }


/* One gutter for every section of the record. Joined up, the sections' own paddings
   stopped being private business and became a ragged left edge - the panels came in at
   24px, card headers at 20px, the tab bar at 12px and one panel body at 0, flush
   against the border. They all line up now, and narrow to 14px on a phone. */
.bh-split__detail .ap-dhdr,
.bh-split__detail .bh-rechdr,
.bh-split__detail .ch,
.bh-split__detail .csb,
.bh-split__detail .cb,
.bh-panel .ch,
.bh-panel .csb,
.bh-panel .cb {
  padding-left: 20px;
  padding-right: 20px;
}

@media (max-width: 767px) {
  .bh-split__detail .bh-recstage { padding: 12px 14px; }

  .bh-split__detail .ap-dhdr,
  .bh-split__detail .bh-rechdr,
  .bh-split__detail .ch,
  .bh-split__detail .csb,
  .bh-split__detail .cb,
  .bh-panel .ch,
  .bh-panel .csb,
  .bh-panel .cb {
    padding-left: 14px;
    padding-right: 14px;
  }
}

/* The Quote Lines section deliberately carries no padding of its own so its table runs
   full width - a rule that stops short of the panel edge looks like a mistake. The
   gutter goes on that table's outer columns instead, which lines it up with every other
   section while its rules still run the whole way across. Scoped to sections that
   actually have padding:0, so a section that already has its own gutter is not indented
   twice. A descendant combinator rather than a child one, because the table is not
   always the section's own child - the Targets page's pipeline table sits a level
   deeper, inside the block that draws it. */
/* !important because the quote lines table sets its cell padding INLINE, per column,
   alongside each column's width - nothing in a stylesheet can outrank that, and
   rewriting eight inline styles to move two gutters is a worse trade. */
.bh-split__detail .csb[style*="padding:0"] table th:first-child,
.bh-split__detail .csb[style*="padding:0"] table td:first-child,
.bh-panel .csb[style*="padding:0"] table th:first-child,
.bh-panel .csb[style*="padding:0"] table td:first-child { padding-left: 20px !important; }
.bh-split__detail .csb[style*="padding:0"] table th:last-child,
.bh-split__detail .csb[style*="padding:0"] table td:last-child,
.bh-panel .csb[style*="padding:0"] table th:last-child,
.bh-panel .csb[style*="padding:0"] table td:last-child { padding-right: 20px !important; }

@media (max-width: 767px) {
  .bh-split__detail .csb[style*="padding:0"] table th:first-child,
  .bh-split__detail .csb[style*="padding:0"] table td:first-child,
  .bh-panel .csb[style*="padding:0"] table th:first-child,
  .bh-panel .csb[style*="padding:0"] table td:first-child { padding-left: 14px !important; }
  .bh-split__detail .csb[style*="padding:0"] table th:last-child,
  .bh-split__detail .csb[style*="padding:0"] table td:last-child,
  .bh-panel .csb[style*="padding:0"] table th:last-child,
  .bh-panel .csb[style*="padding:0"] table td:last-child { padding-right: 14px !important; }
}

/* Tabs card for Tasks / Notes / Mail. The panel blocks inside are untouched - their
   card chrome is removed here and their own titles hidden, because the tab already
   names each one. Their action button stays and sits to the right. */
.bh-rtabs { border-top: 1px solid var(--border); }
.bh-rtabs > .ch { padding-bottom: 0; border-bottom: 1px solid var(--border); }
.bh-rtabs > .ch .tbar { margin-bottom: -1px; }

/* The tab strip had the height of the text and nothing else, so it read as squashed
   against the card edge (Khalid, 27 Sep 2026). Room above and below, and a strip tall
   enough to be a touch target. */
.bh-rtabs > .ch { padding-top: 4px; }
.bh-rtabs > .ch .tbar { min-height: 42px; align-items: stretch; }
.bh-rtabs > .ch .tbar .tb { padding: 11px 14px; line-height: 1.2; }

/* A pane's own card header keeps only its actions - the tab already names it, and the
   title is hidden below. With nothing but a title in it the header was an empty strip
   on one tab and absent on the other, depending on whether that pane had buttons. */
.bh-rtabs .card > .ch:not(:has(button)):not(:has(a)):not(:has(input)):not(:has(select)) {
  display: none;
}

/* A tab carries its own side padding, so with the section gutter as well the first
   label sat 10px further in than every heading below it. Pulling the bar out by that
   much lines the LABEL up with the gutter rather than the tab's box. */
.bh-rtabs > .ch .tbar { margin-left: -10px; }

.bh-rtabs .card > .ch .ct { display: none; }
.bh-rtabs .card > .ch {
  justify-content: flex-end;
  padding-top: 10px;
  padding-bottom: 0;
  border-bottom: 0;
  min-height: 0;
}
.bh-rtabs .card + .card { border-top: 0; }

/* A tab bar wider than its box (Khalid, 25 Sep 2026). Quotes has seven status tabs and
   .tbar is a nowrap flex row with overflow visible, so on a phone four of them sat past
   the right edge with nothing to scroll - the bar itself did not scroll, and neither did
   the page. They were simply unreachable.

   Below 767px the bar wraps instead of scrolling, so every tab is on screen and reachable
   without a gesture; a swipe that hides half the switcher is worse than two rows of tabs.
   The overflow-x fallback covers the case wrapping cannot fix - a single tab wider than
   the screen - and shows a real scrollbar rather than clipping silently. */
.tbar {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: thin;
}
.tbar > .tb { flex: 0 0 auto; }
.tbar::-webkit-scrollbar { height: 4px; }
.tbar::-webkit-scrollbar-thumb { background: var(--border); border-radius: 2px; }

@media (max-width: 767px) {
  .tbar {
    flex-wrap: wrap;
    row-gap: 4px;
    overflow-x: visible;
  }
}

/* A panel whose sections sit SIDE BY SIDE - the row modifier says so rather than the
   CSS guessing from the grid, because a panel may equally stack its sections. The
   hairline runs down between them; on a phone the columns stack and it turns across.
   Panels are spaced from the page header and from each other rather than run together,
   because two rows here are two different readings - where you are against target, and
   what sits behind it. */
.bh-panel { margin-top: 14px; }
.bh-panel:last-child { margin-bottom: 14px; }

.bh-panel--row > .card + .card {
  border-top: 0;
  border-left: 1px solid var(--border);
}

@media (max-width: 767px) {
  /* One column, and edge to edge like every other panel - .pg-body has no padding at
     this width, so dropping the side borders and the radius is all it takes. */
  .bh-panel--row { grid-template-columns: minmax(0, 1fr) !important; }
  .bh-panel--row > .card + .card {
    border-left: 0;
    border-top: 1px solid var(--border);
  }
  .bh-panel {
    border-left: 0;
    border-right: 0;
    border-radius: 0;
  }
}

/* ===========================================================================
   CALENDAR - design C1 (25 Sep 2026)

   emxml_modStaffCalendar.xml is shared by five sites and emxml_modManagerCalendar.xml by
   the Manager app; both now carry the C1 header, so the structure changes for all six.
   Only Sales Staff loads this stylesheet, so the other five get C1's structure with the
   existing bizcore look until their own turn comes.

   The entry pills are coloured in emjs_bizcore_calendar.js rather than here, because the
   colour belongs to the entry TYPE and an administrator sets it - see bcCalFill/bcCalInk.
============================================================================ */

.cal-hdr { align-items: flex-end; }

.cal-eyebrow {
  font-size: 11px;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--text-3);
  font-weight: 700;
  margin-bottom: 3px;
}

/* The month is the page title now, so it carries the weight a page title has. */
.cal-title {
  font-size: 23px;
  font-weight: 800;
  letter-spacing: -0.025em;
  margin: 0;
}

/* Segmented control: one track, the chosen segment filled. Replaces a row of buttons
   that all looked equally pressable. */
.cal-seg {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  background: var(--card-bg);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 3px;
}

.cal-seg .seg {
  height: 30px;
  padding: 0 12px;
  border: 0;
  background: transparent;
  font-family: inherit;
  font-size: 12.5px;
  font-weight: 600;
  color: var(--text-2);
  cursor: pointer;
  border-radius: 8px;
  white-space: nowrap;
}
.cal-seg .seg:hover { background: var(--row-stripe); }
.cal-seg .seg--on {
  background: var(--ink, #1A1E33);
  color: #fff;
  font-weight: 700;
}

/* Date navigation, the colour key and the scope buttons share one strip under the
   header, and it is the panel's top edge. */
.cal-nav {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 14px 16px 0;
  padding: 10px 14px;
  border: 1px solid var(--border);
  border-bottom: 0;
  border-radius: 14px 14px 0 0;
  background: var(--card-bg);
}

.cal-nav__title {
  font-size: 13px;
  font-weight: 700;
  color: var(--text-2);
  margin-left: 4px;
  min-width: 0;
}

.cal-key {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: 14px;
  flex-wrap: wrap;
}
.cal-key__item {
  font-size: 11px;
  font-weight: 600;
  color: var(--text-2);
  display: inline-flex;
  align-items: center;
  gap: 6px;
  white-space: nowrap;
}
.cal-key__dot {
  width: 8px;
  height: 8px;
  border-radius: 3px;
  display: inline-block;
  flex-shrink: 0;
}

.calendar-grid { padding: 0 !important; }

/* The module sets .pg-body's padding inline, and its 16px top held the grid a gap below
   the nav, so the two read as separate things rather than one panel. */
.pg-body:has(.cal-layout) { padding-top: 0 !important; }

.calendar-month {
  border-radius: 0 0 14px 14px;
  border-top: 0;
}

/* The weekday strip was a solid block of brand colour; C1 makes it a quiet track with
   small caps, so colour in this page means an entry type and nothing else. */
.calendar-month__header {
  background: var(--card-bg);
  color: var(--text-3);
  border-bottom: 1px solid var(--border);
}
.calendar-month__dow {
  font-size: 10.5px;
  letter-spacing: .08em;
  text-transform: uppercase;
  font-weight: 700;
}

/* Saturday and Sunday are tinted so a week reads as five working days and two not -
   the sixth and seventh of every seven, in both the strip and the grid. */
.calendar-month__header > *:nth-child(7n-1),
.calendar-month__header > *:nth-child(7n),
.calendar-month__body > *:nth-child(7n-1),
.calendar-month__body > *:nth-child(7n) { background: var(--row-stripe); }

/* The last cell in a row has no neighbour to rule against. */
.calendar-month__body > *:nth-child(7n) { border-right: 0; }

/* Today: the cell tinted and the date in a filled circle. bizcore.css already draws the
   circle, so this only quiets the 2px ring it also drew - that ring is fine on a month
   square but becomes a heavy box when the same class lands on the day view's pane. */
.calendar-month__day--today {
  box-shadow: none;
  background: var(--c-primary-xlight) !important;
}

.calendar-month__entry {
  font-size: 10.5px;
  font-weight: 600;
  padding: 3px 7px;
  border-radius: 6px;
  margin-bottom: 3px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  line-height: 1.45;
}

/* ── Agenda side rail (design C2) ─────────────────────────────────────────────
   The list and the rail share a row. In the other three views the rail is hidden and
   the grid has the width to itself, so this row is a plain block most of the time. */
.cal-layout { display: flex; gap: 16px; align-items: flex-start; }
.cal-layout > .calendar-grid { flex: 1 1 auto; min-width: 0; }

.cal-rail {
  width: 258px;
  flex-shrink: 0;
  display: flex;
  flex-direction: column;
  gap: 14px;
}

.cal-rail__card {
  background: var(--card-bg);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 14px;
}

.cal-rail__hd {
  margin: 0 0 8px;
  font-size: 10.5px;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--text-3);
  font-weight: 700;
}

.mini-head { display: flex; align-items: center; gap: 8px; margin-bottom: 10px; }
.mini-title { flex: 1 1 auto; text-align: center; font-size: 13px; font-weight: 700; }
.mini-nav {
  width: 26px;
  height: 26px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--card-bg);
  color: var(--text-2);
  cursor: pointer;
  font-family: inherit;
  font-size: 14px;
  line-height: 1;
}
.mini-nav:hover { background: var(--row-stripe); }

.mini-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 2px; }

.mini-h {
  font-size: 9.5px;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--text-3);
  font-weight: 700;
  text-align: center;
  padding-bottom: 2px;
}

.mini {
  height: 24px;
  border: 0;
  background: transparent;
  font-family: inherit;
  font-size: 11px;
  font-weight: 600;
  color: var(--text-2);
  cursor: pointer;
  border-radius: 7px;
  padding: 0;
}
.mini:hover { background: var(--row-stripe); }
.mini--dim { color: var(--text-3); opacity: .5; cursor: default; }
/* A day with something on it, so the mini month is a map and not just a date picker. */
.mini--has { background: var(--c-primary-xlight); color: var(--c-primary); font-weight: 700; }
.mini--today { background: var(--c-primary); color: #fff; font-weight: 800; }

.cal-fl {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 7px 0;
  font-size: 12.5px;
  color: var(--text-2);
  cursor: pointer;
}
.cal-fl input { width: 15px; height: 15px; flex-shrink: 0; }

/* ── Agenda (design C2) ───────────────────────────────────────────────────────
   A day per row: when it is on the left, what is on it to the right. The month grid
   shows shape; this shows detail - time, title, and where it is or who it is with,
   none of which fits in a pill in a month cell. */
.calendar-agenda { display: block; }

.agenda-day {
  display: flex;
  gap: 16px;
  padding: 14px 18px;
  border-bottom: 1px solid var(--border);
}
.agenda-day:last-child { border-bottom: 0; }
.agenda-day--today { background: var(--c-primary-xlight); }

.agenda-day__label { width: 92px; flex-shrink: 0; }

.agenda-day__rel {
  font-size: 10.5px;
  letter-spacing: .08em;
  text-transform: uppercase;
  font-weight: 700;
  color: var(--text-3);
}
.agenda-day--today .agenda-day__rel { color: var(--c-primary); }

.agenda-day__date {
  font-size: 19px;
  font-weight: 800;
  letter-spacing: -0.02em;
  color: var(--text-2);
  margin-top: 3px;
}
.agenda-day--today .agenda-day__date { color: var(--text-1); }

.agenda-day__body { flex: 1 1 auto; min-width: 0; }

.agenda-entry {
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 8px 0;
}
.agenda-entry__bar {
  width: 3px;
  align-self: stretch;
  border-radius: 3px;
  flex-shrink: 0;
}
.agenda-entry__time {
  width: 56px;
  flex-shrink: 0;
  font-size: 12.5px;
  font-weight: 700;
  color: var(--text-2);
  font-variant-numeric: tabular-nums;
}
.agenda-entry__main { flex: 1 1 auto; min-width: 0; }
.agenda-entry__title {
  display: block;
  font-size: 13.5px;
  font-weight: 700;
  color: var(--text-1);
}
.agenda-entry__sub {
  display: block;
  font-size: 11.5px;
  color: var(--text-3);
  margin-top: 2px;
}
.agenda-none {
  margin: 0;
  padding: 8px 0;
  font-size: 12.5px;
  color: var(--text-3);
}

@media (max-width: 767px) {
  .pg-body:has(.cal-layout) { padding: 0 !important; }

  /* No room for a rail beside the list; it goes under it, full width. align-items has
     to be reset too - flex-start is what keeps the rail from stretching to the list's
     height in the side-by-side layout, and it stops it filling the width here. */
  .cal-layout { flex-direction: column; gap: 0; align-items: stretch; }
  .cal-rail { width: auto; padding: 14px; }

  /* The day label sits above its entries rather than beside them - 92px of label plus
     a time plus a title does not fit across a phone. */
  .agenda-day { flex-direction: column; gap: 6px; padding: 12px 14px; }
  .agenda-day__label { width: auto; display: flex; align-items: baseline; gap: 8px; }
  .agenda-day__date { margin-top: 0; font-size: 16px; }

  .cal-hdr { flex-direction: column; align-items: stretch; gap: 10px; }
  .cal-seg { width: 100%; justify-content: space-between; }
  .cal-seg .seg { flex: 1 1 auto; text-align: center; padding: 0 8px; }

  .cal-nav {
    margin: 0;
    border-left: 0;
    border-right: 0;
    border-radius: 0;
    flex-wrap: wrap;
  }
  /* The key wraps under the navigation rather than squeezing it off the screen. */
  .cal-key { margin-left: 0; width: 100%; gap: 10px; }

  .calendar-month {
    border-left: 0;
    border-right: 0;
    border-radius: 0;
  }
  /* Day numbers were landing 2px from the screen edge, which reads as clipped even
     though nothing is actually cut off. */
  .calendar-month__day { padding: 4px 6px; }
}

/* The count on a tab. Quiet when the tab is closed and picked out when it is open, so it
   reads as "there are four of these" rather than competing with the label. */
.tb .tb-count {
  display: inline-block;
  margin-left: 6px;
  min-width: 17px;
  padding: 0 5px;
  border-radius: 999px;
  background: var(--neutral-1);
  color: var(--text-3);
  font-size: 10px;
  font-weight: 700;
  line-height: 17px;
  text-align: center;
  vertical-align: 1px;
}
.tb.on .tb-count { background: var(--c-primary-light); color: var(--c-primary); }

/* Two charts on one row. They fall back to one column on a narrow screen, because a
   chart squeezed under 400px stops being readable. */
.bh-chartrow {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 16px;
  margin-top: 16px;
}
.bh-chartrow > .card { margin-top: 0; }

@media (max-width: 1100px) {
  .bh-chartrow { grid-template-columns: minmax(0, 1fr); }
}

/* A card whose header is a tab bar plus an action. The two share one line: the tab bar
   takes what is left and scrolls sideways if its tabs do not fit, and the action keeps
   its place at the right-hand end. Without the nowrap the button dropped onto a second
   line under the tabs, which read as belonging to nothing. */
.ch:has(> .tbar) {
  display: flex;          /* not assumed: a .ch holding a tab bar renders as a block here */
  flex-wrap: nowrap;
  align-items: center;
  gap: 10px;
}

.ch > .tbar {
  flex: 1 1 auto;
  min-width: 0;
  border: 0;
  background: transparent;
  padding: 0;
  overflow-x: auto;
  scrollbar-width: none;
}
.ch > .tbar::-webkit-scrollbar { display: none; }
.ch > .tbar > .tb { flex: 0 0 auto; }

/* Whatever follows the tab bar in the header is the action, and it stays to the right. */
.ch > .tbar ~ .btn,
.ch > .tbar ~ .a-bar { flex: 0 0 auto; margin-left: auto; }

/* ===========================================================================
   SECTION INDEX (25 Sep 2026)

   Borrowed from the Settings designs: an index of sections down the left, the chosen one
   beside it. My Account uses it - seven panels you came to use one of, rather than a
   grid of seven you scroll past.

   The buttons are ordinary .tb tabs so they work with bcTabPanes, which every tabbed
   card in the app already uses; they are simply laid out as a vertical index here rather
   than a horizontal bar. That keeps one switching mechanism in the app instead of two.
============================================================================ */

.bh-secnav {
  display: grid;
  grid-template-columns: minmax(0, 208px) minmax(0, 1fr);
  gap: 16px;
  align-items: start;
}

.bh-secnav__ix {
  display: flex;
  flex-direction: column;
  gap: 2px;
  background: transparent;
  border: 0;
  padding: 0;
  overflow: visible;
}

.bh-secnav__ix .tb {
  display: block;
  width: 100%;
  text-align: left;
  padding: 9px 12px;
  border: 0;
  border-radius: 9px;
  background: transparent;
  font-size: 13px;
  font-weight: 500;
  color: var(--text-2);
  cursor: pointer;
  white-space: nowrap;
}
.bh-secnav__ix .tb:hover { background: var(--row-stripe); color: var(--text-1); }

.bh-secnav__ix .tb.on {
  background: var(--c-primary-xlight);
  color: var(--c-primary);
  font-weight: 700;
}

.bh-secnav__panes { min-width: 0; }

@media (max-width: 900px) {
  /* The index goes above the panel and runs across, because 208px of index plus a panel
     does not fit. It stays a real switcher either way - no section is ever hidden. */
  .bh-secnav { grid-template-columns: minmax(0, 1fr); }
  .bh-secnav__ix {
    flex-direction: row;
    flex-wrap: wrap;
    gap: 4px;
    margin-bottom: 4px;
  }
  .bh-secnav__ix .tb { width: auto; padding: 8px 12px; }
}

/* ===========================================================================
   NATIVE SPLIT PANE (25 Sep 2026)

   Eleven modules were already built as a split pane before any of this - Approvals, the
   five *Reports pages, CRM's companies and contacts, and the rest. They do not need the
   .bh-split blocks the sales pages got; they need the same LOOK, so the two kinds of
   split page do not sit side by side in one app looking unrelated.

   The tab bar is lifted out of the left column to run above both, the same way and for
   the same reason as on the sales lists: squeezed into a 340px rail it wraps into three
   rows and reads as belonging to the list rather than to the page.
============================================================================ */

.split-pane {
  grid-template-columns: minmax(0, 340px) minmax(0, 1fr);
  grid-template-areas:
    "tabs tabs"
    "list detail";
  gap: 14px;
  height: auto;
  overflow: visible;
  align-items: start;
}

/* Dissolves the left column so its tab bar and its list become items of the split grid
   and can land in different rows. */
.split-pane__list {
  display: contents;
}

.split-pane__list > .tbar { grid-area: tabs; }
.split-pane__items,
.split-pane__list-body { grid-area: list; }
.split-pane__detail { grid-area: detail; }

.split-pane__items,
.split-pane__list-body {
  background: var(--card-bg);
  border: 1px solid var(--border);
  border-radius: 14px;
  overflow: hidden;
  min-width: 0;
}

/* The record beside it, as one joined panel - the same as a .bh-split record. */
.split-pane__detail {
  background: var(--card-bg);
  border: 1px solid var(--border);
  border-radius: 14px;
  overflow: hidden;
  padding: 0;
  min-width: 0;
}

.split-pane__detail .card {
  border: 0;
  border-radius: 0;
  box-shadow: none;
  margin: 0;
  background: transparent;
}
.split-pane__detail .card + .card { border-top: 1px solid var(--border); }
.split-pane__detail .ap-dhdr { border-bottom: 1px solid var(--border); }

/* One gutter for every section of the record, as elsewhere. */
.split-pane__detail .ap-dhdr,
.split-pane__detail .ch,
.split-pane__detail .csb,
.split-pane__detail .cb {
  padding-left: 20px;
  padding-right: 20px;
}

/* The chosen row, whatever the module calls it - .ap-item here, .approval-item there.
   Marked the same way as the open row on every other page, so "this one" looks the same
   throughout the app. */
.split-pane__items .selected,
.split-pane__list-body .selected {
  background: var(--c-primary-xlight);
  box-shadow: inset 3px 0 0 0 var(--c-primary);
}

/* Nothing chosen yet: say so quietly rather than filling the pane with a large icon. */
.split-pane__empty { padding: 28px 20px; }
.split-pane__empty .empty-state__icon,
.split-pane__empty-icon { display: none; }

@media (max-width: 900px) {
  /* One column. The list keeps the page and the record opens under it, because these
     modules have no Close button of their own to come back with. */
  .split-pane {
    grid-template-columns: minmax(0, 1fr);
    grid-template-areas: "tabs" "list" "detail";
  }
}

@media (max-width: 767px) {
  .split-pane { gap: 0; }
  .split-pane__items,
  .split-pane__list-body,
  .split-pane__detail {
    border-left: 0;
    border-right: 0;
    border-radius: 0;
  }
  .split-pane__detail .ap-dhdr,
  .split-pane__detail .ch,
  .split-pane__detail .csb,
  .split-pane__detail .cb {
    padding-left: 14px;
    padding-right: 14px;
  }
}

/* Close sits with the record's own actions, pushed to the far end of that row so it
   reads as "leave this record" rather than as one more thing to do to it. */
.bh-close { margin-left: auto; }
.bh-close i { margin-right: 4px; }

/* An action row on a phone must wrap. It did not, and the last button - Schedule
   Follow-up - ran past the viewport with no sideways scroll to reach it, so the
   control was simply unreachable there. */
@media (max-width: 767px) {
  /* The card header is a flex ROW: title on the left, actions on the right. At 375px
     the title took its space first and the actions were pushed past the edge with no
     sideways scroll to reach them, so Schedule Follow-up could not be pressed at all.
     Both levels have to wrap - the header, so the actions drop to their own line, and
     the action row itself, so the buttons stack rather than run off again. */
  .ch {
    flex-wrap: wrap;
    row-gap: 8px;
  }
  .page-actions {
    flex-wrap: wrap;
    gap: 8px;
    row-gap: 8px;
  }
  .bh-close { margin-left: 0; }

  /* The rules above name .ch and .page-actions, which is every action row the Sales
     pages happened to use. The Customer Service details put their buttons in a plain
     inline-styled flex div instead, so none of it applied: on Cases the row measured
     464px inside a 375px viewport and Close sat at x=485, off the right edge. The list
     is display:none at this width, so Close is the ONLY way out of a record - it was
     unreachable. Matching the row that CONTAINS Close covers every shape of it.
     !important is needed because the inline style sets flex-shrink:0 on the row. */
  div:has(> .bh-close) {
    flex-wrap: wrap;
    flex-shrink: 1 !important;
    min-width: 0;
    row-gap: 8px;
  }

  /* The two-up row stacks at this width, so the rule between its halves has to turn
     with it - left as a border-left it hung beside the lower card as a stray line. */
  .bh-split__detail div[style*="grid-template-columns"] > .card + .card {
    border-left: 0;
    border-top: 1px solid var(--border);
  }

  /* A card body clips at overflow-x:hidden, so a table wider than the phone loses its
     last columns with no way to reach them - on the quote detail that took the line
     total and the remove-line button off screen. The quotes list already wraps its own
     table in overflow-x:auto, so scrolling a wide table sideways is this app's existing
     answer; :has(> table) keeps it to card bodies that actually hold one. */
  .csb:has(> table) {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
  }
}

/* A row opens its lead, so it should look like it does */
.lead-row { cursor: pointer; }
.lead-row:hover { background: var(--c-primary-xlight); }

@media (max-width: 900px) {
  /* No room for two columns - the detail takes the page, Back returns to the list */
  .bh-leadsplit { grid-template-columns: minmax(0, 1fr); }
  .bh-leadsplit__list { display: none; }
}

/* bizcore.css splits dashboard rows 2fr / 1fr. Aurora gives both cards the same
   width, so a row reads as two equal panels rather than a main one and a sidebar. */
.dash-split { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }

/* bizcore stacks .dash-split below 900px, but that rule is earlier in the cascade than
   this stylesheet, so the line above was winning at EVERY width and the two cards stayed
   side by side on a phone at about 180px each. Restated here so the stacking survives
   (found 25 Sep 2026; it had been wrong since the dashboard was first converted). */
@media (max-width: 900px) {
  .dash-split { grid-template-columns: minmax(0, 1fr); }
}

.split-pane { gap: var(--space-4); }

.split-pane__list,
.split-pane__items,
.split-pane__detail {
  background: var(--card-bg);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  overflow: hidden;
}

.ap-item { border-left: 3px solid transparent; border-bottom: 1px solid var(--slate-100); }
.ap-item:hover { background: var(--row-stripe); }

.ap-item.selected {
  background: var(--c-primary-xlight);
  border-left-color: var(--c-primary);
}

.ap-list-hdr { border-bottom: 1px solid var(--border); background: var(--card-bg); }

.nf-item { border-bottom: 1px solid var(--slate-100); }
.nf-item:hover { background: var(--row-stripe); }
.nf-item.unread { background: var(--c-primary-xlight); }
.nf-ico { border-radius: var(--radius-md); }
.nf-title { font-weight: 700; color: var(--text-primary); }
.nf-sub   { color: var(--text-muted); font-size: 12px; }
.nf-time  { color: var(--slate-400); font-size: 11.5px; }
.nf-act   { color: var(--c-primary); font-weight: 700; text-decoration: none; }

.ch, .csb { scrollbar-color: var(--slate-200) transparent; }


/* =============================================================================
   18. RESPONSIVE
   The breakpoints bizcore.css already uses. Phase one only adjusts what the
   Aurora values change; the bottom navigation arrives with phase two, when the
   shell markup changes.
============================================================================= */

@media (max-width: 1024px) {
  .nav-item { margin: 1px 6px; justify-content: center; }
}

@media (max-width: 767px) {

  /* -- FIX ------------------------------------------------------------------
     bizcore.css line 587 sets .shell.sidebar--collapsed { grid-template-columns:
     56px 1fr } with no media query, and that selector is more specific than the
     mobile .shell rule, so it wins on a phone too. The result is a two-column
     grid behind a one-column grid-template-areas, which squeezes main into a
     56px strip — the sliver you saw after pressing the hamburger. Worse, the
     collapsed state is remembered in localStorage, so collapsing on a desktop
     leaves the phone broken until you expand it again.
     This restores the single column whatever the collapsed class says.
     It is a pre-existing bug and affects every app; this only fixes the pilot.
  -------------------------------------------------------------------------- */
  .shell.sidebar--collapsed {
    grid-template-columns: 1fr;
    grid-template-areas:
      "header"
      "main";
  }

  .pg-title { font-size: 20px; }
  .kpi-val  { font-size: 22px; }

  /* Full bleed on phones: the content runs to both edges, so panels become bands
     across the screen rather than cards floating with no margin around them.
     Side borders go with the radius — there is no gap left for them to sit in. */
  .card, .dc, .panel,
  .table-wrap,
  .split-pane__list,
  .split-pane__detail {
    border-radius: 0;
    border-left: 0;
    border-right: 0;
  }

  .pg-hdr { border-radius: 0; }

  div:has(> .tbar) {
    border-left: 0;
    border-right: 0;
  }

  /* bizcore.css already reflows tables into blocks here — give each block the
     Aurora card edge so the rows read as separate things */
  .data-table tbody tr,
  .dt tbody tr,
  .lt tbody tr { border-bottom: 1px solid var(--border); }

  .modal {
    border-radius: var(--radius-lg) var(--radius-lg) 0 0;
    box-shadow: var(--shadow-3);
  }

  .modal-header { padding: 16px 18px 14px; }
  .modal-body   { padding: 16px 18px; }
  .modal-footer { padding: 14px 18px calc(14px + env(safe-area-inset-bottom, 0px)); }

  /* Comfortable thumb targets on the controls people actually press */
  .btn { min-height: 44px; }
  .btn-sm { min-height: 38px; }
  .form-input, .form-select, .form-textarea, .form-control { min-height: 44px; }
}


/* =============================================================================
   19. PHONE NAVIGATION
   The bottom bar and the More sheet, from emxml_blkShellBottomNav.xml. Both are
   absent above 767px, so the desktop shell is exactly as it was.
============================================================================= */

.bnav, .msheet { display: none; }

@media (max-width: 767px) {

  .bnav {
    display: flex;
    position: fixed;
    left: 0; right: 0; bottom: 0;
    z-index: 120;
    background: var(--card-bg);
    border-top: 1px solid var(--border);
    padding-bottom: env(safe-area-inset-bottom, 8px);
  }

  .bnav-items { display: contents; }   /* the dynamiclist wrapper must not become a row */

  /* The hamburger toggles a sidebar that is not on screen at this width, and the
     bottom bar now does the navigating, so it has nothing left to do. Hidden
     rather than removed, because the markup is in the shared header block. */
  .header-hamburger { display: none; }

  /* The module apps live in the More sheet on a phone, so the header copy of
     them is redundant — and it is the one that opens a new tab. */
  .header-nav { display: none; }

  .bnav-item {
    flex: 1 1 0;
    min-width: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 3px;
    padding: 9px 2px 7px;
    border: 0;
    background: transparent;
    color: var(--text-muted);
    text-decoration: none;
    font-family: var(--aurora-sans);
    cursor: pointer;
    position: relative;
  }

  .bnav-item.on { color: var(--c-primary); }
  .bnav-item:active { background: var(--bg-2); }

  .bnav-icon  { font-size: 19px; line-height: 1; }
  .bnav-label {
    font-size: 10px;
    font-weight: 700;
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  /* Screen width is scarce on a phone, so the content runs almost to the edge.
     The only padding left is enough to keep the card borders off the bezel, plus
     room at the bottom for the fixed nav bar. */
  .main    { padding: 0 0 84px; }
  .pg-body { padding: 0; }
  .pg-hdr  { padding: 12px 14px; }

  /* The panels are edge to edge, so their own inner padding is what keeps the
     content off the screen edge. */
  div:has(> .tbar):not(.ch):not(.bh-recstage) { padding: 6px 12px 0 !important; }
  .csb, .dc-body, .card-body { padding-left: 14px; padding-right: 14px; }
  .data-table td, .dt td, .lt td,
  .data-table th, .dt th, .lt th { padding-left: 14px; padding-right: 14px; }

  /* ── More sheet ───────────────────────────────────────────────────────── */
  .msheet {
    display: block;
    position: fixed;
    inset: 0;
    z-index: 130;
    background: rgba(20, 24, 44, .5);
    opacity: 0;
    pointer-events: none;
    transition: opacity var(--transition);
  }

  .msheet.on { opacity: 1; pointer-events: auto; }

  .msheet-panel {
    position: absolute;
    left: 0; right: 0; bottom: 0;
    max-height: 86vh;
    display: flex;
    flex-direction: column;
    background: var(--card-bg);
    border-radius: var(--radius-xl) var(--radius-xl) 0 0;
    transform: translateY(14px);
    transition: transform var(--transition-slow);
  }

  .msheet.on .msheet-panel { transform: translateY(0); }

  .msheet-grab {
    width: 40px; height: 4px;
    border-radius: 3px;
    background: #D9DBEB;
    margin: 10px auto 4px;
    flex-shrink: 0;
  }

  .msheet-head {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 8px 18px 14px;
    border-bottom: 1px solid var(--slate-100);
    flex-shrink: 0;
  }

  .msheet-who  { flex-grow: 1; min-width: 0; }
  .msheet-name { font-size: 15px; font-weight: 800; letter-spacing: -.02em; color: var(--text-primary); }
  .msheet-role { font-size: 12px; color: var(--text-muted); margin-top: 2px; }

  .msheet-close {
    width: 34px; height: 34px;
    border: 0;
    border-radius: var(--radius-xl);
    background: var(--bg-2);
    color: var(--text-secondary);
    cursor: pointer;
    flex-shrink: 0;
  }

  .msheet-scroll { flex-grow: 1; min-height: 0; overflow-y: auto; -webkit-overflow-scrolling: touch; }

  .msheet-grp {
    display: flex;
    align-items: baseline;
    gap: 10px;
    padding: 16px 18px 8px;
    font-size: 10px;
    letter-spacing: .11em;
    text-transform: uppercase;
    color: var(--text-muted);
    font-weight: 700;
  }

  .msheet-note { margin-left: auto; text-transform: none; letter-spacing: 0; font-size: 10.5px; font-weight: 500; }

  .msheet-list { display: block; }

  .msheet-item {
    display: flex;
    align-items: center;
    gap: 13px;
    padding: 13px 18px;
    border-bottom: 1px solid var(--slate-100);
    color: var(--text-primary);
    text-decoration: none;
    min-height: 44px;
    box-sizing: border-box;
  }

  .msheet-item:active { background: var(--row-stripe); }
  .msheet-item.on     { background: var(--c-primary-xlight); }
  .msheet-item.on .msheet-lbl { color: var(--brand-800); font-weight: 700; }

  .msheet-ico {
    width: 34px; height: 34px;
    border-radius: var(--radius-md);
    background: var(--bg-2);
    color: var(--text-secondary);
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
  }

  .msheet-ico--app { background: var(--c-primary-light); color: var(--c-primary); }
  .msheet-lbl  { font-size: 14px; font-weight: 600; flex-grow: 1; min-width: 0; }
  .msheet-chev { color: #C3C7DC; flex-shrink: 0; font-size: 13px; }

  .msheet-foot {
    display: flex;
    gap: 10px;
    padding: 12px 18px calc(12px + env(safe-area-inset-bottom, 10px));
    border-top: 1px solid var(--slate-100);
    flex-shrink: 0;
  }

  .msheet-foot .btn {
    flex: 1 1 0;
    border-radius: var(--radius-xl);
    text-align: center;
    display: flex;
    align-items: center;
    justify-content: center;
  }

  .msheet-out { color: var(--c-error); }
}


/* =============================================================================
   20. ACCESSIBILITY
============================================================================= */

@media (prefers-reduced-motion: reduce) {
  * { transition-duration: .01ms !important; animation-duration: .01ms !important; }
}

@media (forced-colors: active) {
  .btn, .card, .dc, .kpi, .modal, .table-wrap { border: 1px solid CanvasText; }
  .nav-item.active { forced-color-adjust: none; }
}

::selection { background: var(--c-primary-light); color: var(--brand-900); }
