/* ============================================================
   Panaderia Pantoja Incorporated — Inventory & Accounting
   Unified ERP design system: tokens + components.

   One system for both portals. Every visual value comes from a
   token below, so the whole suite stays consistent and the
   night-mode / text-size switches only have to flip tokens.
   ============================================================ */

/* ---------- 1. Design tokens ---------- */
:root {
  /* Brand — taken from the Pantoja seal itself: the red of the arc and the
     gold of the lower half. Use --brand-red and --brand-gold wherever the mark
     is being reproduced (print rules, the logo band, the seal), so the page
     matches the printed letterhead exactly. */
  --brand-red: #ed1c24;
  --brand-gold: #ffce00;
  --brand-ink: #231f1f;       /* the near-black of the line art */
  --brand-ring: #f0f1f1;      /* the off-white ring around the seal */

  /* The interactive red is a hair deeper than the mark so button and link text
     clears WCAG AA against white — the same red to the eye, legible in use. */
  --primary: #de1a21;
  --primary-hover: #c0161c;
  --primary-active: #a01218;
  --primary-light: #fef2f2;
  --primary-border: #f5c3c5;
  --accent: #ffce00;          /* Pantoja gold — brand mark + active bar */
  --accent-text: #5a0f13;

  /* Neutrals — the light grey the brief asks for (#f1f1f1), pulled a couple of
     points warm. A dead-neutral grey turns faintly blue next to this red, and
     the two then argue; holding the canvas a shade warm keeps it reading as
     grey while letting the red and gold sit on it. */
  --bg: #f1efec;
  --surface: #ffffff;
  --surface-2: #faf8f5;       /* section fills, filter bars, totals */
  --border: #e5e0da;
  --border-strong: #d2cbc2;

  /* Sidebar — white, like the content it sits beside, so the interface reads
     as one clean surface rather than a dark rail bolted to a light page. Where
     you are is marked by a red bar and a faint red wash: the brand is the
     wayfinding, and it needs no dark ground to be visible. */
  --sidebar-bg: #ffffff;
  --sidebar-bg-2: #faf8f5;    /* the brand band and the user box */
  --sidebar-text: #5c544b;
  --sidebar-text-active: #231f20;
  --sidebar-text-strong: #231f20;   /* the company name, the signed-in name */
  --sidebar-active-bg: #fdf1f1;
  --sidebar-active-bar: #de1a21;    /* Panaderia red marks the active item */
  --sidebar-hover: #f6f3ef;
  --sidebar-group: #94897b;
  --sidebar-line: #eae5df;
  --sidebar-btn-border: #d7d0c7;
  --sidebar-btn-border-hover: #94897b;

  /* Text — warm ink, matching the letterhead */
  --text: #241f1c;
  --text-secondary: #5c544b;
  --text-muted: #94897b;
  --text-invert: #ffffff;

  /* Status — soft fills, readable text, never loud */
  --success: #1a7f47;
  --success-bg: #eaf6ef;
  --success-border: #c2e3ce;
  --warning: #91660a;
  --warning-bg: #fdf6e3;
  --warning-border: #ecdead;
  --danger: #b3261e;
  --danger-bg: #fdeeed;
  --danger-border: #f0c8c5;
  --info: #1c5f92;
  --info-bg: #eaf2f9;
  --info-border: #c3dbee;
  --neutral: #6b6157;
  --neutral-bg: #f1ede7;
  --neutral-border: #dcd4ca;
  --neutral-hover: #eae4dc;

  /* Derived surfaces (tokens so night mode can flip them) */
  --table-head-bg: #f6f3ef;
  --row-hover: #faf7f3;
  --avatar-bg: #4a3b30;
  --login-grad: #3a1113;
  --chart-track: #efebe5;
  --chart-axis: #e7e2db;
  --chart-label: #94897b;
  --dot-stroke: #ffffff;
  --focus-ring: 0 0 0 3px rgba(222, 26, 33, 0.16);
  --scrim: rgba(29, 22, 17, 0.48);

  /* Typography — one family, one scale. Every size derives from
     --fs-scale, which the "Text size" picker in the topbar sets. */
  --font: "Inter", "Segoe UI", Roboto, Arial, sans-serif;
  --font-num: "Inter", "Segoe UI", Roboto, Arial, sans-serif;
  --fs-scale: 1;
  --fs-xs: calc(11px * var(--fs-scale));      /* labels in caps, helper text */
  --fs-sm: calc(12.5px * var(--fs-scale));    /* table + form text */
  --fs-base: calc(13.5px * var(--fs-scale));  /* body */
  --fs-md: calc(15px * var(--fs-scale));      /* card / section titles */
  --fs-lg: calc(17px * var(--fs-scale));      /* dialog + login titles */
  --fs-xl: calc(20px * var(--fs-scale));      /* page title */
  --fs-kpi: calc(24px * var(--fs-scale));     /* KPI figure */

  /* Spacing scale — use these, never loose numbers */
  --sp-1: 4px;  --sp-2: 8px;  --sp-3: 12px;  --sp-4: 16px;
  --sp-5: 20px; --sp-6: 24px; --sp-8: 32px;

  /* Shape & metrics — a touch softer than default, matching the round seal */
  --radius: 8px;
  --radius-sm: 6px;
  --radius-pill: 999px;
  --shadow: 0 1px 2px rgba(16, 24, 40, 0.04), 0 1px 3px rgba(16, 24, 40, 0.05);
  --shadow-pop: 0 8px 24px rgba(16, 24, 40, 0.14);
  --shadow-modal: 0 16px 48px rgba(16, 24, 40, 0.22);
  /* controls all share one height so filter bars line up exactly */
  --control-h: calc(34px + (var(--fs-scale) - 1) * 16px);
  /* chrome grows with the text, but gently, so it never dominates */
  --sidebar-w: calc(244px + (var(--fs-scale) - 1) * 150px);
  --topbar-h: calc(52px + (var(--fs-scale) - 1) * 24px);
}

/* ---------- 1b. Night mode ----------
   Applied when the user picks Night in the topbar (data-theme="dark" on
   <html>), or by system preference when they have not chosen. The same
   token names flip, so no component rule needs a dark variant. */
:root[data-theme="dark"] {
  /* Night mode lifts the brand red until it reads on a dark surface; the gold
     is already bright enough to carry unchanged. */
  --primary: #ff6b6f;
  --primary-hover: #ff8286;
  --primary-active: #e4545a;
  --primary-light: #331a1b;
  --primary-border: #632e30;
  --accent: #ffce00;
  --accent-text: #3d0c0e;

  --bg: #16120e;
  --surface: #1f1a15;
  --surface-2: #272119;
  --border: #362f27;
  --border-strong: #4c4237;

  /* At night the sidebar goes dark with the rest of the interface, but the
     active item is still marked in red — the wayfinding does not change
     meaning between the two modes, only its ground. */
  --sidebar-bg: #191410;
  --sidebar-bg-2: #13100c;
  --sidebar-text: #a99d8e;
  --sidebar-text-active: #ffffff;
  --sidebar-text-strong: #ffffff;
  --sidebar-active-bg: #2b241c;
  --sidebar-active-bar: #ff6b6f;
  --sidebar-hover: #221c15;
  --sidebar-group: #776a58;
  --sidebar-line: rgba(255, 255, 255, 0.06);
  --sidebar-btn-border: rgba(255, 255, 255, 0.18);
  --sidebar-btn-border-hover: rgba(255, 255, 255, 0.4);

  --text: #ede8e1;
  --text-secondary: #c4bab0;
  --text-muted: #90857a;
  --text-invert: #16120e;

  --success: #5ec98a;
  --success-bg: #16301f;
  --success-border: #2b5c3d;
  --warning: #f0c05a;
  --warning-bg: #322810;
  --warning-border: #5d4a1d;
  --danger: #ef7070;
  --danger-bg: #331b1a;
  --danger-border: #613030;
  --info: #6bb3e0;
  --info-bg: #13293a;
  --info-border: #2b4d68;
  --neutral: #b1a596;
  --neutral-bg: #2b241d;
  --neutral-border: #453c32;
  --neutral-hover: #332b22;

  --table-head-bg: #272119;
  --row-hover: #292219;
  --avatar-bg: #4a3b30;
  --login-grad: #2e1214;
  --chart-track: #362f27;
  --chart-axis: #4c4237;
  --chart-label: #90857a;
  --dot-stroke: #1f1a15;
  --focus-ring: 0 0 0 3px rgba(255, 107, 111, 0.24);
  --scrim: rgba(0, 0, 0, 0.6);

  --shadow: 0 1px 2px rgba(0, 0, 0, 0.35);
  --shadow-pop: 0 8px 24px rgba(0, 0, 0, 0.5);
  --shadow-modal: 0 16px 48px rgba(0, 0, 0, 0.6);
  color-scheme: dark;
}

