/* =====================================================================
   SIA Books - components.css
   Requires tokens.css to be loaded first.

   RULES
   1. No color literals. No raw px except 0, 1px hairlines, and %.
      Everything comes from tokens.css.
   2. No page-specific CSS anywhere else in the codebase. If a page needs
      something that isn't here, ADD IT HERE and add it to the styleguide.
   3. No inline style="" attributes in templates.
   4. Every component works in both themes with no extra rules, because
      it only consumes semantic tokens.
   ===================================================================== */

/* ---------- Base ---------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }
html, body { height: 100%; }
body {
  margin: 0;
  font-family: var(--font-ui);
  font-size: var(--text-base);
  line-height: var(--leading-base);
  color: var(--text-primary);
  background: var(--surface);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}
h1, h2, h3, h4, h5 { margin: 0; line-height: var(--leading-tight); font-weight: var(--weight-bold); }
p, ul, ol { margin: 0; }
a { color: var(--text-link); text-decoration: none; }
a:hover { text-decoration: underline; }
:focus-visible { outline: none; box-shadow: var(--focus-ring); border-radius: var(--radius-sm); }

/* Numeric text - mandatory on every money, count, ID, and date cell. */
.num, .tabular { font-variant-numeric: tabular-nums; }
.num { text-align: right; }
.prose { max-width: var(--measure); line-height: var(--leading-prose); }
.truncate { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.visually-hidden {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
}


/* ---------- App shell ----------------------------------------------- */
.app { display: flex; min-height: 100vh; }

.sidebar {
  flex: 0 0 var(--sidebar-w);
  width: var(--sidebar-w);
  height: 100vh;
  position: sticky;
  top: 0;
  display: flex;
  flex-direction: column;
  background: var(--surface-sidebar);
  border-right: var(--border-w) solid var(--border);
}
.sidebar__head { flex: 0 0 auto; padding: var(--space-4); border-bottom: var(--border-w) solid var(--border); }
.sidebar__nav  { flex: 1 1 auto; overflow-y: auto; padding: var(--space-3) var(--space-2); }
.sidebar__foot {
  flex: 0 0 auto; padding: var(--space-3) var(--space-4);
  border-top: var(--border-w) solid var(--border);
  font-size: var(--text-sm); color: var(--text-secondary);
  display: flex; align-items: center; gap: var(--space-2); flex-wrap: wrap;
}
.brand { display: flex; align-items: center; gap: var(--space-2); margin-bottom: var(--space-4); }
.brand__mark {
  width: 28px; height: 28px; border-radius: var(--radius-sm);
  background: var(--brand); color: var(--text-on-solid);
  display: grid; place-items: center;
  font-size: var(--text-xs); font-weight: var(--weight-bold);
}
.brand__name { font-size: var(--text-base); font-weight: var(--weight-semi); }

.nav-group {
  font-size: var(--text-xs); text-transform: uppercase;
  letter-spacing: var(--tracking-caps); color: var(--text-muted);
  padding: var(--space-2) var(--space-3); margin-top: var(--space-3);
}
.nav-group:first-child { margin-top: 0; }
.nav-item {
  display: block; padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-md); border-left: 3px solid transparent;
  color: var(--text-primary); font-size: var(--text-base); text-decoration: none;
  transition: background var(--dur-fast) var(--ease);
}
.nav-item:hover { background: var(--surface-hover); text-decoration: none; }
.nav-item--active {
  background: var(--surface-active);
  border-left-color: var(--brand);
  font-weight: var(--weight-medium);
}

.main { flex: 1 1 auto; min-width: 0; padding: var(--space-6); }
.main__inner { max-width: 1240px; }


/* ---------- Page header --------------------------------------------- */
.page-head { margin-bottom: var(--space-5); }
.page-title {
  font-size: var(--text-xl); font-weight: var(--weight-bold);
  display: flex; align-items: baseline; gap: var(--space-3); flex-wrap: wrap;
}
.page-subtitle { font-size: var(--text-base); font-weight: var(--weight-normal); color: var(--text-secondary); }
.rule { width: 40px; height: 2px; background: var(--brand); margin: var(--space-2) 0 var(--space-3); }
.page-note {
  font-size: var(--text-sm); color: var(--text-secondary);
  max-width: var(--measure); line-height: var(--leading-prose);
}
.section { margin-top: var(--space-8); }
.section-title { font-size: var(--text-lg); font-weight: var(--weight-bold); }
.toolbar { display: flex; align-items: center; gap: var(--space-2); flex-wrap: wrap; margin: var(--space-4) 0; }
.toolbar__spacer { flex: 1 1 auto; }


/* ---------- Buttons -------------------------------------------------
   TIERS, not per-function colors:
     .btn--primary    ONE per page. Neutral dark (inverts in dark mode).
     .btn--secondary  everything routine: Run, Open, Export, Import, Cancel
     .btn--ghost      table row actions, tertiary controls
     .btn--danger     destructive ONLY. Red appears nowhere else.
   -------------------------------------------------------------------- */
.btn {
  height: var(--control-h);
  display: inline-flex; align-items: center; justify-content: center; gap: var(--space-2);
  padding: 0 var(--space-3);
  border: var(--border-w) solid transparent;
  border-radius: var(--radius-md);
  font-family: inherit; font-size: var(--text-base); font-weight: var(--weight-medium);
  line-height: 1; white-space: nowrap; cursor: pointer;
  transition: background var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease);
}
.btn:disabled { opacity: .45; cursor: not-allowed; }
.btn--sm { height: var(--control-h-sm); font-size: var(--text-sm); padding: 0 var(--space-2); }
.btn--block { width: 100%; }

.btn--primary   { background: var(--btn-primary-bg); color: var(--btn-primary-text); }
.btn--primary:hover:not(:disabled) { background: var(--btn-primary-bg-hover); }

.btn--secondary {
  background: var(--btn-secondary-bg); color: var(--btn-secondary-text);
  border-color: var(--btn-secondary-border);
}
.btn--secondary:hover:not(:disabled) { background: var(--btn-secondary-bg-hover); }

.btn--ghost { background: transparent; color: var(--btn-ghost-text); }
.btn--ghost:hover:not(:disabled) { background: var(--btn-ghost-bg-hover); color: var(--text-primary); }

.btn--danger {
  background: transparent; color: var(--btn-danger-text); border-color: var(--btn-danger-border);
}
.btn--danger:hover:not(:disabled) { background: var(--btn-danger-bg-hover); }
/* Solid red only on the second step of a confirm, never at rest. */
.btn--danger-confirm { background: var(--btn-danger-bg-solid); color: var(--text-on-solid); border-color: transparent; }

.btn-group { display: inline-flex; gap: var(--space-2); }


/* ---------- Menu bar (top navigation, desktop-app style) --------------
   Click a header to open its menu; hover moves across open headers;
   entries with children fly out a submenu. Escape / click-away closes.
   -------------------------------------------------------------------- */
.menubar { display: flex; align-items: stretch; gap: 2px; min-width: 0; flex-wrap: wrap; }
.menubar__group { position: relative; }
.menubar__top {
  height: var(--control-h);
  padding: 0 var(--space-3);
  border: 0; border-radius: var(--radius-md);
  background: transparent; color: var(--text-primary);
  font-family: inherit; font-size: var(--text-base); font-weight: var(--weight-medium);
  white-space: nowrap; cursor: pointer;
}
.menubar__top:hover { background: var(--surface-hover); }
.menubar__top[aria-expanded="true"] { background: var(--surface-active); }
.menubar__panel {
  position: absolute; left: 0; top: 100%; z-index: 90;
  min-width: 220px; padding: var(--space-1);
  background: var(--surface-raised);
  border: var(--border-w) solid var(--border);
  border-radius: var(--radius-md); box-shadow: var(--shadow-md);
}
.menubar__sub { left: 100%; top: 0; }
.menubar__entry {
  display: flex; align-items: center; gap: var(--space-2); width: 100%;
  padding: var(--space-2) var(--space-3);
  background: transparent; border: 0; border-radius: var(--radius-sm);
  font-family: inherit; font-size: var(--text-base); color: var(--text-primary);
  text-align: left; white-space: nowrap; cursor: pointer;
}
.menubar__entry:hover, .menubar__entry:focus-visible { background: var(--surface-hover); }
.menubar__entry--parent::after { content: "\203A"; margin-left: auto; color: var(--text-muted); }


