/* ==========================================================================
   Monika Alcobev — Label Registration Portal
   Hand-written design system (no external CSS dependency, works offline)

   Palette: neutral enterprise canvas — true-gray surfaces and text, with
   emerald (--brand-*) and brass (--accent2-*) kept strictly as accents
   (buttons, active nav, badges, focus rings, the brand mark). Replaces the
   earlier "Botanical Gin" identity, whose warm-tinted neutrals and colored
   background wash read as a boutique/consumer site rather than MNC-grade
   SCM software. Applied purely at the token/value level below: every
   existing selector, class name and id an existing page's JS depends on is
   untouched — only colors, fonts, spacing and a few visual properties
   changed.
   ========================================================================== */

@font-face{
  font-family:'IBM Plex Sans';font-style:normal;font-weight:400;font-display:swap;
  src:url(../fonts/ibm-plex-sans-regular.woff2) format('woff2');
}
@font-face{
  font-family:'IBM Plex Sans';font-style:normal;font-weight:500;font-display:swap;
  src:url(../fonts/ibm-plex-sans-medium.woff2) format('woff2');
}
@font-face{
  font-family:'IBM Plex Sans';font-style:normal;font-weight:600;font-display:swap;
  src:url(../fonts/ibm-plex-sans-semibold.woff2) format('woff2');
}
@font-face{
  font-family:'IBM Plex Sans';font-style:normal;font-weight:700;font-display:swap;
  src:url(../fonts/ibm-plex-sans-bold.woff2) format('woff2');
}
@font-face{
  font-family:'IBM Plex Mono';font-style:normal;font-weight:400;font-display:swap;
  src:url(../fonts/ibm-plex-mono-regular.woff2) format('woff2');
}
@font-face{
  font-family:'IBM Plex Mono';font-style:normal;font-weight:500;font-display:swap;
  src:url(../fonts/ibm-plex-mono-medium.woff2) format('woff2');
}
@font-face{
  font-family:'IBM Plex Mono';font-style:normal;font-weight:600;font-display:swap;
  src:url(../fonts/ibm-plex-mono-semibold.woff2) format('woff2');
}

:root{
  /* Brand — emerald. 500-900 stay constant across light/dark themes (this
     particular emerald is saturated enough to read on both); only the
     50/100 tints (used as subtle hover/focus backgrounds) get dark-
     appropriate replacements below. */
  --brand-900:#0a1f3d;
  --brand-800:#123a66;
  --brand-700:#1a56a3;
  --brand-600:#2568c2;
  --brand-500:#3f82db;
  --brand-100:#dbe9fb;
  --brand-50:#f0f6fd;
  /* Emerald text sitting directly on a card/surface background (pills,
     active tabs) — needs to be brighter than brand-700 once the surface
     goes dark, so it gets its own token instead of reusing the button-
     background green. */
  --brand-text:var(--brand-700);

  /* Brass — the palette's second accent (secondary badges, alternating KPI
     borders, warn-toned states). Same "500-900 constant" reasoning as
     brand-* above. */
  --accent2-900:#4a3113;
  --accent2-800:#6b4a1c;
  --accent2-700:#8a6224;
  --accent2-600:#b08d57;
  --accent2-500:#c7a877;
  --accent2-100:#f3ead9;
  --accent2-50:#faf6ee;

  /* Fixed-dark — always this exact dark, warm-tinted near-black regardless
     of theme. Used by components that are intentionally dark in both
     themes (toasts) and by the sidebar's own dark-theme
     palette below. Never overridden in the dark-theme blocks below. */
  --fixed-dark-900:#16201b;

  /* Login/Maintenance screen backdrop — its own fixed palette (not
     --fixed-dark-900 above, which stays shared with the sidebar/toasts),
     always this exact indigo/navy regardless of theme, same "never
     overridden below" rule. Deliberately not brand green — the emerald
     version of this backdrop read as unattractive in practice; brass
     (--accent2-600, used further down) stays as the one warm glow against
     it, everything else here is cool and neutral-dark. */
  --login-dark-1:#0e1220;
  --login-dark-2:#1b2340;
  --login-glow-blue:#4a63c8;

  /* Sidebar — follows the light/dark theme (unlike the fixed-dark items
     above). Light values live here; the dark-theme blocks below swap them
     for the dark treatment. Hover/glow keep only a whisper of brand tint —
     the sidebar's one legitimate "accent" surface — everything else here is
     neutral. */
  --sidebar-bg-1:var(--ink-50);
  --sidebar-bg-2:var(--white);
  --sidebar-text:var(--ink-800);
  --sidebar-text-strong:var(--ink-900);
  --sidebar-text-muted:var(--ink-500);
  --sidebar-border:var(--ink-200);
  --sidebar-hover-bg:var(--ink-100);
  --sidebar-glow-bg:radial-gradient(ellipse at top, rgba(26,86,163,.08), transparent 70%);
  --sidebar-toggle-bg:var(--ink-50);
  --sidebar-toggle-border:var(--ink-200);
  --sidebar-scrollbar-thumb:var(--ink-300);

  /* Neutrals — true gray, no warm/green bias. The dominant surface color in
     this system, by design: emerald/brass are reserved for accents (see
     --brand-*/--accent2- above), never the base canvas. */
  --ink-900:#111418;
  --ink-800:#1f242b;
  --ink-700:#333a44;
  --ink-600:#4b525c;
  --ink-500:#6b7280;
  --ink-400:#9198a1;
  --ink-300:#c1c6cc;
  --ink-200:#dfe2e6;
  --ink-100:#eef0f2;
  --ink-50:#f7f8fa;

  --white:#ffffff;

  /* "Glass" tokens — kept as the surface/border source for .card/.modal/
     .topbar/.sidebar (rather than reverting those selectors individually)
     so this stays a one-place change: solid, visible-bordered, no blur, in
     both themes. */
  --glass-bg:var(--white);
  --glass-border:var(--ink-200);
  --blur:none;
  /* Flat neutral canvas — no colored background wash. An operational SCM
     dashboard reads as "enterprise" partly by NOT tinting every surface
     with the brand color; the accent only shows up where it's doing a job
     (buttons, active nav, badges). */
  --body-mesh:none;

  /* Semantic — kept as its own green independent of --brand-* (which moved
     to blue for the enterprise re-theme), so "approved" keeps a distinct,
     conventional green rather than following the brand accent's hue; warn/
     pending leans brass; danger stays a clearly-different warm rust; info
     is a soft teal, distinct from both. */
  --success-700:#134e3d;
  --success-600:#1f7a5c;
  --success-100:#e1efe8;
  --warn-700:#7a5c1f;
  --warn-600:#b08d57;
  --warn-100:#f6eedd;
  --danger-700:#7a2c1f;
  --danger-600:#a3402f;
  --danger-100:#f5e2dc;
  --info-700:#1f4a42;
  --info-600:#3a7a6d;
  --info-100:#e2eeea;

  /* Dashboard Drill Down — one color per hierarchy level (Region/State/
     Manager/Employee), so a pivoted table reads which level a row belongs
     to at a glance instead of every subtotal looking like flat grey. A
     validated 4-hue categorical palette (blue/orange/aqua/yellow, in fixed
     order — never reassigned per query) — see js/pages/targets.js's
     LEVEL_COLOR_CLASS. */
  --level-region-600:#2a78d6;
  --level-region-100:#e4eefb;
  --level-state-600:#eb6834;
  --level-state-100:#fce6da;
  --level-manager-600:#1baf7a;
  --level-manager-100:#e0f5ec;
  --level-employee-600:#eda100;
  --level-employee-100:#fbebd0;

  --radius-sm:5px;
  --radius-md:9px;
  --radius-lg:14px;
  --shadow-sm:0 1px 2px rgba(17,20,24,.07);
  --shadow-md:0 4px 14px rgba(17,20,24,.10);
  --shadow-lg:0 12px 32px rgba(17,20,24,.16);
  --sidebar-w:228px;
  --topbar-h:58px;
  /* One enterprise-grade sans for everything — display headings use the
     same family at heavier weight rather than pairing in a second face, and
     IBM Plex Mono carries tabular figures (KPI values, currency) so columns
     of numbers actually line up. */
  --font: 'IBM Plex Sans', "Segoe UI Variable Text", "Segoe UI", -apple-system, BlinkMacSystemFont, "Inter", "Calibri", Roboto, Helvetica, Arial, sans-serif;
  --font-display: 'IBM Plex Sans', "Segoe UI Variable Display", "Segoe UI Variable Text", "Segoe UI", "Inter", -apple-system, BlinkMacSystemFont, Roboto, Helvetica, Arial, sans-serif;
  --font-mono: 'IBM Plex Mono', "Cascadia Mono", "Consolas", "SFMono-Regular", Menlo, monospace;
  --ease: cubic-bezier(.22,.9,.3,1);
  --t-fast: .15s;
  --t-med: .28s;
}

/* ---------- Dark theme ----------
   Two blocks, deliberately identical: one for an explicit user choice
   (data-theme="dark"), one that follows the OS preference when the user has
   picked "System" (no data-theme attribute at all — see js/theme.js). */
:root[data-theme="dark"]{
  --brand-50:#142a4d;
  --brand-100:#1c3c6b;
  --brand-text:var(--brand-500);

  --accent2-50:#241c0e;
  --accent2-100:#382c17;

  --ink-900:#f4f5f6;
  --ink-800:#e2e4e7;
  --ink-700:#b7bcc2;
  --ink-600:#8b909a;
  --ink-500:#767c87;
  --ink-400:#565c66;
  --ink-300:#383d45;
  --ink-200:#282c33;
  --ink-100:#1c1f24;
  --ink-50:#121417;

  --white:#17191d;

  --glass-bg:var(--white);
  --glass-border:var(--ink-200);
  --blur:none;
  --body-mesh:none;

  --success-700:#8fe0c0;
  --success-600:#3ecf9a;
  --success-100:#123424;
  --warn-700:#f0cf8f;
  --warn-600:#d1a668;
  --warn-100:#3a2e15;
  --danger-700:#f0a99a;
  --danger-600:#c2604a;
  --danger-100:#3a1c14;
  --info-700:#a8d9cd;
  --info-600:#5aa696;
  --info-100:#16332c;

  --level-region-600:#3987e5;
  --level-region-100:#17283f;
  --level-state-600:#d95926;
  --level-state-100:#3a2313;
  --level-manager-600:#199e70;
  --level-manager-100:#103a2b;
  --level-employee-600:#c98500;
  --level-employee-100:#3a2c10;

  --shadow-sm:0 1px 2px rgba(0,0,0,.4);
  --shadow-md:0 4px 14px rgba(0,0,0,.45);
  --shadow-lg:0 12px 32px rgba(0,0,0,.55);

  --sidebar-bg-1:var(--fixed-dark-900);
  --sidebar-bg-2:#131a12;
  --sidebar-text:#dde6de;
  --sidebar-text-strong:#ffffff;
  --sidebar-text-muted:#8d9c8f;
  --sidebar-border:rgba(255,255,255,.08);
  --sidebar-hover-bg:rgba(255,255,255,.07);
  --sidebar-glow-bg:radial-gradient(ellipse at top, rgba(26,86,163,.5), rgba(176,141,87,.16) 45%, transparent 70%);
  --sidebar-toggle-bg:rgba(255,255,255,.04);
  --sidebar-toggle-border:rgba(255,255,255,.1);
  --sidebar-scrollbar-thumb:rgba(255,255,255,.18);
}

@media (prefers-color-scheme: dark){
  :root:not([data-theme]){
    --brand-50:#142a4d;
    --brand-100:#1c3c6b;
  --brand-text:var(--brand-500);

    --accent2-50:#241c0e;
    --accent2-100:#382c17;

    --ink-900:#f4f5f6;
    --ink-800:#e2e4e7;
    --ink-700:#b7bcc2;
    --ink-600:#8b909a;
    --ink-500:#767c87;
    --ink-400:#565c66;
    --ink-300:#383d45;
    --ink-200:#282c33;
    --ink-100:#1c1f24;
    --ink-50:#121417;

    --white:#17191d;

    --glass-bg:var(--white);
    --glass-border:var(--ink-200);
    --blur:none;
    --body-mesh:none;

    --success-700:#8fe0c0;
    --success-600:#3ecf9a;
    --success-100:#123424;
    --warn-700:#f0cf8f;
    --warn-600:#d1a668;
    --warn-100:#3a2e15;
    --danger-700:#f0a99a;
    --danger-600:#c2604a;
    --danger-100:#3a1c14;
    --info-700:#a8d9cd;
    --info-600:#5aa696;
    --info-100:#16332c;

    --level-region-600:#3987e5;
    --level-region-100:#17283f;
    --level-state-600:#d95926;
    --level-state-100:#3a2313;
    --level-manager-600:#199e70;
    --level-manager-100:#103a2b;
    --level-employee-600:#c98500;
    --level-employee-100:#3a2c10;

    --shadow-sm:0 1px 2px rgba(0,0,0,.4);
    --shadow-md:0 4px 14px rgba(0,0,0,.45);
    --shadow-lg:0 12px 32px rgba(0,0,0,.55);

    --sidebar-bg-1:var(--fixed-dark-900);
    --sidebar-bg-2:#131a12;
    --sidebar-text:#dde6de;
    --sidebar-text-strong:#ffffff;
    --sidebar-text-muted:#8d9c8f;
    --sidebar-border:rgba(255,255,255,.08);
    --sidebar-hover-bg:rgba(255,255,255,.07);
    --sidebar-glow-bg:radial-gradient(ellipse at top, rgba(26,86,163,.5), rgba(176,141,87,.16) 45%, transparent 70%);
    --sidebar-toggle-bg:rgba(255,255,255,.04);
    --sidebar-toggle-border:rgba(255,255,255,.1);
    --sidebar-scrollbar-thumb:rgba(255,255,255,.18);
  }
}