/* No explicit choice yet: follow the device. An explicit choice writes
   data-theme, and the rules above win because they are more specific. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    /* identical to the explicit Night block above — keep the two in step */
    --primary: #ff6b6f;
    --primary-hover: #ff8286;
    --primary-active: #e4545a;
    --primary-light: #331a1b;
    --primary-border: #632e30;
    --accent: #ffce00;
    --accent-text: #3d0c0e;

    --bg: #16120e;
    --surface: #1f1a15;
    --surface-2: #272119;
    --border: #362f27;
    --border-strong: #4c4237;

  /* At night the sidebar goes dark with the rest of the interface, but the
     active item is still marked in red — the wayfinding does not change
     meaning between the two modes, only its ground. */
  --sidebar-bg: #191410;
  --sidebar-bg-2: #13100c;
  --sidebar-text: #a99d8e;
  --sidebar-text-active: #ffffff;
  --sidebar-text-strong: #ffffff;
  --sidebar-active-bg: #2b241c;
  --sidebar-active-bar: #ff6b6f;
  --sidebar-hover: #221c15;
  --sidebar-group: #776a58;
  --sidebar-line: rgba(255, 255, 255, 0.06);
  --sidebar-btn-border: rgba(255, 255, 255, 0.18);
  --sidebar-btn-border-hover: rgba(255, 255, 255, 0.4);

    --text: #ede8e1;
    --text-secondary: #c4bab0;
    --text-muted: #90857a;
    --text-invert: #16120e;

    --success: #5ec98a;
    --success-bg: #16301f;
    --success-border: #2b5c3d;
    --warning: #f0c05a;
    --warning-bg: #322810;
    --warning-border: #5d4a1d;
    --danger: #ef7070;
    --danger-bg: #331b1a;
    --danger-border: #613030;
    --info: #6bb3e0;
    --info-bg: #13293a;
    --info-border: #2b4d68;
    --neutral: #b1a596;
    --neutral-bg: #2b241d;
    --neutral-border: #453c32;
    --neutral-hover: #332b22;

    --table-head-bg: #272119;
    --row-hover: #292219;
    --avatar-bg: #4a3b30;
    --login-grad: #2e1214;
    --chart-track: #362f27;
    --chart-axis: #4c4237;
    --chart-label: #90857a;
    --dot-stroke: #1f1a15;
    --focus-ring: 0 0 0 3px rgba(255, 107, 111, 0.24);
    --scrim: rgba(0, 0, 0, 0.6);

    --shadow: 0 1px 2px rgba(0, 0, 0, 0.35);
    --shadow-pop: 0 8px 24px rgba(0, 0, 0, 0.5);
    --shadow-modal: 0 16px 48px rgba(0, 0, 0, 0.6);
    color-scheme: dark;
  }
}

/* ---------- 2. Base ---------- */
* { box-sizing: border-box; }
html, body { height: 100%; }
body {
  margin: 0;
  font-family: var(--font);
  font-size: var(--fs-base);
  font-weight: 400;
  line-height: 1.45;
  color: var(--text);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}
h1, h2, h3, h4 { margin: 0; font-weight: 600; line-height: 1.3; }
a { color: var(--primary); text-decoration: none; }
a:hover { text-decoration: underline; }

/* Scrollbars: thin and neutral so they stop drawing the eye */
* { scrollbar-width: thin; scrollbar-color: var(--border-strong) transparent; }
*::-webkit-scrollbar { width: 10px; height: 10px; }
*::-webkit-scrollbar-track { background: transparent; }
*::-webkit-scrollbar-thumb { background: var(--border-strong); border-radius: var(--radius-pill); border: 3px solid transparent; background-clip: content-box; }
*::-webkit-scrollbar-thumb:hover { background: var(--text-muted); background-clip: content-box; }

/* ---------- 3. App shell ---------- */
.shell { display: flex; min-height: 100vh; }

/* The letterhead's red-over-gold rule, carried across the top of the chrome —
   the same signature the printed documents wear. Fixed and pointer-inert, so
   it costs nothing and never intercepts a click. */
.shell::before {
  content: "";
  position: fixed; top: 0; left: 0; right: 0; height: 5px;
  background: linear-gradient(180deg,
    var(--brand-red) 0, var(--brand-red) 60%,
    var(--brand-gold) 60%, var(--brand-gold) 100%);
  z-index: 60; pointer-events: none;
}

.sidebar {
  width: var(--sidebar-w);
  min-width: var(--sidebar-w);
  background: var(--sidebar-bg);
  color: var(--sidebar-text);
  display: flex;
  flex-direction: column;
  position: sticky;
  top: 0;
  height: 100vh;
  /* explicit desktop state, so nothing survives from the phone drawer rules
     when the window is resized back across the breakpoint */
  transform: none;
  visibility: visible;
  /* the sidebar and the content are both light now, so the boundary has to be
     drawn rather than implied by the change in ground */
  border-right: 1px solid var(--border);
  /* keep all painting inside the sidebar's own box: a stale compositing layer
     from a previous width cannot then bleed out as a second, narrower copy */
  contain: paint;
}
.sidebar .brand {
  display: flex; align-items: center; gap: 10px;
  padding: 0 var(--sp-4);
  height: var(--topbar-h);
  flex-shrink: 0;
  background: var(--sidebar-bg-2);
  border-bottom: 1px solid var(--sidebar-line);
}
/* The seal itself, not a monogram. It carries its own red ground, so it needs
   no plate behind it — only a circular crop and a size that stays legible when
   the sidebar collapses to an icon rail. */
.brand-mark {
  width: 32px; height: 32px; border-radius: 50%;
  object-fit: cover; flex-shrink: 0;
  background: var(--brand-red);
  display: flex; align-items: center; justify-content: center;
  font-weight: 700; font-size: calc(13px * var(--fs-scale));
  color: #fff; letter-spacing: -0.01em;
  /* a faint gold keyline, like the seal's own ring */
  box-shadow: 0 0 0 2px rgba(255, 206, 0, 0.28);
}
.brand-name { font-size: calc(12.5px * var(--fs-scale)); font-weight: 600; color: var(--sidebar-text-strong); line-height: 1.25; }
.brand-sub  { font-size: calc(10.5px * var(--fs-scale)); color: var(--sidebar-group); letter-spacing: 0.015em; }

.nav { flex: 1; overflow-y: auto; padding: var(--sp-2) 0 var(--sp-4); }
/* Each module group is a disclosure: the header is a real button that folds
   its screens away, so someone who lives in one module can quiet the rest.
   The chevron is the only moving part, and it moves fast — this is filing,
   not theatre. */
/* The module title carries the map: it has to be readable at a glance, not a
   faint whisper over the rows. It is set in the strong sidebar ink rather than
   the muted group grey, and each module is separated by a rule and a band so
   the eye can see where one module ends and the next begins. */
.nav-group {
  display: flex; align-items: center; justify-content: space-between; gap: 6px;
  width: 100%;
  background: var(--sidebar-bg-2); border: none; text-align: left; cursor: pointer;
  font: inherit;
  padding: var(--sp-3) var(--sp-4) var(--sp-2);
  /* Set as written rather than forced to capitals: "Items & Products" reads as
     a name, "ITEMS & PRODUCTS" reads as shouting, and mixed case gives the eye
     word-shapes to catch. Caps need wide tracking to stay legible; mixed case
     does not, so the letter-spacing comes back down. */
  font-size: calc(12.5px * var(--fs-scale)); font-weight: 700; letter-spacing: 0.005em;
  color: var(--sidebar-text-strong);
  border-top: 1px solid var(--sidebar-line);
}
.nav-group:hover { color: var(--sidebar-text-strong); background: var(--sidebar-hover); }
.nav-sect:first-child .nav-group { border-top: none; }
/* a little air after a module's last row, so the band above the next module
   reads as a new section rather than another row */
