/* ============================================================
   Pangolin Back-Office — MASTER STYLESHEET
   ------------------------------------------------------------
   The single source of truth for the platform's look. Linked by
   EVERY page (login, dashboard, and every tool) as:
       <link rel="stylesheet" href="/assets/style.css">
   Tool-specific rules live in their own sheet loaded AFTER this
   one (e.g. /assets/form-builder.css, /assets/spend-tracker.css).

   Canonical token vocabulary — use these names everywhere:
     surfaces  --bg  --surface  --surface-2
     lines     --border  --border-2
     text      --text  --text-muted
     brand     --accent  --accent-hover  --accent-ink
     status    --ok  --danger
     chips     --chip  --chip-ink
   ============================================================ */
:root {
  --bg:           #0f1115;
  --surface:      #1a1d23;
  --surface-2:    #22262e;
  --border:       rgba(255, 255, 255, 0.08);
  --border-2:     rgba(255, 255, 255, 0.05);
  --text:         #e7e9ee;
  --text-muted:   #9aa1ad;
  --accent:       #A71F23;
  --accent-hover: #9c3b3e;
  --accent-ink:   #ffffff;
  --ok:           #3fb950;
  --danger:       #ff6b6b;
  --chip:         rgba(167, 31, 35, 0.18);
  --chip-ink:     #f2a3a5;

  --radius:     12px;
  --radius-sm:  8px;
  --gap:        1rem;
  --transition: 0.15s ease;

  --sans: "Montserrat", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Arial, sans-serif;
  --mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
}

/* ============================================================
   Base / reset
   ------------------------------------------------------------
   NOTE: raw <a>/<button> are kept minimal on purpose. Give
   interactive elements a real class (.btn, .tile, .icon-btn…)
   rather than relying on element-level styling.
   ============================================================ */
*, *::before, *::after { box-sizing: border-box; }

html, body { margin: 0; }
body {
  min-height: 100dvh;
  color: var(--text);
  background: radial-gradient(600px circle at 50% 15%, #9c3b3e12, transparent 55%), var(--bg);
  font-family: var(--sans);
  line-height: 1.5;
}
a { color: inherit; text-decoration: none; }
button { font-family: inherit; cursor: pointer; }
h1, h2, h3 { margin: 0; }

/* ============================================================
   Layout helpers
   ============================================================ */
.flex           { display: flex; }
.v-flex         { flex-direction: column; }
.justify-center { justify-content: center; }
.items-center   { align-items: center; }

/* Standard centered content column (used by tool bodies) */
.wrap { max-width: 1600px; margin: 0 auto; padding: 1.75rem 1.5rem 4rem; }

/* ============================================================
   Buttons — one system for the whole platform
   ------------------------------------------------------------
   Base .btn is a neutral inline pill. Compose modifiers:
     .btn--primary       accent-filled (main action)
     .btn--ghost         transparent (quiet action)
     .btn--sm            compact
     .btn--danger        red outline on hover (destructive-ish)
     .btn--danger-solid  filled red (confirm-destructive)
     .btn--block         full width (e.g. login submit)
   ============================================================ */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  white-space: nowrap;
  padding: 0.55rem 0.9rem;
  font-size: 0.9rem;
  font-weight: 600;
  font-family: inherit;
  color: var(--text);
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  cursor: pointer;
  transition: background var(--transition), border-color var(--transition), transform var(--transition);
}
.btn:hover   { border-color: var(--accent); }
.btn:active  { transform: translateY(1px); }