/* ---------- Overflow menu (replaces multi-button table rows) --------- */
.menu { position: relative; display: inline-block; }
.menu__panel {
  position: absolute; right: 0; top: calc(100% + var(--space-1)); z-index: 20;
  min-width: 168px; padding: var(--space-1);
  background: var(--surface-raised);
  border: var(--border-w) solid var(--border);
  border-radius: var(--radius-md); box-shadow: var(--shadow-md);
}
.menu__panel[hidden] { display: none; }
.menu__item {
  display: flex; align-items: center; gap: var(--space-2); width: 100%;
  padding: var(--space-2) var(--space-3);
  background: transparent; border: 0; border-radius: var(--radius-sm);
  font-family: inherit; font-size: var(--text-base); color: var(--text-primary);
  text-align: left; cursor: pointer;
}
.menu__item:hover { background: var(--surface-hover); }
.menu__item--danger { color: var(--btn-danger-text); }
.menu__sep { height: 1px; background: var(--border); margin: var(--space-1) 0; }


/* ---------- Form controls -------------------------------------------
   Every control is the same height and shares one focus treatment.
   Controls are ALWAYS width:100% of their grid cell - fixed widths are
   what forces horizontal scrolling. Let the grid do the sizing.
   -------------------------------------------------------------------- */
.field { display: flex; flex-direction: column; gap: var(--space-1); min-width: 0; }
.field__label {
  font-size: var(--text-xs); text-transform: uppercase;
  letter-spacing: var(--tracking-caps); color: var(--text-secondary);
}
.field__hint { font-size: var(--text-sm); color: var(--text-muted); }

.input, .select, .textarea {
  width: 100%; min-width: 0;
  height: var(--control-h);
  padding: 0 var(--space-2);
  font-family: inherit; font-size: var(--text-base); color: var(--text-primary);
  background: var(--surface);
  border: var(--border-w) solid var(--border-strong);
  border-radius: var(--radius-sm);
  transition: border-color var(--dur-fast) var(--ease);
}
.textarea { height: auto; min-height: 72px; padding: var(--space-2); line-height: var(--leading-base); resize: vertical; }
.input::placeholder { color: var(--text-muted); }
.input:focus, .select:focus, .textarea:focus {
  outline: none; border-color: var(--border-focus); box-shadow: var(--focus-ring);
}
.input:disabled, .select:disabled { background: var(--surface-sunken); color: var(--text-muted); }
.input[type="date"] { min-width: 0; }   /* stops Chromium reserving extra width */

.checkbox-row { display: flex; align-items: center; gap: var(--space-2); font-size: var(--text-base); }


/* ---------- Date range ----------------------------------------------
   From and To sit SIDE BY SIDE in one row, in DOM order, so Tab moves
   start -> end. Never stack them on separate rows; never let the
   container scroll horizontally.
   Bind min/max in JS: end.min = start.value; start.max = end.value.
   -------------------------------------------------------------------- */
.date-range {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-2);
  align-items: end;
  min-width: 0;
}
.date-range--with-preset { grid-template-columns: 1fr 1fr auto; }
.date-range__sep {
  align-self: center; padding-bottom: var(--space-2);
  color: var(--text-muted); font-size: var(--text-sm);
}
/* Below 420px the two fields stack rather than overflow. */
@media (max-width: 420px) {
  .date-range, .date-range--with-preset { grid-template-columns: 1fr; }
}


/* ---------- Filter panel / config pane -------------------------------
   Auto-fitting grid. This is the fix for panes that scroll sideways:
   columns collapse instead of overflowing.
   -------------------------------------------------------------------- */
.panel {
  background: var(--surface-sunken);
  border: var(--border-w) solid var(--border);
  border-radius: var(--radius-md);
  padding: var(--space-4);
  min-width: 0;
  overflow: visible;          /* never overflow-x: auto on a form pane */
}
.panel__title {
  font-size: var(--text-xs); text-transform: uppercase;
  letter-spacing: var(--tracking-caps); color: var(--text-secondary);
  margin-bottom: var(--space-3);
}
.panel__grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: var(--space-3);
  min-width: 0;
}
.panel__grid > .field--wide { grid-column: 1 / -1; }
.panel__actions { display: flex; gap: var(--space-2); margin-top: var(--space-4); }

/* Filter-left / results-right page pattern */
.split { display: grid; grid-template-columns: minmax(200px, 240px) minmax(0, 1fr); gap: var(--space-5); align-items: start; }
@media (max-width: 900px) { .split { grid-template-columns: minmax(0, 1fr); } }
.result-meta {
  font-size: var(--text-sm); color: var(--text-secondary);
  font-variant-numeric: tabular-nums; margin-bottom: var(--space-2);
}


/* ---------- Tables --------------------------------------------------- */
.table-wrap {
  border: var(--border-w) solid var(--border);
  border-radius: var(--radius-md);
  overflow: auto;
  /* 60vh is the NO-JS FALLBACK only - sizeShells() measures each wrap and
     sets an inline max-height to the exact window remainder (S-60b), so
     scrollbars appear at the window edge, never three inches early. */
  max-height: 60vh;
  background: var(--surface);
  box-shadow: var(--shadow-sm);
}
/* S-62 (Jack): tables FIT THEIR CONTENTS by default - a two-column table
   takes two columns' width, never the whole window with stretched cells.
   The wrap still bounds tall/wide content; genuinely wide tables scroll. */
.table { width: max-content; min-width: 0; max-width: 100%; border-collapse: separate; border-spacing: 0; font-size: var(--text-base); }
.table--full { width: 100%; }
/* header styling also covers headerless-thead tables (drag grids emit a
   plain first row of th cells; the browser auto-wraps them in tbody) */
.table thead th, .table tbody tr:first-child th {
  position: sticky; top: 0; z-index: 2;
  background: var(--surface-sunken);
  padding: var(--space-2) var(--space-3);
  font-size: var(--text-xs); font-weight: var(--weight-semi);
  text-transform: uppercase; letter-spacing: var(--tracking-head);
  color: var(--text-secondary); text-align: left; white-space: nowrap;
  border-bottom: var(--border-w) solid var(--border);
}
.table thead th.num, .table tbody tr:first-child th.num { text-align: right; }
/* Resize-handle grab line (S-60c UI rule): headers show a slight visible
   line where the column can be grabbed. The .rz handle is injected by the
   shared resize machinery; this rule keeps the affordance when the legacy
   style block dies. */
.table thead th, .table tbody tr:first-child th { position: relative; }
.table thead th .rz {
  position: absolute; right: -3px; top: 0; bottom: 0; width: 7px;
  cursor: col-resize; z-index: 2;
  background: linear-gradient(var(--border-strong), var(--border-strong)) no-repeat 3px 50% / 1px 62%;
}
.table tbody td {
  height: var(--row-h);
  padding: var(--space-2) var(--space-3);
  border-bottom: var(--border-w) solid var(--border);
  vertical-align: middle;
}
.table tbody tr:last-child td { border-bottom: 0; }
.table tbody tr:hover { background: var(--surface-hover); }
.table tbody tr[aria-disabled="true"] td { color: var(--text-muted); }

/* Clickable rows - the row itself navigates; actions stopPropagation. */
.table tbody tr.row-link { cursor: pointer; }

/* Centered cell - checkbox/availability columns (S-59). Applies to th and td. */
.table .cell-center { text-align: center; }

/* Selected row - the open item while its side pane is up (S-59). */
.table tbody tr.sel td { background: var(--surface-sunken); }

/* Report rows (S-61): totals close a statement; derived rows flag
   engine-computed values (the classic TB's has_derived italic). */
.table tbody tr.t-total td {
  border-top: 2px solid var(--border-strong);
  font-weight: var(--weight-semi);
}
.table tbody tr.t-derived td { color: var(--status-warning-fg); font-style: italic; }

/* Section header row inside a listing (register groups, statement sections). */
.table tbody tr.t-sec td {
  background: var(--surface-sunken);
  font-weight: var(--weight-semi);
  border-top: 2px solid var(--border-strong);
}

/* Side-by-side report columns - the "All entities" diagnostics view. */
.report-cols { display: flex; gap: var(--space-5); align-items: flex-start; overflow-x: auto; }
.report-cols > .report-col { min-width: 420px; }

/* Small logo thumbnail in admin tables. */
.logo-thumb { height: 22px; max-width: 60px; vertical-align: middle; border-radius: var(--radius-sm); }

/* Embedded same-origin frame (the New Submission client form). */
.embed-frame { width: 100%; height: 100%; border: 0; border-radius: var(--radius-md); background: var(--surface); }

/* Read-only journal entry (S-64, Jack): a posted/deleted entry displays at
   FULL contrast - exactly like a draft - and only the not-allowed cursor
   says "no edits here". Buttons keep the dimmed disabled look; the DATA
   never dims. */
