/* PAM web UI — a Notion-like workspace with a macOS menu bar.
   Layout: [menubar] / [sidebar | main]. Palette and metrics are tuned to
   read like Notion: hairline borders, soft grays, generous whitespace. */

:root {
  --font: "Rethink Sans", -apple-system, BlinkMacSystemFont, "Segoe UI",
          "Helvetica Neue", Arial, sans-serif;
  --mono: "Geist Mono", ui-monospace, SFMono-Regular, "SF Mono", Menlo,
          Consolas, monospace;

  --bg: #ffffff;
  --bg-sidebar: #f7f7f5;
  --bg-hover: #efefed;
  --bg-active: #e8e8e6;
  --text: #37352f;
  --text-soft: #787774;
  --text-faint: #9b9a97;
  --border: #ebebea;
  --border-strong: #e0e0de;
  --accent: #2383e2;
  --accent-soft: #e7f1fb;
  /* Derived accent states — kept as color-mix() over var(--accent) so a
     white-labelled accent (set at runtime on :root) re-tints them too, instead
     of falling back to a baked-in blue. --accent-hover: a touch darker for the
     pressed/hover primary action. --accent-ring: the accent at 30% alpha for
     the selected-cell hairline. */
  --accent-hover: color-mix(in srgb, var(--accent) 90%, #000);
  --accent-ring: color-mix(in srgb, var(--accent) 30%, transparent);
  /* The palest accent tint — the barely-there lift behind the sign-in card. */
  --accent-wash: color-mix(in srgb, var(--accent) 8%, #fff);
  --danger: #eb5757;
  /* Soft, Notion-like elevation. Small popups use --shadow; floating panels
     (modal, drawer) use --shadow-lg. Kept deliberately faint — a hairline
     ring for definition plus a whisper of a drop, never a dark halo. */
  --shadow: 0 0 0 1px rgba(15, 15, 15, .03), 0 1px 3px rgba(15, 15, 15, .035);
  --shadow-lg: 0 0 0 1px rgba(15, 15, 15, .035), 0 1px 2px rgba(15, 15, 15, .03),
            0 4px 14px rgba(15, 15, 15, .055);

  --menubar-h: 30px;
  --topbar-h: 44px;
  --sidebar-w: 248px;

  /* tag palette (Notion-ish) */
  --t-gray: #e3e2e0;   --t-gray-fg: #5a5a57;
  --t-brown: #eee0da;  --t-brown-fg: #6c5a4e;
  --t-orange: #fadec9; --t-orange-fg: #8a5527;
  --t-yellow: #fdecc8; --t-yellow-fg: #7c6213;
  --t-green: #dbeddb;  --t-green-fg: #2b5e3a;
  --t-blue: #d3e5ef;   --t-blue-fg: #1c4f6b;
  --t-purple: #e8deee; --t-purple-fg: #54407a;
  --t-pink: #f5e0e9;   --t-pink-fg: #84365f;
  --t-red: #ffe2dd;    --t-red-fg: #8a3a2c;
}

* { box-sizing: border-box; }
html, body { height: 100%; margin: 0; }
body {
  font-family: var(--font);
  color: var(--text);
  background: var(--bg);
  font-size: 14px;
  -webkit-font-smoothing: antialiased;
}
button { font-family: inherit; cursor: pointer; }
input, select, textarea { font-family: inherit; font-size: 14px; }

/* Notion-style checkbox: a rounded square that fills with the accent and
   shows a white tick when checked. Applies everywhere (filters, forms). */
input[type="checkbox"] {
  appearance: none; -webkit-appearance: none; margin: 0;
  width: 16px; height: 16px; flex-shrink: 0;
  border: 1.5px solid var(--border-strong); border-radius: 4px;
  background: #fff; cursor: pointer; vertical-align: middle;
  /* Grid centers the tick; a small optical nudge sits the vertex true. */
  display: inline-grid; place-content: center;
  transition: background .12s ease, border-color .12s ease;
}
input[type="checkbox"]::before {
  content: ""; width: 4px; height: 8px;
  border: solid #fff; border-width: 0 2px 2px 0;
  transform: translate(-0.5px, -1px) rotate(45deg);
  opacity: 0; transition: opacity .1s ease;
}
input[type="checkbox"]:hover { border-color: var(--text-faint); }
input[type="checkbox"]:checked { background: var(--accent); border-color: var(--accent); }
input[type="checkbox"]:checked::before { opacity: 1; }
input[type="checkbox"]:focus-visible {
  outline: 0; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft);
}

/* dvh, not vh, where supported: on mobile browsers 100vh includes the area
   behind the collapsing address bar, which would hide the bottom tab bar. */
#app { height: 100vh; height: 100dvh; display: flex; flex-direction: column; }

/* ---------------- macOS menu bar -------------------------------------- */
.menubar {
  height: var(--menubar-h);
  display: flex;
  align-items: center;
  gap: 2px;
  padding: 0 8px;
  background: rgba(246, 246, 246, .85);
  backdrop-filter: saturate(180%) blur(20px);
  border-bottom: 1px solid var(--border-strong);
  user-select: none;
  position: relative;
  z-index: 50;
  font-size: 13px;
}
/* The app icon (mascot). On wide screens it's the static logo it always was;
   on narrow screens it doubles as the tap target that reveals the vertical menu
   drawer (see the responsive block at the foot). */
.menubar .logo { font-size: 15px; line-height: 1; padding: 0 10px 0 6px; }
.menubar img.logo { width: 19px; height: 19px; padding: 0 9px 0 5px; box-sizing: content-box; display: block; object-fit: contain; }
/* The horizontal row of top-level menus. Wrapping them lets the responsive
   block collapse the whole group into a drawer without touching each menu. */
.menubar-menus { display: flex; align-items: center; gap: 2px; }
.menu { position: relative; }
.menu > button {
  background: none; border: 0; padding: 3px 9px; border-radius: 5px;
  color: var(--text); font-size: 13px; line-height: 1;
}
.menu > button:hover, .menu.open > button { background: rgba(0, 0, 0, .08); }
.menu-dropdown {
  position: absolute; top: calc(100% + 3px); left: 0;
  min-width: 240px; padding: 5px;
  background: rgba(250, 250, 250, .98);
  backdrop-filter: blur(20px);
  border: 1px solid var(--border-strong);
  border-radius: 7px; box-shadow: var(--shadow);
}
.menu-dropdown button {
  display: flex; justify-content: space-between; align-items: center;
  width: 100%; gap: 24px;
  background: none; border: 0; text-align: left;
  padding: 5px 8px; border-radius: 5px; color: var(--text); font-size: 13px;
}
.menu-dropdown button:hover { background: var(--accent); color: #fff; }
.menu-dropdown button:disabled { color: var(--text-faint); background: none; }
.menu-dropdown .shortcut { color: var(--text-faint); font-size: 12px; }
.menu-dropdown button:hover .shortcut { color: rgba(255, 255, 255, .8); }
.menu-sep { height: 1px; background: var(--border); margin: 5px 6px; }
.menubar .spacer { flex: 1; }
.menubar .book-menu > button { display: flex; align-items: center; gap: 6px; font-weight: 500; }
.menubar .book-menu .book-ico { font-size: 12px; }

/* ---- offline sync indicator ------------------------------------------ */
/* A quiet status pill on the menu bar: a soft dot + a short label, shown only
   when offline or there are queued writes. Click opens a small panel listing
   what's waiting, with Sync-now / discard controls. */
.menubar .sync-menu { position: relative; }
.sync-pill {
  display: flex; align-items: center; gap: 6px;
  background: none; border: 0; border-radius: 5px;
  padding: 3px 9px; font: inherit; font-size: 12px;
  color: var(--text-soft); line-height: 1;
}
.sync-pill:hover, .sync-menu.open .sync-pill { background: rgba(0, 0, 0, .08); }
.sync-dot {
  width: 7px; height: 7px; border-radius: 50%;
  background: var(--text-faint); flex-shrink: 0;
}
.sync-pill.pending .sync-dot { background: var(--accent); }
.sync-pill.failed .sync-dot { background: var(--danger); }
.sync-dot.spin { animation: sync-pulse 1s ease-in-out infinite; }
@keyframes sync-pulse { 0%, 100% { opacity: 1; } 50% { opacity: .35; } }

.sync-head { padding: 8px 9px 6px; }
.sync-head .sync-state { font-size: 13px; font-weight: 600; color: var(--text); }
.sync-head .sync-sub {
  margin-top: 3px; font-size: 12px; color: var(--text-soft); line-height: 1.45;
}
.sync-list { max-height: 220px; overflow-y: auto; padding: 2px 0; }
.sync-dropdown .sync-item {
  display: flex; align-items: center; gap: 8px;
  width: 100%; padding: 4px 9px;
  font-size: 12.5px; color: var(--text-soft);
}
.sync-item-dot {
  width: 5px; height: 5px; border-radius: 50%;
  background: var(--text-faint); flex-shrink: 0;
}
.sync-item.failed .sync-item-dot { background: var(--danger); }
.sync-item-label {
  flex: 1; min-width: 0; overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap;
}
.sync-item-tag {
  font-size: 11px; color: var(--danger);
  font-family: var(--mono); flex-shrink: 0;
}
.sync-dropdown .sync-item-rm {
  width: 18px; height: 18px; padding: 0; flex-shrink: 0;
  display: grid; place-content: center;
  background: none; border: 0; border-radius: 4px;
  color: var(--text-faint); font-size: 15px; line-height: 1;
}
.sync-dropdown .sync-item-rm:hover { background: var(--bg-hover); color: var(--text); }
.sync-actions {
  display: flex; align-items: center; gap: 8px; padding: 4px 7px 2px;
}
.sync-actions .spacer { flex: 1; }
.sync-dropdown .sync-actions .btn {
  width: auto; gap: 0; justify-content: center;
  padding: 4px 12px; font-size: 13px;
}
.sync-dropdown .sync-actions .btn.primary { background: var(--accent); color: #fff; }
.sync-dropdown .sync-actions .btn.primary:hover { background: var(--accent); color: #fff; }
.sync-dropdown .sync-actions .btn.ghost:hover { background: var(--bg-hover); color: var(--text); }
.sync-dropdown .sync-actions .btn:disabled { opacity: .5; cursor: default; }

/* ---------------- workspace shell ------------------------------------- */
.workspace { flex: 1; display: flex; min-height: 0; }

.sidebar {
  width: var(--sidebar-w); flex-shrink: 0;
  background: var(--bg-sidebar);
  border-right: 1px solid var(--border);
  display: flex; flex-direction: column;
  padding: 10px 0; overflow-y: auto;
}
.sidebar .section-label {
  font-size: 11px; text-transform: uppercase; letter-spacing: .04em;
  color: var(--text-faint); padding: 12px 14px 4px;
}
/* Collapsible group header: a disclosure chevron + label that toggles the
   group. Borderless with a quiet bg-hover, like the nav items it heads. */
.sidebar .section-label.collapsible {
  display: flex; align-items: center; gap: 6px; cursor: pointer;
  user-select: none; margin: 4px 8px 0; padding: 8px 8px 4px; border-radius: 6px;
}
.sidebar .section-label.collapsible.first { margin-top: 0; }
.sidebar .section-label.collapsible:hover { background: var(--bg-hover); }
.sidebar .section-label .sec-caret {
  margin-left: auto; font-size: 10px; line-height: 1; color: var(--text-soft);
  display: inline-block; transition: transform .12s ease;
}
.sidebar .section-label .sec-caret.collapsed { transform: rotate(-90deg); }
.nav-item {
  display: flex; align-items: center; gap: 8px;
  margin: 1px 8px; padding: 5px 8px; border-radius: 6px;
  color: var(--text-soft); font-size: 14px; cursor: pointer;
}
.nav-item:hover { background: var(--bg-hover); }
.nav-item.active { background: var(--bg-active); color: var(--text); font-weight: 500; }
.nav-item .icon { width: 18px; text-align: center; opacity: .8; }
.nav-item .count {
  margin-left: auto; font-size: 12px; color: var(--text-faint);
  background: rgba(0,0,0,.04); border-radius: 9px; padding: 0 7px;
}

/* Scrim behind the sidebar when it overlays the content on narrow screens.
   Hidden by default (and on wide screens); the responsive block switches it on.
   Mirrors the modal's light frosted scrim so the page stays visible behind it. */
.sidebar-scrim { display: none; }

/* ---------------- main panel ------------------------------------------ */
.main { flex: 1; min-width: 0; display: flex; flex-direction: column; overflow: hidden; }
.topbar {
  height: var(--topbar-h); flex-shrink: 0;
  display: flex; align-items: center; gap: 10px;
  /* Left padding matches the menubar (8px) so the collapsed-sidebar toggle
     lines up with the "PAM" logo; the right side keeps its roomier padding. */
  padding: 0 22px 0 8px; border-bottom: 1px solid var(--border);
}
.topbar .icon-btn,
.toolbar .icon-btn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 28px; height: 28px; margin-right: 0;
  border: 0; background: none; color: var(--text-soft); border-radius: 6px;
}
.topbar .icon-btn:hover,
.toolbar .icon-btn:hover { background: var(--bg-hover); color: var(--text); }
.topbar .crumbs { color: var(--text-soft); font-size: 13px; }
.topbar h1 { font-size: 16px; margin: 0; font-weight: 600; }
.topbar .spacer { flex: 1; }
.btn {
  border: 1px solid var(--border-strong); background: #fff; color: var(--text);
  padding: 5px 11px; border-radius: 6px; font-size: 13px; font-weight: 500;
}
.btn:hover { background: var(--bg-hover); }
.btn.primary { background: var(--accent); color: #fff; border-color: var(--accent); }
.btn.primary:hover { background: var(--accent-hover); }
.btn.ghost { border-color: transparent; color: var(--text-soft); }
.btn.ghost:hover { background: var(--bg-hover); }
.btn.danger { color: var(--danger); }
.toolbar {
  display: flex; align-items: center; gap: 8px;
  padding: 8px 22px; border-bottom: 1px solid var(--border);
}
/* The search flexes to fill the whole toolbar row; every other control
   (SUM tally, toggles, export, the "N of M" count) sits at its natural width
   and floats to the right, shrinking the search as space runs out. Note: the
   meta/controls must NOT use margin-left:auto — an auto margin would absorb the
   free space before flex-grow could, leaving the search at its content width. */
.toolbar input.search {
  border: 0; outline: 0; background: none; font-size: 13px;
  color: var(--text); flex: 1 1 auto; min-width: 0;
}
.toolbar .toolbar-meta { color: var(--text-faint); font-size: 12px; flex-shrink: 0; }
/* Selection tally — sits next to the search box, reads like the "N of M" meta
   but with a mono, tabular figure so subtotals line up as you sweep cells. */
.toolbar .sum-meta { color: var(--text-soft); white-space: nowrap; }
.toolbar .sum-meta b {
  font-weight: 600; color: var(--text);
  font-family: var(--mono); font-variant-numeric: tabular-nums;
}
/* Wrapper for the toolbar "New ▾" split button. A plain positioning context —
   NOT .menu, whose `.menu > button` rule would override the .btn padding. */
.newmenu { position: relative; }
/* Lift its dropdown above the table's sticky header (z-index:2); it lives in
   the topbar, not the menubar, so it doesn't inherit the menubar's stacking. */
.newmenu .menu-dropdown { z-index: 60; }

.scroll { flex: 1; overflow: auto; }

/* ---------------- full-screen editor page (deal / investor) ------------ */
/* A page takes over the whole .main area in place of the table: it borrows
   the .topbar for its header (back + title + Save) and .scroll for the body,
   then centres the form in a document-width column so it reads like a page,
   not a stretched-wide modal. */
.page { flex: 1; min-height: 0; display: flex; flex-direction: column; }
.page-doc { max-width: 760px; margin: 0 auto; padding: 20px 24px 64px; }
.page-doc .report-group-title:first-child { margin-top: 4px; }
.page-hint { font-size: 12px; color: var(--text-faint); margin: 8px 2px 0; line-height: 1.5; }
/* Settings pages (account → Settings) reuse the .page shell and the .sidebar
   nav language; these are the only extras. The intro sits atop a settings
   page's doc column; the "← Back to app" item sits at the foot of the settings
   sidebar, pushed down and set off by a hairline. */
.settings-intro { color: var(--text-soft); font-size: 13px; line-height: 1.55; margin: 0 0 22px; }
/* A copyable link row (Investor logins → "Share with your investors"): reads
   like an input — hairline --border-strong box, 7px radius — holding the URL in
   mono, with its actions as ordinary buttons at the end. */
.share-link {
  display: flex; align-items: center; gap: 6px;
  border: 1px solid var(--border-strong); border-radius: 7px; padding: 3px 3px 3px 10px;
  background: var(--bg-sidebar);
}
.share-link code {
  flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font-family: var(--mono); font-size: 12px; color: var(--text);
}
.share-link .btn { padding: 3px 9px; font-size: 12px; text-decoration: none; }
.share-help { font-size: 12px; color: var(--text-faint); line-height: 1.5; margin: 6px 0 22px; }
.settings-sidebar { display: flex; flex-direction: column; }
.settings-back { margin-top: auto; border-top: 1px solid var(--border); padding-top: 10px; }
.settings-back .icon { font-size: 15px; }

/* Icon action button for a dense table row (e.g. remove) — quiet by default, a
   soft danger wash on hover. Cleaner than a full text button inside a row. */
.row-icon-btn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 26px; height: 26px; padding: 0; border: 0; background: none;
  border-radius: 6px; color: var(--text-faint); cursor: pointer;
  transition: background .12s ease, color .12s ease;
}
.row-icon-btn:hover { background: var(--bg-hover); color: var(--text); }
.row-icon-btn.danger:hover { background: var(--t-red); color: var(--t-red-fg); }
/* The 26px button is taller than a text line, so its cell would inflate the row
   (making rows with a remove button taller than those without). Trim its
   vertical padding so the text cells uniformly set the row height. */
.ntable td:has(> .row-icon-btn) { padding-top: 3px; padding-bottom: 3px; }

/* ---------------- Notion-like table ----------------------------------- */
.ntable { width: 100%; border-collapse: collapse; font-size: 14px; min-width: max-content; }
.ntable thead th {
  position: sticky; top: 0; z-index: 2;
  background: var(--bg); text-align: left; font-weight: 500;
  color: var(--text-soft); font-size: 13px;
  padding: 3px 4px; border-bottom: 1px solid var(--border);
  border-right: 1px solid var(--border); white-space: nowrap;
  overflow: hidden;
}
.ntable thead th .th {
  display: flex; align-items: center; gap: 6px;
  padding: 4px 6px; border-radius: 5px; cursor: pointer;
}
/* Let a pinned (resized) header label shrink and clip instead of forcing the
   column wider; min-width:0 frees the flex item to shrink below its content. */
.ntable thead th .th-label { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
/* Drag handle on each header's right edge — invisible until hovered, then a
   quiet accent hairline (mirroring the focus ring). Drag to resize the column;
   double-click to auto-fit it back to content width. */
.ntable thead th .col-resize {
  position: absolute; top: 0; right: 0; width: 8px; height: 100%;
  cursor: col-resize; z-index: 3; user-select: none;
}
.ntable thead th .col-resize::after {
  content: ''; position: absolute; top: 5px; bottom: 5px; right: 3px; width: 1px;
  background: transparent; transition: background .12s ease;
}
.ntable thead th .col-resize:hover::after { background: var(--accent); }
.ntable.resizing { cursor: col-resize; user-select: none; }
.ntable thead th .th-btn:hover { background: var(--bg-hover); }
.ntable thead th .th-btn.active { color: var(--text); }
.ntable thead th.num .th { justify-content: flex-end; }
.ntable thead th .tico { color: var(--text-faint); font-size: 12px; width: 14px; }
.ntable thead th .th-caret { color: var(--text-faint); font-size: 10px; opacity: .5; }
.ntable thead th .th-btn:hover .th-caret { opacity: 1; }
.ntable thead th .th-sort { color: var(--accent); font-size: 12px; }
.ntable thead th .th-dot { color: var(--accent); font-size: 8px; }
.ntable tbody td {
  padding: 7px 10px; border-bottom: 1px solid var(--border);
  border-right: 1px solid var(--border); vertical-align: top;
  color: var(--text); white-space: nowrap; max-width: 420px;
  overflow: hidden; text-overflow: ellipsis;
}
.ntable tbody tr:hover td { background: #fbfbfa; }
.ntable tbody tr.voided td { color: var(--text-faint); text-decoration: line-through; }
/* Report tables put several name columns side by side (fund, deal, party);
   cap them tighter so the figures stay in view. Full text on hover. */
.ntable.rtable tbody td:not(.num):not(.rowidx) { max-width: 280px; }
@media (max-width: 768px) {
  .ntable.rtable tbody td:not(.num):not(.rowidx) { max-width: 150px; }
}
.ntable td.num, .ntable th.num { text-align: right; font-variant-numeric: tabular-nums; font-family: var(--mono); }
.ntable td.mono { font-family: var(--mono); font-size: 12px; color: var(--text-soft); }
.ntable td.muted { color: var(--text-faint); }
.ntable .rowidx { color: var(--text-faint); width: 36px; text-align: right; font-size: 12px; position: relative; }
.grp-caret {
  position: absolute; inset: 0; opacity: 0;
  display: flex; align-items: center; justify-content: center;
  border: 0; background: none; cursor: pointer; color: var(--text-faint);
  padding: 0;
}
.grp-caret svg { width: 17px; height: 17px; display: block; }
.grp-toggle { display: inline-flex; align-items: center; gap: 5px; padding: 2px 10px; font-size: 12px; }
.grp-toggle svg { width: 15px; height: 15px; }
.grp-caret:hover { color: var(--text); }
/* The row number reads by default; the caret takes its place on hover. */
.ntable tbody tr:hover .grp-caret { opacity: 1; }
.ntable tbody tr:hover .rowidx.has-caret .rowidx-num { opacity: 0; }

/* Row-selection tick (bulk "group into step"): same swap as the group caret —
   the row number reads by default, the checkbox takes its place on hover, and
   once ticked it stays put. The tick is centred in the 36px rail, so the rail
   itself is centred too (below) — otherwise a checked row's box would drift
   left of an unchecked row's right-aligned number. */
.rowidx-check {
  /* Transform-centre, not inset:0 + margin:auto — the base
     `input[type=checkbox]{margin:0}` rule outranks a class selector and would
     cancel the auto margins, pinning the tick to the left of the rail. */
  position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);
  opacity: 0; transition: opacity .12s ease;
}
.ntable tbody tr:hover .rowidx-check,
.rowidx.checked .rowidx-check { opacity: 1; }
.ntable tbody tr:hover .rowidx.has-check .rowidx-num,
.rowidx.has-check.checked .rowidx-num { opacity: 0; }
/* Centre the whole row-number rail (number, header, checkbox) on a selectable
   table so the tick lands exactly where the number was — no left/right drift
   between checked and unchecked rows. Only selectable tables; every other
   table keeps its right-aligned numbers. */
.ntable.selectable tbody .rowidx { text-align: center; vertical-align: middle; }
.ntable.selectable thead .rowidx { text-align: center; }
/* Header select-all sits inline (not swapped), quiet at rest so it doesn't
   shout, full-strength on hover or when engaged. */
.rowidx-check.head { position: static; margin: 0; opacity: .5; }
.ntable thead .rowidx:hover .rowidx-check.head,
.rowidx-check.head:checked { opacity: 1; }
.ntable tbody tr.summary td { background: #faf9f7; font-weight: 500; }
.ntable tbody tr.summary:hover td { background: #f4f3f0; }
/* Excel-style cell selection: while dragging, kill native text selection so the
   sweep is clean; selected cells fill with a soft accent wash and a hairline
   ring (listed across row states so hover/summary can't outrank the highlight). */
.ntable.selecting { user-select: none; }
.ntable tbody td.sel,
.ntable tbody tr:hover td.sel,
.ntable tbody tr.summary td.sel,
.ntable tbody tr.summary:hover td.sel {
  background: var(--accent-soft);
  box-shadow: inset 0 0 0 1px var(--accent-ring);
}
.ntable tfoot tr.totals-row td {
  padding: 8px 10px; border-top: 2px solid var(--border);
  font-weight: 600; background: #faf9f7; position: sticky; bottom: 0;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.ntable tfoot .totals-note { font-weight: 500; color: var(--text-soft); white-space: nowrap; }
.ntable tfoot .totals-note .neg { color: var(--danger); }
.ntable .rowact { position: relative; width: 34px; }
.ntable tbody tr:hover .row-menu-btn { opacity: 1; }
.row-menu-btn {
  opacity: 0; border: 0; background: none; color: var(--text-soft);
  border-radius: 5px; padding: 2px 6px; font-size: 15px; line-height: 1;
}
.row-menu-btn:hover { background: var(--bg-hover); }
.cell-link { color: var(--text); cursor: pointer; }
.cell-link:hover { text-decoration: underline; }
.add-row {
  display: flex; align-items: center; gap: 8px;
  padding: 8px 14px; color: var(--text-faint); font-size: 14px; cursor: pointer;
  border-bottom: 1px solid var(--border);
}
.add-row:hover { background: #fbfbfa; color: var(--text-soft); }

/* tag pills */
.tag {
  display: inline-block; padding: 1px 8px; border-radius: 4px;
  font-size: 12px; line-height: 18px; font-weight: 500;
  background: var(--t-gray); color: var(--t-gray-fg);
}
.tag.gray { background: var(--t-gray); color: var(--t-gray-fg); }
.tag.brown { background: var(--t-brown); color: var(--t-brown-fg); }
.tag.orange { background: var(--t-orange); color: var(--t-orange-fg); }
.tag.yellow { background: var(--t-yellow); color: var(--t-yellow-fg); }
.tag.green { background: var(--t-green); color: var(--t-green-fg); }
.tag.blue { background: var(--t-blue); color: var(--t-blue-fg); }
.tag.purple { background: var(--t-purple); color: var(--t-purple-fg); }
.tag.pink { background: var(--t-pink); color: var(--t-pink-fg); }
.tag.red { background: var(--t-red); color: var(--t-red-fg); }

/* inline-editable cell */
.editable { cursor: text; border-radius: 4px; }
.editable:hover { box-shadow: 0 0 0 1px var(--border-strong) inset; }
.editable input {
  border: 0; outline: 0; width: 100%; background: var(--accent-soft);
  padding: 1px 2px; border-radius: 3px; font-size: 14px;
}

/* ---------------- row action menu (teleported, escapes overflow) ------ */
.rowmenu-scrim { position: fixed; inset: 0; z-index: 129; background: transparent; }
.rowmenu { position: fixed; z-index: 130; min-width: 168px; }

/* ---------------- bulk-action bar (row selection) --------------------- */
/* Floats bottom-centre when rows are ticked; sits below the modal/peek scrims
   (z-index 90/100) so opening the group dialog dims it. A quiet floating card —
   hairline outline + soft drop, same recipe as a toast. */
.bulk-bar {
  position: fixed; left: 50%; bottom: 24px; transform: translateX(-50%);
  z-index: 80; display: flex; align-items: center; gap: 10px;
  padding: 7px 8px 7px 15px;
  background: var(--bg); border: 1px solid var(--border-strong);
  border-radius: 10px; box-shadow: var(--shadow-lg);
}
.bulk-count {
  font-size: 13px; font-weight: 500; color: var(--text-soft);
  white-space: nowrap; font-variant-numeric: tabular-nums;
}
.bulk-sep { width: 1px; align-self: stretch; margin: 2px 0; background: var(--border); }
.bulk-act { display: inline-flex; align-items: center; gap: 6px; }
.bulk-ico { font-size: 13px; }
.bulk-clear {
  border: 0; background: none; color: var(--text-soft);
  font-size: 13px; font-weight: 500; padding: 5px 9px;
  border-radius: 6px; cursor: pointer;
  transition: background .12s ease, color .12s ease;
}
.bulk-clear:hover { background: var(--bg-hover); color: var(--text); }

/* ---------------- column header menu (sort + filter) ------------------ */
.col-menu {
  position: fixed; z-index: 130; width: 240px;
  background: #fff; border: 1px solid var(--border-strong);
  border-radius: 8px; box-shadow: var(--shadow); padding: 6px;
}
.col-menu .col-sep { height: 1px; background: var(--border); margin: 6px 4px; }
.col-section { display: flex; flex-direction: column; gap: 2px; }
.col-line {
  display: block; width: 100%; text-align: left; border: 0; background: none;
  padding: 6px 8px; border-radius: 6px; font-size: 13px; color: var(--text);
}
.col-line:hover { background: var(--bg-hover); }
.col-line.on { background: var(--accent-soft); color: var(--accent); font-weight: 500; }
.col-search {
  width: 100%; padding: 6px 8px; border-radius: 6px;
  border: 1px solid var(--border-strong); font-size: 13px;
}
.col-search:focus { outline: 0; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }
.col-opts { max-height: 220px; overflow-y: auto; margin-top: 6px; }
.col-opt {
  display: flex; align-items: center; gap: 8px;
  padding: 5px 6px; border-radius: 5px; font-size: 13px; cursor: pointer;
}
.col-opt:hover { background: var(--bg-hover); }
.col-opt span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.col-empty { color: var(--text-faint); font-size: 12px; padding: 8px 6px; }
.col-range { display: flex; align-items: center; gap: 8px; }
.col-range input {
  flex: 1; min-width: 0; padding: 6px 8px; border-radius: 6px;
  border: 1px solid var(--border-strong); font-size: 13px;
}
.col-range input:focus { outline: 0; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }
.col-range span { color: var(--text-faint); }
/* Date range stacks vertically with mini labels so native pickers never overflow. */
.col-mini {
  display: flex; flex-direction: column; gap: 3px;
  font-size: 11px; color: var(--text-faint); margin-bottom: 6px;
}
.col-mini input {
  width: 100%; box-sizing: border-box; padding: 6px 8px; border-radius: 6px;
  border: 1px solid var(--border-strong); font-size: 13px; color: var(--text);
}
.col-mini input:focus { outline: 0; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }
.col-foot { display: flex; gap: 8px; justify-content: flex-end; }
.col-foot .btn { padding: 4px 10px; font-size: 12px; }

/* ---------------- peek allocations table ------------------------------ */
.alloc-table { width: 100%; border-collapse: collapse; font-size: 13px; }
.alloc-table th {
  text-align: left; font-weight: 500; color: var(--text-faint); font-size: 12px;
  padding: 6px 8px; border-bottom: 1px solid var(--border);
}
.alloc-table td { padding: 6px 8px; border-bottom: 1px solid var(--border); }
/* Figures and tags never wrap; a long name wraps at word breaks. If the
   drawer is still too narrow the body scrolls sideways rather than clipping. */
.alloc-table td { overflow-wrap: break-word; }
/* A row with settlements behind it expands in place (caret, like a group). */
.alloc-table tr.alloc-expandable { cursor: pointer; }
.alloc-table tr.alloc-expandable:hover td { background: var(--bg-hover); }
.alloc-caret { display: inline-block; width: 14px; color: var(--text-faint); font-size: 11px; }
/* A name column that yields to the figures: truncated, full text on hover. */
.alloc-table td.cell-clip {
  max-width: 110px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.alloc-table td.num, .alloc-table th.num, .alloc-table td.muted, .alloc-table .tag { white-space: nowrap; }
.alloc-table td.num, .alloc-table th.num {
  text-align: right; font-family: var(--mono); font-variant-numeric: tabular-nums;
}
.alloc-table td.muted { color: var(--text-faint); }

/* ---------------- empty / loading ------------------------------------- */
.empty { text-align: center; color: var(--text-faint); padding: 64px 20px; }
.empty .big { font-size: 40px; margin-bottom: 8px; }
.empty .btn { margin-top: 14px; }
.spinner {
  width: 18px; height: 18px; border: 2px solid var(--border-strong);
  border-top-color: var(--accent); border-radius: 50%;
  animation: spin .7s linear infinite; display: inline-block;
}
@keyframes spin { to { transform: rotate(360deg); } }

/* Button busy state: text turns transparent (preserving size) and a spinner
   is overlaid via ::after, so the button never changes dimensions. Bind with
   :class="{ busy }" — no structural HTML changes needed. */
.btn.busy { position: relative; color: transparent !important; pointer-events: none; cursor: default; }
.btn.busy::after {
  content: ''; position: absolute;
  width: 13px; height: 13px;
  inset: 0; margin: auto;
  border: 2px solid rgba(255,255,255,.35); border-top-color: #fff;
  border-radius: 50%; animation: spin .7s linear infinite;
}
.btn:not(.primary).busy::after {
  border-color: var(--border-strong); border-top-color: var(--text);
}

/* Same pattern for report-tab switches */
.report-tab.busy { position: relative; color: transparent !important; pointer-events: none; cursor: default; }
.report-tab.busy::after {
  content: ''; position: absolute;
  width: 11px; height: 11px;
  inset: 0; margin: auto;
  border: 1.5px solid var(--border-strong); border-top-color: var(--text-soft);
  border-radius: 50%; animation: spin .7s linear infinite;
}

/* ---------------- modal & forms --------------------------------------- */
.overlay {
  position: fixed; inset: 0;
  /* A light frosted scrim rather than a dark wash — keeps the page visible
     and reads modern against the Notion-white theme. */
  background: rgba(248, 248, 247, .6);
  backdrop-filter: blur(3px) saturate(120%);
  -webkit-backdrop-filter: blur(3px) saturate(120%);
  display: flex; align-items: flex-start; justify-content: center;
  padding: 8vh 16px 16px; z-index: 100;
}
.modal {
  background: #fff; border-radius: 10px; box-shadow: var(--shadow-lg);
  width: 100%; max-width: 560px; max-height: 84vh;
  display: flex; flex-direction: column; overflow: hidden;
}
.modal.wide { max-width: 760px; }
/* Reports size to their widest table (set inline by ReportPanel) rather than
   scrolling inside a fixed box; this is the default + the viewport-bound cap. */
.modal.report { width: 880px; max-width: min(94vw, 1500px); }
.modal-head {
  display: flex; flex-direction: column; gap: 8px;
  padding: 16px 20px 12px; border-bottom: 1px solid var(--border);
}
/* Icon, title and close share the top row; any subtitle drops to its own
   full-width row below — so a long description can't stretch the middle column
   and pull the icon and close button out of alignment. */
.modal-head-row { display: flex; align-items: center; gap: 10px; }
.modal-head .micon { font-size: 20px; }
/* On a parameterised report, the icon doubles as a back button: the emoji
   swaps to a ← on hover so the filter form is one click away. */
.modal-head button.micon-back {
  border: 0; background: none; padding: 0; cursor: pointer; line-height: 1;
  display: inline-flex; align-items: center; justify-content: center;
  width: 24px; height: 24px; border-radius: 6px;
}
.modal-head button.micon-back .ic-back { display: none; color: var(--accent); font-size: 18px; }
.modal-head button.micon-back:hover { background: var(--bg-hover); }
.modal-head button.micon-back:hover .ic-emoji { display: none; }
.modal-head button.micon-back:hover .ic-back { display: inline; }
.modal-head h2 { font-size: 16px; margin: 0; font-weight: 600; }
.modal-head p { margin: 0; font-size: 12px; color: var(--text-soft); line-height: 1.45; }
.modal-head .close {
  margin-left: auto; border: 0; background: none; font-size: 20px;
  color: var(--text-faint); border-radius: 6px; padding: 2px 8px;
}
.modal-head .close:hover { background: var(--bg-hover); }
.modal-body { padding: 16px 20px; overflow-y: auto; }
/* Schema-driven forms lay their fields out in a two-column flex grid so the
   compact, often-optional fields (dates, codes, rates, "restrict to…" filters)
   pair up half-width instead of each eating a full row. Reports and the members
   panel reuse the plain .modal-body for block content, so the grid is opt-in via
   .form-grid. Per-field margin-bottom (not row-gap) keeps the vertical rhythm so
   wrapped rows stay 14px apart whether they hold one full field or two halves. */
.modal-body.form-grid {
  display: flex; flex-wrap: wrap; align-items: flex-start; column-gap: 14px;
}
.form-grid .field { width: 100%; }
.form-grid .field.half { width: calc(50% - 7px); }
@media (max-width: 480px) { .form-grid .field.half { width: 100%; } }
.modal-foot {
  display: flex; align-items: center; gap: 10px; justify-content: flex-end;
  padding: 12px 20px; border-top: 1px solid var(--border); background: #fafafa;
}

/* Per-party report quick-switch tabs: a horizontally scrollable strip pinned
   under the header, so reconciling one party then the next is a click. The
   tabs follow the app's selection language — borderless, a soft gray hover, and
   the accent-soft "on" treatment used by the column-filter options (.col-line.on)
   — rather than loud solid-fill buttons or capsule pills. */
.report-tabs {
  display: flex; gap: 2px; align-items: center;
  padding: 7px 14px; border-bottom: 1px solid var(--border);
  overflow-x: auto; overflow-y: hidden; white-space: nowrap;
  scrollbar-width: thin;
}
.report-tab {
  flex: 0 0 auto; border: 0; background: none;
  color: var(--text-soft); border-radius: 6px; padding: 5px 10px;
  font-size: 13px; line-height: 1.4; cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center;
  min-height: 28px;
}
.report-tab:hover { background: var(--bg-hover); color: var(--text); }
.report-tab.active, .report-tab.active:hover {
  background: var(--accent-soft); color: var(--accent); font-weight: 500;
}
.report-tab:disabled { cursor: default; }

/* Sticky-header gotcha (reports only): the report modal scrolls its cards and
   tables together inside .modal-body, whose 16px top padding sits *inside* the
   scrollport. A position:sticky table header (.ntable thead th, top:0) pins
   below that padding — not at the scroll clip edge — leaving a 16px band above
   it where rows show through as they scroll past, so the header reads as
   floating over the rows instead of anchoring to the top. Zero the body's top
   padding (only reports pin a header in here; forms and the plain table's own
   unpadded .scroll don't) and move that 16px onto the first child, which scrolls
   away with the content instead of clipping above the pinned header. */
.modal.report .modal-body { padding-top: 0; }
.modal.report .modal-body > :first-child { margin-top: 16px; }

/* ---- ReportTable: read-only ntable with local sort/filter/search ---- */
/* A report that could only translate some books says so above its figures —
   the same soft yellow wash the investor portal uses for the same message. */
.report-notice {
  background: var(--t-yellow); color: var(--t-yellow-fg); border-radius: 8px;
  padding: 10px 14px; margin: 16px 0 4px; font-size: 13px; line-height: 1.45;
}
.report-notice strong { font-weight: 600; }

/* A wide report (cash statement: ten columns) scrolls sideways inside the
   modal rather than clipping its last columns at the modal's edge. */
.rtable-wrap { margin-top: 16px; overflow-x: auto; }
.rtable-wrap:first-child { margin-top: 0; }
.rtable-head {
  display: flex; align-items: center; gap: 8px;
  min-height: 24px; margin-bottom: 5px;
}
.rtable-title {
  margin: 0; color: var(--text-faint);
  text-transform: uppercase; font-size: 12px; letter-spacing: .05em;
  flex: 0 0 auto;
}
.rtable-controls { display: flex; align-items: center; gap: 6px; margin-left: auto; }
.rtable-search {
  height: 26px; padding: 0 8px; font-size: 12px;
  border: 1px solid var(--border); border-radius: 6px;
  background: var(--bg); color: var(--text); width: 150px; outline: none;
}
.rtable-search:focus {
  border-color: var(--accent); box-shadow: 0 0 0 2px var(--accent-soft);
}
.rtable-count { font-size: 12px; color: var(--text-soft); white-space: nowrap; }
.rtable-total { color: var(--text-faint); }
.rtable-clear { font-size: 11px; padding: 2px 7px; height: 22px; }
/* A report's view-toggle (e.g. Party Balances' "Toggle grouping") sits in the
   table header controls, just left of the export button. Styled to match the
   Intent Log's "Show voided" toolbar label exactly — faint 12px text, a 6px gap
   to the global accent-fill checkbox — so the two read as the same control. */
.rtable-toggle {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 12px; color: var(--text-faint); cursor: pointer;
  user-select: none; white-space: nowrap; flex-shrink: 0;
}
.rtable-toggle:hover { color: var(--text-soft); }
.rtable-toggle.busy { opacity: .6; pointer-events: none; }
.rtable-empty { padding: 20px 0; color: var(--text-faint); font-size: 13px; }
/* Inside a report modal the table bottom margin is handled by .rtable-wrap spacing. */
.ntable.rtable { margin-bottom: 0; }
.rtable-sel-status {
  font-size: 12px; color: var(--text-soft); text-align: right;
  padding: 4px 6px; font-variant-numeric: tabular-nums; font-family: var(--mono);
}
.rtable-sel-sum { color: var(--text); }
.rtable-sel-count { color: var(--text-faint); margin-left: 4px; }

.field { margin-bottom: 14px; }
.field > label {
  display: block; font-size: 13px; font-weight: 500; margin-bottom: 5px;
  color: var(--text);
}
/* A quiet inline action tucked to the right of a field label (e.g. "+ New
   group"): a ghost button that reads as a soft link, not a boxed control. */
.field > label:has(.field-link) { display: flex; align-items: center; }
.field > label .field-link {
  margin-left: auto; font-size: 12px; font-weight: 500; padding: 1px 6px;
  color: var(--accent); border: 0;
}
.field > label .field-link:hover { background: var(--accent-soft); }
.field .req { color: var(--danger); margin-left: 2px; }
.field .help { font-size: 12px; color: var(--text-faint); margin-top: 4px; }
.field input[type=text], .field input[type=number], .field input[type=date],
.field input[type=email], .field input[type=password],
.field select, .field textarea {
  width: 100%; padding: 7px 10px; border-radius: 7px;
  border: 1px solid var(--border-strong); background: #fff; color: var(--text);
}
/* Inputs, selects and date pickers share one height so a half-field pair lines
   up exactly; box-sizing keeps the border inside that height. Checkboxes and the
   journal line editor opt out — they're matched more specifically elsewhere. */
.field > input[type=text], .field > input[type=number], .field > input[type=date],
.field > input[type=email], .field > input[type=password], .field > select {
  height: 36px;
}
/* The native select chevron differs per-OS and renders a hair taller than a text
   input; swap in our own so selects are visually identical to the inputs beside
   them. background-position leaves room for the 12px glyph + the 30px pad-right. */
.field > select {
  appearance: none; -webkit-appearance: none; -moz-appearance: none;
  padding-right: 30px; background-repeat: no-repeat;
  background-position: right 11px center; background-size: 12px;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12' fill='none' stroke='%23667085' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'><path d='M2.5 4.5 6 8l3.5-3.5'/></svg>");
}
.field input:focus, .field select:focus, .field textarea:focus {
  outline: 0; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft);
}
.field textarea { min-height: 60px; resize: vertical; }
/* Numeric inputs read like a money cell: mono, tabular, right-aligned so the
   figures line up with the tables and reports they feed. */
.num-input {
  font-family: var(--mono); font-variant-numeric: tabular-nums;
  text-align: right;
}
/* Smart date field (DateField): a normal text box — type or paste any common
   format, normalised to YYYY-MM-DD on blur/Enter — with a calendar button that
   opens the OS picker. Reads exactly like the sibling inputs (7px radius, strong
   hairline, accent focus ring); the icon sits in reserved right padding and the
   native <input type=date> is an invisible anchor for showPicker(). Selectors
   carry the input class so they out-rank the generic `.field input[type=text]`
   padding. */
.datefield { position: relative; display: block; }
.datefield input.datefield-text {
  width: 100%; height: 36px; padding: 7px 34px 7px 10px;
  border: 1px solid var(--border-strong); border-radius: 7px;
  background: #fff; color: var(--text); font: inherit;
}
.datefield input.datefield-text:focus {
  outline: 0; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft);
}
.datefield.disabled { opacity: .55; }
.datefield .datefield-cal {
  position: absolute; top: 50%; right: 5px; transform: translateY(-50%);
  display: inline-flex; align-items: center; justify-content: center;
  width: 26px; height: 26px; padding: 0; border: 0; border-radius: 6px;
  background: none; color: var(--text-faint); cursor: pointer;
  font-size: 13px; line-height: 1;
  transition: background .12s ease;
}
.datefield .datefield-cal:hover { background: var(--bg-hover); }
.datefield .datefield-cal:disabled { cursor: default; opacity: .4; }
.datefield input.datefield-native {
  position: absolute; top: 0; right: 4px; width: 28px; height: 100%;
  opacity: 0; padding: 0; border: 0; background: none; pointer-events: none;
}
.field.check { display: flex; align-items: center; gap: 8px; }
.field.check input { width: 16px; height: 16px; }
/* Multi-party picker (type: parties): the dropdown adds a chip per pick. Chips
   are a soft selected-state — gray fill + text, 6px radius — not a loud pill. */
.field .chips { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
.field .chip {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 2px 4px 2px 8px; border-radius: 6px;
  background: var(--bg-active); color: var(--text);
  font-size: 12px; line-height: 18px;
}
.field .chip-rm {
  border: 0; background: none; cursor: pointer; color: var(--text-faint);
  font-size: 14px; line-height: 1; padding: 0 2px;
}
.field .chip-rm:hover { color: var(--danger); }
.field.check label { margin: 0; }
.field-row { display: flex; gap: 14px; }
.field-row .field { flex: 1; }

/* Collapsible form sections — a hairline-separated toggle row that shows/hides
   the fields beneath it. No background highlight on its own; hover just
   darkens the text so it reads as interactive without adding visual weight. */
.form-section { width: 100%; margin-bottom: 6px; margin-top: 2px; }
.form-section-toggle {
  display: flex; align-items: center; gap: 6px; width: 100%;
  padding: 5px 0; border: 0; background: none; cursor: pointer;
  color: var(--text-soft); font-size: 13px; font-weight: 500;
  text-align: left; border-top: 1px solid var(--border);
}
.form-section-toggle:hover { color: var(--text); }
.form-section-toggle .sec-chevron {
  width: 12px; height: 12px; flex-shrink: 0;
  transition: transform 0.1s;
}
.form-section-toggle.open .sec-chevron { transform: rotate(90deg); }

/* journal voucher line editor — a compact, Excel-like grid: flush square cells
   that share 1px grid lines, no per-cell radius or gaps, each control filling
   its cell edge-to-edge. The column widths line up across every row. */
.jv-lines { border: 1px solid var(--border-strong); border-radius: 8px; overflow: hidden; }
.jv-line {
  display: grid; grid-template-columns: 96px 1fr 116px 136px 30px;
  align-items: stretch; border-bottom: 1px solid var(--border);
}
/* Controls fill their cell with no border/radius of their own; the only rules
   are the shared 1px separators between cells (border-left on all but the first). */
.jv-line > select, .jv-line > input {
  height: 34px; width: 100%; border: 0; border-radius: 0; box-shadow: none;
  padding: 6px 8px; font-size: 13px; background-color: #fff; color: var(--text);
}
.jv-line > * + * { border-left: 1px solid var(--border); }
.jv-line .amt { text-align: right; font-variant-numeric: tabular-nums; font-family: var(--mono); }
/* Selects reuse the consistent chevron, sized down to sit flush in the cell. */
.jv-line > select {
  appearance: none; -webkit-appearance: none; -moz-appearance: none;
  padding-right: 22px; background-repeat: no-repeat;
  background-position: right 7px center; background-size: 11px;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12' fill='none' stroke='%23667085' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'><path d='M2.5 4.5 6 8l3.5-3.5'/></svg>");
}
/* Inset focus ring so a focused cell highlights without a halo breaking the grid. */
.jv-line > select:focus, .jv-line > input:focus {
  outline: 0; box-shadow: inset 0 0 0 2px var(--accent-soft);
}
.jv-line .rm {
  border: 0; background: none; color: var(--text-faint); font-size: 16px;
  cursor: pointer; display: flex; align-items: center; justify-content: center;
}
.jv-line .rm:hover { color: var(--danger); }
.jv-add { padding: 8px; color: var(--accent); font-size: 13px; cursor: pointer; }
.jv-add:hover { background: var(--accent-soft); }
.jv-balance { font-size: 12px; padding: 6px 8px; font-family: var(--mono); border-top: 1px solid var(--border); }
.jv-balance.empty { color: var(--text-faint); }
.jv-balance.ok { color: var(--t-green-fg); }
.jv-balance.bad { color: var(--danger); }

/* ---------------- record peek (open as page) -------------------------- */
.peek-overlay { position: fixed; inset: 0; z-index: 90; display: flex; justify-content: flex-end; }
.peek-overlay .scrim {
  position: absolute; inset: 0; background: rgba(248, 248, 247, .4);
  backdrop-filter: blur(2px); -webkit-backdrop-filter: blur(2px);
}
.peek {
  position: relative; width: 520px; min-width: 360px; max-width: 96vw;
  background: #fff; border-left: 1px solid var(--border);
  box-shadow: var(--shadow-lg); display: flex; flex-direction: column;
}
.peek.resizing { user-select: none; }
/* Drag handle on the drawer's left edge. A faint hairline that lifts to the
   accent on hover, with a minimal centred grip pill as the affordance. */
.peek-resize {
  position: absolute; top: 0; left: 0; height: 100%; width: 11px;
  margin-left: -6px; cursor: col-resize; z-index: 3;
  display: flex; align-items: center; justify-content: center;
}
.peek-resize::before {
  content: ""; position: absolute; left: 6px; top: 0; width: 1px; height: 100%;
  background: transparent; transition: background .12s ease, width .12s ease;
}
.peek-resize:hover::before, .peek-resize.dragging::before {
  background: var(--accent); width: 2px; left: 5px;
}
.peek-resize .grip {
  position: relative; width: 4px; height: 30px; border-radius: 4px;
  background: var(--border-strong); transition: background .12s ease, height .12s ease;
}
.peek-resize:hover .grip, .peek-resize.dragging .grip { background: var(--accent); height: 40px; }
.peek-head { padding: 18px 24px 12px; border-bottom: 1px solid var(--border); display: flex; align-items: center; gap: 10px; }
.peek-head h2 { font-size: 17px; margin: 0; }
.peek-head .close { margin-left: auto; border: 0; background: none; font-size: 20px; color: var(--text-faint); padding: 2px 8px; border-radius: 6px; }
.peek-head .close:hover { background: var(--bg-hover); }
.peek-body { padding: 18px 24px; overflow-y: auto; overflow-x: auto; }
/* Same sticky-header gotcha as .modal.report .modal-body above: the drawer
   scrolls its embedded ReportTable (.ntable) inside .peek-body, whose 18px top
   padding would leave a band above the pinned header for rows to show through.
   Drop the top padding and move it onto the first child so the header anchors
   flush with the scroll edge. */
.peek-body { padding-top: 0; }
.peek-body > :first-child { margin-top: 18px; }
.prop { display: flex; gap: 12px; padding: 6px 0; }
.prop .k { width: 150px; flex-shrink: 0; color: var(--text-soft); font-size: 13px; display: flex; align-items: center; gap: 6px; }
.prop .v { color: var(--text); font-size: 14px; }
.peek h3 { font-size: 12px; text-transform: uppercase; letter-spacing: .05em; color: var(--text-faint); margin: 22px 0 8px; }
.kv { background: var(--bg-sidebar); border-radius: 8px; padding: 4px 12px; }
.codeblock { background: #f7f7f5; border: 1px solid var(--border); border-radius: 8px; padding: 12px; font-family: var(--mono); font-size: 12px; white-space: pre-wrap; color: var(--text-soft); }

/* Commitment status bar: paid | called-unpaid | uncalled, out of committed. */
.commit-bar { display: flex; height: 14px; border-radius: 7px; overflow: hidden;
  background: var(--border); }
.commit-bar .seg { height: 100%; }
.commit-bar .seg.paid { background: #3a9b5c; }
.commit-bar .seg.due { background: #d9a23b; }
.commit-bar .seg.uncalled { background: #c2c0bb; }
.commit-legend { display: flex; gap: 14px; margin-top: 6px; font-size: 12px;
  color: var(--text-soft); }
.commit-legend i.dot { display: inline-block; width: 9px; height: 9px;
  border-radius: 2px; margin-right: 5px; vertical-align: baseline; }
.commit-legend i.dot.paid { background: #3a9b5c; }
.commit-legend i.dot.due { background: #d9a23b; }
.commit-legend i.dot.uncalled { background: #c2c0bb; }

/* report tables reuse ntable; summary cards — the hairline Card recipe, kept
   compact: smaller value, tighter padding, denser grid so a party's summary
   reads as a quiet stat strip rather than a wall of big boxes. */
.cards { display: grid; grid-template-columns: repeat(auto-fill, minmax(130px, 1fr)); gap: 8px; margin-bottom: 14px; }
.card { border: 1px solid var(--border); border-radius: 10px; padding: 8px 11px; }
.card .label { font-size: 12px; color: var(--text-soft); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.card .value { font-size: 16px; font-weight: 600; margin-top: 2px; font-variant-numeric: tabular-nums; overflow-wrap: break-word; }
.card .value.neg { color: var(--danger); }
/* party/project is free-text identity, not a stat — squeezed into a single
   130px column a long one wraps across many lines and blows the row tall.
   Give it the full row instead: it always leads (report-panel.js sorts it
   first), so the rest of the cards flow into a clean row 2 underneath. */
.card.wide { grid-column: 1 / -1; }
.report-group-title { margin: 14px 0 6px; color: var(--text-faint);
  text-transform: uppercase; font-size: 11px; letter-spacing: .05em; font-weight: 600; }

/* ---------------- toasts ---------------------------------------------- */
.toasts { position: fixed; bottom: 18px; right: 18px; z-index: 200; display: flex; flex-direction: column; gap: 8px; }
/* Quiet, hairline card. Type is signalled by a small soft-wash icon badge
   (the tag-pill recipe: pastel bg + darker same-hue glyph) — never a loud
   solid bar. */
.toast {
  display: flex; gap: 9px; align-items: flex-start;
  background: var(--bg); border: 1px solid var(--border-strong);
  border-radius: 7px; box-shadow: var(--shadow); padding: 10px 13px;
  min-width: 260px; max-width: 380px; font-size: 13px;
  animation: slidein .18s ease; cursor: default;
}
.toast .t-icon {
  flex: none; margin-top: 1px; width: 17px; height: 17px; border-radius: 5px;
  display: grid; place-items: center; font-size: 11px; font-weight: 600;
  line-height: 1; background: var(--accent-soft); color: var(--accent);
}
.toast.success .t-icon { background: var(--t-green); color: var(--t-green-fg); }
.toast.error .t-icon { background: var(--t-red); color: var(--t-red-fg); }
.toast .t-body { min-width: 0; flex: 1; }
.toast .t-title { font-weight: 600; margin-bottom: 1px; }
.toast .t-msg { color: var(--text-soft); }
/* Quiet dismiss icon — a borderless icon button, like every other one in the app. */
.toast .t-close {
  flex: none; margin: -2px -4px 0 4px; padding: 0; border: 0; background: none;
  width: 20px; height: 20px; border-radius: 6px; display: grid; place-items: center;
  color: var(--text-faint); font-size: 12px; line-height: 1; cursor: pointer;
  transition: background .12s ease, color .12s ease;
}
.toast .t-close:hover { background: var(--bg-hover); color: var(--text); }
@keyframes slidein { from { transform: translateX(20px); opacity: 0; } }

/* ---------------- sign-in page ---------------------------------------- */
.auth-body {
  /* A soft Notion-paper backdrop with a barely-there radial lift behind
     the card, so the white card reads as gently elevated. */
  min-height: 100vh; display: grid; place-items: center;
  padding: 24px; background:
    radial-gradient(1100px 600px at 50% -10%, var(--accent-wash) 0%, transparent 60%),
    var(--bg-sidebar);
}
.auth { width: 100%; max-width: 380px; }
.auth-card {
  background: #fff; border: 1px solid var(--border);
  border-radius: 14px; box-shadow: var(--shadow-lg);
  padding: 30px 28px 26px;
}
.auth-brand { text-align: center; margin-bottom: 20px; }
/* Fit the logo inside a 64px box without forcing a square: a wordmark or any
   non-square logo keeps its aspect ratio (contained, not stretched). */
.auth-logo {
  display: block; width: auto; height: auto; max-width: 100%; max-height: 64px;
  margin: 0 auto 12px; object-fit: contain;
}
.auth-brand h1 { font-size: 20px; font-weight: 700; margin: 0 0 4px; letter-spacing: -.01em; }
.auth-brand p { font-size: 13px; color: var(--text-soft); margin: 0; }
.auth-card .field { margin-bottom: 14px; }
.auth-card .field input {
  width: 100%; box-sizing: border-box; padding: 9px 11px; border-radius: 8px;
  border: 1px solid var(--border-strong); background: #fff; color: var(--text);
}
.auth-card .field input:focus {
  outline: 0; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft);
}
.auth-submit { width: 100%; justify-content: center; padding: 9px; margin-top: 4px; font-size: 14px; }
.auth-error {
  background: var(--t-red); color: var(--t-red-fg);
  border-radius: 8px; padding: 9px 12px; font-size: 13px; margin-bottom: 16px;
}
.auth-foot { text-align: center; color: var(--text-faint); font-size: 12px; margin: 16px 0 0; }
.auth-foot a { color: var(--accent); text-decoration: none; }
.auth-foot a:hover { text-decoration: underline; }
/* Two-factor challenge step: a short lead line and a roomy, spaced-out code box
   so the six digits are easy to read back while typing. */
.auth-2fa-lead { font-size: 13px; color: var(--text-soft); margin: 0 0 16px; text-align: center; }
.auth-card .field input.auth-otp-input {
  text-align: center; font-family: var(--mono); font-size: 20px;
  letter-spacing: .18em; padding: 12px 11px;
}

/* ---------------- public investor-access guide (/investors) ------------ */
/* The shareable "how to access your portal" page. It is the sign-in page's
   sibling — same paper backdrop, same card, same brand block — just wider and
   top-aligned, since it reads as a short document rather than a form. */
.auth-foot-link { margin-top: 6px; }
.guide-body { place-items: start center; padding-top: 48px; }
.guide { width: 100%; max-width: 600px; }
.guide-card { padding: 30px 32px 28px; }
.guide-lead { font-size: 14px; line-height: 1.55; color: var(--text-soft); margin: 0 0 6px; text-align: center; }
/* The app's uppercase section-label recipe (sidebar / report group titles). */
.guide-label {
  font-size: 11px; font-weight: 500; text-transform: uppercase; letter-spacing: .05em;
  color: var(--text-faint); margin: 22px 0 8px;
}
.guide-steps { list-style: none; margin: 0; padding: 0; }
.guide-steps li {
  display: flex; gap: 12px; padding: 10px 0; border-bottom: 1px solid var(--border);
}
.guide-steps li:last-child { border-bottom: 0; }
/* Step number: the soft accent wash (a "this one" marker), never solid blue. */
.guide-num {
  flex: none; width: 22px; height: 22px; border-radius: 6px; display: grid; place-items: center;
  background: var(--accent-soft); color: var(--accent);
  font: 600 12px/1 var(--mono); font-variant-numeric: tabular-nums;
}
.guide-step-title { font-weight: 600; font-size: 14px; margin: 1px 0 2px; }
.guide-step-body { font-size: 13px; line-height: 1.5; color: var(--text-soft); }
.guide-step-body b { color: var(--text); font-weight: 500; }
.guide-card a:not(.btn) { color: var(--accent); text-decoration: none; }
.guide-card a:not(.btn):hover { text-decoration: underline; }
.guide-step-body + .share-link { margin-top: 8px; }
.guide-sections { display: grid; grid-template-columns: 1fr 1fr; gap: 2px 14px; }
.guide-section { display: flex; gap: 9px; padding: 7px 0; font-size: 13px; }
.guide-section .icon { flex: none; width: 18px; text-align: center; }
.guide-section b { display: block; font-weight: 500; }
.guide-section span:not(.icon) { color: var(--text-soft); line-height: 1.45; }
.guide-cta { display: flex; margin-top: 20px; text-decoration: none; }
.guide-faq { margin: 0; font-size: 13px; }
.guide-faq dt { font-weight: 500; margin-top: 10px; }
.guide-faq dt:first-child { margin-top: 0; }
.guide-faq dd { margin: 2px 0 0; color: var(--text-soft); line-height: 1.5; }
.guide-faq b { color: var(--text); font-weight: 500; }
@media (max-width: 560px) {
  .guide-body { padding: 16px; }
  .guide-card { padding: 24px 18px 22px; }
  .guide-sections { grid-template-columns: 1fr; }
}

/* ---------------- guided tour (first-login walkthrough) ---------------- */
/* One spotlight + one card. The spotlight is a hairline accent ring whose huge
   spread paints the same light scrim the modal overlay uses — the page stays
   visible, only quieter; never a dark wash. The card is the popup recipe:
   white, --border-strong hairline, --shadow-lg, 10px radius. */
.tour { position: fixed; inset: 0; z-index: 400; pointer-events: none; }
.tour-shield { position: fixed; inset: 0; pointer-events: auto; }
.tour-shield.dim {
  background: rgba(248, 248, 247, .6);
  backdrop-filter: blur(3px) saturate(120%); -webkit-backdrop-filter: blur(3px) saturate(120%);
}
.tour-spot {
  position: fixed; border-radius: 8px; pointer-events: none;
  box-shadow: 0 0 0 2px var(--accent-ring), 0 0 0 100vmax rgba(248, 248, 247, .72);
  transition: top .12s ease, left .12s ease, width .12s ease, height .12s ease;
}
.tour-card {
  position: fixed; pointer-events: auto; background: var(--bg);
  border: 1px solid var(--border-strong); border-radius: 10px; box-shadow: var(--shadow-lg);
  padding: 14px 16px 12px; font-size: 13px;
  transition: top .12s ease, left .12s ease;
}
.tour-meta {
  display: flex; align-items: center; font-size: 11px; font-weight: 500;
  text-transform: uppercase; letter-spacing: .05em; color: var(--text-faint);
}
.tour-count { margin-left: auto; font-family: var(--mono); font-variant-numeric: tabular-nums; letter-spacing: 0; }
.tour-title { font-size: 14px; font-weight: 600; margin: 6px 0 4px; color: var(--text); }
.tour-body { color: var(--text-soft); line-height: 1.5; }
.tour-body b { color: var(--text); font-weight: 500; }
.tour-body p { margin: 0 0 6px; }
.tour-body ul { margin: 4px 0 0; padding-left: 18px; }
.tour-body li { margin: 2px 0; }
/* A hairline progress rule: the filled part is the accent wash's text colour
   at low weight — quiet, reads as "how far along", not as a control. */
.tour-progress { height: 2px; background: var(--border); border-radius: 2px; margin: 12px 0 10px; overflow: hidden; }
.tour-progress span { display: block; height: 100%; background: var(--accent-ring); transition: width .12s ease; }
.tour-foot { display: flex; align-items: center; gap: 6px; }
.tour-foot .spacer { flex: 1; }
.tour-skip { margin-left: -8px; }
/* Keyboard focus lands on "Next" each step; ring it the app's way, not the UA's. */
.tour-card .btn:focus-visible { outline: 0; box-shadow: 0 0 0 3px var(--accent-soft); }

/* ---------------- account (user) menu in the menu bar ----------------- */
.menubar .user-menu > button {
  display: flex; align-items: center; gap: 7px; padding-left: 6px; padding-right: 8px;
}
.avatar {
  display: inline-grid; place-content: center; width: 22px; height: 22px;
  border-radius: 50%; background: var(--accent); color: #fff;
  font-size: 11px; font-weight: 600; line-height: 1; text-transform: uppercase;
}
.menu-userhead {
  display: flex; align-items: center; gap: 10px; padding: 8px 10px 10px;
}
.menu-userhead .avatar { width: 32px; height: 32px; font-size: 13px; }
.menu-userhead .who { min-width: 0; }
.menu-userhead .who .nm { font-weight: 600; font-size: 13px; line-height: 1.3;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.menu-userhead .who .em { color: var(--text-faint); font-size: 12px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* Workspace-members panel (account menu → Workspace members) */
.add-member {
  /* minmax(0, 1fr): let a column shrink below its content so the doc-upload
     file field clips a long name instead of overflowing the grid. */
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 10px 14px;
  padding: 14px; border: 1px solid var(--border-strong); border-radius: 8px;
  background: var(--bg-sidebar);
}
.add-member .add-foot {
  grid-column: 1 / -1; display: flex; align-items: center;
  justify-content: flex-end; gap: 10px;
}
.members-table td { vertical-align: middle; }
/* A settings table held to the page column: long names and long dropdown
   labels truncate (full text on hover) instead of widening the table past it. */
.ntable.fit-table { min-width: 0; table-layout: fixed; }
.ntable.fit-table td:not(.num) { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ntable.fit-table select, .ntable.fit-table input { width: 100%; min-width: 0; text-overflow: ellipsis; }
/* The inline role picker uses the shared `.flush-inputs` table treatment. */
.ntable tr.inactive { opacity: .5; }
.ntable .muted { color: var(--text-faint); font-size: 12px; }
.btn.danger, .btn.ghost.danger { color: var(--danger); }
.btn.ghost.danger:hover { background: var(--t-red); color: var(--t-red-fg); }

/* ---------------- branding page --------------------------------------- */
/* minmax(0, 1fr) — not plain 1fr — so a column can shrink below its content's
   intrinsic width. A file field with a long name would otherwise force its
   track wider than half and overflow the grid instead of clipping. */
.brand-cols { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 0 14px; }
.brand-color { display: flex; align-items: center; gap: 8px; }
.brand-color input[type=color] {
  width: 38px; height: 30px; padding: 0; flex-shrink: 0; cursor: pointer;
  border: 1px solid var(--border-strong); border-radius: 6px; background: #fff;
}
.brand-color input[type=text] { flex: 1; min-width: 0; }
.brand-file { display: flex; align-items: center; gap: 10px; }
.brand-file img {
  width: 36px; height: 36px; border-radius: 6px; object-fit: contain; flex-shrink: 0;
  border: 1px solid var(--border); background: var(--bg-sidebar);
}
.brand-file input[type=file] { font-size: 12px; color: var(--text-soft); min-width: 0; }
.brand-domains { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 2px; }
.brand-domain {
  font-family: var(--mono); font-size: 12px; color: var(--text-soft);
  background: var(--bg-active); border: 1px solid var(--border);
  border-radius: 6px; padding: 3px 8px;
}

/* Contact number: one input-shaped control holding the ISD code picker and the
   national number. Same segmented recipe as .filefield below — the two halves
   share a border, radius and focus ring, split by a hairline — so the phone
   reads as one field beside its neighbours rather than two boxed controls. */
.phonefield {
  display: flex; align-items: stretch; width: 100%; min-width: 0; height: 36px;
  border: 1px solid var(--border-strong); border-radius: 7px;
  background: var(--bg); overflow: hidden;
  transition: border-color .12s ease, box-shadow .12s ease;
}
.phonefield:focus-within {
  border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft);
}
/* The segments own no border/radius of their own — the wrapper is the control.
   `!important`-free: `.field .phonefield select` out-specifies `.field select`. */
.field .phonefield .pf-code, .field .phonefield .pf-num {
  height: 100%; border: 0; border-radius: 0; background: transparent;
  padding: 0 10px; font-size: 13px; color: var(--text);
}
.field .phonefield .pf-code:focus, .field .phonefield .pf-num:focus {
  outline: 0; box-shadow: none;
}
.field .phonefield .pf-code {
  flex: 0 0 auto; width: 152px; color: var(--text-soft);
  border-right: 1px solid var(--border-strong);
  appearance: none; -webkit-appearance: none; -moz-appearance: none;
  padding-right: 24px; background-repeat: no-repeat;
  background-position: right 8px center; background-size: 12px;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12' fill='none' stroke='%23667085' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'><path d='M2.5 4.5 6 8l3.5-3.5'/></svg>");
}
.field .phonefield .pf-code:hover { background-color: var(--bg-hover); }
/* The number is the content, so it gets the full text colour and the mono
   tabular treatment every other figure in the app uses. */
.field .phonefield .pf-num {
  flex: 1; min-width: 0; font-family: var(--mono);
  font-variant-numeric: tabular-nums; font-size: 13px;
}

/* Themed file picker (replaces the native input): the whole control reads like
   a regular bordered input — same border, radius and focus ring — with the
   trigger as a segmented button on the left, split from the filename by a
   hairline divider. Full width so it lines up with the other inputs in a form. */
.filefield {
  display: flex; align-items: stretch; width: 100%; min-width: 0;
  border: 1px solid var(--border-strong); border-radius: 7px;
  background: var(--bg); overflow: hidden;
  transition: border-color .12s ease, box-shadow .12s ease;
}
.filefield:focus-within { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }
.filefield.disabled { opacity: .55; }
.filefield .ff-btn {
  flex-shrink: 0; display: inline-flex; align-items: center; gap: 6px;
  border: 0; border-right: 1px solid var(--border-strong); border-radius: 0;
  background: transparent; color: var(--text-soft);
  padding: 7px 11px; font-size: 13px; font-weight: 500; cursor: pointer;
}
.filefield .ff-btn:hover { background: var(--bg-hover); color: var(--text); }
.filefield.disabled .ff-btn { cursor: default; }
.filefield .ff-ico { color: var(--text-faint); font-size: 12px; }
/* The filename must clip, not push the control wider than its box. It's a plain
   block (not a flex container): `text-overflow: ellipsis` only applies to a block
   with inline content, so a `display: flex` here would silently disable the
   ellipsis and hard-cut the name. `align-self: center` keeps the single line
   vertically centred in the stretched row. */
.filefield .ff-name {
  flex: 1; min-width: 0; align-self: center; display: block; padding: 0 10px;
  font-size: 13px; color: var(--text); overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap;
}
.filefield .ff-name.ff-empty { color: var(--text-faint); }

/* Flush table inputs (opt-in via `.flush-inputs` on the .ntable). A cell whose
   control is a text field or select — not a checkbox — holds it edge-to-edge,
   like an Excel cell: the table's hairline borders are the only grid lines, rows
   stay tight, and the active cell lights up with an inset accent ring on focus.
   Text-only cells in the same table are untouched, so it also fits a mixed table
   (e.g. the members roster's role picker). The compound `.ntable.flush-inputs`
   prefix out-specifies the base `.ntable tbody td` padding (7px 10px), which
   would otherwise keep the cell padded and float the ring inside it. */
.ntable.flush-inputs tbody td:has(> input:not([type=checkbox])),
.ntable.flush-inputs tbody td:has(> select) { padding: 0; vertical-align: middle; }
.ntable.flush-inputs tbody td:has(> input:not([type=checkbox])):focus-within,
.ntable.flush-inputs tbody td:has(> select):focus-within {
  background-color: #fff; box-shadow: inset 0 0 0 2px var(--accent);
  position: relative; z-index: 1;
}
.ntable.flush-inputs tbody td:hover:not(:focus-within):has(> input:not([type=checkbox])),
.ntable.flush-inputs tbody td:hover:not(:focus-within):has(> select) {
  background-color: var(--bg-hover);
}
.ntable.flush-inputs tbody td > input:not([type=checkbox]),
.ntable.flush-inputs tbody td > select {
  width: 100%; height: 28px; min-width: 56px; box-sizing: border-box; display: block;
  padding: 0 8px; font-size: 13px; font-family: inherit;
  color: var(--text); border: 0; border-radius: 0; background: transparent;
  appearance: none;
}
.ntable.flush-inputs tbody td > input:focus,
.ntable.flush-inputs tbody td > select:focus { outline: 0; }
.ntable.flush-inputs tbody td > select {
  padding-right: 18px;
  background-image: linear-gradient(45deg, transparent 50%, var(--text-faint) 50%),
    linear-gradient(135deg, var(--text-faint) 50%, transparent 50%);
  background-position: right 9px center, right 5px center;
  background-size: 4px 4px, 4px 4px; background-repeat: no-repeat;
}
/* Keep the native date control from inflating the fixed row height. */
.ntable.flush-inputs tbody td > input[type=date] { padding-right: 4px; }
.ntable.flush-inputs tbody td > input[type=date]::-webkit-calendar-picker-indicator { margin: 0; padding: 0; }
.ntable.flush-inputs tbody td > input.num-in { text-align: right; font-family: var(--mono); }

/* Deal instruments grid: flush inputs + a compact trailing remove-button cell. */
.ntable.deal-instruments tbody td:last-child { padding: 2px 4px; text-align: center; width: 34px; }
.deal-instruments td:last-child .btn { padding: 2px 7px; }

/* ---------------- account security form ------------------------------- */
/* Two stacked sections (Password, Two-factor), each led by a .report-group-title
   — the same section language as the deal/investor pages, so everything lines up
   with the field column. The 2FA-specific blocks (QR frame, manual key,
   recovery-code grid, status line) are quiet, hairline, token-coloured. */
.sec-section .report-group-title { margin-top: 0; }
.sec-section + .sec-section { margin-top: 28px; }
.sec-actions {
  display: flex; align-items: center; justify-content: flex-end; gap: 10px;
  margin-top: 16px;
}
/* Inline management actions (regenerate / turn off) sit at the left, not as a
   form submit on the right. */
.sec-actions.sec-actions-start { justify-content: flex-start; }
.sec-lead { font-size: 13px; color: var(--text-soft); line-height: 1.5; margin: 0 0 14px; }
.sec-meta { font-size: 13px; color: var(--text-soft); margin: 0 0 12px; }
.sec-ok {
  background: var(--t-green); color: var(--t-green-fg); border-radius: 7px;
  padding: 8px 11px; font-size: 13px; margin-bottom: 12px;
}
.sec-status {
  display: flex; align-items: center; gap: 8px;
  font-size: 14px; color: var(--text); margin-bottom: 12px;
}
.sec-status-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--text-faint); }
.sec-status.on .sec-status-dot { background: var(--t-green-fg); }
.sec-qr {
  display: flex; justify-content: center; padding: 14px;
  background: #fff; border: 1px solid var(--border); border-radius: 10px;
  margin-bottom: 12px;
}
.sec-qr svg { width: 200px; height: 200px; display: block; }
.sec-key { display: flex; flex-direction: column; gap: 5px; align-items: center; }
.sec-key-label { font-size: 12px; color: var(--text-faint); }
.sec-key code {
  font-family: var(--mono); font-size: 13px; color: var(--text);
  background: var(--bg-sidebar); border: 1px solid var(--border);
  border-radius: 6px; padding: 6px 10px; letter-spacing: .04em;
  word-break: break-all; text-align: center;
}
.recovery-codes {
  display: grid; grid-template-columns: 1fr 1fr; gap: 7px 14px;
  background: var(--bg-sidebar); border: 1px solid var(--border);
  border-radius: 8px; padding: 13px 15px; margin-bottom: 14px;
}
.recovery-codes code {
  font-family: var(--mono); font-size: 13px; color: var(--text);
  letter-spacing: .04em; text-align: center;
}

/* Header of the full-screen mobile menu; only shown below the breakpoint. */
.mobile-menu-head { display: none; }

/* ---------------- responsive: narrow screens -------------------------- */
/* Everything above is the full-size layout and is left untouched. Below the
   breakpoint two things change so the app stays usable on a phone/tablet:
     1. navigation moves to a BOTTOM TAB BAR (TabBar: four primary tables +
        More). More opens the sidebar as a FULL-SCREEN menu over the content —
        every table, report and settings page stays reachable from there — and
        it is closed by default (see store.mobileSidebarOpen);
     2. the macOS menu row COLLAPSES into a vertical drawer revealed by tapping
        the app icon — the same menus/dropdowns, just stacked.
   The book + account menus stay on the right (compact dropdowns already). */
@media (max-width: 768px) {
  /* --- sidebar as the full-screen "More" menu --- */
  .workspace { position: relative; }
  .sidebar {
    position: absolute; top: 0; left: 0; right: 0; bottom: 0; z-index: 45;
    width: auto; border-right: 0; overflow-y: auto;
    padding-top: 0; padding-bottom: 16px;
  }
  .sidebar .nav-item { padding: 9px 10px; font-size: 15px; }
  .mobile-menu-head {
    display: flex; align-items: center; justify-content: space-between;
    padding: 8px 12px 8px 18px; margin-bottom: 4px;
    font-size: 16px; font-weight: 600; color: var(--text);
    border-bottom: 1px solid var(--border);
  }
  .mobile-menu-head .icon-btn {
    font-size: 22px; line-height: 1; border: 0; background: none;
    width: 32px; height: 32px; color: var(--text-soft);
  }
  /* The tab bar's More tab opens and closes the menu; the desktop sidebar
     toggle would be a second, confusing way to do it. */
  .topbar .icon-btn.sidebar-toggle, .sidebar-toggle { display: none; }
  /* Topbar on a phone: the book is already named in the menu bar, so drop the
     breadcrumb; the title truncates and the actions never wrap. */
  .topbar .crumbs { display: none; }
  .topbar h1 { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .topbar .spacer { display: none; }
  .topbar .btn { white-space: nowrap; flex: none; }
  .sidebar-scrim {
    display: none; position: absolute; inset: 0; z-index: 44;
    background: rgba(248, 248, 247, .6);
    backdrop-filter: blur(3px) saturate(120%);
    -webkit-backdrop-filter: blur(3px) saturate(120%);
  }

  /* --- menu row as a drawer under the app icon --- */
  .menubar .logo { cursor: pointer; }
  .menubar.nav-open > .logo { background: rgba(0, 0, 0, .08); border-radius: 5px; }
  /* Collapse the row; reveal it as a floating vertical panel when nav-open. */
  .menubar-menus {
    display: none;
    position: absolute; top: 100%; left: 6px;
    flex-direction: column; align-items: stretch; gap: 0;
    min-width: 200px; max-width: calc(100vw - 16px); padding: 5px;
    background: rgba(250, 250, 250, .98);
    backdrop-filter: blur(20px); -webkit-backdrop-filter: blur(20px);
    border: 1px solid var(--border-strong); border-top: 0;
    border-radius: 0 0 8px 8px; box-shadow: var(--shadow);
  }
  .menubar.nav-open .menubar-menus { display: flex; }
  /* Each menu spans the drawer; its submenu drops inline (static) and indented,
     so the whole thing reads as one accordion rather than nested popups. */
  .menubar-menus .menu { position: static; }
  .menubar-menus .menu > button {
    display: flex; justify-content: space-between; align-items: center;
    width: 100%; padding: 6px 9px; border-radius: 5px; font-weight: 500;
  }
  .menubar-menus .menu-dropdown {
    position: static; min-width: 0; padding: 1px 0 4px 14px;
    background: none; backdrop-filter: none; -webkit-backdrop-filter: none;
    border: 0; border-radius: 0; box-shadow: none;
  }
  /* Keep the book label from pushing the avatar off the bar on tiny widths. */
  .menubar .book-menu > button {
    max-width: 38vw; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  }

  /* --- toolbar: keep it to one row --- */
  /* The search box is a fixed 220px on desktop, which on a phone shoves the
     "Show voided" toggle / "N of M" count / export into a wrap. Let the search
     field flex to absorb the slack instead, and pin the right-side meta so its
     short labels ("Show voided", "10 of 10") never break across lines. */
  .toolbar { gap: 6px; padding: 8px 14px; }
  .toolbar input.search { width: auto; flex: 1 1 60px; min-width: 0; }
  .toolbar .toolbar-meta { white-space: nowrap; flex-shrink: 0; }
  .toolbar .grp-toggle { flex-shrink: 0; }
}

/* ---------------- bottom tab bar (narrow screens only) ----------------- */
/* Rendered only on narrow screens; sits under the workspace in the page's
   column, so it takes its own height rather than covering content. Quiet like
   the rest: white surface, hairline top border, borderless tabs; the current
   tab is soft (accent text + a pale wash behind its icon), never a solid fill. */
.tabbar {
  flex: none; display: flex; align-items: stretch;
  background: var(--bg); border-top: 1px solid var(--border);
  padding: 4px 4px calc(4px + env(safe-area-inset-bottom, 0px));
  position: relative; z-index: 50;
}
.tabbar .tab {
  flex: 1 1 0; min-width: 0;
  display: flex; flex-direction: column; align-items: center; gap: 2px;
  padding: 5px 2px 4px; border: 0; background: none; border-radius: 6px;
  font: inherit; font-size: 11px; color: var(--text-soft); cursor: pointer;
  transition: background .12s ease, color .12s ease;
}
.tabbar .tab:active { background: var(--bg-hover); }
.tabbar .tab-icon {
  font-size: 18px; line-height: 26px; width: 44px; text-align: center;
  border-radius: 6px; filter: grayscale(.4); opacity: .8;
}
.tabbar .tab-label {
  max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.tabbar .tab.active { color: var(--accent); font-weight: 500; }
.tabbar .tab.active .tab-icon { background: var(--accent-soft); filter: none; opacity: 1; }
