/* ============================================================
   VoltIQ SCADA — Industrial dark operator console
   ============================================================ */
:root {
  /* Zinc/slate industrial-SaaS palette — softer than pure black, still a
     serious operator console. */
  --bg: #09090b;
  --bg-grad: radial-gradient(1200px 600px at 20% -10%, #111113 0%, #09090b 60%);
  --panel: #18181b;
  --panel-2: #232326;
  --panel-hi: #303033;
  --line: #27272a;
  --line-soft: #1f1f22;
  --ink: #fafafa;
  --muted: #a1a1aa;
  --dim: #71717a;
  --label: #a1a1aa;   /* form / field labels — must stay readable on dark */
  --accent: #38BDF8;
  --accent-2: #60A5FA;

  --led-green: #22C55E;
  --led-red: #F43F5E;
  --led-amber: #F59E0B;

  --ok-bg: rgba(34,197,94,.10);
  --warn-bg: rgba(245,158,11,.10);
  --bad-bg: rgba(244,63,94,.10);

  /* Cairo carries full Arabic shaping; system-ui / Segoe UI are the safety net. */
  --font: "Cairo", system-ui, "Segoe UI", "Tahoma", "Noto Sans Arabic", -apple-system, sans-serif;
  /* mono for codes/IDs only — Cairo tail so stray Arabic still shapes, never breaks. */
  --mono: "JetBrains Mono", ui-monospace, "SF Mono", "Consolas", "Cairo", "Segoe UI", monospace;
  --radius: 12px;
  --radius-sm: 8px;

  /* Secondary surfaces (inputs, dropdowns, gradient cards, the JSON/log
     console) — named so the light theme below can re-tone every one of
     them instead of leaving dark boxes stranded on a white page. */
  --panel-grad-2: #131316;
  --card-grad-1: #18181b;
  --card-grad-2: #141417;
  --input-bg: #1c1c1f;
  --console-bg: #0c0c0e;
  --console-ink: #7dd3fc;
}

/* ---- light theme --------------------------------------------------------
   Toggled by the header's sun/moon button (persisted to localStorage).
   Same token set, day-mode values — every component already reads colors
   through these variables, so this is the entire theme. */
:root[data-theme="light"] {
  --bg: #fafafa;
  --bg-grad: radial-gradient(1200px 600px at 20% -10%, #ffffff 0%, #fafafa 60%);
  --panel: #FFFFFF;
  --panel-2: #f4f4f5;
  --panel-hi: #e4e4e7;
  --line: #e4e4e7;
  --line-soft: #ececed;
  --ink: #18181b;
  --muted: #71717a;
  --dim: #a1a1aa;
  --label: #52525b;
  --accent: #0284C7;
  --accent-2: #2563EB;

  --ok-bg: rgba(34,197,94,.12);
  --warn-bg: rgba(245,158,11,.14);
  --bad-bg: rgba(244,63,94,.12);

  --panel-grad-2: #f4f4f5;
  --card-grad-1: #FFFFFF;
  --card-grad-2: #f4f4f5;
  --input-bg: #f4f4f5;
  --console-bg: #18181b;
  --console-ink: #7dd3fc;
}

* { box-sizing: border-box; }
html, body { margin: 0; height: 100%; }
/* Thin, theme-colored scrollbars everywhere (sidebar, page body, panels) —
   the OS-default wide light scrollbar otherwise cuts a bright stripe down
   this dark console. Per-element rules like .tablewrap's below still win
   where they're more specific. */
* { scrollbar-width: thin; scrollbar-color: var(--line) var(--bg); }
::-webkit-scrollbar { width: 6px; height: 6px; }
::-webkit-scrollbar-track { background: var(--bg); }
::-webkit-scrollbar-thumb { background: var(--line); border-radius: 4px; }
::-webkit-scrollbar-thumb:hover { background: var(--muted); }
body {
  background: var(--bg);
  background-image: var(--bg-grad);
  color: var(--ink);
  font-family: var(--font);
  font-size: 13px;
  line-height: 1.5;
  text-align: start;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}
.mono { font-family: var(--mono); font-variant-numeric: tabular-nums; }

/* Isolate numeric / currency / percent runs so $ and L.L. never reorder in RTL. */
.ltr, td.num, tfoot td, .pb-v, .loss, .kpi-big, .bcard .cell b,
.gencard .g-meta, .rc-due-usd, .rc-due-lbp, .rc-fx, .conn, .statusstrip {
  direction: ltr;
  unicode-bidi: isolate;
}
[dir="rtl"] .ltr, [dir="rtl"] td.num { text-align: end; }

/* the bold billing-month label above a faint reading-period line */
.period-title { font-weight: 700; font-size: 12.5px; color: var(--ink); }

/* ---- topbar ---------------------------------------------------------- */
/* One bar height for the sidebar's logo row and the topbar, so the two bottom
   borders form a single straight line (LTR and RTL). Horizontal padding matches
   the page grid: topbar = main (20px), sidebar logo = nav icons (8px + 10px). */
:root { --bar-h: 56px; --bar-pad: 20px; }
.topbar {
  position: sticky; top: 0; z-index: 30;
  display: flex; align-items: center; gap: 16px;
  height: var(--bar-h); padding: 0 var(--bar-pad);
  background: var(--panel);
  border-bottom: 1px solid var(--line);
}
/* the smallest phones (≤340px, e.g. iPhone SE) have just a few px too little
   room for brand + lang switch + connection badge + settings icon. */
@media (max-width: 340px) { .topbar { gap: 8px; padding: 0 10px; } }
.mobile-only { display: none; }
.brand { display: flex; align-items: center; gap: 9px; flex-shrink: 0; }
.logo-led {
  width: 10px; height: 10px; border-radius: 50%;
  background: var(--led-green);
  box-shadow: 0 0 6px var(--led-green), 0 0 14px rgba(34,197,94,.6);
  animation: pulse 2.4s ease-in-out infinite;
}
@keyframes pulse { 50% { opacity: .45; } }
.brand-name { font-weight: 700; letter-spacing: .5px; font-size: 15px; }
.brand-sub { color: var(--dim); font-size: 11px; text-transform: uppercase; letter-spacing: 1px; }
/* phones: the subtitle is the first thing to go so brand + lang/settings
   controls never force the topbar wider than the viewport. */
@media (max-width: 480px) { .brand-sub { display: none; } }

.statusstrip {
  display: flex; gap: 12px; flex: 1; overflow-x: auto; align-items: center;
  padding-inline: 8px; scrollbar-width: none;
}
.statusstrip::-webkit-scrollbar { display: none; }
/* each stat is its own translucent chip so numbers never touch labels */
.statusstrip .kv {
  display: inline-flex; align-items: baseline; gap: 6px; white-space: nowrap;
  background: rgba(148,163,184,.08); border: 1px solid var(--line);
  border-radius: 999px; padding: 4px 12px;
  font-family: var(--font); font-size: 11px;
}
.statusstrip .kv i { color: var(--muted); font-style: normal; }
.statusstrip .kv b { color: var(--ink); font-family: var(--mono); font-weight: 700; }
/* an open field violation is real money/security risk, not routine info —
   make the chip itself read as urgent, not just its number. */
.statusstrip .kv-bad { background: var(--warn-bg, rgba(244,63,94,.12)); border-color: rgba(244,63,94,.5); }
.statusstrip .kv-bad b { color: var(--led-red); }

.topbar-right { display: flex; align-items: center; gap: 10px; flex-shrink: 0; }
.langswitch { display: flex; align-items: stretch; height: 30px; border: 1px solid var(--line); border-radius: 8px; overflow: hidden; }
.langswitch button {
  background: var(--panel); color: var(--muted); border: 0;
  padding: 0 10px; display: inline-flex; align-items: center; justify-content: center;
  font-family: var(--font); font-size: 12px; line-height: 1; cursor: pointer;
}
.langswitch button.on { background: var(--accent); color: #04121f; font-weight: 700; }
.conn { display: inline-flex; align-items: center; height: 26px; font-family: var(--mono); font-size: 11px; line-height: 1; padding: 0 10px; border-radius: 999px;
  background: var(--panel-2); color: var(--muted); border: 1px solid var(--line); }
.conn.ok { background: var(--ok-bg); color: var(--led-green); border-color: rgba(34,197,94,.3); }
.conn.bad { background: var(--bad-bg); color: var(--led-red); border-color: rgba(244,63,94,.3); }
button.icon { background: var(--panel); border: 1px solid var(--line); color: var(--ink);
  width: 30px; height: 30px; padding: 0; display: inline-flex; align-items: center; justify-content: center;
  line-height: 1; border-radius: var(--radius-sm); cursor: pointer; }
button.icon.on { background: var(--accent); border-color: var(--accent); color: #04121f; }

/* ---- app shell: fixed collapsible sidebar + main column ----------------- */
.app-shell { display: flex; align-items: stretch; min-height: 100vh; }
.sidebar {
  width: 244px; flex-shrink: 0; display: flex; flex-direction: column;
  background: var(--panel); border-inline-end: 1px solid var(--line);
  position: sticky; top: 0; height: 100vh; overflow-y: auto; overflow-x: hidden;
  transition: width .16s ease; z-index: 45;
}
html[data-sidebar="collapsed"] .sidebar { width: 64px; }
.sidebar-head {
  display: flex; align-items: center; gap: 9px; height: var(--bar-h); padding: 0 18px;
  border-bottom: 1px solid var(--line-soft); flex-shrink: 0;
}
.sidebar-toggle {
  margin-inline-start: auto; background: transparent; border: 1px solid var(--line);
  width: 26px; height: 26px; padding: 0; border-radius: 7px; color: var(--muted);
  flex-shrink: 0; font-size: 11px; box-shadow: none;
}
.sidebar-toggle:hover { color: var(--ink); background: var(--panel-2); box-shadow: none; }
html[data-sidebar="collapsed"] .sidebar-toggle { transform: rotate(180deg); }
html[data-sidebar="collapsed"] .sidebar-head .brand-name { display: none; }
html[data-sidebar="collapsed"] .sidebar-head { padding-inline: 8px; gap: 6px; justify-content: center; }
html[data-sidebar="collapsed"] .sidebar-toggle { margin-inline-start: 0; }
/* the collapse arrow points toward the sidebar's own edge: mirrored in RTL */
html[dir="rtl"] .sidebar-toggle { transform: scaleX(-1); }
html[dir="rtl"][data-sidebar="collapsed"] .sidebar-toggle { transform: none; }
/* phones: the sidebar is off-canvas, so the topbar carries the logo instead */
.topbar .brand.mobile-brand { display: none; }
@media (max-width: 900px) { .topbar .brand.mobile-brand { display: flex; } }
.sidenav { padding: 10px 8px 16px; display: flex; flex-direction: column; gap: 2px; flex: 1; }
.sidenav-group { display: flex; flex-direction: column; gap: 2px; }
.sidenav-heading {
  font-size: 10px; text-transform: uppercase; letter-spacing: .8px; color: var(--dim);
  font-weight: 700; padding: 14px 10px 4px;
}
html[data-sidebar="collapsed"] .sidenav-heading { display: none; }
.sidenav-item {
  display: flex; align-items: center; gap: 10px; width: 100%; text-align: start;
  background: transparent; border: 1px solid transparent; color: var(--muted);
  padding: 9px 10px; border-radius: var(--radius-sm); font-weight: 600; font-size: 12.5px;
  box-shadow: none; justify-content: flex-start;
}
.sidenav-item:hover { background: var(--panel-2); color: var(--ink); box-shadow: none; }
.sidenav-item.on { background: rgba(56,189,248,.12); color: var(--accent); }
.sidenav-item .ic { width: 18px; height: 18px; display: inline-flex; flex-shrink: 0; font-size: 0; }
.sidenav-item .ic svg { width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; }
.sidenav-item { color: var(--muted); }
.sidenav-item.on .ic svg { stroke-width: 2; }
html[data-sidebar="collapsed"] .sidenav-item .lbl { display: none; }
html[data-sidebar="collapsed"] .sidenav-item { justify-content: center; }
.sidenav-item[hidden], .sidenav-heading[hidden] { display: none; }
.sidebar-backdrop { display: none; }
.main-wrap { flex: 1; min-width: 0; display: flex; flex-direction: column; }

@media (max-width: 900px) {
  .sidebar {
    position: fixed; inset-inline-start: 0; top: 0; width: 244px;
    transform: translateX(-100%); box-shadow: 0 0 40px rgba(0,0,0,.4);
  }
  [dir="rtl"] .sidebar { transform: translateX(100%); }
  html[data-mobile-nav="open"] .sidebar { transform: none; }
  .sidebar-toggle { display: none; }
  .mobile-only { display: inline-flex; align-items: center; justify-content: center; }
  html[data-mobile-nav="open"] .sidebar-backdrop {
    display: block; position: fixed; inset: 0; background: rgba(3,7,15,.55); z-index: 44;
  }
}

/* ---- layout grid --------------------------------------------------------- */
main {
  max-width: 1600px; width: 100%; margin: 14px auto; padding: 0 20px 32px;
  display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); gap: 12px;
}
.span-12 { grid-column: span 12; }
.span-7 { grid-column: span 7; }
.span-6 { grid-column: span 6; }
.span-5 { grid-column: span 5; }
@media (max-width: 1000px) { .span-7, .span-6, .span-5 { grid-column: span 12; } }

.panel {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 14px 16px;
  box-shadow: none;
  /* grid items default to a content-based minimum width, so a wide table
     inside would force this panel — and the whole page — wider than the
     viewport instead of letting .tablewrap's own overflow-x:auto scroll it. */
  min-width: 0;
}
.phead { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 12px; min-height: 26px; }
.panel h2 { margin: 0; font-size: 12px; font-weight: 700; letter-spacing: 1.4px; text-transform: uppercase; color: var(--accent); }
.panel h3.mini { margin: 8px 0 5px; font-size: 10px; text-transform: uppercase; letter-spacing: 1px; color: var(--dim); }
.pactions { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }

.split2 { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 18px; }
@media (max-width: 900px) { .split2 { grid-template-columns: minmax(0, 1fr); } }

/* ---- controls ----------------------------------------------------------- */
button, .chip {
  font-family: var(--font); cursor: pointer; font-size: 12px;
  border: 1px solid var(--accent); background: rgba(56,189,248,.12); color: var(--accent);
  padding: 6px 12px; border-radius: var(--radius-sm); font-weight: 600;
  transition: background .12s, border-color .12s;
}
button:hover, .chip:hover { background: rgba(56,189,248,.20); box-shadow: none; }
button.ghost, .chip { background: transparent; color: var(--muted); border-color: var(--line); }
button.ghost:hover, .chip:hover { color: var(--ink); }
button.danger { border-color: var(--led-red); background: rgba(244,63,94,.12); color: #ffb3bd; }
button.danger:hover { background: rgba(244,63,94,.22); box-shadow: none; }
/* the one action a screen wants you to take — solid fill, stands apart from
   the translucent default/ghost/danger buttons around it. */
button.primary {
  background: var(--accent); border-color: var(--accent); color: #04121f;
  font-weight: 800; font-size: 13px; padding: 8px 18px;
}
button.primary:hover { background: #7cd4fb; box-shadow: none; }
.chip { padding: 4px 10px; font-weight: 500; }
.chip.on { background: rgba(56,189,248,.18); border-color: var(--accent); color: var(--ink); font-weight: 700; }
.seg { display: inline-flex; gap: 4px; align-items: center; }

/* ---- Aronium-style screens: action bar, search bar, soft tabs, sortable headers ----------------------- */
.actionbar {
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px;
  padding: 8px 10px; margin-bottom: 10px;
  border: 1px solid var(--line); border-radius: var(--radius);
  background: linear-gradient(180deg, var(--card-grad-1), var(--card-grad-2));
}
.abtn {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 9px 16px; font-size: 13px; font-weight: 600; line-height: 1;
  background: transparent; color: var(--ink); border: 1px solid var(--line); border-radius: 8px;
}
.abtn .ico { font-size: 15px; line-height: 1; opacity: .9; }
.abtn .caret { font-size: 10px; opacity: .7; margin-inline-start: -2px; }
.abtn:hover { background: rgba(56,189,248,.12); border-color: var(--accent); color: var(--ink); }
.abtn.primary { background: var(--accent); border-color: var(--accent); color: #04121f; font-weight: 800; padding: 9px 16px; font-size: 13px; }
.abtn.primary:hover { background: #7cd4fb; }
.abtn.accent { border-color: var(--accent); color: var(--accent); }
.abtn.danger { color: #ffb3bd; border-color: rgba(244,63,94,.55); background: rgba(244,63,94,.08); }
.abtn.danger:hover { background: rgba(244,63,94,.2); border-color: var(--led-red); }
.abtn.warn { color: var(--led-amber, #f59e0b); border-color: rgba(245,158,11,.5); background: transparent; margin-inline-start: auto; }
.abtn:disabled, .abtn[disabled] { opacity: .38; cursor: not-allowed; pointer-events: none; }
.ab-sep { width: 1px; align-self: stretch; margin: 2px 4px; background: var(--line); }

.searchbar { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-bottom: 10px; }
.searchbar .sb-by { min-width: 150px; padding: 10px 12px; font-size: 13px; }
.searchbox {
  flex: 1 1 340px; display: flex; align-items: center; gap: 8px; min-width: 220px;
  background: var(--input-bg); border: 1px solid var(--line); border-radius: 8px; padding: 0 12px;
}
.searchbox:focus-within { border-color: var(--accent); box-shadow: 0 0 0 2px rgba(56,189,248,.18); }
.searchbox .mag { opacity: .7; font-size: 14px; }
.searchbox input { flex: 1; border: 0; background: transparent; padding: 11px 0; font-size: 14px; outline: none; min-width: 0; }
.searchbar .sel { font-size: 13px; padding: 10px 12px; }

.softtabs { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin-bottom: 12px; }
.stab {
  padding: 7px 16px; font-size: 13px; font-weight: 600; border-radius: 999px;
  background: transparent; color: var(--muted); border: 1px solid var(--line);
}
.stab:hover { color: var(--ink); background: rgba(56,189,248,.08); }
.stab.on { background: rgba(56,189,248,.18); border-color: var(--accent); color: var(--ink); font-weight: 800; }
.softtabs .meta { margin-inline-start: auto; }
.actionbar, .searchbar, .softtabs { direction: inherit; max-width: 100%; box-sizing: border-box; }
.actionbar .abtn { flex: 0 0 auto; white-space: nowrap; }
@media (max-width: 1100px) { .searchbox { flex-basis: 100%; order: -1; } .searchbar .sb-by { flex: 1 1 140px; } }

th.sortable { cursor: pointer; user-select: none; }
th.sortable:hover { color: var(--ink); background: rgba(56,189,248,.06); }
th.sortable .sort-ind { display: inline-block; margin-inline-start: 6px; font-size: 10px; opacity: .35; }
th.sortable.sorted .sort-ind { opacity: 1; color: var(--accent); }
tr.sel-row td { background: rgba(56,189,248,.12); }
#invoiceTable tbody tr, #admMeterTable tbody tr { cursor: pointer; }

.popmenu {
  position: absolute; z-index: 60; min-width: 220px; padding: 6px;
  background: var(--card-grad-1); border: 1px solid var(--line); border-radius: 10px;
  box-shadow: 0 12px 32px rgba(0,0,0,.45);
}
.popmenu button {
  display: flex; width: 100%; align-items: center; gap: 10px; text-align: start;
  background: transparent; border: 0; color: var(--ink); padding: 9px 12px; border-radius: 7px; font-size: 13px; font-weight: 500;
}
.popmenu button:hover { background: rgba(56,189,248,.14); }
/* (?) help badge with a tooltip, used next to form labels */
.help {
  display: inline-flex; align-items: center; justify-content: center; position: relative;
  width: 15px; height: 15px; margin-inline-start: 5px; border-radius: 50%; cursor: help;
  font-size: 10px; font-weight: 800; color: var(--accent); border: 1px solid var(--accent);
  vertical-align: middle; user-select: none;
}
.help:hover::after, .help:focus::after {
  content: attr(data-tip); position: absolute; z-index: 80; inset-inline-start: -10px; top: 20px;
  width: max-content; max-width: 240px; padding: 7px 10px; border-radius: 8px;
  background: var(--card-grad-1); color: var(--ink); border: 1px solid var(--line);
  font-size: 11.5px; font-weight: 500; line-height: 1.4; white-space: normal; text-align: start;
  box-shadow: 0 8px 22px rgba(0,0,0,.4);
}
.field-note { font-size: 10.5px; color: var(--dim); }
#edVoidWarn { color: var(--led-amber, #f59e0b); font-weight: 700; }
/* bulk WhatsApp composer */
.wa-compose { display: grid; gap: 8px; margin-bottom: 12px; }
.wa-text { width: 100%; box-sizing: border-box; font-family: var(--font); font-size: 13px; line-height: 1.6; padding: 10px 12px;
  background: var(--input-bg); color: var(--ink); border: 1px solid var(--line); border-radius: 8px; resize: vertical; }
.wa-text:focus { outline: none; border-color: var(--accent); }
.wa-vars { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }
.wa-vars .chip { font-family: var(--mono); font-size: 11.5px; }
.wa-preview { border: 1px dashed var(--line); border-radius: 8px; padding: 8px 12px; font-size: 12px; color: var(--muted); }
.wa-preview pre { margin: 4px 0 0; white-space: pre-wrap; font-family: var(--font); color: var(--ink); font-size: 12.5px; line-height: 1.6; }
.popmenu hr { border: 0; border-top: 1px solid var(--line); margin: 4px 0; }
.sel, input {
  font-family: var(--font); font-size: 12px;
  background: var(--input-bg); color: var(--ink);
  border: 1px solid var(--line); border-radius: 8px; padding: 8px 11px;
}
.sel:focus, input:focus { outline: none; border-color: var(--accent); }
input[type="datetime-local"], input[type="date"], input[type="month"] { color-scheme: dark; }

/* approved-pricing strip shown above the billing action buttons — same pill
   chips as the header status strip, so it reads as "current live facts". */
.billing-summary {
  display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin: 10px 0;
}
.billing-summary .kv {
  display: inline-flex; align-items: baseline; gap: 6px; white-space: nowrap;
  background: rgba(148,163,184,.08); border: 1px solid var(--line);
  border-radius: 999px; padding: 4px 12px;
  font-family: var(--font); font-size: 11px;
}
.billing-summary .kv i { color: var(--muted); font-style: normal; }
.billing-summary .kv b { color: var(--accent); font-family: var(--mono); font-weight: 700; }

/* ---- balance cards ---------------------------------------------------------- */
.balgrid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 12px; }
@media (max-width: 820px) { .balgrid { grid-template-columns: minmax(0, 1fr); } }
.bcard {
  border: 1px solid var(--line); border-radius: var(--radius);
  background: linear-gradient(180deg, var(--card-grad-1), var(--card-grad-2));
  padding: 12px 14px; position: relative; overflow: hidden;
}
.bcard::before {
  content: ""; position: absolute; inset-inline-start: 0; top: 0; bottom: 0; width: 3px;
  background: var(--led-green); box-shadow: 0 0 10px var(--led-green);
}
.bcard.warn::before { background: var(--led-amber); box-shadow: 0 0 10px var(--led-amber); }
.bcard.bad::before { background: var(--led-red); box-shadow: 0 0 10px var(--led-red); }
.bcard .svc { display: flex; align-items: center; gap: 8px; font-weight: 700; letter-spacing: .5px; }
.bcard .svc .em { font-size: 15px; }
.bcard .grid3 { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 6px; margin: 10px 0 8px; }
.bcard .cell { text-align: center; }
.bcard .cell small { display: block; color: var(--dim); font-size: 10px; text-transform: uppercase; letter-spacing: .5px; }
.bcard .cell b { font-family: var(--mono); font-size: 15px; }
.loss { font-family: var(--mono); font-weight: 700; font-size: 13px; padding: 2px 8px; border-radius: 6px; }
.loss.ok { background: var(--ok-bg); color: var(--led-green); }
.loss.warn { background: var(--warn-bg); color: var(--led-amber); }
.loss.bad { background: var(--bad-bg); color: var(--led-red); }
.bar { height: 6px; background: var(--input-bg); border: 1px solid var(--line-soft); border-radius: 999px; overflow: hidden; margin-top: 8px; }
.bar > span { display: block; height: 100%; border-radius: 999px; }

/* ---- chart ------------------------------------------------------------- */
.chart { width: 100%; overflow-x: auto; }
.chart svg { display: block; }
.meta { color: var(--muted); font-size: 11px; margin-bottom: 6px; }

/* ---- tables (high density) ------------------------------------------------- */
.tablewrap { overflow-x: auto; border: 1px solid var(--line-soft); border-radius: 8px; }
/* client-side pager under any paginated table — flips pages instantly,
   no re-fetch, so a 4,000-row table never dumps itself on one screen. */
.pager {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: 12px;
  padding: 10px 8px; border-top: 1px solid var(--line-soft);
}
.pager .pg-label { font-size: 11px; color: var(--muted); min-width: 90px; text-align: center; }
.pager .pg-size { margin-inline-start: 8px; font-size: 11px; padding: 4px 8px; }
.pager button:disabled { opacity: .35; cursor: not-allowed; box-shadow: none; }
table { width: 100%; border-collapse: collapse; }
th, td { text-align: start; padding: 7px 11px; border-bottom: 1px solid var(--line-soft); white-space: nowrap; vertical-align: middle; }
thead th {
  position: sticky; top: 0; background: var(--panel-2); z-index: 1;
  font-size: 10px; text-transform: uppercase; letter-spacing: .8px; color: var(--dim); font-weight: 700;
}
/* numeric header columns align with their (end-aligned) values */
th.num, thead th.num { text-align: end; }
tbody tr:nth-child(odd) { background: rgba(255,255,255,.014); }
tbody tr:hover { background: rgba(56,189,248,.07); }
td.num { font-family: var(--mono); font-variant-numeric: tabular-nums; text-align: end; color: var(--ink); }
.dense th, .dense td { padding: 5px 9px; font-size: 12px; }
/* Compact-view toggle (header button) — tightens EVERY table on the page,
   even ones that weren't already .dense, like accounting software's own
   "compact rows" switch. Higher specificity than .dense so it always wins. */
body[data-density="compact"] table th, body[data-density="compact"] table td { padding: 3px 7px; font-size: 11px; line-height: 1.25; }
body[data-density="compact"] .pager { padding: 5px; }

.pill { font-family: var(--font); font-weight: 600; padding: 2px 8px; border-radius: 5px; font-size: 11px; background: var(--panel-2); color: var(--muted); white-space: nowrap; }
.pill.open, .pill.high, .pill.urgent, .pill.overdue { background: var(--bad-bg); color: var(--led-red); }
.pill.medium, .pill.pending { background: var(--warn-bg); color: var(--led-amber); }
.pill.low, .pill.paid, .pill.closed, .pill.resolved, .pill.active { background: var(--ok-bg); color: var(--led-green); }

/* LED dot for relay state */
.led { display: inline-block; width: 8px; height: 8px; border-radius: 50%; margin-inline-end: 6px; vertical-align: middle; }
.led.on { background: var(--led-green); box-shadow: 0 0 6px var(--led-green); }
.led.off { background: var(--led-red); box-shadow: 0 0 6px var(--led-red); }
.led.unknown { background: var(--dim); }

/* ---- relay toggle switch --------------------------------------------------- */
.switch { position: relative; display: inline-block; width: 40px; height: 22px; }
.switch input { opacity: 0; width: 0; height: 0; }
.slider { position: absolute; inset: 0; background: var(--panel-hi); border: 1px solid var(--line); border-radius: 999px; transition: .15s; }
.slider::before { content: ""; position: absolute; height: 16px; width: 16px; inset-inline-start: 2px; top: 2px;
  background: #94a3b8; border-radius: 50%; transition: .15s; }
.switch input:checked + .slider { background: rgba(34,197,94,.35); border-color: rgba(34,197,94,.5); }
.switch input:checked + .slider::before { transform: translateX(18px); background: var(--led-green); box-shadow: 0 0 8px var(--led-green); }
[dir="rtl"] .switch input:checked + .slider::before { transform: translateX(-18px); }
.switch input:disabled + .slider { opacity: .4; cursor: not-allowed; }
/* The relay switch controls live power, unlike every other toggle in this
   table (billing-enabled, etc.) — its OFF state (breaker cut) reads as an
   active warning, not a neutral "off", so it can never be mistaken for the
   harmless toggle right next to it. */
.switch-relay input:not(:checked) + .slider { background: rgba(244,63,94,.28); border-color: rgba(244,63,94,.55); }
.switch-relay input:not(:checked):not(:disabled) + .slider::before { background: var(--led-red); box-shadow: 0 0 8px var(--led-red); }

/* ---- misc ------------------------------------------------------------- */
.field-row { display: flex; gap: 12px; flex-wrap: wrap; margin-bottom: 14px; }
.btn-row { display: flex; gap: 10px; flex-wrap: wrap; margin-bottom: 8px; }
.btn-row button { padding: 8px 16px; }
.field-row label {
  display: flex; flex-direction: column; gap: 5px; flex: 1; min-width: 190px;
  font-size: 11px; color: var(--label); font-weight: 600; letter-spacing: .3px;
}
.field-row label input { width: 100%; }
.out {
  background: var(--console-bg); color: var(--console-ink); border: 1px solid var(--line-soft);
  padding: 9px; border-radius: 8px; max-height: 150px; overflow: auto; font-size: 11px;
  white-space: pre-wrap; margin: 6px 0 0;
}

dialog { border: 1px solid var(--line); border-radius: 12px; padding: 0; background: var(--panel); color: var(--ink); }
dialog::backdrop { background: rgba(3,7,15,.6); }

/* ---- collector quick lookup -------------------------------------------- */
.lookup-bar { position: relative; }
.lookup-input {
  width: 100%; font-size: 15px; padding: 12px 16px;
  border: 1px solid var(--accent); background: var(--input-bg);
}
.lookup-suggest {
  position: absolute; z-index: 20; top: calc(100% + 4px); left: 0; right: 0;
  background: var(--card-grad-1); border: 1px solid var(--line); border-radius: 10px;
  max-height: 320px; overflow-y: auto;
  box-shadow: 0 16px 40px rgba(0,0,0,.5);
}
.lookup-suggest .item {
  display: flex; justify-content: space-between; align-items: center; gap: 10px;
  padding: 10px 14px; cursor: pointer; border-bottom: 1px solid var(--line-soft);
}
.lookup-suggest .item:last-child { border-bottom: none; }
.lookup-suggest .item:hover, .lookup-suggest .item.hi { background: rgba(56,189,248,.12); }
.lookup-suggest .item .who { display: flex; flex-direction: column; gap: 2px; }
.lookup-suggest .item .who b { font-size: 13px; }
.lookup-suggest .item .who span { font-size: 11px; color: var(--muted); }
.lookup-suggest .empty { padding: 14px; text-align: center; color: var(--muted); font-size: 12px; }

.lookup-card {
  margin-top: 14px; border: 1px solid var(--accent); border-radius: 12px;
  padding: 16px 18px; background: linear-gradient(180deg, rgba(56,189,248,.08), transparent 60%);
}
.lookup-card .lc-head { display: flex; justify-content: space-between; align-items: flex-start; gap: 12px; flex-wrap: wrap; }
.lookup-card .lc-name { font-size: 17px; font-weight: 800; }
.lookup-card .lc-meta { font-size: 12px; color: var(--muted); margin-top: 2px; }
.lookup-card .lc-status { display: flex; align-items: center; gap: 6px; font-size: 12px; white-space: nowrap; }
.lookup-card .lc-due { margin-top: 14px; border-top: 1px dashed var(--line); padding-top: 12px; }
.lookup-card .lc-due-label { font-size: 10px; letter-spacing: 1px; text-transform: uppercase; color: var(--muted); margin-bottom: 2px; }
.lookup-card .lc-due-main { font-size: 26px; font-weight: 800; color: var(--ink); }
.lookup-card .lc-due-sub { font-size: 15px; font-weight: 700; color: var(--muted); margin-top: 2px; }
.lookup-card .lc-breakdown { margin-top: 10px; display: grid; gap: 5px; font-size: 12px; }
.lookup-card .lc-breakdown .kv { display: flex; justify-content: space-between; gap: 10px; }
.lookup-card .lc-breakdown .kv i { color: var(--muted); font-style: normal; }
.lookup-card .lc-actions { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 14px; }
/* 44px is the standard minimum comfortable touch target (iOS HIG / Material) —
   field collectors use this panel on phones, so these can't be thumb-traps. */
.lookup-card .lc-actions button { padding: 9px 16px; min-height: 44px; min-width: 44px; }
.lookup-card .lc-empty { color: var(--muted); font-size: 13px; padding: 8px 0; }
.settings { padding: 18px; display: grid; gap: 12px; min-width: 340px; max-width: calc(100vw - 32px); box-sizing: border-box; }
@media (max-width: 400px) { .settings { min-width: 0; width: calc(100vw - 32px); } }
.settings h3 { margin: 0; color: var(--accent); font-size: 13px; text-transform: uppercase; letter-spacing: 1px; }
.settings label { display: grid; gap: 4px; font-size: 11px; color: var(--dim); }
.settings menu { display: flex; justify-content: flex-end; gap: 8px; padding: 0; margin: 4px 0 0; }

.toast {
  position: fixed; inset-inline: 0; margin-inline: auto; width: max-content; max-width: 92vw;
  bottom: 22px; background: var(--panel-2); color: var(--ink);
  border: 1px solid var(--line); border-inline-start: 3px solid var(--accent);
  padding: 10px 16px; border-radius: 10px; font-size: 12px;
  opacity: 0; transform: translateY(14px); transition: .18s; pointer-events: none; z-index: 50;
}
.toast.show { opacity: 1; transform: translateY(0); }
.toast.bad { border-inline-start-color: var(--led-red); }

/* RTL: force-LTR only for machine text (JSON / SVG); for .mono (codes, IDs,
   timestamps) isolate the run instead of flipping it, so an Arabic label that
   lands in a mono cell still shapes correctly (no more "ةلواط"). */
[dir="rtl"] .chart svg, [dir="rtl"] .out { direction: ltr; }
[dir="rtl"] .mono { unicode-bidi: isolate; }
/* chips flow in reading order (right to left in Arabic); only the numbers inside stay LTR */
[dir="rtl"] .statusstrip { direction: rtl; }
.statusstrip .kv b { direction: ltr; unicode-bidi: isolate; }
.statusstrip .kv { align-items: center; line-height: 1.5; }

/* ---- invoice row actions + edit dialog --------------------------------- */
.rowacts { display: flex; gap: 4px; }
.tinybtn {
  border: 1px solid var(--line); background: var(--panel-2); color: var(--ink);
  width: 26px; height: 24px; padding: 0; border-radius: 6px; font-size: 12px; line-height: 1;
  /* Flex-center rather than rely on line-height/baseline — an emoji glyph's
     own ascent/descent metrics vary by font, so text-layout centering (e.g.
     the 🗑 delete button in the Tariffs capacity/tier rows, sat noticeably
     above-center next to its input field) drifts depending on the glyph. */
  display: inline-flex; align-items: center; justify-content: center;
}
.tinybtn:hover { background: var(--panel-hi); box-shadow: none; }
.tinybtn:disabled { opacity: .3; cursor: not-allowed; }
/* Irreversible actions (hard-delete a row, restore a backup) get their own
   color so they don't sit visually identical to edit/pay/print in a dense
   action column — a misclick shouldn't be this easy to not notice. */
.tinybtn.danger { border-color: var(--led-red); background: rgba(244,63,94,.12); color: #ffb3bd; }
.tinybtn.danger:hover { background: rgba(244,63,94,.22); }
/* The A4/POS/Voucher print-format picker on the Invoices table — one
   <select> instead of three separate tinybtns, so the action column keeps
   fitting alongside edit/paid/delete without pushing the table into a
   horizontal scroll on a 1280px screen. */
select.print-select {
  width: 30px; padding: 0 2px; appearance: none; -webkit-appearance: none;
  text-align: center; text-align-last: center; cursor: pointer;
}
select.print-select option { color: var(--ink); background: var(--panel); text-align: start; }
/* Invoice numbers embed the meter + full period ("INV-WTR-0005-
   20260920-20260921") and were the single widest column — letting them
   wrap at the hyphens (instead of forcing the whole table wider) is what
   actually keeps the action column on-screen; the same info still shows
   in full in the Billing period column next to it. */
/* The invoice number never wraps or collapses (it printed letter by letter in a narrow RTL window): the column
   keeps at least 190px and the table scrolls sideways inside its panel instead of squeezing its columns. */
#invoiceTable td.inv-no, #invoiceTable thead th:first-child {
  white-space: nowrap; min-width: 190px; word-break: keep-all;
}
#invoiceTable > table, #admMeterTable > table { width: max-content; min-width: 100%; }
#invoiceTable thead th, #admMeterTable thead th { white-space: nowrap; }
#invoiceTable thead th:nth-child(2) { min-width: 150px; }   /* customer */
#invoiceTable thead th:nth-child(3) { min-width: 100px; }   /* meter */
#invoiceTable thead th:nth-child(4) { min-width: 150px; }   /* billing period */
#invoiceTable thead th:nth-child(5) { min-width: 80px; }    /* kWh */
#invoiceTable thead th:nth-child(6) { min-width: 150px; }   /* total */
#invoiceTable thead th:nth-child(7) { min-width: 90px; }    /* status */
#invoiceTable thead th:nth-child(8) { min-width: 150px; }   /* actions */
#admMeterTable thead th:nth-child(2) { min-width: 170px; }  /* customer */
#admMeterTable thead th:nth-child(3) { min-width: 120px; }  /* meter */
#invoiceTable, #admMeterTable { overflow-x: auto; max-width: 100%; }
.edit-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
.tf-confirm-body { display: flex; flex-direction: column; gap: 8px; margin: 6px 0 10px; }
.tf-confirm-body .kv { display: flex; justify-content: space-between; gap: 10px; font-size: 13px; }
.tf-confirm-body .kv i { color: var(--dim); font-style: normal; }
.tf-confirm-body .kv b { font-family: var(--font); }
.tf-confirm-body .kv.pct-up b { color: var(--led-red); }
.tf-confirm-body .kv.pct-down b { color: var(--led-green); }
.edit-grid label { display: grid; gap: 4px; font-size: 11px; color: var(--dim); }
#invEditPreview { margin: 4px 0 0; color: var(--accent); }

/* Views are transparent wrappers: their .panel children participate directly
   in the 12-col <main> grid (span-* classes only work on direct grid items). */
.view { display: contents; }
.view[hidden] { display: none; }

/* ---- unified table toolbar (search + filters + actions, one row) ------- */
/* 3-zone toolbar: search always at the inline-start edge, filters truly
 * centered, actions always at the inline-end edge — a 3-column grid (not
 * flex auto-margins) so the middle zone centers against the FULL toolbar
 * width, not just whatever space happens to be left over. Grid columns are
 * direction-aware (RTL mirrors automatically), so every toolbar needs all
 * three zones present in source order (an empty .toolbar-filters div is
 * fine when a page has no filters) for auto-placement to land correctly. */
.toolbar {
  display: grid; grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
  align-items: center; gap: 8px; margin-bottom: 12px;
}
.toolbar .search { justify-self: start; width: 100%; max-width: 320px; min-width: 160px; }
.toolbar-filters {
  grid-column: 2; justify-self: center;
  display: flex; flex-wrap: wrap; gap: 8px; align-items: center;
}
.toolbar-actions {
  grid-column: 3; justify-self: end;
  display: flex; flex-wrap: wrap; gap: 8px; align-items: center;
}
@media (max-width: 720px) {
  .toolbar { grid-template-columns: minmax(0, 1fr); }
  .toolbar .search, .toolbar-filters, .toolbar-actions { justify-self: stretch; }
}

/* ---- executive overview page -------------------------------------------- */
.panel.no-card {
  background: none; border: none; box-shadow: none; padding: 4px 2px 0;
}
.ov-head { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 12px; }
.ov-title { margin: 0; font-size: 20px; font-weight: 800; letter-spacing: -.2px; color: var(--ink); }

/* ---- backups info page --------------------------------------------------- */
.bk-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 12px; margin: 14px 0; }
.bk-card {
  border: 1px solid var(--line); border-radius: var(--radius); padding: 12px 14px;
  background: linear-gradient(180deg, var(--card-grad-1), var(--card-grad-2));
}
.bk-code { font-size: 13px; margin-top: 4px; color: var(--accent); }
.bk-val { font-size: 12px; margin-top: 4px; color: var(--muted); }

/* ---- KPI cards ------------------------------------------------------- */
.kpigrid { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 12px; }
@media (max-width: 1000px) { .kpigrid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 480px) { .kpigrid { grid-template-columns: minmax(0, 1fr); } }
.kpicard {
  border: 1px solid var(--line); border-radius: var(--radius);
  background: linear-gradient(180deg, var(--card-grad-1), var(--card-grad-2)); padding: 12px 14px;
  border-inline-start: 3px solid var(--dim);
}
.kpicard.ok { border-inline-start-color: var(--led-green); }
.kpicard.warn { border-inline-start-color: var(--led-amber); }
.kpicard.bad { border-inline-start-color: var(--led-red); }
.kpicard.clickable { cursor: pointer; transition: border-color .15s, transform .1s; }
.kpicard.clickable:hover { border-color: var(--accent); }
.kpicard.clickable:active { transform: scale(.98); }
.kpi-label { color: var(--dim); font-size: 10px; text-transform: uppercase; letter-spacing: .8px; }
.kpi-big { font-size: 22px; font-weight: 800; margin: 4px 0 2px; }
.kpi-sub { color: var(--muted); font-size: 11px; }

/* ---- settings forms ----------------------------------------------- */
.stackform { display: grid; gap: 10px; grid-template-columns: repeat(2, minmax(0, 1fr)); width: 100%; max-width: 100%; }
.stackform label { display: grid; gap: 4px; font-size: 11px; color: var(--dim); }
.stackform button[type="submit"] { justify-self: start; margin-top: 4px; grid-column: 1 / -1; }
@media (max-width: 640px) { .stackform { grid-template-columns: minmax(0, 1fr); } }

/* ---- arrears report ------------------------------------------------- */
.filterbar { display: flex; gap: 8px; flex-wrap: wrap; align-items: end; margin-bottom: 10px; }
.filterbar label { display: grid; gap: 3px; font-size: 10px; color: var(--dim); text-transform: uppercase; letter-spacing: .5px; }
.filterbar input, .filterbar select { min-width: 120px; }
.filterbar input.grow { min-width: 200px; }
td.bal-debt { color: var(--led-red); font-weight: 700; }
td.bal-credit { color: var(--led-green); font-weight: 700; }
tfoot td { border-top: 2px solid var(--line); font-family: var(--mono); font-weight: 700; padding: 6px 9px; }
tfoot .num { text-align: end; }
.tariff-group { margin-bottom: 26px; }
.tariff-group-title {
  font-weight: 800; font-size: 15px; margin-bottom: 12px; padding-bottom: 8px;
  border-bottom: 2px solid var(--line);
}
.tariff-block {
  margin-bottom: 18px; padding: 16px; border: 1px solid var(--line);
  border-radius: var(--radius-sm); background: var(--panel-2);
}
.tariff-head {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  font-weight: 700; font-size: 13px; margin-bottom: 12px;
}
.tariff-head .tariff-name { color: var(--muted); font-weight: 500; }
.tariff-sections { display: grid; grid-template-columns: 1fr 1fr; gap: 24px; }
@media (max-width: 900px) { .tariff-sections { grid-template-columns: 1fr; } }
.tariff-section { min-width: 0; }
.tariff-section-title {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  font-weight: 700; text-transform: uppercase; letter-spacing: .5px; font-size: 10.5px;
  color: var(--dim); margin: 0 0 8px; padding-bottom: 6px; border-bottom: 1px solid var(--line);
}
.tariff-section-title .chip { text-transform: none; letter-spacing: normal; font-size: 11px; padding: 3px 9px; }
/* The tariff tables must never need a horizontal scrollbar — fixed layout
   with per-column widths (below) instead of the app-wide .tablewrap
   overflow-x:auto, which is meant for wide data-heavy tables elsewhere. */
.tariff-section .tablewrap { overflow-x: visible; }
.tariff-section table { width: 100%; table-layout: fixed; }
.tariff-section th:nth-child(1), .tariff-section td:nth-child(1) { width: 38%; }
.tariff-section th:nth-child(2), .tariff-section td:nth-child(2) { width: 40%; }
.tariff-section th:nth-child(3), .tariff-section td:nth-child(3) { width: 22%; }
.tariff-section th:nth-child(4), .tariff-section td:nth-child(4) {
  /* Wide enough for the add-row's two icon buttons (✓/✕) side by side,
     not just the single 🗑 delete button most rows show. */
  width: 64px; text-align: center; padding-inline: 4px 12px;
}
.tariff-section td:nth-child(4) .rowacts { justify-content: center; }
.tariff-block input[type="number"] { max-width: 110px; width: 100%; }
.tf-amount-cell { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.tf-money { color: var(--muted); font-size: 11px; white-space: nowrap; }
.tf-add-row td { padding-top: 8px; }
.tf-add-input { max-width: 110px; width: 100%; }
.tf-add-row .rowacts { display: flex; gap: 4px; justify-content: center; }
#admMeterFilter { width: 160px; }

/* A collector's role.hidden lockdown already hides whole sidebar pages, but
   Batch Reading itself is one of their two allowed pages — these two
   buttons inside it call Admin-only endpoints (POST /invoices/generate,
   POST /invoices/run-enforcement) that would just 403 for them. Hide them
   instead of leaving a button that looks clickable but never works. */
body.role-collector #genInvoices, body.role-collector #runEnforce { display: none; }

/* ---- print ---------------------------------------------------------- */
/* Printing is done in a hidden <iframe> (see app.js printViaIframe) so the
   dashboard DOM is never sent to the printer. The on-screen #receipt node is
   only a build buffer — keep it out of view and out of any print. */
.receipt { display: none !important; }
@media print { body > *:not(#print-frame) { display: none !important; } }

/* ---- expense payment-status pill ----------------------------------- */
.pill.pending-pay { background: var(--warn-bg); color: var(--led-amber); }
.pill.paid-pay { background: var(--ok-bg); color: var(--led-green); }

/* ---- settings toggle row ------------------------------------------- */
.toggle-row { grid-column: 1 / -1; display: flex; align-items: center;
  justify-content: space-between; gap: 12px; }
.toggle-row span { text-transform: none; }

/* ---- breaker log reason pill ------------------------------------- */
.pill.r-overcurrent { background: var(--bad-bg); color: var(--led-red); }
.pill.r-grace_expired { background: var(--warn-bg); color: var(--led-amber); }
.pill.r-manual_operator { background: var(--bg2); color: var(--dim); }
.pill.r-payment_reconnect { background: var(--ok-bg); color: var(--led-green); }

/* ---- generators card grid ------------------------------------------ */
.gengrid { display: grid; grid-template-columns: repeat(auto-fill, minmax(340px, 1fr)); gap: 16px; }
/* a 340px minimum card is itself wider than the smallest phones — drop the
   floor below that breakpoint so cards shrink to fit instead of overflowing. */
@media (max-width: 360px) { .gengrid { grid-template-columns: minmax(0, 1fr); } }
.gencard {
  border: 1px solid var(--line); border-radius: 8px; padding: 16px 18px;
  background: var(--input-bg); display: flex; flex-direction: column; gap: 2px;
  position: relative; overflow: hidden;
}
/* Oil-service warning — same left-accent-bar treatment as .bcard, so a
   generator overdue (or nearly due) for an oil change reads as urgent from
   across the room, not just from the small text line inside the card. */
.gencard::before {
  content: ""; position: absolute; inset-inline-start: 0; top: 0; bottom: 0; width: 3px;
}
.gencard.oil-soon { border-color: rgba(245,158,11,.4); }
.gencard.oil-soon::before { background: var(--led-amber); box-shadow: 0 0 10px var(--led-amber); }
.gencard.oil-due { border-color: rgba(244,63,94,.5); }
.gencard.oil-due::before { background: var(--led-red); box-shadow: 0 0 10px var(--led-red); }
/* Suspected fuel loss/theft outranks the oil-service accent — a diesel
   variance is real money walking out the door, right now. */
.gencard.waste-alert { border-color: rgba(244,63,94,.7); }
.gencard.waste-alert::before { background: var(--led-red); box-shadow: 0 0 12px var(--led-red); width: 4px; }

/* header: name + status on one clean line */
.gencard .g-top {
  display: flex; justify-content: space-between; align-items: center; gap: 12px;
  padding-bottom: 10px; margin-bottom: 4px; border-bottom: 1px solid var(--line-soft);
}
.gencard .g-name { font-family: var(--font); font-weight: 800; font-size: 14px; letter-spacing: .3px; color: var(--ink); }
.gencard .g-stat {
  font-size: 10px; font-weight: 700; padding: 3px 11px; border-radius: 999px;
  text-transform: uppercase; letter-spacing: .6px; white-space: nowrap;
}
.g-stat.running { background: var(--ok-bg); color: var(--led-green); }
.g-stat.standby { background: rgba(148,163,184,.10); color: var(--muted); border: 1px solid var(--line); }
.g-stat.maintenance { background: var(--warn-bg); color: var(--led-amber); }

/* fuel gauge — full-width bar, figure + percent on the line below */
.gencard .g-fuel { display: flex; flex-direction: column; gap: 6px; padding: 8px 0; }
.gencard .g-fuel .bar {
  width: 100%; height: 12px; border-radius: 999px; background: var(--input-bg);
  border: 1px solid var(--line); overflow: hidden; margin: 0;
}
.gencard .g-fuel .bar > span { display: block; height: 100%; background: var(--led-green); transition: width .3s; }
.gencard .g-fuel.low .bar > span { background: var(--led-red); }
.gencard .g-fuel.warn .bar > span { background: var(--led-amber); }
.gencard .g-fuel .g-cap { display: flex; justify-content: space-between; align-items: baseline; font-size: 11.5px; }
.gencard .g-fuel .g-cap .g-lbl { color: var(--label); }
.gencard .g-fuel .g-cap .g-fig { font-family: var(--mono); color: var(--ink); font-weight: 700; }

/* labelled value rows — each on its own independent line */
.gencard .g-line {
  display: flex; align-items: center; gap: 10px; font-size: 12px; color: var(--muted);
  padding: 6px 0; border-top: 1px solid var(--line-soft);
}
.gencard .g-line .g-ic { width: 18px; text-align: center; opacity: .85; }
.gencard .g-line .g-lbl { color: var(--label); }
.gencard .g-line .g-val { margin-inline-start: auto; font-family: var(--mono); color: var(--ink); font-weight: 600; }

.gencard .g-alert { font-size: 11px; color: var(--led-amber); display: flex; align-items: center; gap: 6px; padding: 5px 0; }
.gencard .g-alert.bad { color: var(--led-red); }

/* status: segmented toggle (running / standby / maintenance) */
.gencard .g-seg {
  display: flex; margin-top: 12px;
  border: 1px solid var(--line); border-radius: 8px; overflow: hidden;
}
.gencard .g-seg button {
  flex: 1; border: 0; border-radius: 0; background: transparent; color: var(--muted);
  padding: 7px 8px; font-size: 11px; font-family: var(--font); font-weight: 600;
  white-space: nowrap; box-shadow: none; cursor: pointer;
}
.gencard .g-seg button + button { border-inline-start: 1px solid var(--line); }
.gencard .g-seg button.on { background: rgba(56,189,248,.16); color: var(--accent); cursor: default; }
.gencard .g-seg button:not(.on):hover { background: rgba(148,163,184,.08); color: var(--ink); }

/* operation buttons — readable, framed, never wrap inside one button */
.gencard .g-acts {
  display: flex; gap: 8px; flex-wrap: wrap; margin-top: 10px;
  padding-top: 12px; border-top: 1px solid var(--line-soft);
}
.gencard .g-acts button {
  flex: 1 1 128px; min-width: 128px; white-space: nowrap;
  font-size: 11px; font-family: var(--font); font-weight: 600;
  padding: 8px 12px; border-radius: 7px;
  background: var(--bg2); color: var(--ink); border: 1px solid var(--line); box-shadow: none;
}
.gencard .g-acts button:hover { border-color: var(--accent); color: var(--accent); }

/* ---- phase balance bar ------------------------------------------- */
.pbrow { display: grid; grid-template-columns: 28px 1fr 84px; align-items: center; gap: 8px; margin: 8px 0; }
.pbrow .pb-l { font-family: var(--mono); font-weight: 700; color: var(--dim); }
.pbrow .pb-track { height: 16px; background: var(--bg2); border-radius: 4px; overflow: hidden; border: 1px solid var(--line); }
.pbrow .pb-fill { height: 100%; background: linear-gradient(90deg, var(--led-green), var(--accent)); }
.pbrow .pb-fill.hot { background: linear-gradient(90deg, var(--led-amber), var(--led-red)); }
.pbrow .pb-v { font-family: var(--mono); font-size: 11px; text-align: end; }
.pb-note { font-size: 11px; color: var(--muted); margin-top: 4px; }
.pb-note.bad { color: var(--led-red); }

/* theft-suspect badge */
.badge-theft { color: var(--led-red); cursor: help; margin-inline-start: 4px; }
/* whatsapp button */
.wa-btn { color: #25D366; }

/* ============ UI polish (v10): tables, focus, segmented filter ============ */

/* Maintenance + anomaly tables: never crush columns — scroll the wrapper. */
#anomTable table, #ticketTable table { min-width: 560px; }
#anomTable td, #ticketTable td, #protTable td { padding: 8px 12px; }
/* status / priority / action cells sit centred in their column */
#anomTable td:has(.pill), #anomTable td:has(button),
#ticketTable td:has(.pill), #ticketTable td:has(button),
#protTable td:has(.pill) { text-align: center; }
#anomTable td:has(button) button, #ticketTable td:has(button) button { min-width: 68px; }
/* keep timestamps on one line so the ack button can't overlap them */
#anomTable td.mono, #ticketTable td.mono { min-width: 118px; }

.tablewrap { scrollbar-width: thin; }
.tablewrap::-webkit-scrollbar { height: 8px; }
.tablewrap::-webkit-scrollbar-thumb { background: var(--line); border-radius: 4px; }

/* segmented control (balance-card service filter) */
.seg { display: inline-flex; border: 1px solid var(--line); border-radius: 8px; overflow: hidden; }
.seg button {
  border: 0; border-radius: 0; background: transparent; color: var(--muted);
  padding: 5px 12px; font-size: 11px; box-shadow: none;
}
.seg button + button { border-inline-start: 1px solid var(--line); }
.seg button.on { background: rgba(56,189,248,.16); color: var(--accent); }
.seg button:hover { color: var(--ink); box-shadow: none; }

/* a touch more air around card grids */
.balgrid { gap: 14px; }
.kpigrid { gap: 14px; }

/* ============ settlement & routing (v12) ============ */
.drawer-panel { border-inline-start: 3px solid var(--accent); }
.drawergrid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 14px; margin-bottom: 4px; }
@media (max-width: 900px) { .drawergrid { grid-template-columns: minmax(0, 1fr); } }
.drawercard {
  border: 1px solid var(--line); border-radius: 10px; padding: 14px 16px;
  background: var(--input-bg); border-inline-start: 3px solid var(--line);
}
.drawercard.ok     { border-inline-start-color: var(--led-green); }
.drawercard.accent { border-inline-start-color: var(--accent); }
.drawercard .kpi-big { font-size: 25px; margin: 6px 0 2px; }
.drawercard .kpi-sub { margin-top: 2px; }

/* subject cell: bold name + faint contact/route line */
td.subj b { font-family: var(--font); font-weight: 700; font-size: 12.5px; color: var(--ink); }
td.subj .meta { font-size: 10.5px; }

/* Subscribers table: bulk-action bar for the ticked rows */
.bulkbar {
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px;
  margin: 0 0 10px; padding: 8px 10px;
  border: 1px solid var(--accent); border-radius: 8px; background: var(--panel-hi);
}
.bulkbar[hidden] { display: none; }
.bulkbar .sel { width: auto; min-width: 90px; max-width: 150px; }
.bulkbar b { color: var(--accent); margin-inline-end: 4px; }
th.selcol, td.selcol { width: 28px; text-align: center; padding-inline: 4px; }

/* the `hidden` attribute must always win over component display rules (e.g. label rows) */
[hidden] { display: none !important; }

/* manual-invoice dialog: blocking "this period is already billed" warning */
.giwarn {
  margin-top: 8px; padding: 8px 10px; border-radius: 8px; font-size: 13px; line-height: 1.5;
  border: 1px solid var(--led-red); background: rgba(244,63,94,.12); color: #ffb3bd;
}

/* ---- arrears screen: filter bar + table layout --------------------------- */
/* The default .toolbar is a 3-column grid (search | filters | actions); the
   arrears page has nine filters, which that middle column squeezed into
   overlapping rows. Here every control is a sibling in one wrapping flex row. */
.toolbar.toolbar-wrap {
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px;
}
.toolbar.toolbar-wrap .toolbar-filters,
.toolbar.toolbar-wrap .toolbar-actions { display: contents; }
.toolbar.toolbar-wrap .search { flex: 1 1 220px; max-width: 320px; min-width: 180px; width: auto; }
.toolbar.toolbar-wrap .sel { width: auto; min-width: 120px; }
.toolbar.toolbar-wrap input[type=number].sel { width: 130px; min-width: 110px; }
.toolbar.toolbar-wrap .toolbar-actions > :first-child { margin-inline-start: auto; }

/* Never squeeze the columns: keep the table at least as wide as its content and
   let .tablewrap scroll sideways; the balance column (USD over L.L.) gets room. */
.arrears-table { width: 100%; min-width: max-content; }
.arrears-table th, .arrears-table td { white-space: nowrap; }
.arrears-table th:nth-child(7), .arrears-table td:nth-child(7),
.arrears-table th:nth-child(8), .arrears-table td:nth-child(8) { min-width: 110px; }
.arrears-table th:nth-child(9), .arrears-table td:nth-child(9) { min-width: 130px; }
#rpArrears { overflow-x: auto; }

/* monthly-cycle dialog */
.cy-preview { margin: 10px 0; padding: 10px 12px; border: 1px solid var(--line); border-radius: 8px; background: var(--panel-hi); line-height: 1.7; }
.cy-preview b { color: var(--accent); }
.cy-preview .cy-eligible { font-size: 15px; }
.cy-preview .cy-skip { color: var(--muted); font-size: 12px; }
.cy-result { margin: 10px 0; padding: 10px 12px; border-radius: 8px; border: 1px solid var(--led-green); background: rgba(34,197,94,.1); line-height: 1.7; }
.cy-result.warn { border-color: var(--led-red); background: rgba(244,63,94,.1); }
.cy-result ul { margin: 6px 0 0; padding-inline-start: 18px; font-size: 12px; color: var(--muted); max-height: 160px; overflow: auto; }
body.role-collector #cycleBtn { display: none; }

/* subscribers bulk bar: prominent + stays in view while the table scrolls */
.bulkbar { position: sticky; top: 8px; z-index: 6; box-shadow: 0 6px 18px rgba(0,0,0,.35); border-width: 2px; }
.bulkbar .chip.bulk-on  { border-color: var(--led-green); color: var(--led-green); font-weight: 700; }
.bulkbar .chip.bulk-off { border-color: var(--led-red);   color: var(--led-red);   font-weight: 700; }

/* cycle dialog: eligible-subscribers table */
.cy-list { margin-top: 10px; }
.cy-list > summary { cursor: pointer; font-weight: 700; color: var(--accent); }
.cy-list .cy-search { width: 100%; margin: 8px 0; }
.cy-tablewrap { max-height: 280px; overflow: auto; border: 1px solid var(--line); border-radius: 8px; }
.cy-table { width: 100%; border-collapse: collapse; font-size: 12px; }
.cy-table th { position: sticky; top: 0; background: var(--panel-hi); text-align: start; padding: 6px 8px; border-bottom: 1px solid var(--line); }
.cy-table td { padding: 5px 8px; border-bottom: 1px solid var(--line); }
.cy-table .num { text-align: end; font-variant-numeric: tabular-nums; white-space: nowrap; }
.cy-table tr.cy-dim td { color: var(--muted); opacity: .7; }
.cy-table tfoot td { font-weight: 800; position: sticky; bottom: 0; background: var(--panel-hi); }
#cycleDlg .settings { min-width: min(720px, 94vw); }

/* batch print dialog + cycle "print all" shortcut */
#batchPrintDlg .settings { min-width: min(420px, 94vw); }
#batchPrintDlg progress { width: 100%; margin-top: 8px; }
#batchPrintDlg label.check { flex-direction: row; align-items: center; gap: 8px; }
.cy-result .cy-printall { margin-top: 10px; }

/* phones: the topbar keeps menu + logo + essentials on one line, no overflow */
@media (max-width: 480px) {
  .topbar { gap: 8px; padding: 0 12px; }
  .topbar .statusstrip, .topbar #compactBtn { display: none; }
  .topbar-right { gap: 8px; margin-inline-start: auto; }
}

/* cycle dialog: filters, selection and quick actions */
.cy-filters { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.cy-table .cy-chk { width: 28px; text-align: center; padding-inline: 4px; }
.cy-table tr.cy-off td { opacity: .45; text-decoration: line-through; }
.cy-table tr.cy-off td.cy-chk, .cy-table tr.cy-off td.cy-acts { opacity: 1; text-decoration: none; }
.cy-table .cy-acts { white-space: nowrap; }
.cy-table .cy-acts .tinybtn { margin-inline-end: 4px; }

/* subscribers toolbar on phones: search + buttons wrap instead of overlapping */
@media (max-width: 720px) {
  .toolbar { display: flex; flex-wrap: wrap; gap: 8px; width: 100%; }
  .toolbar .search { flex: 1 1 100%; max-width: none; width: 100%; }
  .toolbar-filters, .toolbar-actions { grid-column: auto; flex: 1 1 100%; justify-content: flex-start; flex-wrap: wrap; gap: 8px; width: 100%; }
  .toolbar-filters:empty { display: none; }
}

/* subscribers bulk bar: floats under the topbar while the long table scrolls */
.bulkbar { top: calc(var(--bar-h) + 6px); z-index: 100; }
.bulkbar .bulk-group { display: inline-flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.bulkbar .bulk-label { color: var(--muted); font-size: 12px; }
.bulkbar .chip.bulk-warn { border-color: var(--led-amber, #f59e0b); color: var(--led-amber, #f59e0b); font-weight: 700; }
.bulkbar .bulk-clear { margin-inline-start: auto; }

/* ---- Tariffs screen: two plain plans ---------------------------------------- */
.tf-fx { margin-bottom: 16px; padding: 14px 16px; border: 2px solid var(--accent); border-radius: var(--radius-sm); background: var(--panel-hi); }
.tf-fx-title { font-weight: 800; margin-bottom: 8px; }
.tf-fx-row { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-bottom: 6px; }
.tf-fx-input { width: 150px; font-size: 16px; font-weight: 700; direction: ltr; text-align: end; }
.tf-fx-unit { color: var(--muted); }
.tf-fx-preview { color: var(--accent); font-weight: 700; }
.tf-warn { margin: 0 0 14px; padding: 10px 12px; border: 1px solid var(--led-amber, #f59e0b); border-radius: 8px;
  background: rgba(245,158,11,.1); font-size: 12.5px; }
.tariff-head-simple { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; margin-bottom: 14px; }
.tariff-title { font-weight: 800; font-size: 16px; margin-bottom: 2px; }
.tariff-sections.one { grid-template-columns: 1fr; max-width: 640px; }
.tariff-section-title { text-transform: none; letter-spacing: 0; font-size: 12.5px; color: var(--ink); }
.tf-sec-actions { display: inline-flex; gap: 6px; flex-wrap: wrap; }
.tariff-section th:nth-child(1), .tariff-section td:nth-child(1) { width: 30%; }
.tariff-section th:nth-child(2), .tariff-section td:nth-child(2) { width: auto; }
.tariff-section th:nth-child(3), .tariff-section td:nth-child(3) { width: 72px; text-align: center; padding-inline: 4px; }
.tf-amount-cell { flex-wrap: nowrap; }
.tf-amount-cell .tf-money { white-space: normal; }
.tf-ccy { color: var(--muted); font-weight: 700; }
tr.tf-unpriced td { background: rgba(245,158,11,.07); }
.tf-badge { margin-inline-start: 8px; padding: 1px 7px; border-radius: 999px; font-size: 10px; font-family: var(--font);
  background: rgba(245,158,11,.18); color: var(--led-amber, #f59e0b); }
.tf-archived { margin-top: 22px; }
.tf-archived > summary { cursor: pointer; font-weight: 700; color: var(--muted); }
.tf-archived-table { width: 100%; font-size: 12px; margin-top: 8px; }
.tf-archived-table td { padding: 4px 8px; border-bottom: 1px solid var(--line); }
.tf-money { direction: ltr; unicode-bidi: isolate; }
.tariff-section td:nth-child(1).ltr { text-align: start; }

/* demo data */
.demo-counts { font-weight: 700; margin: 8px 0; }
.demo-switch { display: flex; align-items: center; gap: 8px; margin: 10px 0; }
.demo-actions { margin-top: 12px; }
.pill.demo-pill { margin-inline-start: 8px; background: rgba(245,158,11,.18); color: var(--led-amber, #f59e0b); }

/* sign-in dialog + accounts card */
.login-dlg { border: 1px solid var(--line); border-radius: 12px; padding: 0; background: var(--panel); color: var(--ink); }
.login-dlg::backdrop { background: rgba(3,7,15,.85); }
.login-dlg .settings { min-width: min(360px, 90vw); }
.lg-err { color: var(--led-red); min-height: 1.2em; font-size: 12.5px; }
.sec-form { display: grid; gap: 8px; margin: 14px 0; padding-top: 10px; border-top: 1px solid var(--line); }
.sec-form h4, #securityBody > h4 { margin: 0; }
/* operators / collectors: no accounting-settings controls */
body.role-nonadmin #subBulkFee, body.role-nonadmin #subBulkFeeCcy, body.role-nonadmin #subBulkFeeSet,
body.role-nonadmin #subFlatRow, body.role-nonadmin #asFlatRow, body.role-nonadmin #edUnpay { display: none !important; }

/* monthly-cycle generation is Admin-only */
body.role-nonadmin #cycleBtn, body.role-nonadmin #genInvoices { display: none !important; }

/* phone / PWA card */
.ph-row { display: flex; align-items: center; gap: 14px; margin: 10px 0; }
.ph-row img { background: #fff; padding: 4px; border-radius: 6px; }
.ph-url { font-weight: 700; color: var(--accent); word-break: break-all; }
.ph-steps { padding-inline-start: 20px; line-height: 1.8; font-size: 13px; }
.ph-steps a { color: var(--accent); }

/* backup settings + alert */
.backup-alert { margin: 0; padding: 10px 18px; background: rgba(244,63,94,.16); border-bottom: 2px solid var(--led-red);
  color: #ffd3da; font-weight: 700; text-align: center; position: sticky; top: var(--bar-h); z-index: 29; }
.bk-settings { margin: 12px 0 18px; padding: 14px 16px; border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--panel-2); }
.bk-form { display: grid; gap: 12px; max-width: 640px; }
.bk-row { display: grid; gap: 4px; }
.bk-label { font-weight: 700; }
.bk-dest { width: 100%; font-family: var(--mono); }
.bk-chips { display: flex; gap: 8px; flex-wrap: wrap; }
.bk-inline { display: inline-flex; align-items: center; gap: 8px; }
.bk-inline input { width: 110px; }
.bk-toggle { display: flex; align-items: center; gap: 8px; font-size: 14px; }
.bk-actions { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-top: 14px; }
.bk-status { margin-top: 12px; font-size: 12.5px; color: var(--muted); line-height: 1.8; }

/* system reset */
.reset-banner { margin-bottom: 14px; padding: 10px 14px; border: 1px solid var(--led-red); border-radius: 8px; background: rgba(244,63,94,.1); font-weight: 600; }
.reset-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 14px; margin-bottom: 12px; }
.reset-card { padding: 14px 16px; border: 1px solid var(--led-red); border-radius: var(--radius-sm); background: var(--panel-2); display: grid; gap: 10px; align-content: start; }
.reset-card h3 { margin: 0; color: #ffb3bd; }
.reset-lines { display: grid; gap: 6px; font-size: 13px; line-height: 1.7; }
.reset-dlg { border: 3px solid var(--led-red); border-radius: 12px; padding: 0; background: var(--panel); color: var(--ink); }
.reset-dlg::backdrop { background: rgba(60,0,10,.85); }
.reset-dlg h3 { color: #ff8da0; margin: 0; }
.reset-warn { padding: 10px 12px; border-radius: 8px; background: rgba(244,63,94,.16); border: 1px solid var(--led-red); font-weight: 700; line-height: 1.7; }
.reset-dlg progress { width: 100%; }

/* wide money columns: never cut a large L.L. amount */
.arrears-table th:nth-child(7), .arrears-table td:nth-child(7),
.arrears-table th:nth-child(8), .arrears-table td:nth-child(8) { min-width: 150px; }
.arrears-table th:nth-child(9), .arrears-table td:nth-child(9) { min-width: 200px; }
.arrears-table td.num { white-space: nowrap; }
#ovInvoices { overflow-x: auto; }
#ovInvoices table { min-width: max-content; width: 100%; }
#ovInvoices td.num, #ovInvoices th.num { white-space: nowrap; min-width: 150px; }
/* cash handover table: variance + action cell */
#crTable td.cr-var { white-space: nowrap; font-weight: 700; }
#crTable td.cr-var.bad { color: var(--led-red); }
#crTable td.cr-var.warn { color: var(--led-amber, #f59e0b); }
#crTable td.cr-var.ok { color: var(--led-green); }
#crTable td.cr-act { display: table-cell; white-space: normal; min-width: 150px; }
#crTable td.cr-act > * { display: block; margin: 2px 0; }
#crTable { table-layout: auto; }

/* breaker log dialog: state cells keep dot + word apart */
.bl-state { white-space: nowrap; }
#blogBody th, #blogBody td { padding-inline: 12px; }
#blogBody td.bl-state { min-width: 110px; }

/* printing the dashboard page itself (Ctrl+P): let tables flow over as many sheets as they need */
@media print {
  html, body, .app-shell, .main-wrap, main, .view, .panel, .tablewrap, #rpExpenses, #rpPayments, #rpArrears {
    overflow: visible !important; height: auto !important; max-height: none !important; position: static !important;
  }
  table { page-break-inside: auto; }
  thead { display: table-header-group; }
  tfoot { display: table-row-group; }
  tr { page-break-inside: avoid; break-inside: avoid; }
}

/* carried-over balance = a book entry, visibly different from real receipts */
.pill.carry { background: rgba(148,163,184,.18); color: var(--muted); border: 1px dashed var(--muted); }
.drawercard.carry { border-style: dashed; opacity: .85; }

/* ---- settings: About & updates ---- */
.ver-rows { display: grid; gap: 4px; margin-bottom: 8px; }
.ver-row { display: flex; justify-content: space-between; gap: 12px; align-items: baseline; }
.ver-ok { color: var(--led-green, #3ddc84); font-weight: 700; }
.ver-status { margin: 6px 0; }
.ver-log { margin: 4px 0 8px; padding-inline-start: 18px; font-size: 13px; line-height: 1.7; }

/* ---- VoltIQ logo: sidebar / top bar mark + wordmark, sign-in logo ---- */
.brand-logo { display: block; height: 30px; width: auto; flex-shrink: 0; }
.sidebar-head .brand-logo { height: 34px; }
.brand-name b { color: var(--accent); font-weight: 800; }
.login-logo { display: block; width: 168px; height: 168px; margin: 2px auto 10px; border-radius: 18px; }

/* ---- Batch readings: viewport-fit layout (like Subscribers' tidy bars, but the table scrolls INSIDE the card) ---- */
.bill-line { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 12px; }
.bill-line label { display: flex; flex-direction: column; gap: 5px; flex: 0 1 190px; min-width: 150px;
  font-size: 11px; color: var(--label); font-weight: 600; letter-spacing: .3px; }
.bill-line label input { width: 100%; }
.bill-line .btn-row { margin-bottom: 0; margin-inline-start: auto; }
.batch-bill .billing-summary:empty, .batch-bill .out:empty { display: none; }
.batch-bill .out { max-height: 84px; }
.batch-reads { display: flex; flex-direction: column; min-height: 0; }
.batch-reads .phead { flex: 0 0 auto; }
.batch-reads .actionbar, .batch-reads .searchbar { flex: 0 0 auto; }
.batch-reads .batch-scroll { flex: 1 1 auto; min-height: 220px; overflow: auto; }
.batch-reads thead th { position: sticky; top: 0; z-index: 3; background: var(--panel-2); box-shadow: 0 1px 0 var(--line); }
body[data-view="batch"] main {
  height: calc(100vh - var(--bar-h) - 28px); padding-bottom: 14px;
  grid-template-rows: auto minmax(0, 1fr); align-content: stretch;
}
@media (max-width: 900px) {
  body[data-view="batch"] main { height: auto; grid-template-rows: none; }
  .batch-reads .batch-scroll { max-height: 65vh; }
  .bill-line .btn-row { margin-inline-start: 0; }
}
/* tighter billing bar + one-row reading toolbar, so the table gets most of the window */
.batch-bill { padding: 8px 14px 10px; }
.batch-bill .phead { margin-bottom: 4px; }
.batch-bill .phead h2 { font-size: 12px; }
.batch-bill .billing-summary { margin-top: 6px; font-size: 11px; line-height: 1.35; }
.batch-reads { padding-top: 8px; }
.batch-reads .phead { margin-bottom: 4px; }
.batch-toolbar { margin-bottom: 8px; padding: 6px 8px; }
.batch-toolbar .searchbox { flex: 1 1 260px; }
.batch-toolbar .sb-by { min-width: 130px; padding: 8px 10px; }
.batch-toolbar .abtn { padding: 8px 14px; }
.batch-toolbar .searchbox input { padding: 8px 0; }

.login-brand { text-align: center; margin: 2px auto 14px; }
.login-brand img { display: block; margin: 0 auto 6px; }
.login-wordmark { font-size: 30px; font-weight: 800; letter-spacing: .5px; color: var(--ink); line-height: 1.1; }
.login-wordmark b { color: var(--accent); font-weight: 800; }
.login-tag { font-size: 12px; color: var(--muted, #8fa3b8); margin-top: 4px; }