.je-ro input:disabled, .je-ro select:disabled, .je-ro textarea:disabled {
  color: var(--text-primary);
  -webkit-text-fill-color: var(--text-primary);
  opacity: 1;
  cursor: not-allowed;
}
.je-ro #f-grid td, .je-ro #hl-bar, .je-ro #hd-bar, .je-ro #f-defrow { cursor: not-allowed; }

/* ---------- Layout + text utilities (S-65, the pane round) ------------
   The small vocabulary that replaced ~150 one-off inline styles in pane
   and view markup. Presentational styles ONLY - JS-toggled state
   (display:none flips, computed widths) stays inline by doctrine. */
.row   { display: flex; align-items: center; gap: var(--space-2); }
.row--top   { align-items: flex-start; }
.row--gap-lg { gap: var(--space-3); }
.row--wrap { flex-wrap: wrap; }
.stack { display: flex; flex-direction: column; gap: var(--space-2); }
.grow  { flex: 1 1 0; }
.grow--lg { flex: 1.4 1 0; }
.in-xs { width: 70px; }
.in-sm { width: 90px; }
.in-md { width: 110px; }
.in-lg { width: 150px; }
.in-full { width: 100%; }
.fs-xs { font-size: var(--text-xs); }
.wt-b  { font-weight: var(--weight-semi); }
.nowrap { white-space: nowrap; }
.scroll-x { overflow-x: auto; }
.mono { font-family: var(--font-mono); }
.inert { pointer-events: none; }
.section-title--spaced { margin-top: var(--space-6); }
label.block { display: block; margin: var(--space-1) 0; }
.inline { display: inline; }
.ml-2 { margin-left: var(--space-2); }
.ml-3 { margin-left: var(--space-3); }
.mr-2 { margin-right: var(--space-2); }
.mt-1 { margin-top: var(--space-1); }
.mt-2 { margin-top: var(--space-2); }
.mt-4 { margin-top: var(--space-4); }
.mb-1 { margin-bottom: var(--space-1); }
.mb-2 { margin-bottom: var(--space-2); }
.my-1 { margin: var(--space-1) 0; }
.fs-xl { font-size: var(--text-xl); }
.wt-n  { font-weight: var(--weight-normal); }
.mt-8  { margin-top: var(--space-8); }
.maxw-xs { max-width: 330px; }
.in-xs2  { width: 80px; }
.in-icon { width: 34px; }
.grab { cursor: grab; }
.progress__fill--info { background: var(--status-info-fg); }
.preview-frame { width: 100%; max-width: 900px; height: 760px;
  border: 1px solid var(--border); border-radius: var(--radius-md);
  background: var(--surface-sunken); }
.plain-link { text-decoration: none; }
.maxw-sm { max-width: 460px; }
.maxw-md { max-width: 660px; }
.col-w30 { width: 30%; }
.col-w34 { width: 34%; }
.sticky-top { position: sticky; top: 0; background: var(--surface-raised); padding: var(--space-1); }
.mark-warn { background: var(--status-warning-bg); padding: 0 var(--space-1); }
.mark-dim  { background: var(--surface-sunken); padding: 0 var(--space-1); }
.mark-info { background: var(--status-info-bg); }
.cell-dim  { background: var(--surface-sunken); color: var(--text-secondary); }
.indent { margin-left: var(--space-4); border-left: 2px solid var(--border); padding-left: var(--space-2); }
label.inline-cb { display: inline-block; margin-right: var(--space-2); }
.pick-item { display: block; padding: var(--space-1) var(--space-3); }
.ctx-logo { width: 36px; height: 36px; object-fit: contain;
  border: 1px solid var(--border-strong); border-radius: var(--radius-md);
  background: var(--surface); flex-shrink: 0; }

/* Pane section separator - divides the left pane's logical sections
   (Filters / List / Export / Settings). S-60 universal rule: all settings,
   buttons, and filters live in the left pane, sectioned by these lines. */
.pane-sep { border-top: 1px solid var(--border); margin: var(--space-3) 0; }

/* Sticky first column, for wide ledgers */
.table--sticky-first thead th:first-child,
.table--sticky-first tbody td:first-child {
  position: sticky; left: 0; z-index: 1; background: var(--surface);
}
.table--sticky-first thead th:first-child { z-index: 3; background: var(--surface-sunken); }

.cell-link { color: var(--text-primary); font-weight: var(--weight-medium); }
.cell-link:hover { color: var(--brand); }
.cell-truncate { max-width: 240px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.row-actions { display: flex; gap: var(--space-1); justify-content: flex-end; white-space: nowrap; }


/* ---------- Badges & counts ------------------------------------------ */
.badge {
  display: inline-flex; align-items: center; height: 20px;
  padding: 0 var(--space-2); border-radius: var(--radius-full);
  font-size: var(--text-xs); font-weight: var(--weight-semi); letter-spacing: .02em;
  white-space: nowrap;
}
.badge--success { background: var(--status-success-bg); color: var(--status-success-fg); }
.badge--info    { background: var(--status-info-bg);    color: var(--status-info-fg); }
.badge--warning { background: var(--status-warning-bg); color: var(--status-warning-fg); }
.badge--danger  { background: var(--status-danger-bg);  color: var(--status-danger-fg); }
.badge--neutral { background: var(--status-neutral-bg); color: var(--status-neutral-fg); }
.badge--void    { background: transparent; color: var(--text-muted); }   /* S-72 (Jack): no strike-through anywhere */
.badge--stark   { background: var(--badge-stark-bg); color: var(--badge-stark-fg);
                  border: 1px solid var(--badge-stark-border); }  /* white pill, black ring, both themes */

/* ---------- Info tip ---------------------------------------------------- */
/* View-level guidance lives in a hover tooltip, not a text block (S-37).
   Put one in the page's header row; the title attribute carries the text. */
.info-tip {
  display: inline-flex; align-items: center; justify-content: center;
  width: 18px; height: 18px; border-radius: var(--radius-full);
  border: 1px solid var(--border-strong); color: var(--text-secondary);
  font-size: var(--text-xs); font-weight: var(--weight-semi);
  cursor: help; user-select: none; flex-shrink: 0;
}

.count {
  display: inline-grid; place-items: center; min-width: 18px; height: 18px;
  padding: 0 5px; border-radius: var(--radius-full);
  font-size: var(--text-xs); font-weight: var(--weight-semi);
  font-variant-numeric: tabular-nums;
}
.count--danger  { background: var(--status-danger-bg);  color: var(--status-danger-fg); }
.count--warning { background: var(--status-warning-bg); color: var(--status-warning-fg); }
.count--neutral { background: var(--status-neutral-bg); color: var(--status-neutral-fg); }


/* ---------- Progress -------------------------------------------------- */
.progress { display: flex; align-items: center; gap: var(--space-2); min-width: 140px; }
.progress__track { flex: 1 1 auto; height: 5px; background: var(--progress-track); border-radius: var(--radius-full); overflow: hidden; }
.progress__fill  { height: 100%; background: var(--progress-fill); border-radius: var(--radius-full); }
.progress__value { font-size: var(--text-sm); color: var(--text-secondary); font-variant-numeric: tabular-nums; white-space: nowrap; }


/* ---------- Alert ----------------------------------------------------- */
.alert {
  border: var(--border-w) solid var(--border);
  border-left: 3px solid var(--brand);
  background: var(--brand-subtle);
  border-radius: var(--radius-md);
  padding: var(--space-3) var(--space-4);
  margin-bottom: var(--space-5);
}
.alert__title { font-size: var(--text-base); font-weight: var(--weight-semi); margin-bottom: var(--space-1); }
.alert__body  { font-size: var(--text-sm); color: var(--text-secondary); line-height: var(--leading-prose); }
.alert--info    { border-left-color: var(--status-info-fg);    background: var(--status-info-bg); }
.alert--warning { border-left-color: var(--status-warning-fg); background: var(--status-warning-bg); }
.alert--danger  { border-left-color: var(--btn-danger-border);  background: var(--status-danger-bg); }


/* ---------- Tips / helper card ---------------------------------------
   The app's inline explanatory prose is a feature. Keep it, contain it.
   -------------------------------------------------------------------- */
.tips {
  background: var(--surface-sunken);
  border: var(--border-w) solid var(--border);
  border-radius: var(--radius-md);
  padding: var(--space-4);
  max-width: var(--measure);
}
.tips__title { font-size: var(--text-base); font-weight: var(--weight-semi); margin-bottom: var(--space-2); }
.tips li {
  font-size: var(--text-sm); color: var(--text-secondary);
  line-height: var(--leading-prose); margin-left: var(--space-4); margin-bottom: var(--space-1);
}
kbd {
  font-family: var(--font-mono); font-size: var(--text-xs);
  background: var(--surface); color: var(--text-primary);
  border: var(--border-w) solid var(--border-strong); border-bottom-width: 2px;
  border-radius: var(--radius-sm); padding: 1px 5px;
}


/* ---------- Empty / loading / error states ---------------------------- */
.empty {
  border: 1px dashed var(--border-strong);
  border-radius: var(--radius-md);
  padding: var(--space-8);
  text-align: center;
  color: var(--text-muted);
  font-size: var(--text-sm);
  line-height: var(--leading-prose);
}
.empty__title { font-size: var(--text-base); color: var(--text-secondary); font-weight: var(--weight-medium); margin-bottom: var(--space-1); }

.loading-bar { position: fixed; top: 0; left: 0; right: 0; height: 2px; background: var(--brand); z-index: 100; transform-origin: 0 50%; }

.error-state {
  border: var(--border-w) solid var(--border);
  border-left: 3px solid var(--status-danger-fg);
  background: var(--status-danger-bg);
  border-radius: var(--radius-md);
  padding: var(--space-4);
  font-size: var(--text-sm);
  color: var(--text-primary);
}

.skeleton {
  background: var(--surface-hover); border-radius: var(--radius-sm);
  animation: skeleton-pulse 1.4s ease-in-out infinite;
}
@keyframes skeleton-pulse { 0%,100% { opacity: 1 } 50% { opacity: .5 } }


/* ---------- Theme toggle ----------------------------------------------- */
.theme-toggle {
  display: inline-flex; padding: 2px; gap: 2px;
  background: var(--surface-sunken);
  border: var(--border-w) solid var(--border);
  border-radius: var(--radius-full);
}
.theme-toggle button {
  height: 24px; padding: 0 var(--space-3);
  border: 0; border-radius: var(--radius-full);
  background: transparent; color: var(--text-secondary);
  font-family: inherit; font-size: var(--text-xs); font-weight: var(--weight-medium);
  cursor: pointer;
}
.theme-toggle button[aria-pressed="true"] {
  background: var(--surface-raised); color: var(--text-primary); box-shadow: var(--shadow-sm);
}


/* ---------- Tabs (S-80c2) ------------------------------------------------ */
/* Top tabs for a page split into panes (the budget page). One row, hairline
   below; the selected tab carries the brand underline. Panes stay mounted. */
.tabs { display:flex; gap:var(--space-1); border-bottom:var(--border-w) solid var(--border); margin:var(--space-2) 0 var(--space-3); flex-wrap:wrap; }
.tabs .tab { padding:var(--space-2) var(--space-3); border:0; border-bottom:2px solid transparent; margin-bottom:-1px;
  background:transparent; color:var(--text-secondary); font-family:inherit; font-size:var(--text-sm); font-weight:var(--weight-medium); cursor:pointer; }
.tabs .tab:hover { color:var(--text-primary); background:var(--surface-hover); }
.tabs .tab[aria-selected="true"] { color:var(--text-primary); border-bottom-color:var(--brand-500); }

/* ---------- Floating save bar ------------------------------------------ */
/* Fixed bottom-right, shown while a grid is in EDIT MODE - makes it clear
   nothing sticks until Save is clicked. One per page, edit mode only. */
.float-save {
  position: fixed;
  right: var(--space-6);
  bottom: var(--space-6);
  display: flex;
  gap: var(--space-2);
  align-items: center;
  padding: var(--space-3);
  background: var(--surface-raised);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-md);
  z-index: 500;
}
.float-save .float-save__note { color: var(--text-secondary); font-size: var(--text-xs); }


