/* =============================================================================
   TABLES.CSS — the shared mobile table pattern library.

   The house patterns every data table migrates onto. Spec, decision tree and
   rollout order: docs/MOBILE_CSS_ROLLOUT.md §2. Standard: docs/MOBILE_UX.md §5.

   Pick with the decision tree — do NOT fork a new wrapper prefix per table:
     A  .tbl-wrap [--pin]   scroll wrapper (+ sticky first column)
     B  .tbl-col--sec       priority columns — secondary ones drop at <=768px
     C  .tbl--cards         stacked labelled rows
     D  .tbl-disc           summary-first <details>
     E  (nothing)           <=3 short columns; add overflow-wrap and stop

   Tokens only, 0 radius, sanctioned breakpoints only. Existing compliant
   wrappers (.hcf-wrap, .cm-table-wrap, .pj-wrap, .cf-scroll-wrap,
   .cov-borough-wrap) are already-correct Pattern A instances — they are NOT
   renamed; new and migrated tables use tbl-*.
   ============================================================================= */
@layer components {

/* ── A. Scroll wrapper ─────────────────────────────────────────────────────
   For analytical cross-tabs the user COMPARES across. Wraps a real <table> —
   never `display:block` the table itself, which strips its implicit ARIA roles
   and makes sticky columns impossible. */
.tbl-wrap {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  border: 1px solid var(--c-rule);
  background: var(--c-white);
  max-width: 100%;
}
.tbl-wrap > table {
  width: 100%;
  border-collapse: collapse;
}
/* Numeric cells never wrap: they set the table's natural min-width, which is
   what makes the WRAPPER scroll instead of the page. */
.tbl-num {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  text-align: right;
}

/* ── A+. Pinned first column — row identity survives the scroll ─────────── */
.tbl-wrap--pin th.tbl-pin,
.tbl-wrap--pin td.tbl-pin {
  position: sticky;
  left: 0;
  z-index: 1;
  background: var(--c-bone);
  /* Borders scroll away under a sticky cell; this hairline does not. Same
     device as .hcf-table td.label. */
  box-shadow: 1px 0 0 var(--c-rule);
  /* Guarantee the next column always peeks — the clipped column IS the scroll
     affordance (gradient fades are not in the visual language). */
  max-width: 45vw;
  overflow-wrap: anywhere;
}
.tbl-wrap--pin thead th.tbl-pin { z-index: 2; }

/* ── D. Summary-first disclosure ───────────────────────────────────────────
   For secondary/embedded evidence, or >8 columns with no priority order.
   Composes with A or C inside. The CLOSED state must still inform — put real
   aggregates in .tbl-disc__stat, never a bare heading. */
.tbl-disc {
  border: 1px solid var(--c-rule);
  background: var(--c-white);
  margin-bottom: var(--space-4);
}
.tbl-disc > summary {
  list-style: none;
  cursor: pointer;
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-4);
  padding: var(--space-3) var(--space-4);
  min-height: 44px;              /* it is a tap target (MOBILE_UX §3) */
}
.tbl-disc > summary::-webkit-details-marker { display: none; }
.tbl-disc__title {
  font-size: var(--text-2xs);
  font-weight: var(--weight-semibold);
  text-transform: uppercase;
  letter-spacing: var(--tracking-wide);
  color: var(--c-muted);
}
.tbl-disc__stat {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-size: var(--text-sm);
  color: var(--c-ink);
}
.tbl-disc__chevron {
  color: var(--c-pale);
  transition: transform var(--transition-fast);
}
.tbl-disc[open] > summary { border-bottom: 1px solid var(--c-rule); }
.tbl-disc[open] > summary .tbl-disc__chevron { transform: rotate(90deg); }
.tbl-disc > .tbl-wrap { border: 0; }   /* inner wrapper inherits the frame */


/* ══ PHONE (<=768px) ═══════════════════════════════════════════════════════
   B and C are mobile transforms: above the phone line these tables render as
   ordinary ledgers, untouched. */
@media (max-width: 768px) {

  /* ── B. Priority columns ────────────────────────────────────────────────
     Tag the <th> AND every <td> of a secondary column. A dropped column must
     never be the only home of a fact — the row must link somewhere that has
     it. Keep <=4 visible columns. */
  .tbl-col--sec { display: none; }
  /* Kept columns absorb the overflow the dropped ones no longer take. */
  .tbl-keep { overflow-wrap: anywhere; }
  /* A fixed column plan is meaningless once columns drop. */
  .tbl--relax { table-layout: auto; }
  .tbl--relax colgroup col { width: auto; }

  /* ── C. Card rows ───────────────────────────────────────────────────────
     Each row becomes a labelled block. Labels come from data-label via
     generated content — chosen over duplicated mobile markup (two render
     paths for one dataset) and per-table grid re-layout (unbounded CSS).
     Note: any display change on table elements drops implicit ARIA table
     roles — the mobile rendering IS a list of labelled blocks. Where genuine
     table semantics matter, add explicit role="table|row|cell". */
  .tbl--cards { border: 0; background: transparent; }
  .tbl--cards,
  .tbl--cards tbody,
  .tbl--cards tr,
  .tbl--cards td { display: block; }
  .tbl--cards thead { display: none; }    /* labels moved into the cells */

  .tbl--cards tr {
    background: var(--c-white);
    border: 1px solid var(--c-rule);
    margin-bottom: var(--space-3);
  }

  .tbl--cards td {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: var(--space-4);
    padding: 10px var(--space-4);
    border-bottom: 1px solid var(--border-subtle);
    font-size: var(--text-sm);
    color: var(--c-ink);
  }
  .tbl--cards tr > td:last-child { border-bottom: 0; }

  .tbl--cards td::before {
    content: attr(data-label);
    font-size: var(--text-2xs);
    font-weight: var(--weight-semibold);
    text-transform: uppercase;
    letter-spacing: var(--tracking-wide);
    color: var(--c-muted);
    flex-shrink: 0;
  }

  /* The row's subject cell is the card header. */
  .tbl--cards .tbl-card-head {
    display: block;
    padding: var(--space-3) var(--space-4);
    font-size: var(--text-base);
    font-weight: var(--weight-medium);
    border-bottom: 1px solid var(--c-rule);
  }
  .tbl--cards .tbl-card-head::before { content: none; }

  /* An empty cell drops the whole label/value pair — no orphan labels.
     :empty is whitespace-sensitive: render such cells with nothing inside the
     tag, e.g. <td data-label="X">{{ v|default:"" }}</td> on one line. */
  .tbl--cards td:empty { display: none; }

  /* Row actions get a full-width row of real tap targets — this is how a
     dense row honestly reaches 44px (MOBILE_UX §3). */
  .tbl--cards .tbl-card-actions { justify-content: flex-end; gap: var(--space-2); }
  .tbl--cards .tbl-card-actions::before { content: none; }
  .tbl--cards .tbl-card-actions .action-btn,
  .tbl--cards .tbl-card-actions .table-btn { min-height: 44px; }
}

}  /* end @layer components */