/* ── Shared data tables ─────────────────────────────────────────
   The app-wide table component (.data-table + .data-table-wrap), used by
   index/list views across features (invoices, cashbook, donor invoices,
   controlling, budget lines, ToRs, bank, admin…). Promoted here from
   invoices.css so features don't depend on an unrelated feature file.
   Loads right after base.css; feature files add their own column widths and
   row accents on top (e.g. controlling.css, cashbook.css). */

.data-table-wrap {
  width: 100%;
  /* overflow-x: auto already makes overflow-y compute to auto, so this wrap
     is a scroll container in both axes. Bound its height so it actually
     scrolls internally — that's what lets the sticky header (top: 0, below)
     pin to the top of the visible rows instead of scrolling away with the
     page. Short tables never reach the cap, so they don't gain a scrollbar. */
  overflow: auto;
  max-height: calc(100vh - var(--nav-height) - 3rem);
}

.data-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.9rem;
}

.data-table thead th {
  text-align: left;
  padding: 0.75rem 1rem;
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--gray-mid);
  background: var(--surface-muted);
  border-bottom: 1px solid var(--gray-light);
  white-space: nowrap;
  /* The opaque background above keeps body rows from bleeding through the
     sticky header; z-index stays under the nav (100). */
  position: sticky;
  top: var(--nav-height);
  z-index: 2;
}

/* Inside a .data-table-wrap the table scrolls within that container, so the
   header pins to the container's top, not below the page-level nav. */
.data-table-wrap .data-table thead th {
  top: 0;
}

/* Row-action column: keep the table's natural column spacing untouched and
   right-justify the (inline-flex) .icon-actions group within the last column. */
.data-table .col-actions {
  white-space: nowrap;
  text-align: right;
}

.data-table thead th a {
  color: inherit;
  text-decoration: none;
}

.data-table thead th a:hover {
  color: var(--gray-dark);
}

.data-table thead th a.asc::after  { content: " ↑"; }
.data-table thead th a.desc::after { content: " ↓"; }

/* Client-side sortable headers (table_sort_controller): clickable, with a dim
   caret that resolves to a solid arrow on the active column. Distinct from the
   Ransack sort_link styling above (a.asc/a.desc), which is server-side sorting
   on index views; this applies where the sorted values are computed in Ruby
   (donor-invoice line items, the Management project table, the controlling
   tables, the budget-lines index). The controller makes these headers
   focusable, so they need a focus ring like any other control. */
.data-table th[data-sortable] {
  cursor: pointer;
  user-select: none;
}
.data-table th[data-sortable]:focus-visible {
  outline: 2px solid var(--teal);
  outline-offset: -2px;
}
.data-table th[data-sortable]::after {
  content: " ↕";
  color: var(--gray-mid);
  opacity: 0.4;
}
.data-table th.is-sorted-asc::after  { content: " ↑"; opacity: 1; }
.data-table th.is-sorted-desc::after { content: " ↓"; opacity: 1; }

.data-table tbody td {
  padding: 0.85rem 1rem;
  color: var(--gray-dark);
  vertical-align: middle;
  border-bottom: 1px solid var(--divider);
}

.data-table tbody tr:last-child td {
  border-bottom: none;
}

.data-table tbody tr:hover {
  background: var(--surface-muted);
}

.data-table tbody tr[data-controller~="row-link"] {
  cursor: pointer;
}

/* Totals row at the foot of a table. tfoot cells inherit no padding from the
   tbody rule above, so give the row its own band: real padding, a firm top
   rule separating it from the data, and a tinted background. */
.data-table tfoot .totals-row td {
  padding: 1rem;
  border-top: 2px solid var(--gray-mid);
  background: var(--surface-muted);
  font-weight: 700;
  font-size: 0.9rem;
}

.data-table .col-amount {
  text-align: right;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.data-table .col-date {
  white-space: nowrap;
  color: var(--gray-mid);
}

/* Record identifiers (e.g. the LERF ZIP reference) — compact, secondary, never wrap. */
.data-table .col-id {
  white-space: nowrap;
  color: var(--gray-mid);
  font-variant-numeric: tabular-nums;
  font-size: 0.85rem;
}

.data-table .cell-title a {
  color: var(--gray-dark);
  font-weight: 600;
  text-decoration: none;
}

.data-table .cell-title a:hover {
  color: var(--teal);
  text-decoration: underline;
}

/* As a table cell, `.empty-state` loses its colour to the more specific
   `.data-table tbody td` rule above, so restate it for that case. */
.data-table tbody td.empty-state {
  color: var(--gray-mid);
}

/* The empty branch of a list/table view: the muted "nothing here yet"
   paragraph rendered where the rows would be. */
.empty-state {
  font-size: 0.9rem;
  color: var(--gray-mid);
  font-style: italic;
}

/* Deliverables table with in-cell inputs: the approval form and the admin
   approval type's default deliverables. */
.deliverables-table { min-width: 640px; }
.deliverables-table td { vertical-align: middle; }
.deliverables-table .cell-input {
  width: 100%;
  padding: 0.45rem 0.6rem;
  border: 1px solid var(--border-input);
  border-radius: 4px;
  font-family: inherit;
  font-size: 0.85rem;
  color: var(--gray-dark);
  background: var(--white);
}
.deliverables-table .cell-input:focus { outline: none; border-color: var(--teal); box-shadow: 0 0 0 3px rgba(0, 153, 153, 0.12); }
.deliverables-table .cell-input--num { text-align: right; font-variant-numeric: tabular-nums; }
.deliverables-col-qty { width: 7rem; }
.deliverables-col-days { width: 12rem; }
.deliverables-col-actions { width: 3rem; text-align: right; }
.deliverables-col-actions .btn-remove-line-item { margin-top: 0; }
.deliverables-days { display: flex; align-items: center; gap: 0.35rem; }
.deliverables-days .cell-input--num { width: 5rem; }
.deliverables-plus,
.deliverables-unit { color: var(--gray-mid); font-size: 0.82rem; }
.deliverables-table + .btn,
.data-table-wrap + template + .btn { margin-top: 0.75rem; }