*,*::before,*::after{box-sizing:border-box;}
/* Without !important, an element that is both [hidden] AND carries a class
   that sets its own `display` (.check-grid{display:grid}, .pivot-dropzone,
   etc.) stays VISIBLE — author-stylesheet rules beat the browser's built-in
   [hidden]{display:none} at equal specificity, so the later class wins.
   This makes `hidden` actually mean hidden everywhere in the app, not just
   in places that happen to set no display of their own (the bug this
   caught: a Publish modal's Designation checklist bleeding through into
   the "Specific People" view because both are .check-grid). */
[hidden]{display:none!important;}
html,body{height:100%;}
body{
  margin:0;
  font-family:var(--font);
  font-size:14px;
  line-height:1.5;
  color:var(--ink-800);
  background-color:var(--ink-50);
  background-image:var(--body-mesh);
  background-attachment:fixed;
  -webkit-font-smoothing:antialiased;
  text-rendering:optimizeLegibility;
  transition:background-color .25s ease, color .25s ease;
}

@media (prefers-reduced-motion: reduce){
  *,*::before,*::after{animation-duration:.001ms !important;animation-iteration-count:1 !important;transition-duration:.001ms !important;}
}
h1,h2,h3,h4,p{margin:0;}
h1,h2,h3,h4,.kpi-value,.topbar-title,.login-brand h1,.sidebar-brand-text b{font-family:var(--font-display);letter-spacing:-.01em;}
ul{list-style:none;margin:0;padding:0;}
a{color:inherit;text-decoration:none;}
button{font-family:inherit;}
input,select,textarea{font-family:inherit;}

.hidden{display:none !important;}

/* ---------- Login (and the Maintenance screen, which shares its look) ---------- */
#login-screen,
#maintenance-screen{
  min-height:100vh;
  display:flex;
  align-items:center;
  justify-content:center;
  position:relative;
  overflow:hidden;
  background:linear-gradient(135deg, var(--login-dark-1), var(--login-dark-2) 70%);
  padding:20px;
}
#login-screen::before,
#login-screen::after,
#maintenance-screen::before,
#maintenance-screen::after{
  content:"";
  position:absolute;
  width:60vmax;height:60vmax;
  border-radius:50%;
  filter:blur(60px);
  opacity:.35;
  pointer-events:none;
  z-index:0;
}
#login-screen::before,
#maintenance-screen::before{
  background:radial-gradient(circle, var(--login-glow-blue), transparent 65%);
  top:-20vmax;left:-15vmax;
  animation:blobFloat1 16s ease-in-out infinite alternate;
}
#login-screen::after,
#maintenance-screen::after{
  background:radial-gradient(circle, var(--accent2-600), transparent 65%);
  bottom:-25vmax;right:-15vmax;
  opacity:.28;
  animation:blobFloat2 20s ease-in-out infinite alternate;
}
@keyframes blobFloat1{
  0%{transform:translate(0,0) scale(1);}
  100%{transform:translate(6vmax,8vmax) scale(1.12);}
}
@keyframes blobFloat2{
  0%{transform:translate(0,0) scale(1);}
  100%{transform:translate(-5vmax,-6vmax) scale(1.15);}
}
.login-split{
  position:relative;z-index:1;
  width:100%;max-width:860px;
  display:grid;grid-template-columns:1.05fr 1fr;
  border-radius:var(--radius-lg);
  overflow:hidden;
  box-shadow:var(--shadow-lg);
  animation:cardRise .5s var(--ease);
}
@media (max-width:760px){.login-split{grid-template-columns:1fr;max-width:420px;}}
.login-art-panel{
  position:relative;
  padding:36px 34px;
  display:flex;flex-direction:column;justify-content:space-between;
  background:
    radial-gradient(60% 55% at 68% 22%, rgba(176,141,87,.22), transparent 65%),
    radial-gradient(70% 60% at 25% 65%, rgba(74,99,200,.28), transparent 70%),
    linear-gradient(165deg, rgba(255,255,255,.10), rgba(255,255,255,.02));
  border-right:1px solid rgba(255,255,255,.12);
}
@media (max-width:760px){.login-art-panel{display:none;}}
.login-art-brand{display:flex;align-items:center;gap:10px;}
.login-art-brand .mark{width:32px;height:32px;border-radius:9px;background:rgba(255,255,255,.14);border:1px solid rgba(255,255,255,.3);display:flex;align-items:center;justify-content:center;color:#fff;padding:6px;}
.login-art-brand .mark svg{width:100%;height:100%;fill:none;stroke:currentColor;stroke-width:1.6;stroke-linecap:round;stroke-linejoin:round;}
.login-art-brand span{color:rgba(255,255,255,.92);font-size:11.5px;font-weight:700;letter-spacing:.14em;}
.login-bottles{align-self:center;width:100%;max-width:280px;filter:drop-shadow(0 18px 26px rgba(0,0,0,.28));}
.login-art-copy .tagline{
  font-size:10.5px;font-weight:700;letter-spacing:.16em;text-transform:uppercase;
  color:#f3ead9;background:rgba(255,255,255,.12);border:1px solid rgba(255,255,255,.2);
  padding:4px 10px;border-radius:999px;display:inline-block;
}
.login-art-copy .headline{
  font-family:var(--font-display);font-style:italic;font-weight:600;font-size:23px;
  color:#fff;margin:12px 0 6px;line-height:1.2;
}
.login-art-copy .sub{color:rgba(255,255,255,.72);font-size:12px;max-width:30ch;}
.login-card{
  position:relative;
  z-index:1;
  width:100%;
  max-width:400px;
  margin:0 auto;
  background:var(--glass-bg);
  -webkit-backdrop-filter:var(--blur);
  backdrop-filter:var(--blur);
  border-radius:var(--radius-lg);
  box-shadow:var(--shadow-lg);
  padding:36px 32px 28px;
  display:flex;flex-direction:column;justify-content:center;
  animation:cardRise .5s var(--ease);
}
/* Nested inside .login-split (the real Sign In screen) — the outer wrapper
   already owns the rounding/shadow/entrance animation for the whole two-
   panel unit, so the card itself just fills its grid column plainly.
   Standalone (the Maintenance screen, which reuses .login-card on its own
   with no .login-split wrapper) keeps the rule above untouched. */
.login-split .login-card{max-width:none;margin:0;border-radius:0;box-shadow:none;animation:none;}
@keyframes cardRise{
  from{opacity:0;transform:translateY(14px) scale(.98);}
  to{opacity:1;transform:none;}
}
.login-brand{
  display:flex;
  flex-direction:column;
  align-items:center;
  gap:10px;
  margin-bottom:22px;
}
.brand-logo-full{
  display:flex;align-items:center;justify-content:center;
  background:#fff;
  border-radius:var(--radius-md);
  padding:10px 18px;
  box-shadow:var(--shadow-md);
  transition:transform var(--t-med) var(--ease);
}
.brand-logo-full img{display:block;height:44px;width:auto;max-width:200px;object-fit:contain;}
.brand-logo-full:hover{transform:scale(1.03);}
.login-brand h1{font-size:17px;font-weight:700;color:var(--ink-900);text-align:center;}
.login-brand span{font-size:12.5px;color:var(--ink-500);text-align:center;}
.brand-tagline{
  display:inline-block;
  margin-top:4px;
  font-size:10.5px;
  font-weight:700;
  letter-spacing:.08em;
  text-transform:uppercase;
  color:var(--brand-text);
}
.sidebar-brand .brand-tagline{margin-top:1px;font-size:9px;letter-spacing:.07em;}
.login-demo{
  margin-top:18px;
  background:var(--ink-50);
  border:1px dashed var(--ink-300);
  border-radius:var(--radius-md);
  padding:12px 14px;
  font-size:12px;
  color:var(--ink-600);
  line-height:1.6;
}
.login-demo b{color:var(--ink-800);}
.login-error{
  background:var(--danger-100);color:var(--danger-700);
  border-radius:var(--radius-sm);
  padding:9px 12px;font-size:13px;margin-bottom:14px;
}
#login-maintenance-banner:empty{display:none;}
#login-maintenance-banner .banner{
  background:var(--warn-100);color:var(--warn-700);
  border-radius:var(--radius-sm);
  padding:9px 12px;font-size:13px;margin-bottom:14px;text-align:left;
}

/* ---------- App shell ---------- */
#app-shell{display:flex;min-height:100vh;}

.sidebar{
  width:var(--sidebar-w);
  flex-shrink:0;
  background:linear-gradient(180deg,var(--sidebar-bg-1),var(--sidebar-bg-2) 85%);
  -webkit-backdrop-filter:var(--blur);
  backdrop-filter:var(--blur);
  color:var(--sidebar-text);
  border-right:1px solid var(--sidebar-border);
  display:flex;
  flex-direction:column;
  position:fixed;
  top:0;left:0;bottom:0;
  overflow-y:hidden;
  overflow-x:hidden;
  transition:background var(--t-med) var(--ease), color var(--t-med) var(--ease), border-color var(--t-med) var(--ease);
}
/* #sidebar-nav (not .sidebar) is the scroll region, so a long/expanded nav
   list (e.g. every Masters item open at once) scrolls in place instead of
   pushing the Collapse button below it — min-height:0 is required for a
   flex child to shrink and scroll instead of growing past its container. */
#sidebar-nav{
  flex:1 1 auto;
  min-height:0;
  overflow-y:auto;
  overflow-x:hidden;
}
.sidebar::before{
  content:"";
  position:absolute;
  top:-10%;left:-40%;
  width:180%;height:45%;
  background:var(--sidebar-glow-bg);
  pointer-events:none;
  animation:sidebarGlow 10s ease-in-out infinite alternate;
  z-index:0;
}
@keyframes sidebarGlow{
  0%{opacity:.5;transform:translateY(0) scale(1);}
  100%{opacity:.85;transform:translateY(3%) scale(1.05);}
}
.sidebar-brand,.nav-section{position:relative;z-index:1;}
.sidebar-brand{
  display:flex;align-items:center;gap:10px;
  padding:18px 18px;
  border-bottom:1px solid var(--sidebar-border);
  /* It's a <button> now (click the logo to go Home) — reset browser button chrome */
  width:100%;background:none;border-left:none;border-right:none;border-top:none;
  font:inherit;text-align:left;cursor:pointer;
  transition:background var(--t-fast) var(--ease);
}
.sidebar-brand:hover{background:rgba(255,255,255,.06);}
.brand-logo-mark{
  width:46px;height:46px;border-radius:12px;flex-shrink:0;
  background:#fff;
  display:flex;align-items:center;justify-content:center;
  overflow:hidden;
  box-shadow:0 1px 3px rgba(0,0,0,.3);
  padding:5px;
}
.brand-logo-mark img{width:100%;height:100%;object-fit:contain;display:block;}
.sidebar-brand-text b{display:block;font-size:12.5px;color:var(--sidebar-text-strong);overflow:hidden;text-overflow:ellipsis;}
.sidebar-brand-text span{font-size:10.5px;color:var(--sidebar-text-muted);letter-spacing:.4px;}
.sidebar-brand-text{min-width:0;overflow:hidden;white-space:nowrap;}