.btn--primary        { background: var(--accent); border-color: var(--accent); color: var(--accent-ink); }
.btn--primary:hover  { background: var(--accent-hover); border-color: var(--accent-hover); }
.btn--ghost          { background: transparent; }
.btn--ghost:hover    { background: var(--surface-2); }
.btn--sm             { padding: 0.35rem 0.6rem; font-size: 0.8rem; }
.btn--danger:hover   { border-color: var(--danger); color: var(--danger); }
.btn--danger-solid       { background: var(--danger); border-color: var(--danger); color: #2a0d0d; }
.btn--danger-solid:hover { background: #ff8585; border-color: #ff8585; }
.btn--block          { display: flex; width: 100%; }

/* Square icon-only button (row actions, close buttons, etc.) */
.icon-btn {
  display: grid; place-items: center; width: 30px; height: 30px; padding: 0;
  background: transparent; border: 1px solid transparent; border-radius: 6px;
  color: var(--text-muted); cursor: pointer;
}
.icon-btn:hover      { background: var(--surface-2); color: var(--text); }
.icon-btn--del:hover { color: var(--danger); }

/* ============================================================
   Form controls
   ------------------------------------------------------------
   .input  = roomy control (login / portal forms)
   .ctl    = shared appearance for tool controls; tools set
             their own padding/font-size/min-width on top.
   ============================================================ */
.input {
  width: 100%;
  padding: 0.8rem 1rem;
  font-size: 1rem;                 /* 16px -> stops iOS zooming on focus */
  font-family: inherit;
  color: var(--text);
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  transition: border-color var(--transition), box-shadow var(--transition);
}
.ctl {
  width: 100%;
  font-family: inherit;
  color: var(--text);
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  transition: border-color var(--transition), box-shadow var(--transition);
}
.input::placeholder, .ctl::placeholder { color: var(--text-muted); }
.input:focus, .ctl:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(167, 31, 35, 0.25);
}

/* ============================================================
   Card
   ============================================================ */
.card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 2rem;
  box-shadow: 0 20px 50px rgba(0, 0, 0, 0.45);
}

/* ============================================================
   Data table  ⭐ SHARED COMPONENT
   ------------------------------------------------------------
   Consumed by: inventory.php, spend-tracker.php.   public-safe.

   Opt IN with a class — this deliberately does NOT style a bare
   <table>. The signature app draws its divider bar as a fixed-width
   <table> (Outlook ignores width on a div), and the form builder
   renders user-generated HTML in its preview pane; an element rule
   here would reach both. A bare `table { min-width:720px }` was
   measured blowing the signature bar from 196px to 720px.

     <div class="table-wrap">
       <table class="tbl tbl--wide">          <- --wide = 720px floor
     ...and inside a dialog, where there is no room to scroll:
       <table class="tbl">                    <- no floor, cells wrap

   ⚠ SPECIFICITY — why the scope is wrapped in :where().
   These rules replace bare `thead th` / `tbody td` rules that used
   to live in the tool sheets. Every utility class in those sheets
   (.num, .chk-col, .row-item > td, .cell-name…) was written to beat
   an element selector, i.e. to outrank (0,0,2). Writing the shared
   rule as `.tbl thead th` raises it to (0,1,2) and silently steals
   all of them — measured: right-aligned numeric columns went
   left-aligned and row borders changed colour.
   `:where()` contributes ZERO specificity, so `:where(.tbl) thead th`
   is (0,0,2) — byte-identical in weight to the rule it replaces,
   while still being scoped so it cannot leak to the signature app.
   Needs Chrome 88 / Safari 14 / Firefox 78 (2020-21).
   Keep :where() on the SCOPE and never on the part a tool overrides.
   ============================================================ */
.table-wrap {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: auto;
}

.tbl        { width: 100%; border-collapse: collapse; font-size: 0.86rem; }
.tbl--wide  { min-width: 720px; }          /* scrolls inside .table-wrap */

:where(.tbl) thead th {
  text-align: left;
  padding: 0.7rem 0.85rem;
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--text-muted);
  background: var(--surface-2);
  border-bottom: 1px solid var(--border);
  position: sticky; top: 0;
  z-index: 2;                              /* or cell content paints over it */
  white-space: nowrap;
}
:where(.tbl) tbody td { padding: 0.6rem 0.85rem; border-bottom: 1px solid var(--border-2); vertical-align: middle; }
:where(.tbl) tbody tr:last-child td { border-bottom: none; }

