/* --- Data table: stacked cards on phones, a real table from 1024px ------ */
.listwrap { border-radius: var(--r-lg); overflow: hidden; box-shadow: var(--shadow-xs); }
.tablewrap { border: 1px solid var(--rule); border-top: 0; background: var(--surface); }
/* Nothing follows it — a pager would otherwise close the stack. */
.tablewrap--closed { border-radius: 0 0 var(--r-lg) var(--r-lg); }
/* Inside a panel the panel IS the frame. Without this the wrap draws a second
   border a pixel inside the first, and squares off the rounded corner behind
   it. The head's own bottom rule already separates the table from what is
   above it. */
.panel .tablewrap { border: 0; }

table.data { width: 100%; border-collapse: collapse; font-size: var(--t-13); }
table.data thead { display: none; }
table.data tbody, table.data tr, table.data td { display: block; }
table.data tr { padding: var(--s-4) var(--s-5); border-bottom: 1px solid var(--rule); }
table.data tr:last-child { border-bottom: 0; }
table.data tr[aria-selected="true"] { background: var(--accent-weak); }
table.data td {
  display: flex; align-items: baseline; justify-content: space-between; gap: var(--s-5);
  padding: var(--s-2) 0; text-align: right;
}
table.data td::before {
  content: attr(data-label);
  font: 800 10px/1.4 var(--font-ui); letter-spacing: .08em; text-transform: uppercase;
  color: var(--ink-muted); text-align: left; flex: none;
}
table.data td:empty { display: none; }
/* Secondary columns are dropped from the phone card so a row stays scannable;
   they return as columns once there is a table to put them in. */
table.data .col-secondary { display: none; }
/* The identifier leads the card; the checkbox and actions frame it. */
table.data td.id { font-family: var(--font-num); font-size: var(--t-13); font-weight: 600; color: var(--ink); }
table.data td.checkcol { justify-content: flex-start; padding-bottom: var(--s-3); }
table.data td.checkcol::before { content: none; }
table.data td.act { justify-content: flex-end; padding-top: var(--s-3); border-top: 1px solid var(--rule); margin-top: var(--s-3); }
table.data td.act::before { content: none; }

@media (min-width: 1024px) {
  .listwrap .toolbar { border-radius: 0; }
  .tablewrap { overflow: auto; max-height: 440px; }
  /* A list that IS the page fills the window instead of stopping at 440px and
     leaving the rest of a tall screen empty. `:has(> .tablewrap)` picks out
     exactly that case and leaves the ones nested inside a panel — the import
     preview, a scheme level, the staff record — on the fixed cap, where they
     are one section among several rather than the whole screen.
     The siblings are held at their natural height so only the table absorbs
     what is left; 240px is the floor, below which a list is not worth
     scrolling inside. */
  main:has(> .tablewrap) { display: flex; flex-direction: column; }
  main:has(> .tablewrap) > * { flex: none; }
  main:has(> .tablewrap) > .tablewrap { flex: 1 1 0; min-height: 240px; max-height: none; }
  /* A table that IS the form rather than a list of results — the import's
     column mapping — must not sit in a scroll box: every row needs answering,
     and half of them being below an inner fold reads as a cut-off page. */
  .tablewrap--full { max-height: none; overflow: visible; }
  table.data { border-collapse: separate; border-spacing: 0; }
  table.data thead { display: table-header-group; }
  table.data tbody { display: table-row-group; }
  table.data tr { display: table-row; padding: 0; }
  table.data td { display: table-cell; }
  table.data .col-secondary { display: table-cell; }
  table.data th.col-secondary { display: table-cell; }
  /* Vertical padding, not just a row height: --row-h is the floor for a
     single-line row, and a cell holding two lines grows past it rather than
     crushing them together. */
  table.data th, table.data td {
    padding: var(--s-4) var(--s-6); height: var(--row-h);
    border-bottom: 1px solid var(--rule); text-align: left; white-space: nowrap;
  }
  table.data td::before { content: none; }
  table.data thead th {
    position: sticky; top: 0; z-index: 3;
    background: var(--surface-sunk); color: var(--ink-muted);
    font: 800 10px/1 var(--font-ui); letter-spacing: .1em; text-transform: uppercase;
    border-bottom: 1px solid var(--rule-strong);
  }
  table.data thead th.sortable { cursor: pointer; }
  table.data thead th.sortable:hover { color: var(--ink); }
  table.data thead th .arrow { color: var(--c-teal); margin-left: 3px; }
  table.data td.n, table.data th.n { text-align: right; }
  table.data td.id { font-size: var(--t-12); font-weight: 400; color: var(--ink-muted); }
  table.data tbody tr:hover td { background: var(--surface-sunk2); }
  table.data tbody tr[aria-selected="true"] { background: none; }
  table.data tbody tr[aria-selected="true"] td { background: var(--accent-weak); }
  table.data tbody tr:last-child td { border-bottom: 0; }
  table.data .freeze { position: sticky; left: 0; background: var(--surface); z-index: 2; }
  table.data thead .freeze { z-index: 4; background: var(--surface-sunk); }
  table.data tbody tr:hover .freeze { background: var(--surface-sunk2); }
  table.data tbody tr[aria-selected="true"] .freeze { background: var(--accent-weak); }
  table.data td.checkcol, table.data td.act { padding-top: 0; padding-bottom: 0; border-top: 0; margin-top: 0; }
  table.data td.act { text-align: right; padding-right: var(--s-4); }
  .checkcol { width: 38px; padding-right: 0 !important; }
  table.data .fill { width: 100%; }
}