/* ---------- Print ------------------------------------------------------ */
@media print {
  .sidebar, .toolbar, .row-actions, .theme-toggle { display: none !important; }
  .main { padding: 0; }
  .table-wrap { max-height: none; overflow: visible; border: 0; box-shadow: none; }
  .table thead th { position: static; }
}


/* =====================================================================
   APP CHROME + WIDGET LAYER (S-63, declared PERMANENT in S-68) - the
   home of the app shell (topbar, hidden nav model, panes, toasts,
   combos), the filter-shell frame, and the surface-specific grid rules
   (report engine output, JE editor, Edit List, close widgets). Every
   rule consumes semantic tokens; the shared cores live in the registered
   components above (.table, .entry-grid, .btn, badges). This is not
   debt: it is organized, token-clean, battery-pinned CSS. Prefer the
   registered components for anything new; extend this layer only for
   the surfaces it already owns.
   ===================================================================== */

:root { --sidew:230px; }
/* UNIVERSAL PANE LAW (Jack): the WINDOW never scrolls. Every column -
   sidebar, content, right panes - is exactly viewport-height and scrolls
   INTERNALLY, only when its own content overflows. Split views (.fshell)
   additionally measure their remaining height via sizeShells(). */
html, body { height:100%; overflow:hidden; }
body { margin:0; font:var(--text-base)/var(--leading-base) var(--font-ui);
       color:var(--text-primary); background:var(--surface); }
h1, h2, h3, h4, #side h1, .sec { font-family:var(--font-ui); }
select, input, button { font:inherit; padding:4px 7px; border:1px solid var(--border-strong);
  border-radius:var(--radius-sm); background:var(--surface); color:var(--text-primary); }
button { cursor:pointer; }

#shell { display:none; height:100vh; }
#shell.on { display:flex; flex-direction:column; }
/* S-27: top navigation bar; the sidebar below it is the HIDDEN nav model */
#topbar { display:flex; align-items:center; gap:10px; flex-wrap:wrap;
  padding:6px 14px; border-bottom:1px solid var(--border);
  background:var(--surface-sidebar); position:relative; z-index:80; flex:none; }
#topbar .tb-firmlogo { height:34px; width:auto; flex-shrink:0; cursor:pointer; }
#ctxLogo { cursor:pointer; }
/* S-34 wrap/truncate mode (app-shell ids; retire with the legacy block).
   Truncate clips cell TEXT to the column; hover reveals via title. */
html[data-wrap="truncate"] #view td, html[data-wrap="truncate"] #pane td,
html[data-wrap="truncate"] #lst-pane-body td, html[data-wrap="truncate"] #diag-out td {
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis; max-width:240px; }
/* S-80a (F2): the entity SEGMENT cell is a badge, never text - the truncate
   cap must not clip it to an ellipsis in a fixed-layout grid column */
html[data-wrap="truncate"] #view td.ent-td, html[data-wrap="truncate"] #pane td.ent-td { overflow:visible; text-overflow:clip; }
/* S-35: once a table is column-resized (frozen = REAL fixed layout), the
   dragged widths rule - the blanket cap would clip inside wider columns */
html[data-wrap="truncate"] #view table[data-frozen] td,
html[data-wrap="truncate"] #pane table[data-frozen] td,
html[data-wrap="truncate"] #lst-pane-body table[data-frozen] td,
html[data-wrap="truncate"] #diag-out table[data-frozen] td { max-width:none; }
#topbar #entityBadges { display:inline-flex; gap:var(--space-2); align-items:center; }
/* S-72: per-entity header badge - logo · code · exemption */
.ent-badge { display:inline-flex; align-items:center; gap:var(--space-1); padding:0 var(--space-1);
  border-radius:var(--radius-md); }
.ent-badge--current { outline:1px solid var(--border-strong); }
.ent-sep { color:var(--border-strong); font-weight:var(--weight-bold); padding:0 var(--space-1); }   /* S-72: clear divider between entity groups */
.ent-badge__logo { height:20px; width:auto; border-radius:var(--radius-sm); }
/* S-72: the User menu drops from the right edge; static rows are labels, not actions */
.menubar__panel--right { left:auto; right:0; }
.menubar__entry--static { cursor:default; display:flex; align-items:center; gap:var(--space-2); }
.menubar__entry--static:hover { background:transparent; }
#topbar .tb-spacer { flex:1 1 auto; }
#topbar #ctxPickers { display:flex; gap:6px; align-items:center; min-width:0; }
#topbar #ctxPickers select { max-width:190px; }
/* S-72 4b (D32): the entity picker is the hidden ROUTING model - never displayed */
#topbar #ctxPickers #entitySel2 { display:none !important; }
.page-entity { font-size:var(--text-sm); font-weight:var(--weight-normal); margin-left:var(--space-3); }
.page-entity select { max-width:260px; }
/* S-72 D28: DERIVED cells (entity from the Function/account, Function grayed on
   balance-sheet lines) must stay LEGIBLE - browsers dim disabled controls to
   near-invisible in some themes (Jack, testing 2026-09-06: the cell held RAF
   and read as blank) */
