/* ===========================================================================
   BAFNA GROUP ERP — enterprise design system.

   THIS IS THE OLD ERP'S DESIGN SYSTEM, ADOPTED WHOLE.

   The visual language below is lifted from the Bafna Group Dashboard's own
   stylesheet (\\192.168.4.10\d$\Bafna Group Dashboard\crm\web\crm.html) — the
   same tokens, the same rail, the same top bar, the same card rhythm, the same
   gold-on-black-on-white. Nothing here was invented: where the old ERP already
   had a rule for a thing, that rule is what this file says.

   One stylesheet for the whole application, in three parts: (1) tokens,
   (2) the application shell, (3) the component kit every screen draws with.

   THE COMPONENT CLASS NAMES ARE THE CURRENT ERP'S, UNCHANGED, ON PURPOSE.
   Sixty-odd screens draw themselves with .card, .panel, .btn, .badge, .modal,
   .tabs and friends, so re-skinning those classes re-skins the whole product
   without touching a line of their code — which is the same trick the old ERP
   played on itself when it was re-skinned. Where a screen needs a look the
   current markup has no class for, it gets the OLD ERP's own class (.tile,
   .sheet, .pill, .out, .subtabs, .chip), never a third style.

   Reference points, as the old file put it: SAP Fiori's information density,
   Oracle Fusion's card rhythm, Dynamics' dark rail, and Apple's restraint
   about shadow and colour.
   =========================================================================== */

/* ------------------------------------------------------------------ tokens */
:root{
  /* Brand */
  --gold:#C89B3C; --gold-600:#B08630; --gold-700:#96701F; --gold-50:#FBF4E4;
  --ink:#111111; --ink-700:#2B2B2B; --ink-500:#4B4B4B;

  /* Surfaces */
  --paper:#F7F7F5; --card:#FFFFFF; --line:#E5E5E5; --line-soft:#EFEFEC;
  --muted:#6B7280; --muted-2:#9096A1;

  /* Status. The -soft tone is the wash, the solid is the mark or fill. The
     text tones are a step darker than the brand swatch so a 12px label still
     clears 4.5:1 on white; the swatch itself is kept for fills and dots. */
  --success:#22C55E; --green:#15803D; --green-soft:#E9F8EE;
  --warn:#F59E0B;    --amber:#B45309; --amber-soft:#FEF4E2;
  --danger:#EF4444;  --red:#DC2626;   --red-soft:#FDECEC;
  --info:#3B82F6;    --blue:#2563EB;  --blue-soft:#EAF1FE;
  --plum:#7C3AED;    --plum-soft:#F2ECFE;
  --purple:var(--plum);

  --mono:'IBM Plex Mono', ui-monospace, "Cascadia Code", Consolas, monospace;
  --sans:'Inter', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;

  /* Elevation — soft only, never a hard drop shadow */
  --sh-1:0 1px 2px rgba(17,17,17,.04), 0 1px 3px rgba(17,17,17,.04);
  --sh-2:0 2px 8px rgba(17,17,17,.05), 0 12px 28px -16px rgba(17,17,17,.16);
  --sh-3:0 18px 44px -18px rgba(17,17,17,.26);

  /* Shape + rhythm */
  --r-card:16px; --r:10px; --r-sm:8px; --r-pill:999px;
  --gap:24px; --pad:16px;
  --rail:264px; --rail-min:76px; --topbar:68px;
  --ease:cubic-bezier(.22,.61,.36,1);

  /* ---- COMPATIBILITY ALIASES ------------------------------------------
     A few dozen inline styles across app.js were written against the previous
     palette's NAMES (--brand, --text-dim, --border, --panel …). Repointing them
     here re-colours every one of them at once, and means the redesign needed no
     edit inside a business screen. This is exactly what the old ERP did for
     itself with --brass / --brass-soft. */
  --brand:var(--gold-700); --brand-2:var(--ink); --brand-soft:var(--gold-50);
  --brass:var(--gold); --brass-soft:var(--gold-50);
  --bg:var(--paper); --panel:var(--card);
  --border:var(--line); --border-2:var(--line);
  --text:var(--ink); --text-dim:var(--ink-500); --text-mute:var(--muted);
  --sidebar:#141414; --sidebar-2:#1D1D1D;
  --shadow:var(--sh-1);
}

*{box-sizing:border-box;margin:0;padding:0}
html{-webkit-text-size-adjust:100%}
html,body,#app{height:100%;min-height:0}
body{background:var(--paper);color:var(--ink);
     font-family:var(--sans);
     font-size:14px;line-height:1.5;-webkit-font-smoothing:antialiased;
     text-rendering:optimizeLegibility;
     /* A file name, an email address or a web address has no spaces in it, so a
        browser will not break it and it simply runs out of its box. break-word
        only breaks a word that would otherwise overflow, and does not change how
        anything is measured, so it is safe to say once for the whole ERP. */
     overflow-wrap:break-word}
/* The app shell owns every scrollbar; the document itself never scrolls. This is
   what keeps the rail and the main content as two independent scroll regions
   instead of one long page. */
html,body{overflow:hidden}
h1,h2,h3,h4{letter-spacing:-.018em}
::selection{background:var(--gold-50);color:var(--ink)}
button,input,select,textarea{font-family:inherit}
button{cursor:pointer}
a{color:var(--gold-700);text-decoration:none}

/* Sankalp 2030 mission as a whisper-faint backdrop — present, never competing
   with the content. If bg-sankalp.jpg isn't there, nothing shows. */
body::before{content:"";position:fixed;inset:0;z-index:0;pointer-events:none;
  background:url('/assets/bg-sankalp.jpg') center/cover no-repeat;opacity:.028}

/* Scrollbars: thin, neutral, never a scenery element */
*::-webkit-scrollbar{width:10px;height:10px}
*::-webkit-scrollbar-thumb{background:#D8D8D4;border-radius:99px;border:3px solid transparent;
  background-clip:content-box}
