/* Shared tables, list surfaces, and row interactions. */

.table-wrapper {
  display: block;
  width: 100%;
  overflow: auto hidden;
  -webkit-overflow-scrolling: touch;
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
}

.stat-row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  margin-bottom: var(--space-4);
}

.table-surface > .helper-text,
.table-surface > .form-actions,
.table-surface > .stat-row,
.table-surface > .surface-meta {
  padding-left: 1.2rem;
  padding-right: 1.2rem;
}

.table-surface .filter-bar {
  margin: 0;
  border: 0;
  border-bottom: 1px solid var(--app-border-default);
  border-radius: 0;
  box-shadow: none;
  background: var(--app-surface-subtle);
}

.table-surface .table-wrapper {
  border-radius: 0;
  box-shadow: none;
}

.table-surface .surface-meta {
  color: var(--app-text-muted);
  font-size: 0.875rem;
  padding: 0.85rem var(--space-4) 0;
}

.stat-pill {
  background: var(--app-surface-panel);
  border: 1px solid var(--app-border-default);
  border-radius: 999px;
  padding: 0.45rem 0.8rem;
  box-shadow: var(--shadow-sm);
  font-size: 0.85rem;
}

table {
  width: 100%;
  border-collapse: collapse;
  background: var(--app-surface-panel);
}

/* Canonical data-table header (UI-consistency pass, 2026-05-28): one light
   header treatment across EVERY data table instead of the legacy heavy
   dark-teal bar that only survived on tables nobody had restyled. Light
   surface + muted uppercase micro-caps + a crisp 2px divider reads as a
   refined, data-dense admin header and matches the labor-by-day table that
   had already moved off the teal. Sort-link/indicator colors below are
   re-pointed to dark text to stay legible on the light header. */
thead {
  background: var(--app-surface-subtle);
}

thead th {
  background: var(--app-surface-subtle);

  /* J03 (M-13): muted-gray was 4.36:1 on the light thead (just under AA) on
     every list; --app-text-strong = 14.33:1. Background stays light (G01). */
  color: var(--app-text-strong);
  font-size: 0.78rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  padding: 0.6rem 0.85rem;
  text-align: left;
  white-space: nowrap;
  border-bottom: 2px solid var(--app-border-default);
}

thead th.numeric,
td.numeric {
  text-align: right;
  font-variant-numeric: tabular-nums;
}

thead th:first-child {
  border-top-left-radius: var(--radius);
}

thead th:last-child {
  border-top-right-radius: var(--radius);
}

.table-sort-link {
  color: inherit;
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  text-decoration: none;
}

.table-sort-link:hover {
  color: var(--app-brand-700);
  text-decoration: none;
}

.table-sort-link.is-current {
  color: var(--app-text-strong);
}

.table-sort-indicator {
  color: var(--app-text-muted);
  font-size: 0.72rem;
  line-height: 1;
  opacity: 1;
}

tbody tr {
  border-bottom: 1px solid var(--app-border-default);
  border-left: 3px solid transparent;
}

.clickable-row {
  cursor: pointer;
}

/* J05 (P2-1): onclick-only rows have no keyboard/AT path. Mirroring the
   jobs-list precedent, the primary cell carries a real <a> so the detail page
   is reachable by Tab/Enter and screen readers; the row onclick stays as a
   mouse convenience. The link is styled to inherit the cell text so the table
   looks unchanged. */
.cell-detail-link {
  color: inherit;
  text-decoration: none;
}

.cell-detail-link:hover,
.cell-detail-link:focus-visible {
  text-decoration: underline;
}

/* F06: layered into app.tables (ranks below app.jobs) and de-!important'd so
   the jobs status row tints win by LAYER precedence, not an !important arms
   race. This generic hover is the ONLY rule the jobs tints' old !important
   defended against. Other tables have no row-tint rules (grep-verified), so
   de-!importanting here is safe; a selected row's own bg (.table-row-selected,
   still !important) now correctly survives hover. */
@layer app.tables {
  tbody tr:hover {
    background: var(--app-surface-subtle);
  }
}

.table-row-selected {
  background: var(--app-surface-selected) !important;
  border-left-color: var(--app-brand-600);
}

.row-actions {
  white-space: nowrap;
}

.table-empty {
  text-align: center;
  padding: var(--space-6);
  color: var(--app-text-muted);
}

td {
  padding: 0.52rem 0.85rem;
  font-size: 0.9rem;
  vertical-align: middle;
}

@media (width <= 768px) {
  .table-wrapper table {
    width: max-content;
    min-width: 100%;
  }
}

/* v1.13.0 R83 (TR-092): "not charged if not approved. should be highlighted
 * though, so it can be seen easily." Time past 8h on a job without OT
 * approval — worked, never charged. */
.labor-unapproved-overage {
  background: var(--app-warning-bg);
  color: var(--app-warning-fg);
}

a.stat-pill.labor-unapproved-overage {
  border: 1px solid var(--app-warning-border);
  text-decoration: none;
}

/* R72 (TR-090): the job's one lead, marked in the day's worker table. */
.labor-lead-tag {
  margin-left: var(--space-1);
  padding: 0 var(--space-1);
  border: 1px solid var(--app-border);
  border-radius: 4px;
  font-size: 0.75rem;
}

/* R70: why this worker has overtime — the day in time order. */
.labor-ot-reason summary {
  cursor: pointer;
  font-size: 0.8rem;
}

.labor-ot-reason ul {
  margin: var(--space-1) 0 0;
  padding-left: var(--space-4);
  font-size: 0.8rem;
}