#f-grid select.l-ent.derived, #f-grid td.derived select, #f-grid td.derived input,
#f-grid select.l-ent:disabled, #f-grid td.derived input:disabled {
  color:var(--text-secondary); -webkit-text-fill-color:var(--text-secondary); opacity:1;
  background:var(--surface-sunken); border-color:var(--border); font-weight:var(--weight-bold); }
#f-entent.derived { color:var(--text-muted); }
/* S-72 D28 (Jack): the entity segment is ALWAYS a code badge - derived = plain,
   selectable = badge + caret opening a picker (.ent-picker) */
.ent-cell { display:inline-flex; align-items:center; gap:var(--space-1); }
.ent-cell--pick { cursor:pointer; }
.ent-cell__caret { color:var(--text-muted); font-size:var(--text-xs); }
.ent-anchor { position:relative; }
.ent-picker { display:block; left:0; top:100%; z-index:30; }
.ent-picker .menubar__entry.sel { background:var(--surface-active); }
#topbar .acct { display:flex; align-items:center; gap:6px; font-size:var(--text-xs);
  color:var(--text-secondary); white-space:nowrap; }
#mainrow { flex:1 1 auto; min-height:0; display:flex; min-width:0; }
#side { width:var(--sidew); min-width:var(--sidew); background:var(--surface-sidebar);
        border-right:1px solid var(--border); padding:14px 12px; overflow-y:auto;
        display:flex; flex-direction:column; gap:4px; }
#side h1 { font-size:var(--text-base); margin:0 0 10px; letter-spacing:.4px; }
.signin-logo { width:180px; max-width:60vw; }
#acctBottom #whoRole { white-space:nowrap; }
#side label { font-size:var(--text-xs); color:var(--text-secondary); display:block; margin-top:6px; }
#side select { width:100%; }
#side .acct { font-size:var(--text-xs); color:var(--text-secondary); margin:8px 0 2px; word-break:break-all; }
.pill { font-size:var(--text-xs); padding:1px 7px; border-radius:var(--radius-full);
        background:var(--surface); border:1px solid var(--border-strong); }
#side .sec { margin-top:14px; font-size:var(--text-xs); text-transform:uppercase;
             letter-spacing:var(--tracking-caps); color:var(--text-muted);
             cursor:pointer; user-select:none; display:flex; justify-content:space-between; align-items:center; }
#side .sec:hover { color:var(--text-primary); }
.caret { transition:transform .12s; font-size:var(--text-xs); }
.secItems.collapsed { display:none; }
            border-left:2px solid var(--brand); border-radius:0 6px 6px 0;
            display:flex; flex-direction:column; gap:6px; font-size:var(--text-sm); }
                  flex-wrap:wrap; color:var(--text-secondary); white-space:nowrap; }
/* resizable sidebar */
#side { position:relative; display:flex; flex-direction:column; }
#side .sec, #side .secItems { flex:none; }
#sideRz { position:absolute; top:0; right:-4px; bottom:0; width:8px;
          cursor:col-resize; z-index:5; }
#sideRz:hover, #sideRz.active { background:var(--brand); opacity:.3; }
.sec.closed .caret, .caret.closed { transform:rotate(-90deg); }
/* S-27: the sidebar is the hidden nav MODEL - never displayed. Trims,
   dynamic items, and active states still write to it; buildMenubar reads it. */
#side { display:none !important; }
#side a.nav { display:block; padding:5px 9px; border-radius:var(--radius-md); color:var(--text-primary); text-decoration:none; }
#side a.nav:hover { background:var(--surface-hover); }
#side a.nav.active { background:var(--surface-active); color:var(--brand); font-weight:600;
  border-left:3px solid var(--brand); border-radius:0 6px 6px 0; padding-left:6px; }

#main { flex:1; display:flex; min-width:0; }
#content { flex:1; min-width:0; overflow-y:auto; padding:var(--space-3) var(--space-5); }
#pane { width:0; min-width:0; border-left:1px solid var(--border-strong); overflow-y:auto;
        transition:width .15s; background:var(--surface-raised); }
#pane.open { width:46%; min-width:420px; padding:12px 18px; }
#pane .close { float:right; }
#pane { position:relative; }
.pdrag { position:absolute; left:0; top:0; bottom:0; width:7px; cursor:col-resize; z-index:5; }
.pdrag:hover { background:var(--border-strong); }
/* F9: responsive split shells - fill tall windows, scroll inside short
   ones, stack on narrow ones. Used by Report Engine + every filterShell. */
.fshell { display:flex; gap:0; align-items:stretch; }
.fshell > .fcol { overflow-y:auto; overflow-x:hidden; }
.fshell > .fbody { flex:1; min-width:0; overflow:auto; }
@media (max-width:820px) {
  .fshell { flex-direction:column; height:auto !important; }
  .fshell > .fcol { flex:0 0 auto !important; width:auto !important; max-height:45vh;
    border-bottom:1px solid var(--border-strong); }
  .fshell > .vdrag { display:none; }
}

.bar { display:flex; gap:8px; align-items:center; flex-wrap:wrap; margin:8px 0; }
.muted { color:var(--text-secondary); font-size:var(--text-sm); }
table { border-collapse:collapse; width:auto; margin:6px 0 16px; }
th, td { padding:3px 8px; border-bottom:1px solid var(--border); text-align:left; }
th { background:var(--surface-sunken); font-weight:600; font-size:var(--text-xs); position:relative; }
.tipsbox { margin-top:14px; padding:10px 12px; background:var(--surface-sunken); border:1px solid var(--border);
    border-radius:var(--radius-md); font-size:var(--text-sm); color:var(--text-secondary); max-width:720px; }
.tipsbox ul { margin:4px 0 0 18px; padding:0; }
.tipsbox li { margin:2px 0; }
.tipsbox code { background:var(--surface-sunken); padding:0 3px; border-radius:3px; }
#f-lines tr.lrow { content-visibility: auto; contain-intrinsic-block-size: auto 30px; }
#f-grid .defrow td { background:var(--surface-sunken); }
#f-grid .defrow input, #f-grid .defrow select {
  border:none; background:transparent; color:var(--text-secondary); width:100%; box-sizing:border-box; }
#f-grid .defrow input:focus { outline:1px solid var(--border-focus); background:var(--surface); }
#f-lines input::placeholder { color:var(--status-info-fg); opacity:.95; }
#f-lines input.ghostred::placeholder { color:var(--status-danger-fg); }
#f-grid .sysrow td { background:var(--surface-sunken); color:var(--text-secondary); font-style:italic; }
/* S-72: allocation entry editing - the run's rows are grayed originals (Split only); splits are the editable copies */
#f-grid tr.alloc-src td { background:var(--surface-sunken); }
#f-grid tr.alloc-src input, #f-grid tr.alloc-src select { color:var(--text-secondary); }
#f-grid tr.alloc-split td:first-child { border-left:3px solid var(--border-strong); }
/* S-72 Batch C: allocated source rows on a posted entry - locked */
#f-grid tr.alloc-locked td { background:var(--surface-sunken); }
#f-grid tr.alloc-locked input, #f-grid tr.alloc-locked select { color:var(--text-secondary); cursor:not-allowed; }
#f-grid tfoot td { background:var(--surface-sunken); font-weight:600; font-size:var(--text-xs);
    padding:4px 6px; border:1px solid var(--border); }
#fillHandle { position:absolute; width:8px; height:8px; background:var(--brand);
    border:1px solid var(--surface); cursor:crosshair; z-index:30; }
body.filling, body.filling * { cursor:crosshair !important; user-select:none !important; }
#f-lines tr.fillTarget td { background:var(--status-info-bg); }
/* journal lines: editable-spreadsheet feel */
#f-grid th { border:1px solid var(--border); }
#f-grid th .rz { background:none; }   /* spreadsheet borders already mark edges */
#f-lines input:focus, #f-lines select:focus { outline:2px solid var(--brand); outline-offset:-2px;
    background:var(--surface); }
#f-lines input:disabled { background:var(--surface-sunken); cursor:not-allowed; }
#f-lines .l-dr, #f-lines .l-cr { text-align:right; }
.combopop { position:absolute; z-index:60; background:var(--surface-raised); border:1px solid var(--border-strong);
    box-shadow:var(--shadow-md); max-height:240px; overflow-y:auto; font-size:var(--text-sm); }