/* Tied to --wide on purpose: a table with a 720px floor scrolls sideways, so
   keeping each cell on one line is what makes it readable. A table WITHOUT the
   floor (i.e. inside a dialog) has nowhere to scroll, so its cells must wrap. */
:where(.tbl--wide) tbody td { white-space: nowrap; }
:where(.tbl) td.empty { padding: 3rem 1rem; text-align: center; color: var(--text-muted); white-space: normal; }

/* Sortable column heading — the whole cell is the target, not just the words.
   First click on a new column sorts ascending; clicking the active one flips.
   (0,1,1), so it still outranks the :where(.tbl) thead th base above.) */
:where(.tbl) th.th-sort { padding: 0; }
:where(.tbl) th.th-sort > a {
  display: block;
  padding: 0.7rem 0.85rem;
  color: inherit;
  white-space: nowrap;
  transition: color var(--transition), background var(--transition);
}
:where(.tbl) th.th-sort > a:hover   { color: var(--text); background: rgba(255, 255, 255, 0.04); }
:where(.tbl) th.th-sort.num > a     { text-align: right; }
:where(.tbl) th.th-sort--active > a { color: var(--accent); }
.th-arrow { font-size: 0.6em; margin-left: 0.3em; vertical-align: middle; }

/* ============================================================
   Dialog  ⭐ SHARED COMPONENT
   ------------------------------------------------------------
   Consumed by: inventory.php, spend-tracker.php.   public-safe.
   Opt in with <dialog class="dlg">, for the same reason as .tbl.
   Add .dlg-wide for a roomier one (order forms, import previews).
   ============================================================ */
.dlg {
  padding: 0;
  width: min(600px, 94vw);
  color: var(--text);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: 0 30px 80px rgba(0, 0, 0, 0.6);
  color-scheme: dark;                      /* native scrollbars/controls go dark */
}
.dlg.dlg-wide  { width: min(920px, 96vw); }
.dlg::backdrop { background: rgba(0, 0, 0, 0.6); }

@media (max-width: 640px) {
  .dlg, .dlg.dlg-wide { width: 96vw; }
}

/* ============================================================
   Dialog internals  ⭐ SHARED COMPONENT
   ------------------------------------------------------------
   Consumed by: inventory.php, spend-tracker.php.   public-safe.
   Head / scrolling two-column body / right-aligned footer.
   ============================================================ */
.dlg-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 1rem 1.25rem; border-bottom: 1px solid var(--border);
}
.dlg-head h3 { font-size: 1.05rem; }
.dlg-body {
  display: grid; grid-template-columns: 1fr 1fr; gap: 0.85rem;
  padding: 1.25rem;
  max-height: 70vh; overflow-y: auto;     /* or a tall form runs off-screen */
}
.dlg-body .full  { grid-column: 1 / -1; }
.dlg-body label  { display: block; font-size: 0.72rem; text-transform: uppercase; letter-spacing: 0.05em; color: var(--text-muted); margin-bottom: 0.3rem; }
.dlg-body .ctl, .dlg-body textarea { width: 100%; }
.dlg-foot {
  display: flex; justify-content: flex-end; gap: 0.6rem;
  padding: 1rem 1.25rem; border-top: 1px solid var(--border);
}
@media (max-width: 640px) {
  .dlg-body { grid-template-columns: 1fr; padding: 1rem; max-height: 74vh; }
  .dlg-head, .dlg-foot { padding: 0.9rem 1rem; }
  .dlg-foot .btn { flex: 1; justify-content: center; }
}

/* ============================================================
   Panel · scorecards · section heading  ⭐ SHARED COMPONENTS
   ------------------------------------------------------------
   Consumed by: inventory.php, spend-tracker.php.   public-safe.
   ============================================================ */
