/* ═══════════════════════════════════════════════════════════════════
   MINELEDGER — Design System v3
   DM Sans · Navy/Amber · Light neutral surface
   ═══════════════════════════════════════════════════════════════════ */

/* ── Fonts ─────────────────────────────────────────────────────── */
/* Self-hosted (was Google Fonts CDN — see docs/AUDIT-2026-07-12.md B1: CSP
   must not depend on third-party origins, and self-hosting is faster on a
   slow connection since it shares this stylesheet's own connection/cache).
   ibm-plex.css is kept for IBM Plex Mono only (--mono, numeric/tabular
   values). Sans was Poppins (matching registration.auca.ac.rw, 2026-08-06),
   replaced 2026-09-13 with DM Sans — Jean Luc compared both against the real
   payroll screen (side-by-side artifact) and picked DM Sans for holding up
   better in this app's dense small-text tables. */
@import url('/vendor/fonts/ibm-plex.css');
@import url('/vendor/fonts/dm-sans.css');

/* ── Design Tokens ─────────────────────────────────────────────── */
:root {
  /* Primary navy */
  --navy:        #1F3A5F;
  --navy-700:    #1A3252;
  --navy-800:    #142840;
  --navy-900:    #0F1F33;
  --navy-tint:   #2D4E78;

  /* Surfaces */
  --surface:     #F8FAFC;
  --surface-2:   #EEF2F7;
  --surface-3:   #DCE6F0;
  --white:       #FFFFFF;
  --line:        #E5E7EB;
  --line-soft:   #ECEFF3;

  /* Text */
  --ink:         #0F172A;
  --ink-2:       #3F5470;
  --ink-3:       #6B7E96;
  --ink-4:       #9AA9BC;
  --on-navy:     #EAF1F9;
  --on-navy-dim: #9DB2CC;

  /* Status */
  --amber:       #F6C667;
  --amber-deep:  #C98A12;
  --amber-bg:    #FCF1D6;
  --red:         #C0392B;
  --red-bg:      #F9E3E0;
  --red-deep:    #97271B;
  --green:       #1E8E5A;
  --green-bg:    #DDF1E6;
  --green-deep:  #156B43;
  --sky:         #0ea5e9;
  --sky-bg:      #e0f2fe;
  --blue:        #2A6FB5;
  --blue-bg:     #E1ECF7;
  --violet:      #6B4FA8;
  --violet-bg:   #ECE6F6;

  /* Radii */
  --r-xs:   5px;
  --r-sm:   7px;
  --r-md:  10px;
  --r-lg:  14px;
  --r-xl:  20px;
  --r-pill: 999px;

  /* Component radii — the exact scale a premium surface is judged on:
     card/table share one radius, buttons/inputs share another, badges
     are always a full pill. Kept distinct from the general r-* scale
     above so this refinement doesn't reflow dialogs/chips/etc. */
  --r-card:  16px;
  --r-table: 16px;
  --r-btn:   12px;
  --r-input: 12px;

  /* Shadows */
  --sh-sm:  0 1px 2px rgba(20,40,64,.06), 0 1px 3px rgba(20,40,64,.05);
  --sh-md:  0 2px 6px rgba(20,40,64,.07), 0 6px 16px rgba(20,40,64,.06);
  --sh-lg:  0 8px 28px rgba(20,40,64,.13), 0 2px 8px rgba(20,40,64,.07);
  --sh-pop: 0 18px 48px rgba(15,31,51,.22);

  /* One elevation system for every card-like surface (stat cards, table
     wrap, buttons) — resting state and its hover state, nothing else. */
  --sh-card:       0 6px 24px rgba(15,23,42,.06);
  --sh-card-hover: 0 12px 40px rgba(15,23,42,.10);

  /* Fonts */
  --font: "DM Sans", system-ui, -apple-system, sans-serif;
  --mono: "IBM Plex Mono", ui-monospace, Menlo, monospace;

  /* Layout */
  --sidebar-w:  248px;
  --topbar-h:    60px;

  /* Motion */
  --ease:     cubic-bezier(.2,.8,.2,1);
  --dur-fast: .14s;
  --dur:      .22s;
  --dur-slow: .36s;
}

/* ── Reset ─────────────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; }
html {
  /* Scales the whole rendered page (text, spacing, icons) down together —
     cheaper and more consistent than hand-tuning every hardcoded px value
     in this file. Applied once here, not on body too, so it isn't doubled. */
  zoom: 85%;
}
html, body {
  margin: 0; padding: 0;
  height: 100%;
  background: var(--surface);
  color: var(--ink-2);
  font-family: var(--font);
  font-size: 14px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}
h1, h2, h3, h4 { color: var(--ink); margin: 0; font-weight: 700; letter-spacing: -.01em; line-height: 1.25; }
p { margin: 0; }
button { font-family: inherit; cursor: pointer; }
a { color: inherit; text-decoration: none; }
::selection { background: var(--amber); color: var(--navy-900); }