.combopop .copt { padding:4px 8px; cursor:pointer; white-space:nowrap; }
.combopop .copt:hover, .combopop .copt.sel { background:var(--surface-active); }
#f-lines td.msel { outline:2px solid var(--brand); outline-offset:-2px; background:var(--status-info-bg); }
#f-lines td.msel select, #f-lines td.msel input { background:var(--status-info-bg); }
#f-lines td.rowbtns { white-space:nowrap; padding:0 2px; border:none; background:none; }
#f-lines td.rowbtns button { border:none; background:none; cursor:pointer; font-size:var(--text-xs);
    padding:2px 1px; opacity:.45; }
#f-lines td.rowbtns button:hover { opacity:1; }
input.derived { background:var(--surface-sunken); color:var(--text-secondary); border-style:dotted; cursor:not-allowed; }
.rec-sticky { position:sticky; top:0; background:var(--surface); z-index:20; padding:2px 0 6px;
              border-bottom:2px solid var(--border-strong); }
.rec-sticky h2 { margin:4px 0 6px; }
.rc-mark { background:var(--status-warning-bg); color:var(--status-warning-fg); border-radius:var(--radius-sm);
           padding:0 4px; font-size:var(--text-xs); cursor:help; user-select:none; }
tr.rc-locked td { background:var(--status-warning-bg); }
.rec-sum td { padding:1px 10px 1px 0; }
.rec-top { display:flex; gap:22px; align-items:flex-start; flex-wrap:wrap; }
.stmt-block { border:1px solid var(--border-strong); border-radius:var(--radius-md); padding:8px 10px; margin:8px 0; }
/* shared editable-spreadsheet feel (mirrors #f-lines) for quick-add grids */
table.sheet { border-collapse:collapse; }
table.sheet td { padding:0; border:1px solid var(--border); }
table.sheet th { border:1px solid var(--border); background:var(--surface-sunken); font-size:var(--text-xs); padding:3px 6px; }
table.sheet td.ro { padding:4px 6px; background:var(--surface-sunken); color:var(--text-secondary); }
table.sheet tr.simrow td { background:var(--surface-sunken); color:var(--text-secondary); font-style:italic; }   /* S-80: a SIMULATED holding reversal in the budget (mirrors #f-grid .sysrow) */
table.sheet input, table.sheet select { width:100%; border:none; background:transparent;
    padding:4px 6px; font:inherit; box-sizing:border-box; border-radius:0; }
table.sheet input:focus, table.sheet select:focus { outline:2px solid var(--brand);
    outline-offset:-2px; background:var(--surface); }
table.sheet input[type=checkbox] { width:auto; padding:0; margin:4px 8px; }
table.stmt-split { border-collapse:collapse; margin:6px 0 10px; }
table.stmt-split th, table.stmt-split td { border:1px solid var(--border); padding:2px 8px; font-size:var(--text-sm); }
table.stmt-split th { background:var(--surface-sunken); text-align:left; }
table.stmt-split td.num, table.stmt-split th.num { text-align:right; }
table.stmt-split tr.bank td { color:var(--status-info-fg); font-weight:600; }
.stmt-block h3 { margin:2px 0 6px; }
.stmt-tier { margin:8px 0; }
.stmt-tier b.cnt { background:var(--surface-sunken); border-radius:var(--radius-full); padding:0 7px; }
.rec-top .bar { margin:2px 0; }
#f-grid tr > th:first-child { border:none; background:none; }
#f-grid tfoot td:first-child { border:none; background:none; }
tr.grp { cursor:pointer; font-weight:600; }
tr.grp:hover td { background:var(--surface-sunken); }
/* S-60c (Jack, UI rule): every resize handle shows a slight VISIBLE line
   so the grab spot is findable - drawn INSIDE the th (the old border sat
   4px past the edge and clipped) */
th .rz { position:absolute; right:-3px; top:0; bottom:0; width:7px; cursor:col-resize; z-index:2;
         background:linear-gradient(var(--border-strong), var(--border-strong)) no-repeat 3px 50% / 1px 62%; }
th .rz:hover, th .rz.active { background:var(--brand); opacity:.35; }
body.resizing, body.resizing * { cursor:col-resize !important; user-select:none !important; }
td.num, th.num { text-align:right; font-variant-numeric:tabular-nums; }
tr.derived td { color:var(--status-warning-fg); font-style:italic; }
tr.rcl-soft td { background:var(--status-warning-bg); }   /* B5: behind soft close - editable, flagged */
tr.rcl-hard td { background:var(--surface-sunken); color:var(--text-muted); }  /* B5: hard-closed - locked */
/* S-30: @me badge takes MY staff-grid color (inline style at render);
   total badge is the primary fill (black in light, inverts in dark).
   display:inline-block stops a wrapping <a>'s underline from running
   under the badge. */
.fbadge { background:var(--status-danger-bg); color:var(--status-danger-fg); border-radius:var(--radius-full);
  padding:0 7px; font-size:var(--text-xs); font-weight:700; display:inline-block; text-decoration:none; }
.fbadge[style] { color:var(--text-on-solid); }
.fbadge2 { background:var(--btn-primary-bg); color:var(--btn-primary-text); border-radius:var(--radius-full);
  padding:0 7px; font-size:var(--text-xs); font-weight:700; display:inline-block; text-decoration:none; }
.fment { background:var(--status-neutral-fg); color:var(--text-on-solid); border-radius:var(--radius-full);
  padding:0 7px; font-size:var(--text-xs); font-weight:700; white-space:nowrap; }  /* 039: @mention badge */
.fdlb { border-radius:var(--radius-full); min-width:20px; padding:1px 5px; font-size:var(--text-xs);
  font-weight:700; display:inline-block; text-align:center; text-decoration:none; }  /* dashboard lookback badge */
.fdstuck { background:var(--status-warning-bg); color:var(--status-warning-fg); border-radius:var(--radius-full);
  padding:0 7px; font-size:var(--text-xs); font-weight:700; display:inline-block; }  /* dashboard stuck count */
.csmatch { background:var(--status-info-bg); color:var(--status-info-fg); border-radius:var(--radius-full);
  padding:0 7px; font-size:var(--text-xs); font-weight:700; display:inline-block; }  /* S-40: possible-match count (blue = informational) */
.csep { border:none; border-top:3px solid var(--border-strong); margin:12px 0; }  /* S-40: bold pane section break */
.rtwrap { border:1px solid var(--border-strong); border-radius:var(--radius-md); background:var(--surface); }
.rtbar { border-bottom:1px solid var(--border); padding:2px 4px; display:flex; gap:2px; }
.rtbar button { font-size:var(--text-xs); padding:1px 7px; }
.rted { padding:6px 9px; outline:none; overflow:auto; max-height:340px; }
.rted ul, .rtbody ul { margin:4px 0 4px 20px; }
.rted ol, .rtbody ol { margin:4px 0 4px 20px; }
.rtbody a { color:var(--text-link); }
.fdraghandle { cursor:grab; color:var(--text-muted); user-select:none; }
tr.fsec td { background:var(--surface-sunken); font-weight:700; padding:7px 9px;
  border-top:2px solid var(--border-strong); }      /* b9f: section rows in the ONE table */