.nav-section{padding:14px 12px 4px;}
.nav-section-label{
  font-size:10.5px;text-transform:uppercase;letter-spacing:.05em;
  color:var(--sidebar-text-muted);padding:6px 10px;font-weight:700;
  white-space:nowrap;overflow:hidden;
}
.nav-link{
  display:flex;align-items:center;gap:10px;
  padding:9px 12px;border-radius:var(--radius-sm);
  font-size:13.5px;color:var(--sidebar-text);cursor:pointer;
  margin-bottom:2px;
  position:relative;
  border-left:2px solid transparent;
  white-space:nowrap;overflow:hidden;
  transition:background var(--t-fast) var(--ease), color var(--t-fast) var(--ease), border-color var(--t-fast) var(--ease), transform var(--t-fast) var(--ease), padding-left var(--t-fast) var(--ease);
}
.nav-link .ico{
  width:24px;height:24px;flex-shrink:0;display:inline-flex;align-items:center;justify-content:center;
  border-radius:7px;background:var(--brand-100);color:var(--brand-text);opacity:.9;
  transition:transform var(--t-fast) var(--ease), opacity var(--t-fast) var(--ease), background var(--t-fast) var(--ease), color var(--t-fast) var(--ease);
}
.nav-link .ico svg{width:14px;height:14px;}
.nav-link:hover .ico,.nav-link.active .ico{opacity:1;}
.nav-link:hover{background:var(--sidebar-hover-bg);color:var(--sidebar-text-strong);padding-left:16px;}
.nav-link:hover .ico{transform:scale(1.1);}
.nav-link.active .ico{background:rgba(255,255,255,.24);color:#fff;}
.nav-link.sub .ico,.nav-group-children .nav-link .ico{background:var(--accent2-100);color:var(--accent2-700);}
.nav-link.sub.active .ico,.nav-group-children .nav-link.active .ico{background:rgba(255,255,255,.24);color:#fff;}
.nav-link.active{background:var(--brand-700);color:#fff;border-left-color:var(--brand-500);box-shadow:0 4px 14px rgba(26,86,163,.35);}
.nav-link.sub{padding-left:30px;font-size:13px;}
.nav-link:active{transform:scale(.98);}

.sidebar-toggle{
  display:flex;align-items:center;gap:10px;
  margin:auto 12px 14px;padding:9px 12px;
  border-radius:var(--radius-sm);border:1px solid var(--sidebar-toggle-border);
  background:var(--sidebar-toggle-bg);color:var(--sidebar-text-muted);
  font-size:12.5px;font-family:inherit;cursor:pointer;
  white-space:nowrap;overflow:hidden;position:relative;z-index:1;
  transition:background var(--t-fast) var(--ease), color var(--t-fast) var(--ease);
}
.sidebar-toggle:hover{background:var(--sidebar-hover-bg);color:var(--sidebar-text-strong);}
.sidebar-toggle .ico{width:18px;flex-shrink:0;display:inline-flex;align-items:center;justify-content:center;}
.sidebar-toggle .ico svg{width:16px;height:16px;}

/* ---------- Sidebar collapsed (icon-only) ---------- */
#app-shell.sidebar-collapsed{--sidebar-w:68px;}
#app-shell.sidebar-collapsed .nav-text,
#app-shell.sidebar-collapsed .sidebar-brand-text,
#app-shell.sidebar-collapsed .nav-section-label{display:none;}
#app-shell.sidebar-collapsed .sidebar-brand{justify-content:center;padding:18px 10px;}
#app-shell.sidebar-collapsed .nav-link{justify-content:center;padding-left:12px;}
#app-shell.sidebar-collapsed .nav-link:hover{padding-left:12px;}
#app-shell.sidebar-collapsed .nav-link .ico{width:24px;}
#app-shell.sidebar-collapsed .sidebar-toggle{justify-content:center;padding-left:12px;}

/* ---------- Nav position: top ---------- */
#app-shell[data-nav-pos="top"]{flex-direction:column;}
#app-shell[data-nav-pos="top"] .sidebar{
  position:relative;width:100%;height:auto;
  flex-direction:row;align-items:center;
  overflow:visible;
  z-index:25;
}
/* .sidebar-brand's base rule sets width:100% for left-nav mode, where it's
   a block stacked in a column flex sidebar and should span that column.
   In row-flex top-nav mode that same width:100% makes it try to fill
   nearly the whole bar, crowding #sidebar-nav down to nothing and pushing
   the collapse toggle off the visible edge — reset it back to content-sized. */
#app-shell[data-nav-pos="top"] .sidebar-brand{width:auto;border-bottom:none;border-right:1px solid var(--sidebar-border);flex-shrink:0;padding:9px 14px;}
#app-shell[data-nav-pos="top"] .brand-logo-mark{width:30px;height:30px;border-radius:8px;padding:3px;}
#app-shell[data-nav-pos="top"] .sidebar-brand-text b{font-size:11.5px;}
#app-shell[data-nav-pos="top"] .sidebar-brand-text span{font-size:9px;}
#app-shell[data-nav-pos="top"] #sidebar-nav{
  display:flex;align-items:center;flex-wrap:wrap;flex:1;min-width:0;
  gap:2px;padding:6px 8px;
  /* #sidebar-nav's base rule (left-sidebar mode) sets overflow-y:auto so a
     long nav list scrolls instead of pushing the Collapse button out of
     view — but a workflow's dropdown here (.nav-group-children,
     position:absolute, popping out below this row) is a DESCENDANT of
     #sidebar-nav, so that same overflow clips it down to a sliver the
     instant it's supposed to open. Canceling back to visible here matches
     .sidebar's own overflow:visible override two rules up, for the same
     reason. */
  overflow:visible;
}
#app-shell[data-nav-pos="top"] .nav-section{
  display:flex;align-items:center;flex-wrap:wrap;gap:2px;padding:0;
  border-right:1px solid var(--sidebar-border);
  margin-right:6px;padding-right:6px;
}
#app-shell[data-nav-pos="top"] .nav-section:last-child{border-right:none;}
#app-shell[data-nav-pos="top"] .nav-section-label{display:none;}
#app-shell[data-nav-pos="top"] .nav-link{margin-bottom:0;border-left:none;border-bottom:2px solid transparent;padding:7px 11px;font-size:13px;}
#app-shell[data-nav-pos="top"] .nav-link:hover{padding-left:11px;}
#app-shell[data-nav-pos="top"] .nav-link.active{border-left-color:transparent;border-bottom-color:var(--brand-500);}
#app-shell[data-nav-pos="top"] .nav-link .ico{width:20px;height:20px;}
#app-shell[data-nav-pos="top"] .sidebar-toggle{margin:0 10px 0 4px;flex-shrink:0;padding:6px 10px;font-size:12px;}
#app-shell[data-nav-pos="top"] .main-area{margin-left:0;}
#app-shell[data-nav-pos="top"].sidebar-collapsed .sidebar-brand-text{display:none;}

/* Top-nav mode already spends a row on the nav tabs above (the .sidebar
   overrides just above this block) — the topbar below it only has to carry
   the page title and the FY/user/logout controls, so it can be much
   shorter than its left-sidebar-mode height (58px). Two full-height bars
   stacked was exactly what was eating a laptop-height screen's vertical
   space; this keeps both rows but shrinks the second one down to what its
   contents actually need. */
#app-shell[data-nav-pos="top"] .topbar{height:40px;padding:0 16px;}
#app-shell[data-nav-pos="top"] .topbar-right{gap:8px;}
#app-shell[data-nav-pos="top"] .topbar-title{font-size:13px;}
/* The active nav tab above already shows which top-level section you're
   in — this breadcrumb would just repeat it, so it's dropped here (not in
   left-sidebar mode, where the topbar has no such tab to lean on). */
#app-shell[data-nav-pos="top"] .topbar-crumb{display:none;}
#app-shell[data-nav-pos="top"] .support-bell-pill{width:26px;height:26px;}
#app-shell[data-nav-pos="top"] .fy-pill{padding:3px 4px 3px 9px;}
#app-shell[data-nav-pos="top"] .fy-pill select{padding:3px 8px;font-size:12px;}
#app-shell[data-nav-pos="top"] .user-chip{gap:7px;}
#app-shell[data-nav-pos="top"] .user-avatar{width:26px;height:26px;font-size:11px;}
#app-shell[data-nav-pos="top"] .user-meta b{font-size:12px;}
#app-shell[data-nav-pos="top"] .user-meta span{font-size:10px;}
#app-shell[data-nav-pos="top"] .btn-logout{padding:5px 10px;font-size:12px;}

.topbar{
  height:var(--topbar-h);
  background:var(--glass-bg);
  -webkit-backdrop-filter:var(--blur);
  backdrop-filter:var(--blur);
  border-bottom:1px solid var(--glass-border);
  display:flex;align-items:center;justify-content:space-between;
  padding:0 22px;
  position:sticky;top:0;z-index:20;
}
.topbar-left{display:flex;align-items:center;gap:14px;}
.topbar-title{font-size:16px;font-weight:700;color:var(--ink-900);}
.topbar-crumb{font-size:12px;color:var(--ink-500);}
.topbar-right{display:flex;align-items:center;gap:14px;}

.fy-pill{
  display:flex;align-items:center;gap:8px;
  background:var(--ink-50);border:1px solid var(--ink-200);
  border-radius:999px;padding:5px 6px 5px 12px;
}
.fy-pill label{font-size:11px;color:var(--ink-500);font-weight:600;}
.fy-pill select{
  border:none;background:var(--white);border-radius:999px;
  padding:4px 10px;font-size:12.5px;font-weight:600;color:var(--brand-text);
  cursor:pointer;
}

/* Master-only topbar toggle — Masters > Maintenance Mode. Off is a quiet
   neutral pill; On turns amber and pulses, matching .badge-warn's "needs
   attention" treatment elsewhere, since a Master leaving this on by mistake
   after a deploy is exactly the mistake this color is meant to catch. */
.maintenance-pill{
  display:flex;align-items:center;gap:6px;
  border:1px solid var(--ink-200);background:var(--ink-50);color:var(--ink-600);
  border-radius:999px;padding:6px 14px;font-size:12.5px;font-weight:700;
  cursor:pointer;transition:transform var(--t-fast) var(--ease);
}
.maintenance-pill:hover{transform:translateY(-1px);}
.maintenance-pill.on{
  background:var(--warn-100);color:var(--warn-700);border-color:transparent;
  animation:badgePulse 2.4s ease-in-out infinite;
}

/* Theme toggle is a two-icon pill (sun/moon), same look and behavior as the
   nav layout pill just above — no written-out "Light"/"Dark" label. */