*::-webkit-scrollbar-thumb:hover{background:#BFBFB9;background-clip:content-box}
*::-webkit-scrollbar-track{background:transparent}


/* ═══════════════════════════════════════════════════════════════════ login
   Two panels: the group on the left, the form on the right. The same page the
   old ERP signs people in with, so signing in and being signed in are visibly
   one product rather than two. */
/* The sign-in page paints its OWN ground. The Sankalp watermark that body::before lays over
   the whole application is deliberately not on it — the old ERP's sign-in page is a separate
   document with no such backdrop, and the mission is already present on this page, at ten times
   the strength, inside the brand panel on the left. Two copies at two strengths read as a
   printing fault. */
.login-wrap{height:100%;display:grid;grid-template-columns:1.05fr .95fr;overflow:auto;
  position:relative;z-index:1;background:var(--paper)}
.login-brand{position:relative;overflow:hidden;padding:56px 60px;
  background:linear-gradient(160deg,#161616 0%,#0D0D0D 100%);color:#fff;
  display:flex;flex-direction:column;justify-content:space-between;gap:34px}
.login-brand::before{content:"";position:absolute;inset:0;
  background:url('/assets/bg-sankalp.jpg') center/cover no-repeat;opacity:.10}
.login-brand::after{content:"";position:absolute;inset:0;
  background:radial-gradient(760px 460px at 12% 8%,rgba(200,155,60,.22),transparent 66%)}
.login-brand>*{position:relative;z-index:1}
.bmark{display:flex;align-items:center;gap:14px}
.bmark img{height:46px;width:46px;object-fit:contain;background:#fff;border-radius:12px;
  padding:5px;box-shadow:0 4px 18px -6px rgba(0,0,0,.7)}
.bmark .n{font-size:17px;font-weight:700;line-height:1.15}
.bmark .t{font-size:9.5px;font-weight:500;letter-spacing:.19em;text-transform:uppercase;
  color:var(--gold);margin-top:3px}
.pitch h2{font-size:38px;font-weight:700;line-height:1.14;max-width:15ch;letter-spacing:-.022em}
.pitch p{margin-top:16px;font-size:14.5px;color:#B7B7B4;max-width:44ch;line-height:1.65}
.points{display:flex;flex-direction:column;gap:13px;margin-top:32px}
.points div{display:flex;align-items:center;gap:11px;font-size:13.5px;color:#D4D4D1}
.points svg{width:17px;height:17px;flex:0 0 17px;color:var(--gold)}
.bfoot{font-size:11.5px;color:#6A6A67;display:flex;gap:18px;flex-wrap:wrap}

.login-side{display:flex;align-items:center;justify-content:center;padding:40px 32px}
.login-card{width:100%;max-width:392px}
.login-card .eyebrow{font-size:9.5px;font-weight:600;letter-spacing:.19em;text-transform:uppercase;
  color:var(--gold-700)}
.login-card h1{font-size:27px;font-weight:700;margin-top:9px;letter-spacing:-.022em}
.login-card .sub{color:var(--muted);font-size:13.5px;margin-top:7px;margin-bottom:12px}
.login-card .field{margin-bottom:0}
.login-card .field label{margin:18px 0 6px}
.login-card .field input{font-size:14px;padding:12px 14px;border-radius:var(--r)}
.login-card .btn.full{width:100%;margin-top:26px;padding:13px;font-size:14px;border-radius:var(--r)}
.login-card .err{font-size:12.5px;min-height:18px;margin-top:14px}
.login-card .hint{margin-top:26px;padding-top:22px;border-top:1px solid var(--line);
  font-size:11.5px;color:var(--muted);line-height:1.75;text-align:left}
.login-card .hint b{color:var(--ink);font-weight:600}
.login-card .hint code{font-family:var(--mono);font-size:11px;background:var(--paper);
  padding:2px 6px;border-radius:5px;border:1px solid var(--line);color:var(--ink-700)}
@media(max-width:1180px){ .login-wrap{grid-template-columns:1fr 1fr} .login-brand{padding:44px} }
@media(max-width:900px){
  .login-wrap{grid-template-columns:1fr;height:auto;min-height:100%}
  .login-brand{padding:30px 24px;gap:22px}
  .pitch h2{font-size:26px} .pitch p{font-size:13.5px}
  .points,.bfoot{display:none}
  .login-side{padding:34px 24px 48px}
}


/* ======================================================== application shell */
.shell,.app{display:flex;height:100vh;height:100dvh;min-height:0;overflow:hidden;
  position:relative;z-index:1}

/* ---- left rail ---------------------------------------------------------- */
.sidebar,.rail{position:relative;flex:0 0 var(--rail);width:var(--rail);z-index:70;
  background:linear-gradient(180deg,#141414 0%,#0F0F0F 100%);
  border-right:1px solid #232323;display:flex;flex-direction:column;min-height:0;
  transition:flex-basis .22s var(--ease),width .22s var(--ease)}
.sidebar::after,.rail::after{content:"";position:absolute;inset:0;pointer-events:none;
  background:radial-gradient(520px 260px at 0% 0%,rgba(200,155,60,.14),transparent 70%)}
.sidebar>*,.rail>*{position:relative;z-index:1}
body.rail-min .sidebar,body.rail-min .rail{flex-basis:var(--rail-min);width:var(--rail-min)}
body.rail-min .r-label,body.rail-min .r-sec,body.rail-min .nav .sect,
body.rail-min .r-badge,body.rail-min .r-foot .rf span,body.rail-min .r-ver{display:none}
body.rail-min .navitem,body.rail-min .r-item{justify-content:center;padding-left:0;padding-right:0}
body.rail-min .brand .rb-txt,body.rail-min .r-brand .rb-txt{display:none}
body.rail-min .brand,body.rail-min .r-brand{justify-content:center;padding:0}
body.rail-min .r-foot .rf{justify-content:center}

.brand,.r-brand{display:flex;align-items:center;gap:11px;height:var(--topbar);flex:0 0 auto;
  padding:0 18px;border-bottom:1px solid #232323}
.brand img,.r-brand img{height:34px;width:34px;object-fit:contain;border-radius:9px;background:#fff;
  padding:3px;box-shadow:0 2px 10px -4px rgba(0,0,0,.6);flex:0 0 34px}
.rb-txt .n{font-size:14px;font-weight:700;color:#fff;line-height:1.15;white-space:nowrap}
.rb-txt .t{font-size:9.5px;font-weight:500;letter-spacing:.17em;text-transform:uppercase;
  color:var(--gold);white-space:nowrap;margin-top:2px}

/* The rail's own scroll region: min-height:0 lets it shrink inside the flex
   column so it scrolls internally, and overscroll-behavior stops a rail scroll
   from ever reaching the main content or the document. */
.nav,.r-scroll{flex:1;min-height:0;overflow-y:auto;overflow-x:hidden;padding:14px 12px 10px;
  overscroll-behavior:contain}
.nav::-webkit-scrollbar,.r-scroll::-webkit-scrollbar{width:6px}
.nav::-webkit-scrollbar-thumb,.r-scroll::-webkit-scrollbar-thumb{background:#2E2E2E;border:0;
  border-radius:99px;background-clip:border-box}
.nav::-webkit-scrollbar-thumb:hover,.r-scroll::-webkit-scrollbar-thumb:hover{background:#3D3D3D;
  background-clip:border-box}
.nav .sect,.r-sec{font-size:9.5px;font-weight:600;letter-spacing:.16em;text-transform:uppercase;
  color:#5E5E5E;padding:16px 12px 7px}
.nav .sect:first-child,.r-sec:first-child{padding-top:2px}

.navitem,.r-item{display:flex;align-items:center;gap:11px;padding:9px 12px;border-radius:var(--r);
  color:#B7B7B4;font-size:13.5px;font-weight:500;cursor:pointer;user-select:none;
  white-space:nowrap;position:relative;transition:background .14s,color .14s}
.navitem svg,.r-item svg{flex:0 0 18px;width:18px;height:18px;stroke-width:1.9}
.navitem .ic{display:grid;place-items:center;flex:0 0 18px;width:18px;height:18px}
.r-label,.navitem .r-label{flex:1;overflow:hidden;text-overflow:ellipsis}
.navitem:hover,.r-item:hover{background:#1D1D1D;color:#fff}
.navitem.active,.r-item.on{background:linear-gradient(90deg,rgba(200,155,60,.20),rgba(200,155,60,.06));
  color:#fff;font-weight:600}
.navitem.active::before,.r-item.on::before{content:"";position:absolute;left:-12px;top:8px;bottom:8px;
  width:3px;border-radius:0 3px 3px 0;background:var(--gold)}
.navitem.active svg,.r-item.on svg{color:var(--gold)}
.r-badge{font-family:var(--mono);font-size:10px;font-weight:500;background:var(--gold);color:#111;
  border-radius:99px;padding:1px 7px;min-width:20px;text-align:center;line-height:1.5}

.r-foot{flex:0 0 auto;border-top:1px solid #232323;padding:12px}
.r-foot .rf{display:flex;align-items:center;gap:10px;padding:8px 10px;border-radius:var(--r);
  color:#8E8E8B;font-size:12.5px;font-weight:500;cursor:pointer;text-decoration:none;
  background:none;border:0;width:100%;box-shadow:none;text-align:left}
.r-foot .rf:hover{background:#1D1D1D;color:#fff;box-shadow:none;border-color:transparent}
.r-foot .rf svg{width:17px;height:17px;flex:0 0 17px}
.r-ver{font-family:var(--mono);font-size:9.5px;color:#4A4A4A;padding:9px 10px 2px;
  letter-spacing:.05em}

/* ---- main column -------------------------------------------------------- */
.main-wrap,.main{flex:1;min-width:0;min-height:0;display:flex;flex-direction:column;overflow:hidden}

/* ---- top bar ------------------------------------------------------------ */
.topbar{flex:0 0 auto;z-index:60;height:var(--topbar);
  display:flex;align-items:center;gap:16px;padding:0 24px;
  background:rgba(255,255,255,.86);backdrop-filter:saturate(180%) blur(14px);
  -webkit-backdrop-filter:saturate(180%) blur(14px);border-bottom:1px solid var(--line)}
.hamb{display:grid;place-items:center;width:38px;height:38px;min-height:0;border-radius:var(--r);
  border:1px solid var(--line);background:var(--card);color:var(--ink-500);cursor:pointer;
  flex:0 0 auto;padding:0;transition:.14s;background-image:none}
.hamb:hover{border-color:var(--gold);color:var(--gold-700);background:var(--gold-50);
  box-shadow:none;background-image:none}
.hamb svg{width:18px;height:18px}
.tb-title{min-width:0;flex:0 0 auto}
.tb-title h1,.topbar .title{font-size:19px;font-weight:700;line-height:1.2;color:var(--ink);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;letter-spacing:-.02em}
.tb-title .crumb{display:flex;align-items:center;gap:6px;font-size:11.5px;color:var(--muted);
  margin-top:1px;white-space:nowrap}
.tb-title .crumb b{font-weight:500;color:var(--gold-700)}
.topbar .spacer{flex:1}

/* The company switcher. Deliberately looks like a scope selector rather than a
   filter chip — in a group ERP "which company am I in" is the frame everything
   else is read inside, so it sits next to the page title, not in the toolbar. */
.tb-co{flex:0 0 auto;position:relative}
.tb-co .co{display:flex;align-items:center;gap:9px;padding:6px 11px;border-radius:var(--r);
  border:1px solid var(--line);background:var(--card);cursor:pointer;transition:.14s;
  max-width:260px;font-weight:500;box-shadow:none;background-image:none;min-height:0}
.tb-co .co:hover{border-color:var(--gold);background:var(--gold-50);box-shadow:none;
  background-image:none}
/* A single-company account has nothing to choose. The control still NAMES the company — that is
   the frame every screen is read inside — but it stops inviting a click it cannot honour. */
.tb-co .co.fixed{cursor:default;background:var(--paper)}
.tb-co .co.fixed:hover{border-color:var(--line);background:var(--paper)}
.tb-co .co>svg:first-child{width:15px;height:15px;color:var(--gold-700);flex:0 0 15px}
.tb-co .co .cot{min-width:0;text-align:left}
.tb-co .co .k{font-size:9px;font-weight:600;letter-spacing:.13em;text-transform:uppercase;
  color:var(--muted-2);line-height:1.2}
.tb-co .co .n{font-size:12.5px;font-weight:600;color:var(--ink);line-height:1.25;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.tb-co .co .cv{width:13px;height:13px;color:var(--muted-2);flex:0 0 13px}
/* Wide enough for a legal entity's full name, and never wider than the screen —
   it is pinned to the left of the button, so on a narrow window it would
   otherwise hang off the right-hand edge. */
.tb-co .menu{position:absolute;top:calc(100% + 6px);left:0;z-index:120;display:none;
  width:340px;max-width:calc(100vw - 24px);max-height:min(70vh,460px);overflow-y:auto;
  flex-direction:column;background:var(--card);border:1px solid var(--line);border-radius:12px;
  padding:7px;box-shadow:var(--sh-3);animation:popIn .15s var(--ease)}
.tb-co.open .menu{display:flex}
.tb-co .menu .hd{font-size:9.5px;font-weight:600;letter-spacing:.13em;text-transform:uppercase;
  color:var(--muted-2);padding:7px 10px 5px}
.tb-co .menu a{display:flex;align-items:center;gap:9px;padding:9px 10px;border-radius:var(--r-sm);
  font-size:12.5px;cursor:pointer;color:var(--ink-700)}
/* The tick on the row you are already in. Without a size of its own an <svg> is
   300x150, which leaves no room at all for the name beside it. */
.tb-co .menu a svg{width:15px;height:15px;flex:0 0 15px;color:var(--gold-700)}
.tb-co .menu a>div{flex:1;min-width:0}
/* A company name may run onto a second line, but it is broken between words and
   never through the middle of one. */
.tb-co .menu a>div{overflow-wrap:normal;word-break:normal}
.tb-co .menu a:hover{background:var(--paper)}
.tb-co .menu a.on{background:var(--gold-50);color:var(--gold-700);font-weight:600}
@media(max-width:1180px){.tb-co .co .k{display:none}}
@media(max-width:900px){.tb-co{display:none}}

.tb-actions{display:flex;align-items:center;gap:6px;flex:0 1 auto;min-width:0;margin-left:auto}
.iconbtn{position:relative;display:grid;place-items:center;width:38px;height:38px;min-height:0;
  padding:0;border-radius:var(--r);border:1px solid transparent;background:transparent;
  background-image:none;color:var(--ink-500);cursor:pointer;transition:.14s}
.iconbtn svg{width:19px;height:19px;stroke-width:1.8}
.iconbtn:hover{background:var(--gold-50);color:var(--gold-700);border-color:#F0E4C7;
  box-shadow:none;background-image:none}
.tb-sep{width:1px;height:26px;background:var(--line);margin:0 5px}

.profile{display:flex;align-items:center;gap:10px;padding:5px 10px 5px 5px;
  border-radius:var(--r-pill);border:1px solid var(--line);background:var(--card);
  cursor:pointer;transition:.14s;position:relative}
.profile:hover{border-color:var(--gold);box-shadow:var(--sh-1)}
.pf-av,.avatar{width:30px;height:30px;border-radius:50%;display:grid;place-items:center;flex:0 0 30px;
  background:linear-gradient(135deg,var(--gold-600),var(--gold-700));color:#fff;
  font-size:11.5px;font-weight:700}
.pf-txt{min-width:0}
.pf-txt .n{font-size:12.5px;font-weight:600;line-height:1.15;white-space:nowrap;max-width:160px;
  overflow:hidden;text-overflow:ellipsis}
.pf-txt .r{font-size:10.5px;color:var(--muted);line-height:1.2}
.profile>svg:last-child{width:15px;height:15px;color:var(--muted-2);flex:0 0 15px}
@media(max-width:1120px){ .profile .pf-txt{display:none} .profile{padding:5px} }

/* The profile popover hung off the top bar. */
.pop{position:absolute;top:calc(100% + 8px);right:0;z-index:120;width:250px;
  display:none;flex-direction:column;overflow:hidden;background:var(--card);
  border:1px solid var(--line);border-radius:14px;box-shadow:var(--sh-3);
  animation:popIn .16s var(--ease);cursor:default}
.pop.on{display:flex}
.pop-h{padding:13px 16px;border-bottom:1px solid var(--line);font-size:13px;font-weight:700}
.pop-h .lite{font-size:11px;font-weight:500;color:var(--muted);margin-top:2px}
.pop-b{padding:6px}
.pop-row{display:flex;gap:11px;align-items:center;padding:10px 11px;border-radius:var(--r);
  cursor:pointer;transition:background .12s;font-size:12.5px;color:var(--ink-700);
  background:none;background-image:none;border:0;width:100%;text-align:left;box-shadow:none;
  font-weight:500}
.pop-row:hover{background:var(--paper);box-shadow:none;background-image:none}
.pop-row svg{width:16px;height:16px;flex:0 0 16px;color:var(--muted)}
@keyframes popIn{from{opacity:0;transform:translateY(-6px)}to{opacity:1;transform:none}}

/* ---- content ------------------------------------------------------------ */
/* The main content's own scroll region: min-height:0 makes overflow-y:auto scroll
   INSIDE the panel (not stretch the shell), and overscroll-behavior keeps its
   scroll from reaching the rail or the document. The top bar stays put because
   only this element scrolls. */
.content{flex:1;min-height:0;overflow-y:auto;overscroll-behavior:contain;
  display:flex;flex-direction:column}
.wrap{width:100%;max-width:1760px;margin:0 auto;padding:var(--gap) 24px 40px;
  position:relative;z-index:1;flex:1}

/* ============================================================= page footer */
.foot{flex:0 0 auto;border-top:1px solid var(--line);background:var(--card);
  padding:15px 24px;display:flex;align-items:center;justify-content:space-between;gap:16px;
  font-size:11.5px;color:var(--muted);flex-wrap:wrap}
.foot .r{display:flex;gap:16px;align-items:center;flex-wrap:wrap}
.foot b{font-weight:600;color:var(--ink-700)}


/* ===================================================== controls + form kit */
select,button,input,textarea{font-family:var(--sans);font-size:13.5px}
select,input[type=text],input[type=date],input[type=datetime-local],input[type=time],
input[type=month],input[type=number],input[type=email],input[type=search],
input[type=password],input[type=tel],input[type=url],textarea{
  padding:9px 12px;border-radius:var(--r-sm);border:1px solid var(--line);background:var(--card);
  color:var(--ink);outline:none;max-width:100%;transition:border-color .14s,box-shadow .14s}
select{appearance:none;-webkit-appearance:none;padding-right:30px;cursor:pointer;
  background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%236B7280' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
  background-repeat:no-repeat;background-position:right 10px center}
select:focus,input:focus,textarea:focus{border-color:var(--gold);box-shadow:0 0 0 3px var(--gold-50)}
input::placeholder,textarea::placeholder{color:var(--muted-2)}
input[type=checkbox],input[type=radio]{accent-color:var(--gold-700);cursor:pointer}
/* A text field, a dropdown and a textarea each carry a browser default that says
   "never become narrower than what is written in me". Put one in a row beside
   other things and the row cannot shrink: the last item is pushed off the right
   of the screen instead. Reset here, once, for the whole ERP. A button is
   deliberately NOT in this list — a button is as wide as its label and should
   stay that way; it is the field beside it that has to give. */
input,select,textarea{min-width:0}

/* ---- buttons ---- */
/* The brand gold is #C89B3C, but white text on it clears only ~2.4:1 — not
   readable at 13px. Filled surfaces therefore use the deeper end of the same
   ramp; the bright swatch stays where it belongs, on washes, rings and marks. */
button,.btn{font-weight:600;padding:9px 15px;border-radius:var(--r-sm);border:1px solid var(--line);
  background:var(--card);color:var(--ink);cursor:pointer;transition:.15s var(--ease);
  display:inline-flex;align-items:center;justify-content:center;gap:7px;line-height:1.25;
  font-size:13.5px;font-family:var(--sans)}
button:hover,.btn:hover{border-color:#D4D4D0;background:var(--paper);box-shadow:var(--sh-1)}
button:active,.btn:active{transform:translateY(1px)}
/* .btn IS THE PRIMARY ACTION in this ERP — "+ New", "Save", "Sign in" all carry
   the bare class, so the bare class is what has to look like the primary. */
.btn,button.primary{background:linear-gradient(135deg,var(--gold-600),var(--gold-700));color:#fff;
  border-color:var(--gold-700);box-shadow:0 2px 10px -4px rgba(200,155,60,.75)}
.btn:hover,button.primary:hover{background:var(--ink);border-color:var(--ink);color:#fff;
  box-shadow:0 4px 16px -6px rgba(17,17,17,.5)}
.btn.ghost,button.ghost{background:var(--card);background-image:none;border-color:var(--line);
  color:var(--ink-500);box-shadow:none}
.btn.ghost:hover,button.ghost:hover{border-color:var(--gold);color:var(--gold-700);
  background:var(--gold-50);background-image:none;box-shadow:none}
.btn.danger,button.danger{color:var(--red);border-color:#F6D5D5;background:var(--card);
  background-image:none;box-shadow:none}
.btn.danger:hover,button.danger:hover{background:var(--red-soft);background-image:none;
  border-color:var(--red);color:var(--red);box-shadow:none}
button:disabled,.btn:disabled,.btn[disabled]{opacity:.42;cursor:default;box-shadow:none;transform:none}
.btn.sm,.btn.small,button.small{padding:5px 11px;font-size:12px;border-radius:7px}
.btn.full{width:100%;justify-content:center}
/* A quiet outline action — export, download, "open in Tally". */
.out{display:inline-flex;align-items:center;gap:6px;font-size:12px;font-weight:500;
  color:var(--ink-500);border:1px solid var(--line);border-radius:var(--r-sm);padding:7px 12px;
  background:var(--card);text-decoration:none;cursor:pointer;transition:.15s}
.out:hover{border-color:var(--gold);color:var(--gold-700);background:var(--gold-50)}
/* A link that is really a button (the bulk-select rows in the permission picker). */
.lnk{background:none;background-image:none;border:0;box-shadow:none;padding:3px 6px;
  color:var(--gold-700);font-size:12px;font-weight:600;cursor:pointer;border-radius:6px}
.lnk:hover{background:var(--gold-50);background-image:none;border-color:transparent;box-shadow:none}
.lnk:focus-visible{outline:2px solid var(--gold);outline-offset:1px}

/* ---- fields ---- */
.field{margin-bottom:15px}
.field label{display:block;font-size:11.5px;color:var(--ink-500);margin-bottom:5px;font-weight:600}
.field input,.field select,.field textarea{width:100%}
.field textarea{min-height:70px;resize:vertical;line-height:1.55}
.field .note{font-size:11px;color:var(--muted);margin-top:4px}
.form label{display:block;font-size:11.5px;font-weight:600;color:var(--ink-500);margin:14px 0 6px}
.form input,.form select,.form textarea{width:100%}
.form textarea{resize:vertical;line-height:1.55;min-height:70px}
input[disabled],select[disabled],textarea[disabled],
.form input[disabled],.form select[disabled],.form textarea[disabled]{
  background:var(--paper);color:var(--muted);cursor:not-allowed}
.req{color:var(--red)}
.note{font-size:11.5px;color:var(--muted);margin:6px 0;line-height:1.55}
.note.ok{color:var(--green)}
.note.bad{color:var(--red)}
.err{color:var(--red);font-size:12.5px;min-height:17px;margin-top:6px;font-weight:500}
.hint{color:var(--muted-2);font-size:11.5px;text-align:center;margin-top:16px;line-height:1.6}
.muted{color:var(--muted)}
.mono{font-family:var(--mono);font-size:11.5px;color:var(--muted)}
.row2,.grid2{display:grid;grid-template-columns:1fr 1fr;gap:12px}
.row3,.grid3{display:grid;grid-template-columns:repeat(3,1fr);gap:12px}
.grid4{display:grid;grid-template-columns:repeat(4,1fr);gap:12px}
/* A grid column is "1fr" but a grid ITEM defaults to min-width:auto, which means
   it refuses to become narrower than its own content — so a cell holding a wide
   table pushes its column out and the whole page runs off the right of the
   screen. Letting the item shrink is the fix; the box inside it scrolls. */
.grid2>*,.grid3>*,.grid4>*,.row2>*,.row3>*{min-width:0}
@media(max-width:1000px){.grid3,.grid4{grid-template-columns:1fr 1fr}}
@media(max-width:700px){.grid2,.grid3,.grid4,.row2,.row3{grid-template-columns:1fr}}
/* A tick list — companies on a grant, departments on an employee. The box and
   the name belong together on one line, so these opt OUT of width:100%. */
.checks{display:flex;flex-wrap:wrap;gap:7px;margin-top:7px}
.chk{display:inline-flex;align-items:center;gap:7px;padding:6px 11px;border:1px solid var(--line);
  border-radius:var(--r-sm);font-size:12.5px;font-weight:500;cursor:pointer;background:var(--card);
  color:var(--ink-700);transition:.14s}
.chk:hover{border-color:var(--gold);background:var(--gold-50);color:var(--gold-700)}
.chk input,.form .chk input{width:auto;flex:none;margin:0}
/* A chip: an on/off choice that reads as a filter rather than a form control. */
.chips{display:flex;flex-wrap:wrap;gap:7px}
.chip{font-size:12px;padding:7px 13px;border:1px solid var(--line);border-radius:var(--r-pill);
  cursor:pointer;background:var(--card);user-select:none;font-weight:500;transition:.15s}
.chip:hover{border-color:#D4D4D0;background:var(--paper)}
.chip.on{background:var(--gold-50);border-color:var(--gold);color:var(--gold-700);font-weight:600}

/* The search box above a register. */
.search{padding:9px 12px 9px 34px;border:1px solid var(--line);border-radius:var(--r-sm);
  font-size:13px;width:270px;max-width:100%;color:var(--ink);
  background:var(--card) no-repeat left 11px center;
  background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='15' height='15' viewBox='0 0 24 24' fill='none' stroke='%239096A1' stroke-width='2' stroke-linecap='round'%3E%3Ccircle cx='11' cy='11' r='8'/%3E%3Cpath d='m21 21-4.3-4.3'/%3E%3C/svg%3E")}
.search:focus{border-color:var(--gold);box-shadow:0 0 0 3px var(--gold-50);outline:none}

/* The filter bar. It sits above a register and means the same thing on all of
   them — pick a department and a status once and the whole screen follows. */
.filters{display:flex;gap:9px;align-items:center;flex-wrap:wrap;padding:12px 16px;
  border-bottom:1px solid var(--line);background:var(--paper)}
.filters .lbl{font-size:9.5px;font-weight:600;letter-spacing:.15em;text-transform:uppercase;
  color:var(--muted-2)}
.filters select,.filters input[type=date],.filters input[type=text]{padding:7px 10px;
  font-size:12.5px;max-width:200px}
.filters select{padding-right:26px}
.spacer,.filters .spacer{flex:1}


/* ============================================================== page header */
.page-head{display:flex;align-items:center;gap:14px;margin-bottom:18px;flex-wrap:wrap}
.page-head h2{font-size:19px;font-weight:700;letter-spacing:-.02em;color:var(--ink)}
.page-head .sub{color:var(--muted);font-size:12.5px;margin-top:2px}
.page-head h2 .badge{vertical-align:middle;margin-left:8px}
.sec-h{display:flex;align-items:baseline;justify-content:space-between;gap:14px;margin-bottom:12px}
/* A rule-and-caption band inside a long form. */
.sec{font-size:10px;font-weight:600;letter-spacing:.15em;text-transform:uppercase;
  color:var(--muted-2);margin:22px 0 6px;padding-bottom:7px;border-bottom:1px solid var(--line)}


/* =============================================================== KPI tiles */
/* The dashboard's figures. .cards/.card is the current ERP's markup for them;
   .tiles/.tile is the old ERP's own name, kept so new markup can use it. */
.cards,.tiles{display:grid;grid-template-columns:repeat(auto-fit,minmax(212px,1fr));
  gap:16px;margin:0 0 var(--gap)}
.card,.tile{background:var(--card);border:1px solid var(--line);border-radius:var(--r-card);
  padding:18px;position:relative;overflow:hidden;box-shadow:var(--sh-1);
  transition:transform .2s var(--ease),box-shadow .2s var(--ease),border-color .2s;
  animation:fadeUp .4s var(--ease) both}
.card:hover,.tile:hover{box-shadow:var(--sh-2);border-color:#DCDCD7}
.tile{cursor:pointer}
.tile:hover{transform:translateY(-3px)}
.card .k,.tile .l{font-size:10px;font-weight:600;letter-spacing:.13em;text-transform:uppercase;
  color:var(--muted-2)}
.card .v,.tile .v{font-size:29px;font-weight:700;line-height:1.05;letter-spacing:-.03em;
  color:var(--ink);margin-top:9px}
.card .v-sub{font-size:18px;font-weight:600;color:var(--muted-2)}
.card .foot,.tile .s{font-size:11.5px;color:var(--muted-2);margin-top:6px;
  border:0;background:none;padding:0;display:block}
.card.muted-card{background:var(--paper);border-style:dashed;box-shadow:none}
.tile .ico{width:42px;height:42px;border-radius:12px;display:grid;place-items:center;margin-bottom:15px}
.tile .ico svg{width:20px;height:20px;stroke-width:2}
/* At six tiles across, five left-hand stripes read as a barcode — so the accent
   is a corner wash instead. */
.tile .edge{position:absolute;top:-58px;right:-58px;width:140px;height:140px;border-radius:50%;
  background:currentColor;opacity:.07;pointer-events:none}
.tile.brass{color:var(--gold)}   .tile.brass .ico{background:var(--gold-50);color:var(--gold-700)}
.tile.green{color:var(--success)}.tile.green .ico{background:var(--green-soft);color:var(--green)}
.tile.blue{color:var(--info)}    .tile.blue  .ico{background:var(--blue-soft);color:var(--blue)}
.tile.red{color:var(--danger)}   .tile.red   .ico{background:var(--red-soft);color:var(--red)}
.tile.plum{color:var(--plum)}    .tile.plum  .ico{background:var(--plum-soft);color:var(--plum)}
.tile.amber{color:var(--warn)}   .tile.amber .ico{background:var(--amber-soft);color:var(--amber)}
@keyframes fadeUp{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:none}}
@keyframes fadeIn{from{opacity:0}to{opacity:1}}
@keyframes grow{from{width:0!important}}

/* ============================================================ panels/cards */
/* .panel is the current ERP's framed section — a head, a body, sometimes a
   filter bar and a pager. It is the old ERP's .card with a rule under its head. */
.panel{background:var(--card);border:1px solid var(--line);border-radius:var(--r-card);
  box-shadow:var(--sh-1);overflow:hidden;margin-bottom:var(--gap);
  transition:box-shadow .2s var(--ease),border-color .2s}
.panel:hover{box-shadow:var(--sh-2)}
.panel-head{display:flex;align-items:center;gap:10px;padding:14px 18px;flex-wrap:wrap;
  border-bottom:1px solid var(--line)}
.panel-head h3,.panel-head>b,.panel-head>strong{font-size:14.5px;font-weight:700;color:var(--ink)}
.panel-head .spacer{flex:1}
.dash-grid{display:grid;grid-template-columns:1fr 1fr;gap:var(--gap);margin-bottom:var(--gap)}
.dash-grid.three{grid-template-columns:1.15fr 1.15fr .7fr}
.dash-grid>*{min-width:0}
@media(max-width:1280px){.dash-grid,.dash-grid.three{grid-template-columns:1fr}}
.dash-foot{color:var(--muted-2);font-size:11.5px;margin:14px 2px 4px}

/* ================================================================= tables */
.sheet{border:1px solid var(--line);border-radius:14px;overflow:auto;background:var(--card)}
table{width:100%;border-collapse:separate;border-spacing:0;font-size:13px}
th{font-size:10px;font-weight:600;letter-spacing:.11em;text-transform:uppercase;
  color:var(--muted);text-align:left;padding:11px 14px;background:var(--paper);
  border-bottom:1px solid var(--line);white-space:nowrap}
thead th{position:sticky;top:0;z-index:2}
td{padding:11px 14px;border-bottom:1px solid var(--line-soft);font-size:13px;
  vertical-align:middle;color:var(--ink-700);text-align:left}
tbody tr:last-child td{border-bottom:none}
tbody tr{transition:background .12s}
tbody tr:hover{background:var(--gold-50)}
tbody tr:hover td{color:var(--ink)}
tbody tr.clickable,tbody tr.click{cursor:pointer}
td.num,th.num,.rpt-num{text-align:right;white-space:nowrap;font-variant-numeric:tabular-nums}
td.num,td.rpt-num{font-family:var(--mono);font-size:12px}
td .row-actions{display:flex;gap:6px;flex-wrap:wrap}
/* The same class names the action cluster in a page header (Import / Export / + New), where the
   buttons are full size on purpose. Only the ones INSIDE a row shrink, so a register's rows stay
   the height of their text rather than the height of two stacked buttons. */
td .row-actions button,td .row-actions .btn{padding:5px 11px;font-size:12px;border-radius:7px;
  min-height:0}
/* Sortable headings. The heading has to LOOK clickable or nobody discovers it,
   and the arrow has to hold its space or the column jumps sideways on sort. */
th.sortable{cursor:pointer;user-select:none;transition:color .12s,background .12s}
th.sortable:hover{color:var(--gold-700);background:var(--gold-50)}
.sort-ind{display:inline-block;min-width:12px;font-size:9px;color:var(--gold-700);
  vertical-align:middle}
/* The pager under a register. */
.pager{display:flex;align-items:center;gap:9px;padding:12px 16px;border-top:1px solid var(--line);
  font-size:12.5px;color:var(--muted);background:var(--paper);flex-wrap:wrap}
.pager select{padding:5px 24px 5px 9px;font-size:12.5px}
.pager .spacer{flex:1}
/* A toolbar above a sheet: count, search, filter, export, pagination. */
.tbar{display:flex;align-items:center;gap:8px;flex-wrap:wrap;margin-bottom:12px}
.tbar .grow{flex:1}
.tbar .cnt{font-family:var(--mono);font-size:11px;color:var(--muted);background:var(--paper);
  border:1px solid var(--line);border-radius:var(--r-pill);padding:4px 11px}

/* ================================================================== pills */
/* .badge is the current ERP's status mark; .pill is the old ERP's own name. */
.badge,.pill{display:inline-flex;align-items:center;gap:5px;font-size:10px;letter-spacing:.05em;
  text-transform:uppercase;padding:3px 9px;border-radius:var(--r-pill);font-weight:600;
  white-space:nowrap;line-height:1.5;background:var(--paper);color:var(--muted);
  border:1px solid var(--line)}
.badge:empty,.pill:empty{display:none}
.badge.tag,.badge.brass,.pill.brass{background:var(--gold-50);color:var(--gold-700);
  border-color:#F0E4C7}
.badge.active,.badge.green,.pill.green{background:var(--green-soft);color:var(--green);
  border-color:#CFEBD9}
.badge.blue,.pill.blue{background:var(--blue-soft);color:var(--blue);border-color:#D5E4FC}
.badge.plum,.pill.plum{background:var(--plum-soft);color:var(--plum);border-color:#E3D7FB}
.badge.inactive,.badge.red,.pill.red{background:var(--red-soft);color:var(--red);
  border-color:#F6D5D5}
.badge.amber,.pill.amber{background:var(--amber-soft);color:var(--amber);border-color:#F5E2C0}
.badge.gray,.badge.grey,.pill.grey{background:var(--paper);color:var(--muted);border-color:var(--line)}
/* The CRM enquiry ladder — the same stages, in the gold system's tones. */
.badge.stage{background:var(--paper);color:var(--muted);border-color:var(--line)}
.badge.stage.new{background:var(--blue-soft);color:var(--blue);border-color:#D5E4FC}
.badge.stage.contacted,.badge.stage.interested{background:var(--amber-soft);color:var(--amber);
  border-color:#F5E2C0}
.badge.stage.qualified{background:var(--gold-50);color:var(--gold-700);border-color:#F0E4C7}
.badge.stage.converted{background:var(--green);color:#fff;border-color:var(--green)}
.badge.stage.junk,.badge.stage.lost{background:var(--red-soft);color:var(--red);border-color:#F6D5D5}

/* Enough room to read as deliberate, not enough to read as unfinished. */
.empty,.no-access{padding:34px 24px;text-align:center;color:var(--muted);font-size:12.5px}
.empty .big{font-size:15.5px;font-weight:600;color:var(--ink);margin-bottom:5px;
  letter-spacing:-.015em}
.spinner{display:inline-block;width:15px;height:15px;border:2px solid var(--line);
  border-top-color:var(--gold-700);border-radius:50%;animation:spin .7s linear infinite;
  vertical-align:middle}
@keyframes spin{to{transform:rotate(360deg)}}
/* A message band inside a form or a page. */
.msg{font-size:12.5px;padding:11px 14px;border-radius:var(--r);margin-bottom:14px;
  display:none;font-weight:500}
.msg.bad{display:block;background:var(--red-soft);color:var(--red)}
.msg.ok{display:block;background:var(--green-soft);color:var(--green)}
.msg.warn{display:block;background:var(--amber-soft);color:var(--amber)}

/* =================================================================== tabs */
/* The screen-level tab bar: underline-and-gold, as the old ERP's .secx-tabs. */
.tabs{display:flex;gap:2px;flex-wrap:wrap;border-bottom:1px solid var(--line);margin-bottom:16px}
.tab{padding:11px 14px;font-size:13px;font-weight:500;color:var(--muted);cursor:pointer;
  border-bottom:2px solid transparent;white-space:nowrap;transition:.14s}
.tab:hover{color:var(--ink);background:var(--gold-50)}
.tab.active,.tab.on{color:var(--gold-700);border-bottom-color:var(--gold);font-weight:600}
/* A pill tab strip, for tabs that live inside a card. The old ERP's .subtabs. */
.subtabs{display:flex;gap:4px;flex-wrap:wrap;margin:0 0 var(--gap);padding:5px;
  background:var(--card);border:1px solid var(--line);border-radius:var(--r-pill);
  width:fit-content;max-width:100%;box-shadow:var(--sh-1)}
.subtabs a{font-size:12.5px;font-weight:500;color:var(--muted);cursor:pointer;padding:7px 15px;
  border-radius:var(--r-pill);user-select:none;transition:.15s var(--ease)}
.subtabs a:hover{color:var(--ink);background:var(--paper)}
.subtabs a.on{color:#fff;background:var(--ink);font-weight:600;box-shadow:var(--sh-1)}

/* ============================================================== key/value */
.kv{display:grid;grid-template-columns:190px 1fr;gap:8px 14px;font-size:13px}
.kv .k{font-size:10.5px;font-weight:600;letter-spacing:.09em;text-transform:uppercase;
  color:var(--muted-2);padding-top:3px}
.kv .v{word-break:break-word;color:var(--ink-700)}
@media(max-width:640px){.kv{grid-template-columns:1fr;gap:2px 0}.kv .k{margin-top:10px}}

/* ================================================================= modals */
/* The record form. Three bands, as the old ERP's drawer: a head that stays put,
   one scrolling body, and a foot that carries the action. */
/* THE COLUMN IS minmax(0,1fr) SO A MODAL CAN ACTUALLY SHRINK.
   A grid column defaults to `auto`, which sizes to its content — so a .modal.wide asking for
   820px made the TRACK 820px wide, and the `max-width:100%` on .modal below then resolved
   against that 820px rather than against the screen. On a 390px phone the dialog sat 430px
   wider than the viewport with its right-hand side, and its buttons, off the edge. Pinning the
   track to the container makes 100% mean the screen again; nothing changes above 860px, where
   the modal was already narrower than the space it had. */
.modal-bg{position:fixed;inset:0;background:rgba(17,17,17,.42);display:grid;place-items:center;
  grid-template-columns:minmax(0,1fr);
  z-index:900;backdrop-filter:blur(2px);-webkit-backdrop-filter:blur(2px);
  animation:fadeIn .2s ease both;padding:20px}
/* '.modal' IS THE SCROLL CONTAINER, and the height and the overflow are written out in full
   here on purpose. The Tally workflow modal captures scrollTop off `mb.closest('.modal')` before
   it wipes its body and puts it back afterwards; move overflow onto '.modal-bg' or the body and
   that reads the wrong element and silently stops working, with no visible failure anywhere else.
   TallyWorkflowModalScrollTests pins this exact rule — keep it as one declaration block. */
.modal { width: 560px; max-width: 100%; max-height: 90vh; overflow: auto; background: var(--card); border: 1px solid var(--line); border-radius: var(--r-card); padding: 24px; box-shadow: var(--sh-3); animation: popIn .19s var(--ease) both; }
.modal.wide{width:820px}
.modal>h3{display:flex;justify-content:space-between;align-items:center;gap:12px;
  margin-bottom:18px;font-size:19px;font-weight:700;letter-spacing:-.02em;color:var(--ink)}
.modal .x,.x{border:none;background:none;background-image:none;font-size:22px;color:var(--muted-2);
  cursor:pointer;line-height:1;padding:2px 7px;border-radius:8px;transition:.14s;box-shadow:none;
  font-weight:400}
.modal .x:hover,.x:hover{color:var(--ink);background:var(--paper);box-shadow:none;
  border-color:transparent}
.modal label{display:block;font-size:11.5px;font-weight:600;color:var(--ink-500);margin:14px 0 6px}
/* A TICK ROW IS NOT A FIELD LABEL, and inside a modal it was being treated as one. The rule
   above is `.modal label` (0,1,1); .pick-row, .chk and .checkpill are single classes (0,1,0), so
   the field-label rule outranked them and turned every tick row into a block with 14px of margin
   — the box, the name and the description lost their gaps and ran into one another
   ("CRM ManagerFull CRM access…"), and each row grew a heading's worth of space above it.
   Restated here, below and at equal weight, so the row keeps being a row. */
.modal .pick-row,.modal .chk,.modal .checkpill,.modal .ticklist label{display:inline-flex;margin:0;
  font-weight:inherit;font-size:inherit;color:inherit}
.modal .pick-row{display:flex}
.modal .pick-row .nm,.modal .chk span,.modal .checkpill span{font-weight:inherit}
.modal input,.modal select,.modal textarea{width:100%}
/* A TICK IS NOT A FIELD. The rule above stretches every control across the row, which is right
   for a text box and wrong for a checkbox: it put the box in the middle of the row with its name
   marooned underneath. It has to be stated HERE, below that rule, because the two selectors carry
   the same weight and the later one wins. */
.modal input[type=checkbox],.modal input[type=radio],.modal .chk input{width:auto;flex:none;margin:0}
.modal textarea{resize:vertical;min-height:70px;line-height:1.55}
.modal .actions{display:flex;justify-content:flex-end;align-items:center;gap:10px;margin-top:22px;
  padding-top:18px;border-top:1px solid var(--line)}
/* A modal in three bands: pinned head, one scrolling body, pinned foot. The body
   is the ONLY scrolling region, so the search box and Save never leave the
   screen on a long role. */
.modal.frame{padding:0;display:flex;flex-direction:column;overflow:hidden}
.modal.frame>h3{padding:22px 24px 0;margin:0 0 14px}
.modal.frame>.frame-body{flex:1;min-height:0;display:flex;flex-direction:column}

/* ============================================== the save bar on a full page */
.cm-body{padding:4px 20px 22px}
.cm-body>div{min-width:0}
/* The profile is saved as one record, so the control that saves it must not
   scroll away with the section in view. */
.cm-actions{position:sticky;bottom:0;display:flex;align-items:center;gap:10px;margin-top:18px;
  padding:13px 18px;background:var(--card);border:1px solid var(--line);border-radius:var(--r-card);
  box-shadow:0 -3px 16px -8px rgba(17,17,17,.3)}
.cm-actions .spacer{flex:1}

/* ================================================================= toasts */
#toast-host{position:fixed;right:20px;bottom:20px;display:flex;flex-direction:column;gap:10px;
  z-index:999}
.toast{display:flex;align-items:center;gap:11px;padding:13px 16px;border-radius:var(--r);
  font-size:13px;background:var(--card);box-shadow:var(--sh-3);border:1px solid var(--line);
  min-width:260px;transition:opacity .25s;animation:popIn .2s var(--ease) both}
.toast .ti{font-weight:800}
.toast.success{border-left:4px solid var(--success)} .toast.success .ti{color:var(--green)}
.toast.error{border-left:4px solid var(--danger)}    .toast.error .ti{color:var(--red)}
.toast.warning{border-left:4px solid var(--warn)}    .toast.warning .ti{color:var(--amber)}
.toast.info{border-left:4px solid var(--gold)}       .toast.info .ti{color:var(--gold-700)}

/* ================================================================= charts */
/* Charts are hand-drawn SVG. No library: nothing to fetch, nothing to build,
   and it still works on a machine that cannot reach the internet. */
.chart{display:block;width:100%;height:auto;padding:12px 10px 2px;overflow:visible}
.chart .grid{stroke:var(--line-soft);stroke-width:1}
.chart .axis{fill:var(--muted-2);font-size:10px;font-family:var(--mono)}
.chart .val{fill:var(--ink-500);font-size:10px;font-weight:600;font-family:var(--mono)}
.chart .line{fill:none;stroke:var(--gold);stroke-width:2.4;stroke-linejoin:round;
  stroke-linecap:round}
.chart .area{fill:var(--gold-50)}
.chart .dot{fill:#fff;stroke:var(--gold);stroke-width:2}
.chart .donut-v{fill:var(--ink);font-size:20px;font-weight:700;font-family:var(--sans);
  letter-spacing:-.02em}
.legend{display:flex;flex-wrap:wrap;gap:6px 16px;padding:2px 18px 16px;font-size:11.5px;
  color:var(--ink-700)}
.legend i{width:9px;height:9px;border-radius:3px;display:inline-block;margin-right:7px}
/* A meter — a proportion drawn as one bar. */
.meter{height:7px;border-radius:99px;background:var(--line-soft);overflow:hidden}
.meter i{display:block;height:100%;border-radius:99px;background:var(--gold);
  animation:grow .7s var(--ease) both}

/* =================================================== module readiness grid */
.mods{display:grid;grid-template-columns:repeat(auto-fill,minmax(190px,1fr));gap:12px;padding:18px}
.mod{border:1px solid var(--line);border-radius:12px;padding:14px 15px;background:var(--card);
  transition:.16s var(--ease)}
.mod:hover{border-color:var(--gold);box-shadow:var(--sh-1)}
.mod .n{font-weight:700;font-size:13.5px;color:var(--ink)}
.mod .c{font-family:var(--mono);font-size:11px;color:var(--muted-2);margin-top:3px}
.mod.off{background:var(--paper);border-style:dashed}
.mod.off:hover{border-color:var(--line);box-shadow:none}
.mod.off .n{color:var(--muted);font-weight:600}
/* The activity feed under the dashboard. */
.act{display:flex;align-items:center;gap:11px;padding:11px 18px;
  border-bottom:1px solid var(--line-soft);font-size:12.5px;color:var(--ink-700)}
.act:last-child{border-bottom:none}
.act:hover{background:var(--paper)}
.act .a{font-family:var(--mono);font-size:11px;color:var(--gold-700);white-space:nowrap}
.act .spacer{flex:1}
.act .t{color:var(--muted-2);font-family:var(--mono);font-size:11px;white-space:nowrap}

/* ================================================== the new-enquiry wizard */
/* A step-by-step line. It is deliberately not the pipeline board: these move
   one way, one at a time, and are never dragged. */
.wiz-steps{display:flex;gap:0;flex-wrap:wrap;align-items:stretch;margin:4px 0 20px}
.wiz-step{flex:1 1 0;min-width:130px;font-size:11.5px;font-weight:500;padding:9px 14px;
  border:1px solid var(--line);background:var(--card);color:var(--muted);transition:.15s}
.wiz-step:first-child{border-radius:var(--r-pill) 0 0 var(--r-pill)}
.wiz-step:last-child{border-radius:0 var(--r-pill) var(--r-pill) 0}
.wiz-step+.wiz-step{border-left:none}
.wiz-step .n{font-weight:700;font-size:9.5px;text-transform:uppercase;letter-spacing:.13em;
  color:var(--muted-2)}
.wiz-step.done{background:var(--green-soft);color:var(--green);border-color:#CFEBD9}
.wiz-step.done .n{color:var(--green)}
.wiz-step.active{background:var(--gold-700);color:#fff;border-color:var(--gold-700);font-weight:600}
.wiz-step.active .n{color:rgba(255,255,255,.78)}
/* Picking the customer an enquiry belongs to. */
.pick-list{max-height:280px;overflow-y:auto;border:1px solid var(--line);border-radius:var(--r);
  background:var(--card)}
.pick-row{display:flex;align-items:center;gap:10px;padding:10px 13px;
  border-bottom:1px solid var(--line-soft);font-size:12.5px;cursor:pointer;transition:.13s}
.pick-row:last-child{border-bottom:none}
.pick-row:hover{background:var(--gold-50)}
.pick-row.sel{background:var(--gold-50);box-shadow:inset 3px 0 0 var(--gold)}
.pick-row .nm{font-weight:600;color:var(--ink)}
.pick-row .sub{color:var(--muted-2);font-size:11.5px}
.pick-row .spacer{flex:1}

/* ================================================================ pipeline */
.kanban{display:flex;gap:16px;padding:16px 18px;overflow-x:auto;align-items:flex-start}
.kan-col{flex:0 0 268px;background:var(--paper);border:1px solid var(--line);border-radius:14px;
  display:flex;flex-direction:column;max-height:70vh;transition:.16s}
.kan-col.retired{border-style:dashed;background:#FAFAF8}
.kan-head{padding:12px 14px;border-bottom:1px solid var(--line);background:inherit;
  border-radius:14px 14px 0 0}
.kan-head .nm{font-size:12.5px;font-weight:600;color:var(--ink)}
.kan-head .sub{font-family:var(--mono);font-size:10.5px;color:var(--muted);margin-top:3px}
.kan-cards{padding:10px;overflow-y:auto;display:flex;flex-direction:column;gap:9px;min-height:80px}
.kan-card{background:var(--card);border:1px solid var(--line);border-radius:12px;padding:12px;
  box-shadow:var(--sh-1);transition:.16s var(--ease)}
.kan-card:hover{border-color:var(--gold);transform:translateY(-2px);box-shadow:var(--sh-2)}
.kan-card.quiet{border-left:3px solid var(--danger)}
.kan-card .ttl{font-size:12.5px;font-weight:600;line-height:1.35;color:var(--ink);cursor:pointer}
.kan-card .ttl:hover{color:var(--gold-700)}
.kan-card .sub{font-size:11.5px;color:var(--muted);margin-top:3px}
.kan-row{display:flex;align-items:center;gap:7px;margin-top:7px;font-size:11.5px;color:var(--muted)}
.kan-row .val{font-family:var(--mono);font-size:12px;color:var(--gold-700);font-weight:500;
  font-variant-numeric:tabular-nums}
.kan-move{width:100%;margin-top:9px;font-size:11px;padding:5px 22px 5px 7px;border-radius:7px;
  background-color:var(--paper);color:var(--ink-700)}
.kan-move:hover{border-color:var(--gold)}
.kan-empty{font-size:11.5px;color:var(--muted-2);text-align:center;padding:16px 6px}
.kan-more{font-size:11px;color:var(--muted-2);padding:9px 13px;border-top:1px solid var(--line)}


/* ═════════════════════════════════ the permission picker (MODULE ▸ FEATURE ▸
   ACTION). Re-skinned onto the old ERP's console vocabulary — a toolbar over a
   rule, a scrolling body, and a foot the Save button cannot scroll away from. */
.perm-head{padding:0 24px 14px;border-bottom:1px solid var(--line)}
.perm-head .note{margin:0 0 10px}
.perm-scroll{flex:1;min-height:0;overflow:auto;padding:10px 24px 18px}
.perm-foot{display:flex;align-items:center;gap:10px;padding:14px 24px;
  border-top:1px solid var(--line);background:var(--paper);
  border-radius:0 0 var(--r-card) var(--r-card)}
.permcount{font-size:12.5px;font-weight:600;color:var(--ink-500);font-variant-numeric:tabular-nums}
.permpick-head{margin:8px 0 12px}

.permmod{border:1px solid var(--line);border-radius:12px;margin:10px 0;overflow:hidden;
  background:var(--card);transition:border-color .16s}
.permmod:hover{border-color:#DCDCD7}
.permmod-head{display:flex;align-items:center;gap:10px;padding:10px 13px;background:var(--paper)}
.permmod.open .permmod-head{border-bottom:1px solid var(--line)}
.permmod-toggle{display:flex;align-items:center;gap:9px;background:none;background-image:none;
  border:0;padding:2px 0;font:inherit;cursor:pointer;box-shadow:none}
.permmod-toggle:hover{background:none;background-image:none;border-color:transparent;box-shadow:none}
.permmod-toggle:hover .nm{color:var(--ink)}
.permmod-toggle:focus-visible{outline:2px solid var(--gold);outline-offset:3px;border-radius:5px}
.permmod-toggle .caret{color:var(--muted-2);font-size:10px;width:10px;text-align:center}
.permmod-toggle .nm{font-weight:700;font-size:10px;text-transform:uppercase;letter-spacing:.13em;
  color:var(--gold-700)}
.permmod .tally{font-family:var(--mono);font-size:11px;font-weight:500;color:var(--muted);
  font-variant-numeric:tabular-nums}
.permbulk{display:flex;gap:6px}
.permmod-body{padding:6px 13px 13px}
.permfeat{margin-top:12px}
.permfeat>.nm{font-weight:600;font-size:12.5px;color:var(--ink);margin-bottom:3px}
.permfeat>.nm .muted{font-weight:400;font-size:11.5px;margin-left:8px}
/* Compact action toggles. The checkbox is still a real checkbox — kept focusable
   and operable by Space, just visually replaced by the pill — so keyboard and
   screen readers are unaffected. */
.checks .checkpill{display:inline-flex;align-items:center;gap:5px;margin:0;padding:5px 12px;
  border:1px solid var(--line);border-radius:var(--r-pill);background:var(--card);
  color:var(--muted);font-size:12px;font-weight:500;text-transform:none;letter-spacing:0;
  cursor:pointer;position:relative;user-select:none;transition:.14s}
.checks .checkpill:hover{border-color:var(--gold);color:var(--gold-700);background:var(--gold-50)}
.checks .checkpill.on{background:var(--gold-50);border-color:var(--gold);color:var(--gold-700);
  font-weight:600}
.checks .checkpill.ro{cursor:default;opacity:.8}
.checks .checkpill.ro:hover{border-color:var(--line);color:var(--muted);background:var(--card)}
.checks .checkpill .mk{width:9px;font-size:11px;font-weight:800;line-height:1}
.checks .checkpill input{position:absolute;opacity:0;width:1px;height:1px;margin:0;padding:0}
.checks .checkpill:focus-within{outline:2px solid var(--gold);outline-offset:2px}


/* ============================================================================================
   TRAINING
   Two things live below: the Training SCREEN (module cards, topic list, step cards), and the
   GUIDED OVERLAY — the spotlight, the tooltip and the step panel drawn OVER the real ERP while
   training is running.

   THE OVERLAY NEVER ALTERS THE ERP. It is three fixed-position elements appended to <body>: a
   ring around whatever the current step points at, a tooltip beside it, and the panel. Nothing
   here restyles a business screen, and pointer-events:none on the ring and the tip is what keeps
   the learner clicking the REAL control underneath rather than a training decoration.
   ============================================================================================ */

/* ---- progress bar ---- */
.tr-bar{display:block;height:6px;border-radius:99px;background:var(--line-soft);overflow:hidden;
  margin-top:7px}
.tr-bar span{display:block;height:100%;background:linear-gradient(90deg,var(--gold),var(--gold-600));
  border-radius:99px;transition:width .25s ease}

/* ---- module cards ---- */
.tr-modules{display:grid;grid-template-columns:repeat(auto-fill,minmax(240px,1fr));gap:16px;
  margin-bottom:var(--gap)}
.tr-mod{background:var(--card);border:1px solid var(--line);border-radius:var(--r-card);padding:18px;
  box-shadow:var(--sh-1);cursor:pointer;
  transition:transform .2s var(--ease),box-shadow .2s var(--ease),border-color .2s}
.tr-mod:hover{border-color:var(--gold);transform:translateY(-3px);box-shadow:var(--sh-2)}
.tr-mod.empty{opacity:.6;padding:18px;text-align:left}
.tr-mod-top{display:flex;align-items:center;gap:11px;font-size:14.5px;font-weight:700;
  color:var(--ink)}
.tr-mod-ic{font-size:20px}
.tr-mod-blurb{color:var(--muted);font-size:11.5px;margin-top:8px;line-height:1.5;min-height:32px}
.tr-mod-foot{display:flex;align-items:center;font-size:11.5px;margin-top:13px;color:var(--muted-2)}
.tr-mod-foot .spacer{flex:1}
.tr-mod-note{color:var(--amber);font-size:11px;margin-top:7px}

/* ---- banners: outdated, unverified, practice refused, partial translation ---- */
.tr-banner{background:var(--amber-soft);border:1px solid #F5E2C0;color:var(--amber);
  border-radius:var(--r);padding:11px 15px;font-size:12.5px;margin-bottom:14px;line-height:1.55}
.tr-banner.bad{background:var(--red-soft);border-color:#F6D5D5;color:var(--red)}

/* ---- resume list ---- */
.tr-resume{display:flex;align-items:center;gap:11px;padding:12px 18px;
  border-bottom:1px solid var(--line-soft);cursor:pointer;font-size:13px;color:var(--ink-700)}
.tr-resume:hover{background:var(--gold-50)}
.tr-resume .spacer{flex:1}
.tr-resume:last-child{border-bottom:none}

/* ---- step cards on the topic screen ---- */
.tr-steps{display:flex;flex-direction:column;gap:14px;margin-top:18px}
.tr-step{display:flex;gap:15px;background:var(--card);border:1px solid var(--line);
  border-radius:var(--r-card);padding:18px;box-shadow:var(--sh-1)}
.tr-step.done{border-color:#CFEBD9;background:#FCFEFD}
.tr-step.blocked{opacity:.82}
.tr-step-no{flex-shrink:0;width:30px;height:30px;border-radius:50%;background:var(--gold-50);
  color:var(--gold-700);display:grid;place-items:center;font-weight:700;font-size:13px}
.tr-step.done .tr-step-no{background:var(--green-soft);color:var(--green)}
.tr-step-body{flex:1;min-width:0}
.tr-step-head{display:flex;align-items:center;gap:10px;margin-bottom:5px;font-weight:700;
  font-size:14px;color:var(--ink)}
.tr-step-head .spacer{flex:1}
.tr-tick{font-size:15px}

/* The four labels the whole module exists to put in front of a learner. Colour-coded because
   people scan for them rather than read a card top to bottom. */
.tr-sec{font-size:9.5px;font-weight:600;letter-spacing:.15em;text-transform:uppercase;
  color:var(--gold-700);margin:13px 0 4px}
.tr-sec.happens{color:var(--green)}
.tr-sec.why{color:var(--plum)}
.tr-sec.next{color:var(--muted-2)}
.tr-text{font-size:13px;line-height:1.6;color:var(--ink-700)}
.tr-hint{font-size:12px;color:var(--muted);margin-top:5px;font-style:italic;line-height:1.55}
.tr-mistakes{margin:2px 0 0 18px;font-size:12.5px;color:var(--muted);line-height:1.65}
.tr-refs{display:flex;flex-wrap:wrap;gap:7px;margin-top:13px}
.tr-fallback{font-size:11px;color:var(--muted-2);margin-top:9px}
.tr-navpath{font-size:11.5px;color:var(--muted);margin-bottom:7px}
.tr-blocked{background:var(--paper);border:1px solid var(--line);border-radius:var(--r-sm);
  padding:9px 12px;font-size:12px;color:var(--muted);margin:9px 0;line-height:1.55}

/* ============================================================================================
   THE GUIDED OVERLAY
   ============================================================================================ */

/* The spotlight: a ring around the real control, with a huge soft shadow that dims everything
   else without a full-screen scrim. pointer-events:none is load-bearing — the learner must click
   the REAL button underneath, and a scrim that swallowed the click would make guided training a
   simulation rather than the ERP. */
.tr-spot{
  position:fixed;z-index:1200;pointer-events:none;display:none;
  border:2px solid var(--gold);border-radius:var(--r);
  box-shadow:0 0 0 9999px rgba(17,17,17,.40), 0 0 0 4px rgba(200,155,60,.30);
  transition:top .12s ease,left .12s ease,width .12s ease,height .12s ease;
  animation:tr-pulse 1.9s ease-in-out infinite;
}
/* A gentle pulse so the eye finds it immediately. The ring is the instruction; the animation is
   decoration, so it is dropped entirely for anybody who has asked not to be moved. */
@keyframes tr-pulse{
  0%,100%{box-shadow:0 0 0 9999px rgba(17,17,17,.40), 0 0 0 4px rgba(200,155,60,.30)}
  50%    {box-shadow:0 0 0 9999px rgba(17,17,17,.40), 0 0 0 9px rgba(200,155,60,.15)}
}
@media (prefers-reduced-motion: reduce){.tr-spot{animation:none;transition:none}}

.tr-tip{
  position:fixed;z-index:1201;pointer-events:none;display:none;
  max-width:260px;background:var(--ink);color:#fff;border-radius:var(--r-sm);
  padding:9px 13px;font-size:12.5px;line-height:1.45;box-shadow:var(--sh-3);
  border-left:3px solid var(--gold);
}
.tr-tip::after{content:'';position:absolute;left:50%;margin-left:-6px;border:6px solid transparent;
  border-top-color:var(--ink);bottom:-12px}
.tr-tip.below::after{border-top-color:transparent;border-bottom-color:var(--ink);bottom:auto;top:-12px}

/* The step panel. Fixed bottom-right so it never sits over the rail (where most first steps
   point) and never over the top bar. It scrolls internally: a long WHY must not push the buttons
   off the screen. */
.tr-panel{
  position:fixed;z-index:1202;right:20px;bottom:20px;width:380px;max-width:calc(100vw - 40px);
  max-height:min(74vh,640px);display:flex;flex-direction:column;overflow:hidden;
  background:var(--card);border:1px solid var(--line);border-radius:var(--r-card);
  box-shadow:var(--sh-3);
}
.tr-panel-head{display:flex;align-items:center;gap:10px;padding:13px 16px;
  border-bottom:1px solid var(--line);background:var(--paper);font-size:13px;font-weight:600}
.tr-panel-head .spacer{flex:1}
.tr-panel-body{padding:16px;overflow-y:auto;overscroll-behavior:contain}
.tr-stepno{font-size:9.5px;font-weight:600;letter-spacing:.15em;text-transform:uppercase;
  color:var(--muted-2)}
.tr-steptitle{font-size:16px;font-weight:700;margin:4px 0 2px;letter-spacing:-.02em}
.tr-msg{margin-top:13px;padding:10px 13px;border-radius:var(--r);font-size:12.5px;line-height:1.5}
.tr-msg.ok{background:var(--green-soft);color:var(--green)}
.tr-msg.bad{background:var(--red-soft);color:var(--red)}
.tr-done{font-size:34px;text-align:center;color:var(--green)}


/* ============================================================== responsive
   Desktop first — this is a 1920-wide operations screen for most of the day —
   then laptop, tablet and finally a phone, where the rail becomes a drawer. */
@media(max-width:1400px){
  :root{--rail:236px}
}
@media(max-width:1180px){
  .tb-title{display:none}
}
@media(max-width:900px){
  :root{--gap:16px;--topbar:60px}
  /* The rail leaves the flow and slides in over the page. */
  .sidebar,.rail{position:fixed;left:0;top:0;bottom:0;flex:0 0 auto;width:var(--rail)!important;
    transform:translateX(-100%);transition:transform .24s var(--ease);box-shadow:var(--sh-3)}
  body.rail-open .sidebar,body.rail-open .rail{transform:none}
  /* Collapsing is a desktop idea; on a phone the rail is either open or it is not. */
  body.rail-min .r-label,body.rail-min .nav .sect,body.rail-min .r-sec,
  body.rail-min .r-badge,body.rail-min .brand .rb-txt,body.rail-min .r-brand .rb-txt,
  body.rail-min .r-foot .rf span,body.rail-min .r-ver{display:revert}
  body.rail-min .navitem,body.rail-min .r-item{justify-content:flex-start;padding-left:12px;
    padding-right:12px}
  body.rail-min .brand,body.rail-min .r-brand{justify-content:flex-start;padding:0 18px}
  /* Backdrop for the slid-in rail. It MUST live in the shell's stacking context (the shell is
     position:relative;z-index:1) — the rail is fixed INSIDE it, so a body-level backdrop would
     paint OVER the rail and swallow its taps. As .shell::after it sits above the page
     (z-index 65 > topbar 60) but below the rail (70), so rail items stay on top and receive
     touches; a tap on it lands on .shell and the JS closes the menu. */
  body.rail-open .shell::after,body.rail-open .app::after{content:"";position:fixed;inset:0;
    background:rgba(17,17,17,.45);z-index:65}
  .wrap{padding:16px 14px 32px}
  .topbar{padding:0 14px;gap:10px}
  .foot{padding-left:14px;padding-right:14px;flex-direction:column;align-items:flex-start;gap:7px}
  .pop{right:10px}
  .pf-txt{display:none}
  .profile{padding:4px}
  .cards,.tiles{grid-template-columns:repeat(auto-fit,minmax(158px,1fr));gap:12px}
  .card,.tile{padding:15px}
  .card .v,.tile .v{font-size:24px}
  .dash-grid,.dash-grid.three{grid-template-columns:1fr}
  .kanban{gap:10px}
  /* The page must never scroll sideways; wide tables scroll inside their own box. */
  .main-wrap,.main{overflow-x:clip}
  .panel{overflow-x:auto}
  .sheet,.panel{max-width:100%}
  table{max-width:100%}
  /* Touch targets. */
  .navitem,.r-item,.tab,.pick-row{min-height:44px}
  button,.btn{min-height:40px}
}
@media(max-width:640px){
  .search{width:100%}
  .cards,.tiles{grid-template-columns:repeat(2,1fr)}
  .filters{padding:10px 12px;gap:7px}
  .modal{padding:18px}
  .modal.frame>h3{padding:18px 18px 0}
  .perm-head,.perm-scroll,.perm-foot{padding-left:18px;padding-right:18px}
  .tabs{flex-wrap:nowrap;overflow-x:auto;scrollbar-width:none}
  .tabs::-webkit-scrollbar{display:none}
  .tr-panel{right:10px;left:10px;bottom:10px;width:auto;max-height:60vh}
}
@media(prefers-reduced-motion:reduce){
  *,*::before,*::after{animation-duration:.001ms!important;animation-iteration-count:1!important;
    transition-duration:.001ms!important}
}
@media print{
  .sidebar,.rail,.topbar,.filters,.foot,.toast,.pop,#toast-host{display:none!important}
  html,body{overflow:visible}
  .shell,.app,.main-wrap,.main,.content{display:block;overflow:visible;height:auto}
  .card,.tile,.panel,.sheet{box-shadow:none;break-inside:avoid}
  body::before{display:none}
}

/* ═══════════════════════════════════════════ live Tally indicator (top bar) ══════════════
   KEPT FROM THE LIVE PRODUCTION BUILD, restated in this design system rather than left in the
   palette that was retired around it — the original used --panel/--line and raw greens and reds
   that no longer belong to anything.
   It reports the state of the CONNECTION and of the last mirror update, and never says anything
   about the figures themselves: when Tally is unreachable this goes red and the numbers on
   screen stay exactly as they were, because unavailable is not zero. */
.live-status{display:flex;align-items:center;gap:7px;padding:5px 11px;border-radius:var(--r-pill);
  background:var(--card);border:1px solid var(--line);font-size:11.5px;white-space:nowrap;
  cursor:default;color:var(--ink-700)}
.live-status .live-label{font-weight:600;letter-spacing:.02em}
.live-status .live-when{color:var(--muted-2);font-family:var(--mono);font-size:10.5px}
.live-dot{width:8px;height:8px;border-radius:50%;display:inline-block;flex:0 0 auto}
.live-dot.ok  {background:var(--success);box-shadow:0 0 0 3px rgba(34,197,94,.15)}
.live-dot.busy{background:var(--gold);box-shadow:0 0 0 3px rgba(200,155,60,.18);
               animation:live-pulse 1.2s ease-in-out infinite}
.live-dot.off {background:var(--danger);box-shadow:0 0 0 3px rgba(239,68,68,.15)}
.live-dot.idle{background:var(--muted-2)}
@keyframes live-pulse{0%,100%{opacity:1}50%{opacity:.35}}
/* On a narrow window the words go and the dot stays — the state is the dot. */
@media(max-width:1120px){ .live-status .live-when{display:none} }
@media(max-width:900px){ .live-status{padding:5px;gap:0} .live-status .live-label{display:none} }

/* ---------- side drawer ----------
   THE FIRST DRAWER IN THIS DESIGN SYSTEM, so it is named for what it is rather than for the one
   screen that happens to need it first: the drill is a MODIFIER. The next side panel inherits the
   surface, the header and the scroll behaviour instead of copying them, which is the difference
   between one drawer and four that drift apart.

   It sits OVER the page. Whatever opened it stays mounted underneath with its filters, its scroll
   position and its selection untouched. */
.drawer-scrim{position:fixed;inset:0;background:rgba(17,17,17,.42);opacity:0;pointer-events:none;
  transition:opacity .16s ease;z-index:80}
.drawer-scrim.on{opacity:1;pointer-events:auto}

/* --card, NOT --bg. `--bg` is a compatibility alias for the retired palette and resolves to
   --paper, the page GROUND; a surface floating above the page painted in the page's own colour
   leaves the shadow doing all the elevation on its own. Every other raised surface here uses
   --card, and so does this. */
.drawer{position:fixed;top:0;right:0;bottom:0;width:min(1180px,96vw);
  background:var(--card);border-left:1px solid var(--line);box-shadow:var(--sh-3);
  transform:translateX(102%);transition:transform .18s ease;z-index:81;
  display:flex;flex-direction:column}
.drawer.on{transform:none}
.drawer--drill{width:min(1180px,96vw)}

.drawer-head{display:flex;align-items:flex-start;gap:14px;padding:14px 18px 10px;
  border-bottom:1px solid var(--line)}
.drawer-heading{flex:1;min-width:0}
.drawer-title{margin:0;font-size:17px;line-height:1.25;overflow-wrap:anywhere}
.drawer-who{font-size:12px;color:var(--muted-2);margin-top:2px}
.drawer-ctx{font-size:11.5px;color:var(--ink-700,var(--ink));text-align:right;max-width:46%;
  line-height:1.5;white-space:normal;overflow-wrap:anywhere;font-family:var(--mono)}
.drawer-x{border:0;background:transparent;font-size:22px;line-height:1;cursor:pointer;
  color:var(--muted-2);padding:0 2px}
.drawer-x:hover{color:var(--ink)}
.drawer-crumb{display:flex;flex-wrap:wrap;gap:6px;align-items:center;padding:8px 18px;
  font-size:11.5px;border-bottom:1px solid var(--line);background:var(--paper)}
.drawer-body{flex:1;overflow:auto;padding:16px 18px 40px}

/* On a narrow window a drawer takes the screen: this is a full task, not a sidebar. */
@media(max-width:900px){ .drawer{width:100vw} .drawer-ctx{display:none} }

/* ---------- what the drill puts INSIDE the drawer ---------- */
.drill-up{color:var(--brand);text-decoration:none}
.drill-up:hover{text-decoration:underline}
.drill-here{font-weight:600}
.drill-sep{color:var(--muted-2)}
.drill-loading,.drill-empty{color:var(--muted-2);font-size:13px;padding:14px 0}
.drill-error{color:var(--danger);font-size:13px;padding:12px 0}
.drill-h{margin:20px 0 8px;font-size:13.5px}
.drill-summary{font-size:13px;margin-bottom:10px}
.drill-dim{color:var(--muted-2)}
.drill-more{font-size:11.5px;color:var(--muted-2);margin-top:10px}
.drill-narration{font-size:12.5px;color:var(--ink);opacity:.85;margin:10px 0;white-space:pre-wrap}
.drill-source{font-size:11px;color:var(--muted-2);margin-top:22px;overflow-wrap:anywhere;
  font-family:var(--mono)}

.drill-facts{display:flex;flex-wrap:wrap;gap:22px;margin-bottom:6px}
.drill-fact-l{font-size:11px;color:var(--muted-2)}
.drill-fact-v{font-size:14px;font-weight:600;font-variant-numeric:tabular-nums}
.drill-fact-v.drill-flag{color:var(--gold)}

.drill-scroll{overflow-x:auto}
.drill-table{width:100%;border-collapse:collapse;font-size:12.5px}
.drill-table th,.drill-table td{padding:7px 10px;border-bottom:1px solid var(--line);
  text-align:left;vertical-align:top}
.drill-table th{font-weight:600;color:var(--muted-2);white-space:nowrap}
.drill-table td.num,.drill-table th.num{text-align:right;font-variant-numeric:tabular-nums;
  white-space:nowrap;font-family:var(--mono)}
.drill-table tr.drill-click{cursor:pointer}
.drill-table tr.drill-click:hover{background:var(--paper)}

.drill-notes{margin-top:18px;display:flex;flex-direction:column;gap:8px}
.drill-note{font-size:12px;background:rgba(200,155,60,.08);border:1px solid rgba(200,155,60,.35);
  border-radius:var(--r-sm);padding:9px 11px;line-height:1.5}
.drill-warn{font-size:12.5px;background:rgba(239,68,68,.07);border:1px solid rgba(239,68,68,.3);
  border-radius:var(--r-sm);padding:9px 11px;margin:10px 0}
.drill-blocked{color:var(--gold);cursor:help;border-bottom:1px dotted currentColor}
.drill-blocked-box{background:var(--paper);border:1px solid var(--line);
  border-radius:var(--r-sm);padding:14px 16px;font-size:13px;line-height:1.6}

/* A figure on a report that can be opened. Quiet until hovered - a report should still read as a
   report. */
.drillable{cursor:pointer}
.drillable:hover{background:var(--paper)}

/* ============================================ payroll: a generated salary structure */
/* The totals under a generated breakdown. A structure is read for ONE figure — what reaches the
   employee's bank — so the net is sized to be read first and the supporting totals stay quiet. */
.pay-tot{display:grid;grid-template-columns:1fr auto;gap:6px 16px;font-size:13px;
  margin-top:12px;padding-top:10px;border-top:1px solid var(--line)}
.pay-tot .l{color:var(--muted)}
.pay-tot .a{text-align:right;font-weight:600;color:var(--ink);font-variant-numeric:tabular-nums}
.pay-net{display:flex;align-items:baseline;justify-content:space-between;gap:16px;
  margin-top:12px;padding:14px 16px;background:var(--paper);border:1px solid var(--line);
  border-radius:var(--r)}
.pay-net .l{font-size:10px;font-weight:600;letter-spacing:.15em;text-transform:uppercase;
  color:var(--muted)}
.pay-net .a{font-size:29px;font-weight:700;line-height:1.05;letter-spacing:-.03em;
  color:var(--ink);font-variant-numeric:tabular-nums}

/* ====================================================== MIS two-tier tabs */
/* The MIS asks a question on top and answers it underneath. Nineteen report
   buttons in one row was a list, not a screen: everything looked equally
   important and nothing could be found twice in the same place. The upper tier
   is the question ("How we did", "Who owes us") with the number of reports it
   holds; the lower tier is only that group's reports. Ported from the old ERP's
   .misgroups/.misgrp/.missubs and repointed at this ERP's own tokens — the
   folder-tab join is the .on tab painting over the strip's own bottom rule, so
   both must stay the same colour. The lower tier is a bare flex row because the
   buttons in it are ordinary .btn/.btn.ghost and already have their look. */
.misgroups{display:flex;gap:4px;flex-wrap:wrap;border-bottom:1px solid var(--line);
  margin:0 0 10px;padding-bottom:0}
.misgrp{border:1px solid transparent;border-bottom:none;background:transparent;
  color:var(--muted);font-size:12.5px;font-weight:600;padding:8px 13px;cursor:pointer;
  border-radius:9px 9px 0 0;margin-bottom:-1px;transition:.14s;box-shadow:none;
  background-image:none}
.misgrp:hover{color:var(--ink);background:var(--paper);background-image:none;
  border-color:transparent;border-bottom:none;box-shadow:none}
.misgrp.on{color:var(--gold-700);background:var(--card);background-image:none;
  border-color:var(--line);border-bottom:1px solid var(--card)}
.misgrp .n{display:inline-block;margin-left:5px;font-size:9.5px;font-weight:700;
  color:var(--muted-2);background:var(--paper);border-radius:8px;padding:1px 5px}
.misgrp.on .n{background:var(--gold-50);color:var(--gold-700)}
.missubs{display:flex;gap:6px;flex-wrap:wrap}

/* ============================================== MIS Inventory (Stock Summary) */
/* Inventory is Tally's Stock Summary: fourteen columns in four groups, so the
   table keeps its own width and scrolls sideways INSIDE its own box — the page
   itself must never scroll sideways. The group heading row is deliberately NOT
   sticky: `thead th{position:sticky;top:0}` above pins every header row to the
   same offset, so two sticky rows land on top of each other and the reader loses
   both. Ported from the old ERP at crm.html:504-522, repointed at this ERP's own
   tokens (its mono stack is --mono here). Only .stksheet is styled; the plain
   .sheet every other report uses is untouched. */
.stksheet{overflow-x:auto}
.stksheet table{min-width:1180px}
.stksheet thead th.stkgrp{position:static}
.stksheet thead th.stkgrp+th.stkgrp{border-left:1px solid var(--line)}
.stksheet thead tr+tr th:nth-child(3n+1){border-left:1px solid var(--line)}
/* A ruled line where each column group begins, the way Tally rules them. */
.stksheet tbody td:nth-child(3),.stksheet tbody td:nth-child(6),
.stksheet tbody td:nth-child(9),.stksheet tbody td:nth-child(12){
  border-left:1px solid var(--line-soft)}
/* The godowns an item sits in: indented under their item and visibly subordinate
   to it, exactly as Tally indents them. */
.stksheet tbody tr.stkgd td{background:var(--paper);padding-top:6px;padding-bottom:6px;
  color:var(--muted)}
.stksheet tbody tr.stkgd td:first-child{padding-left:34px;
  font-family:var(--mono);font-size:11.5px}

/* ====================================== the drill as a SCREEN, not a side note */
/* The old ERP learned this the hard way (crm.html:808-816): a 620px panel with the
   report still showing beside it meant the bill list scrolled sideways while the
   panel scrolled downwards, and the column headings slid away the moment you
   moved — so you read figures with no idea which column they belonged to. A
   drill-down is a task, not a footnote. One scroller, headings that stay put, and
   a Back button that is always there.

   DELIBERATELY NO PAGE FREEZE. A narrow panel over a visible page is right to stop
   the page scrolling underneath it. A panel covering the whole window is not:
   there is nothing behind to protect, and if its own scroller fails for any reason
   a frozen page leaves NOTHING that scrolls. The old ERP shipped that bug for half
   a day and wrote the reason down at crm.html:797-806. This ERP's shell already
   owns its scrolling (html,body{overflow:hidden}, line 92), so there is no freeze
   rule to exclude here — and none should be added.

   This is a MODIFIER. `.drawer--drill` is untouched: every other money screen
   still opens the 1180px side drawer, and only the MIS drill adds .drawer--full. */
.drawer--full{left:0;width:100%;border-left:none;box-shadow:none;
  transform:translateY(12px);opacity:0;visibility:hidden;
  transition:opacity .19s var(--ease),transform .19s var(--ease),visibility 0s .19s}
.drawer--full.on{transform:none;opacity:1;visibility:visible;
  transition:opacity .19s var(--ease),transform .19s var(--ease)}

/* The head is a flex sibling of the body, so it stays put without being sticky. */
.drawer--full .drawer-head{padding:16px 24px;align-items:center}
.drawer--full .drawer-title{font-size:21px}
.drawer--full .drawer-ctx{white-space:nowrap;max-width:none;flex:0 0 auto}
.drawer--full .drawer-crumb{padding:9px 24px}

/* One scroller for the whole screen. The max() keeps a long line readable on a wide
   monitor without wrapping every screen's markup in another element. There is NO
   top padding on purpose: a sticky heading comes to rest at the scroller's padding
   edge, and 22px of padding leaves a 22px letterbox above it through which the rows
   keep sliding, in full view. The gap goes on whatever the screen draws first,
   where it cannot be scrolled under. */
.drawer--full .drawer-body{padding:0 max(28px,calc((100% - 1640px)/2)) 80px}
.drawer--full .drawer-body>*:first-child{margin-top:22px}

/* NO TABLE GETS A SCROLLBAR OF ITS OWN IN HERE — nested scrollbars are what made
   the old panel unreadable. The headings stick to the top of the one scroller
   instead, so the columns are still named four hundred rows down. */
.drawer--full .sheet{overflow:visible}
.drawer--full .sheet thead th{box-shadow:0 1px 0 var(--line)}
/* misTable draws a SECOND header row of filter dropdowns. Both rows are sticky and
   both would otherwise pin to top:0 and cover each other — the same trap .stksheet
   avoids by not being sticky at all. Here the rows are wanted, so the first is
   given a stated height and the second is parked exactly beneath it. A fixed height
   is not decoration: border-box makes 38px mean 38px, which is what lets the offset
   be right rather than approximately right (crm.html:845-848). */
.drawer--full .sheet thead tr:first-child th{top:0;z-index:8;height:38px;line-height:16px}
.drawer--full .sheet thead tr.filterrow th{top:38px;z-index:7;box-shadow:0 1px 0 var(--line)}

@media(max-width:900px){ .drawer--full .drawer-ctx{display:none} }

/* ================================ payroll: the statutory schemes */
/* THREE SCHEMES ON ONE TAB — provident fund, professional tax and TDS — read one after another,
   so each is separated from the next by a real rule rather than by whitespace alone. A scheme is
   read for one thing first: whether it is trusted, which is why the badge and the warning sit
   above the figures and not under them. */
/* THE STATUTORY DASHBOARD. One card per levy, each answering the two questions an operator
   opens this page with: which figures the run will use, and whether anybody has confirmed them.
   The detail lives behind the card rather than under it, which is what stops the page being a
   scroll through every slab of every scheme.
   Cards flow rather than sitting in a fixed grid, so three fit a desktop, two a tablet and one
   a phone without a breakpoint per count. `min-width:0` lets a card shrink below its content so
   a wide table inside it scrolls instead of pushing the page sideways. */
/* A SALARY LINE TABLE THAT STOPS BEING A TABLE ON A PHONE. Component / Calculation / Amount is
   three columns of prose and money, and on a narrow screen the honest thing is to stack them
   into one block per component rather than let the page run off to the right or hide the amount
   behind a sideways scroll. `data-label` on each cell carries the heading down with it, so the
   stacked rows still say which figure is which. */
.pay-lines table{width:100%}
.pay-lines .pay-total-row td{border-top:2px solid var(--line);background:var(--paper)}
@media(max-width:700px){
  .pay-lines thead{display:none}
  .pay-lines tr{display:block;padding:10px 0;border-bottom:1px solid var(--line)}
  .pay-lines td{display:flex;justify-content:space-between;gap:14px;border:none;padding:3px 0;text-align:left!important}
  .pay-lines td::before{content:attr(data-label);color:var(--ink-500,#777);font-size:11px;
    text-transform:uppercase;letter-spacing:.04em;flex:0 0 auto;padding-top:2px}
  .pay-lines td:empty,.pay-lines td[data-label='']::before{display:none}
  .pay-lines .pay-total-row{background:var(--paper)}
}

.stat-cards{display:flex;gap:14px;flex-wrap:wrap;align-items:stretch}
.stat-card{flex:1 1 300px;min-width:0;display:flex;flex-direction:column;gap:8px;
  padding:16px 18px;border:1px solid var(--line);border-radius:var(--r);background:var(--card)}
.stat-card .sec{margin:0}
.stat-card .spacer{flex:1 1 auto}
@media(max-width:640px){ .stat-card{flex:1 1 100%;padding:14px 15px} }

.pay-stat{margin-bottom:22px;padding-bottom:20px;border-bottom:1px solid var(--line)}
.pay-stat:last-child{margin-bottom:0;padding-bottom:0;border-bottom:none}
.pay-stat .panel-head{align-items:center;gap:10px}

/* A slab table an operator edits in place. The cells are figures, so they are read as figures —
   right-aligned and tabular, the way every other money column in this ERP is — and the remove
   column stays as narrow as its button. */
.pay-slabs table{margin-top:0}
.pay-slabs td input{text-align:right;font-variant-numeric:tabular-nums}
.pay-slabs th:last-child,.pay-slabs td:last-child{width:1%;white-space:nowrap;text-align:right}

/* ============================================================================
   EMPLOYEE CALENDAR — the self-service month.
   Built to the existing calendar's proportions rather than restyled into cards:
   a blue day-header strip, square-ish bordered cells, the date in the corner,
   a figure in the cell and a coloured status bar across the bottom of it.
   ============================================================================ */
.ecal-head{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin:0 0 14px}
.ecal-head .grp{display:flex;align-items:center;gap:6px}
.ecal-head .spacer{flex:1}
.ecal-btn{background:#1b74d1;color:#fff;border:1px solid #1b74d1;border-radius:4px;
  padding:7px 14px;font-size:13.5px;font-weight:600;cursor:pointer;line-height:1.2}
.ecal-btn:hover{background:#155ea9;border-color:#155ea9}
.ecal-head select{padding:6px 8px;font-size:13.5px;border:1px solid #b9c2cc;border-radius:4px;background:#fff}

.ecal-wrap{overflow-x:auto}
table.ecal{width:100%;border-collapse:collapse;table-layout:fixed;min-width:760px;
  border:2px solid #1b74d1;background:#fff}
table.ecal th{background:#1b74d1;color:#fff;font-size:13.5px;font-weight:700;
  padding:9px 6px;text-align:center;border-right:1px solid #4a92dc}
table.ecal th:last-child{border-right:0}
table.ecal td{border:1px solid #c9d3dd;vertical-align:top;height:96px;width:14.28%;padding:0;
  position:relative;background:#fff}
/* today, exactly as the reference marks it */
table.ecal td.is-today{background:#fdfbe4}
table.ecal td.is-blank{background:#fff}

.ecal-date{position:absolute;top:4px;right:7px;font-size:13px;font-weight:700;color:#1b74d1;line-height:1}
.ecal-figure{display:flex;align-items:center;justify-content:flex-start;
  padding:10px 0 0 10px;height:56px}
.ecal-figure svg{height:44px;width:auto;display:block}

/* the coloured bar across the bottom of the cell */
.ecal-bar{position:absolute;left:6px;right:6px;bottom:6px;border-radius:3px;
  color:#fff;font-size:11.5px;font-weight:700;text-align:center;padding:3px 2px;
  line-height:1.25;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.ecal-bar.present{background:#e01b24}
.ecal-bar.half_day{background:#c8541b}
.ecal-bar.absent{background:#8b1a1a}
.ecal-bar.holiday{background:#6b3f1d}
.ecal-bar.weekly_off{background:#5a1f1f}
.ecal-bar.leave{background:#c25b6a}
.ecal-bar.on_duty{background:#1b74d1}
.ecal-bar.not_marked{background:#98a3ae}
.ecal-bar.future{display:none}

td.ecal-day{cursor:pointer}
td.ecal-day:hover{outline:2px solid #1b74d1;outline-offset:-2px}

/* compact month summary — a strip, not a dashboard */
.ecal-sum{display:flex;flex-wrap:wrap;gap:8px;margin:0 0 12px;font-size:12.5px}
.ecal-sum span{border:1px solid #c9d3dd;border-radius:4px;padding:4px 10px;background:#fff}
.ecal-sum b{font-size:14px;margin-right:5px}

/* legends */
.ecal-legend{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:10px 18px}
.ecal-legend div{display:flex;align-items:center;gap:10px}
.ecal-legend svg{height:34px;width:auto;flex:none}

/* SMALLER SCREENS keep the seven columns — a week that wraps is not a week.
   The cell gets shorter, the figure smaller and the bar shows the short code. */
@media (max-width:860px){
  table.ecal{min-width:0}
  table.ecal th{font-size:0;padding:8px 2px}
  table.ecal th::first-letter{font-size:12.5px}
  table.ecal td{height:70px}
  .ecal-figure{height:38px;padding:12px 0 0 4px;justify-content:center}
  .ecal-figure svg{height:30px}
  .ecal-bar{left:2px;right:2px;bottom:3px;font-size:10px;padding:2px 1px}
  .ecal-date{font-size:11px;top:2px;right:3px}
}

/* ============================================================================
   THE RECORD FORM — a person, not a questionnaire.

   The employee form was thirty fields stacked under four headings in one modal:
   correct, and it read as a form to be survived rather than a record to be
   maintained. This is the same fields, given the shape of the thing they
   describe — who it is at the top, one subject at a time, and the decision to
   save it where the eye already is.

   THE LABEL SITS BESIDE ITS FIELD, not above it. Above is right for a narrow
   modal; beside is right for a wide one, and it halves the vertical distance a
   person's eye travels across thirty fields. Below 760px it goes back to above,
   because beside stops working when there is no room to be beside.
   ============================================================================ */
/* WIDTH, NOT max-width. `.modal` carries `width: 560px` outright, so a rule that only raised the
   MAXIMUM changed nothing at all and the card stayed 560px wide: the name wrapped to three lines
   and every field became a stub. `.modal.wide{width:820px}` is the pattern already in this file;
   this follows it. `max-width:100%` is what keeps a phone from being handed a 1180px dialog. */
.modal.rec{width:1180px;max-width:100%;padding:0;overflow:hidden;
  display:flex;flex-direction:column;max-height:90vh}
/* A SHORT FORM DOES NOT NEED 1180px. Three fields spread across a wide card read as a mistake,
   so the small records keep the same language in a narrower frame with a single column. */
.modal.rec.narrow{width:760px}
.modal.rec.narrow .rec-grid{grid-template-columns:1fr}
.modal.rec>h3{display:none}                    /* the header below replaces it */

/* flex:none ON EVERY BAND THAT IS NOT THE BODY. The card is a flex column with a capped
   height, and a flex item shrinks by default — so the TAB STRIP was squeezed to nothing and
   the form looked as though it had no tabs at all, while the four of them sat inside it with
   zero height. The header survived only because its content refused to go quite that small. */
.rec-head{display:flex;align-items:flex-start;gap:20px;padding:24px 30px 0;flex:none}
.rec-av{width:74px;height:74px;border-radius:50%;flex:none;
  background:linear-gradient(160deg,var(--gold,#b8860b),var(--gold-700,#8a6508));
  color:#fff;display:flex;align-items:center;justify-content:center;
  font-size:26px;font-weight:700;letter-spacing:.5px;user-select:none}
.rec-id{flex:1;min-width:0;padding-top:4px}
.rec-eyebrow{font-size:13px;color:var(--ink-500,#6b7684);margin:0 0 2px}
.rec-name{font-size:26px;font-weight:700;color:var(--ink,#1d2530);line-height:1.15;
  margin:0 0 6px;overflow-wrap:anywhere}
.rec-sub{display:flex;align-items:center;gap:7px;font-size:13px;color:var(--ink-500,#6b7684)}
.rec-sub svg{opacity:.7;flex:none}
.rec-actions{display:flex;gap:10px;flex:none;padding-top:6px}
.rec-actions .btn{display:inline-flex;align-items:center;gap:8px;padding:10px 18px;font-size:14px}

/* the tab strip, with a rule that runs the width of the card */
.rec-tabs{display:flex;gap:2px;margin:20px 0 0;padding:0 30px;flex:none;
  border-bottom:1px solid var(--line,#dbe2ea);overflow-x:auto}
.rec-tab{display:inline-flex;align-items:center;gap:9px;white-space:nowrap;
  padding:13px 20px;font-size:14px;font-weight:600;color:var(--ink-500,#6b7684);
  border-bottom:3px solid transparent;margin-bottom:-1px;cursor:pointer;
  border-radius:6px 6px 0 0;transition:background .12s,color .12s}
.rec-tab svg{opacity:.65}
.rec-tab:hover{background:var(--gold-50,#fdf7e8);color:var(--ink,#1d2530)}
.rec-tab.on{color:var(--gold-700,#8a6508);border-bottom-color:var(--gold,#b8860b);
  background:var(--gold-50,#fdf7e8)}
.rec-tab.on svg{opacity:1}

/* ONE SCROLLBAR, NOT TWO. The card is a flex column with the head and the tabs pinned; only
   this band scrolls. A max-height here on top of the modal's own overflow gave two bars side by
   side, each moving a different part of the same form. */
/* The modal's own body div sits between the card and this band, so it has to carry the flex
   through or `flex:1` here would be measured against a parent that is not a flex container. */
.modal.rec>div:not(.rec-head):not(.rec-tabs){flex:1;min-height:0;display:flex;flex-direction:column}
.rec-body{flex:1;min-height:0;overflow-y:auto;padding:22px 30px 28px}

/* A ROW IS A LABEL AND ITS FIELD. Two rows to a line on a wide card, one on a
   narrow one — and the label column is fixed so every field starts on the same
   vertical line whatever its name is called. */
.rec-grid{display:grid;grid-template-columns:1fr 1fr;gap:4px 40px}
.rec-row{display:grid;grid-template-columns:150px 1fr;align-items:center;
  gap:16px;padding:9px 0;min-width:0}
.rec-row.wide{grid-column:1 / -1}
.rec-row.wide.tall{align-items:start}
.rec-row>label{font-size:13.5px;font-weight:500;color:var(--ink-600,#4a5561);
  margin:0;line-height:1.35}
.rec-row>label .req{color:var(--red,#e01b24);font-weight:700}
.rec-ctl{min-width:0}
.rec-ctl>input,.rec-ctl>select,.rec-ctl>textarea{width:100%;
  padding:10px 13px;font-size:14px;border:1px solid var(--line,#dbe2ea);border-radius:8px;
  background:#fff;color:var(--ink,#1d2530);transition:border-color .12s,box-shadow .12s}
.rec-ctl>textarea{min-height:96px;resize:vertical;line-height:1.5}
.rec-ctl>input:focus,.rec-ctl>select:focus,.rec-ctl>textarea:focus{
  outline:none;border-color:var(--gold,#b8860b);box-shadow:0 0 0 3px var(--gold-50,#fdf7e8)}
.rec-ctl>input:disabled,.rec-ctl>input[readonly]{background:var(--paper,#f4f6f8);
  color:var(--ink-500,#6b7684);cursor:not-allowed}
.rec-hint{font-size:12px;color:var(--ink-500,#6b7684);margin:6px 0 0;line-height:1.45}
.rec-note{grid-column:1 / -1;font-size:12.5px;color:var(--ink-500,#6b7684);
  background:var(--paper,#f4f6f8);border-radius:8px;padding:10px 14px;margin:6px 0 10px}
.rec-err{grid-column:1 / -1;color:var(--red,#e01b24);font-size:13px;margin:8px 0 0;min-height:0}
.rec-sep{grid-column:1 / -1;border-top:1px solid var(--line,#dbe2ea);margin:14px 0 4px}

/* A tick belongs on the line with its words, not stacked under a heading. */
.rec-ctl .chk{display:inline-flex;align-items:center;gap:8px;padding:8px 12px;margin:0}
.rec-ticks{display:flex;flex-wrap:wrap;gap:8px}

@media (max-width:1000px){
  .rec-grid{grid-template-columns:1fr}
}
@media (max-width:760px){
  .modal.rec{max-width:100%}
  .rec-head{flex-wrap:wrap;padding:18px 18px 0;gap:14px}
  .rec-av{width:56px;height:56px;font-size:20px}
  .rec-name{font-size:21px}
  .rec-actions{width:100%;padding-top:0}
  .rec-actions .btn{flex:1;justify-content:center}
  .rec-tabs{padding:0 12px}
  .rec-tab{padding:12px 13px;font-size:13px}
  .rec-body{padding:16px 18px 22px;max-height:none}
  /* beside stops working when there is nothing to be beside */
  .rec-row{grid-template-columns:1fr;gap:6px;padding:8px 0}
  .rec-row>label{font-weight:600;font-size:12.5px}
}

/* LEGACY FIELDS, THE SAME LANGUAGE. Thirty-odd HR dialogs build their fields with the older
   helper — a div holding a label and then a control. Rewriting each one by hand would be thirty
   chances to drop a variable in the edit, which is exactly the mistake that cost an afternoon on
   the employee form. So the MARKUP stays as it is and the layout is given to it here: inside a
   record card, a plain field div becomes the same label-beside-control row as a recRow.
   A tick row is not a field and is excluded — its label belongs on the line with its box. */
.rec-body div:has(> label:first-child):not(.chk):not(.checkpill):not(.pick-row){
  display:grid;grid-template-columns:150px 1fr;align-items:center;gap:8px 16px;padding:9px 0;min-width:0}
.rec-body div:has(> label:first-child):not(.chk):not(.checkpill):not(.pick-row) > label{
  margin:0;font-size:13.5px;font-weight:500;color:var(--ink-600,#4a5561);text-transform:none;
  letter-spacing:0;line-height:1.35;grid-column:1}
/* EVERY NON-LABEL CHILD BELONGS IN THE SECOND COLUMN, and this line is the whole fix.
   The legacy fld() markup is <div><label><input><div class=note>hint</div></div> — THREE children.
   Auto-placed in a two-column grid the hint landed in column ONE of the next row, under the label,
   so a paragraph of help text sat where a field name should be and squeezed every input to a stub.
   Forcing column 2 stacks the control and its hint under each other, which is what the markup meant. */
.rec-body div:has(> label:first-child):not(.chk):not(.checkpill):not(.pick-row) > *:not(label){
  grid-column:2;min-width:0}
.rec-body div:has(> label:first-child) > input,
.rec-body div:has(> label:first-child) > select,
.rec-body div:has(> label:first-child) > textarea{
  width:100%;padding:10px 13px;font-size:14px;border-radius:8px}
/* A hint is help, not a paragraph competing with the field it explains. */
.rec-body div:has(> label:first-child) > .note{
  background:none;border:0;padding:0;margin:0;font-size:12px;line-height:1.45;
  color:var(--ink-500,#6b7684)}
/* The two-up rows these dialogs use keep their shape, with the card's own gap. */
.rec-body .grid2{display:grid;grid-template-columns:1fr 1fr;gap:4px 40px}
.rec-body .grid2 > div{min-width:0}
.rec-body .note{font-size:12.5px;line-height:1.55;margin:8px 0}
@media (max-width:1000px){ .rec-body .grid2{grid-template-columns:1fr} }
@media (max-width:760px){
  .rec-body div:has(> label:first-child):not(.chk):not(.checkpill):not(.pick-row){
    grid-template-columns:1fr;gap:6px}
}

/* THE PHONEBOOK'S ONE ROW STYLE. Everything else on that panel is the dashboard's own; this is the
   line that holds a name against an extension, and it has to stay readable when the panel drops to
   a single narrow column on a phone - hence the min-width:0 that lets the name ellipsis rather than
   push the extension off the edge. */
.pb-row{display:flex;align-items:center;justify-content:space-between;gap:12px;
        padding:8px 12px;border-top:1px solid var(--line)}
.pb-row>*{min-width:0}

/* ONE DAY RULE ON ONE LINE, and it has to stay readable when a shift has three of them. The
   columns are sized to their content rather than equally: a weekday name needs room, a break in
   minutes does not. Below a tablet it stacks, because seven fields side by side on a phone is
   seven fields nobody can read. */
.shift-day-row{display:grid;gap:8px;align-items:end;margin-bottom:10px;
  grid-template-columns:1.3fr 1.2fr .9fr .9fr .7fr .8fr .8fr auto}
.shift-day-row label{display:block;font-size:11px;color:var(--muted);margin-bottom:2px}
.shift-day-row input,.shift-day-row select{width:100%}
@media(max-width:900px){.shift-day-row{grid-template-columns:1fr 1fr}}

/* ===== ASK SIFRA =============================================================================
   A launcher that is always reachable and never in the way, and a panel that reads like the rest
   of the ERP rather than like a chat widget bolted onto it. Nothing here is decorative-only: the
   thinking line exists because a local model on CPU takes real seconds and silence reads as a
   hang, and the panel is bounded in height so a long answer scrolls instead of pushing the page.
   ========================================================================================== */
.asksifra-launch {
  position: fixed; right: 22px; bottom: 22px; z-index: 900;
  padding: 10px 16px; border: 0; border-radius: 22px; cursor: pointer;
  font: 600 13px/1 inherit; letter-spacing: .02em;
  background: #1f3a5f; color: #fff; box-shadow: 0 6px 18px rgba(15, 30, 55, .28);
}
.asksifra-launch:hover { background: #27496f; }
.asksifra-launch.is-open { background: #14273f; }

/* HIDDEN HAS TO MEAN HIDDEN.
   The browser's own sheet says [hidden]{display:none}, but a UA rule is the LOWEST cascade origin:
   any author rule that sets `display` beats it, whatever the specificity. `.asksifra-panel` sets
   `display:flex`, so `panel.hidden = true` changed nothing at all — the Ask SIFRA panel could be
   opened and not closed, and after a navigation rebuilt it empty the same rule drew the bordered
   box with no content as a 1px line floating over the page.
   This is the standard guard against that whole family of bug, and it is why every reset carries
   it. It goes here, next to the other resets, so the next component to use `hidden` works. */
[hidden] { display: none !important; }

.asksifra-panel {
  position: fixed; right: 22px; bottom: 74px; z-index: 900;
  width: min(420px, calc(100vw - 44px)); max-height: min(560px, calc(100vh - 120px));
  display: flex; flex-direction: column;
  background: #fff; border: 1px solid #d9e0ea; border-radius: 12px;
  box-shadow: 0 18px 48px rgba(15, 30, 55, .22); overflow: hidden;
}
.asksifra-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 12px 14px; border-bottom: 1px solid #e8edf3; background: #f7f9fc;
}
.asksifra-title { font-weight: 600; color: #1f3a5f; }
.asksifra-x { border: 0; background: none; font-size: 20px; line-height: 1; cursor: pointer; color: #6b7a8d; }

.asksifra-body { padding: 12px 14px; overflow-y: auto; flex: 1 1 auto; }
.asksifra-hint { color: #6b7a8d; font-size: 13px; margin: 4px 0 0; }
.asksifra-turn { margin-bottom: 12px; }
.asksifra-who { font-size: 11px; text-transform: uppercase; letter-spacing: .06em; color: #8a97a8; margin-bottom: 3px; }
.asksifra-text { font-size: 14px; line-height: 1.5; color: #22303f; white-space: pre-wrap; }
.asksifra-you .asksifra-text { color: #1f3a5f; font-weight: 500; }
.asksifra-thinking { color: #8a97a8; font-style: italic; }

.asksifra-foot { display: flex; gap: 8px; padding: 10px 12px; border-top: 1px solid #e8edf3; background: #fbfcfe; }
.asksifra-input { flex: 1 1 auto; padding: 9px 11px; border: 1px solid #d9e0ea; border-radius: 8px; font: inherit; font-size: 14px; }
.asksifra-input:focus { outline: 2px solid #9db8dc; outline-offset: -1px; }
.asksifra-mic, .asksifra-send {
  border: 1px solid #d9e0ea; background: #fff; border-radius: 8px; cursor: pointer; font: inherit; font-size: 13px; padding: 0 12px;
}
.asksifra-send { background: #1f3a5f; color: #fff; border-color: #1f3a5f; font-weight: 600; }
.asksifra-send:disabled, .asksifra-input:disabled { opacity: .55; cursor: default; }
.asksifra-mic.is-live { background: #fdecec; border-color: #e6a8a8; }

/* ------------------------------------------------ organisation chart
   THE INDENT COMES FROM THE NESTING, not from a computed padding per row:
   each level of the tree is one .org-kids container with a left margin and
   a single 1px border for the connector. A twenty-deep chart is therefore
   twenty borders rather than eight hundred calculated offsets, which is
   what keeps a long list scrolling at full speed.

   PRINTING IS PART OF THE SCREEN, not an afterthought. An org chart is a
   thing people put on a wall, so the rail, the top bar and the buttons are
   dropped at print and every folded branch stays folded — printing what is
   on the screen, which is what the reader chose to look at. */
.orgtree{padding:10px 6px 14px}
.org-kids{margin-left:15px;padding-left:13px;border-left:1px solid var(--line)}
.org-row{display:flex;align-items:center;gap:9px;flex-wrap:wrap;
  padding:7px 10px;border-radius:var(--r-sm);min-height:36px}
.org-row:hover{background:var(--gold-50)}
.org-row.loop{background:var(--red-soft)}
.org-row .spacer{flex:1}
.org-twist{width:20px;height:20px;flex:none;display:grid;place-items:center;
  border:1px solid var(--line);border-radius:6px;background:var(--card);
  color:var(--muted);font-size:11px;line-height:1;cursor:pointer;padding:0}
.org-twist:hover{border-color:var(--gold);color:var(--gold-700)}
.org-twist.off{border-color:transparent;background:none;cursor:default;color:var(--muted-2)}
.org-who{display:inline-flex;align-items:center;gap:8px;flex-wrap:wrap;min-width:0}
.org-name{font-size:13.5px;font-weight:600;color:var(--ink)}
.org-desig{font-size:12px;color:var(--muted)}
.org-dept{font-size:11.5px;color:var(--muted-2)}
.org-code{font-size:11px;color:var(--muted-2)}

.org-dept-body{padding:6px 18px 16px}
.org-headline{display:flex;align-items:center;gap:10px;flex-wrap:wrap;
  padding:10px 12px;margin:10px 0;border:1px solid var(--line);
  border-radius:var(--r);background:var(--gold-50)}
.org-headline .lbl{font-size:9.5px;font-weight:600;letter-spacing:.15em;
  text-transform:uppercase;color:var(--gold-700)}
.org-leader{margin:12px 0;border:1px solid var(--line);border-radius:var(--r);overflow:hidden}
.org-leader-head{display:flex;align-items:center;gap:9px;flex-wrap:wrap;
  padding:9px 12px;background:var(--paper);border-bottom:1px solid var(--line-soft)}
.org-leader-head .spacer{flex:1}
.org-team{padding:4px 12px 8px}
.org-member{display:flex;align-items:center;gap:9px;flex-wrap:wrap;
  padding:6px 2px;border-bottom:1px solid var(--line-soft)}
.org-member:last-child{border-bottom:0}

@media print{
  .rail,.topbar,.filters,.tabs,.btn,.org-twist,#toast-host{display:none!important}
  .content,#content{padding:0!important}
  .panel{border:0;box-shadow:none;break-inside:auto}
  .org-leader,.org-member,.org-row{break-inside:avoid}
}

/* ── MY MAIL ───────────────────────────────────────────────────────────────────────────────
   A MAIL LIST IS NOT A TABLE OF RECORDS, and it was drawn as one: FROM / SUBJECT / RECEIVED
   column headings, a boxed grid, and an Open button on every line. That is right for payslips
   and wrong for mail — nobody scans their inbox by column. Every mail client in the world uses
   the same shape instead, so this does too: one line per message, the whole line clickable,
   sender then subject then the snippet in the same breath, the time on the right.

   The tokens are the ERP's own (--line, --paper, --ink, --muted), so it reads as Gmail's SHAPE
   in this application's own skin rather than as a second design pasted in. */
.mail-list{border-top:1px solid var(--line-soft)}
.mail-row{display:grid;grid-template-columns:210px 1fr auto;gap:14px;align-items:baseline;
  padding:11px 16px;border-bottom:1px solid var(--line-soft);cursor:pointer;
  background:var(--card);transition:background .12s var(--ease),box-shadow .12s var(--ease)}
.mail-row:hover{background:var(--paper);box-shadow:inset 3px 0 0 var(--brand)}
/* READ MAIL RECEDES; UNREAD DOES NOT. Gmail's one real signal, and the only thing on this row
   that carries weight — there is no unread BADGE, because a badge on every second line is noise. */
.mail-row.is-read{background:var(--paper)}
.mail-row.is-read .mail-from,.mail-row.is-read .mail-subject{font-weight:400;color:var(--ink-500)}
.mail-from{font-weight:600;color:var(--ink);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* SUBJECT AND SNIPPET SHARE ONE LINE and the snippet gives way first: the subject is what a
   person is looking for, the snippet is only what helps when two subjects look alike. */
.mail-line{display:flex;gap:8px;min-width:0;align-items:baseline}
.mail-subject{font-weight:600;color:var(--ink);white-space:nowrap;flex:0 1 auto;
  overflow:hidden;text-overflow:ellipsis;max-width:60%}
.mail-snippet{color:var(--muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;flex:1 1 auto}
.mail-when{color:var(--muted);font-size:12px;white-space:nowrap;text-align:right}
@media (max-width:820px){
  .mail-row{grid-template-columns:1fr auto;row-gap:2px}
  .mail-from{grid-column:1}.mail-when{grid-column:2}
  .mail-line{grid-column:1 / -1}
  .mail-subject{max-width:100%}
}
/* The opened message. Gmail replaces the list rather than floating a box over it, and a mail is
   long — a modal made the body a 4-line window with its own scrollbar inside the page's. */
.mail-open{background:var(--card)}
.mail-open-head{padding:16px 20px;border-bottom:1px solid var(--line-soft)}
.mail-open h3{margin:0 0 10px;font-size:18px;line-height:1.35}
.mail-meta{display:grid;grid-template-columns:auto 1fr;gap:4px 14px;font-size:13px;color:var(--muted)}
.mail-meta b{color:var(--ink-700);font-weight:600}
/* THE BODY IS TEXT AND IS RENDERED AS TEXT. A mail arrives from outside, from anybody; this is
   the one surface in the ERP where markup from a stranger would otherwise reach the page. */
.mail-body{padding:18px 20px;white-space:pre-wrap;word-break:break-word;line-height:1.6;
  color:var(--ink-700);font-size:14px}
.mail-actions{padding:14px 20px;border-top:1px solid var(--line-soft);display:flex;gap:10px;
  align-items:center;flex-wrap:wrap}