table.fclose td { vertical-align:top; }
tr.fdone td { opacity:.62; }
/* batch3: long lists are the norm - virtualize rows like the JE grid */
#lgbody tr { content-visibility:auto; contain-intrinsic-block-size:auto 28px; }
#lst-pane-body tr { content-visibility:auto; contain-intrinsic-block-size:auto 26px; }
tr.total td { font-weight:700; border-top:2px solid var(--text-primary); }
tr.click { cursor:pointer; } tr.click:hover { background:var(--surface-sunken); }
.ok { color:var(--status-success-fg); } .warn { color:var(--status-danger-fg); }
@media (max-width:900px){ #pane.open { min-width:320px; } }

#signin { display:flex; flex-direction:column; align-items:center; gap:16px; padding:90px 0; }
#toast { position:fixed; bottom:18px; right:18px; background:var(--btn-primary-bg); color:var(--btn-primary-text);
padding:10px 12px 10px 16px; border-radius:var(--radius-md); font-size:var(--text-base); opacity:0; transition:opacity .3s;
z-index:2000; pointer-events:none; max-width:480px; display:flex; align-items:flex-start; gap:10px; }
#toast.show { opacity:1; pointer-events:auto; }
#toast .t-msg { user-select:text; -webkit-user-select:text; cursor:text; word-break:break-word; }
#toast button { background:transparent; color:inherit; border:1px solid currentColor; border-radius:var(--radius-sm);
padding:2px 8px; font-size:var(--text-sm); cursor:pointer; flex-shrink:0; }
#toast button:hover { background:var(--surface-overlay); }
#toast.warn { background:var(--btn-danger-bg-solid); color:var(--text-on-solid); }
.lgrid td { padding:1px 3px; } .lgrid input[type=text], .lgrid input[type=date] { width:100%; box-sizing:border-box; }
.lgrid .lgbtns button { border:none; background:none; cursor:pointer; padding:0 2px; }
.lgrid tr.lgoff td { opacity:.55; }   /* S-72 (Jack): inactive rows dim, never strike through */
.lgrid tr.lgsys td { background:var(--surface-sunken); }  /* batch3: system rows locked in view */
.lgrid tr.rowerr td { background:var(--status-danger-bg); }
th.sortable { cursor:pointer; user-select:none; }
th.sortable .sind { font-size:var(--text-xs); color:var(--text-muted); }
input.cmb.pendnew { color:var(--status-danger-fg); font-weight:600; }
input.cmb.bud-prop { color:var(--status-info-fg); font-style:italic; }   /* S-79: a combo pick that is a budget PROPOSAL (not yet a live list row) */
input.cmb.sim-flag { color:var(--status-danger-fg); text-decoration:underline dotted; }   /* S-80c: a budget item whose Allocation Function could not simulate (tooltip carries the flag) */
/* S-80c: Sheets-style fill handle on amount / estimate cells (drag to copy down or up the column) */
table.sheet td.fillcell { position:relative; }
table.sheet .fill-handle { position:absolute; right:-3px; bottom:-3px; width:7px; height:7px; background:var(--brand); border:1px solid var(--surface); cursor:crosshair; z-index:2; }
body.filling, body.filling * { cursor:crosshair !important; user-select:none; }
/* adjustable pane widths: plain drag handles, no collapsing (Jack's call) */
.vdrag { flex:0 0 5px; cursor:col-resize; background:var(--border); align-self:stretch; }
.vdrag:hover { background:var(--border-strong); }
/* compact table-style settings pane
   S-26: fixed layout so a long option label can never stretch the table
   past the pane (the closed select truncates; the popup shows full text).
   S-67 (Jack): generalized from #re-pane to EVERY left pane - contents fit
   the pane compactly instead of the pane chasing intrinsic widths. */
.fcol table.cfg { width:100%; border-collapse:collapse; table-layout:fixed; }
.fcol table.cfg select, .fcol table.cfg input:not([type=checkbox]) { max-width:100%; }
.fcol table.cfg td { padding:2px 3px; vertical-align:middle; }
/* S-68/S-69 (Jack): the label column is a CONSTANT width (wrapping when a
   label is long), so the fields' left edge NEVER drifts as the pane grows.
   Fixed table layout reads widths from the first row - panes that open with
   a colspan section title defeated a cell width, so cfgColFix() injects a
   colgroup and the width lives on the col. */
.fcol table.cfg col.cfg-label-col { width:110px; }
.fcol table.cfg td:first-child { white-space:normal; overflow-wrap:break-word; font-size:var(--text-sm); }
.fcol table.cfg td[colspan] { white-space:normal; width:auto; }
.fcol table.cfg select, .fcol table.cfg input[type=text],
.fcol table.cfg input[type=date], .fcol table.cfg input:not([type=checkbox]) {
  width:100%; box-sizing:border-box; }
#re-pane table.cfg select[multiple] { height:74px; }
/* S-67 (Jack): truncate mode is for DATA tables - it never clips the left
   pane's settings (the #view td cap above was forcing the pane wide) */
html[data-wrap="truncate"] #view .fcol td {
  white-space:normal; overflow:visible; text-overflow:clip; max-width:none; }
/* spreadsheet-style report grid: web display doubles as the excel preview */
table.regrid { border-collapse:collapse; font-size:var(--text-base); background:var(--surface); }
table.regrid th, table.regrid td { border:1px solid var(--border-strong); padding:2px 7px; }
table.regrid th { background:var(--surface-sunken); position:sticky; top:0; cursor:pointer;
user-select:none; white-space:nowrap; }
table.regrid td.num { text-align:right; font-variant-numeric:tabular-nums; }
table.regrid tr.tot td { border-top:2px solid var(--text-secondary); font-weight:600; }
table.regrid tr.sub td { font-weight:600; background:var(--surface-sunken); }
table.regrid tr.grp td { background:var(--surface-active); }
/* resize grab zone: absolute full-height strip on the header's right
 edge - float targets collapse when many columns squeeze the cells */
table.regrid th { position:sticky; }
table.regrid th .rz { position:absolute; right:0; top:0; bottom:0; width:8px;
cursor:col-resize; display:flex; align-items:center; justify-content:center;
color:var(--text-muted);
background:linear-gradient(var(--border-strong), var(--border-strong)) no-repeat center / 1px 62%; }
table.regrid th .rz:hover { background:var(--surface-active); color:var(--text-primary); }
table.regrid td.drill { cursor:pointer; }
table.regrid td.drill:hover { background:var(--surface-hover); text-decoration:underline; }
.rf-list { max-height:130px; overflow-y:auto; border:1px solid var(--border-strong); padding:2px 4px; }
.rf-list .rf-item { display:block; font-size:var(--text-sm); white-space:nowrap;
overflow:hidden; text-overflow:ellipsis; }


/* Spreadsheet entry grid (S-67): the ONE core the JE editor (#f-grid) and
   the client form grid (#f-lines) share - cells ARE the borders, inputs
   are invisible fills. Per-surface focus/total/default-row rules stay
   with their surfaces. */
.entry-grid { table-layout: fixed; width: 100%; }
.entry-grid td { padding: 0; border: 1px solid var(--border); }
.entry-grid input, .entry-grid select { width: 100%; box-sizing: border-box; border: 0;
  border-radius: 0; background: transparent; font: inherit; padding: 4px 6px; }

/* Open-item thread cards (S-66): a BOLD top rule separates threads; the
   ticket id badge rides the header. Closed threads dim as a whole card. */
.oi-card { border: 1px solid var(--border); border-top: 3px solid var(--border-strong);
  border-radius: var(--radius-md); padding: var(--space-2) var(--space-3); margin: var(--space-2) 0; }
.oi-card--closed { opacity: .65; }

/* pane-round additions to the chrome layer (S-65) */
.fcol--sm { flex: 0 0 150px; }
.fcol--md { flex: 0 0 210px; }
.fcol--lg { flex: 0 0 300px; }
.fcol-head { border-bottom: 2px solid var(--text-primary); padding-bottom: var(--space-2);
  margin-bottom: var(--space-2); font-weight: var(--weight-semi); }
.rf-list--short { max-height: 84px; }


/* =====================================================================
   CLIENT FORM PAGE (S-67) - relocated from form.html's own style block,
   which is DELETED (rule 3 now holds absolutely: the styleguide is the
   ONLY page with a <style> block). Every rule is scoped under .form-page
   (the form's <body> class) so nothing leaks into the staff app; the
   form was already fully tokenized (S-25/S-60).
   ===================================================================== */

/* =====================================================================
     CLIENT INTAKE FORM - RETOKENIZED (S-25, 2026-08-17).
     tokens.css + components.css load first; this block styles the form's
     own markup and consumes SEMANTIC TOKENS ONLY. Button tiers per
     UI-CONTRACT: .fsubmit = the page's one primary; default = secondary;
     .ghost = ghost. The 16px mobile input size is a functional iOS
     no-zoom threshold, not a type-scale value.
     ===================================================================== */
.form-page { font: var(--text-base)/var(--leading-base) var(--font-ui); margin: 0;
         background: var(--surface-sunken); color: var(--text-primary); }
.form-page .wrap { max-width: 1100px; margin: 0 auto; padding: 24px 16px 60px; }
.form-page.preview .wrap { padding: 8px 8px 20px; }
.form-page .card { background: var(--surface); border: 1px solid var(--border); border-radius: 8px; padding: 18px 20px; margin: 14px 0; }
.form-page h1 { font-size: var(--text-xl); margin: 8px 0; }
.form-page h2 { font-size: var(--text-lg); margin: 0 0 10px; }
.form-page label { display: block; margin: 10px 0 2px; font-weight: 600; font-size: var(--text-sm); }
.form-page input, .form-page select, .form-page textarea { font: inherit; padding: 6px 8px; border: 1px solid var(--border-strong);
    border-radius: var(--radius-sm); max-width: 100%; box-sizing: border-box;
    background: var(--surface); color: var(--text-primary); }