.nav-items { padding-bottom: var(--sp-2); }
.nav-chev {
  width: 11px; height: 11px; flex-shrink: 0;
  display: inline-flex; align-items: center; justify-content: center;
  opacity: 0.7;
  transition: transform 0.15s ease;
}
.nav-chev svg { width: 100%; height: 100%; display: block; }
.nav-sect.collapsed .nav-chev { transform: rotate(-90deg); }
.nav-sect.collapsed .nav-items { display: none; }
.nav-item {
  display: flex; align-items: center; gap: 10px;
  position: relative;
  width: 100%;
  /* indented past the module title so the hierarchy is visible without a rule */
  padding: 8px var(--sp-4) 8px calc(var(--sp-4) + 8px);
  border: none; background: none; text-align: left;
  font: inherit; font-size: var(--fs-sm); font-weight: 500;
  color: var(--sidebar-text);
  cursor: pointer;
  border-left: 3px solid transparent;
  transition: background-color 0.12s ease, color 0.12s ease;
}
.nav-item:hover { background: var(--sidebar-hover); color: var(--sidebar-text-active); }
.nav-item.active {
  background: var(--sidebar-active-bg);
  color: var(--sidebar-text-active);
  border-left-color: var(--sidebar-active-bar);
  font-weight: 600;
}
.nav-item .ico {
  width: calc(17px * var(--fs-scale)); height: calc(17px * var(--fs-scale));
  flex-shrink: 0;
  display: inline-flex; align-items: center; justify-content: center;
  opacity: 0.72;
}
.nav-item .ico svg { width: 100%; height: 100%; display: block; }
.nav-item:hover .ico, .nav-item.active .ico { opacity: 1; }
.nav-item .lbl { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* The emoji that heads a module group. Sized off the group text so it rides
   the same line, and kept at full opacity — it is the fastest thing to scan
   in a long map. */
.nav-gico {
  margin-right: 8px;
  font-size: calc(13.5px * var(--fs-scale));
  line-height: 1;
  filter: saturate(0.85);
}

/* A screen the module map names but that is not built yet. It stays visible on
   purpose: the map is the plan of the system, and a gap you can see is worth
   more than a row that quietly does nothing when clicked. Not focusable, so
   keyboard and screen-reader users are not walked into a dead end. */
.nav-item.planned {
  cursor: default;
  color: var(--sidebar-group);
  opacity: 0.72;
}
.nav-item.planned:hover { background: none; color: var(--sidebar-group); }
.nav-item.planned .ico { opacity: 0.4; }
.nav-soon {
  margin-left: auto;
  font-size: calc(9px * var(--fs-scale)); font-weight: 700;
  letter-spacing: 0.06em; text-transform: uppercase;
  color: var(--sidebar-group);
  border: 1px solid currentColor; border-radius: var(--radius-pill);
  padding: 0 5px; opacity: 0.75; flex-shrink: 0;
}

.nav-badge {
  margin-left: auto;
  background: var(--accent); color: var(--accent-text);
  font-size: calc(10px * var(--fs-scale)); font-weight: 700;
  border-radius: var(--radius-pill); padding: 1px 6px;
  min-width: 18px; text-align: center; flex-shrink: 0;
}

.sidebar .user-box {
  border-top: 1px solid var(--sidebar-line);
  background: var(--sidebar-bg-2);
  padding: var(--sp-3) var(--sp-4);
  display: flex; align-items: center; gap: 10px;
  flex-shrink: 0;
}
.avatar {
  width: 30px; height: 30px; border-radius: 50%;
  background: var(--avatar-bg); color: #fff;
  display: flex; align-items: center; justify-content: center;
  font-size: calc(11.5px * var(--fs-scale)); font-weight: 600; flex-shrink: 0;
}
.user-meta { flex: 1; min-width: 0; }
.user-name { font-size: calc(12.5px * var(--fs-scale)); font-weight: 600; color: var(--sidebar-text-strong); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.user-role { font-size: calc(10.5px * var(--fs-scale)); color: var(--sidebar-group); }
.logout-btn {
  background: none; border: 1px solid var(--sidebar-btn-border); color: var(--sidebar-text);
  border-radius: var(--radius-sm); font: inherit; font-size: calc(10.5px * var(--fs-scale));
  font-weight: 500; padding: 3px 8px; cursor: pointer;
  transition: border-color 0.12s ease, color 0.12s ease;
}
.logout-btn:hover { color: var(--sidebar-text-active); border-color: var(--sidebar-btn-border-hover); }
.user-actions { display: flex; flex-direction: column; gap: var(--sp-1); flex-shrink: 0; }

.main { flex: 1; min-width: 0; display: flex; flex-direction: column; }

/* ---------- 3b. Topbar ---------- */
.topbar {
  height: var(--topbar-h);
  background: var(--surface);
  border-bottom: 1px solid var(--border);
  display: flex; align-items: center; gap: var(--sp-3);
  padding: 0 var(--sp-6);
  position: sticky; top: 0; z-index: 20;
}
/* ---------- request indicator ----------
   A brand-coloured hairline across the top of the window while anything is in
   flight. Fixed, 2px, above everything, and it never shifts the layout. */
.busy-bar {
  position: fixed; top: 0; left: 0; right: 0; height: 2px; z-index: 200;
  background: linear-gradient(90deg, var(--brand-red), var(--brand-gold), var(--brand-red));
  background-size: 200% 100%;
  transform: scaleX(0); transform-origin: left;
  opacity: 0;
  transition: transform 0.25s ease, opacity 0.25s ease;
  pointer-events: none;
}
.busy-bar.on {
  transform: scaleX(1);
  opacity: 1;
  animation: busy-slide 1.1s linear infinite;
}
@keyframes busy-slide { from { background-position: 0 0; } to { background-position: -200% 0; } }
@media (prefers-reduced-motion: reduce) { .busy-bar.on { animation: none; } }

/* ---------- system switcher ----------
   Sits first in the topbar and reads as the module tab of the suite: the name
   of the system you are in, set like a heading and underscored in brand red,
   with the way into the other systems behind it. The name carries the weight;
   the control chrome stays quiet. */
.sys-switch { position: relative; flex-shrink: 0; }
.sys-btn {
  display: inline-flex; align-items: center; gap: 7px;
  font: inherit; font-size: var(--fs-sm); font-weight: 600;
  color: var(--text);
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 0 var(--sp-2);
  height: calc(28px * var(--fs-scale));
  cursor: pointer; white-space: nowrap;
}
.sys-btn:hover { background: var(--neutral-hover); border-color: var(--border-strong); }
.sys-btn::before {                       /* the brand mark, reduced to a bar */
  content: ""; width: 3px; height: 1em; border-radius: 2px;
  background: linear-gradient(var(--brand-red) 0 55%, var(--brand-gold) 55% 100%);
}
/* the module name is the one loud element: uppercase, spaced, and carrying
   the same red bar that marks the active item in the sidebar */
.sys-btn .sys-name {
  text-transform: uppercase; letter-spacing: 0.06em; font-weight: 700;
  font-size: calc(11.5px * var(--fs-scale));
  padding-bottom: 1px;
  box-shadow: inset 0 -2px 0 var(--brand-red);
}
.sys-caret { color: var(--text-muted); font-size: 0.8em; }

.sys-menu {
  position: absolute; top: calc(100% + 6px); left: 0; z-index: 140;
  min-width: 232px;
  background: var(--surface);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius);
  box-shadow: var(--shadow-pop);
  padding: var(--sp-1);
}
.sys-item {
  display: block; padding: 7px var(--sp-3);
  border-radius: var(--radius-sm);
  text-decoration: none; color: var(--text);
}
.sys-item:hover { background: var(--row-hover); text-decoration: none; }
.sys-item.current { background: var(--primary-light); }
.sys-item-name { display: block; font-size: var(--fs-sm); font-weight: 600; }
.sys-item-note { display: block; font-size: var(--fs-xs); color: var(--text-muted); margin-top: 1px; }
.sys-here {
  font-size: var(--fs-xs); font-weight: 600; color: var(--primary);
  border: 1px solid var(--primary-border); border-radius: var(--radius-pill);
  padding: 0 6px; margin-left: 4px;
}
.sys-all { border-top: 1px solid var(--border); margin-top: var(--sp-1); padding-top: var(--sp-2); }
@media (max-width: 767px) { .sys-btn .sys-name { display: none; } }

.breadcrumb { font-size: var(--fs-sm); color: var(--text-muted); font-weight: 500; }
.breadcrumb b { color: var(--text); font-weight: 600; }
.breadcrumb .sep { margin: 0 6px; color: var(--border-strong); }
.topbar .spacer { flex: 1; }
.topbar .chip {
  font-size: var(--fs-xs); font-weight: 600; color: var(--text-secondary);
  background: var(--surface-2); border: 1px solid var(--border);
  border-radius: var(--radius-pill); padding: 4px 11px; white-space: nowrap;
}
.fs-pick {
  font-size: var(--fs-xs); font-weight: 600; color: var(--text-secondary);
  background: var(--surface-2); border: 1px solid var(--border);
  border-radius: var(--radius-pill); padding: 0 var(--sp-2);
  height: calc(26px * var(--fs-scale)); min-height: 0;
  cursor: pointer; flex-shrink: 0;
}
.fs-pick:hover { background: var(--neutral-hover); }

.content { padding: var(--sp-6); max-width: 1360px; width: 100%; margin: 0 auto; }

/* ---------- 3b2. Scope indicator ----------
   Which locations the figures on screen cover. This is the one chip that must
   never be missed: a consolidated gross profit and a single branch's gross
   profit look identical on the page, and confusing them is the expensive kind
   of mistake. So it carries the brand red when it is showing everything, and
   names the branch when it is not. */
.chip.scope {
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  font-size: calc(10.5px * var(--fs-scale));
  display: inline-flex; align-items: center; gap: 6px;
}
.chip.scope::before {
  content: ""; width: 7px; height: 7px; border-radius: 50%;
  background: currentColor; flex-shrink: 0;
}
.chip.scope-all {
  color: var(--primary);
  background: var(--primary-light);
  border-color: var(--primary-border);
}
.chip.scope-one {
  color: var(--text-secondary);
  background: var(--surface-2);
  border-color: var(--border-strong);
}
/* a location that has shut still gets reported on; say so plainly */
.chip.scope-closed {
  color: var(--warning);
  background: var(--warning-bg);
  border-color: var(--warning-border);
}

/* ---------- 3c. Page heading ---------- */
.page-title { font-size: var(--fs-xl); font-weight: 600; letter-spacing: -0.011em; }
.page-sub   { font-size: var(--fs-sm); color: var(--text-muted); margin-top: 2px; max-width: 68ch; }
.page-head  {
  display: flex; align-items: flex-end; justify-content: space-between;
  gap: var(--sp-4); margin-bottom: var(--sp-5); flex-wrap: wrap;
}
.page-head .actions { display: flex; gap: var(--sp-2); flex-wrap: wrap; }

/* ---------- 4. Cards, sections & KPI tiles ---------- */
.card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  margin-bottom: var(--sp-5);
}
.card-head {
  padding: var(--sp-3) var(--sp-4);
  border-bottom: 1px solid var(--border);
  display: flex; align-items: center; gap: var(--sp-3);
  min-height: calc(46px * var(--fs-scale));
}
.card-title { font-size: var(--fs-md); font-weight: 600; letter-spacing: -0.005em; }
.card-head .actions { margin-left: auto; display: flex; gap: var(--sp-2); flex-wrap: wrap; align-items: center; }
.card-body { padding: var(--sp-4); }
.card-body.flush { padding: 0; }
/* a card whose body is only filters reads as a toolbar, not as content:
   tinted, tighter, and clearly the controls for the results below it */
.card-body.filters {
  display: block;
  background: var(--surface-2);
  padding: var(--sp-3) var(--sp-4);
  border-radius: inherit;
}