/* Checkbox and radio share one language: an outlined box or circle that fills
   teal and shows a white mark when checked. The mark is a properly stroked
   tick with round caps, masked in, rather than a clip-path wedge. */
input[type=checkbox], input[type=radio] {
  appearance: none; -webkit-appearance: none;
  width: 18px; height: 18px; margin: 0; flex: none;
  border: 1.5px solid var(--rule-strong);
  background: var(--surface);
  display: inline-grid; place-content: center; cursor: pointer;
  vertical-align: -4px;
  transition: background var(--dur-fast), border-color var(--dur-fast);
}
input[type=checkbox] { border-radius: var(--r-sm); }
input[type=radio]    { border-radius: 50%; }
input[type=checkbox]:hover, input[type=radio]:hover { border-color: var(--c-teal); }

input[type=checkbox]::before, input[type=radio]::before {
  content: ""; background: #fff; transform: scale(0);
  transition: transform var(--dur-fast) var(--ease-out);
}
input[type=checkbox]::before {
  width: 13px; height: 13px;
  -webkit-mask: var(--tick) center / contain no-repeat;
          mask: var(--tick) center / contain no-repeat;
}
input[type=radio]::before { width: 6px; height: 6px; border-radius: 50%; }

input[type=checkbox]:checked, input[type=radio]:checked {
  background: var(--c-teal); border-color: var(--c-teal);
}
input[type=checkbox]:checked::before, input[type=radio]:checked::before { transform: scale(1); }
input[type=checkbox]:disabled, input[type=radio]:disabled { opacity: .45; cursor: not-allowed; }

/* Sorting is a link, not JS: a client-side sort reorders the table but still
   exports the original order, and the export is what staff act on. The anchor
   must read as the heading, not as a link. */
table.data thead th.sortable a {
  color: inherit; text-decoration: none; display: inline-flex; align-items: center;
}
table.data thead th.sortable a:hover { color: var(--ink); text-decoration: underline; }

/* A cell whose value is two lines — an identifier and the thing it names.
   Laid out explicitly rather than left to inline flow: the phone card makes a
   td a flex row, so an unwrapped `code<br>title` puts the title beside the code
   instead of under it, and the desktop row crushes both into --row-h. */
table.data td .cellstack { display: flex; flex-direction: column; gap: var(--s-2); align-items: flex-end; }
table.data td .cellstack__line { display: flex; align-items: center; flex-wrap: wrap; gap: var(--s-3); justify-content: flex-end; }
table.data td .cellstack small {
  color: var(--ink-muted); font-size: var(--t-12); line-height: 1.35;
  white-space: normal;
}

/* For a cell holding a list or a phrase rather than a value. Wrapping is what
   keeps one long cell from widening the table until the last column scrolls
   out of reach. */
table.data td.wrap, table.data th.wrap { white-space: normal; }

@media (min-width: 1024px) {
  table.data td .cellstack,
  table.data td .cellstack__line { align-items: flex-start; justify-content: flex-start; }
  table.data td .cellstack { max-width: 34ch; }
  table.data td.wrap { max-width: 30ch; line-height: 1.4; }
}