.layout-pill,.theme-pill{
  display:flex;align-items:center;gap:2px;
  background:var(--ink-50);border:1px solid var(--ink-200);
  border-radius:999px;padding:3px;
}
.layout-btn,.theme-btn{
  display:flex;align-items:center;justify-content:center;
  width:28px;height:26px;border:none;border-radius:999px;
  background:transparent;color:var(--ink-500);cursor:pointer;
  transition:background var(--t-fast) var(--ease), color var(--t-fast) var(--ease);
}
.layout-btn svg,.theme-btn svg{width:15px;height:15px;}
.layout-btn:hover,.theme-btn:hover{color:var(--ink-800);}
.layout-btn.active,.theme-btn.active{background:var(--brand-700);color:#fff;}

/* Topbar notification bell — a real notification center (unread tickets +
   chat messages, merged server-side — see Backend/src/routes/
   notifications.js), not just a link. Same "small pill, muted until it
   has something to say" treatment as the pills beside it; the count badge
   borrows .badge-danger's red since unread activity is the same kind of
   "needs attention" signal. */
.notif-bell-wrap{position:relative;}
.support-bell-pill{
  position:relative;display:flex;align-items:center;justify-content:center;
  width:32px;height:32px;border-radius:999px;
  background:var(--ink-50);border:1px solid var(--ink-200);color:var(--ink-600);
  cursor:pointer;transition:color var(--t-fast) var(--ease), transform var(--t-fast) var(--ease);
}
.support-bell-pill:hover{color:var(--ink-800);transform:translateY(-1px);}
.support-bell-pill svg{width:16px;height:16px;}
.support-bell-count{
  position:absolute;top:-3px;right:-4px;min-width:16px;text-align:center;
  background:var(--danger-600);color:#fff;font-size:10px;font-weight:700;line-height:1;
  padding:2px 4px;border-radius:999px;box-shadow:0 0 0 2px var(--white);
}
.notif-panel{
  position:absolute;top:calc(100% + 8px);right:0;z-index:40;
  width:320px;max-height:420px;overflow-y:auto;
  background:var(--glass-bg);border:1px solid var(--glass-border);
  border-radius:var(--radius-md);box-shadow:var(--shadow-lg);
}
.notif-panel-head{padding:10px 14px;font-size:12.5px;font-weight:700;color:var(--ink-700);border-bottom:1px solid var(--ink-100);}
.notif-item{
  display:flex;align-items:flex-start;gap:10px;width:100%;
  padding:10px 14px;border:none;background:none;text-align:left;cursor:pointer;
  border-bottom:1px solid var(--ink-100);font:inherit;color:inherit;
}
.notif-item:last-child{border-bottom:none;}
.notif-item:hover{background:var(--ink-50);}
.notif-item-ico{
  flex-shrink:0;width:26px;height:26px;border-radius:50%;
  display:flex;align-items:center;justify-content:center;
  background:var(--brand-100);color:var(--brand-text);
}
.notif-item-ico svg{width:13px;height:13px;}
.notif-item-body{display:flex;flex-direction:column;gap:2px;min-width:0;}
.notif-item-body b{font-size:12.5px;font-weight:600;}
.notif-item-sub{font-size:11.5px;color:var(--ink-500);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.notif-empty{padding:24px 14px;text-align:center;font-size:12.5px;color:var(--ink-500);}

/* Sidebar nav item badge (Support) — same red, pushed to the row's far
   right by the nav-link's own flex layout. */
.nav-badge{
  margin-left:auto;background:var(--danger-600);color:#fff;
  font-size:10px;font-weight:700;line-height:1;
  padding:2px 6px;border-radius:999px;flex-shrink:0;
}
.nav-badge[hidden]{display:none;}

.login-theme-toggle{
  position:absolute;top:18px;right:18px;z-index:2;
}
.login-theme-toggle .theme-pill{
  background:rgba(255,255,255,.12);
  border:1px solid rgba(255,255,255,.25);
}
.login-theme-toggle .theme-btn{color:rgba(255,255,255,.7);}
.login-theme-toggle .theme-btn:hover{color:#fff;}
.login-theme-toggle .theme-btn.active{background:rgba(255,255,255,.25);color:#fff;}

.user-chip{display:flex;align-items:center;gap:10px;}
.user-avatar{
  width:34px;height:34px;border-radius:50%;
  background:var(--brand-700);color:#fff;
  display:flex;align-items:center;justify-content:center;
  font-weight:700;font-size:13px;
}
.user-meta{line-height:1.25;}
.user-meta b{font-size:13px;display:block;color:var(--ink-900);}
.user-meta span{font-size:11px;color:var(--ink-500);text-transform:capitalize;}
.btn-logout{
  border:1px solid var(--ink-200);background:var(--white);
  border-radius:var(--radius-sm);padding:7px 12px;font-size:12.5px;
  color:var(--ink-600);cursor:pointer;
}
.btn-logout:hover{background:var(--ink-100);}

.main-area{margin-left:var(--sidebar-w);flex:1;min-width:0;display:flex;flex-direction:column;}
/* Data-grid pages (many-column tables, wide filter bars) benefit from the
   full window — a fixed 1400px cap just left dead space on any normal
   desktop monitor. 2200px is a soft ceiling only an ultrawide would ever
   hit; every realistic screen now gets the whole main-area width. */
.page-content{padding:16px 26px 52px;max-width:2200px;width:100%;margin:0 auto;}

/* ---------- Generic layout bits ---------- */
/* The page name already shows in the topbar (App.setTopbar(), driven by
   js/router.js's ROUTES titles) — page-header no longer repeats it as its
   own heading. The description line carries the accent bar + a bit more
   weight instead, so it still reads as a proper header, not an afterthought. */
.page-header{display:flex;align-items:center;justify-content:space-between;margin-bottom:16px;gap:14px;flex-wrap:wrap;padding-bottom:14px;border-bottom:1px solid var(--ink-200);}
.page-header p{
  font-size:14px;font-weight:600;color:var(--ink-800);line-height:1.45;
  position:relative;padding-left:14px;margin:0;
}
.page-header p::before{
  content:"";position:absolute;left:0;top:1px;bottom:1px;width:4px;border-radius:99px;
  background:linear-gradient(180deg,var(--brand-500),var(--brand-800));
}
.header-actions{display:flex;gap:8px;flex-wrap:wrap;}

.card{background:var(--glass-bg);-webkit-backdrop-filter:var(--blur);backdrop-filter:var(--blur);border:1px solid var(--glass-border);border-radius:var(--radius-lg);box-shadow:var(--shadow-sm);transition:box-shadow var(--t-med) var(--ease), transform var(--t-med) var(--ease), border-color var(--t-med) var(--ease);}
.card-pad{padding:14px 16px;}
/* Only meant for cards stacked one after another in normal block flow
   (e.g. Masters pages) — a sibling selector can't tell that from cards laid
   out side by side in a .grid, where it was adding a stray 16px margin-top
   to every card but the first. .grid already spaces its items via gap, so
   cancel it there: without this, that margin ate into a grid row's
   stretched height, making every card but the first look visibly shorter. */
.card + .card{margin-top:16px;}
.grid > .card + .card{margin-top:0;}

/* ---------- Sales Hierarchy org-chart canvas ---------- */
.hier-canvas-wrap{overflow:auto;border:1px solid var(--ink-200);border-radius:var(--radius-lg);max-height:640px;background:var(--ink-50);}
.hier-canvas{position:relative;}
.hier-lines{position:absolute;top:0;left:0;pointer-events:none;}
.hier-node{
  position:absolute;width:152px;padding:9px 11px;border-radius:10px;
  background:var(--white);border:2px solid var(--ink-300);box-shadow:var(--shadow-sm);
  user-select:none;
}
.hier-node.context{opacity:.45;}
.hier-node .hn-name{font-weight:700;font-size:12.5px;color:var(--ink-900);line-height:1.3;}
.hier-node .hn-desig{font-size:10.5px;color:var(--ink-500);margin-top:1px;}
.hier-node .hn-tag{font-size:10px;color:var(--ink-600);margin-top:4px;}
.hier-connector{
  position:absolute;left:50%;bottom:-7px;transform:translateX(-50%);
  width:14px;height:14px;border-radius:50%;background:var(--brand-600);
  border:2px solid var(--white);cursor:crosshair;
}
.hier-connector:hover{background:var(--brand-700);}
.hier-legend{display:flex;gap:16px;flex-wrap:wrap;font-size:11.5px;color:var(--ink-600);margin-bottom:10px;}
.hier-legend .item{display:flex;align-items:center;gap:6px;}
.hier-legend .swatch{width:11px;height:11px;border-radius:3px;display:inline-block;}

.page-content{animation:none;}
.route-enter{animation:pageFadeIn .4s var(--ease);}
@keyframes pageFadeIn{
  from{opacity:0;transform:translateY(10px);}
  to{opacity:1;transform:none;}
}

.page-loading{display:flex;align-items:center;justify-content:center;gap:10px;padding:80px 0;}
.spinner{
  width:34px;height:34px;border-radius:50%;
  border:3px solid var(--ink-200);
  border-top-color:var(--brand-600);
  animation:spin .7s linear infinite;
}
@keyframes spin{to{transform:rotate(360deg);}}

.grid{display:grid;gap:16px;}
.grid > *{min-width:0;}
.grid-cols-2{grid-template-columns:repeat(2,1fr);}
.grid-cols-3{grid-template-columns:repeat(3,1fr);}
.grid-cols-4{grid-template-columns:repeat(4,1fr);}
.grid-cols-5{grid-template-columns:repeat(5,1fr);}
.grid-cols-6{grid-template-columns:repeat(6,1fr);}
@media (max-width:1300px){.grid-cols-6{grid-template-columns:repeat(3,1fr);}}
@media (max-width:1100px){.grid-cols-4{grid-template-columns:repeat(2,1fr);}.grid-cols-5{grid-template-columns:repeat(2,1fr);}.grid-cols-3{grid-template-columns:repeat(2,1fr);}.grid-cols-6{grid-template-columns:repeat(2,1fr);}}
@media (max-width:680px){.grid-cols-2,.grid-cols-3,.grid-cols-4,.grid-cols-5,.grid-cols-6{grid-template-columns:1fr;}}

/* KPI cards */
.kpi{padding:11px 14px;display:flex;flex-direction:column;gap:4px;}
.kpi .kpi-label{font-size:11px;color:var(--ink-500);font-weight:600;text-transform:uppercase;letter-spacing:.05em;}
.kpi .kpi-value{font-family:var(--font-mono);font-size:22px;font-weight:600;color:var(--ink-900);font-variant-numeric:tabular-nums;line-height:1.2;}
.kpi .kpi-sub{font-size:11.5px;color:var(--ink-500);line-height:1.4;}
.kpi.accent-brand{border-top:3px solid var(--brand-600);}
.kpi.accent-warn{border-top:3px solid var(--warn-600);}
.kpi.accent-success{border-top:3px solid var(--success-600);}
.kpi.accent-danger{border-top:3px solid var(--danger-600);}
.kpi.accent-info{border-top:3px solid var(--info-600);}
.kpi:hover{transform:translateY(-3px);box-shadow:var(--shadow-md);}
.route-enter .kpi{animation:kpiRise .5s var(--ease) backwards;}
@keyframes kpiRise{from{opacity:0;transform:translateY(12px);}to{opacity:1;transform:none;}}
.route-enter .kpi:nth-of-type(1){animation-delay:.02s;}
.route-enter .kpi:nth-of-type(2){animation-delay:.07s;}
.route-enter .kpi:nth-of-type(3){animation-delay:.12s;}
.route-enter .kpi:nth-of-type(4){animation-delay:.17s;}
.route-enter .kpi:nth-of-type(5){animation-delay:.22s;}
.route-enter .kpi:nth-of-type(6){animation-delay:.27s;}

/* ---------- Buttons ---------- */
.btn{
  display:inline-flex;align-items:center;justify-content:center;gap:6px;
  border-radius:var(--radius-sm);border:1px solid transparent;
  padding:8px 14px;font-size:13px;font-weight:600;cursor:pointer;
  white-space:nowrap;
  transition:background var(--t-fast) var(--ease), border-color var(--t-fast) var(--ease), opacity var(--t-fast) var(--ease), transform var(--t-fast) var(--ease), box-shadow var(--t-fast) var(--ease);
}
.btn:disabled{opacity:.5;cursor:not-allowed;}
.btn:not(:disabled):hover{transform:translateY(-1px);}
.btn:not(:disabled):active{transform:translateY(0) scale(.97);}
.btn-primary{background:var(--brand-700);color:#fff;}
.btn-primary:hover:not(:disabled){background:var(--brand-800);box-shadow:0 6px 16px rgba(18,58,102,.32);}
.btn-secondary{background:var(--glass-bg);color:var(--ink-700);border-color:var(--ink-300);}
.btn-secondary:hover:not(:disabled){background:var(--ink-100);}
.btn-success{background:var(--success-600);color:#fff;}
.btn-success:hover:not(:disabled){background:var(--success-700);box-shadow:0 6px 16px rgba(31,122,92,.3);}
.btn-danger{background:var(--danger-600);color:#fff;}
.btn-danger:hover:not(:disabled){background:var(--danger-700);box-shadow:0 6px 16px rgba(163,64,47,.3);}
.btn-ghost{background:transparent;color:var(--ink-600);}
.btn-ghost:hover:not(:disabled){background:var(--ink-100);}
.btn-sm{padding:5px 10px;font-size:12px;}
.btn-icon{width:30px;height:30px;padding:0;border-radius:8px;}

/* ---------- Forms ---------- */
.field{margin-bottom:12px;}
.field label{display:block;font-size:12.5px;font-weight:600;color:var(--ink-700);margin-bottom:5px;}
/* Bare (not just .field-scoped) so a standalone helper/status line outside
   a form field — e.g. a picker's "N shown" count, a template's in-use
   notice — gets the same small, muted treatment without needing a .field
   wrapper just to pick up styling. */
.hint{font-size:11px;color:var(--ink-500);margin-top:4px;}
.field input[type=text],
.field input[type=password],
.field input[type=number],
.field input[type=date],
.field input[type=email],
.field input[type=file],
.field input[type=search],
.field select,
.field textarea{
  width:100%;
  border:1px solid var(--ink-300);
  border-radius:var(--radius-sm);
  padding:8px 11px;
  font-size:13.5px;
  color:var(--ink-900);
  background:var(--white);
  transition:border-color var(--t-fast) var(--ease), box-shadow var(--t-fast) var(--ease);
}
.field input:focus,.field select:focus,.field textarea:focus{
  outline:none;border-color:var(--brand-600);box-shadow:0 0 0 3px var(--brand-100);
}
.field input:hover,.field select:hover{border-color:var(--ink-400);}
.field textarea{resize:vertical;min-height:70px;}
.checkbox-row{display:flex;align-items:center;gap:8px;font-size:13px;color:var(--ink-700);}
.checkbox-row input{width:15px;height:15px;}
.form-grid{display:grid;grid-template-columns:1fr 1fr;gap:0 16px;}
@media (max-width:640px){.form-grid{grid-template-columns:1fr;}}

.check-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:8px;max-height:260px;overflow-y:auto;padding:4px 2px;}
@media (max-width:800px){.check-grid{grid-template-columns:repeat(2,1fr);}}
.check-item{
  display:flex;align-items:center;gap:8px;
  border:1px solid var(--ink-200);border-radius:var(--radius-sm);
  padding:8px 10px;font-size:12.5px;color:var(--ink-700);
  transition:border-color var(--t-fast) var(--ease), background var(--t-fast) var(--ease);
}
.check-item:hover{border-color:var(--brand-500);background:var(--brand-50);}
.check-item input{width:14px;height:14px;flex-shrink:0;}
.check-item-disabled{opacity:.55;cursor:not-allowed;}
.check-item-disabled:hover{border-color:var(--ink-200);background:none;}

/* Single-column version of .check-grid — used where indentation (a
   manager's row sitting directly above their own reports) needs to read
   top-to-bottom, which a multi-column grid would break up. */
.hierarchy-check-list{display:flex;flex-direction:column;gap:4px;max-height:320px;overflow-y:auto;padding:4px 2px;}
.hierarchy-check-list .check-item{justify-content:flex-start;}

/* ---------- Tables ----------
   Banded like a spreadsheet on purpose — this app lives and dies on people
   scanning long rows of figures, and alternating bands are what makes that
   fast. (A sticky header was tried here too, but position:sticky on a <th>
   renders unreliably across the app's different scroll contexts — plain
   full-page tables, the fixed-height product picker on New Selection, etc.
   — and was overlapping rows instead of floating cleanly above them.
   Dropped rather than risk that again; the tinted header + banding do the
   actual readability work anyway.)

   border-collapse stays "collapse", not "separate" — separate treats every
   cell as its own independently-composited box, which is a real cost once
   a table gets into the hundreds of rows (Product Master: 406, all
   rendered at once, no pagination) and was the cause of the page
   momentarily freezing on the first scroll attempt after opening it. */
.table-wrap{overflow-x:auto;border-radius:var(--radius-md);}
table.data-table{width:100%;border-collapse:collapse;font-size:12.5px;line-height:1.3;}
.data-table thead th{
  text-align:left;font-size:10.5px;text-transform:uppercase;letter-spacing:.05em;
  color:var(--ink-600);font-weight:700;
  background:var(--ink-50);
  padding:7px 12px;border-bottom:1px solid var(--ink-200);
  white-space:nowrap;
}
.data-table tbody td{
  padding:4px 12px;border-bottom:1px solid var(--ink-100);
  color:var(--ink-800);vertical-align:middle;
}
/* The two-line "product name + brand" cell pattern (product name in <b>,
   brand in a muted sub-line below it) used across most list tables — kept
   tight so it doesn't blow the row back out to card height. */
.data-table tbody td > .muted.text-sm{line-height:1.2;margin-top:1px;}
.data-table tbody tr{background:var(--white);transition:background var(--t-fast) var(--ease);}
.data-table tbody tr:nth-child(even){background:var(--ink-50);}
.data-table tbody tr:hover{background:var(--ink-100);}
/* Split View's "selected row" marker — set directly on the row by the
   page's own JS (registrationSelect.js-style row click), not by Table.js,
   which stays unaware of selection so every other page keeps working
   unmodified. */
.data-table tbody tr.row-selected{background:var(--brand-50) !important;}
.data-table tbody tr.table-empty-row,
.data-table tbody tr.table-empty-row:hover{background:var(--white);}
.data-table tbody tr.table-empty-row td{padding:0;}
.data-table tbody tr:last-child td{border-bottom:none;}
.table-empty{padding:40px 10px;text-align:center;color:var(--ink-500);font-size:13.5px;}
.row-actions{display:flex;gap:6px;flex-wrap:wrap;}
.table-pager{display:flex;align-items:center;justify-content:flex-end;gap:12px;flex-wrap:wrap;margin:8px 0;}

/* Sales Incentive Matrix */
.text-xs{font-size:11px;}.text-success{color:var(--success-700);}.text-danger{color:var(--danger-700);}
.incentive-page-header h3{margin:0 0 5px;font-size:20px;color:var(--ink-900);}
.privacy-pill{display:inline-flex;align-items:center;padding:7px 11px;border:1px solid var(--warn-600);border-radius:999px;background:var(--warn-100);color:var(--warn-700);font-size:12px;font-weight:700;white-space:nowrap;}
.incentive-kpi-grid{display:grid;grid-template-columns:repeat(5,minmax(0,1fr));gap:12px;}
.incentive-dashboard-grid{display:grid;grid-template-columns:minmax(0,1.2fr) minmax(320px,.8fr);gap:16px;margin-top:16px;}
.incentive-progress-row{display:grid;gap:8px;margin:16px 0;}
.incentive-progress{height:9px;background:var(--ink-100);border-radius:999px;overflow:hidden;}
.incentive-progress span{display:block;height:100%;border-radius:inherit;}
.incentive-progress .tone-brand{background:var(--brand-600);}.incentive-progress .tone-success{background:var(--success-600);}.incentive-progress .tone-info{background:var(--info-600);}
.incentive-readiness{display:flex;align-items:center;gap:12px;padding:11px 0;border-bottom:1px solid var(--ink-100);}.incentive-readiness:last-child{border-bottom:none;}
.incentive-check{display:grid;place-items:center;width:28px;height:28px;border-radius:50%;background:var(--warn-100);color:var(--warn-700);font-weight:800;}.incentive-check.done{background:var(--success-100);color:var(--success-700);}
.salary-editor{display:flex;align-items:center;min-width:138px;border:1px solid var(--ink-200);border-radius:7px;background:var(--white);overflow:hidden;}.salary-editor span{padding-left:10px;color:var(--ink-500);}.salary-editor input{width:112px;border:0;background:transparent;padding:8px 8px 8px 4px;outline:none;color:var(--ink-900);}
.incentive-config-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:16px;}.incentive-config-grid h4{margin:0;}
.formula-callout{margin-top:14px;padding:12px;border:1px dashed var(--brand-500);border-radius:8px;background:var(--brand-50);color:var(--brand-text);font-size:13px;font-weight:650;}
.switch-line{display:flex;align-items:center;gap:8px;font-size:13px;font-weight:650;color:var(--ink-700);}.switch-line input{width:17px;height:17px;}
.template-tokens{margin-top:8px;padding:10px 12px;border-radius:7px;background:var(--ink-50);color:var(--ink-500);font-size:12px;line-height:1.6;}
.focus-product-grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:10px;}
.focus-product-card{display:flex;align-items:center;gap:11px;min-height:68px;padding:12px;border:1px solid var(--ink-200);border-radius:9px;background:var(--white);cursor:pointer;transition:.15s ease;}.focus-product-card:hover{border-color:var(--brand-500);}.focus-product-card.selected{border-color:var(--brand-500);background:var(--brand-50);box-shadow:0 0 0 1px var(--brand-500);}.focus-product-card input{display:none;}.focus-product-card span:nth-child(2){display:grid;gap:4px;flex:1;}.focus-product-card small{color:var(--ink-500);}.focus-mark{display:grid;place-items:center;width:23px;height:23px;border-radius:50%;background:var(--ink-100);color:transparent;font-weight:800;}.focus-product-card.selected .focus-mark{background:var(--brand-600);color:#fff;}
.focus-filter-bar{margin-bottom:8px;}.focus-filter-bar .field.grow{min-width:280px;}.focus-filter-bar .field:not(.grow){min-width:190px;}.focus-filter-bar>.btn{margin-bottom:0;}.focus-filter-summary{display:flex;justify-content:space-between;gap:16px;margin:0 0 12px;color:var(--ink-500);font-size:12px;font-weight:650;}.focus-empty{grid-column:1/-1;}
.calculation-hero{display:flex;justify-content:space-between;align-items:center;gap:24px;background:linear-gradient(135deg,var(--brand-50),var(--white));border-color:var(--brand-100);}.calculation-hero h3{font-size:30px;margin:4px 0;color:var(--brand-text);}.calculation-formula{display:flex;align-items:center;gap:10px;flex-wrap:wrap;padding:12px 15px;border-radius:9px;background:var(--white);border:1px solid var(--brand-100);}.calculation-formula b{font-size:17px;color:var(--brand-text);}
.calculation-kpi-grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:16px;}.calculation-kpi dl{display:grid;gap:0;margin:16px 0 0;}.calculation-kpi dl div{display:flex;justify-content:space-between;gap:12px;padding:9px 0;border-bottom:1px solid var(--ink-100);}.calculation-kpi dt{color:var(--ink-500);}.calculation-kpi dd{margin:0;font-weight:650;text-align:right;}.calculation-payout{display:flex;justify-content:space-between;align-items:end;margin:14px -16px -16px;padding:14px 16px;border-radius:0 0 9px 9px;background:var(--ink-50);}.calculation-payout b{font-size:19px;color:var(--success-700);}
.approval-steps{display:flex;align-items:center;gap:8px;padding:12px 15px;border:1px solid var(--ink-200);border-radius:9px;background:var(--white);overflow:auto;}.approval-steps span{white-space:nowrap;font-size:12px;font-weight:700;color:var(--ink-600);}.approval-steps i{width:26px;min-width:26px;height:1px;background:var(--ink-300);}.lock-indicator{font-size:12px;font-weight:700;color:var(--info-700);}
@media(max-width:1200px){.incentive-kpi-grid{grid-template-columns:repeat(3,minmax(0,1fr));}.focus-product-grid{grid-template-columns:repeat(2,minmax(0,1fr));}}
@media(max-width:800px){.incentive-dashboard-grid,.incentive-config-grid,.calculation-kpi-grid{grid-template-columns:1fr}.incentive-kpi-grid{grid-template-columns:repeat(2,minmax(0,1fr));}.focus-product-grid{grid-template-columns:1fr}.calculation-hero{align-items:flex-start;flex-direction:column;}.focus-filter-bar .field.grow,.focus-filter-bar .field:not(.grow){flex:1 1 100%;min-width:100%;}.focus-filter-bar>.btn{width:100%;}.focus-filter-summary{flex-wrap:wrap;}}

.badge{
  display:inline-flex;align-items:center;gap:4px;
  padding:3px 9px;border-radius:999px;font-size:11px;font-weight:700;
  text-transform:uppercase;letter-spacing:.05em;
}
.badge svg{width:11px;height:11px;flex-shrink:0;}
.badge-success{background:var(--success-100);color:var(--success-700);}
.badge-warn{background:var(--warn-100);color:var(--warn-700);}
.badge-danger{background:var(--danger-100);color:var(--danger-700);}
.badge-info{background:var(--info-100);color:var(--info-700);}
.badge-neutral{background:var(--ink-100);color:var(--ink-600);}
.dot{width:6px;height:6px;border-radius:50%;background:currentColor;display:inline-block;}
.dot-danger{color:var(--danger-600);}
.badge-warn{animation:badgePulse 2.4s ease-in-out infinite;}
@keyframes badgePulse{
  0%,100%{box-shadow:0 0 0 0 rgba(176,141,87,.35);}
  50%{box-shadow:0 0 0 4px rgba(176,141,87,0);}
}

/* Support ticket detail — a chronological message thread, not a table.
   ticket-comment-mine (the signed-in viewer's own messages) gets a faint
   brand tint so the back-and-forth is easy to scan at a glance, the same
   idea as a chat app right-aligning your own bubbles. */
.ticket-thread{display:flex;flex-direction:column;gap:14px;}
.ticket-comment{padding:12px 14px;border:1px solid var(--ink-200);border-radius:var(--radius-md);background:var(--ink-50);}
.ticket-comment-mine{background:var(--brand-50);border-color:var(--brand-100);}
.ticket-comment-head{display:flex;align-items:baseline;gap:8px;margin-bottom:6px;flex-wrap:wrap;}
.ticket-comment-head span{text-transform:capitalize;}
.ticket-comment-body{font-size:13.5px;line-height:1.5;white-space:pre-wrap;}
.ticket-comment-attachment{display:inline-flex;align-items:center;gap:5px;margin-top:8px;font-size:12.5px;color:var(--brand-text);text-decoration:none;}
.ticket-comment-attachment svg{width:13px;height:13px;}
.ticket-comment-attachment:hover{text-decoration:underline;}
.field-inline{padding:7px 10px;font-size:12.5px;border:1px solid var(--ink-200);border-radius:var(--radius-sm);background:var(--white);color:var(--ink-800);}

/* Chat — Support's lighter sibling, styled like a messaging app: a fixed-
   height two-pane shell (contact list + conversation) with each pane's
   own internal area scrolling, rather than two independently-sized cards
   that end up visibly mismatched in height. .select-layout (wide-content-
   first) doesn't fit this — a narrow list + wide conversation is the
   opposite ratio — so this is its own small grid. */
.chat-layout{display:grid;grid-template-columns:300px 1fr;gap:16px;height:min(640px, calc(100vh - 260px));min-height:420px;}
@media (max-width:900px){.chat-layout{grid-template-columns:1fr;height:auto;}}

.chat-contacts-panel,.chat-conversation-panel{
  display:flex;flex-direction:column;min-height:0;padding:0;overflow:hidden;
}
.chat-contacts-search{flex-shrink:0;padding:10px;border-bottom:1px solid var(--ink-100);}
.chat-contacts-search input{width:100%;}
.chat-thread-list{flex:1;min-height:0;overflow-y:auto;padding:4px;}
.chat-thread-item{
  position:relative;display:flex;align-items:center;gap:10px;width:100%;
  padding:9px 10px;border:none;background:none;text-align:left;cursor:pointer;
  border-radius:var(--radius-sm);font:inherit;color:inherit;
}
.chat-thread-item:hover{background:var(--ink-50);}
.chat-thread-item.active{background:var(--brand-50);}
.chat-thread-item-body{display:flex;flex-direction:column;gap:2px;min-width:0;flex:1;}
.chat-thread-item-top{display:flex;align-items:baseline;justify-content:space-between;gap:6px;}
.chat-thread-item-time{flex-shrink:0;font-size:10.5px;color:var(--ink-500);font-weight:400;}
.chat-thread-item-preview{font-size:11.5px;color:var(--ink-500);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.chat-thread-item-preview em{font-style:normal;color:var(--brand-text);}
.chat-thread-item .dot{position:absolute;top:10px;right:8px;}

.chat-avatar{
  flex-shrink:0;width:38px;height:38px;border-radius:50%;
  display:flex;align-items:center;justify-content:center;
  background:var(--brand-700);color:#fff;font-weight:700;font-size:13px;
}

.chat-conversation-panel .chat-empty-state{
  flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;
  gap:10px;color:var(--ink-500);font-size:13px;
}
.chat-conversation-panel .chat-empty-state .ico{width:40px;height:40px;border-radius:50%;background:var(--ink-100);display:flex;align-items:center;justify-content:center;color:var(--ink-500);}
.chat-conversation-panel .chat-empty-state .ico svg{width:18px;height:18px;}
.chat-conversation-head{
  flex-shrink:0;display:flex;align-items:center;gap:10px;
  padding:12px 16px;border-bottom:1px solid var(--ink-100);
}
.chat-conversation-panel-solo{height:min(640px, calc(100vh - 260px));min-height:420px;}

/* Chat bubbles — deliberately distinct from .ticket-comment's card style;
   a casual back-and-forth reads as a chat, not another record. Mine
   right-aligns and uses the brand color, same convention as every
   messaging app. */
.chat-messages{flex:1;min-height:0;display:flex;flex-direction:column;gap:10px;overflow-y:auto;padding:16px;}
.chat-bubble{
  max-width:70%;padding:9px 13px;border-radius:14px;
  background:var(--ink-100);color:var(--ink-900);
  font-size:13.5px;line-height:1.45;white-space:pre-wrap;align-self:flex-start;
  border-bottom-left-radius:4px;
}
.chat-bubble-mine{
  align-self:flex-end;background:var(--brand-700);color:#fff;
  border-bottom-left-radius:14px;border-bottom-right-radius:4px;
}
.chat-bubble-meta{display:block;margin-top:4px;font-size:10.5px;opacity:.7;}
.chat-input-row{
  flex-shrink:0;display:flex;align-items:flex-end;gap:10px;
  padding:12px 16px;border-top:1px solid var(--ink-100);
}
.chat-input-row textarea{flex:1;resize:none;}
.chat-input-row .btn{flex-shrink:0;}

.pill-select{border:none;background:transparent;font-weight:600;cursor:pointer;}

/* Filter bar — deliberately tighter than a form field: on a laptop-width
   screen, 6-7 of these plus a search box wrap across several full-height
   rows and eat half the visible page before you ever reach the table.
   Smaller label/control sizing and a lower min-width (more fields survive
   per row before wrapping) both attack that directly; scoped to
   .filter-bar only so modal/form fields elsewhere keep their normal size. */
.filter-bar{display:flex;flex-wrap:wrap;gap:8px 10px;align-items:flex-end;margin-bottom:14px;}
.filter-bar .field{margin-bottom:0;min-width:118px;}
.filter-bar .field.grow{flex:1;min-width:170px;}
.filter-bar .field label{font-size:11px;margin-bottom:3px;}
.filter-bar select,
.filter-bar input[type=text],
.filter-bar input[type=date],
.filter-bar input[type=search],
.filter-bar .ss-trigger{padding:6px 9px;font-size:12.5px;}
.filter-bar .search-box input{padding-left:28px !important;}
.filter-bar .btn-seg{padding:6px 11px;font-size:12px;}

/* Searchable select (js/components/searchableSelect.js) — every <select>
   in the app becomes a combobox: the real <select> (.ss-native-select)
   stays in the DOM as the source of truth but is visually hidden; a
   button (.ss-trigger) stands in its place, looking exactly like the
   original select, and opens a dropped-down panel (.ss-panel, positioned
   in the fixed/viewport layer so it's never clipped by a scrollable table
   or modal) with a search box pinned above the option list. */
.ss-wrap{position:relative;width:100%;}
.ss-native-select{position:absolute;width:1px;height:1px;opacity:0;pointer-events:none;}
.ss-trigger{
  width:100%;
  display:flex;align-items:center;justify-content:space-between;gap:8px;
  border:1px solid var(--ink-300);
  border-radius:var(--radius-sm);
  padding:8px 11px;
  font-size:13.5px;
  color:var(--ink-900);
  background:var(--white);
  text-align:left;
  cursor:pointer;
  transition:border-color var(--t-fast) var(--ease), box-shadow var(--t-fast) var(--ease);
}
.ss-trigger:hover{border-color:var(--ink-400);}
.ss-trigger:focus,.ss-trigger.ss-open{
  outline:none;border-color:var(--brand-600);box-shadow:0 0 0 3px var(--brand-100);
}
.ss-trigger.ss-disabled{background:var(--ink-100);color:var(--ink-500);cursor:not-allowed;}
.ss-trigger-label{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.ss-chevron{
  flex:none;width:8px;height:8px;
  border-right:1.5px solid var(--ink-500);border-bottom:1.5px solid var(--ink-500);
  transform:rotate(45deg);margin-top:-4px;transition:transform var(--t-fast) var(--ease);
}
.ss-trigger.ss-open .ss-chevron{transform:rotate(-135deg);margin-top:2px;}
.ss-panel{
  position:fixed;
  background:var(--white);
  border:1px solid var(--ink-300);
  border-radius:var(--radius-sm);
  box-shadow:0 8px 24px rgba(0,0,0,.14);
  z-index:1000;
  padding:6px;
  display:flex;flex-direction:column;gap:6px;
}
.ss-search{
  width:100%;
  border:1px solid var(--ink-300);
  border-radius:var(--radius-sm);
  padding:6px 10px;
  font-size:12.5px;
  color:var(--ink-900);
  background:var(--white);
}
.ss-search:focus{outline:none;border-color:var(--brand-600);box-shadow:0 0 0 3px var(--brand-100);}
.ss-list{max-height:280px;overflow-y:auto;}
.ss-option{
  padding:7px 10px;font-size:13px;color:var(--ink-800);border-radius:var(--radius-sm);cursor:pointer;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
}
.ss-option:hover,.ss-option-highlighted{background:var(--brand-50,var(--ink-100));}
.ss-option-filtered{display:none;}
.ss-option-disabled{color:var(--ink-400);cursor:not-allowed;}
.ss-empty{padding:8px 10px;font-size:12.5px;color:var(--ink-500);}

/* Search box */
.search-box{position:relative;min-width:0;}
.search-box input{padding-left:30px !important;}
.search-box::before{
  content:"";position:absolute;left:11px;bottom:12px;width:8px;height:8px;
  border:1.5px solid var(--ink-400);border-radius:50%;pointer-events:none;
}
.search-box::after{
  content:"";position:absolute;left:19px;bottom:10px;width:5px;height:1.5px;
  border-radius:999px;background:var(--ink-400);transform:rotate(45deg);pointer-events:none;
}

/* Steps */
.steps{display:flex;align-items:center;gap:0;margin-bottom:14px;}
.step{display:flex;align-items:center;gap:8px;}
.step-num{
  width:26px;height:26px;border-radius:50%;
  display:flex;align-items:center;justify-content:center;
  font-size:12px;font-weight:700;
  background:var(--ink-200);color:var(--ink-600);
}
.step.active .step-num{background:var(--brand-700);color:#fff;}
.step.done .step-num{background:var(--success-600);color:#fff;}
.step.rejected .step-num{background:var(--danger-600);color:#fff;}
.step-label{font-size:12.5px;font-weight:600;color:var(--ink-500);}
.step.active .step-label,.step.done .step-label,.step.rejected .step-label{color:var(--ink-800);}
.step-sep{width:34px;height:2px;background:var(--ink-200);margin:0 8px;}

/* ---------- Modal ---------- */
.modal-overlay{
  position:fixed;inset:0;background:rgba(15,18,26,.55);
  backdrop-filter:blur(3px);
  -webkit-backdrop-filter:blur(3px);
  display:flex;align-items:center;justify-content:center;
  z-index:100;padding:20px;
  animation:overlayIn .18s ease-out;
}
@keyframes overlayIn{from{opacity:0;}to{opacity:1;}}
.modal{
  background:var(--glass-bg);
  -webkit-backdrop-filter:var(--blur);
  backdrop-filter:var(--blur);
  border:1px solid var(--glass-border);
  border-top:3px solid var(--brand-700);
  border-radius:var(--radius-lg);
  box-shadow:var(--shadow-lg);
  width:100%;max-width:560px;max-height:90vh;
  display:flex;flex-direction:column;
  animation:modalIn .22s var(--ease);
}
.modal.modal-lg{max-width:820px;}
.modal.modal-xl{max-width:1240px;}
@keyframes modalIn{from{opacity:0;transform:translateY(8px) scale(.98);}to{opacity:1;transform:none;}}
.modal-head{display:flex;align-items:center;justify-content:space-between;padding:16px 20px;border-bottom:1px solid var(--ink-200);}
.modal-head h3{font-size:15.5px;font-weight:700;color:var(--ink-900);}
.modal-close{cursor:pointer;color:var(--ink-400);font-size:18px;border:none;background:none;line-height:1;}
.modal-close:hover{color:var(--ink-700);}
.modal-body{padding:18px 20px;overflow-y:auto;}
.modal-foot{display:flex;justify-content:flex-end;gap:8px;padding:14px 20px;border-top:1px solid var(--ink-200);}

/* ---------- Busy overlay ---------- */
.busy-overlay{
  position:fixed;inset:0;background:rgba(15,18,26,.55);
  backdrop-filter:blur(3px);
  -webkit-backdrop-filter:blur(3px);
  display:flex;align-items:center;justify-content:center;
  z-index:300;
  animation:overlayIn .18s ease-out;
}
.busy-box{
  background:var(--white);border-radius:var(--radius-lg);
  box-shadow:var(--shadow-lg);
  padding:28px 34px;
  min-width:260px;
  display:flex;flex-direction:column;align-items:center;gap:14px;
}
.busy-message{font-size:13.5px;font-weight:600;color:var(--ink-700);}
.busy-progress-track{
  width:100%;height:8px;border-radius:99px;
  background:var(--ink-200);overflow:hidden;
}
.busy-progress-fill{
  height:100%;border-radius:99px;
  background:var(--brand-600);
  transition:width .15s ease-out;
}
.busy-percent{font-family:var(--font-mono);font-size:12px;font-weight:700;color:var(--brand-700);font-variant-numeric:tabular-nums;}

/* ---------- Toast ---------- */
#toast-root{position:fixed;top:18px;right:18px;z-index:200;display:flex;flex-direction:column;gap:8px;}
.toast{
  min-width:240px;max-width:340px;
  background:var(--fixed-dark-900);color:#fff;
  border-radius:var(--radius-sm);padding:11px 14px;
  font-size:13px;box-shadow:var(--shadow-lg);
  animation:toastIn .16s ease-out;
  border-left:4px solid var(--brand-600);
}
.toast.success{border-left-color:var(--success-600);}
.toast.error{border-left-color:var(--danger-600);}
.toast.info{border-left-color:var(--info-600);}
@keyframes toastIn{from{opacity:0;transform:translateX(20px);}to{opacity:1;transform:none;}}

/* ---------- Misc ---------- */
.muted{color:var(--ink-500);}
.text-sm{font-size:12.5px;}
.flex{display:flex;}
.flex-between{display:flex;align-items:center;justify-content:space-between;}
.gap-8{gap:8px;}
.gap-12{gap:12px;}
.mt-8{margin-top:8px;}
.mt-16{margin-top:16px;}
.mb-8{margin-bottom:8px;}
.divider{height:1px;background:var(--ink-200);margin:16px 0;}

.tabs{display:flex;gap:4px;border-bottom:1px solid var(--ink-200);margin-bottom:18px;}
.tab{padding:9px 14px;font-size:13px;font-weight:600;color:var(--ink-500);cursor:pointer;border-bottom:2px solid transparent;margin-bottom:-1px;transition:color var(--t-fast) var(--ease), border-color var(--t-fast) var(--ease);}
.tab:hover{color:var(--ink-800);}
.tab.active{color:var(--brand-text);border-bottom-color:var(--brand-700);}

.activity-row{display:flex;align-items:flex-start;justify-content:space-between;gap:10px;}
.activity-main{min-width:0;flex:1;}
.activity-title{display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.activity-badge{flex-shrink:0;}

.empty-state{
  text-align:center;padding:50px 20px;color:var(--ink-500);
}
.empty-state .ico{display:flex;justify-content:center;margin-bottom:10px;color:var(--ink-400);}
.empty-state .ico svg{width:34px;height:34px;stroke-width:1.4;}
.empty-state h4{font-size:14.5px;color:var(--ink-700);margin-bottom:6px;}

.progress-bar{height:7px;background:var(--ink-100);border-radius:999px;overflow:hidden;}
.progress-bar > div{height:100%;background:var(--brand-600);}

.file-chip{
  display:inline-flex;align-items:center;gap:8px;
  background:var(--ink-50);border:1px solid var(--ink-200);
  border-radius:var(--radius-sm);padding:7px 11px;font-size:12.5px;color:var(--ink-700);
}
.file-chip svg{width:14px;height:14px;flex-shrink:0;color:var(--ink-500);}

/* Local (not-yet-uploaded) preview of a picked attachment — Registration
   List's Attach/Approve/Expense modals — see js/pages/registrationList.js's
   wireFilePreview(). */
.attachment-preview{
  display:block;width:100%;max-height:280px;margin-top:8px;
  border:1px solid var(--ink-200);border-radius:var(--radius-sm);background:var(--ink-50);
}
img.attachment-preview{object-fit:contain;}

.value-chain-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:0 16px;}
@media (max-width:900px){.value-chain-grid{grid-template-columns:repeat(2,1fr);}}
@media (max-width:600px){.value-chain-grid{grid-template-columns:1fr;}}

/* Value Chain v2 — the margin-gate banner on a product's Run view
   (js/pages/registrationValueChain.js), and its audit-trace panel. */
.gate-banner{display:flex;align-items:center;justify-content:space-between;gap:16px;padding:14px 16px;border-radius:var(--radius-lg);border:1px solid var(--glass-border);flex-wrap:wrap;}
.gate-banner.ok{background:var(--success-100);border-color:var(--success-600);}
.gate-banner.short{background:var(--danger-100);border-color:var(--danger-600);}
.gate-banner .gt{font-size:14.5px;font-weight:700;}
.gate-banner.ok .gt{color:var(--success-700);}
.gate-banner.short .gt{color:var(--danger-700);}
.trace-box{margin-top:12px;padding:12px 14px;border-radius:var(--radius-md);background:var(--ink-50);border:1px solid var(--ink-200);font-size:12.5px;line-height:1.7;}
.trace-box b{font-family:var(--font-mono);}

/* Template Builder (registrationValueChain.js) — compact one-row-per-
   component table, replacing the old always-expanded-card layout. */
.vc-def{display:flex;align-items:center;gap:6px;flex-wrap:wrap;}
.vc-def select,.vc-def input[type=number]{min-width:0;}
.vc-num-sm{width:64px;flex-shrink:0;}
.vc-chips{display:flex;align-items:center;gap:5px;flex-wrap:wrap;}
.vc-chip{display:inline-flex;align-items:center;gap:5px;background:var(--ink-100);color:var(--ink-800);border-radius:99px;padding:3px 6px 3px 10px;font-size:12px;white-space:nowrap;}
.vc-chip button{border:none;background:none;color:var(--ink-500);cursor:pointer;font-size:13px;line-height:1;padding:2px;border-radius:50%;}
.vc-chip button:hover{background:var(--danger-100);color:var(--danger-700);}
.vc-chip-add{border:1px dashed var(--ink-300);background:none;color:var(--ink-600);border-radius:99px;padding:3px 10px;font-size:12px;cursor:pointer;}
.vc-chip-add:hover{border-color:var(--brand-500);color:var(--brand-700);}
.vc-row-adv{background:var(--ink-50);}
.vc-row-adv td{padding:10px 12px !important;}
.vc-adv-toggle{border:none;background:none;color:var(--ink-500);cursor:pointer;padding:3px 5px;border-radius:var(--radius-sm);font-size:13px;line-height:1;}
.vc-adv-toggle:hover{background:var(--ink-100);color:var(--ink-800);}
.vc-adv-toggle[aria-expanded="true"]{background:var(--brand-100);color:var(--brand-700);}

/* Solve-direction toggle (Run view) — a two-way segmented button, same
   visual language as .btn but grouped into one bordered pill. */
.btn-group{display:inline-flex;border:1px solid var(--ink-300);border-radius:var(--radius-sm);overflow:hidden;}
.btn-seg{background:var(--white);color:var(--ink-700);border:none;padding:8px 14px;font-size:12.5px;font-weight:600;cursor:pointer;}
.btn-seg+.btn-seg{border-left:1px solid var(--ink-300);}
.btn-seg[aria-pressed="true"]{background:var(--brand-700);color:#fff;}

/* Kanban board (Supplier Orders — Reorder Recommendations page). Reuses
   the same card/badge/ink tokens as everything else; only the column and
   drag-target layout are new. */
.kanban-board{display:grid;grid-template-columns:repeat(3,1fr);gap:14px;align-items:start;}
@media (max-width:900px){.kanban-board{grid-template-columns:1fr;}}
.kanban-col{background:var(--ink-50);border:1px solid var(--ink-200);border-radius:var(--radius-md);padding:10px;}
.kanban-col-head{display:flex;align-items:center;justify-content:space-between;padding:2px 4px 10px;}
.kanban-count{font-size:11.5px;color:var(--ink-500);font-family:var(--font-mono);}
.kanban-col-body{min-height:64px;display:flex;flex-direction:column;gap:8px;border-radius:var(--radius-sm);transition:background var(--t-fast) var(--ease);}
.kanban-col-body.drag-over{background:var(--brand-50);outline:2px dashed var(--brand-500);outline-offset:-2px;}
.kanban-card{background:var(--white);border:1px solid var(--ink-200);border-radius:var(--radius-sm);padding:9px 11px;box-shadow:var(--shadow-sm);}
.kanban-card[draggable="true"]{cursor:grab;}
.kanban-card[draggable="true"]:active{cursor:grabbing;}
.kanban-card b{display:block;font-size:12.8px;color:var(--ink-900);}
.kanban-card-meta{display:flex;justify-content:space-between;margin-top:6px;font-size:11px;color:var(--ink-500);}
.kanban-empty{padding:14px 6px;text-align:center;font-size:12px;color:var(--ink-400);}

/* Component breakdown table (Run view) — section-header rows and a
   right-aligned, tabular-figure numeric column. */
.data-table tr.sec-row{background:var(--ink-100);}
.data-table tr.sec-row:hover{background:var(--ink-100);}
.data-table tr.active-row{background:var(--brand-100) !important;}
.data-table td.num{text-align:right;font-family:var(--font-mono);font-variant-numeric:tabular-nums;}

/* Dashboard Drill Down — per-group collapse/expand arrow on a subtotal row. */
.drilldown-toggle{background:none;border:none;cursor:pointer;padding:0 4px 0 0;font-size:10px;color:var(--ink-500);line-height:1;vertical-align:middle;}
.drilldown-toggle:hover{color:var(--ink-900);}

/* One color per hierarchy level (Region/State/Manager/Employee — see
   LEVEL_COLOR_CLASS in js/pages/targets.js) so a Drill Down table reads
   which level a row belongs to at a glance. A subtotal row (.sec-row) gets
   the level's pale tint as its background — the extra .data-table tr
   prefix outranks the plain grey .sec-row default above; a leaf row (an
   individual Region/State/Manager/Employee) only gets the left-edge accent,
   not a full tint, so a long list of leaf rows doesn't turn into a wall of
   color. */
.data-table tr.drilldown-level-region{border-left:3px solid var(--level-region-600);}
.data-table tr.sec-row.drilldown-level-region{background:var(--level-region-100);}
.data-table tr.drilldown-level-state{border-left:3px solid var(--level-state-600);}
.data-table tr.sec-row.drilldown-level-state{background:var(--level-state-100);}
.data-table tr.drilldown-level-manager{border-left:3px solid var(--level-manager-600);}
.data-table tr.sec-row.drilldown-level-manager{background:var(--level-manager-100);}
.data-table tr.drilldown-level-employee{border-left:3px solid var(--level-employee-600);}

/* Pivot Table Creator (js/pages/pivotReportBuilder.js) — a fixed-width
   Fields column on the left (per explicit request — this page departs from
   the app's usual wide-left-content/sticky-right-controls split-view
   convention on purpose) plus a flexible main column (drop zones above the
   result table). Wraps to a stacked single column on narrow viewports via
   plain flex-wrap, no separate breakpoint rule needed. */
.pivot-builder-layout{display:flex;flex-wrap:wrap;gap:16px;align-items:flex-start;}
/* Sticky + independently-scrolling, same technique as .select-panel-sticky/
   .select-scroll elsewhere in the app — pinned to the left column here
   instead of the right. Without this, scrolling down to reach a field near
   the bottom of a long list also scrolls the Rows/Filters/Columns/Values
   drop zones out of view, making them impossible to drag onto. Only active
   once the columns sit side by side (matches the width flex-wrap needs to
   keep both columns' min-widths, 220+320+16 gap, on one line) — while
   stacked on a narrow viewport, a sticky/scrolling fields panel above the
   rest of the page would trap the scroll instead of helping it. */
.pivot-fields-col{flex:0 0 260px;min-width:220px;position:sticky;top:16px;max-height:calc(100vh - 32px);overflow-y:auto;}
@media (max-width:640px){.pivot-fields-col{position:static;max-height:none;overflow-y:visible;}}
.pivot-main-col{flex:1 1 320px;min-width:320px;display:flex;flex-direction:column;}
.pivot-zones-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:12px;}

/* Field chips — draggable via Pointer Events (see pivotReportBuilder.js's
   wireChipDrag; NOT the native HTML5 draggable attribute, which never
   fires from a touch screen). touch-action:none stops the browser's own
   touch-scroll from fighting the pointer-drag on a phone/tablet. Chips
   also carry click-to-add buttons for every action (+Row/+Filter/+Column/
   +Value) as an always-available alternative to dragging. */
.pivot-field-list{display:flex;flex-direction:column;gap:6px;}
.pivot-chip{display:flex;align-items:center;gap:6px;padding:6px 8px;border:1px solid var(--ink-200);border-radius:var(--radius-sm);background:var(--white);font-size:12.5px;cursor:grab;touch-action:none;user-select:none;}
.pivot-chip:active{cursor:grabbing;}
.pivot-chip-grip{color:var(--ink-400);font-size:14px;line-height:1;}
.pivot-chip-label{font-weight:600;color:var(--ink-800);flex:1;}
.pivot-chip-actions{display:flex;flex-wrap:wrap;gap:4px;}
/* The floating clone that follows the pointer while dragging — fixed
   positioning, tracks cursor/finger coordinates set directly in JS. */
.pivot-chip-ghost{position:fixed;z-index:2000;pointer-events:none;opacity:.9;box-shadow:var(--shadow-md);}
/* Set on <body> for the duration of a drag so nothing else on the page
   (text, other controls) is accidentally selected/highlighted while
   dragging across it. */
body.pivot-dragging{cursor:grabbing;}
body.pivot-dragging *{user-select:none;}

.pivot-dropzone{border:1px dashed var(--ink-300);border-radius:var(--radius-md);padding:12px;background:var(--white);transition:background .12s,border-color .12s;}
.pivot-dropzone-over{background:var(--brand-50);border-color:var(--brand-400);}
.pivot-zone-items{display:flex;flex-direction:column;gap:6px;}
/* Also draggable (moved between Rows/Filters/Columns without removing and
   re-adding) — same Pointer Events mechanism and cursor/touch-action as the
   Fields panel's own chips above; the grip icon signals it's grabbable. */
.pivot-zone-item{display:flex;align-items:center;gap:8px;padding:6px 8px;border-radius:var(--radius-sm);background:var(--ink-50);font-size:12.5px;cursor:grab;touch-action:none;}
.pivot-zone-item:active{cursor:grabbing;}
.pivot-zone-item .pivot-chip-grip{color:var(--ink-400);font-size:14px;line-height:1;}
.pivot-zone-item span{flex:1;font-weight:600;color:var(--ink-800);}
.pivot-zone-item select,.pivot-zone-item input{font-size:12px;padding:2px 6px;}

/* Fields panel search box — filters the chip list below it by label text. */
.pivot-field-search{width:100%;padding:6px 8px;font-size:12.5px;border:1px solid var(--ink-200);border-radius:var(--radius-sm);margin-bottom:8px;}

/* Sort-order control, sits with the Values zone. */
.pivot-sort-row{display:flex;align-items:center;gap:8px;margin-top:8px;}
.pivot-sort-row select{font-size:12.5px;padding:4px 6px;}

/* Grand Total footer row — bold + a stronger top border to read as a
   summary line, distinct from an ordinary subtotal row. */
.pivot-report-table tr.pivot-grand-total-row{background:var(--ink-100);border-top:2px solid var(--ink-300);}
.pivot-report-table tr.pivot-grand-total-row td{font-weight:700;}

/* Custom Group builder modal — one row per distinct raw value, a text
   input for the bucket name it should fold into (same bucket name typed
   for several values merges them, e.g. "Q1" next to April/May/June). */
.pivot-group-value-list{max-height:320px;overflow-y:auto;border:1px solid var(--ink-100);border-radius:var(--radius-sm);}
.pivot-group-value-row{display:flex;align-items:center;gap:10px;padding:6px 10px;border-bottom:1px solid var(--ink-100);}
.pivot-group-value-row:last-child{border-bottom:none;}
.pivot-group-value-row span{flex:0 0 45%;font-size:12.5px;color:var(--ink-800);}
.pivot-group-value-row input{flex:1;font-size:12.5px;padding:4px 6px;}

/* Publish modal's "Specific People" list — a Personnel row with no portal
   login can't actually be granted access (there's no account to check
   against when the report is opened), so it's shown for context, not left
   out silently, but greyed and unselectable rather than a plain checkbox. */
.check-item.pivot-person-no-login{opacity:.55;}
.check-item.pivot-person-no-login input{cursor:not-allowed;}

/* Distributor Coverage Report — a states × distributors grid replacing a
   bipartite line diagram (two alphabetically-sorted, uncorrelated lists
   connected by lines are mostly crossings once there's more than a
   handful of either side). Sticky first column/row so a wide/tall grid
   still reads while scrolled; row hover picks out one state at a glance
   in place of the old per-node line-tracing interaction. */
.cov-matrix-wrap{max-height:560px;overflow:auto;border:1px solid var(--ink-100);border-radius:var(--radius-md);}
.cov-matrix{border-collapse:separate;border-spacing:0;width:auto;}
.cov-matrix th,.cov-matrix td{border-right:1px solid var(--ink-100);border-bottom:1px solid var(--ink-100);padding:0;}
.cov-matrix-corner{position:sticky;left:0;top:0;z-index:3;background:var(--white);min-width:150px;text-align:left;padding:8px 12px !important;font-size:11px;color:var(--ink-600);text-transform:uppercase;letter-spacing:.02em;}
.cov-matrix-col-head{position:sticky;top:0;z-index:2;background:var(--white);min-width:34px;max-width:34px;height:150px;vertical-align:bottom;padding:6px 2px !important;}
.cov-matrix-col-head span{writing-mode:vertical-rl;transform:rotate(180deg);white-space:nowrap;font-size:11px;font-weight:600;color:var(--ink-700);display:inline-block;max-width:140px;overflow:hidden;text-overflow:ellipsis;}
.cov-matrix-row-head{position:sticky;left:0;z-index:1;background:var(--white);text-align:left;white-space:nowrap;padding:6px 12px !important;font-weight:600;font-size:12.5px;color:var(--ink-800);}
.cov-matrix-cell{min-width:34px;max-width:34px;height:32px;text-align:center;font-size:13px;color:var(--brand-600);}
.cov-matrix-cell.mapped{background:var(--brand-50);font-weight:700;}
.cov-matrix tbody tr:hover .cov-matrix-row-head,
.cov-matrix tbody tr:hover td{background:var(--ink-50);}
.cov-matrix tbody tr:hover td.mapped{background:var(--brand-100);}

/* New Selection — wide two-pane layout: product picker gets the lion's
   share of the width, the "selected" cart stays a manageable, sticky rail. */
.select-layout{display:grid;grid-template-columns:1.7fr 1fr;gap:16px;align-items:start;}
/* Registration selection: one scrolling page, a bounded catalogue and batch review. */
.rs-heading{display:flex;align-items:center;justify-content:space-between;gap:20px;margin-bottom:20px;}
.rs-heading h2{font-size:26px;margin:4px 0 6px;letter-spacing:-.5px;}
.rs-heading p,.rs-section-heading p{margin:0;color:var(--ink-500);font-size:13px;line-height:1.5;}
.rs-eyebrow{font-size:10px;font-weight:600;letter-spacing:1.5px;color:var(--brand-text);}
.rs-section-heading{display:flex;align-items:flex-start;gap:10px;margin-bottom:18px;}
.rs-section-heading h3,.rs-review h3{font-size:15px;margin:0 0 4px;}
.rs-step{display:grid;place-items:center;flex:0 0 28px;width:28px;height:28px;border-radius:9px;background:var(--brand-50);color:var(--brand-text);font-size:13px;font-weight:600;}
.rs-market{display:grid;grid-template-columns:minmax(190px,.8fr) minmax(300px,1.7fr);gap:16px 24px;align-items:start;}
.rs-market .rs-section-heading{margin:0;}
.rs-mapped{grid-column:1/-1;border-top:1px solid var(--ink-200);padding-top:10px;font-size:12px;color:var(--ink-500);}
.rs-mapped summary,.rs-more-selected summary{cursor:pointer;padding:8px 0;}
.rs-workspace{grid-template-columns:minmax(0,2.2fr) minmax(260px,1fr);gap:20px;}
.rs-catalogue .search-box{margin-bottom:0;}
.rs-results-heading{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-top:12px;font-size:12px;color:var(--ink-500);}
.rs-catalogue .table-wrap{border-radius:10px;}
.rs-catalogue tbody tr{cursor:pointer;}
.rs-catalogue tbody tr:has(.prod-check:checked){background:var(--brand-50);}
.rs-catalogue .prod-check{width:18px;height:18px;accent-color:var(--brand-700);}
.rs-pager{display:flex;justify-content:space-between;align-items:center;gap:8px;padding-top:16px;font-size:12px;color:var(--ink-500);}
.rs-catalogue-note,.rs-submit-note{font-size:12px;line-height:1.6;color:var(--ink-500);margin:16px 0 0;}
.rs-review{display:flex;flex-direction:column;gap:14px;}
.rs-review .sel-row{gap:12px;padding:11px 0;border-bottom:1px solid var(--ink-200);align-items:flex-start;}
.rs-review .sel-row span{overflow-wrap:anywhere;line-height:1.5;white-space:normal;overflow:visible;text-overflow:clip;}
.rs-review .sel-row button{flex-shrink:0;}
.rs-selection-empty{padding:20px 12px;background:var(--ink-50);border-radius:10px;text-align:center;color:var(--ink-500);font-size:13px;}
.rs-selection-empty strong{color:var(--ink-700);}
.rs-selection-empty p{margin:6px 0 0;line-height:1.5;}
.rs-more-selected{font-size:12px;color:var(--ink-600);}
.rs-submit-note{margin:0;text-align:center;}
@media(min-width:761px) and (max-width:1100px){.rs-workspace{grid-template-columns:minmax(0,1fr);}.rs-review{position:static;}.rs-market{grid-template-columns:1fr;}}
#page-content .rs-catalogue .table-wrap{max-height:none;overflow:visible;}
@media(min-width:761px){#page-content .rs-catalogue table{table-layout:fixed;width:100%;}#page-content .rs-catalogue :is(th,td){overflow-wrap:anywhere;white-space:normal;}#page-content .rs-catalogue th:nth-child(2){width:33%;}#page-content .rs-catalogue th:nth-child(3){width:20%;}#page-content .rs-catalogue th:nth-child(4){width:17%;}}
@media (max-width:1000px){.select-layout{grid-template-columns:1fr;}}
/* Grid items default to min-width:auto, so a wide child (a many-column
   table, say) forces its own track past the 1.7fr/1fr split and overflows
   the whole grid horizontally — .table-wrap's own overflow-x:auto can't
   help until the track itself is allowed to shrink. This lets it. */
.select-layout > *{min-width:0;}
.select-scroll{max-height:560px;overflow-y:auto;}
.select-panel-sticky{position:sticky;top:16px;}
@media (max-width:1000px){.select-panel-sticky{position:static;}}
#product-list.select-scroll tbody tr{cursor:pointer;}

/* Selected Products list — one compact row per product, not a full padded
   card, now that distributor scope moved out to its own batch-level panel
   (step 3) instead of living inside each row. */
.sel-row{display:flex;align-items:center;justify-content:space-between;gap:8px;padding:7px 4px;border-bottom:1px solid var(--ink-100);}
.sel-row:last-child{border-bottom:none;}
.sel-row:hover{background:var(--ink-50);}
.sel-row span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}

.chart-legend{display:flex;flex-wrap:wrap;gap:10px 16px;margin-top:12px;}
.chart-legend .item{display:flex;align-items:center;gap:6px;font-size:12px;color:var(--ink-600);}
.chart-legend .swatch{width:10px;height:10px;border-radius:3px;}

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

/* Slim, modern scrollbars */
*{scrollbar-width:thin;scrollbar-color:var(--ink-300) transparent;}
::-webkit-scrollbar{width:8px;height:8px;}
::-webkit-scrollbar-track{background:transparent;}
::-webkit-scrollbar-thumb{background:var(--ink-300);border-radius:99px;}
::-webkit-scrollbar-thumb:hover{background:var(--ink-400);}
#sidebar-nav{scrollbar-color:var(--sidebar-scrollbar-thumb) transparent;}
#sidebar-nav::-webkit-scrollbar-thumb{background:var(--sidebar-scrollbar-thumb);}

/* Topbar + user chip micro-interactions */
.topbar{transition:box-shadow var(--t-med) var(--ease);}
.fy-pill select{transition:transform var(--t-fast) var(--ease);}
.fy-pill select:hover{transform:translateY(-1px);}
.user-chip{transition:transform var(--t-fast) var(--ease);}
.btn-logout:hover{transform:translateY(-1px);}

/* Sidebar workflow drill-down group (Label Registration + future modules) */
.nav-group-toggle{cursor:pointer;}
.nav-chevron{width:14px;flex-shrink:0;display:inline-flex;align-items:center;justify-content:center;opacity:.6;transition:transform var(--t-fast) var(--ease);}
.nav-chevron svg{width:13px;height:13px;}
/* Direct-child combinators (>) throughout this block are deliberate, not
   stylistic — Product Master nests one group (Product Attributes/Product
   List) inside Masters' own group now. Without >, an expanded OUTER group
   (Masters) would satisfy the descendant selector for an INNER group's own
   chevron/children too, showing/rotating the nested one regardless of
   whether IT has been toggled open — collapsing just the inner "Product
   Master" row would then do nothing visible as long as Masters stayed open. */
.nav-group.expanded > .nav-group-toggle .nav-chevron{transform:rotate(180deg);}
/* A fixed max-height (used to be a literal 420px) is the classic way to
   animate an accordion open/closed in CSS, but it's a ceiling on the actual
   content — Masters silently clipped its own list once enough items
   (Sales Types, Trade Types, ...) pushed it past that number. grid-
   template-rows: 0fr -> 1fr animates to whatever the real content height
   is instead, so this can't silently clip again no matter how many items a
   group ends up with, at any nesting depth. .nav-group-children-inner (see
   app.js's group()) is the single grid item whose min-height:0 lets it
   actually shrink to zero when the row track is 0fr — a plain block child
   with no min-height override would refuse to collapse below its content's
   natural height. */
.nav-group-children{display:grid;grid-template-rows:0fr;transition:grid-template-rows var(--t-med) var(--ease);}
.nav-group-children-inner{overflow:hidden;min-height:0;}
.nav-group.expanded > .nav-group-children{grid-template-rows:1fr;}
.nav-group-children .nav-link{padding-left:34px;font-size:12.5px;}
.nav-group-children .nav-link:hover{padding-left:34px;}
.nav-group-children .nav-group-children .nav-link{padding-left:48px;}
.nav-group-children .nav-group-children .nav-link:hover{padding-left:48px;}
#app-shell.sidebar-collapsed .nav-chevron{display:none;}
#app-shell.sidebar-collapsed .nav-group-children{display:none;}
#app-shell[data-nav-pos="top"] .nav-group-children{max-height:none;position:absolute;top:100%;left:0;background:var(--sidebar-bg-1);border:1px solid var(--sidebar-border);flex-direction:column;min-width:200px;box-shadow:var(--shadow-lg);border-radius:0 0 var(--radius-sm) var(--radius-sm);z-index:30;display:none;}
#app-shell[data-nav-pos="top"] .nav-group{position:relative;}
#app-shell[data-nav-pos="top"] .nav-group.expanded > .nav-group-children{display:flex;}
/* The open dropdown's own .nav-section is a stacking context (see the
   universal .sidebar-brand,.nav-section rule) — without this, a *later*
   sibling section (e.g. "Sales") paints over an *earlier* one's open
   dropdown (e.g. "Targets") since both sit at the same z-index and later
   DOM order wins ties. Bumping just the active one above its siblings
   fixes the overlap regardless of which group is open. */
#app-shell[data-nav-pos="top"] .nav-section:has(.nav-group.expanded){z-index:2;}
#app-shell[data-nav-pos="top"] .nav-group-children .nav-link{padding-left:12px;}

.nav-link .nav-text{flex:1;}

/* Portal Home — module hub cards.
   Compact tile pattern (icon + label + a couple of stats, whole card
   clickable, no separate button) rather than the earlier big card —
   chosen with room to grow to a dozen-plus modules in mind, where a grid
   of large cards would mean endless scrolling before this even scales. */
.module-card{display:flex;flex-direction:column;gap:6px;padding:14px 15px;cursor:pointer;transition:transform var(--t-fast) var(--ease),box-shadow var(--t-fast) var(--ease),border-color var(--t-fast) var(--ease);}
.module-card:hover{transform:translateY(-2px);box-shadow:var(--shadow-md);border-color:var(--brand-500);}
.module-card-soon{cursor:default;opacity:.75;}
.module-card-soon:hover{transform:none;box-shadow:var(--shadow-sm);border-color:var(--ink-200);}
.module-card-head{display:flex;align-items:center;gap:10px;}
.module-card-head > div:last-child{display:flex;flex-direction:column;gap:3px;align-items:flex-start;flex:1;min-width:0;}
.module-card-head b{font-size:13px;color:var(--ink-900);}
.module-card-arrow{margin-left:auto;color:var(--ink-400);flex-shrink:0;align-self:center;transition:transform var(--t-fast) var(--ease),color var(--t-fast) var(--ease);}
.module-card-arrow svg{width:15px;height:15px;}
.module-card:hover .module-card-arrow{transform:translateX(2px);color:var(--brand-600);}
.module-icon{
  width:32px;height:32px;border-radius:9px;flex-shrink:0;
  display:flex;align-items:center;justify-content:center;
  background:var(--ink-100);color:var(--ink-500);
}
.module-icon svg{width:16px;height:16px;}
.module-icon.accent-live{background:linear-gradient(135deg,var(--brand-600),var(--brand-800));color:#fff;}
.module-icon.accent-soon{background:var(--ink-100);color:var(--ink-500);}
.module-desc{margin:0;font-size:11.5px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.module-stats{display:flex;gap:14px;padding:2px 0 0;}
.module-stats > div{display:flex;flex-direction:column;}
.module-stats b{font-family:var(--font-mono);font-size:14.5px;color:var(--ink-900);font-variant-numeric:tabular-nums;}
.module-stats span{font-size:9.5px;color:var(--ink-500);text-transform:uppercase;letter-spacing:.02em;}

/* Sidebar "coming soon" pill on nav links (linkSoon() in app.js) */
.nav-soon-pill{
  margin-left:auto;font-size:9.5px;font-weight:700;letter-spacing:.03em;text-transform:uppercase;
  padding:2px 6px;border-radius:20px;background:var(--ink-100);color:var(--ink-500);flex-shrink:0;
}