/* Grouping inside a form or a long card */
.section-title {
  font-size: var(--fs-xs); font-weight: 600; letter-spacing: 0.07em;
  text-transform: uppercase; color: var(--text-muted);
  padding-bottom: var(--sp-2); margin-bottom: var(--sp-3);
  border-bottom: 1px solid var(--border);
}
.section + .section { margin-top: var(--sp-5); }

.kpi-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: var(--sp-3);
  margin-bottom: var(--sp-5);
}
.kpi {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: var(--sp-3) var(--sp-4);
}
.kpi .kpi-label {
  font-size: var(--fs-xs); font-weight: 600; letter-spacing: 0.06em;
  text-transform: uppercase; color: var(--text-muted);
}
.kpi .kpi-value {
  font-size: var(--fs-kpi); font-weight: 600; letter-spacing: -0.022em;
  margin-top: 5px; font-variant-numeric: tabular-nums; line-height: 1.15;
}
.kpi .kpi-note  { font-size: var(--fs-xs); color: var(--text-muted); margin-top: 3px; }
/* status is carried by a hairline down the side, not by colouring the tile */
.kpi.alert { box-shadow: var(--shadow), inset 3px 0 0 var(--danger); }
.kpi.warn  { box-shadow: var(--shadow), inset 3px 0 0 var(--warning); }
.kpi.good  { box-shadow: var(--shadow), inset 3px 0 0 var(--success); }
.kpi.alert .kpi-value { color: var(--danger); }
.kpi.warn  .kpi-value { color: var(--warning); }

/* Brand hairlines, the same device used for identity rather than status: red
   for the figures management looks at first, gold for the ones read beside
   them. The figure itself stays charcoal — a tile is not "bad" for being red.

   Status outranks identity. A tile carrying `warn` and `brand` shows the
   warning, because something being wrong with a number always matters more
   than which number it is. Put `brand`/`gold` first in the class list and let
   the status rules that follow win. */
.kpi.brand { box-shadow: var(--shadow), inset 3px 0 0 var(--brand-red); }
.kpi.gold  { box-shadow: var(--shadow), inset 3px 0 0 var(--brand-gold); }
.kpi.ink   { box-shadow: var(--shadow), inset 3px 0 0 var(--text-secondary); }

/* ---------- 5. Filter / toolbar strip ----------
   `.filters` is only the tinted container; the `.form-row` inside it still
   owns the layout, so the two never fight over display/direction. */
/* selector must outrank `.form-row > div`, which stacks its children */
.filter-actions, .form-row > .filter-actions {
  display: flex; flex-direction: row; flex-wrap: wrap;
  gap: var(--sp-2); align-items: flex-end;
  margin-left: auto;
}
.toolbar {
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2);
  margin-bottom: var(--sp-4);
}
.toolbar .spacer { flex: 1; }

/* ---------- 6. Tabs ---------- */
.tabs {
  display: flex; gap: var(--sp-1); flex-wrap: wrap;
  border-bottom: 1px solid var(--border);
  margin-bottom: var(--sp-4);
}
.tab {
  font: inherit; font-size: var(--fs-sm); font-weight: 500;
  color: var(--text-secondary);
  background: none; border: none;
  border-bottom: 2px solid transparent;
  padding: var(--sp-2) var(--sp-3);
  margin-bottom: -1px;
  cursor: pointer; white-space: nowrap;
}
.tab:hover { color: var(--text); }
.tab.active { color: var(--primary); border-bottom-color: var(--primary); font-weight: 600; }

/* ---------- 7. Tables ---------- */
/* A table scrolls inside its own box rather than stretching the page.

   This is what makes the sticky headings actually stick. `overflow-x: auto`
   alone silently makes the box a scroll container on BOTH axes, so a heading
   with `position: sticky` resolves against this box — and a box with no height
   limit never scrolls, so the heading never sticks and slides away with the
   page instead. Capping the height gives it something to stick to.

   Short tables are unaffected: a box only scrolls once its content exceeds the
   cap, so nothing shorter than a screen gains a scrollbar. */
.table-wrap { overflow: auto; max-height: calc(100vh - 15rem); }
/* a report still being fetched is dimmed, so a slow book does not look like a
   stale one — three thousand entries take a moment to rule up */
[aria-busy="true"] { opacity: .45; transition: opacity .15s ease; pointer-events: none; }
/* a table inside a modal or a small panel keeps its own sizing */
.modal .table-wrap, .scroll-panel .table-wrap { max-height: none; }
table.data {
  border-collapse: collapse;
  width: 100%;
  font-size: var(--fs-sm);
  background: var(--surface);
}
table.data th {
  position: sticky; top: 0;
  background: var(--table-head-bg);
  color: var(--text-secondary);
  font-weight: 600;
  font-size: var(--fs-xs);
  letter-spacing: 0.045em;
  text-transform: uppercase;
  text-align: left;
  padding: 9px var(--sp-3);
  border-bottom: 1px solid var(--border-strong);
  white-space: nowrap;
  z-index: 5;
}
table.data td {
  padding: 8px var(--sp-3);
  border-bottom: 1px solid var(--border);
  vertical-align: middle;
}
table.data tbody tr { transition: background-color 0.1s ease; }
table.data tbody tr:hover td { background: var(--row-hover); }
table.data tbody tr:last-child td { border-bottom: none; }
/* numbers right-aligned with fixed-width digits so columns line up */
table.data .num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
table.data th.num { text-align: right; }
table.data .col-date { white-space: nowrap; font-variant-numeric: tabular-nums; }
/* the descriptive column carries the row: give it room rather than letting
   the browser squeeze it into four-line wraps on a narrow window */
table.data .col-name { min-width: 240px; }
table.data .col-code { white-space: nowrap; font-variant-numeric: tabular-nums; }
table.data .col-actions, table.data th.col-actions { text-align: right; white-space: nowrap; }
/* a row that was just added, so it reads as an addition to the list rather
   than a replacement of what was there before */
table.data tr.row-new td { background: var(--success-bg); }
table.data tr.row-new:hover td { background: var(--success-bg); }

/* one action cell everywhere: primary action then the "⋯" menu, pinned right */
.row-actions { display: flex; gap: 6px; justify-content: flex-end; align-items: center; }
/* totals: weight and a rule, not colour */
table.data tfoot td, table.data tr.total td {
  background: var(--surface-2);
  font-weight: 600;
  color: var(--text);
  border-top: 2px solid var(--border-strong);
  border-bottom: none;
}
table.data tfoot tr:hover td, table.data tr.total:hover td { background: var(--surface-2); }
/* two levels of subtotal sit between the data and the grand total:
   classification subtotal, then the whole Manufactured / Traded group */
table.data tr.subtotal td {
  background: var(--surface-2); font-weight: 600;
  color: var(--text-secondary);
  border-top: 1px solid var(--border);
}
table.data tr.group-total td {
  background: var(--neutral-bg); font-weight: 700;
  color: var(--text);
  border-top: 1px solid var(--border-strong);
  border-bottom: 1px solid var(--border-strong);
}
table.data tr.subtotal:hover td { background: var(--surface-2); }
table.data tr.group-total:hover td { background: var(--neutral-bg); }
/* says why the quantity columns on this subtotal are blank */
.mixed-units {
  font-size: 0.85em; font-weight: 500; color: var(--text-muted);
  border: 1px solid var(--border-strong); border-radius: var(--radius-pill);
  padding: 0 6px; margin-left: 6px; white-space: nowrap;
}
table.data tr.group-head td {
  background: var(--surface-2); font-weight: 600;
  font-size: var(--fs-xs); letter-spacing: 0.045em; text-transform: uppercase;
  color: var(--text-secondary);
}
table.data td.indent { padding-left: var(--sp-6); }

/* ---------- 7b. Grouped lists ----------
   Two levels of heading inside one table: a top group (Manufactured /
   Traded / Materials) and the classification under it. Both collapse. */
table.data tr.group-top td {
  background: var(--surface-2);
  border-top: 1px solid var(--border-strong);
  border-bottom: 1px solid var(--border);
  padding: 9px var(--sp-3);
  cursor: pointer;
}
table.data tr.group-top:first-child td { border-top: none; }
table.data tr.group-top:hover td { background: var(--neutral-bg); }
.gt-label {
  font-size: var(--fs-sm); font-weight: 700; color: var(--text);
  letter-spacing: 0.02em; text-transform: uppercase;
}
/* counts stay inline on the left: a float-right count scrolls out of sight
   as soon as the table is wider than the viewport */
.gt-count {
  font-size: var(--fs-xs); font-weight: 600; color: var(--text-secondary);
  background: var(--surface); border: 1px solid var(--neutral-border);
  border-radius: var(--radius-pill); padding: 1px 9px; margin-left: var(--sp-2);
  font-variant-numeric: tabular-nums; white-space: nowrap;
}
.gt-note { font-size: var(--fs-xs); color: var(--text-muted); margin-left: var(--sp-2); }
.gt-actions { float: right; display: inline-flex; gap: 6px; margin-top: -2px; }

/* Column captions that live INSIDE the body, one row per batch, placed under
   the batch identity: they must not stick (a dozen of them would pile up at
   the top of the scroll), they just caption the runs that follow. */
table.data tr.cols th { position: static; }

/* One caption over several columns that belong together as one measurement. */
table.data th.gh-span {
  text-align: center;
  border-bottom: 2px solid var(--border-strong, var(--border));
  box-shadow: inset 0 -2px 0 var(--brand-gold, var(--accent, var(--border-strong)));
}
/* ---------- Daily Production Plan ----------
   A working screen that is also a form: the computed sections read as tables,
   the ones the floor completes print as ruled blanks. */