.form-page input[type=text], .form-page textarea { width: 100%; }
.form-page button { font: inherit; padding: 7px 14px; border-radius: var(--radius-md);
    border: 1px solid var(--btn-secondary-border); background: var(--btn-secondary-bg);
    color: var(--btn-secondary-text); cursor: pointer; }
.form-page button:hover { background: var(--btn-secondary-bg-hover); }
.form-page button.fsubmit { background: var(--btn-primary-bg); border-color: var(--btn-primary-bg); color: var(--btn-primary-text); }
.form-page button.fsubmit:hover { background: var(--btn-primary-bg-hover); }
.form-page button.ghost { background: transparent; border-color: transparent; color: var(--btn-ghost-text); }
.form-page button.ghost:hover { background: var(--btn-ghost-bg-hover); }
.form-page button[disabled] { opacity: .5; cursor: default; }
.form-page table { border-collapse: collapse; width: 100%; margin-top: 8px; }
.form-page th, .form-page td { border: 1px solid var(--border); padding: 5px 7px; text-align: left; font-size: var(--text-base); vertical-align: top; }
.form-page th { background: var(--surface-sunken); }
.form-page tr.ftotal td { background: var(--surface-sunken); font-weight: 600; border-top: 2px solid var(--border-strong); }
.form-page .muted { color: var(--text-secondary); font-size: var(--text-sm); }
.form-page .warn { color: var(--status-danger-fg); }
.form-page .ok { background: var(--status-success-bg); border-color: var(--status-success-fg); }
.form-page .propose { background: var(--surface-sunken); border: 1px dashed var(--border-strong); border-radius: var(--radius-md); padding: 6px 8px; margin-top: 4px; }
.form-page .num input { text-align: right; width: 90px; }
.form-page .lrow { display: flex; align-items: flex-start; }
.form-page .lcell { min-width: 0; padding: 0 7px; }
.form-page .lcell:first-child { padding-left: 0; }
.form-page .lcell:last-child { padding-right: 0; }
.form-page .info { cursor: help; color: var(--text-link); margin-left: 5px; font-weight: 400; font-size: var(--text-sm); }
.form-page .req { color: var(--status-danger-fg); margin-left: 2px; }
.form-page .lnote { background: var(--surface-sunken); border-left: 3px solid var(--border-strong); padding: 6px 10px; font-size: var(--text-sm); margin: 8px 0; }

/* --- staff edit mode --- */
.form-page.editing .lcell { outline: 1px dashed var(--border-strong); border-radius: var(--radius-md); position: relative; padding-top: 2px; }
.form-page.editing .lcell:hover { outline-color: var(--border-focus); background: var(--surface-hover); }
.form-page.editing .dragbar { cursor: grab; color: var(--text-muted); font-size: var(--text-xs); user-select: none; }
.form-page.editing .gearbtn { position: absolute; top: 0; right: 2px; cursor: pointer; color: var(--text-link);
    font-size: var(--text-xs); background: none; border: none; padding: 2px 4px; }
.form-page.editing .divider { flex: 0 0 10px; cursor: col-resize; display: flex; align-items: center;
    justify-content: center; color: var(--text-muted); user-select: none; }
.form-page.editing .rowgap { height: 12px; border-radius: var(--radius-sm); }
.form-page.editing .rowgap.hot { background: var(--surface-active); }
.form-page.editing [contenteditable="true"] { cursor: text; }
.form-page.editing [contenteditable="true"]:hover, .form-page.editing [contenteditable="true"]:focus { background: var(--status-warning-bg); outline: 1px solid var(--status-warning-fg); border-radius: 3px; }
.form-page.editing input, .form-page.editing select, .form-page.editing textarea, .form-page.editing #f-lines button, .form-page.editing #s-actions button { pointer-events: none; }
.form-page.editing .rowgap .addtext { pointer-events: auto; font-size: var(--text-xs); padding: 0 6px;
    background: var(--surface); color: var(--text-link); border: 1px dashed var(--border-focus); border-radius: var(--radius-sm);
    opacity: 0; transition: opacity .1s; }
.form-page.editing .rowgap:hover .addtext { opacity: 1; }
.form-page.editing th[data-col] { cursor: grab; }
.form-page.editing th[data-col="_rowbtns"] { cursor: default; }

/* S-57: sizable, not draggable */
.form-page.editing .gridtools { pointer-events: auto; }
.form-page .gridwrap { overflow-x: auto; -webkit-overflow-scrolling: touch; }
.form-page .neg { color: var(--status-danger-fg) !important; }
.form-page .defval {  }

/* header-tracked defaults read as normal entries (Jack) -
                   the class only marks cells still following the header */
.form-page .combo { position: relative; display: block; }
.form-page .combo > input { width: 100%; box-sizing: border-box; }

/* every field takes its whole cell, like Memo - date, payee, all of them */
.form-page .lcell > input:not([type=checkbox]), .form-page .lcell select, .form-page .lcell > span > .combo > input, .form-page .gfield:not([type=checkbox]) { width: 100%; box-sizing: border-box; }
.form-page #f-hcon-host, .form-page #g-funder-host { display: block; }
.form-page .combolist { position: fixed; z-index: 40; background: var(--surface-raised);
    border: 1px solid var(--border-strong); border-radius: 0 0 6px 6px; max-height: 180px; overflow-y: auto;
    box-shadow: var(--shadow-md); }
.form-page .combolist div { padding: 5px 8px; cursor: pointer; }
.form-page .combolist div:hover, .form-page .combolist div.hot { background: var(--surface-hover); }
.form-page .ccard { border: 1px dashed var(--status-info-fg); border-radius: var(--radius-md); padding: 8px 10px; margin-top: 6px;
    background: var(--surface-hover); display: flex; flex-wrap: wrap; gap: 6px 14px; align-items: flex-end; }
.form-page .ccard b { font-size: var(--text-sm); }
.form-page .ccard .cctitle { flex: 1 1 100%; }
.form-page .ccard .cf { flex: 1 1 200px; min-width: 160px; }
.form-page .ccard .cf input, .form-page .ccard .cf select { width: 100%; }
.form-page .cfnow { display: block; font-size: var(--text-xs); }
.form-page tr.cardrow > td { background: none; border-left: 0; border-right: 0; }
.form-page th .thdiv { position: absolute; top: 0; right: -5px; width: 10px; height: 100%; cursor: col-resize;
    
/* S-60c UI rule: a slight visible line marks every grab spot */
    background: linear-gradient(var(--border-strong), var(--border-strong)) no-repeat 5px 50% / 1px 62%; }

/* S-60: static inline styles retired to classes (UI-CONTRACT rule 3);
     the only style="" left in templates carries COMPUTED values (column
     widths, cell flex weights from the saved design). */
.form-page #f-lines th { position: relative; }
.form-page #f-lines th .gearbtn { position: static; }
.form-page .gridtools { margin: var(--space-1) 0; }
.form-page label.plain { font-weight: 400; }
.form-page #f-hamt { text-align: right; width: 100%; }
.form-page #f-hdue { width: 100%; }
.form-page .form-logo { max-height: 52px; max-width: 180px; object-fit: contain; float: right; }

/* spreadsheet, not bubbles: cells ARE the borders; inputs are invisible fills */
.form-page #f-lines td:focus-within { outline: 2px solid var(--border-focus); outline-offset: -2px; }
.form-page #f-lines td.rowbtns { border-left: 0; border-top: 0; border-bottom: 0; background: none;
    white-space: nowrap; text-align: center; }
.form-page #f-lines td.rowbtns button { border: 0; background: none; padding: 0 1px; font-size: var(--text-xs);
    cursor: pointer; opacity: .35; width: auto; }
.form-page #f-lines tr:hover td.rowbtns button { opacity: 1; }
.form-page #fillHandle { position: absolute; width: 9px; height: 9px; background: var(--brand);
    border: 1px solid var(--surface); cursor: ns-resize; z-index: 5; }
.form-page tr.ftotal td.num, .form-page #f-total { text-align: right; }
.form-page #f-delta { text-align: right; margin: 2px 0 0; }
.form-page a { color: var(--text-link); }
@media (max-width: 640px) {
  .form-page .wrap { padding: 12px 8px 40px; }
  .form-page .lrow { flex-direction: column; }
  .form-page .lcell { padding: 0 !important; flex: 1 1 auto !important; width: 100%; }
  .form-page input, .form-page select, .form-page textarea, .form-page button { font-size: 16px; }
  
/* stops iOS zoom */
}
.form-page .editcap { font-size: 11.5px; color: var(--text-muted); margin: 2px 0 6px; }
.form-page .editcap__txt { border-bottom: 1px dashed currentColor; cursor: text; }
