/* Palette: the Jarves house theme, taken from project.jarves.net — a slate
   monochrome, brand = slate-900 with white on top. Measured off the live site:
   buttons #0f172a on #fff, body text #334155, borders #e2e8f0, page #f8fafc.
   The till (static/pos/styles.css) carries the same block; keep them in step. */
:root {
  --bg: #f8fafc;          /* slate-50  — the page */
  --sidebar: #0f172a;
  --sidebar-2: #1e293b;
  --card: #ffffff;
  --ink: #0f172a;
  --muted: #64748b;       /* slate-500 */
  --line: #e2e8f0;        /* slate-200 — cards, dividers, table lines */
  --control-border: #7d8b9e; /* slate-ish, 3.47:1 on white — form-control edges (WCAG 1.4.11) */
  --accent: #0f172a;      /* slate-900 — the brand; white on it is 17.9:1 */
  --accent-d: #1e293b;    /* slate-800 — hover */
  --accent-soft: #f1f5f9;   /* slate-100 — tinted surfaces (pills, chips) */
  --accent-soft-2: #e2e8f0; /* slate-200 — their hover */
  --accent-ink: #334155;    /* slate-700 — text on those surfaces, 9.6:1 */
  /* Semantic, not brand: a state badge still has to say good-or-bad at a glance. */
  --ok: #047857;
  --ok-bg: #ecfdf5;
  --emerald: #10b981;
  --danger: #ef4444;
  /* #ef4444 as TEXT on the #fef2f2 tint is 3.44:1. Fine as a fill, not as
     a label — a negative quantity badge is exactly the thing you must be
     able to read. red-700 takes the same pairing to 6.4:1. */
  --danger-ink: #b91c1c;
  --shadow: 0 1px 3px rgba(16,24,40,.08), 0 1px 2px rgba(16,24,40,.06);
}
* { box-sizing: border-box; }
html, body { height: 100%; }
body { margin: 0; background: var(--bg); color: var(--ink);
  font: 14px/1.5 -apple-system, "Segoe UI", Roboto, system-ui, sans-serif; }
.hidden { display: none !important; }
.muted { color: var(--muted); }
.err { color: var(--danger-ink); min-height: 1.1em; margin: 8px 0 0; }
button { cursor: pointer; font: inherit; border: 0; border-radius: 10px; }
input, select { font: inherit; }
.dot { display: inline-block; width: 10px; height: 10px; border-radius: 50%; background: var(--accent); margin-right: 6px; }