.dp-grid {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
  gap: 6px var(--sp-4);
}
.dp-grid > div { display: flex; gap: var(--sp-2); align-items: baseline;
  border-bottom: 1px dotted var(--border); padding: 4px 0; }
.dp-k { font-size: var(--fs-xs); color: var(--text-muted); text-transform: uppercase;
  letter-spacing: .04em; min-width: 9.5em; }
.dp-v { font-weight: 600; font-size: var(--fs-sm); }
td.dp-blank { height: 26px; border-bottom: 1px solid var(--border); }
.dp-lines { height: 64px; border-bottom: 1px solid var(--border);
  background: repeating-linear-gradient(transparent, transparent 27px,
    var(--border) 27px, var(--border) 28px); }
.dp-signs { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: var(--sp-5) var(--sp-4); margin-top: var(--sp-6); }
.dp-rule { border-bottom: 1px solid var(--text-secondary); margin-bottom: 4px; }
.dp-title { text-align: center; font-size: 15px; line-height: 1.5; margin-bottom: 8px; }
.print-only { display: none; }
@media print {
  .print-only { display: block; }
  .no-print, .sidebar, .topbar { display: none !important; }
  .dp-doc .card { break-inside: avoid; box-shadow: none; border: 1px solid #999; }
}


/* A denser variant for long operational lists — the same table, less air, so a
   day's production fits on one screen instead of three. */
table.data.compact th { padding: 6px var(--sp-3); }
table.data.compact td { padding: 5px var(--sp-3); }
table.data.compact tr.group-top td { padding: 6px var(--sp-3); }
table.data.compact tr.group-head td { padding: 4px var(--sp-3) 4px var(--sp-5); }
table.data.compact tr.subtotal td { padding: 5px var(--sp-3); }

table.data tr.group-head td {
  padding: 6px var(--sp-3) 6px var(--sp-6);
  cursor: pointer;
  text-transform: none; letter-spacing: 0;
}
table.data tr.group-head:hover td { background: var(--neutral-bg); }
.gh-code {
  font-size: var(--fs-xs); font-weight: 600; color: var(--text-muted);
  font-variant-numeric: tabular-nums; letter-spacing: 0.04em;
  min-width: 3.4em; display: inline-block;
}
.gh-name  { font-size: var(--fs-sm); font-weight: 600; color: var(--text-secondary); }
.gh-count {
  font-size: var(--fs-xs); font-weight: 600; color: var(--text-muted);
  background: var(--neutral-bg); border: 1px solid var(--neutral-border);
  border-radius: var(--radius-pill); padding: 0 7px; margin-left: var(--sp-2);
  font-variant-numeric: tabular-nums;
}
/* the ▾/▸ twisty */
.tw {
  display: inline-block; width: 1.1em;
  color: var(--text-muted); font-size: 0.85em;
}
/* items sit indented under their classification so the levels read at a glance.
   `~` would also catch the following group rows, so exclude them explicitly. */
table.data tr.group-head ~ tr:not(.group-head):not(.group-top) td:first-child {
  padding-left: var(--sp-8);
}

/* footer strip under a list: counts on the left, controls on the right */
.list-foot {
  display: flex; align-items: center; gap: var(--sp-3);
  padding: 10px var(--sp-4);
  border-top: 1px solid var(--border);
  background: var(--surface-2);
  border-radius: 0 0 var(--radius) var(--radius);
}
.list-foot .spacer { flex: 1; }

/* ---------- 7c. Financial statement hierarchy ----------
   Statement lines nest: a group, its accounts, its subtotal. Indentation and
   weight carry that structure, so the reader can see the shape of the statement
   without any colour being spent on it. */
table.data td.lvl-1 { padding-left: var(--sp-5); }
table.data td.lvl-2 { padding-left: var(--sp-6); }
table.data td.lvl-3 { padding-left: calc(var(--sp-6) + var(--sp-3)); }
table.data td.lvl-4 { padding-left: var(--sp-8); }
/* a heading line inside a statement — no figures of its own */
table.data tr.fs-head td { font-weight: 600; color: var(--text); background: var(--surface-2); }
/* the running subtotal of a section, and the statement's bottom line */
table.data tr.fs-total td {
  font-weight: 600;
  border-top: 1px solid var(--border-strong);
}
table.data tr.fs-grand td {
  font-weight: 700;
  border-top: 2px solid var(--border-strong);
  border-bottom: 3px double var(--border-strong);   /* the accountant's double rule */
  background: var(--surface-2);
}

/* Signed figures: variance, over/short, in/out */
.neg { color: var(--danger); font-weight: 600; }
.pos { color: var(--success); font-weight: 600; }

/* ---------- accounting portal helpers ---------- */
.grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: var(--sp-4); }
@media (max-width: 900px) { .grid-2 { grid-template-columns: 1fr; } }

.pill {
  display: inline-block; padding: 1px 8px; border-radius: 999px;
  font-size: calc(10.5px * var(--fs-scale)); font-weight: 600;
  background: var(--surface-2); border: 1px solid var(--border);
  color: var(--text-secondary); white-space: nowrap;
}
.pill.ok   { background: var(--success-bg); border-color: transparent; color: var(--success); }
.pill.warn { background: var(--warning-bg); border-color: transparent; color: var(--warning); }
.pill.muted { opacity: 0.7; }

table.data tr.group td {
  background: var(--surface-2); font-size: var(--fs-sm);
  border-top: 1px solid var(--border-strong);
}
table.data tr.total-row td {
  font-weight: 700; border-top: 2px solid var(--primary);
  background: var(--surface-2);
}
table.data tr.warn-row td { background: var(--warning-bg); }
table.data tfoot td {
  font-weight: 700; background: var(--surface-2);
  border-top: 2px solid var(--border-strong);
  font-variant-numeric: tabular-nums;
}
.zero { color: var(--text-muted); }

/* Compact per-row actions menu (the "⋯" button) */
.row-menu {
  position: fixed; z-index: 130;
  min-width: 168px;
  background: var(--surface);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius);
  box-shadow: var(--shadow-pop);
  padding: var(--sp-1) 0;
}
.row-menu button {
  display: block; width: 100%;
  padding: 7px var(--sp-4);
  background: none; border: none; text-align: left;
  font: inherit; font-size: var(--fs-sm); color: var(--text);
  cursor: pointer; white-space: nowrap;
}
.row-menu button:hover { background: var(--row-hover); }
.row-menu button.danger { color: var(--danger); }
.row-menu button.danger:hover { background: var(--danger-bg); }

/* One-tap suggestions for a line the reader could not match */
.chips { display: flex; flex-wrap: wrap; gap: 6px; margin-top: var(--sp-1); }
.chip-btn {
  font: inherit; font-size: var(--fs-xs); font-weight: 600;
  color: var(--text-secondary);
  background: var(--surface-2);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-pill); padding: 4px 11px;
  cursor: pointer; white-space: nowrap;
}
.chip-btn:hover { background: var(--primary); color: var(--text-invert); border-color: var(--primary); }
@media (max-width: 767px) { .chip-btn { min-height: 34px; } }

/* Unit beside a quantity: smaller and muted so the figure reads first.
   em-based, so it follows the topbar text-size setting. */
.qty-unit {
  font-size: 0.8em;
  font-weight: 400;
  color: var(--text-muted);
  letter-spacing: 0.01em;
}

/* Numbers in data tables use tabular (equal-width) digits, so every digit
   column is exactly under the one above — the other half of decimal
   alignment, alongside the fixed decimal places the formatters print. */
table.data td.num, table.data th.num, .kpi-value {
  font-variant-numeric: tabular-nums;
}

/* In a numeric column the unit gets a fixed slot, so the digits of every row
   end at the same place regardless of whether the unit is "pc", "packs" or
   "kilos" — quantities align by number, units align by name. */
td.num .qty-unit, th.num .qty-unit {
  display: inline-block;
  min-width: 3.2em;
  text-align: left;
}

/* ---------- 8. Status badges ----------
   One tone per meaning, used identically in every module:
     neutral  draft, cancelled, inactive, closed
     warning  pending, awaiting, needs review, partial
     info     submitted, approved, in transit, reviewed
     success  posted, received, confirmed, resolved, active
     danger   rejected, voided, locked, short                     */
.badge {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 3px 9px;
  border-radius: var(--radius-pill);
  font-size: var(--fs-xs);
  font-weight: 600;
  line-height: 1.35;
  letter-spacing: 0.015em;
  white-space: nowrap;
  border: 1px solid transparent;
}
.badge::before { content: ""; width: 5px; height: 5px; border-radius: 50%; background: currentColor; flex-shrink: 0; }
.badge.success { color: var(--success); background: var(--success-bg); border-color: var(--success-border); }
.badge.warning { color: var(--warning); background: var(--warning-bg); border-color: var(--warning-border); }
.badge.danger  { color: var(--danger);  background: var(--danger-bg);  border-color: var(--danger-border); }
.badge.info    { color: var(--info);    background: var(--info-bg);    border-color: var(--info-border); }
.badge.neutral { color: var(--neutral); background: var(--neutral-bg); border-color: var(--neutral-border); }
/* semantic aliases used by JS */
.badge.matched   { color: var(--success); background: var(--success-bg); border-color: var(--success-border); }
.badge.fuzzy     { color: var(--warning); background: var(--warning-bg); border-color: var(--warning-border); }
.badge.unmatched { color: var(--danger);  background: var(--danger-bg);  border-color: var(--danger-border); }
/* a dot-free variant for dense tables */
.badge.plain::before { display: none; }