.panel {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 1.1rem 1.25rem;
  margin-bottom: 1.25rem;
}
.panel__title {
  display: block;
  margin-bottom: 0.9rem;
  font-size: 0.8rem; text-transform: uppercase; letter-spacing: 0.06em;
  color: var(--text-muted);
}

.grid-2 { display: grid; grid-template-columns: 1.3fr 1fr; gap: 1rem; align-items: start; }
/* A grid item defaults to min-width:auto and will NOT shrink below its
   content's min-content width. Without this a wide table inside a panel forces
   the whole COLUMN wide and the page scrolls sideways — overflow:auto on
   .table-wrap cannot save it, because the column itself is oversized.
   This broke the inventory tracker's People tab at 375px (PLATFORM.md §6). */
.grid-2 > * { min-width: 0; }
@media (max-width: 900px) { .grid-2 { grid-template-columns: 1fr; } }

.cards  { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 1rem; margin-bottom: 1.25rem; }
.scard  { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); padding: 1.1rem 1.25rem; }
.scard__label { font-size: 0.75rem; text-transform: uppercase; letter-spacing: 0.06em; color: var(--text-muted); }
.scard__value { margin-top: 0.3rem; font-size: 1.7rem; font-weight: 700; font-variant-numeric: tabular-nums; }
.scard__sub   { margin-top: 0.25rem; font-size: 0.78rem; color: var(--text-muted); }
.scard--accent .scard__value { color: var(--accent); }

.section-head {
  display: flex; align-items: center; justify-content: space-between;
  gap: 1rem; flex-wrap: wrap; margin: 1.5rem 0 0.8rem;
}
.section-head h2        { font-size: 1.15rem; }
.section-head__actions  { display: flex; gap: 0.6rem; flex-wrap: wrap; }

@media (max-width: 640px) {
  .cards        { grid-template-columns: 1fr 1fr; gap: 0.6rem; }
  .scard        { padding: 0.8rem 0.9rem; }
  .scard__value { font-size: 1.3rem; }
  .section-head          { flex-direction: column; align-items: stretch; }
  .section-head__actions { width: 100%; }
  .section-head__actions .btn { flex: 1; justify-content: center; }
}

/* ============================================================
   Row expander  ⭐ SHARED COMPONENT
   ------------------------------------------------------------
   Consumed by: MS, INV.   public-safe.
   Driven by ui.js: <button class="exp" data-toggle="k"> reveals
   every <tr data-child="k"> by clearing .is-hidden.

     <th class="col-exp"></th>              in the header
     <td class="col-exp">…chevron…</td>     in the row
     <tr class="row-sub is-hidden" data-child="k">
       <td class="col-exp"></td>
       <td colspan="N" class="sub row-note"><span>…</span></td>

   THE PLATFORM RULE FOR NOTES (PLAN Phase 5 §5.1): a note that can
   run long and is not needed at a glance goes behind this chevron.
   A note that is habitually one line and is context for the row
   above it stays inline. Do not truncate a note and rely on a
   title= tooltip — that does not exist on touch.
   ============================================================ */
.col-exp { width: 34px; padding-right: 0 !important; }
.exp {
  display: grid; place-items: center; width: 22px; height: 22px; padding: 0;
  background: transparent; border: 1px solid transparent; border-radius: 5px;
  color: var(--text-muted); cursor: pointer; transition: var(--transition);
}
.exp:hover { background: var(--surface-2); color: var(--text); }
.exp svg { transition: transform var(--transition); }
.exp[aria-expanded="true"] svg { transform: rotate(90deg); }
.exp[aria-expanded="true"]     { color: var(--accent); }

.row-sub td   { white-space: normal; background: rgba(255, 255, 255, 0.015); }
.row-note     { line-height: 1.55; padding-top: 0.5rem !important; padding-bottom: 0.7rem !important; }
.row-note span { display: block; max-width: 90ch; }