/* ── Scrollbar ──────────────────────────────────────────────────── */
*::-webkit-scrollbar { width: 10px; height: 10px; }
*::-webkit-scrollbar-thumb { background: #C4D2E0; border-radius: 999px; border: 2px solid transparent; background-clip: padding-box; }
*::-webkit-scrollbar-thumb:hover { background: #A9BBCD; background-clip: padding-box; }
*::-webkit-scrollbar-track { background: transparent; }

/* ── Utilities ──────────────────────────────────────────────────── */
.mono    { font-family: var(--mono); font-feature-settings: "tnum" 1; }
.eyebrow { font-size: 11px; font-weight: 600; letter-spacing: .09em; text-transform: uppercase; color: var(--ink-3); }
.muted   { color: var(--ink-3); }
.faint   { color: var(--ink-4); }
.num     { font-family: var(--mono); font-variant-numeric: tabular-nums; }
.scroll-y { overflow-y: auto; }
.hr      { height: 1px; background: var(--line-soft); border: 0; margin: 0; }
.d-none   { display: none; }
.d-inline { display: inline; }

/* ════════════════════════════════════════════════════════════════
   APP SHELL
   ════════════════════════════════════════════════════════════════ */
.ml-shell, .app-shell {
  display: grid;
  grid-template-columns: var(--sidebar-w) 1fr;
  /* 100% (not 100vh) — under the html-level `zoom` scale-down above, vh
     resolves against the real device viewport and comes up short; % of the
     already-zoomed html/body box fills correctly. */
  height: 100%;
  overflow: hidden;
  background: var(--surface);
  font-family: var(--font);
  color: var(--ink-2);
}

/* Right column wrapper */
.ml-main {
  display: flex;
  flex-direction: column;
  overflow: hidden;
  min-width: 0;
}

.ml-content, .app-main {
  flex: 1;
  overflow-y: auto;
  padding: 32px 32px 64px;
  background: var(--surface);
}

/* ════════════════════════════════════════════════════════════════
   SIDEBAR
   ════════════════════════════════════════════════════════════════ */
.ml-sidebar, .app-sidebar {
  background: var(--navy-900);
  color: var(--on-navy);
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

/* Logo bar */
.sidebar-logo {
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 16px 16px 14px;
}

.sidebar-logo__mark {
  width: 36px; height: 36px;
  border-radius: 8px;
  background: #fff;
  display: flex; align-items: center; justify-content: center;
  flex-shrink: 0;
  overflow: hidden;
}

.sidebar-logo__img {
  width: 100%; height: 100%;
  object-fit: contain;
  padding: 3px;
}

.sidebar-logo__name  { font-size: 13.5px; font-weight: 700; color: #fff; letter-spacing: .02em; }
.sidebar-logo__sub   { font-size: 10.5px; color: var(--on-navy-dim); margin-top: 2px; }

/* Hairline divider */
.sidebar-hr { height: 1px; background: rgba(255,255,255,.08); margin: 0 12px 10px; }

/* User chip */
.sidebar-user {
  padding: 0 12px 8px;
}

.sidebar-user__chip {
  display: flex; align-items: center; gap: 10px;
  padding: 10px 12px;
  background: rgba(255,255,255,.055);
  border: 1px solid rgba(255,255,255,.08);
  border-radius: 10px;
}

.sidebar-user__name { font-size: 12.5px; font-weight: 600; color: #fff; white-space: nowrap; line-height: 1.2; }
.sidebar-user__role { font-size: 10.5px; color: var(--on-navy-dim); white-space: nowrap; }

/* Language dropdown — shared across the whole app (fragments/lang-dropdown.html):
   globe + current language name + chevron, opens a small menu. Default
   variant suits a light background (used inline in .ml-topbar, on every
   staff/owner/admin page); .lang-dd--on-dark suits landing/login/
   change-password's dark hero panels. */
.lang-dd { position: relative; }
.lang-dd__trigger {
  display: flex; align-items: center; gap: 6px;
  background: transparent; border: 1px solid var(--line); color: var(--ink-2);
  padding: 6px 11px; border-radius: var(--r-pill); font-size: 12px; font-weight: 600;
  font-family: inherit; cursor: pointer; transition: background var(--dur-fast) var(--ease);
}
.lang-dd__trigger:hover { background: var(--surface-2); }
.lang-dd__globe, .lang-dd__chevron { width: 14px; height: 14px; flex-shrink: 0; }
.lang-dd__chevron { transition: transform var(--dur-fast) var(--ease); }
.lang-dd.is-open .lang-dd__chevron { transform: rotate(180deg); }
.lang-dd__menu {
  position: absolute; top: calc(100% + 8px); right: 0; min-width: 150px;
  background: var(--white); border-radius: var(--r-md); box-shadow: var(--sh-pop);
  padding: 6px; display: none; z-index: 40;
}
.lang-dd.is-open .lang-dd__menu { display: block; }
.lang-dd__item {
  display: block; padding: 9px 12px; border-radius: var(--r-sm);
  color: var(--ink-2); font-size: 13.5px; font-weight: 500; text-decoration: none;
}
.lang-dd__item:hover { background: var(--surface-2); color: var(--ink); }

.lang-dd--on-dark .lang-dd__trigger {
  background: rgba(255,255,255,.08); border-color: rgba(255,255,255,.25); color: #fff;
}
.lang-dd--on-dark .lang-dd__trigger:hover { background: rgba(255,255,255,.16); }

@media (max-width: 560px) {
  .lang-dd__trigger span { display: none; }
  .lang-dd__trigger { padding: 6px 8px; }
}
.sidebar-lang__sep { color: rgba(255,255,255,.25); }

/* Nav */
.sidebar-nav { flex: 1; padding: 6px 12px; overflow-y: auto; }

.sidebar-nav__group {
  font-size: 10px; font-weight: 600;
  letter-spacing: .09em; text-transform: uppercase;
  color: rgba(255,255,255,.32);
  padding: 18px 8px 6px;
}

.nav-item {
  display: flex; align-items: center; gap: 11px;
  width: 100%; padding: 10px 12px; margin: 3px 0;
  border: 0; border-radius: 9px;
  font-size: 13px; font-weight: 500;
  color: var(--on-navy-dim);
  background: transparent;
  cursor: pointer; text-align: left;
  position: relative;
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease);
}

.nav-item:hover { background: rgba(255,255,255,.07); color: var(--on-navy); }

.nav-item.active {
  background: rgba(246,198,103,.16);
  color: #fff;
  font-weight: 600;
}

.nav-item.active::before {
  content: '';
  position: absolute; left: 0; top: 8px; bottom: 8px;
  width: 3px; border-radius: 3px;
  background: var(--amber);
}

/* Sign-out lives inside a .nav-item too (sidebar-foot) — a faint red tint
   on hover signals "exit" the way Linear/Vercel treat destructive/leave
   actions, without needing a whole separate button style. */
.sidebar-foot .nav-item:hover { background: rgba(220,38,38,.14); color: #fca5a5; }

.nav-item__icon {
  font-size: 14px;
  flex-shrink: 0;
  opacity: .8;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 17px;
  height: 17px;
}
.nav-item__icon svg { width: 100%; height: 100%; }

/* Sidebar counter pill — e.g. open tasks waiting on you. Right-aligned inside
   the flex .nav-item. */
.nav-item__count {
  margin-left: auto;
  min-width: 18px; height: 18px; padding: 0 5px;
  border-radius: 999px;
  background: var(--amber); color: var(--navy);
  font-size: 10.5px; font-weight: 700; line-height: 1;
  display: inline-flex; align-items: center; justify-content: center;
}
.nav-item.active .nav-item__count { background: #fff; }

/* Logout */
.sidebar-foot {
  padding: 12px;
  border-top: 1px solid rgba(255,255,255,.08);
}

/* ════════════════════════════════════════════════════════════════
   TOPBAR
   ════════════════════════════════════════════════════════════════ */
.ml-topbar, .topbar {
  height: var(--topbar-h);
  display: flex; align-items: center; justify-content: space-between;
  padding: 0 24px;
  background: var(--white);
  border-bottom: 1px solid var(--line);
  flex-shrink: 0;
  z-index: 10;
}

.topbar__left  { display: flex; align-items: center; gap: 8px; font-size: 13px; }
.topbar__org   { color: var(--ink-3); font-weight: 500; }
.topbar__slash { color: var(--ink-4); margin: 0 2px; }
.topbar__title { font-weight: 700; color: var(--ink); }

.topbar__right { display: flex; align-items: center; gap: 14px; }
.topbar__divider { width: 1px; height: 24px; background: var(--line); }
.topbar__user-name { font-size: 13px; font-weight: 600; color: var(--ink); line-height: 1.25; }
.topbar__user-role { font-size: 11px; color: var(--ink-3); }
.topbar__date { font-family: var(--mono); font-size: 11.5px; color: var(--ink-4); }

/* ════════════════════════════════════════════════════════════════
   CARDS
   ════════════════════════════════════════════════════════════════ */
.card, .ml-card {
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  box-shadow: var(--sh-card);
}

.card-pad { padding: 18px 20px; }

.card-hd, .ml-card__header {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 15px 20px;
  border-bottom: 1px solid var(--line-soft);
}

.card-hd h3, .ml-card__title { font-size: 14.5px; color: var(--ink); font-weight: 600; }
.ml-card__subtitle { font-size: 12px; color: var(--ink-3); margin-top: 2px; }
.ml-card__menu { color: var(--ink-4); font-size: 20px; cursor: pointer; line-height: 1; }
.ml-card__body { padding: 14px 20px; }

/* Accent left border variant */
.card--accent-left, .ml-card--accent-left { border-left: 3px solid var(--amber-deep); }
.card--accent-green { border-left: 4px solid var(--green); }
.bg-surface-2 { background: var(--surface-2); }

/* ════════════════════════════════════════════════════════════════
   BUTTONS
   ════════════════════════════════════════════════════════════════ */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  height: 44px; padding: 0 22px;
  border-radius: var(--r-btn); border: 1px solid transparent;
  font-size: 14px; font-weight: 600; line-height: 1;
  transition: background var(--dur) var(--ease), border-color var(--dur) var(--ease),
              box-shadow var(--dur) var(--ease), transform var(--dur) var(--ease);
  white-space: nowrap;
}
.btn:active { transform: translateY(.5px) scale(.99); }

.btn-primary, .btn.btn-primary { background: var(--navy); color: #fff; border-color: var(--navy); box-shadow: var(--sh-card); }
.btn-primary:hover, .btn.btn-primary:hover { background: var(--navy-700); box-shadow: var(--sh-card-hover); transform: translateY(-1px) scale(1.02); }

.btn-amber, .btn.btn-amber { background: var(--amber); color: var(--navy-900); }
.btn-amber:hover { background: #f3bd4f; }

.btn-ghost, .btn.btn-ghost, .btn-outline, .btn-secondary {
  background: var(--white); color: var(--ink); border-color: var(--line);
}
.btn-ghost:hover, .btn.btn-ghost:hover, .btn-outline:hover, .btn-secondary:hover {
  background: var(--surface); border-color: var(--surface-3);
  box-shadow: var(--sh-sm); transform: translateY(-1px);
}

.btn-quiet, .btn.btn-quiet { background: transparent; color: var(--ink-2); }
.btn-quiet:hover { background: var(--surface-2); }

.btn-danger, .btn.btn-danger { background: var(--red); color: #fff; }
.btn-danger:hover { background: var(--red-deep); }

/* Size modifiers */
.btn-sm { height: 30px; padding: 0 11px; font-size: 12.5px; border-radius: var(--r-xs); }
.btn-lg { height: 44px; padding: 0 22px; font-size: 15px; }
.btn[disabled], button[disabled] { opacity: .5; pointer-events: none; }
.btn-disabled { opacity: .5; cursor: not-allowed; }

/* Keep old names working */
.btn-pdf { background: var(--navy); color: #fff; border: none; padding: 7px 16px; font-size: 12px; font-weight: 600; border-radius: var(--r-sm); }
.btn-pdf:hover { background: var(--navy-700); }

/* Password-toggle eye button (login page) */
.ml-pwd-toggle {
  position: absolute; right: 12px; top: 50%; transform: translateY(-50%);
  background: none; border: none; color: var(--ink-4, #9AA9BC);
  cursor: pointer; padding: 6px; line-height: 0;
  display: flex; align-items: center; border-radius: 4px;
  transition: color .15s, background .15s;
}
.ml-pwd-toggle:hover { color: var(--ink-2, #3F5470); background: rgba(0,0,0,.05); }

/* ════════════════════════════════════════════════════════════════
   INPUTS
   ════════════════════════════════════════════════════════════════ */
.input, .select, .ml-input, .ml-select, textarea.input {
  width: 100%; height: 38px; padding: 0 12px;
  border: 1px solid var(--line);
  border-radius: var(--r-input);
  background: var(--white); color: var(--ink);
  font-family: inherit; font-size: 13.5px;
  transition: border-color var(--dur-fast), box-shadow var(--dur-fast);
}
textarea.input { height: auto; padding: 9px 12px; resize: vertical; }
.input:focus, .select:focus, .ml-input:focus, .ml-select:focus, textarea.input:focus {
  outline: none;
  border-color: var(--navy-tint);
  box-shadow: 0 0 0 3px rgba(45,78,120,.13);
}
.input::placeholder, .ml-input::placeholder { color: var(--ink-4); }
label.field-label, .ml-label {
  display: block; font-size: 12px; font-weight: 600;
  color: var(--ink-2); margin-bottom: 6px;
}

/* ════════════════════════════════════════════════════════════════
   BADGES
   ════════════════════════════════════════════════════════════════ */
.badge {
  display: inline-flex; align-items: center; gap: 5px;
  height: 24px; padding: 0 12px;
  border-radius: var(--r-pill);
  font-size: 11.5px; font-weight: 600; letter-spacing: .01em;
  white-space: nowrap; line-height: 1;
  transition: filter var(--dur) var(--ease);
}
.badge:hover { filter: brightness(1.06); }

.badge-grey,    .badge--dept     { background: var(--surface-2); color: var(--ink-3); }
.badge-navy                      { background: #E2EAF3; color: var(--navy); }
.badge-blue,    .badge--leave, .badge--grade-c { background: var(--blue-bg); color: var(--blue); }
.badge-green,   .badge--active, .badge--present, .badge--op, .badge--grade-a
                                 { background: var(--green-bg); color: var(--green-deep); }
.badge-amber,   .badge--leave, .badge--maint, .badge--grade-b
                                 { background: var(--amber-bg); color: var(--amber-deep); }
.badge-red,     .badge--inactive, .badge--absent
                                 { background: var(--red-bg); color: var(--red-deep); }
.badge-violet                    { background: var(--violet-bg); color: var(--violet); }
/* In-progress status (maintenance records) — was an inline style="" on the
   template, which CSP's style-src 'self' silently drops (no unsafe-inline).
   A real class so the sky color actually renders. */
.badge--progress                 { background: var(--sky-bg); color: var(--sky); }

/* ════════════════════════════════════════════════════════════════
   TABLE
   ════════════════════════════════════════════════════════════════ */
.tbl, .ml-table {
  width: 100%; border-collapse: collapse; font-size: 13px;
}

.tbl thead th, .ml-table thead th {
  text-align: left; font-size: 12.5px; font-weight: 600;
  letter-spacing: .07em; text-transform: uppercase;
  color: var(--ink-3); padding: 14px 20px;
  border-bottom: 1px solid var(--line);
  background: var(--surface-2); position: sticky; top: 0; z-index: 1;
}

/* .t-right is the same class used on <td> cells to right-align a value — reusing it
   on <th> must actually right-align the header too, not just cancel letter-spacing.
   Without this, "text-align:left" above (more specific than the bare .t-right utility)
   silently wins and every "t-right" header sits left of its right-aligned column. */
.tbl thead th.right, .ml-table thead th.right,
.tbl thead th.t-right, .ml-table thead th.t-right { text-align: right; letter-spacing: normal; }

.tbl tbody td, .ml-table tbody td {
  padding: 15px 20px;
  font-size: 14.5px;
  border-bottom: 1px solid var(--line-soft);
  color: var(--ink-2); vertical-align: middle;
}

.tbl tbody tr, .ml-table tbody tr { transition: background var(--dur) var(--ease); }
.tbl tbody tr:hover td, .ml-table tbody tr:hover td { background: var(--surface-2); }
.tbl tbody tr:last-child td, .ml-table tbody tr:last-child td { border-bottom: none; }

.tbl td.mono, .ml-table td.mono   { font-family: var(--mono); }
.tbl td.right, .ml-table td.right { text-align: right; font-family: var(--mono); }
.tbl td.bold, .ml-table td.bold   { font-weight: 600; color: var(--ink); }

/* td.bold's own color (above) has higher specificity than a bare .txt-red/.txt-green
   utility class, so pairing them on the same <td> (e.g. a bold profit/loss figure)
   silently loses the color — the utility class never wins. Needs its own rule. */
.tbl td.bold.txt-red,   .ml-table td.bold.txt-red   { color: var(--red); }
.tbl td.bold.txt-green, .ml-table td.bold.txt-green { color: var(--green); }

/* Spend breakdown (dashboard "By Site"/"Lifetime" tables) — a raw sum on its own
   doesn't say which things it's made of, so the amount expands in place into
   Purchases vs Payroll, each with a count/date-range. Deliberately not absolutely
   positioned: the table's card wrapper is overflow:hidden (.overflow-h), so a
   floating panel would get clipped — the row just grows taller instead. */
.ml-spend-detail { cursor: pointer; }
.ml-spend-detail summary {
  list-style: none;
  color: var(--ink-2);
}
.ml-spend-detail summary::-webkit-details-marker { display: none; }
.ml-spend-detail summary::after {
  content: '▾';
  display: inline-block;
  margin-left: 6px;
  font-size: 10px;
  color: var(--ink-4);
}
.ml-spend-detail[open] summary::after { content: '▴'; }
.ml-spend-detail__panel {
  margin-top: 10px;
  padding: 12px 14px;
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  font-size: 12.5px;
  max-width: 280px;
}
.ml-spend-detail__row { display: flex; justify-content: space-between; align-items: baseline; }
.ml-spend-detail__row--mt { margin-top: 10px; padding-top: 10px; border-top: 1px solid var(--line-soft); }
.ml-spend-detail__label { color: var(--ink-3); font-weight: 600; }
.ml-spend-detail__amount { font-family: var(--mono); color: var(--ink); }
.ml-spend-detail__meta { color: var(--ink-4); font-size: 11px; margin-top: 2px; }
.ml-spend-detail__link { display: inline-block; margin-top: 6px; color: var(--sky); font-size: 11.5px; }

/* Table wrapper card. overflow-x: auto (not the old plain "overflow: hidden")
   — on a narrow screen a table wider than the viewport needs to actually
   scroll sideways to reach its later columns; "hidden" silently clipped them
   with no way to reach them at all (found live on phone, 2026-09-19: on
   Equipment, everything after "Purchase Date" was simply gone). overflow-y
   stays hidden so the wrapper still clips the table's square corners to its
   own rounded border, same as before. */
.ml-table-wrap {
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--r-table);
  overflow-x: auto;
  overflow-y: hidden;
  box-shadow: var(--sh-card);
}

/* ════════════════════════════════════════════════════════════════
   CHIPS (filter pills)
   ════════════════════════════════════════════════════════════════ */
.chip, .ml-shift-btn {
  display: inline-flex; align-items: center; gap: 6px;
  height: 28px; padding: 0 11px;
  border: 1px solid var(--line); border-radius: var(--r-pill);
  background: var(--white); font-size: 12.5px; font-weight: 500;
  color: var(--ink-2); cursor: pointer;
  transition: all .12s;
}
.chip:hover, .ml-shift-btn:hover { background: var(--surface); }
.chip.active, .ml-shift-btn--active {
  background: var(--navy); color: #fff; border-color: var(--navy);
}

/* ════════════════════════════════════════════════════════════════
   AVATAR
   ════════════════════════════════════════════════════════════════ */
.avatar {
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 50%; font-weight: 600; color: #fff; flex: none;
  font-size: 12px; letter-spacing: .02em;
  background: var(--navy-tint);
}

/* ════════════════════════════════════════════════════════════════
   ANIMATIONS
   ════════════════════════════════════════════════════════════════ */
.fade-in { animation: fadeIn .22s ease both; }
@keyframes fadeIn { from { opacity:0; transform:translateY(4px); } to { opacity:1; transform:none; } }

.rise-in { animation: riseIn var(--dur) var(--ease) both; }
@keyframes riseIn { from { opacity:0; transform:translateY(8px); } to { opacity:1; transform:none; } }

.pop-in { animation: popIn var(--dur) var(--ease) both; }
@keyframes popIn { from { opacity:0; transform:scale(.96); } to { opacity:1; transform:none; } }

.stagger > * { animation: riseIn var(--dur) var(--ease) both; }
.stagger > *:nth-child(1){animation-delay:.02s}
.stagger > *:nth-child(2){animation-delay:.06s}
.stagger > *:nth-child(3){animation-delay:.10s}
.stagger > *:nth-child(4){animation-delay:.14s}
.stagger > *:nth-child(5){animation-delay:.18s}
.stagger > *:nth-child(6){animation-delay:.22s}

.sk { background: linear-gradient(100deg,var(--surface-2) 30%,#F2F6FB 50%,var(--surface-2) 70%); background-size:200% 100%; animation:sk 1.3s ease-in-out infinite; }
@keyframes sk { 0%{background-position:200% 0} 100%{background-position:-200% 0} }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration:.001ms !important; transition-duration:.001ms !important; }
  .sk { animation:none; background:var(--surface-2); }
}

/* ════════════════════════════════════════════════════════════════
   SECTION HEADER
   ════════════════════════════════════════════════════════════════ */
.ml-section-header, .section-hd {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: 20px;
  margin-bottom: 36px;
}
.ml-section-header h2, .section-hd h2 {
  font-size: 32px; font-weight: 700; color: var(--ink); margin: 0;
  letter-spacing: -.02em; line-height: 1.2;
}
.ml-section-header .btn, .section-hd .btn { flex-shrink: 0; margin-top: 2px; }
.ml-section-sub {
  font-size: 14px; color: var(--ink-3); margin: 6px 0 0;
}

/* ════════════════════════════════════════════════════════════════
   FLASH MESSAGES
   ════════════════════════════════════════════════════════════════ */
.ml-flash, .alert {
  display: flex; align-items: center; gap: 10px;
  padding: 12px 16px;
  border-radius: var(--r-sm);
  font-size: 13px;
  margin-bottom: 18px;
}
.ml-flash--success, .alert-success {
  background: var(--green-bg); color: var(--green-deep);
  border: 1px solid #B2E4CA;
}
.ml-flash--error, .alert-error {
  background: var(--red-bg); color: var(--red-deep);
  border: 1px solid #F0BFBA;
}

/* ════════════════════════════════════════════════════════════════
   EMPTY STATE
   ════════════════════════════════════════════════════════════════ */
.ml-empty {
  text-align: center;
  padding: 56px 24px;
  color: var(--ink-3);
}
.ml-empty__icon  { font-size: 30px; margin-bottom: 12px; opacity: .35; }
.ml-empty__title { font-size: 14.5px; font-weight: 600; color: var(--ink-2); margin-bottom: 6px; }
.ml-empty__sub   { font-size: 13px; color: var(--ink-3); line-height: 1.6; }

/* ════════════════════════════════════════════════════════════════
   DASHBOARD — FILTER BAR
   ════════════════════════════════════════════════════════════════ */
.ml-filter-bar {
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  padding: 10px 16px;
  margin-bottom: 18px;
  display: flex; gap: 6px; align-items: center;
  box-shadow: var(--sh-sm);
}
.ml-filter-label { font-size: 12px; color: var(--ink-3); font-weight: 600; margin-right: 2px; }
.ml-filter-select {
  padding: 5px 10px;
  border: 1px solid var(--line);
  border-radius: var(--r-xs);
  font-size: 12.5px;
  background: var(--white);
  font-family: var(--font);
  color: var(--ink);
  outline: none;
}
.ml-filter-select:focus { border-color: var(--navy-tint); }

/* ════════════════════════════════════════════════════════════════
   DASHBOARD — TWO-COL GRID
   ════════════════════════════════════════════════════════════════ */
.ml-two-col {
  display: grid;
  grid-template-columns: 1.65fr 1fr;
  gap: 16px;
  margin-bottom: 16px;
  align-items: start;
}

/* ════════════════════════════════════════════════════════════════
   DASHBOARD — METRIC CARDS
   ════════════════════════════════════════════════════════════════ */
.ml-metric {
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  padding: 20px 24px;
  box-shadow: var(--sh-sm);
}
.ml-metric__label {
  font-size: 10.5px; font-weight: 600; color: var(--ink-3);
  text-transform: uppercase; letter-spacing: .08em; margin-bottom: 6px;
}
.ml-metric__value {
  font-size: 32px; font-weight: 700;
  font-family: var(--mono); color: var(--ink); line-height: 1.1;
}
.ml-metric__sub { font-size: 12px; color: var(--ink-3); margin-top: 8px; }

/* ════════════════════════════════════════════════════════════════
   DASHBOARD — STAT BADGES (workforce card)
   ════════════════════════════════════════════════════════════════ */
.ml-metric-badges {
  padding: 14px 20px;
  display: flex; gap: 10px;
  border-bottom: 1px solid var(--line-soft);
}

.ml-stat-badge { flex: 1; border-radius: var(--r-sm); padding: 10px 14px; }
.ml-stat-badge__label { font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: .5px; margin-bottom: 4px; opacity: .85; }
.ml-stat-badge__value { font-size: 24px; font-weight: 700; font-family: var(--mono); line-height: 1; }

/* ════════════════════════════════════════════════════════════════
   DASHBOARD — DEPT BARS
   ════════════════════════════════════════════════════════════════ */
.ml-dept-bar { margin-bottom: 14px; }
.ml-dept-bar__row { display: flex; justify-content: space-between; margin-bottom: 5px; }
.ml-dept-bar__name { font-size: 13px; font-weight: 500; color: var(--ink); }
.ml-dept-bar__frac { font-size: 12px; color: var(--ink-3); font-family: var(--mono); }
.ml-dept-bar__track { height: 5px; background: var(--surface-2); border-radius: 3px; overflow: hidden; }
.ml-dept-bar__fill  { height: 100%; background: var(--navy); border-radius: 3px; }

/* ════════════════════════════════════════════════════════════════
   DASHBOARD — PAYROLL PREVIEW
   ════════════════════════════════════════════════════════════════ */
.ml-payroll-preview {
  margin-top: 18px; padding-top: 14px;
  border-top: 1px solid var(--line-soft);
}
.ml-payroll-preview__label { font-size: 10.5px; font-weight: 700; color: var(--ink-4); text-transform: uppercase; letter-spacing: .08em; margin-bottom: 6px; }
.ml-payroll-preview__amount { font-size: 20px; font-weight: 700; font-family: var(--mono); color: var(--ink); }
.ml-payroll-preview__sub { font-size: 12px; color: var(--ink-3); margin-top: 2px; }

/* ════════════════════════════════════════════════════════════════
   FORMS — GRID
   ════════════════════════════════════════════════════════════════ */
.ml-form-grid       { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
.ml-form-grid--3    { grid-template-columns: 1fr 1fr 1fr; }
.ml-form-group      { display: flex; flex-direction: column; }
.ml-form-error      { font-size: 11px; color: var(--red); margin-top: 4px; }
.ml-form-hint       { font-size: 11px; color: var(--ink-3); margin-top: 4px; }

/* ════════════════════════════════════════════════════════════════
   FILTER TABS  (worker/shift list pages)
   ════════════════════════════════════════════════════════════════ */
.ml-filter-tabs     { display: flex; gap: 4px; margin-bottom: 20px; }
.ml-filter-tab      {
  padding: 6px 16px; border-radius: var(--r-sm); font-size: 13px; font-weight: 600;
  text-decoration: none; color: var(--ink-2);
  background: var(--surface-2); border: 1px solid var(--line);
  transition: background var(--dur-fast), color var(--dur-fast);
  cursor: pointer;
}
.ml-filter-tab:hover    { background: var(--surface-3); }
.ml-filter-tab--active  { background: var(--navy); color: #fff; border-color: var(--navy); }

/* ════════════════════════════════════════════════════════════════
   NATIVE DIALOG  (reactivate / assign / create modals)
   ════════════════════════════════════════════════════════════════ */
dialog.ml-dialog              { border: none; border-radius: var(--r-lg, 12px); padding: 0; box-shadow: 0 8px 32px rgba(0,0,0,.18); max-width: 460px; width: 90%; }
dialog.ml-dialog::backdrop    { background: rgba(0,0,0,.45); }
.ml-dialog__head              { padding: 20px 24px 16px; border-bottom: 1px solid var(--line); }
.ml-dialog__head h3           { font-size: 16px; font-weight: 700; margin: 0 0 4px; color: var(--ink); }
.ml-dialog__head p            { font-size: 13px; color: var(--ink-3); margin: 0; }
.ml-dialog__body              { padding: 16px 24px; }
.ml-dialog__body textarea     { height: auto; min-height: 80px; resize: vertical; }
.ml-dialog__foot              { padding: 12px 24px 20px; display: flex; gap: 10px; justify-content: flex-end; }

/* ════════════════════════════════════════════════════════════════
   SHIFT CARDS
   ════════════════════════════════════════════════════════════════ */
.ml-shift-card              { background: var(--white); border: 1px solid var(--line); border-radius: var(--r-md); margin-bottom: 16px; overflow: hidden; }
.ml-shift-card__header      { display: flex; align-items: center; gap: 12px; padding: 14px 20px; border-bottom: 1px solid var(--line); flex-wrap: wrap; }
.ml-shift-card__name        { font-size: 15px; font-weight: 700; color: var(--ink); flex: 1; min-width: 120px; }
.ml-shift-card__time        { font-family: var(--mono); font-size: 13px; color: var(--ink-3); white-space: nowrap; }
.ml-shift-card__site        { font-size: 12px; color: var(--ink-3); }
.ml-shift-card__actions     { display: flex; gap: 6px; margin-left: auto; }
.ml-shift-workers           { padding: 0 20px; }
.ml-shift-worker-row        { display: flex; align-items: center; gap: 10px; padding: 9px 0; border-bottom: 1px solid var(--line-soft); }
.ml-shift-worker-row:last-child { border-bottom: none; }
.ml-shift-worker-row__name  { flex: 1; font-size: 13.5px; font-weight: 500; color: var(--ink); }
.ml-shift-worker-row__dept  { font-size: 12px; color: var(--ink-3); }
.ml-shift-card__footer      { padding: 10px 20px; background: var(--surface); border-top: 1px solid var(--line-soft); display: flex; align-items: center; justify-content: space-between; }
.ml-shift-empty             { padding: 14px 20px; font-size: 13px; color: var(--ink-4); font-style: italic; }

/* Shift type badges */
.badge--day   { background: var(--amber-bg); color: var(--amber-deep); border: 1px solid var(--amber); }
.badge--night { background: #eff1ff; color: #4338ca; border: 1px solid #c7d2fe; }

/* ════════════════════════════════════════════════════════════════
   FILTER TABS  (worker list and future list pages)
   ════════════════════════════════════════════════════════════════ */
.ml-filter-tabs { display: flex; gap: 4px; margin-bottom: 20px; }
.ml-filter-tab  {
  padding: 6px 16px; border-radius: var(--r-sm); font-size: 13px; font-weight: 600;
  text-decoration: none; color: var(--ink-2);
  background: var(--surface-2); border: 1px solid var(--line);
  transition: background var(--dur-fast), color var(--dur-fast);
  cursor: pointer;
}
.ml-filter-tab:hover    { background: var(--surface-3); }
.ml-filter-tab--active  { background: var(--navy); color: #fff; border-color: var(--navy); }

/* ════════════════════════════════════════════════════════════════
   NATIVE DIALOG  (reactivate / confirm modals)
   ════════════════════════════════════════════════════════════════ */
dialog.ml-dialog {
  border: none; border-radius: var(--r-lg, 12px); padding: 0;
  box-shadow: 0 8px 32px rgba(0,0,0,.18); max-width: 480px; width: 90%;
}
dialog.ml-dialog--wide { max-width: 560px; }
dialog.ml-dialog::backdrop { background: rgba(0,0,0,.45); }
.ml-dialog__head {
  padding: 20px 24px 16px;
  border-bottom: 1px solid var(--line);
  display: flex;
  justify-content: space-between;
  align-items: center;
}
.ml-dialog__head h3 { font-size: 16px; font-weight: 700; margin: 0; color: var(--ink); }
.ml-dialog__head p  { font-size: 13px; color: var(--ink-3); margin: 4px 0 0; }
.ml-dialog__body    { padding: 20px 24px 8px; }
.ml-dialog__body textarea { height: auto; min-height: 80px; resize: vertical; }
.ml-dialog__foot    { padding: 12px 24px 20px; display: flex; gap: 10px; justify-content: flex-end; border-top: 1px solid var(--line); }

/* ════════════════════════════════════════════════════════════════
   ATTENDANCE PAGE
   ════════════════════════════════════════════════════════════════ */
.ml-att-date-bar {
  display: flex; align-items: center; gap: 16px;
  background: var(--white); border: 1px solid var(--line);
  border-radius: var(--r-md); padding: 14px 20px;
  margin-bottom: 24px; box-shadow: var(--sh-sm);
}
.ml-att-date-bar label { font-size: 12px; font-weight: 600; color: var(--ink-3); text-transform: uppercase; letter-spacing: .06em; }
.ml-att-date-bar input[type="date"] { padding: 7px 12px; border: 1px solid var(--line); border-radius: var(--r-sm); font-size: 13.5px; font-family: var(--mono); color: var(--ink); background: var(--surface); cursor: pointer; }
.ml-att-date-bar input[type="date"]:focus { outline: 2px solid var(--amber); outline-offset: 2px; border-color: var(--amber); }

.ml-att-banner {
  display: flex; align-items: center; gap: 10px;
  background: #FFF8E7; border: 1px solid var(--amber); border-radius: var(--r-sm);
  padding: 10px 16px; margin-bottom: 18px; font-size: 13px; color: #92400e;
}
.ml-att-banner--locked {
  background: var(--red-bg); border-color: var(--red); color: var(--red-deep);
}

/* Attendance: one fold-away section per department (used by the staff form and the owner view) */
.ml-att-totals { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 16px; }
.ml-att-totals .badge b { margin-right: 2px; }
.ml-att-pos { margin-bottom: 10px; border: 1px solid var(--line); border-radius: var(--r-sm); overflow: hidden; background: var(--white); }
.ml-att-pos__head {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  padding: 10px 16px; cursor: pointer; list-style: none;
  background: var(--navy); color: #fff;
}
.ml-att-pos__head::-webkit-details-marker { display: none; }
.ml-att-pos__head::before { content: "▸"; font-size: 12px; transition: transform .15s; }
.ml-att-pos[open] > .ml-att-pos__head::before { transform: rotate(90deg); }
.ml-att-pos__name { font-size: 13.5px; font-weight: 700; }
.ml-att-pos__meta { font-size: 12px; opacity: .8; }
.ml-att-pos__right { margin-left: auto; display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.ml-att-pos__bar { width: 90px; height: 6px; appearance: none; border: 0; border-radius: 99px; overflow: hidden; background: rgba(255,255,255,.25); }
.ml-att-pos__bar::-webkit-progress-bar { background: rgba(255,255,255,.25); }
.ml-att-pos__bar::-webkit-progress-value { background: var(--amber); }
.ml-att-pos__bar::-moz-progress-bar { background: var(--amber); }
.ml-att-pos .ml-att-table { border: 0; border-radius: 0; }
.ml-site-group-heading .ml-att-pos__meta { margin-left: 8px; font-weight: 500; color: var(--ink-3); opacity: 1; }

.ml-att-shift-section { margin-bottom: 28px; }

.ml-att-shift-header {
  display: flex; align-items: center; gap: 12px;
  padding: 10px 16px; margin-bottom: 2px;
  background: var(--navy); border-radius: var(--r-sm) var(--r-sm) 0 0;
  color: #fff;
}
.ml-att-shift-header__name { font-size: 13.5px; font-weight: 700; }
.ml-att-shift-header__time { font-size: 12px; font-family: var(--mono); opacity: .75; }

/* Bare fieldset — used to group a form section that can be disabled as a whole
   (attendance/piecework, once payroll already covers that date) without the
   browser's default fieldset border/padding. A plain style="" attribute is
   blocked by this app's CSP (style-src 'self'), so it has to be a real class. */
.ml-bare-fieldset { border: 0; padding: 0; margin: 0; }

.ml-att-table {
  width: 100%; border-collapse: collapse;
  background: var(--white); border: 1px solid var(--line);
  border-top: none; border-radius: 0 0 var(--r-sm) var(--r-sm);
  overflow: hidden;
}
.ml-att-table th {
  font-size: 11px; font-weight: 700; color: var(--ink-3); text-transform: uppercase;
  letter-spacing: .05em; padding: 9px 16px; background: var(--surface);
  border-bottom: 1px solid var(--line); text-align: left;
}
.ml-att-row { display: contents; }
.ml-att-table td { padding: 11px 16px; border-bottom: 1px solid var(--line-soft); vertical-align: middle; }
.ml-att-table tr:last-child td { border-bottom: none; }
.ml-att-table tr.ml-att-row--absent td { background: #FFF5F5; }
.ml-att-table tr.ml-att-row--half td { background: var(--amber-bg); }

.ml-att-worker-name { font-size: 13.5px; font-weight: 500; color: var(--ink); }
.ml-att-worker-dept { font-size: 12px; color: var(--ink-3); margin-top: 2px; }

.ml-att-status-select {
  padding: 6px 10px; border: 1px solid var(--line); border-radius: var(--r-sm);
  font-size: 13px; background: var(--white); color: var(--ink); cursor: pointer;
}
.ml-att-status-select:focus { outline: 2px solid var(--amber); border-color: var(--amber); }

.ml-att-save-bar {
  display: flex; align-items: center; justify-content: space-between;
  padding: 16px 20px; background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-md); margin-top: 24px; box-shadow: var(--sh-sm);
}

/* ════════════════════════════════════════════════════════════════
   PAYROLL PAGE
   ════════════════════════════════════════════════════════════════ */
.ml-pay-period-bar {
  display: flex; align-items: center; gap: 16px; flex-wrap: wrap;
  background: var(--white); border: 1px solid var(--line);
  border-radius: var(--r-md); padding: 14px 20px;
  margin-bottom: 20px; box-shadow: var(--sh-sm);
}
.ml-pay-period-bar label { font-size: 12px; font-weight: 600; color: var(--ink-3); text-transform: uppercase; letter-spacing: .06em; white-space: nowrap; }
.ml-pay-period-bar input[type="date"] { padding: 7px 12px; border: 1px solid var(--line); border-radius: var(--r-sm); font-size: 13px; font-family: var(--mono); color: var(--ink); background: var(--surface); }
.ml-pay-period-bar input[type="date"]:focus { outline: 2px solid var(--amber); border-color: var(--amber); }
.ml-pay-period-bar__sep { font-size: 13px; color: var(--ink-4); }

/* "Download a generated payroll" list — sits between the period bar and the
   window statement so the bank-sheet export is findable without an exact
   date match in the boxes above. */
.ml-pay-downloads { margin-bottom: 20px; }
.ml-pay-downloads .ml-pay-table td { vertical-align: middle; }

/* Plain-language statement of exactly which dates are being counted — the fix
   for the "days-present mismatch" report (audit A5): two people looking at two
   different windows will correctly see two different counts, and this line
   makes the window impossible to miss. */
.ml-pay-window-statement {
  display: flex; align-items: center; gap: 8px;
  background: var(--surface); border: 1px solid var(--line-soft);
  border-radius: var(--r-sm); padding: 9px 16px;
  margin-bottom: 20px; font-size: 13px; color: var(--ink-2);
}
.ml-pay-window-statement strong { color: var(--ink); font-family: var(--mono); }

.ml-pay-kpi-row { display: grid; grid-template-columns: repeat(4,1fr); gap: 16px; margin-bottom: 24px; }
@media (max-width: 900px) { .ml-pay-kpi-row { grid-template-columns: repeat(2,1fr); } }
@media (max-width: 500px) { .ml-pay-kpi-row { grid-template-columns: 1fr; } }

.ml-pay-kpi { background: var(--white); border: 1px solid var(--line); border-radius: var(--r-md); padding: 18px 20px; box-shadow: var(--sh-sm); }
.ml-pay-kpi__label { font-size: 11px; font-weight: 700; color: var(--ink-3); text-transform: uppercase; letter-spacing: .06em; margin-bottom: 6px; }
.ml-pay-kpi__value { font-size: 24px; font-weight: 800; color: var(--ink); line-height: 1.1; }
.ml-pay-kpi__sub   { font-size: 12px; color: var(--ink-4); margin-top: 4px; }
.ml-pay-kpi--amber { border-top: 3px solid var(--amber); }
.ml-pay-kpi--green { border-top: 3px solid #22c55e; }
.ml-pay-kpi--red   { border-top: 3px solid var(--red); }

/* The Saturday hero number: projected net pay after advances. Deliberately
   distinct from the other KPI cards — this is the one number the whole
   product is staked on. */
.ml-pay-kpi--hero {
  border-top: none;
  background: linear-gradient(135deg, #15803d, #22c55e);
  box-shadow: var(--sh-md);
}
.ml-pay-kpi--hero .ml-pay-kpi__label { color: rgba(255,255,255,.88); }
.ml-pay-kpi--hero .ml-pay-kpi__value { color: #fff; font-size: 30px; }
.ml-pay-kpi--hero .ml-pay-kpi__sub   { color: rgba(255,255,255,.78); }
.ml-pay-kpi--narrow { max-width: 320px; }

/* The days x rate = gross "equation" on the payroll detail page — a table is the
   wrong shape for a single row of numbers; this makes the relationship between
   the values visually obvious instead of implied by column headers. */
.ml-pay-equation { display: flex; align-items: stretch; gap: 14px; margin-bottom: 20px; flex-wrap: wrap; }
.ml-pay-equation__item {
  background: var(--white); border: 1px solid var(--line); border-radius: var(--r-md);
  padding: 16px 22px; box-shadow: var(--sh-sm); text-align: center; min-width: 130px; flex: 1;
}
.ml-pay-equation__item--result { background: linear-gradient(135deg, #15803d, #22c55e); border: none; }
.ml-pay-equation__item--result .ml-pay-equation__value,
.ml-pay-equation__item--result .ml-pay-equation__label { color: #fff; }
.ml-pay-equation__value { font-size: 26px; font-weight: 800; color: var(--ink); line-height: 1.1; }
.ml-pay-equation__label { font-size: 11px; font-weight: 700; color: var(--ink-3); text-transform: uppercase; letter-spacing: .06em; margin-top: 6px; }
.ml-pay-equation__op { display: flex; align-items: center; justify-content: center; font-size: 22px; font-weight: 800; color: var(--ink-4); padding: 0 4px; }
@media (max-width: 700px) {
  .ml-pay-equation { flex-direction: column; }
  .ml-pay-equation__op { padding: 4px 0; }
}

/* Generic CSP-safe "hidden until JS shows it" helper — never use inline style="display:none",
   CSP's style-src has no 'unsafe-inline' and silently drops it (same class of bug as the
   login page's field-spacing fix — see project memory). */
.is-hidden { display: none; }

/* For JS-driven show/hide toggles specifically — the plain `hidden` DOM property
 * silently fails to hide anything that also carries a class setting its own
 * `display` (e.g. .ml-form-group, .field-group both set display:flex, which beats
 * the browser's own low-priority [hidden] default). !important guarantees this
 * always wins regardless of what other classes are on the element. */
.ml-js-hidden { display: none !important; }

.ml-pay-warning {
  display: flex; align-items: center; gap: 10px;
  background: #FFF8E7; border: 1px solid var(--amber); border-radius: var(--r-sm);
  padding: 10px 16px; margin-bottom: 16px; font-size: 13px; color: #92400e;
}
.ml-pay-already {
  display: flex; align-items: center; gap: 10px;
  background: #F0FFF4; border: 1px solid #86efac; border-radius: var(--r-sm);
  padding: 10px 16px; margin-bottom: 16px; font-size: 13px; color: #166534;
}

.ml-pay-table-wrap { background: var(--white); border: 1px solid var(--line); border-radius: var(--r-md); overflow: hidden; margin-bottom: 20px; box-shadow: var(--sh-sm); }
.ml-pay-table { width: 100%; border-collapse: collapse; }
.ml-pay-table th { font-size: 11px; font-weight: 700; color: var(--ink-3); text-transform: uppercase; letter-spacing: .05em; padding: 10px 16px; background: var(--surface); border-bottom: 1px solid var(--line); text-align: left; }
.ml-pay-table th:last-child, .ml-pay-table td:last-child { text-align: right; }
/* Every numeric column is marked with .t-right, not just the last one — :last-child
   above only ever caught the final column. Right-aligned headers must also not carry
   letter-spacing — it adds space after the LAST character too, so a right-aligned
   header sits visibly left of its own right-aligned value below. */
.ml-pay-table th.t-right { text-align: right; letter-spacing: normal; }
.ml-pay-table td.t-right { text-align: right; }
.ml-pay-table td { padding: 12px 16px; border-bottom: 1px solid var(--line-soft); font-size: 13.5px; color: var(--ink); vertical-align: middle; }
.ml-pay-table tr:last-child td { border-bottom: none; }
.ml-pay-table tr.ml-pay-no-rate td { color: var(--ink-4); font-style: italic; }
.ml-pay-table tfoot td { font-weight: 700; background: var(--surface); border-top: 2px solid var(--line); }
.ml-pay-table tr.ml-row-link { cursor: pointer; }
.ml-pay-table tr.ml-row-link:hover td { background: var(--surface); }

.ml-pay-generate-bar {
  display: flex; align-items: center; justify-content: space-between;
  padding: 14px 20px; background: var(--navy); border-radius: var(--r-md);
  color: #fff; margin-bottom: 32px;
}
.ml-pay-generate-bar span { font-size: 13px; opacity: .8; }
.ml-pay-generate-form { display: inline-flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.ml-pay-flat-group    { display: inline-flex; align-items: center; gap: 8px; }
.ml-pay-flat-input       { display: inline-flex; align-items: center; gap: 6px; }
.ml-pay-flat-input label { font-size: 12px; opacity: .85; }
.ml-pay-flat-input input { width: 110px; padding: 6px 8px; border: 1px solid var(--line); border-radius: 6px; font-size: 13px; }
.btn-attention { border-color: var(--amber-deep); color: var(--amber-deep); font-weight: 700; }
.ml-pay-reason-input { width: 220px; padding: 6px 8px; border: 1px solid var(--line); border-radius: 6px; font-size: 13px; color: var(--ink); }

/* Multi-site staff scoping (2026-09-28): heading above each mine site's own
   section of a list — only shown at all when a staff member has more than one
   assigned site (see StaffSiteScopeService), so a single-site account never
   sees this and the page looks exactly like it always did. */
.ml-site-group-heading { font-size: 15px; font-weight: 700; color: var(--ink-2); margin: 28px 0 12px; }
.ml-site-group-heading:first-of-type { margin-top: 0; }

/* History table */
.ml-pay-history-label { font-size: 11px; font-weight: 700; color: var(--ink-3); text-transform: uppercase; letter-spacing: .06em; margin-bottom: 12px; }

/* Payroll history, grouped by run (2026-09-28) — one collapsed summary line per
   past payroll, expanding to that run's per-worker table on click. Native
   <details>/<summary> — no JS needed, and the existing .ml-row-link click
   handler still works on rows once a group is open. */
.ml-history-period { background: var(--white); border: 1px solid var(--line); border-radius: var(--r-md); box-shadow: var(--sh-sm); margin-bottom: 10px; overflow: hidden; }
.ml-history-period[open] { margin-bottom: 16px; }
.ml-history-period__summary { list-style: none; cursor: pointer; display: flex; align-items: center; gap: 20px; padding: 14px 16px; }
.ml-history-period__summary::-webkit-details-marker { display: none; }
.ml-history-period__summary::before { content: '▸'; color: var(--ink-4); font-size: 11px; transition: transform .15s; }
.ml-history-period[open] > .ml-history-period__summary::before { transform: rotate(90deg); }
.ml-history-period__summary:hover { background: var(--surface); }
.ml-history-period__summary > span:first-child { flex: 1; color: var(--ink); }
.ml-history-period__stat { font-size: 13px; color: var(--ink-3); }
.ml-history-period .ml-pay-table-wrap { margin: 0; border: none; border-top: 1px solid var(--line); border-radius: 0; box-shadow: none; }

.ml-pay-history-label-row { display: flex; justify-content: space-between; align-items: center; margin-bottom: 12px; }
.ml-pay-history-label-row .ml-pay-history-label { margin-bottom: 0; }
.ml-print-link { font-size: 11.5px; color: var(--sky); white-space: nowrap; }
.ml-print-link:hover { text-decoration: underline; }
.ml-print-links { display: flex; gap: 16px; align-items: center; }

/* ── Phase 7: form helpers ───────────────────────────────────────── */
.field-group       { display: flex; flex-direction: column; margin-bottom: 14px; }
.field-error       { font-size: 11px; color: var(--red); margin-top: 4px; }

/* Searchable worker combobox — a plain <select> doesn't scale past a handful of
   workers. The visible text input + hidden field is the actual form value; the
   list below it is pre-rendered server-side and just shown/hidden by JS. */
.ml-combobox        { position: relative; }
.ml-combobox-list {
  position: absolute; top: 100%; left: 0; right: 0; margin-top: 4px;
  background: var(--white); border: 1px solid var(--line); border-radius: var(--r-md);
  box-shadow: var(--sh-md); max-height: 220px; overflow-y: auto; z-index: 20;
}
.ml-combobox-item {
  padding: 9px 14px; font-size: 13.5px; color: var(--ink); cursor: pointer;
}
.ml-combobox-item:hover, .ml-combobox-item.is-active { background: var(--surface); }
.ml-combobox-empty { padding: 9px 14px; font-size: 13px; color: var(--ink-4); font-style: italic; }

/* ── Phase 7: pending badge ─────────────────────────────────────── */
.badge--pending    { background: var(--amber-bg); color: var(--amber-deep); }

/* ── Phase 7: revenue / spend summary bar ───────────────────────── */
.ml-payroll-bar {
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  padding: 14px 20px;
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.ml-payroll-bar__label  { font-size: 11px; font-weight: 700; color: var(--ink-3); text-transform: uppercase; letter-spacing: .08em; }
.ml-payroll-bar__amount { font-size: 22px; font-weight: 700; font-family: var(--mono); color: var(--ink); }

/* ── Phase 7: dialog section divider ────────────────────────────── */
.ml-dialog__section-label {
  font-size: 10.5px;
  font-weight: 700;
  color: var(--ink-3);
  text-transform: uppercase;
  letter-spacing: .08em;
  margin: 4px 0 10px;
  padding-top: 8px;
  border-top: 1px solid var(--line);
}

/* ════════════════════════════════════════════════════════════════
   UTILITY — TEXT
   ════════════════════════════════════════════════════════════════ */
.t-right   { text-align: right; }
.t-center  { text-align: center; }
.bold      { font-weight: 600; }
.bold-7    { font-weight: 700; }
.f-11      { font-size: 11px; }
.f-12      { font-size: 12px; }
.f-13      { font-size: 13px; }
.f-14      { font-size: 14px; }
.txt-ink3  { color: var(--ink-3); }
.txt-ink4  { color: var(--ink-4); }
.txt-red   { color: var(--red); }
.txt-amber { color: var(--amber); }
.txt-amber-deep { color: var(--amber-deep); }
.txt-green { color: var(--green); }
.txt-sky   { color: var(--sky); }
.req       { color: var(--red); }
.link-amber      { color: var(--amber-deep); font-weight: 600; }
.link-amber:hover { color: var(--amber); }
.link-red        { color: var(--red); text-decoration: underline; }

/* ════════════════════════════════════════════════════════════════
   UTILITY — SPACING
   ════════════════════════════════════════════════════════════════ */
.mb-14 { margin-bottom: 14px; }
.mb-18 { margin-bottom: 18px; }
.mb-16 { margin-bottom: 16px; }
.mb-20 { margin-bottom: 20px; }
.mb-24 { margin-bottom: 24px; }
.mb-28 { margin-bottom: 28px; }
.mt-8  { margin-top: 8px; }
.mt-10 { margin-top: 10px; }
.mt-32 { margin-top: 32px; }
.w-140 { width: 140px; }

/* ════════════════════════════════════════════════════════════════
   UTILITY — LAYOUT
   ════════════════════════════════════════════════════════════════ */
.max-w-780     { max-width: 780px; }
.overflow-h    { overflow: hidden; }
.span-full     { grid-column: 1 / -1; }
.grid-2        { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.grid-3        { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 12px; }
.flex-baseline { display: flex; align-items: baseline; gap: 8px; }
.flex-between  { display: flex; justify-content: space-between; align-items: center; }
.d-block       { display: block; }

/* ════════════════════════════════════════════════════════════════
   FORM: SECTION TITLE  ("Basic Information", "Assignment", etc.)
   ════════════════════════════════════════════════════════════════ */
.form-section-title {
  font-size: 11px; font-weight: 700; letter-spacing: .06em;
  color: var(--ink-3); text-transform: uppercase;
  margin-bottom: 14px; margin-top: 8px;
}
.form-section-title--first { margin-top: 0; }

/* ════════════════════════════════════════════════════════════════
   FORM: HINTS & SUB-LABELS
   ════════════════════════════════════════════════════════════════ */
.field-hint { font-size: 11px; color: var(--ink-4); margin-top: 4px; }
.field-sub  { font-size: 11px; color: var(--ink-3); margin-bottom: 2px; }

/* ════════════════════════════════════════════════════════════════
   FORM: FOOTER  (dialog / card action row)
   ════════════════════════════════════════════════════════════════ */
.form-footer {
  display: flex; gap: 12px; justify-content: flex-end;
  padding-top: 12px; border-top: 1px solid var(--line);
}
.form-footer--pt8 { padding-top: 8px; }

/* ════════════════════════════════════════════════════════════════
   WORKER IDENTITY ROW  (edit-worker page ID/NID chip)
   ════════════════════════════════════════════════════════════════ */
.worker-id-row {
  display: flex; gap: 24px; padding: 12px 14px;
  background: var(--surface); border-radius: 8px;
  margin-bottom: 20px; border: 1px solid var(--line);
}
.worker-id-row__sub   { font-size: 11px; color: var(--ink-3); margin-bottom: 2px; }
.worker-id-row__value { font-size: 12px; }

/* ════════════════════════════════════════════════════════════════
   STAT CARDS ROW  (equipment / maintenance / mechanics summary)
   ════════════════════════════════════════════════════════════════ */
.stat-cards {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: 14px; margin-bottom: 25px;
}
.stat-card {
  padding: 18px;
  transition: box-shadow var(--dur) var(--ease), transform var(--dur) var(--ease), border-color var(--dur) var(--ease);
}
.stat-card:hover {
  box-shadow: var(--sh-card-hover);
  transform: translateY(-3px);
  border-color: var(--surface-3);
}

/* Icon chip — sits above the label, one soft-tinted square per card so the
   four cards read as distinct at a glance instead of four identical boxes
   that only differ by number. */
.stat-card__icon {
  width: 29px; height: 29px;
  display: flex; align-items: center; justify-content: center;
  border-radius: 8px;
  margin-bottom: 9px;
  background: var(--surface-2); color: var(--ink-3);
}
.stat-card__icon svg { width: 14px; height: 14px; }
.stat-card__icon--blue  { background: var(--blue-bg);  color: var(--blue); }
.stat-card__icon--amber { background: var(--amber-bg); color: var(--amber-deep); }
.stat-card__icon--sky   { background: var(--sky-bg);   color: var(--sky); }
.stat-card__icon--green { background: var(--green-bg); color: var(--green-deep); }

.stat-card__label {
  font-size: 10px; font-weight: 600; color: var(--ink-3);
  text-transform: uppercase; letter-spacing: .06em; margin-bottom: 5px;
}
.stat-card__label--green  { color: var(--green-deep); }
.stat-card__label--amber  { color: var(--amber-deep); }
.stat-card__label--red    { color: var(--red); }
.stat-card__label--sky    { color: var(--sky); }

.stat-card__value {
  font-family: var(--mono); font-size: 25px; font-weight: 700;
  color: var(--ink); line-height: 1; font-variant-numeric: tabular-nums;
}
.stat-card__value--green  { color: var(--green-deep); }
.stat-card__value--amber  { color: var(--amber-deep); }
.stat-card__value--red    { color: var(--red); }
.stat-card__value--sky    { color: var(--sky); }

.stat-card__sub { font-size: 11px; color: var(--ink-4); margin-top: 4px; }

/* ════════════════════════════════════════════════════════════════
   DASHBOARD LAYOUT
   ════════════════════════════════════════════════════════════════ */
.dash-row       { display: grid; gap: 12px; margin-bottom: 16px; }
.dash-row--auto { grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); }
.dash-row--3    { grid-template-columns: 1fr 1fr 1fr; }
.dash-row--2    { grid-template-columns: 1fr 1fr; margin-bottom: 0; }

/* Card sub-label (uppercase section title inside a card) */
.dash-label          { font-size: 11px; font-weight: 700; letter-spacing: .06em; color: var(--ink-3); text-transform: uppercase; margin-bottom: 10px; }
.dash-label--12      { margin-bottom: 12px; }
.dash-label--8       { margin-bottom: 8px; }
.dash-label--amber   { color: var(--amber); }

/* Large stat numbers — neutral by default; green/red reserved for a real
   financial direction (money in vs money out), not decoration. */
.dash-num        { font-size: 32px; font-weight: 700; line-height: 1; color: var(--ink); }
.dash-num--28    { font-size: 28px; }
.dash-num--30    { font-size: 30px; }
.dash-num--24    { font-size: 24px; }
.dash-num--green { color: var(--green); }
.dash-num--red   { color: var(--red); }

.dash-num-row    { display: flex; align-items: baseline; gap: 8px; }
.dash-num-sub    { font-size: 12px; color: var(--ink-4); }

/* Caption line below a number — always neutral; the number above it (or a
   dot in a mini-stat) is what carries any real status, not the caption. */
.dash-caption          { font-size: 11px; margin-top: 6px; color: var(--ink-4); }
.dash-caption--mt10    { margin-top: 10px; }
.dash-caption--mb10    { margin-bottom: 10px; }

.dash-date { font-size: 12px; color: var(--ink-4); margin-top: 2px; }

/* Flex split rows (attendance / equipment status) */
.dash-split    { display: flex; gap: 10px; }
.dash-split--8 { gap: 8px; }

/* Mini-stat inside attendance / equipment cards: neutral surface, a small
   coloured dot carries the status instead of a full-colour fill — one
   consistent pattern instead of a different treatment per card. */
.dash-mini          { flex: 1; border-radius: 8px; padding: 12px; text-align: center; background: var(--surface-2); }
.dash-mini--sm       { padding: 10px 6px; }

.dash-mini__label    { display: flex; align-items: center; justify-content: center; gap: 5px; font-size: 10px; font-weight: 700; text-transform: uppercase; color: var(--ink-3); margin-bottom: 4px; }
.dash-mini__label--9 { font-size: 9px; }

.dash-mini__dot         { width: 6px; height: 6px; border-radius: 50%; flex-shrink: 0; }
.dash-mini__dot--green  { background: var(--green); }
.dash-mini__dot--red    { background: var(--red); }
.dash-mini__dot--amber  { background: var(--amber-deep); }

.dash-mini__num      { font-weight: 700; line-height: 1; color: var(--ink); }
.dash-mini__num--28  { font-size: 28px; }
.dash-mini__num--24  { font-size: 24px; }

/* Equipment page link */
.dash-eq-link { font-size: 11px; color: var(--amber); margin-top: 10px; display: block; }

/* Payroll hero card */
.dash-payroll-card    { border: 1px solid rgba(217,119,6,.3); background: linear-gradient(135deg,#fffbeb 0%,#fff 100%); }
.dash-payroll-num     { font-size: 30px; font-weight: 700; color: var(--amber); line-height: 1; margin-bottom: 4px; }
.dash-payroll-dates   { font-size: 11px; color: var(--ink-4); margin-bottom: 10px; }
.dash-payroll-link    { font-size: 11px; color: var(--amber); }

/* Recent activity card header */
.dash-card-hd         { padding: 16px 18px; border-bottom: 1px solid var(--line); display: flex; justify-content: space-between; align-items: center; }
.dash-card-hd__title  { font-weight: 600; font-size: 14px; }
.dash-card-hd__sub    { font-size: 11px; color: var(--ink-4); }
.dash-card-hd__link   { font-size: 11px; color: var(--amber); }
.dash-card-empty      { padding: 24px; text-align: center; color: var(--ink-4); font-size: 13px; }

/* ════════════════════════════════════════════════════════════════
   TABLE HELPERS
   ════════════════════════════════════════════════════════════════ */
.td-empty { text-align: center; color: var(--ink-4); padding: 32px; }

/* ════════════════════════════════════════════════════════════════
   IN-TABLE FORM CONTROLS
   ════════════════════════════════════════════════════════════════ */
.flex-row   { display: flex; align-items: center; gap: 6px; }
.select-sm  { font-size: 12px !important; padding: 4px 8px !important; height: auto !important; }
.input-sm   { font-size: 12px !important; padding: 4px 8px !important; height: auto !important; width: 72px !important; }
.btn.btn-xs { font-size: 11px; padding: 4px 10px; }

/* ════════════════════════════════════════════════════════════════
   MISC UTILITY
   ════════════════════════════════════════════════════════════════ */
.ml-8        { margin-left: 8px; }
.underline   { text-decoration: underline; }
.no-underline { text-decoration: none; }
.nowrap      { white-space: nowrap; }
.opacity-85  { opacity: .85; }
.form-inline { display: inline; }
.full-w      { width: 100%; box-sizing: border-box; }

/* Workers page: name + daily rate link */
.worker-name-link { font-family: var(--mono); font-size: 13px; font-weight: 600; color: var(--ink); text-decoration: none; }
.worker-rate-link { font-size: 12px; color: var(--amber-deep); font-weight: 600; text-decoration: underline; white-space: nowrap; }

/* ════════════════════════════════════════════════════════════════
   SIDEBAR GROUP SPACER + AVATAR SIZES
   ════════════════════════════════════════════════════════════════ */
.sidebar-nav__group--mt { margin-top: 6px; }
.avatar--sm { width: 28px; height: 28px; border-radius: 7px; font-size: 11px; flex-shrink: 0; }

/* Extra sizing utilities */
.max-w-540   { max-width: 540px; }
.w-220       { width: 220px; }
.min-w-140   { min-width: 140px; }
.lh-125      { line-height: 1.25; }

/* ════════════════════════════════════════════════════════════════
   MOBILE APP SHELL  (2026-09-14)
   The sidebar was a fixed 248px column baked directly into the shell's
   grid (--sidebar-w, near the top of this file) with no mobile fallback
   — on a ~375px phone that alone left barely a third of the screen for
   actual content, on top of dash-row--2/--3 and grid-2/grid-3 forcing
   multiple fixed columns into whatever was left. Below 880px the sidebar
   now becomes an off-canvas drawer (hidden by default, slides in over the
   content when the topbar's hamburger button is tapped) so content gets
   the full screen width, and the fixed-column grids collapse to one
   column like .ml-pay-kpi-row already did above.
   ════════════════════════════════════════════════════════════════ */

.ml-hamburger {
  display: none;
  align-items: center; justify-content: center;
  width: 36px; height: 36px;
  border-radius: 8px; border: 1px solid var(--line);
  background: var(--white); color: var(--ink-2);
  flex-shrink: 0; cursor: pointer;
}
.ml-hamburger svg { width: 18px; height: 18px; }
.ml-hamburger:active { background: var(--surface); }

.ml-sidebar-backdrop {
  display: none;
  position: fixed; inset: 0;
  background: rgba(15, 23, 42, .45);
  z-index: 150;
}
.ml-sidebar-backdrop.is-open { display: block; }

@media (max-width: 880px) {
  .ml-shell, .app-shell { grid-template-columns: 1fr; }

  .ml-sidebar, .app-sidebar {
    position: fixed; top: 0; left: 0; bottom: 0;
    width: min(280px, 82vw);
    transform: translateX(-100%);
    transition: transform var(--dur) var(--ease);
    z-index: 200;
    box-shadow: var(--sh-card-hover);
  }
  .ml-sidebar.is-open, .app-sidebar.is-open { transform: translateX(0); }

  .ml-hamburger { display: inline-flex; }

  .ml-content, .app-main { padding: 16px 16px 40px; }
  .ml-topbar, .topbar { padding: 0 14px; gap: 10px; }
  .topbar__org { display: none; }
  .topbar__slash { display: none; }

  .dash-row--3, .dash-row--2,
  .grid-2, .grid-3,
  .ml-form-grid, .ml-form-grid--3 {
    grid-template-columns: 1fr;
  }
}
.form-bare   { margin: 0; padding: 0; }

/* ── Owner payroll: money story card (2026-10-01) ─────────────────────────────
   One card that reads top to bottom like a payslip for the whole cooperative:
   what workers earned, what came off their pay, what they received — and, beside
   it, where every franc of the payroll cost goes. Replaces the four KPI tiles,
   which did not add up (gross − advances never equalled the net shown). */
.ml-paysum__head   { display: flex; justify-content: space-between; align-items: flex-start;
                     gap: 16px; flex-wrap: wrap; margin-bottom: 18px; }
.ml-paysum__period { font-size: 17px; font-weight: 700; color: var(--ink); }
.ml-paysum__status { font-size: 13px; color: var(--ink-3); margin-top: 4px; }
.ml-paysum__status--paid { color: var(--green-deep, #15803D); font-weight: 600; }
.ml-paysum__grid   { display: grid; grid-template-columns: 1fr 1fr; gap: 28px; }
@media (max-width: 900px) { .ml-paysum__grid { grid-template-columns: 1fr; } }
.ml-paysum__col-title { font-size: 11px; font-weight: 700; letter-spacing: .06em;
                        text-transform: uppercase; color: var(--ink-3); margin-bottom: 8px; }
.ml-paysum__row    { display: flex; justify-content: space-between; gap: 12px;
                     padding: 6px 0; font-size: 14px; color: var(--ink-2); }
.ml-paysum__row span:last-child { font-variant-numeric: tabular-nums; white-space: nowrap; }
.ml-paysum__row--minus { color: var(--ink-3); padding-left: 14px; }
.ml-paysum__row--total { border-top: 1px solid var(--line); margin-top: 6px; padding-top: 10px;
                         font-weight: 700; font-size: 16px; color: var(--ink); }
.ml-paysum__note   { font-size: 12px; color: var(--ink-4); margin-top: 10px; line-height: 1.5; }
.ml-paysum__alerts { margin-top: 16px; }
/* No double underscore in these two: inside a th: attribute, __…__ is Thymeleaf
   pre-processing syntax, and two such class names in one expression broke parsing. */
.ml-paysum-zero td, .ml-paysum-zero td * { color: var(--ink-4) !important; font-weight: 400 !important; }
.ml-paysum-current td { background: var(--surface-2); }
.ml-paysum-current td:first-child { box-shadow: inset 3px 0 0 var(--green); }

/* ── Payroll as the cooperative's sheet (2026-10-01) ─────────────────────────
   One block per sheet (site / per-round position), same 21 columns as the bank
   Excel. Wide on purpose — it scrolls sideways inside its own box, never the page. */
.ml-sheet { border: 1px solid var(--line); border-radius: var(--r-md); background: var(--white);
            margin-bottom: 18px; box-shadow: var(--sh-sm); }
.ml-sheet__head { display: flex; flex-wrap: wrap; align-items: baseline; gap: 6px 14px;
                  padding: 12px 16px; border-bottom: 1px solid var(--line); }
.ml-sheet__name { font-size: 15px; font-weight: 700; color: var(--ink); }
.ml-sheet__meta { font-size: 12.5px; color: var(--ink-3); }
.ml-sheet__scroll { overflow-x: auto; }
.ml-sheet__table { border-collapse: collapse; font-size: 12.5px; min-width: 100%; }
.ml-sheet__table th, .ml-sheet__table td { border: 1px solid var(--line-soft); padding: 6px 9px;
                  white-space: nowrap; color: var(--ink); }
.ml-sheet__table th { font-size: 11px; font-weight: 700; background: var(--surface); color: var(--ink-2, var(--ink)); }
.ml-sheet__table td.t-num { text-align: right; font-variant-numeric: tabular-nums; }
.ml-sheet__table tfoot td { font-weight: 700; background: var(--surface); }
.ml-sheet__table td.ml-sheet__deposit { background: var(--amber-bg); }
.ml-sheet__worker { position: sticky; left: 0; background: var(--white); }
.ml-sheet__table th:nth-child(2) { position: sticky; left: 0; z-index: 1; }
.ml-sheet__off { margin: 6px 0 18px; font-size: 13px; color: var(--ink-3); }
.ml-sheet__off summary { cursor: pointer; font-weight: 600; }
.ml-sheet__off ul { margin: 8px 0 0 18px; columns: 2; }
@media (max-width: 700px) { .ml-sheet__off ul { columns: 1; } }

/* ── Owner: Salary Advances page (2026-10-04) ────────────────────────────────
   Two cards under a row of figures. Every block sits 24px from the next so the
   page reads top to bottom without crowding; the table headings live INSIDE their
   card, and the filter tabs sit on the history card's header, not under it. */
.ml-adv-notice { display: flex; align-items: center; justify-content: space-between; gap: 16px;
                 flex-wrap: wrap; margin-bottom: 24px; }
.ml-adv-notice a { font-weight: 600; white-space: nowrap; }
.ml-adv-card { background: var(--white); border: 1px solid var(--line); border-radius: var(--r-md);
               box-shadow: var(--sh-sm); margin-bottom: 24px; overflow: hidden; }
.ml-adv-card__head { display: flex; align-items: center; justify-content: space-between;
                     flex-wrap: wrap; gap: 10px 16px; padding: 16px 20px;
                     border-bottom: 1px solid var(--line); }
.ml-adv-card__head h3 { margin: 0; font-size: 16px; font-weight: 700; color: var(--ink); }
.ml-adv-card__count { font-size: 12px; color: var(--ink-3); }
.ml-adv-card__head .ml-filter-tabs { margin: 0; }
.ml-adv-scroll { overflow-x: auto; }
.ml-adv-scroll .ml-table { width: 100%; }
.ml-adv-scroll .ml-table th.ml-adv-num,
.ml-adv-scroll .ml-table td.ml-adv-num { text-align: right; white-space: nowrap;
                                         font-variant-numeric: tabular-nums; width: 130px; }
.ml-adv-scroll .ml-table th.ml-adv-narrow,
.ml-adv-scroll .ml-table td.ml-adv-narrow { width: 90px; }
.ml-adv-scroll .ml-table th.ml-adv-state,
.ml-adv-scroll .ml-table td.ml-adv-state { width: 150px; }
.ml-adv-name { font-weight: 600; color: var(--ink); }
.ml-adv-sub { display: block; margin-top: 2px; font-size: 12px; color: var(--ink-3); font-weight: 400; }
.ml-adv-zero { color: var(--ink-4); }
.ml-adv-empty { padding: 36px 20px; text-align: center; font-size: 14px; color: var(--ink-3); }
.ml-adv-card .ml-table { margin: 0; }
.ml-adv-weeknav { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; flex-shrink: 0; }
.ml-adv-weeknav__label { display: inline-flex; align-items: center; gap: 8px; font-size: 14px;
                         font-weight: 700; color: var(--ink); white-space: nowrap; }

/* "Corrected" tag (2026-10-04): the figure beside it is already the right one; the old
   numbers open on click. A plain <details>, so it needs no script under the CSP. */
.ml-corrected { display: inline-block; margin-left: 6px; vertical-align: middle; }
.ml-corrected > summary { cursor: pointer; list-style: none; }
.ml-corrected > summary::-webkit-details-marker { display: none; }
.ml-corrected__list { margin: 8px 0 0; padding: 8px 12px; list-style: none; max-width: 420px;
                      background: var(--surface-2); border-radius: var(--r-md);
                      font-size: 12px; font-weight: 400; color: var(--ink-3); line-height: 1.5; }
.ml-corrected__list li + li { margin-top: 6px; }

/* ── Search above every list (2026-10-05) ────────────────────────────────────
   Added by table-search.js. A quiet bar above the table; rows that do not match are
   hidden with a class (no inline styles — the CSP forbids them). */
.ml-search-hidden { display: none !important; }
.ml-search { position: relative; display: flex; align-items: center; gap: 10px; margin: 0 0 12px; max-width: 420px; }
.ml-search > svg { position: absolute; left: 12px; width: 16px; height: 16px; color: var(--ink-4); pointer-events: none; }
.ml-search__input { flex: 1; min-width: 0; height: 36px; padding: 0 12px 0 36px; font-size: 13px;
                    color: var(--ink); background: var(--white); border: 1px solid var(--line);
                    border-radius: var(--r-md); outline: none; font-family: inherit; }
.ml-search__input:focus { border-color: var(--green); box-shadow: 0 0 0 3px var(--green-bg); }
.ml-search__input::placeholder { color: var(--ink-4); }
.ml-search__count { font-size: 12px; color: var(--ink-3); white-space: nowrap; }
.ml-search__none { padding: 28px 16px; text-align: center; font-size: 14px; color: var(--ink-3); }
/* Inside a card (advances, corrections) the bar sits under the card's heading. */
.ml-adv-card .ml-search { max-width: none; margin: 0; padding: 12px 20px; border-bottom: 1px solid var(--line); }
.ml-adv-card .ml-search > svg { left: 32px; }
.ml-adv-card .ml-search__input { max-width: 380px; }

/* Staff activity report (2026-10-05) */
.ml-adv-filter { display: flex; flex-wrap: wrap; align-items: center; gap: 10px 12px; margin-bottom: 18px; }
.ml-adv-filter label { font-size: 13px; color: var(--ink-3); }
.ml-adv-filter .input { width: auto; max-width: 170px; }
.ml-adv-notice-inline { padding: 10px 20px; font-size: 13px; color: var(--amber-deep); background: var(--amber-bg); }

/* ── Who worked, split by gender (fragments/headcount.html) ─────────────── */
.ml-headcount { display: flex; flex-wrap: wrap; gap: 8px 22px; margin-top: 12px; padding-top: 12px; border-top: 1px solid var(--line-soft); }
.ml-headcount-bar { margin: 0 0 16px; padding: 4px 18px 14px; border: 1px solid var(--line); border-radius: 10px; background: var(--white); }
.ml-headcount-bar .ml-headcount { margin-top: 10px; padding-top: 0; border-top: 0; }
.ml-headcount__item { display: flex; flex-direction: column; gap: 2px; }
.ml-headcount__num { font-size: 20px; font-weight: 700; color: var(--ink); font-variant-numeric: tabular-nums; }
.ml-headcount__label { font-size: 12px; color: var(--ink-3); }
.ml-headcount__item--muted .ml-headcount__num { color: var(--ink-3); }
.ml-headcount__positions { flex-basis: 100%; display: flex; flex-wrap: wrap; gap: 6px 8px; padding-top: 10px; border-top: 1px dashed var(--line-soft); }
.ml-headcount__pos { font-size: 12px; color: var(--ink-2); background: var(--line-soft); border-radius: 999px; padding: 3px 10px; }
.ml-headcount__pos b { color: var(--ink); margin-right: 3px; font-variant-numeric: tabular-nums; }

/* ── Worker details page (fragments/worker-card.html) ───────────────────── */
.ml-worker-card { display: grid; gap: 16px; max-width: 780px; }
.ml-worker-card__title { font-size: 12px; letter-spacing: .06em; text-transform: uppercase; color: var(--ink-3); margin: 0 0 12px; }
.ml-worker-card__note { font-size: 13px; color: var(--ink-2); margin: 0 0 10px; }
.ml-dl { display: grid; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); gap: 14px 24px; margin: 0; }
.ml-dl dt { font-size: 12px; color: var(--ink-3); margin-bottom: 2px; }
.ml-dl dd { margin: 0; font-size: 14px; color: var(--ink); overflow-wrap: anywhere; }
.ml-worker-actions { display: flex; gap: 8px; flex-wrap: wrap; }
.ml-worker-link { color: inherit; text-decoration: none; font-weight: inherit; cursor: pointer; }
.ml-worker-link:hover { color: var(--accent, #1E3A5F); }

.ml-site-fixed { font-weight: 600; font-size: 14px; color: var(--ink); padding: 8px 0; }

/* ── Workers grouped by mine ─────────────────────────────────────────────── */
.ml-site-heading { display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 8px 16px; margin: 22px 0 10px; }
.ml-site-heading--all { margin-top: 4px; padding: 12px 16px; border: 1px solid var(--line); border-radius: 10px; background: var(--white); }
.ml-site-heading .ml-site-group-heading { margin: 0; font-size: 16px; }
.ml-site-counts { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; }
.ml-site-total { font-size: 13px; font-weight: 600; color: var(--ink-2); }
.ml-empty--compact { padding: 18px 16px; text-align: center; }

/* ═══ Owner dashboard, Option A — every figure split by mine (2026-10-06) ═══ */
:root { --mine-1:#2A6FB5; --mine-2:#D9961A; --mine-3:#7A5BB8; --mine-4:#0E9AA7; --mine-5:#C2477B; --mine-6:#6B7E96; }
.dx-bar-row { display:flex; flex-wrap:wrap; align-items:center; justify-content:space-between; gap:10px 16px; margin-bottom:16px; }
.dx-seg-nav { display:inline-flex; flex-wrap:wrap; gap:2px; padding:4px; background:var(--surface-2); border-radius:12px; }
.dx-seg-nav a { display:inline-flex; align-items:center; font-size:13px; font-weight:600; color:var(--ink-2); padding:8px 14px; border-radius:9px; text-decoration:none; }
.dx-seg-nav a.is-on { background:var(--white); color:var(--ink); box-shadow:0 1px 2px rgba(15,23,42,.08); }
.dx-seg-nav a:hover:not(.is-on) { color:var(--ink); }
.dx-scope { font-size:12.5px; color:var(--ink-3); }
.dx-dot { display:inline-block; width:9px; height:9px; border-radius:50%; margin-right:6px; flex:none; background:var(--ink-4); }
.dx-dot.c1 { background:var(--mine-1); } .dx-dot.c2 { background:var(--mine-2); } .dx-dot.c3 { background:var(--mine-3); }
.dx-dot.c4 { background:var(--mine-4); } .dx-dot.c5 { background:var(--mine-5); } .dx-dot.c6 { background:var(--mine-6); }
.dx-dot--ok { background:var(--green); } .dx-dot--warn { background:var(--amber-deep); } .dx-dot--bad { background:var(--red); }
.dx-grid4 { display:grid; grid-template-columns:repeat(4,minmax(0,1fr)); gap:16px; margin-bottom:16px; }
.dx-grid-2-1 { display:grid; grid-template-columns:minmax(0,3fr) minmax(0,2fr); gap:16px; margin-bottom:16px; }
.dx-grid-1-2 { display:grid; grid-template-columns:minmax(230px,1fr) minmax(0,3.6fr); gap:16px; margin-bottom:16px; align-items:start; }
.dx-lbl { font-size:11.5px; font-weight:700; letter-spacing:.07em; text-transform:uppercase; color:var(--ink-3); }
.dx-big { font-size:30px; font-weight:700; letter-spacing:-.02em; line-height:1.1; margin-top:8px; }
.dx-unit { font-size:13px; font-weight:500; color:var(--ink-3); margin-left:5px; letter-spacing:0; }
.dx-cap { font-size:12px; color:var(--ink-3); margin:2px 0 14px; }
.dx-hd { display:flex; align-items:flex-start; justify-content:space-between; gap:8px 16px; flex-wrap:wrap; margin-bottom:12px; }
.dx-hd .dx-cap { margin-bottom:0; }
.dx-bar { display:block; width:100%; height:9px; border-radius:99px; overflow:hidden; }
.dx-bar--thin { height:8px; }
.dx-bar__track { fill:var(--surface-2); }
.dx-seg { stroke:var(--white); stroke-width:.5; }
.dx-seg.c0 { fill:var(--ink-4); }
.dx-seg.c1 { fill:var(--mine-1); } .dx-seg.c2 { fill:var(--mine-2); } .dx-seg.c3 { fill:var(--mine-3); }
.dx-seg.c4 { fill:var(--mine-4); } .dx-seg.c5 { fill:var(--mine-5); } .dx-seg.c6 { fill:var(--mine-6); }
.dx-legend { display:flex; flex-wrap:wrap; gap:4px 14px; margin-top:9px; font-size:12px; color:var(--ink-2); }
.dx-legend > span { display:inline-flex; align-items:center; white-space:nowrap; }
.dx-legend b { margin-left:5px; font-weight:600; color:var(--ink); }
.dx-legend--tight { margin-top:0; }
.dim { opacity:.28; }
.dx-note { margin-top:10px; font-size:11.5px; color:var(--ink-3); }
.dx-link { display:inline-block; margin-top:12px; font-size:13px; }
.dx-chart svg { display:block; width:100%; height:auto; }
.dx-grid { stroke:var(--line); stroke-width:1; }
.dx-axis { font-size:11px; fill:var(--ink-3); }
.dx-area { fill-opacity:.78; stroke:var(--white); stroke-width:1.2; }
.dx-area.c1 { fill:var(--mine-1); } .dx-area.c2 { fill:var(--mine-2); } .dx-area.c3 { fill:var(--mine-3); }
.dx-area.c4 { fill:var(--mine-4); } .dx-area.c5 { fill:var(--mine-5); } .dx-area.c6 { fill:var(--mine-6); }
.dx-end { fill:var(--ink); stroke:var(--white); stroke-width:2; }
.dx-rows { margin-top:14px; padding-top:10px; border-top:1px solid var(--line-soft); display:grid; gap:2px; }
.dx-row { display:grid; grid-template-columns:minmax(0,1.1fr) minmax(0,1.6fr) auto; gap:12px; align-items:center; padding:6px 0; font-size:13px; }
.dx-row__name { display:inline-flex; align-items:center; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.dx-row__val { font-size:12px; color:var(--ink-3); }
.dx-scroll { overflow-x:auto; }
.dx-table td, .dx-table th { white-space:nowrap; }
.dx-table tfoot td { padding:15px 20px; font-size:14.5px; font-weight:700; color:var(--ink); background:var(--surface-2); border-top:1px solid var(--line); vertical-align:middle; }
.dx-equip { display:flex; flex-wrap:wrap; align-items:center; gap:10px 28px; }
.dx-equip__nums { display:flex; flex-wrap:wrap; gap:6px 22px; font-size:13px; color:var(--ink-2); }
.dx-equip__nums span { display:inline-flex; align-items:center; }
.dx-equip__nums b { margin-left:6px; color:var(--ink); font-size:16px; }
.dx-equip .dx-link { margin:0 0 0 auto; }
@media (max-width:1100px) { .dx-grid4 { grid-template-columns:repeat(2,minmax(0,1fr)); } .dx-grid-2-1, .dx-grid-1-2 { grid-template-columns:minmax(0,1fr); } }
@media (max-width:560px) { .dx-grid4 { grid-template-columns:minmax(0,1fr); } .dx-big { font-size:26px; } }

.dx-n { font-variant-numeric: tabular-nums; font-family: inherit; }

/* Production by mineral (coltan, cassiterite, other) — colours kept apart from the mine colours */
:root { --mineral-coltan:#4B5B8C; --mineral-cassiterite:#A9742F; --mineral-other:#8A97A8; }
.dx-seg.k-coltan, .dx-dot.k-coltan { fill:var(--mineral-coltan); background:var(--mineral-coltan); }
.dx-seg.k-cassiterite, .dx-dot.k-cassiterite { fill:var(--mineral-cassiterite); background:var(--mineral-cassiterite); }
.dx-seg.k-other, .dx-dot.k-other { fill:var(--mineral-other); background:var(--mineral-other); }
.dx-seg.k-coltan, .dx-seg.k-cassiterite, .dx-seg.k-other { background:none; }
.dx-mix { margin-top:14px; padding-top:12px; border-top:1px solid var(--line-soft); }
.dx-mix__title { font-size:11px; font-weight:700; letter-spacing:.07em; text-transform:uppercase; color:var(--ink-3); margin-bottom:7px; }

.dx-gridauto { display:grid; grid-template-columns:repeat(auto-fit,minmax(250px,1fr)); gap:16px; margin-bottom:16px; }

.dx-single { max-width:640px; margin-bottom:16px; }

:root { --mineral-mixed:#7E7A52; }
.dx-seg.k-mixed, .dx-dot.k-mixed { fill:var(--mineral-mixed); background:var(--mineral-mixed); }
.dx-seg.k-mixed { background:none; }

/* ═══ Dashboard for many mines: search dropdown, top-3 tiles, sortable mine table (2026-10-07) ═══ */
:root { --mine-6:#9AA9BC; }
.dx-picker { position:relative; }
.dx-picker summary { list-style:none; cursor:pointer; display:inline-flex; align-items:center; gap:2px; padding:10px 14px; border:1px solid var(--line); border-radius:12px; background:var(--white); font-weight:600; font-size:14px; box-shadow:0 1px 2px rgba(15,23,42,.05); }
.dx-picker summary::-webkit-details-marker { display:none; }
.dx-picker summary::after { content:"▾"; color:var(--ink-3); font-size:12px; margin-left:10px; }
.dx-picker__menu { position:absolute; z-index:20; margin-top:6px; width:min(380px, calc(100vw - 32px)); background:var(--white); border:1px solid var(--line); border-radius:12px; box-shadow:0 12px 32px rgba(15,23,42,.18); padding:10px; }
.dx-picker__search { width:100%; padding:9px 11px; border:1px solid var(--line); border-radius:9px; background:var(--surface); color:var(--ink); font:inherit; margin-bottom:8px; }
.dx-picker__list { list-style:none; margin:0; padding:0; max-height:320px; overflow:auto; }
.dx-picker__list a { display:flex; justify-content:space-between; align-items:center; gap:10px; padding:8px 9px; border-radius:8px; color:var(--ink); text-decoration:none; font-size:13.5px; }
.dx-picker__list a:hover, .dx-picker__list a.is-on { background:var(--surface-2); }
.dx-picker__list small { color:var(--ink-3); font-size:12px; white-space:nowrap; }
.dx-picker__none { padding:8px 9px; font-size:13px; color:var(--ink-3); }
.dx-top3 { display:grid; gap:5px; font-size:13px; margin-top:2px; }
.dx-top3 > div { display:flex; align-items:center; justify-content:space-between; gap:8px; }
.dx-top3 > div > span { display:inline-flex; align-items:center; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.dx-top3 b { font-weight:600; color:var(--ink); }
.dx-more { margin-top:9px; font-size:12px; color:var(--ink-3); }
.dx-col { display:grid; gap:16px; align-content:start; min-width:0; }
.dx-morerows { margin-top:4px; }
.dx-morerows summary { cursor:pointer; font-size:12.5px; font-weight:600; color:var(--ink-2); padding:6px 0; }
.dx-toggle { display:inline-flex; align-items:center; gap:8px; font-size:12.5px; color:var(--ink-2); cursor:pointer; }
.dx-table th.dx-sortable { cursor:pointer; user-select:none; }
.dx-table th.dx-sortable:hover { color:var(--ink); }
.dx-table th[aria-sort="descending"]::after { content:" ↓"; }
.dx-table th[aria-sort="ascending"]::after { content:" ↑"; }
.dx-rowlink { cursor:pointer; }
.dx-minelink { color:inherit; text-decoration:none; display:inline-flex; align-items:center; }
.dx-table tr.is-idle td { color:var(--ink-4); }
.dx-table tr.is-idle td.bold, .dx-table tr.is-idle .dx-minelink { color:var(--ink-3); }
.dx-zero { color:var(--ink-4); }
.dx-inbar { display:inline-block; width:64px; height:7px; border-radius:99px; overflow:hidden; vertical-align:middle; margin-right:8px; }
.dx-table tbody tr[hidden] { display:none; }

.dx-charged { display:flex; align-items:center; justify-content:space-between; gap:8px; margin:2px 0 10px; padding:8px 10px; border-radius:9px; background:var(--surface-2); font-size:13px; color:var(--ink-2); }
.dx-charged b { color:var(--ink); font-weight:700; }

/* ═══ Find a worker: top-bar box, results page, one search across every mine on the Workers page (2026-10-09) ═══ */
.topbar__search { display:flex; align-items:center; }
.topbar__search input[type="search"] { width:200px; height:34px; padding:0 12px; font-size:13px; border:1px solid var(--line); border-radius:var(--r-pill); background:var(--surface); color:var(--ink); font-family:inherit; transition:width var(--dur) var(--ease), border-color var(--dur) var(--ease); }
.topbar__search input[type="search"]:focus { width:280px; border-color:var(--green); outline:none; box-shadow:0 0 0 3px var(--green-bg); }
.topbar__search input::placeholder { color:var(--ink-4); }
@media (max-width:900px) { .topbar__search { display:none; } }
.ws-form { display:flex; gap:10px; flex-wrap:wrap; margin-bottom:14px; max-width:620px; }
.ws-form__input { flex:1; min-width:200px; height:42px; padding:0 14px; font-size:14px; border:1px solid var(--line); border-radius:var(--r-input); background:var(--white); color:var(--ink); font-family:inherit; }
.ws-form__input:focus { border-color:var(--green); outline:none; box-shadow:0 0 0 3px var(--green-bg); }
.ws-hint { color:var(--ink-3); font-size:13.5px; margin:0 0 12px; max-width:62ch; }
.ws-count { font-size:13px; color:var(--ink-3); margin:0 0 10px; }
.ws-all { margin-bottom:6px; }
.ws-all__box { margin-bottom:4px; max-width:520px; }
.ws-all__more { display:inline-block; font-size:13px; margin:2px 0 6px; }
.ws-all .ml-search__none { padding:10px 0; text-align:left; }
[data-mine-block][hidden], .ml-table tbody tr[hidden] { display:none; }

.ml-att-search-slot { margin-bottom: 14px; }
.ml-att-search-slot .ml-search { margin-bottom: 0; }