/* ---------- 9. Buttons ----------
   Weight follows intent: one filled primary per screen area,
   outlined neutrals for everything else, red reserved for danger. */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  font: inherit; font-size: var(--fs-sm); font-weight: 600;
  padding: 0 var(--sp-3);
  min-height: var(--control-h);
  border-radius: var(--radius-sm);
  border: 1px solid transparent;
  cursor: pointer;
  line-height: 1.2;
  white-space: nowrap;
  transition: background-color 0.12s ease, border-color 0.12s ease, color 0.12s ease;
}
.btn:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }
.btn:disabled { opacity: 0.45; cursor: default; }

.btn-primary {
  background: var(--primary); color: #fff; border-color: var(--primary);
  box-shadow: 0 1px 2px rgba(222, 26, 33, 0.28);
}
.btn-primary:hover:not(:disabled) { background: var(--primary-hover); border-color: var(--primary-hover); }
.btn-primary:active { background: var(--primary-active); border-color: var(--primary-active); box-shadow: none; }

.btn-secondary { background: var(--surface); color: var(--text-secondary); border-color: var(--border-strong); }
.btn-secondary:hover:not(:disabled) { background: var(--surface-2); color: var(--text); }

.btn-outline { background: var(--surface); color: var(--primary); border-color: var(--primary-border); }
.btn-outline:hover:not(:disabled) { background: var(--primary-light); }

.btn-danger { background: var(--surface); color: var(--danger); border-color: var(--danger-border); }
.btn-danger:hover:not(:disabled) { background: var(--danger-bg); }

/* tertiary: lowest weight, for repeated in-row actions */
.btn-ghost { background: none; color: var(--text-secondary); border-color: transparent; }
.btn-ghost:hover:not(:disabled) { background: var(--neutral-bg); color: var(--text); }

.btn-sm { min-height: calc(27px * var(--fs-scale)); padding: 0 var(--sp-2); font-size: var(--fs-xs); }
/* icons inherit the text colour and ride at the text size, so one markup
   pattern works in buttons, menus, the nav rail and inline labels */
.ico { display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0; }
.ico svg { width: 1.15em; height: 1.15em; display: block; }
.btn .ico svg { width: 1.05em; height: 1.05em; }
.btn-sm .ico svg { width: 1.15em; height: 1.15em; }

/* ---------- 10. Forms & inputs ---------- */
label {
  display: block;
  font-size: var(--fs-xs); font-weight: 600;
  letter-spacing: 0.03em;
  color: var(--text-secondary);
  margin: 0 0 5px;
}
input, select, textarea {
  font: inherit; font-size: var(--fs-sm);
  color: var(--text);
  background: var(--surface);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  padding: 0 10px;
  height: var(--control-h);
  transition: border-color 0.12s ease, box-shadow 0.12s ease;
}
select {
  padding-right: var(--sp-6);
  appearance: none;
  background-image: linear-gradient(45deg, transparent 50%, var(--text-muted) 50%),
                    linear-gradient(135deg, var(--text-muted) 50%, transparent 50%);
  background-position: calc(100% - 15px) calc(50% + 1px), calc(100% - 10px) calc(50% + 1px);
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
}
textarea { height: auto; padding: 8px 10px; line-height: 1.5; resize: vertical; }
input:hover:not(:disabled), select:hover:not(:disabled), textarea:hover:not(:disabled) { border-color: var(--text-muted); }
input:focus, select:focus, textarea:focus {
  outline: none;
  border-color: var(--primary);
  box-shadow: var(--focus-ring);
}
input:disabled, select:disabled, textarea:disabled { background: var(--surface-2); color: var(--text-muted); cursor: not-allowed; }
input::placeholder, textarea::placeholder { color: var(--text-muted); }
input[type="number"] { font-variant-numeric: tabular-nums; }
input[type="checkbox"], input[type="radio"] { height: auto; width: auto; accent-color: var(--primary); }
input[type="file"] {
  height: auto; padding: var(--sp-2);
  background: var(--surface-2);
  border: 1px dashed var(--border-strong);
  font-size: var(--fs-xs); color: var(--text-secondary);
}
input[type="file"]:hover { border-color: var(--primary-border); background: var(--primary-light); }
input[type="date"] { min-width: 140px; }
/* inputs sitting inside a table row stay compact without inline styles */
table.data input, table.data select { height: calc(28px * var(--fs-scale)); font-size: var(--fs-xs); }

.form-row { display: flex; gap: var(--sp-3); flex-wrap: wrap; align-items: flex-end; }
.form-row + .form-row { margin-top: var(--sp-3); }
.form-row > div { display: flex; flex-direction: column; }
.field-sm { width: 110px; }
.field-md { width: 170px; }
.field-lg { width: 260px; }
.field-grow { flex: 1; min-width: 180px; }
.help { font-size: var(--fs-xs); color: var(--text-muted); margin-top: 4px; }
/* a checkbox that sits on the same baseline as the inputs beside it
   (outranks `.form-row > div`, which stacks label above control) */
.check-inline, .form-row > .check-inline {
  display: flex; flex-direction: row; align-items: center;
  min-height: var(--control-h);
}
.check-inline label {
  display: flex; align-items: center; gap: var(--sp-2);
  margin: 0; cursor: pointer;
  font-size: var(--fs-sm); font-weight: 500; letter-spacing: 0;
  color: var(--text-secondary);
}

/* ---------- 11. Alerts, messages & empty states ---------- */
.msg {
  display: none;
  align-items: flex-start; gap: var(--sp-2);
  padding: 10px var(--sp-3);
  border-radius: var(--radius-sm);
  font-size: var(--fs-sm); font-weight: 500;
  line-height: 1.5;
  margin-bottom: var(--sp-4);
  border: 1px solid transparent;
  border-left-width: 3px;
}
.msg::before { font-weight: 700; flex-shrink: 0; line-height: 1.4; }
.msg.ok   { display: flex; color: var(--success); background: var(--success-bg); border-color: var(--success-border); border-left-color: var(--success); }
.msg.err  { display: flex; color: var(--danger);  background: var(--danger-bg);  border-color: var(--danger-border); border-left-color: var(--danger); }
.msg.warn { display: flex; color: var(--warning); background: var(--warning-bg); border-color: var(--warning-border); border-left-color: var(--warning); }
.msg.info { display: flex; color: var(--info);    background: var(--info-bg);    border-color: var(--info-border); border-left-color: var(--info); }
.msg.ok::before   { content: "\2713"; }
.msg.err::before  { content: "\26A0"; }
.msg.warn::before { content: "\26A0"; }
.msg.info::before { content: "\2139"; }

.empty {
  padding: var(--sp-8) var(--sp-4);
  text-align: center;
  color: var(--text-muted);
}
.empty .empty-title { font-size: var(--fs-md); font-weight: 600; color: var(--text-secondary); margin-bottom: 4px; }
.empty .empty-hint  { font-size: var(--fs-sm); max-width: 46ch; margin: 0 auto; }

/* ---------- 12. Login ----------
   The one screen everyone sees every day, so it carries the brand plainly:
   the seal front and centre on warm ink, a soft wash of the brand red and
   gold behind it, and the letterhead rule across the top of the card. */