/* Login */
.login { min-height: 100vh; display: grid; place-items: center;
  background: radial-gradient(1200px 600px at 20% -10%, #1e293b, #0f172a); }
.login-card { width: min(360px, 92vw); background: var(--card); border-radius: 18px; padding: 30px; box-shadow: 0 30px 60px rgba(2,6,23,.45); }
.login-brand { font-size: 22px; font-weight: 800; }
.login-card label { display: block; font-size: 12px; font-weight: 600; color: var(--muted); margin: 14px 0 4px; text-transform: uppercase; letter-spacing: .4px; }
.login-card input { width: 100%; padding: 12px 14px; border: 1px solid var(--control-border); border-radius: 10px; background: #f8fafc; }
.login-card input:focus { outline: 2px solid var(--accent); border-color: transparent; }
.login-card button { width: 100%; margin-top: 20px; padding: 13px; background: var(--accent); color: #fff; font-weight: 700; }

/* Shell — one dark menu bar across the top, content fills the rest.
   The nav used to be a fixed 236px sidebar; moving it up here hands that width
   back to the tables, which are the reason anyone opens this console. */
.app { display: flex; flex-direction: column; height: 100vh; overflow: hidden; }
.topnav { flex-shrink: 0; background: var(--sidebar); color: #cbd5e1;
  display: flex; flex-direction: column; padding: 0 16px; }
.topnav-main { display: flex; align-items: center; gap: 14px; height: 56px; }
/* Name over strapline — stacked, so the brand costs one short column of width
   instead of a long horizontal run the menus would otherwise have to fight for. */
.topnav-brand { flex-shrink: 0; display: flex; flex-direction: column;
  justify-content: center; line-height: 1.15; color: #fff; font-weight: 700; white-space: nowrap; }
.topnav-brand .brand-name { font-size: 15px; }
/* slate-500 on the slate-900 bar is 3.75:1 — under AA. These are the only
   three places text sits directly on the bar in a muted tone; slate-400
   takes them to 6.3:1 without making them shout. */
.topnav-brand .brand-sub { font-size: 10px; font-weight: 500; color: #94a3b8; letter-spacing: .06em; text-transform: uppercase; }
.topnav-right { flex-shrink: 0; display: flex; align-items: center; gap: 8px; margin-left: auto; }
.rtl .topnav-right { margin-left: 0; margin-right: auto; }
.topnav-user { display: flex; align-items: center; gap: 8px; padding-left: 10px; margin-left: 4px; border-left: 1px solid #223049; }
.rtl .topnav-user { border-left: 0; border-right: 1px solid #223049; padding: 0 10px 0 0; margin: 0 4px 0 0; }
.topnav-user .who { font-size: 12px; line-height: 1.15; color: #e2e8f0; max-width: 120px; overflow: hidden; }
.topnav-user .who .muted { color: #94a3b8; }
/* The clock is `.muted` but hangs off .topnav-right, not .who — so it kept
   the slate-500 body colour and stayed at 3.75:1. One rule for the whole bar. */
.topnav .muted { color: #94a3b8; }
.topnav-user button { background: none; color: #94a3b8; font-size: 17px; }
.topnav-user button:hover { color: #e2e8f0; }
.topnav .pill-label { color: #94a3b8; }
/* The brand colour IS the dark bar now — a slate-900 dot on it is nothing. */
.topnav .dot { background: #fff; }

/* Drop the decorative chrome before the menus have to start scrolling: the
   sub-brand first, then the user's name (the avatar still identifies them). */
@media (max-width: 1100px) { .topnav-user .who { display: none; } }

/* Menu bar — each top-level entry owns a dropdown panel */
/* The menus get a row to themselves and WRAP onto a second line when they run
   out of width. They used to share row 1 and scroll sideways, which quietly hid
   whichever menus didn't fit — Finance was cut in half and Setup was gone
   entirely. Wrapping means every menu is reachable at any window size. */
.menubar { display: flex; align-items: center; gap: 2px; flex-wrap: wrap;
  padding-bottom: 7px; }
.menu { position: relative; flex-shrink: 0; }
.menu > .menu-top { display: flex; align-items: center; gap: 5px; background: transparent; color: #cbd5e1;
  font-size: 13.5px; font-weight: 600; padding: 8px 9px; border-radius: 9px; cursor: pointer; white-space: nowrap; }
.menu > .menu-top:hover { background: var(--sidebar-2); color: #fff; }
.menu.open > .menu-top { background: var(--sidebar-2); color: #fff; }
.menu.has-active > .menu-top { color: #fff; }
.menu > .menu-top .chev { font-size: 9px; opacity: .6; }
/* The panel is light on a dark bar: it belongs to the page below it, not the bar. */
/* `position: fixed`, not absolute: the bar scrolls sideways when the menus
   don't fit, and a scroll container CANNOT show a child that escapes it —
   setting overflow-x makes overflow-y compute to auto as well, which silently
   clipped every panel to the height of the bar. Fixed takes the panel out of
   that box entirely; keepOnScreen() positions it under its button. */
.dropdown { display: none; position: fixed; z-index: 80;
  min-width: 226px; background: var(--card); border: 1px solid var(--line); border-radius: 12px;
  padding: 6px; box-shadow: 0 14px 38px rgba(15, 23, 42, .18); }
.menu.open > .dropdown { display: block; }
.dropdown { overflow-y: auto; }
.menu.open > .dropdown.sectioned { display: grid; gap: 2px 8px; padding: 8px 8px 6px; }
.dd-sec { min-width: 0; }
.dd-head { font-size: 11px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
  color: var(--muted); padding: 8px 11px 5px; white-space: nowrap; }
.dd-sec + .dd-sec { border-inline-start: 1px solid var(--line); padding-inline-start: 8px; }
.nav-item { padding: 9px 11px; border-radius: 8px; color: var(--ink); cursor: pointer; font-size: 13.5px; white-space: nowrap; }
.nav-item:hover { background: #f1f5f9; }
.nav-item.active { background: var(--accent); color: #fff; font-weight: 600; }
/* Top-level entries with no dropdown (Dashboard, Notifications) sit in the bar itself */
.menubar > .nav-item { color: #cbd5e1; font-weight: 600; padding: 8px 9px; }
.menubar > .nav-item:hover { background: var(--sidebar-2); color: #fff; }
.menubar > .nav-item.active { background: var(--accent); color: #fff; }

.crumb { display: none; font-weight: 600; color: #e2e8f0; }
.main { display: flex; flex-direction: column; min-width: 0; min-height: 0; overflow: hidden; }
.crumb { font-weight: 700; font-size: 16px; }
.pill { background: var(--accent-soft); color: var(--accent-ink); font-weight: 600; padding: 5px 12px; border-radius: 999px; font-size: 12.5px; }
.view { flex: 1; overflow: auto; min-height: 0; }

/* Hamburger + off-canvas scrim — inert on desktop, activated in the mobile media query */
.menu-btn { display: none; background: transparent; color: #cbd5e1; font-size: 22px; line-height: 1; padding: 4px 8px; border-radius: 10px; flex-shrink: 0; }
.menu-btn:hover { background: var(--sidebar-2); color: #fff; }
.scrim { display: none; }

/* Any table can scroll sideways instead of forcing the page to overflow */
.table-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; }

/* Modules */
.module { padding: 22px; }
.module h2 { margin: 0 0 4px; }
.bar { display: flex; gap: 10px; align-items: center; margin: 14px 0; flex-wrap: wrap; }
.bar input, .bar select { padding: 10px 12px; border: 1px solid var(--control-border); border-radius: 10px; background: var(--card); }
.btn { background: var(--accent); color: #fff; font-weight: 700; padding: 10px 16px; border-radius: 10px; }
.btn:hover { background: var(--accent-d); }
/* Disabled + async-busy button feedback (used app-wide, incl. auto-busy drawer
   footers). The app had no disabled styling, so disabled buttons looked active. */
.btn:disabled, .btn[disabled] { opacity: .5; cursor: not-allowed; }
.btn.is-loading { opacity: .7; cursor: progress; }
.btn.green { background: var(--ok); color: #fff; }
.tiles { display: grid; grid-template-columns: repeat(auto-fit, minmax(190px,1fr)); gap: 16px; margin-bottom: 20px; }
.tile { background: var(--card); border: 1px solid var(--line); border-radius: 14px; padding: 20px; box-shadow: var(--shadow); }
.tile .n { font-size: 28px; font-weight: 800; } .tile.warn .n { color: var(--danger); }
.dtable { width: 100%; border-collapse: collapse; background: var(--card); border: 1px solid var(--line); border-radius: 14px; overflow: hidden; box-shadow: var(--shadow); }
.dtable th, .dtable td { text-align: left; padding: 12px 16px; border-bottom: 1px solid var(--line); }
.dtable th { background: #f8fafc; color: var(--muted); font-size: 12.5px; text-transform: uppercase; letter-spacing: .4px; }
.dtable tbody tr:last-child td { border-bottom: 0; }
.dtable tfoot td { background: #f8fafc; border-top: 2px solid var(--line); border-bottom: 0; }
.dtable td.num, .dtable th.num { text-align: right; font-variant-numeric: tabular-nums; }
.qty-badge { font-weight: 700; padding: 2px 10px; border-radius: 999px; background: var(--accent-soft); color: var(--accent-ink); }
.qty-badge.low { background: #fef2f2; color: var(--danger-ink); }
.qty-badge.ok { background: var(--ok-bg); color: var(--ok); }
.qty-badge.over { background: #fff7ed; color: #c2410c; }
.scan-box { margin: 6px 0 4px; }
.scan-box input { width: 100%; max-width: 520px; padding: 14px 18px; font-size: 16px; border: 2px solid var(--accent); border-radius: 12px; background: var(--card); }
.scan-box input:focus { outline: 3px solid #cbd5e1; }
.card-form h3 { margin: 2px 0 4px; font-size: 14px; font-weight: 700; color: var(--ink); }
/* Bare section headings placed directly in a drawer body (e.g. salary
   Allowances/Deductions) — keep them below the drawer title's size. */
.drawer-body > h3 { margin: 16px 0 6px; font-size: 14px; font-weight: 700; }
.card-form { background: var(--card); border: 1px solid var(--line); border-radius: 14px; padding: 18px; box-shadow: var(--shadow); max-width: 560px; margin-bottom: 18px; display: grid; gap: 10px; }
.card-form .row { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.card-form input, .card-form select { padding: 10px 12px; border: 1px solid var(--control-border); border-radius: 10px; background: #f8fafc; }
.grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px,1fr)); gap: 10px; }
.prod { background: var(--card); border: 1px solid var(--line); border-radius: 12px; padding: 12px; cursor: pointer; box-shadow: var(--shadow); }
.prod:hover { border-color: var(--accent); }
.prod .name { font-weight: 600; } .prod .price { color: var(--accent-ink); font-weight: 700; margin-top: 4px; }
.toast { position: fixed; bottom: 22px; left: 50%; transform: translateX(-50%); background: #0f172a; color: #fff; padding: 12px 20px; border-radius: 12px; box-shadow: 0 10px 30px rgba(2,6,23,.4); opacity: 0; transition: .2s; }
.toast.show { opacity: 1; transform: translateX(-50%) translateY(-4px); }
.toast.ok { background: var(--ok); } .toast.bad { background: var(--danger); }
.toast.warn { background: #b45309; }

/* Page header with title + right-aligned actions */
.page-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; margin-bottom: 6px; }
.page-head .title h2 { margin: 0; }
.page-head .title p { margin: 4px 0 0; }
.page-head .actions { display: flex; gap: 10px; flex-shrink: 0; }
.btn.ghost { background: var(--accent-soft); color: var(--accent-ink); }
.btn.ghost:hover { background: var(--accent-soft-2); }
.btn.sm { padding: 7px 12px; font-size: 13px; border-radius: 9px; }
.btn.icon { background: transparent; color: var(--muted); padding: 6px 8px; }
.btn.icon:hover { background: #f1f5f9; color: var(--ink); }
.btn.danger { background: #fef2f2; color: var(--danger-ink); }
.btn.danger:hover { background: #dc2626; color: #fff; }
.drawer-foot .btn.danger { margin-right: auto; }
.chk { display: flex; align-items: center; gap: 8px; font-size: 13.5px; }

/* Toolbar above a list */
.toolbar { display: flex; align-items: center; gap: 10px; margin: 14px 0; flex-wrap: wrap; }
.toolbar input, .toolbar select { padding: 9px 12px; border: 1px solid var(--control-border); border-radius: 10px; background: var(--card); }
.toolbar .search { position: relative; flex: 1; min-width: 200px; max-width: 340px; }
.toolbar .search input { width: 100%; padding-left: 34px; }
.toolbar .search::before { content: "🔍"; position: absolute; left: 11px; top: 50%; transform: translateY(-50%); font-size: 13px; opacity: .5; }
.toolbar .spacer { flex: 1; }
.count-chip { color: var(--muted); font-size: 13px; }
.date-lbl { display: inline-flex; align-items: center; gap: 6px; font-size: 12.5px; color: var(--muted); }
.date-lbl input[type="date"] { padding: 8px 10px; border: 1px solid var(--control-border); border-radius: 10px; background: var(--card); font: inherit; color: var(--ink); }

/* Clickable rows + status pills */
.dtable tr.clickable { cursor: pointer; }
.dtable tr.clickable:hover td { background: var(--accent-soft); }
.dtable .mono { font-variant-numeric: tabular-nums; font-weight: 600; color: var(--accent-ink); }
/* slate-500 on the slate-100 chip is 4.34:1 — just under AA, and these chips
   carry the row's status. slate-600 reads at 6.5:1 and still looks quiet. */
.tag { display: inline-block; padding: 2px 10px; border-radius: 999px; font-size: 12px; font-weight: 600; background: var(--accent-soft); color: #475569; }
.tag.ok { background: var(--ok-bg); color: var(--ok); }
.tag.info { background: var(--accent-soft); color: var(--accent-ink); }
.tag.warn { background: #fffbeb; color: #b45309; }
.tag.bad { background: #fef2f2; color: #b91c1c; }
.avatar-sm { display: inline-flex; align-items: center; gap: 7px; }
.avatar-sm .a { width: 24px; height: 24px; border-radius: 50%; background: var(--accent); color: #fff; display: grid; place-items: center; font-size: 11px; font-weight: 700; }

/* Empty state */
.empty { text-align: center; padding: 48px 20px; color: var(--muted); background: var(--card); border: 1px dashed var(--line); border-radius: 14px; }
.empty .big { font-size: 34px; margin-bottom: 8px; }

/* Modal / drawer */
.overlay { position: fixed; inset: 0; background: rgba(15,23,42,.45); display: flex; justify-content: flex-end; z-index: 50; opacity: 0; transition: opacity .18s; }
.overlay.show { opacity: 1; }
/* Centered modal (was a right-side drawer). Sized to its content up to 88vh, so
   short forms don't leave empty space or force a scroll; taller ones scroll
   inside the body only. openDrawer adds `.overlay.center` to centre it. */
.drawer { width: min(1040px, 94vw); max-height: 88vh; background: var(--bg); border-radius: 16px; box-shadow: 0 30px 60px rgba(2,6,23,.4); display: flex; flex-direction: column; overflow: hidden; transform: translateY(10px) scale(.985); transition: transform .18s ease; }
.overlay.show .drawer { transform: none; }
.drawer-head { display: flex; align-items: center; justify-content: space-between; padding: 18px 22px; background: var(--card); border-bottom: 1px solid var(--line); }
.drawer-head h3 { margin: 0; font-size: 17px; }
.drawer-head .x { background: transparent; font-size: 22px; color: var(--muted); line-height: 1; padding: 2px 8px; }
.drawer-body { padding: 22px; overflow: auto; flex: 1 1 auto; min-height: 0; }
.drawer-foot { padding: 16px 22px; background: var(--card); border-top: 1px solid var(--line); display: flex; gap: 10px; justify-content: flex-end; }
/* Themed confirm dialog (centered) */
.overlay.center { align-items: center; justify-content: center; padding: 20px; }
.confirm { width: min(430px, 100%); background: var(--card); border-radius: 16px;
  box-shadow: 0 30px 60px rgba(2,6,23,.4); overflow: hidden;
  transform: translateY(10px) scale(.97); transition: transform .18s ease; }
.overlay.center.show .confirm { transform: none; }
.confirm-body { padding: 24px 24px 8px; }
.confirm-body h3 { margin: 0 0 8px; font-size: 18px; }
.confirm-body .msg { margin: 0; color: var(--muted); white-space: pre-line; }
/* Input fields inside a themed promptDialog (native prompt() replacement). */
.pd-field { margin-top: 12px; display: grid; gap: 5px; }
.pd-field label { font-size: 12px; font-weight: 600; color: var(--muted); text-transform: uppercase; letter-spacing: .4px; }
.pd-input { width: 100%; box-sizing: border-box; padding: 10px 12px; border: 1px solid var(--control-border); border-radius: 10px; background: var(--card); font: inherit; }

/* The themed dropdown's own styles, the drawn chevron on a closed <select> and
   the no-spinner rule for number fields now live in /shared/fields.css, loaded
   by every console. Three copies had drifted in three directions. */
.confirm-foot { display: flex; gap: 10px; justify-content: flex-end; padding: 18px 24px; }
.confirm-foot .btn { padding: 10px 18px; }
.confirm-foot .btn.danger { background: #dc2626; color: #fff; }
.confirm-foot .btn.danger:hover { background: #c81e1e; }

.field { display: grid; gap: 5px; margin-bottom: 14px; }
.field label { font-size: 12px; font-weight: 600; color: var(--muted); text-transform: uppercase; letter-spacing: .4px; }
/* width:100% so a <select> fills its grid cell exactly like the text inputs —
   without it the select shrinks to its content and looks narrower than the rest. */
.field input, .field select, .field textarea { width: 100%; box-sizing: border-box; padding: 10px 12px; border: 1px solid var(--control-border); border-radius: 10px; background: var(--card); font: inherit; }
.field.row2 { grid-template-columns: 1fr 1fr; gap: 12px; }
.field.row2 label { grid-column: 1 / -1; }
.section-card { background: var(--card); border: 1px solid var(--line); border-radius: 14px; padding: 18px; box-shadow: var(--shadow); margin-bottom: 16px; }
.section-card > h3 { margin: 0 0 12px; font-size: 13px; text-transform: uppercase; letter-spacing: .4px; color: var(--muted); }
.line-add { display: flex; gap: 8px; align-items: center; }
.line-add input { flex: 1; }
.mini-pick { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px,1fr)); gap: 8px; max-height: 200px; overflow: auto; margin-top: 8px; }
.sum-row { display: flex; justify-content: space-between; padding: 6px 0; }
.sum-row.total { border-top: 1px solid var(--line); margin-top: 6px; padding-top: 12px; font-weight: 800; font-size: 16px; }
.detail-meta { display: grid; grid-template-columns: repeat(auto-fit, minmax(140px,1fr)); gap: 14px; margin-bottom: 18px; }
.detail-meta .m label { display: block; font-size: 11px; text-transform: uppercase; letter-spacing: .4px; color: var(--muted); margin-bottom: 2px; }
.detail-meta .m .v { font-weight: 600; }

/* Segmented toggle (Simple / Variants) */
.seg { display: inline-flex; background: var(--accent-soft); border-radius: 10px; padding: 3px; gap: 3px; margin-bottom: 16px; }
/* Same 4.34:1 as .tag — the un-selected half of a segmented control is still
   a label you have to read to know what you would be switching to. */
.seg button { padding: 8px 18px; border-radius: 8px; background: transparent; color: #475569; font-weight: 600; }
.seg button.on { background: var(--card); color: var(--accent-ink); box-shadow: var(--shadow); }
.hint { font-size: 12.5px; color: var(--muted); margin: -6px 0 10px; }
.var-count { font-weight: 700; color: var(--accent-ink); }
.dtable td .thumb { width: 30px; height: 30px; border-radius: 7px; object-fit: contain; vertical-align: middle; margin-right: 8px; background: #fff; border: 1px solid var(--line); }
.attr-cell { display: inline-flex; gap: 5px; flex-wrap: wrap; }
.attr-cell .tag { background: var(--accent-soft); color: var(--accent-ink); }

/* Dashboard */
.kpis { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 14px; margin: 14px 0 18px; }
.kpi { display: flex; gap: 14px; align-items: center; background: var(--card); border: 1px solid var(--line); border-radius: 14px; padding: 16px 18px; box-shadow: var(--shadow); }
.kpi .ico { width: 44px; height: 44px; border-radius: 12px; background: var(--accent-soft); display: grid; place-items: center; font-size: 22px; flex-shrink: 0; }
.kpi .v { font-size: 24px; font-weight: 800; line-height: 1.1; } .kpi .l { font-weight: 600; font-size: 13px; } .kpi .s { font-size: 11.5px; }
.kpi.warn .ico { background: #fef2f2; } .kpi.warn .v { color: var(--danger); }
.dash-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(360px, 1fr)); gap: 16px; margin-bottom: 16px; }
.card { background: var(--card); border: 1px solid var(--line); border-radius: 14px; padding: 16px 18px; box-shadow: var(--shadow); min-width: 0; }
.card-h { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; margin-bottom: 6px; }
.card-h h3 { margin: 0; font-size: 15px; }
.chart { width: 100%; height: auto; display: block; margin-top: 6px; }
.hbars { display: flex; flex-direction: column; gap: 11px; margin-top: 6px; }
.hbar { display: grid; grid-template-columns: 150px 1fr auto; align-items: center; gap: 12px; }
.hb-name { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; font-weight: 600; }
.hb-track { height: 10px; background: var(--accent-soft); border-radius: 6px; overflow: hidden; }
.hb-fill { height: 100%; background: linear-gradient(90deg, #475569, var(--accent)); border-radius: 6px; }
.hb-val { font-variant-numeric: tabular-nums; font-weight: 700; white-space: nowrap; font-size: 13px; }
/* Inline bar inside a table cell (Store Performance leaderboard) */
.cellbar { display: flex; flex-direction: column; gap: 5px; align-items: flex-end; min-width: 120px; }
.cellbar .hb-track { width: 100%; }
.lowlist { display: flex; flex-direction: column; }
.lowrow { display: flex; justify-content: space-between; align-items: center; padding: 9px 0; border-bottom: 1px solid var(--line); }
.lowrow:last-child { border-bottom: 0; }

/* Tax invoice (ZATCA) preview in the drawer */
.tax-invoice .ti-head { display: flex; justify-content: space-between; align-items: flex-start; border-bottom: 2px solid var(--ink); padding-bottom: 10px; }
.tax-invoice .ti-co { font-size: 18px; font-weight: 800; }
.tax-invoice .ti-title { text-align: center; font-size: 16px; font-weight: 800; margin: 14px 0 8px; }
.tax-invoice .ti-table { width: 100%; border-collapse: collapse; margin-top: 4px; }
.tax-invoice .ti-table th, .tax-invoice .ti-table td { border: 1px solid var(--line); padding: 7px 9px; text-align: left; }
.tax-invoice .ti-table th { background: #f8fafc; color: var(--muted); font-size: 12px; }
.tax-invoice .ti-table .r, .tax-invoice .r { text-align: right; font-variant-numeric: tabular-nums; }
.tax-invoice .ti-foot { display: flex; justify-content: space-between; align-items: flex-start; margin-top: 16px; gap: 18px; }
.tax-invoice .ti-qr { text-align: center; font-size: 11px; color: var(--muted); }
.tax-invoice .ti-qr img { width: 128px; height: 128px; display: block; border: 1px solid var(--line); border-radius: 8px; }
.tax-invoice .ti-tot { min-width: 240px; margin-left: auto; }

/* Category tree */
.cat-card { background: var(--card); border: 1px solid var(--line); border-radius: 14px; box-shadow: var(--shadow); margin-bottom: 12px; overflow: hidden; }
.cat-row { display: grid; grid-template-columns: 1fr auto auto; align-items: center; gap: 12px; padding: 12px 16px; border-bottom: 1px solid var(--line); }
.cat-row:last-child { border-bottom: 0; }
.cat-row.root .cat-name { font-weight: 700; font-size: 14.5px; }
.cat-row.sub { background: var(--accent-soft); padding-left: 30px; }
.cat-row.sub .cat-name { color: var(--muted); }
.cat-meta { color: var(--muted); font-size: 12.5px; }
.cat-actions { display: flex; gap: 6px; align-items: center; }

/* Topbar store selector */
.bell { position: relative; background: transparent; color: #cbd5e1; font-size: 18px; line-height: 1; padding: 6px 8px; border-radius: 10px; }
.bell:hover { background: #f1f5f9; }
.bell .badge { position: absolute; top: -1px; right: -1px; background: #dc2626; color: #fff;
  font-size: 10px; font-weight: 800; min-width: 16px; height: 16px; border-radius: 999px;
  display: grid; place-items: center; padding: 0 4px; }
.pill-label { color: var(--muted); font-size: 12px; text-transform: uppercase; letter-spacing: .5px; }
.pill-select { background: var(--accent-soft); color: var(--accent-ink); font-weight: 700; border: 1px solid var(--accent-soft-2);
  padding: 7px 30px 7px 14px; border-radius: 999px; font-size: 13px; cursor: pointer;
  appearance: none; -webkit-appearance: none;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%23334155' stroke-width='3'><path d='M6 9l6 6 6-6'/></svg>");
  background-repeat: no-repeat; background-position: right 11px center; }
.pill-select:focus { outline: 2px solid var(--accent); }

/* Form controls that sit side-by-side in a row (data tables, journal-entry
   lines, attachment rows) share one compact height, so a <select> lines up with
   the inputs beside it (e.g. the PR lines' supplier dropdown, JV account picker). */
.dtable input, .dtable select, .dtable textarea,
.line-add input, .line-add select,
.sample-att-add select { padding: 6px 8px; }
.dtable select:not(.pill-select), .line-add select:not(.pill-select), .sample-att-add select:not(.pill-select) { padding-right: 26px; background-position: right 8px center; }
.rtl .dtable select:not(.pill-select), .rtl .line-add select:not(.pill-select), .rtl .sample-att-add select:not(.pill-select) { padding-right: 8px; padding-left: 26px; background-position: left 8px center; }

/* Scan / search-to-add box (replaces the messy product grid) */
.itemsearch { position: relative; flex: 1; min-width: 240px; max-width: 460px; }
.itemsearch input { width: 100%; padding: 11px 14px 11px 38px; border: 1px solid var(--control-border); border-radius: 10px; background: var(--card); font: inherit; }
.itemsearch::before { content: "🔍"; position: absolute; left: 13px; top: 12px; font-size: 14px; opacity: .5; pointer-events: none; }
.itemsearch input:focus { outline: 2px solid var(--accent); border-color: transparent; }
.isresults { position: absolute; z-index: 20; left: 0; right: 0; top: calc(100% + 4px); background: var(--card);
  border: 1px solid var(--line); border-radius: 12px; box-shadow: 0 16px 40px rgba(2,6,23,.18); overflow: hidden; max-height: 320px; overflow-y: auto; }
.isrow { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 10px 14px; cursor: pointer; border-bottom: 1px solid var(--line); }
.isrow:last-child { border-bottom: 0; }
.isrow:hover, .isrow.hi { background: var(--accent-soft); }
.isrow .nm { font-weight: 600; display: flex; align-items: center; gap: 8px; }
.isrow .meta { color: var(--muted); font-size: 12.5px; font-variant-numeric: tabular-nums; white-space: nowrap; }
.isrow .thumb { width: 26px; height: 26px; border-radius: 6px; object-fit: contain; background: #fff; border: 1px solid var(--line); }
.transfer-head { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin: 14px 0; }
.transfer-head select { padding: 10px 12px; border: 1px solid var(--control-border); border-radius: 10px; background: var(--card); font: inherit; min-width: 190px; }
.transfer-head .arrow { color: var(--muted); font-weight: 700; }

/* ─────────────────────────────────────────────────────────────────────────
   Mobile / tablet-portrait — sidebar becomes an off-canvas drawer, grids
   collapse to a single column, wide tables scroll sideways.
   ───────────────────────────────────────────────────────────────────────── */
@media (max-width: 860px) {
  /* There is no room for a menu bar on a phone, so the menus drop down as one
     stacked panel under the header and the crumb takes over saying where you
     are. Same markup, same handlers — only the layout changes. */
  .topnav { padding: 0 12px; }
  .topnav-main { gap: 8px; }
  .topnav-brand .brand-sub { display: none; }
  .topnav-user .who { display: none; }
  .menu-btn { display: inline-flex; align-items: center; }
  .crumb { display: block; font-size: 15px; flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

  .menubar {
    display: none; position: fixed; top: 56px; left: 0; right: 0; z-index: 60;
    flex-direction: column; align-items: stretch; gap: 2px;
    /* one column that scrolls — the desktop bar wraps, and a tall open group
       used to wrap the phone menu into side-by-side columns */
    flex-wrap: nowrap;
    background: var(--sidebar); padding: 8px 10px 14px;
    max-height: calc(100vh - 56px); overflow-y: auto;
    box-shadow: 0 24px 50px rgba(2,6,23,.45);
  }
  .app.nav-open .menubar { display: flex; }
  /* Stacked, not floating: a dropdown panel positioned over a phone screen
     would fall off the edge, so open groups just expand in place. */
  /* icon + label read as one thing; only the chevron goes to the far side */
  .menu > .menu-top { width: 100%; justify-content: flex-start; }
  .menu > .menu-top .chev { margin-left: auto; }
  .rtl .menu > .menu-top .chev { margin-left: 0; margin-right: auto; }
  .dropdown { position: static; display: none; min-width: 0; margin: 2px 0 6px;
    box-shadow: none; background: transparent; border: 0; border-left: 1px solid #223049;
    border-radius: 0; padding: 0 0 0 10px; }
  .rtl .dropdown { border-left: 0; border-right: 1px solid #223049; padding: 0 10px 0 0; }
  .menu.open > .dropdown { display: block; }
  .menu.open > .dropdown.sectioned { display: block; padding: 0 0 0 10px; max-height: none; }
  .rtl .menu.open > .dropdown.sectioned { padding: 0 10px 0 0; }
  .dd-sec + .dd-sec { border: 0; padding: 0; }
  .dd-head { color: #64748b; padding: 10px 11px 3px; }
  .dropdown .nav-item { color: #94a3b8; }
  .dropdown .nav-item:hover { background: var(--sidebar-2); color: #e2e8f0; }

  /* Backdrop behind the open menu */
  .scrim { display: block; position: fixed; inset: 0; z-index: 55;
    background: rgba(15,23,42,.45); opacity: 0; pointer-events: none; transition: opacity .2s; }
  .app.nav-open .scrim { opacity: 1; pointer-events: auto; }

  .topnav-right { gap: 4px; }
}

/* Phone: the brand, the store picker and the menu button are all the header can
   hold. The crumb goes — the screen's own <h1> is directly beneath it and says
   the same thing — rather than being squeezed down to one letter. */
@media (max-width: 560px) {
  .crumb { display: none; }
  .topnav-user { padding-left: 6px; margin-left: 0; }
  .topnav-user .avatar { display: none; }
  .pill-select { max-width: 38vw; }
  .pill-label { display: none; }               /* keep just the store <select> */
  .pill-select { max-width: 46vw; }

  /* Tighter content padding */
  .module { padding: 16px 12px; }

  /* Single-column grids so nothing overflows a phone screen */
  .dash-grid { grid-template-columns: 1fr; }
  .kpis { grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); }
  .tiles { grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); }
  .detail-meta { grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); }

  /* Forms stack their two-up rows */
  .card-form .row, .field.row2 { grid-template-columns: 1fr; }
  .card-form { max-width: none; }

  /* Page header: title over actions, actions wrap */
  .page-head { flex-direction: column; align-items: stretch; }
  .page-head .actions { flex-wrap: wrap; }

  /* Dashboard bars: drop the fixed 150px name column */
  .hbar { grid-template-columns: 110px 1fr auto; gap: 8px; }
  .hb-name { font-size: 12.5px; }

  /* Transfer picker stacks */
  .transfer-head { gap: 8px; }
  .transfer-head select { min-width: 0; width: 100%; }
  .transfer-head .arrow { display: none; }

  /* Drawer/modal goes full-width */
  .drawer { width: 96vw; max-height: 92vh; }

  /* Tables never widen the page — they scroll within their wrapper */
  .table-wrap { border-radius: 14px; }
  .dtable { min-width: 560px; }
}

@media (max-width: 460px) {
  .seg { display: flex; }
  .seg button { flex: 1; padding: 8px 10px; }
  .kpis, .tiles { grid-template-columns: 1fr 1fr; }
  .bar, .toolbar { gap: 8px; }
}

/* Multi-select chips + checkbox grids (promotions, etc.) */
.chips { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 6px; }
.chip { display: inline-flex; align-items: center; gap: 6px; background: var(--accent-soft); color: var(--accent-ink); font-weight: 600; font-size: 12.5px; padding: 4px 6px 4px 10px; border-radius: 999px; }
.chip button { background: rgba(15,23,42,.10); color: var(--accent-ink); border-radius: 50%; width: 16px; height: 16px; line-height: 1; font-size: 11px; padding: 0; }
.chip button:hover { background: #dc2626; color: #fff; }
.chk-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); gap: 6px 14px; margin-top: 4px; }
.chk-grid .chk { font-size: 13px; }

/* ── Language toggle + Arabic RTL ─────────────────────────────────────────── */
.lang-btn { background: var(--accent-soft); color: var(--accent-ink); font-weight: 800; border: 1px solid var(--accent-soft-2);
  width: 34px; height: 34px; border-radius: 999px; font-size: 14px; cursor: pointer; }
.lang-btn:hover { background: var(--accent-soft-2); }

body.rtl { font-family: "Segoe UI", Tahoma, "Noto Kufi Arabic", "Geeza Pro", Arial, sans-serif; }
/* nav sub-tree border sits on the right in RTL */
.rtl .nav-item, .rtl .menu > .menu-top { text-align: right; }
/* drawer slides in from the LEFT in RTL */
.rtl .overlay.center { justify-content: center; }
.rtl .drawer { transform: translateY(10px) scale(.985); box-shadow: 0 30px 60px rgba(2,6,23,.4); }
.rtl .overlay.show .drawer { transform: none; }
.rtl .drawer-foot { justify-content: flex-start; }
.rtl .drawer-foot .btn.danger { margin-right: 0; margin-left: auto; }
/* tables: labels right-aligned, numeric columns stay left(=numeric side) */
.rtl .dtable th:not(.num), .rtl .dtable td:not(.num) { text-align: right; }
.rtl .dtable td.num, .rtl .dtable th.num { text-align: left; }
.rtl .search::before, .rtl .itemsearch::before { left: auto; right: 11px; }
.rtl .search input, .rtl .itemsearch input { padding-left: 12px; padding-right: 34px; }
.rtl .pill-select { padding: 7px 14px 7px 30px; background-position: left 11px center; }
.rtl .toolbar .spacer, .rtl .page-head .actions { margin-left: 0; }
.rtl .ti-tot, .rtl .hb-val { margin-left: 0; }
.rtl .kpi .ico { margin-left: 4px; }

/* Settings rows + toggle switches */
.set-row { display: flex; align-items: center; justify-content: space-between; gap: 20px;
  padding: 12px 0; border-bottom: 1px solid var(--line); }
.section-card .set-row:last-child { border-bottom: 0; padding-bottom: 0; }
.set-txt { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.set-txt b { font-weight: 650; font-size: 14px; }
.set-txt .muted { font-size: 12.5px; line-height: 1.45; }
input.switch { appearance: none; -webkit-appearance: none; flex: 0 0 auto;
  width: 44px; height: 25px; border-radius: 999px; background: #cbd5e1; position: relative;
  cursor: pointer; transition: background .18s; }
input.switch::after { content: ""; position: absolute; top: 3px; left: 3px; width: 19px; height: 19px;
  border-radius: 50%; background: #fff; box-shadow: 0 1px 3px rgba(0,0,0,.25); transition: transform .18s; }
input.switch:checked { background: var(--accent); }
input.switch:checked::after { transform: translateX(19px); }
.rtl input.switch:checked::after { transform: translateX(-19px); }

/* Logo picker */
.logo-pick { display: flex; align-items: center; gap: 14px; }
.logo-box { width: 96px; height: 64px; flex: 0 0 auto; border: 1px dashed var(--line); border-radius: 10px;
  background: #f8fafc; display: grid; place-items: center; overflow: hidden; padding: 6px; text-align: center; }
.logo-box img { max-width: 100%; max-height: 100%; object-fit: contain; }
.logo-box .muted { font-size: 11.5px; line-height: 1.3; }
.logo-actions { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.logo-actions .hint { margin: 0; flex-basis: 100%; }
.logo-actions label.btn { display: inline-flex; align-items: center; cursor: pointer; }
/* Logo on the tax invoice */
.tax-invoice .ti-id { display: flex; align-items: flex-start; gap: 12px; }
.tax-invoice .ti-logo { max-width: 92px; max-height: 60px; object-fit: contain; }

/* ── Visual Report ─────────────────────────────────────────────────────────── */
.vr-meta { margin: 2px 0 14px; font-size: 13px; }
.vr-cols { position: relative; }
.vr-cols-panel { position: absolute; top: calc(100% + 6px); left: 0; z-index: 20;
  background: var(--card); border: 1px solid var(--line); border-radius: 12px;
  box-shadow: 0 12px 30px rgba(2,6,23,.16); padding: 10px 12px; min-width: 180px;
  display: grid; gap: 6px; }
.vr-cols-panel label { display: flex; align-items: center; gap: 8px; font-size: 13px; cursor: pointer; white-space: nowrap; }
.rtl .vr-cols-panel { left: auto; right: 0; }

.vr-filters { background: var(--card); border: 1px solid var(--line); border-radius: 14px;
  padding: 16px 18px; margin: 0 0 14px; box-shadow: var(--shadow); display: grid; gap: 14px; }
.vr-frow2 { display: flex; flex-wrap: wrap; gap: 14px; }
.vr-frow2 label { display: grid; gap: 4px; font-size: 12px; font-weight: 600; color: var(--muted); }
.vr-frow2 input { padding: 8px 10px; border: 1px solid var(--control-border); border-radius: 9px; background: #f8fafc; font: inherit; color: var(--ink); min-width: 120px; }
.vr-frow { display: grid; grid-template-columns: 96px 1fr; gap: 12px; align-items: start; }
.vr-flabel { font-size: 12px; font-weight: 700; color: var(--muted); text-transform: uppercase; letter-spacing: .4px; padding-top: 6px; }
.vr-chips { display: flex; flex-wrap: wrap; gap: 6px; }
.vr-chip { padding: 5px 12px; border-radius: 999px; background: var(--accent-soft); color: var(--accent-ink);
  font-size: 12.5px; font-weight: 600; border: 1px solid transparent; cursor: pointer; }
.vr-chip:hover { background: var(--accent-soft-2); }
.vr-chip.on { background: var(--accent); color: #fff; }
.vr-factions { display: flex; justify-content: flex-end; }

.vr-actives { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 12px; }
.vr-actives:empty { display: none; }
.vr-active { padding: 5px 12px; border-radius: 999px; background: #eef2ff; color: #3730a3;
  font-size: 12.5px; font-weight: 600; cursor: pointer; border: 1px solid #e0e7ff; }
.vr-active:hover { background: #e0e7ff; }
.vr-neg { color: var(--danger-ink); }

/* Cards */
.vr-cards { display: grid; grid-template-columns: repeat(auto-fill, minmax(190px, 1fr)); gap: 16px; }
.vr-card { background: var(--card); border: 1px solid var(--line); border-radius: 14px; overflow: hidden;
  box-shadow: var(--shadow); cursor: pointer; transition: transform .12s, box-shadow .12s; }
.vr-card:hover { transform: translateY(-3px); box-shadow: 0 12px 26px rgba(2,6,23,.12); }
.vr-card-img { aspect-ratio: 1 / 1; background: var(--accent-soft); display: grid; place-items: center; overflow: hidden; }
.vr-card-img img { width: 100%; height: 100%; object-fit: contain; background: #fff; }
.vr-ph { font-size: 40px; opacity: .35; }
.vr-ph.big { font-size: 80px; }
.vr-card-b { padding: 12px 14px; }
.vr-card-t { font-weight: 700; line-height: 1.25; }
.vr-card-code { font-size: 12px; margin-top: 2px; }
.vr-card-meta { font-size: 12px; color: var(--muted); margin-top: 6px; }
.vr-card-nums { display: flex; gap: 16px; margin-top: 12px; padding-top: 10px; border-top: 1px solid var(--line); }
.vr-card-nums > div { display: grid; gap: 2px; }
.vr-card-nums span { font-size: 11px; } .vr-card-nums b { font-size: 15px; }

/* Sizes × Colours pivot */
.vr-cap { margin-bottom: 10px; font-size: 13px; }
.vr-matrix th.vr-colhdr { border-left: 1px solid var(--line); }
.vr-matrix td, .vr-matrix th { padding: 9px 12px; }
.vr-matname { text-align: left; font-weight: 600; white-space: nowrap; }
.rtl .vr-matname { text-align: right; }
.vr-dot { color: var(--line); }

/* Lightbox */
.vr-lb { width: min(460px, 94vw); background: var(--card); border-radius: 18px; overflow: hidden;
  box-shadow: 0 30px 70px rgba(2,6,23,.5); transform: scale(.96); transition: transform .18s; }
.overlay.center.show .vr-lb { transform: none; }
.vr-lb-head { display: flex; align-items: flex-start; justify-content: space-between; padding: 16px 18px 10px; }
.vr-lb-t { font-size: 17px; font-weight: 800; }
.vr-lb-head .x { background: transparent; border: 0; font-size: 24px; line-height: 1; color: var(--muted); cursor: pointer; }
.vr-lb-img { aspect-ratio: 4 / 3; background: var(--accent-soft); display: grid; place-items: center; overflow: hidden; }
.vr-lb-img img { width: 100%; height: 100%; object-fit: contain; }
.vr-lb-meta { display: grid; grid-template-columns: 1fr 1fr; gap: 10px 18px; padding: 16px 18px; }
.vr-lb-meta > div { display: flex; justify-content: space-between; gap: 10px; border-bottom: 1px solid var(--line); padding-bottom: 6px; }
.vr-lb-meta span { font-size: 12.5px; } .vr-lb-meta b { font-size: 13.5px; }
.vr-caret { font-size: 10px; margin-left: 4px; color: var(--accent-ink); }
.dtable th.sortable { cursor: pointer; user-select: none; }
.dtable th.sortable:hover { color: var(--ink); }

/* ── Stock Rebalance ────────────────────────────────────────────────────────
   The branch x size grid the buyers already read, but coloured by how long the
   stock will LAST rather than by whether the cell is zero. The five states are
   ordered by how much money is at stake: losing sales first. */
.rb-picks { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 10px; }
.rb-pick { text-align: left; padding: 8px 12px; border: 1px solid var(--line);
  border-radius: 10px; background: #fff; cursor: pointer; font: inherit; }
.rb-pick:hover { border-color: var(--accent); background: var(--accent-soft); }
.rb-pick .nm { display: block; font-weight: 700; font-size: 13.5px; }
.rb-pick .meta { display: block; font-size: 11.5px; color: var(--muted); margin-top: 1px; }

.rb-head { display: flex; align-items: flex-start; gap: 14px; margin-bottom: 12px; }
.rb-img { width: 72px; height: 72px; object-fit: contain; border-radius: 10px;
  background: var(--accent-soft); flex-shrink: 0; }
.rb-attrs { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 6px; }
.rb-attr { font-size: 11.5px; color: var(--muted); background: var(--accent-soft);
  padding: 3px 9px; border-radius: 999px; }
.rb-attr b { color: var(--accent-ink); font-weight: 700; }

.rb-kpis { display: grid; grid-template-columns: repeat(auto-fit, minmax(104px, 1fr)); gap: 8px; }
.rb-kpi { border: 1px solid var(--line); border-radius: 10px; padding: 8px 10px; background: #fff; }
.rb-kpi .k { display: block; font-size: 11px; color: var(--muted); text-transform: uppercase;
  letter-spacing: .03em; }
.rb-kpi b { font-size: 17px; }
.rb-kpi.good b { color: var(--ok); }
.rb-kpi.bad b { color: var(--danger-ink); }

/* Suggestions read as sentences, because a manager has to be able to disagree
   with one. A number with no reason behind it just gets clicked. */
.rb-sugs { display: flex; flex-direction: column; gap: 6px; }
.rb-sug { display: grid; grid-template-columns: auto 1fr; gap: 4px 10px; align-items: center;
  padding: 9px 12px; border: 1px solid var(--line); border-radius: 10px; cursor: pointer; }
.rb-sug:hover { border-color: var(--accent); background: var(--accent-soft); }
.rb-move { font-size: 13.5px; }
.rb-move .arrow { color: var(--accent-ink); font-weight: 600; margin: 0 6px; }
.rb-why { grid-column: 2; font-size: 12px; color: var(--muted); line-height: 1.45; }
.ok-line { color: var(--ok); }

.rb-legend { display: flex; flex-wrap: wrap; gap: 6px; margin: 8px 0 12px; }
.rb-key { font-size: 11px; font-weight: 700; padding: 3px 10px; border-radius: 999px; }

.rb-grid-wrap { margin-top: 14px; overflow-x: auto; }
.rb-colour { font-weight: 800; font-size: 13px; margin-bottom: 6px; }
.rb-grid { border-collapse: collapse; min-width: 100%; }
.rb-grid th, .rb-grid td { border: 1px solid var(--line); padding: 6px 10px; text-align: center;
  font-size: 12.5px; }
.rb-grid thead th { background: var(--accent-soft); font-weight: 700; }
.rb-loc { text-align: left !important; font-weight: 700; white-space: nowrap; background: #fff; }
.rb-loc .cc { font-weight: 500; color: var(--muted); font-size: 10.5px; margin-left: 6px; }
.rb-tot { font-weight: 800; background: var(--accent-soft); }
.rb-cell { min-width: 54px; }
.rb-cell .oh { display: block; font-weight: 700; }
/* Units sold in the window, under the stock figure — the two numbers the whole
   decision rests on, in one cell. */
.rb-cell .sd { display: block; font-size: 10px; opacity: .75; }
.rb-cell .sd:not(:empty)::before { content: "sold "; }

.rb-lost { background: #fee2e2; color: #991b1b; }
.rb-low  { background: #ffedd5; color: #9a3412; }
.rb-ok   { background: #dcfce7; color: #166534; }
.rb-over { background: #e0e7ff; color: #3730a3; }
.rb-dead { background: #f1f5f9; color: #475569; }
.rb-none { background: #fff; color: #cbd5e1; }
.rb-result { margin: 6px 0 0; padding-left: 18px; font-size: 13px; line-height: 1.7; }
/* Stock already on a truck to this branch. Shown next to what is on the shelf,
   because "none left" and "none left but three arriving" are different problems. */
.rb-coming { background: #cffafe; color: #155e75; }
.rb-cell .inc { font-size: 10px; font-weight: 700; opacity: .8; margin-left: 3px; }

/* ── Stock on Hand ──────────────────────────────────────────────────────────
   Filters as controls rather than an Excel autofilter, and a totals strip that
   follows them — the point being that you never export just to add a column up. */
.soh-filters { display: flex; flex-wrap: wrap; gap: 10px 12px; align-items: flex-end; }
.soh-f { display: flex; flex-direction: column; gap: 3px; font-size: 11px; color: var(--muted); }
.soh-f.grow { flex: 1 1 240px; }
.soh-f span { text-transform: uppercase; letter-spacing: .03em; font-weight: 700; }
.soh-f select, .soh-f input { min-height: 34px; border: 1px solid var(--control-border); border-radius: 8px;
  padding: 0 9px; font-size: 13px; background: #fff; color: var(--ink); min-width: 120px; }
.soh-f.chk-f { flex-direction: row; align-items: center; gap: 6px; padding-bottom: 8px; }
.soh-tot { display: flex; flex-wrap: wrap; gap: 8px; }
.soh-tot .rb-kpi { flex: 1 1 130px; }
.soh-scroll { overflow: auto; max-height: 62vh; }
.soh-tbl { font-size: 12.5px; }
.soh-tbl thead th { position: sticky; top: 0; z-index: 1; background: var(--accent-soft); }
.soh-tbl td.r, .soh-tbl th.r { text-align: right; }
.soh-bin { width: 92px; border: 1px solid transparent; border-radius: 6px; padding: 3px 6px;
  font: inherit; font-size: 12px; background: transparent; color: var(--ink); }
.soh-bin:hover { border-color: var(--line); }
.soh-bin:focus { border-color: var(--accent); background: #fff; outline: none; }
/* Old stock is money asleep — the only ageing worth colouring. */
.soh-aging { color: #9a3412; font-weight: 700; }
.soh-old { color: #991b1b; font-weight: 800; }

/* Multi-store picker in the user editor */
.branchpick { display: grid; gap: 4px; max-height: 200px; overflow-y: auto; border: 1px solid var(--line);
  border-radius: 10px; padding: 8px 10px; background: #f8fafc; }
.branchpick .chk { display: flex; align-items: center; gap: 8px; font-size: 13.5px; cursor: pointer; margin: 0; }

/* ── Admin Management Module ─────────────────────────────────────────────────
   Definition lists in detail drawers, budget-usage bars, negative figures. */
.deflist { display: flex; flex-direction: column; gap: 2px; }
.defrow { display: flex; justify-content: space-between; gap: 16px; padding: 7px 0; border-bottom: 1px solid var(--line); }
.defrow:last-child { border-bottom: 0; }
.defrow > span:first-child { flex: 0 0 auto; }
.defrow > span:last-child { text-align: right; }
.bg-bar { display: inline-block; width: 90px; height: 8px; border-radius: 999px; background: var(--accent-soft); overflow: hidden; vertical-align: middle; margin-right: 6px; }
.bg-fill { height: 100%; border-radius: 999px; background: var(--ok); }
.bg-fill.warn { background: #d97706; }
.bg-fill.bad { background: var(--danger); }
b.neg, .neg { color: var(--danger); }
/* ── Marketing module ───────────────────────────────────────────────────────
   Additive styles for the Marketing screens (campaigns, calendar, CRM, events,
   malls, ad logs, budget, performance). Reuses the existing tokens. */
.tag.low { background: #fef2f2; color: #b91c1c; }
.tag.muted { background: var(--accent-soft); color: #475569; }
.meta-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 12px; }
.meta-grid .m label { display: block; font-size: 11px; text-transform: uppercase; letter-spacing: .4px; color: var(--muted); margin-bottom: 2px; }
.meta-grid .m .v { font-weight: 600; }
.split2 { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
.split2 > div > h3 { margin: 0 0 8px; font-size: 12px; text-transform: uppercase; letter-spacing: .4px; color: var(--muted); }
.muted.sm, .sm { font-size: 12px; }
.warn-card { border-color: #fcd34d; background: #fffbeb; }
.chk-row { display: flex; flex-wrap: wrap; gap: 6px 14px; }
.chk-inline { display: inline-flex; align-items: center; gap: 6px; font-size: 13px; cursor: pointer; }
.log-line { border-top: 1px solid var(--line); padding: 6px 0; }
.log-line:first-of-type { border-top: 0; }
.infl-line { align-items: center; }
.mkt-legend { display: flex; gap: 8px; margin-bottom: 10px; }
/* Calendar grid */
.cal-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 6px; }
.cal-dow { text-align: center; font-size: 11px; text-transform: uppercase; letter-spacing: .4px; color: var(--muted); font-weight: 600; padding-bottom: 2px; }
.cal-cell { min-height: 78px; border: 1px solid var(--line); border-radius: 8px; padding: 4px; background: #f8fafc; overflow: hidden; }
.cal-cell.empty { background: transparent; border: 0; }
.cal-day { font-size: 12px; font-weight: 700; color: #64748b; margin-bottom: 2px; }
.cal-ev { font-size: 11px; padding: 1px 5px; border-radius: 5px; margin-bottom: 2px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; background: var(--accent-soft); color: var(--accent-ink); }
.cal-ev.ok { background: var(--ok-bg); color: var(--ok); }
.cal-ev.warn { background: #fffbeb; color: #b45309; }
.cal-ev.info { background: var(--accent-soft); color: var(--accent-ink); }
td.num.ok { color: var(--ok); } td.num.low { color: #b91c1c; }
@media (max-width: 720px) { .split2 { grid-template-columns: 1fr; } }

/* ── Samples (apparel sample lifecycle) ─────────────────────────────────── */
.grid2 { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
@media (max-width: 560px) { .grid2 { grid-template-columns: 1fr; } }
.sample-detail h3 { margin: 18px 0 8px; }
.sample-info { display: grid; gap: 3px; font-size: 13px; margin: 8px 0; }
.sample-info b.bad, .rmk.bad { color: var(--danger); }
.sample-note { background: #f8fafc; border: 1px solid var(--line); border-radius: 8px; padding: 8px 10px; font-size: 13px; }
.sample-actions { flex-wrap: wrap; gap: 8px; }
.sample-msgrid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 8px; }
@media (max-width: 560px) { .sample-msgrid { grid-template-columns: 1fr; } }
.sample-ms { display: grid; gap: 3px; }
.sample-ms label { font-size: 12px; color: var(--muted); }
.sample-histlist { display: grid; gap: 8px; }
.sample-hist { border-left: 3px solid var(--line); padding: 4px 0 4px 10px; font-size: 13px; display: grid; gap: 2px; }
.sample-hist .rmk { color: var(--muted); font-size: 12.5px; }
.sample-attgrid { display: flex; flex-wrap: wrap; gap: 10px; }
.sample-att { width: 120px; border: 1px solid var(--line); border-radius: 10px; overflow: hidden; position: relative; background: var(--card); }
.sample-att img { width: 100%; height: 90px; object-fit: cover; display: block; }
.sample-att-meta { padding: 5px 6px; display: grid; gap: 3px; font-size: 11px; }
.sample-att-meta .nm { color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sample-att [data-rm] { position: absolute; top: 4px; right: 4px; }
.sample-att-add { display: flex; align-items: center; gap: 8px; margin-top: 10px; flex-wrap: wrap; }

/* Customer App → two fields side by side; banner editor rows (2026-09-11). */
.row2 { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
@media (max-width: 720px) { .row2 { grid-template-columns: 1fr; } }
.ban-row { display: grid; grid-template-columns: 160px 1fr; gap: 14px; padding: 12px 0; border-bottom: 1px solid var(--line); }
.ban-img { width: 160px; height: 90px; border-radius: 10px; background: #f1f5f9; display: grid; place-items: center; overflow: hidden; }
.ban-img img { width: 100%; height: 100%; object-fit: cover; }
@media (max-width: 720px) { .ban-row { grid-template-columns: 1fr; } }

/* Line icons (icons.js) — replace the emoji the screens are written with. */
.hq-ico-wrap { display: inline-flex; align-items: center; justify-content: center; vertical-align: -0.14em; line-height: 1; }
.hq-ico { display: block; flex-shrink: 0; }
.kpi .ico { color: var(--accent-ink); }
.kpi.warn .ico { color: var(--danger); }
.kpi .ico .hq-ico { width: 22px; height: 22px; }
.empty .big { color: var(--muted); }
.empty .big .hq-ico { width: 36px; height: 36px; stroke-width: 1.5; }
.menu > .menu-top .hq-ico, .nav-item .hq-ico { width: 16px; height: 16px; opacity: .9; }
.btn .hq-ico-wrap, button .hq-ico-wrap { margin-inline-end: 1px; }

/* Label / value rows on detail cards (employee profile, leave detail, staff login).
   They had no style at all, so "Branch" ran straight into "Dubai Store". */
.kv { display: flex; justify-content: space-between; align-items: baseline; gap: 16px;
  padding: 7px 0; border-bottom: 1px solid var(--line); font-size: 14px; }
.kv:last-child { border-bottom: 0; }
.kv > span:first-child { flex: none; }
.kv > span:last-child { text-align: end; min-width: 0; overflow-wrap: anywhere; }

/* Approval steps timeline (leave / request drawers) */
.appr-steps { list-style: none; margin: 0; padding: 0; }
.appr-steps li { display: grid; grid-template-columns: 14px 1fr auto; gap: 10px; align-items: start; padding: 8px 0; border-bottom: 1px solid var(--line); }
.appr-steps li:last-child { border-bottom: 0; }
.appr-dot { width: 10px; height: 10px; border-radius: 50%; margin-top: 5px; background: #cbd5e1; }
.appr-approved .appr-dot { background: #16a34a; } .appr-rejected .appr-dot { background: #dc2626; }
.appr-pending .appr-dot { background: #f59e0b; box-shadow: 0 0 0 4px #fef3c7; }
.appr-who { font-size: 13.5px; min-width: 0; }
/* Org chart */
.org-tree, .org-kids { list-style: none; margin: 0; padding: 0; }
.org-kids { margin-inline-start: 22px; padding-inline-start: 18px; border-inline-start: 2px solid var(--line); }
.org-node { padding: 6px 0; }
.org-card { display: flex; align-items: center; gap: 10px; padding: 8px 12px; border: 1px solid var(--line); border-radius: 12px; background: var(--card); max-width: 640px; }
.org-card.org-hit { border-color: var(--accent); box-shadow: 0 0 0 3px rgba(79, 70, 229, .12); }
.org-avatar { flex: none; width: 34px; height: 34px; border-radius: 50%; display: grid; place-items: center; background: #eef2ff; color: #3730a3; font-weight: 700; font-size: 13px; }
.org-info { display: flex; flex-direction: column; flex: 1; min-width: 0; }
.org-info .muted { font-size: 12.5px; }
/* Approval matrix */
.chain { display: inline-flex; flex-wrap: wrap; align-items: center; gap: 4px; }
.chip { display: inline-block; padding: 3px 10px; border-radius: 999px; background: #f1f5f9; font-size: 12.5px; font-weight: 600; color: #334155; }
.chip-arrow { color: #94a3b8; }
.mx-step { display: grid; grid-template-columns: 26px minmax(0, 1fr) minmax(0, 1fr) auto auto; gap: 8px; align-items: center; margin-bottom: 8px; }
.mx-n { width: 24px; height: 24px; border-radius: 50%; background: #eef2ff; color: #3730a3; display: grid; place-items: center; font-weight: 700; font-size: 12px; }
@media (max-width: 560px) { .mx-step { grid-template-columns: 26px 1fr auto auto; } .mx-step > select[data-person] { grid-column: 2 / -1; } }

/* Appraisal templates */
.tpl-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 14px; }
.tpl-kpis { display: flex; flex-direction: column; gap: 6px; }
.tpl-kpi { display: grid; grid-template-columns: minmax(0, 1fr) 120px; gap: 10px; align-items: center; font-size: 13.5px; }
.tpl-w { position: relative; height: 18px; background: #f1f5f9; border-radius: 999px; overflow: hidden; }
.tpl-w i { position: absolute; inset: 0 auto 0 0; width: var(--w); background: #c7d2fe; }
[dir=rtl] .tpl-w i { inset: 0 0 0 auto; }
.tpl-w b { position: relative; font-size: 11.5px; padding: 0 8px; line-height: 18px; }
.tpl-edit { border: 1px solid var(--line); border-radius: 12px; padding: 10px 12px; margin-bottom: 10px; }
.tpl-edit details summary, .ap-guide summary { cursor: pointer; color: var(--accent); font-size: 13px; margin: 4px 0; }
.tpl-g label { width: 18px; }
.ap-guide div { font-size: 12.5px; color: #475569; }
.ap-marks td { vertical-align: top; }
.lc-list { max-height: 320px; overflow-y: auto; border: 1px solid var(--line); border-radius: 10px; padding: 4px 8px; }
.lc-row { display: flex; gap: 8px; align-items: center; padding: 6px 2px; border-bottom: 1px solid #f1f5f9; }
.lc-row input { margin: 0; }

/* Boot splash — shown until the scripts decide between sign-in and the app, so a
   refresh is never a blank white page (the login card and app both start hidden). */
#boot { position: fixed; inset: 0; display: grid; place-items: center; background: var(--bg, #f4f6fb); z-index: 5; }
#boot i { width: 30px; height: 30px; border-radius: 50%; border: 3px solid rgba(100,116,139,.25); border-top-color: var(--accent, #0f172a); animation: boot-spin .8s linear infinite; }
@keyframes boot-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { #boot i { animation-duration: 2.4s; } }
body:has(#login:not(.hidden)) #boot, body:has(#app:not(.hidden)) #boot { display: none; }

/* Stock on Hand: the list dims while a new filter loads, instead of looking frozen */
.soh-busy { opacity: .55; pointer-events: none; transition: opacity .15s; }

/* Show / hide columns on any report table (colpick.js) */
.cp-bar { display: flex; justify-content: flex-end; margin: 0 0 8px; }
.cp-btn { display: inline-flex; align-items: center; gap: 6px; min-height: 34px; padding: 0 12px; border-radius: 999px;
  border: 1px solid var(--line, #e2e8f0); background: #fff; color: #334155; font: inherit; font-size: 13px; font-weight: 600; cursor: pointer; }
.cp-btn:hover { border-color: #94a3b8; }
.cp-btn.on { background: #0f172a; border-color: #0f172a; color: #fff; }
.cp-btn:focus-visible { outline: 2px solid #0f172a; outline-offset: 2px; }
.cp-pop { position: absolute; z-index: 60; width: 240px; max-height: 60vh; overflow: auto; padding: 10px; border-radius: 14px;
  background: #fff; border: 1px solid #e2e8f0; box-shadow: 0 14px 34px rgba(15, 23, 42, .18); }
.cp-head { display: flex; justify-content: space-between; align-items: center; margin: 2px 4px 8px; }
.cp-all { border: 0; background: none; color: #1d4ed8; font: inherit; font-size: 12.5px; font-weight: 600; cursor: pointer; }
.cp-row { display: flex; align-items: center; gap: 8px; padding: 6px 6px; border-radius: 8px; font-size: 13.5px; cursor: pointer; }
.cp-row:hover { background: #f1f5f9; }
.cp-row input { width: 16px; height: 16px; accent-color: #0f172a; }
.cp-note { margin: 8px 4px 2px; font-size: 11.5px; color: #64748b; }
/* Stock on Hand: every heading sorts */
.soh-sort { cursor: pointer; user-select: none; white-space: nowrap; }
.soh-sort:hover { color: #0f172a; text-decoration: underline; }
.soh-sort.on { color: #0f172a; }

/* Clean up colour / size names (screen-catalog.js) */
.ac-tabs { display: flex; gap: 6px; margin-bottom: 10px; }
.ac-row { display: flex; justify-content: space-between; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 10px 12px; border: 1px solid #e2e8f0; border-radius: 12px; margin-bottom: 8px; background: #fff; }
.ac-row.sus { border-color: #fcd34d; background: #fffbeb; }
.ac-v { display: flex; flex-direction: column; min-width: 120px; }
.ac-act { display: flex; gap: 6px; align-items: center; flex-wrap: wrap; }
.ac-act input { width: 130px; min-height: 32px; }
/* Stock on Hand: stock with no cost price */
.soh-warn { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; background: #fffbeb; border: 1px solid #fcd34d; color: #92400e; }
.soh-warn .btn { margin-inline-start: auto; }
.ok-note { color: #047857; font-weight: 600; }

/* Designing — the sample status, carrying the Designing team's own colour.
   Their sheet is read by colour before it is read by word, so the list keeps
   that: the colour comes from the server with the status, never hard-coded per
   screen. */
.dev-st { display: inline-block; padding: 3px 9px; border-radius: 999px; font-size: 12.5px; font-weight: 600;
  color: #12141a; background: var(--st, #9aa0a6); white-space: nowrap; }

/* Designing — the summary sheet. Their Excel is read by colour first: each
   count carries its status colour, a supplier who walked away from the whole
   file greys out, and the TOTAL row sits apart. */
.dev-sum .num { text-align: right; }
.dev-cnt { border: 0; border-radius: 6px; padding: 2px 10px; font: inherit; font-weight: 700;
  color: #12141a; background: var(--st, #9aa0a6); cursor: pointer; }
.dev-cnt:hover { filter: brightness(1.08); }
.dev-sum .dev-total td { border-top: 2px solid var(--line); background: var(--accent-soft); }
.dev-sum .dev-row-cancelled td { opacity: .55; text-decoration: line-through; }
.dev-plan { cursor: pointer; border-bottom: 1px dashed var(--line); }