@media (max-width: 640px) {
  .exp { width: 32px; height: 32px; }                        /* roomier tap target */
  /* Keep the note wrapping inside the screen rather than running to the table's
     full (scrollable) width. */
  .row-note span { max-width: calc(100vw - 5.5rem); }
}

/* ============================================================
   Tabs  ⭐ SHARED COMPONENT
   ------------------------------------------------------------
   Consumed by: FB, INV.   public-safe.
   BEM `--active`, per §6.4 — never `.tab.active`.

   Only the TAB is shared. The `.tabs` container is deliberately
   per-tool: inventory's is inline section nav under the page
   heading, the form builder's is a toolbar strip with its own
   background inside a pane header. Same control, two layouts.
   ============================================================ */
.tab {
  padding: 0.45rem 0.9rem;
  border: 1px solid transparent;
  border-radius: 20px;
  font-size: 0.88rem;
  font-weight: 600;
  font-family: inherit;
  color: var(--text-muted);
  background: transparent;
  cursor: pointer;
  transition: var(--transition);
}
.tab:hover      { color: var(--text); background: var(--surface-2); }
.tab--active    { background: var(--accent); border-color: var(--accent); color: #fff; }

@media (max-width: 640px) {
  .tab { padding: 0.4rem 0.7rem; font-size: 0.82rem; }
}

/* ============================================================
   Chips  ⭐ SHARED COMPONENT
   ------------------------------------------------------------
   Consumed by: inventory.php, spend-tracker.php.   public-safe.
   ============================================================ */
.chip {
  display: inline-block;
  padding: 0.12rem 0.5rem;
  border-radius: 20px;
  font-size: 0.72rem;
  font-weight: 600;
  white-space: nowrap;
  background: var(--chip);
  color: var(--chip-ink);
}
.chip--muted { background: var(--surface-2);             color: var(--text-muted); font-weight: 500; }
.chip--ok    { background: rgba(63, 185, 80, 0.16);      color: #7ee08a; }
.chip--warn  { background: rgba(230, 170, 60, 0.16);     color: #e8bf72; }
.chip--low   { background: rgba(255, 107, 107, 0.18);    color: #ffb3b3; margin-left: 0.35rem; }
.chip--out   { background: rgba(255, 107, 107, 0.18);    color: #ffb3b3; }

/* ============================================================
   Bulk selection  ⭐ SHARED COMPONENT
   ------------------------------------------------------------
   Consumed by: inventory.php, spend-tracker.php.   public-safe.
   NOTE: `row-selected` is added and removed by JavaScript in both
   tools' scripts. The rule may move; the NAME must not change.
   ============================================================ */
.chk-col { width: 38px; text-align: center; }
.chk-col input { width: 16px; height: 16px; accent-color: var(--accent); cursor: pointer; vertical-align: middle; }
:where(.tbl) tbody tr.row-selected { background: rgba(167, 31, 35, 0.12); }

.bulkbar {
  position: fixed; left: 50%; transform: translateX(-50%); bottom: 20px; z-index: 60;
  display: flex; align-items: center; gap: 0.75rem; flex-wrap: wrap;
  padding: 0.6rem 0.9rem; max-width: calc(100vw - 2rem);
  background: var(--surface-2); border: 1px solid var(--border);
  border-radius: var(--radius); box-shadow: 0 16px 40px rgba(0, 0, 0, 0.55);
}
.bulkbar[hidden]        { display: none; }
.bulkbar__count         { font-size: 0.9rem; }
.bulkbar__count strong  { color: var(--accent); }
@media (max-width: 640px) {
  /* Full width, clear of the home indicator. Pages that show a bulk bar need
     extra bottom padding on .wrap so it cannot cover the last row. */
  .bulkbar { left: 0.5rem; right: 0.5rem; transform: none; bottom: 0.6rem; justify-content: center; }
}

/* ============================================================
   Small shared utilities
   ------------------------------------------------------------
   Consumed by: inventory.php, spend-tracker.php.   public-safe.
   Deliberately single-class (0,1,0) so they still beat the
   :where()-scoped table rules above, exactly as they used to beat
   the bare element rules they replaced.
   ============================================================ */
/* Toggled by the shared expander in ui.js. The NAME is part of that contract —
   the rule may move, but do not rename it. */
.is-hidden { display: none; }

.num     { text-align: right; font-variant-numeric: tabular-nums; }
.nowrap  { white-space: nowrap; }
.sub     { font-size: 0.78rem; color: var(--text-muted); }
.cell-actions { display: flex; gap: 0.2rem; justify-content: flex-end; align-items: center; }
.cell-actions form { display: inline; margin: 0; }

/* ============================================================
   Flash / inline messages
   ============================================================ */
.flash        { padding: 0.7rem 1rem; border-radius: var(--radius-sm); margin-bottom: 1.25rem; font-size: 0.9rem; }
.flash--ok    { background: rgba(63, 185, 80, 0.10); border: 1px solid rgba(63, 185, 80, 0.30); color: #7ee08a; }
.flash--err   { background: rgba(255, 107, 107, 0.10); border: 1px solid rgba(255, 107, 107, 0.30); color: var(--danger); }

/* ============================================================
   Top bar — shared across every tool
   ------------------------------------------------------------
   Two-tier friendly: brand + crumb on the left, actions on the
   right. Tools that need a second row of controls add their own
   bar (e.g. .toolbar) directly below this one.
   ============================================================ */
.topbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 1rem 1.5rem;
  background: var(--bg);
  border-bottom: 1px solid var(--border);
  position: sticky; top: 0; z-index: 30;
}
.topbar__left   { display: flex; align-items: center; gap: 14px; min-width: 0; }
.topbar__brand  { font-weight: 700; letter-spacing: 0.02em; color: var(--accent); font-size: 15px; }
.topbar__crumb  { color: var(--text-muted); font-size: 13px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.topbar__actions{ display: flex; align-items: center; gap: 8px; flex: none; }
@media (max-width: 640px) {
  .topbar { padding: 0.7rem 1rem; }
  .topbar__crumb { display: none; }         /* keep the small bar to brand + actions */
}

/* ============================================================
   Portal / dashboard
   ============================================================ */
.portal { max-width: 960px; margin: 0 auto; padding: 2.5rem 1.5rem; }
.portal__title    { margin: 0 0 0.25rem; font-size: 2rem; }
.portal__subtitle { margin: 0 0 2rem; color: var(--text-muted); }

.tiles {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 1rem;
}
.tile {
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
  padding: 1.5rem;
  background: var(--surface);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  transition: border-color var(--transition), transform var(--transition), background var(--transition);
}
.tile:hover {
  background: var(--surface-2);
  border-color: var(--accent);
  transform: translateY(-2px);
}
.tile:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.tile__icon {
  display: flex; width: 42px; height: 42px; align-items: center; justify-content: center;
  border-radius: var(--radius-sm); background: #a71f231c; color: var(--accent);
}
.tile__title { font-weight: 600; }
.tile__desc  { font-size: 0.9rem; color: var(--text-muted); }

/* ============================================================
   Login page
   ============================================================ */
.login { min-height: 100dvh; align-items: center; justify-content: center; padding: 1.5rem; }
.login__box   { width: 100%; max-width: 380px; }
.login__brand {
  margin: 0 0 0.25rem; font-size: 0.8rem; font-weight: 600;
  letter-spacing: 0.08em; text-transform: uppercase; color: var(--accent);
}
.login__title { margin: 0 0 1.5rem; font-size: 1.75rem; }
.login__form  { gap: var(--gap); }
.login__error {
  margin: 0 0 1rem; padding: 0.75rem 1rem; font-size: 0.9rem; color: var(--danger);
  background: rgba(255, 107, 107, 0.10); border: 1px solid rgba(255, 107, 107, 0.30);
  border-radius: var(--radius-sm);
}