.login-page {
  min-height: 100vh;
  display: flex; align-items: center; justify-content: center;
  padding: var(--sp-4);
  background:
    radial-gradient(860px 520px at 88% -12%, rgba(237, 28, 36, 0.30), transparent 62%),
    radial-gradient(720px 460px at -12% 112%, rgba(255, 206, 0, 0.16), transparent 58%),
    linear-gradient(160deg, #231f1f 0%, var(--login-grad) 100%);
}
.login-card {
  width: 400px; max-width: 100%;
  background: var(--surface);
  border-radius: 14px;
  padding: var(--sp-8);
  box-shadow: 0 24px 70px rgba(0, 0, 0, 0.45);
  position: relative; overflow: hidden;
}
.login-card::before {
  content: "";
  position: absolute; top: 0; left: 0; right: 0; height: 5px;
  background: linear-gradient(180deg,
    var(--brand-red) 0, var(--brand-red) 60%,
    var(--brand-gold) 60%, var(--brand-gold) 100%);
}
.login-brand {
  display: flex; flex-direction: column; align-items: center; text-align: center;
  gap: var(--sp-3); margin: var(--sp-2) 0 var(--sp-6);
}
.login-brand .brand-mark {
  width: 76px; height: 76px; font-size: calc(26px * var(--fs-scale));
  box-shadow: 0 0 0 4px var(--brand-ring), 0 0 0 5px var(--border),
              0 10px 26px rgba(35, 31, 31, 0.22);
}
.login-title { font-size: var(--fs-lg); font-weight: 700; letter-spacing: -0.01em; }
.login-sub {
  font-size: var(--fs-xs); font-weight: 600; color: var(--text-muted);
  letter-spacing: 0.11em; text-transform: uppercase; margin-top: 3px;
}
.login-card label { margin-top: var(--sp-4); }
.login-card input { width: 100%; }
.login-card .btn { width: 100%; margin-top: var(--sp-6); min-height: 42px; font-weight: 600; }

/* ---------- 13. Modal dialogs ---------- */
.modal-back {
  position: fixed; inset: 0; z-index: 100;
  background: var(--scrim);
  display: flex; align-items: center; justify-content: center;
  padding: var(--sp-4);
}
.modal {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 8px;
  box-shadow: var(--shadow-modal);
  width: 420px; max-width: 100%;
  max-height: calc(100vh - var(--sp-8));
  display: flex; flex-direction: column;
  overflow: hidden;
}
.modal-head {
  padding: var(--sp-3) var(--sp-4);
  border-bottom: 1px solid var(--border);
  font-size: var(--fs-md); font-weight: 600;
  flex-shrink: 0;
}
.modal-body {
  padding: var(--sp-4);
  font-size: var(--fs-sm); color: var(--text-secondary); line-height: 1.55;
  overflow-y: auto;
}
.modal-foot {
  padding: var(--sp-3) var(--sp-4);
  border-top: 1px solid var(--border);
  background: var(--surface-2);
  display: flex; justify-content: flex-end; gap: var(--sp-2);
  flex-shrink: 0;
}
@media (max-width: 767px) {
  .modal-foot { flex-direction: column-reverse; }
  .modal-foot .btn { width: 100%; }
}

/* ---------- 14. Views & utility ---------- */
.view { display: none; }
.view.active { display: block; }
.muted { color: var(--text-muted); }
.small { font-size: var(--fs-xs); }
.mt-2 { margin-top: var(--sp-2); } .mt-3 { margin-top: var(--sp-3); } .mt-4 { margin-top: var(--sp-4); }
.mb-0 { margin-bottom: 0; }
.text-right { text-align: right; }
.nowrap { white-space: nowrap; }
.doc-status { display: flex; align-items: center; gap: var(--sp-3); flex-wrap: wrap; }


/* ---------- 14b. Sizing & layout utilities ----------
   Every ad-hoc `style="width:88px"` in the portals became one of these. Widths
   are named for what the field HOLDS, not for a pixel count, so a quantity box
   is the same width on every screen in all three systems. */
.w-qty    { width: calc(88px  * var(--fs-scale)); }   /* a counted quantity */
.w-money  { width: calc(104px * var(--fs-scale)); }   /* a peso figure */
.w-code   { width: calc(120px * var(--fs-scale)); }   /* reference / document no. */
.w-date   { width: calc(150px * var(--fs-scale)); }   /* a date control */
.w-search { width: calc(210px * var(--fs-scale)); }   /* a search box in a card head */
/* The party a document is with, in a ruled book: one line, clipped rather than
   wrapped, so a page of invoices stays a page and not a scroll. The full text
   is on the cell's title. */
.w-party  {
  width: calc(230px * var(--fs-scale));
  max-width: calc(230px * var(--fs-scale));
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* ---------- a book ruled in columns ----------
   A special journal is read across the page: the date and reference on the
   left, then a column per account. It only works if the whole ruling fits the
   screen at once, so everything here is sized down to what the figures actually
   need — narrow leading columns, tight cells, and account headings that stack
   rather than stretching their column to the width of a name. */
/* table-layout: fixed makes the colgroup above binding — the columns take the
   share they are given and content never widens them, so the page cannot grow
   past the screen however long an account is called. */
table.data.ruled-book {
  font-size: calc(11px * var(--fs-scale));
  table-layout: fixed; width: 100%;
}
table.data.ruled-book th,
table.data.ruled-book td { padding: 2px 4px; }
table.data.ruled-book td.num,
table.data.ruled-book th.num { font-variant-numeric: tabular-nums; }
table.data.ruled-book td.num { white-space: nowrap; }
table.data.ruled-book .w-date,
table.data.ruled-book .w-code,
table.data.ruled-book .w-party {
  width: auto; max-width: none;      /* the colgroup rules the width now */
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
/* The party is the longest text on the line and the least numeric, so it is set
   smallest: every point saved here is a longer name kept whole. The figures are
   NOT reduced with it — a cut number is a wrong report, not an untidy one. */
table.data.ruled-book .w-party { font-size: calc(8px * var(--fs-scale)); }
/* the item and the account behind a Sundry amount read like the party: one
   line, clipped rather than wrapped, with the full text on the cell */
table.data.ruled-book .w-item,
table.data.ruled-book .w-sundry {
  font-size: calc(8px * var(--fs-scale));
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
/* The body of the book is set one size below the headings: the date, the
   document number, the party and the figures all read at the same size, which
   is what makes a ruled page scan down a column rather than across a row.
   Narrower figures also buy width back for the name. */
table.data.ruled-book tbody td { font-size: calc(9px * var(--fs-scale)); }
/* the footed totals are the widest figures in the book and they are bold,
   which widens them again — a shade smaller so a column total is never cut */
table.data.ruled-book tfoot td { font-size: calc(8.5px * var(--fs-scale)); }
/* An account heading is a code over a name, wrapped and centred over its
   column, so the column stays the width of its figures rather than the width of
   "Accounts Receivable-Trade". Centred because a heading sits over a column of
   figures, not in the column — right-aligning it reads as another number. */
table.data.ruled-book thead th.num {
  white-space: normal; overflow-wrap: anywhere; line-height: 1.25;
  font-size: calc(10.5px * var(--fs-scale));
  text-align: center; vertical-align: bottom;
}
table.data.ruled-book .acct-code {
  display: block; font-weight: 600; color: var(--text-muted);
  font-size: calc(10px * var(--fs-scale)); font-variant-numeric: tabular-nums;
}
/* The income statement in columns is a wide report with long line labels, so
   the label keeps its own size and only the figures are set down to fit. */
table.data.ruled-book.fs-columns tbody td:first-child,
table.data.ruled-book.fs-columns thead th:first-child {
  font-size: calc(11px * var(--fs-scale));
  white-space: normal; overflow: visible; text-overflow: clip;
}
table.data.ruled-book.fs-columns thead th.num,
table.data.ruled-book.fs-columns tbody td.num,
table.data.ruled-book.fs-columns tfoot td.num {
  text-align: right;
  font-size: calc(var(--fs-fig, 10.5px) * var(--fs-scale));
}
/* a figure never spills past its column — if it will not fit, the statement is
   presented in thousands rather than letting a number run over its neighbour */
table.data.ruled-book.fs-columns td.num { overflow: hidden; }
/* the accounts inside a grouped statement line: small, wrapped, and never
   allowed to widen the label column */
table.data.ruled-book.fs-columns .fs-accounts {
  font-size: calc(8.5px * var(--fs-scale)); line-height: 1.35;
  white-space: normal; margin-top: 2px;
}
table.data.ruled-book .acct-name {
  display: block; text-transform: none; overflow-wrap: anywhere; hyphens: auto;
}
/* The heading stays put while the book scrolls under it — a page of three
   thousand invoices is unreadable if you have to scroll back up to remember
   which column is which. The book has TWO heading rows, so the second is held
   below the first by the first one's own height, measured after it is drawn. */
table.data.ruled-book thead th { position: sticky; z-index: 3; }
table.data.ruled-book thead tr:first-child th { top: 0; }
table.data.ruled-book thead tr:nth-child(2) th { top: var(--book-head-1, 22px); }
/* the totals stay in view at the foot for the same reason */
table.data.ruled-book tfoot td {
  position: sticky; bottom: 0; z-index: 2;
  background: var(--table-head-bg, var(--surface));
}
/* inputs sitting inside a table row: same widths, row height */
table.data .w-qty, table.data .w-money, table.data .w-code { max-width: 100%; }

/* A panel that scrolls rather than growing without limit — long pick lists,
   match candidates, account trees. */
.scroll-panel { overflow-y: auto; overscroll-behavior: contain; }
.scroll-sm { max-height: calc(230px * var(--fs-scale)); }
.scroll-md { max-height: calc(280px * var(--fs-scale)); }
.scroll-lg { max-height: calc(420px * var(--fs-scale)); }

/* KPI density. The default tile is 190px; these say "these figures are wider"
   without every screen inventing its own grid. */
.kpi-grid.cols-sm { grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); }
.kpi-grid.cols-md { grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); }
.kpi-grid.cols-lg { grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); }
.kpi-grid.cols-xl { grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); }

/* A table that should not stretch the full width — a summary of a few figures
   reads better narrow than spread across a wide screen. */
.table-narrow { max-width: calc(560px * var(--fs-scale)); }

/* Padding inside a flush card body, where content is not itself a table */
.card-pad { padding: var(--sp-3) var(--sp-4); }

/* Text utilities */
.text-center { text-align: center; }
.capitalize  { text-transform: capitalize; }
.truncate {
  max-width: calc(420px * var(--fs-scale));
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.mb-1 { margin-bottom: var(--sp-1); }
.mb-2 { margin-bottom: var(--sp-2); }
.mb-3 { margin-bottom: var(--sp-3); }
.mb-4 { margin-bottom: var(--sp-4); }
.row-gap { display: flex; flex-wrap: wrap; gap: var(--sp-6); }
.wrap { flex-wrap: wrap; }
.pb-0 { padding-bottom: 0; }
.mt-1 { margin-top: var(--sp-1); }
/* a row or tile the reader can click through to a detail view */
.clickable { cursor: pointer; }
.clickable:hover { background: var(--row-hover); }

/* A numbered walkthrough — the daily workflow lists on both dashboards */
.checklist {
  margin: 0; padding-left: var(--sp-5);
  line-height: 1.9;
  font-size: var(--fs-sm); color: var(--text-secondary);
}
.checklist li { padding-left: 2px; }
.checklist b { color: var(--text); }

/* ---------- 15. Responsive: laptop / tablet / phone ----------
   Laptop & desktop (>= 1025px) use the full labelled sidebar defined above.
   Tablet (768-1024px) collapses it to an icon rail.
   Phone (<= 767px) turns it into a slide-in drawer opened from the topbar. */

.nav-toggle { display: none; }
.nav-scrim  { display: none; }

/* --- Tablet: icon rail --- */
@media (max-width: 1024px) and (min-width: 768px) {
  .sidebar { width: 60px; min-width: 60px; }
  .sidebar .brand-name, .sidebar .brand-sub, .sidebar .nav-group,
  .sidebar .nav-item span.lbl, .sidebar .user-meta, .sidebar .user-actions,
  .sidebar .nav-soon { display: none; }
  /* the group headers are hidden on the rail, so a collapsed group would have
     no handle to reopen it — on the rail every screen stays visible */
  .sidebar .nav-sect.collapsed .nav-items { display: block; }
  .sidebar .brand { justify-content: center; padding: 0; }
  .sidebar .user-box { justify-content: center; padding: var(--sp-3) 0; cursor: pointer; }
  .nav { padding: var(--sp-2) 0; }
  .nav-item { justify-content: center; padding: 10px 0; border-left-width: 3px; }
  .nav-item .ico { width: 18px; height: 18px; }
  /* keep the alert counts visible — they are the reason to look at the rail */
  .nav-badge {
    position: absolute; top: 4px; right: 7px;
    margin-left: 0; padding: 0 4px; min-width: 15px;
    font-size: calc(9px * var(--fs-scale)); line-height: 15px;
  }
  .content { padding: var(--sp-5) var(--sp-4); }
  .field-lg { width: 220px; }
  .topbar { padding: 0 var(--sp-4); }
}

/* --- Phone: off-canvas drawer + single-column forms --- */
@media (max-width: 767px) {
  .sidebar {
    position: fixed; top: 0; left: 0; z-index: 60;
    width: 258px; min-width: 258px;
    transform: translateX(-100%);
    /* visibility, not just an off-screen transform: a translated-but-visible
       drawer keeps a live paint layer that can be left behind as a ghost
       "second sidebar" when the window crosses this breakpoint */
    visibility: hidden;
    transition: transform 0.22s ease, visibility 0s linear 0.22s;
    box-shadow: 2px 0 18px rgba(0, 0, 0, 0.32);
  }
  body.nav-open .sidebar {
    transform: none;
    visibility: visible;
    transition: transform 0.22s ease, visibility 0s;
  }
  body.nav-open { overflow: hidden; }
  .nav-scrim {
    display: block; position: fixed; inset: 0; z-index: 50;
    background: var(--scrim);
    opacity: 0; pointer-events: none; transition: opacity 0.22s ease;
  }
  body.nav-open .nav-scrim { opacity: 1; pointer-events: auto; }

  .nav-toggle {
    display: inline-flex; align-items: center; justify-content: center;
    width: 36px; height: 36px; flex-shrink: 0;
    margin-left: calc(var(--sp-3) * -1);
    background: none; border: none; border-radius: var(--radius-sm);
    color: var(--text-secondary); font-size: calc(18px * var(--fs-scale)); line-height: 1; cursor: pointer;
  }
  .nav-toggle:active { background: var(--neutral-bg); }

  /* keep the day/night and text-size pickers reachable; the chips just repeat
     information already shown on the pages themselves */
  .topbar { padding: 0 var(--sp-3); gap: var(--sp-2); }
  .breadcrumb { font-size: var(--fs-xs); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .topbar .chip { display: none; }
  .fs-pick { max-width: 92px; padding: 0 var(--sp-1); }
  .content { padding: var(--sp-4) var(--sp-3); }

  .page-title { font-size: var(--fs-lg); }
  .page-head { margin-bottom: var(--sp-4); }
  .card { margin-bottom: var(--sp-4); }
  .card-head { flex-wrap: wrap; }
  .card-head .actions { margin-left: 0; width: 100%; }

  /* one field per line, thumb-sized controls */
  .form-row { gap: var(--sp-3); }
  .form-row > div, .field-sm, .field-md, .field-lg { width: 100%; }
  .form-row > .btn { width: 100%; }
  .filters .filter-actions { margin-left: 0; width: 100%; }
  input, select, textarea { min-height: 40px; }
  .btn { min-height: 40px; padding: 0 var(--sp-4); }
  .btn-sm { min-height: 32px; }

  .kpi-grid { grid-template-columns: 1fr 1fr; gap: var(--sp-3); margin-bottom: var(--sp-4); }
  .kpi { padding: var(--sp-3); }
  .kpi .kpi-value { font-size: calc(19px * var(--fs-scale)); }

  /* tables stay readable and scroll sideways rather than squashing */
  table.data { font-size: var(--fs-xs); }
  table.data th, table.data td { padding: 7px var(--sp-2); }
  .table-wrap { -webkit-overflow-scrolling: touch; }
}

/* --- Small phones --- */
@media (max-width: 430px) {
  .kpi-grid { grid-template-columns: 1fr; }
  .page-sub { display: none; }
}

/* ---------- 15b. Cost tracing ----------
   Two rows the costing reports need: one that flags a figure which does not
   reconcile, and one that hangs detail underneath the row it belongs to. */

table.data tr.row-warn > td {
  background: var(--warning-bg);
  box-shadow: inset 3px 0 0 var(--warning);
}

table.data tr.sub-row > td {
  background: var(--bg);
  border-bottom-style: dotted;
  padding-top: var(--sp-1);
  padding-bottom: var(--sp-1);
}
table.data tr.sub-row + tr:not(.sub-row) > td { border-top: 1px solid var(--border); }

/* Spanned column-group headers, for the reports that put what came in and what
   went out side by side. The rule under each group is what tells the eye which
   figures belong together. */
table.data th.gh-in,
table.data th.gh-out {
  text-align: center;
  font-size: var(--fs-xs, 0.75rem);
  letter-spacing: 0.04em;
  border-bottom: 2px solid var(--border-strong, var(--border));
}
table.data th.gh-in  { box-shadow: inset 0 -2px 0 var(--success); }
table.data th.gh-out { box-shadow: inset 0 -2px 0 var(--brand-red, var(--danger)); }

/* ---------- 15c. Product picker ----------
   A button that opens a tick list, for reports read across several chosen
   products at once. Ticking nothing means everything, and the button says so. */
.wf-pick { position: relative; }
.wf-pick-btn {
  width: 100%; height: var(--control-h);
  padding: 0 var(--sp-3);
  text-align: left; cursor: pointer;
  font: inherit; font-size: var(--fs-sm); color: var(--text);
  background: var(--surface);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
}
.wf-pick-btn:focus-visible { outline: none; box-shadow: var(--focus-ring); }
.wf-pick-menu {
  position: absolute; top: calc(100% + 4px); left: 0; right: 0; z-index: 30;
  max-height: 280px; overflow-y: auto;
  background: var(--surface);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow-pop);
  padding: var(--sp-1) 0;
}
.wf-pick-menu label {
  display: flex; align-items: center; gap: var(--sp-2);
  padding: 5px var(--sp-3);
  font-size: var(--fs-sm);
}
.wf-pick-menu label:hover { background: var(--row-hover); }

/* ---------- 16. Print ----------
   Any page can be sent to the printer: drop the chrome, flatten the
   surfaces to ink-on-paper and keep table rows whole across breaks. */
@media print {
  :root { --fs-scale: 1; }
  body { background: #fff; color: #000; }
  .sidebar, .topbar, .nav-scrim, .row-menu, .modal-back,
  .page-head .actions, .card-head .actions, .filters, .toolbar,
  .btn, .fs-pick, .nav-toggle { display: none !important; }
  .shell { display: block; }
  .content { padding: 0; max-width: none; }
  .card {
    border: 1px solid #ccc; box-shadow: none; margin-bottom: 12px;
    break-inside: avoid;
  }
  .card-head { background: #fff; }
  table.data { font-size: 10.5pt; }
  table.data th {
    position: static;
    background: #f0f0f0 !important;
    color: #000; border-bottom: 1px solid #666;
    -webkit-print-color-adjust: exact; print-color-adjust: exact;
  }
  table.data td { border-bottom: 1px solid #ddd; }
  table.data tr { break-inside: avoid; }
  thead { display: table-header-group; }
  .badge {
    border: 1px solid #999; color: #000; background: none;
    -webkit-print-color-adjust: exact; print-color-adjust: exact;
  }
  .badge::before { display: none; }
}

/* A consequential action that is not a destructive one. Saving a month-end
   count moves the ledger onto the count and closes the period, so it must not
   look like an ordinary secondary button \u2014 but it destroys nothing, so it must
   not borrow the language of Clear and Delete either. */
.btn-warn { background: var(--surface); color: var(--warning); border-color: var(--warning-border); }
.btn-warn:hover:not(:disabled) { background: var(--warning-bg); }

/* The statement picker. A row of the whole set, with the current one filled in
   — the reader should be able to see what else there is without opening
   anything, because choosing between statements IS the task here. */
.fs-tabs { display: flex; flex-wrap: wrap; gap: .4rem; margin-bottom: .9rem; }
.fs-tab {
  border: 1px solid var(--border); background: var(--surface); color: var(--text);
  border-radius: 999px; padding: .38rem .85rem; font-size: .82rem; cursor: pointer;
  white-space: nowrap; transition: background .12s, border-color .12s;
}
.fs-tab:hover { background: var(--surface-2, var(--bg)); border-color: var(--text-muted); }
.fs-tab.on {
  /* gold carries dark text, not white — the theme pairs them for a reason */
  background: var(--accent); border-color: transparent;
  color: var(--accent-text); font-weight: 600;
}
