@layer components {
/* static/css/tables.css
 * Shared admin list-page layout — table controls header, search input, filter panel.
 * Used by all admin pages with the blue header + filter strip pattern.
 */

/* Always-visible filter strip below the search bar */
.filters-panel-visible {
    background-color: var(--filter-panel-bg);
    border-top: 1px solid var(--table-control-border);
    padding: 1rem 1.5rem;
}

/* Clickable table rows — add .table-clickable to the table or a wrapper */
.table-clickable tbody tr {
    cursor: pointer;
    transition: background-color 0.15s ease;
}
.table-clickable tbody tr:hover {
    background-color: var(--table-row-hover);
}

/* ═════════════════════════════════════════════════════════════════════════
   THE TABLE LAYER — tokens + five classes
   ═════════════════════════════════════════════════════════════════════════

   Everything above styles the chrome AROUND a list (search strip, filters).
   This section styles the table itself, replacing the ad-hoc mix of
   `table-sm` / `table-borderless` / `table-striped` spread across 98 tables
   that produced three different cell font sizes on four pages
   (9.6 / 10.5 / 12px) and rows ranging 25-55px tall.

   Rationale and sources: plans/ui-revamp/RESEARCH-RESULTS-table-design.md.
   Deliberately NOT a vendored theme — Tabler and friends are whole admin
   themes with their own CSP surface and upgrade burden. This is ~120 lines.

   Nothing here applies until a table opts in with `.table-dense`, so adding
   it changes no page. */

:root {
    /* Desktop: the dense layer. 28px rows sit between Carbon's xs (24) and
       sm (32) and fit a 13px/1.35 line plus 4px padding — ~28-30 rows in a
       900px area against ~18 at a 48px "comfortable" height. */
    --tbl-row-h: 28px;
    --tbl-cell-pad-y: 4px;
    --tbl-cell-pad-x: 8px;        /* 8px a side = Primer's >=16px between columns */

    /* 13px body, 12px hard floor. Apple HIG: "never smaller than 11 points";
       Material's smallest is 11sp; Primer's is 12px. The 9.6px this replaces
       is below all of them — and expertise does not raise visual acuity:
       familiarity speeds recognition of known layouts, not resolution of
       small glyphs. */
    --tbl-font-size: 13px;
    --tbl-font-size-min: 12px;
    --tbl-line-height: 1.35;

    --tbl-header-size: 12px;      /* a step down is fine because it is SemiBold */
    --tbl-header-weight: 600;

    --tbl-border-color: var(--table-border);
    --tbl-border-width: 1px;
    --tbl-hover-bg: var(--table-hover-bg);
    --tbl-selected-bg: var(--action-accent-subtle);

    /* Zebra OFF. Enders' two studies (OZCHI 2007 n=244; 2008 timed n=2,276)
       found "no statistically significant improvement in accuracy — and very
       little statistically significant improvement in speed". Its cost is
       real at this density: a tint on every other row competes with the hover
       tint that carries meaning. Carbon's rule then applies — no zebra means
       rows must have dividers. */
    --tbl-text: var(--content-text);
    --tbl-text-muted: var(--content-text-subtle);
}

/* Density follows the POINTER, not the width (DECISIONS.md D11): a touch
   tablet at 1024px needs comfortable targets despite having desktop room. */
@media (any-pointer: coarse) {
    :root {
        --tbl-row-h: 44px;        /* WCAG 2.5.5 primary-target size */
        --tbl-cell-pad-y: 10px;
        --tbl-cell-pad-x: 12px;
        --tbl-font-size: 16px;    /* >=16px also stops iOS zooming on focus */
        --tbl-header-size: 14px;
    }
}

/* ── 1. .table-dense — the core class ─────────────────────────────────── */
.table-dense {
    width: 100%;
    color: var(--tbl-text);
    font-size: max(var(--tbl-font-size), var(--tbl-font-size-min));
    line-height: var(--tbl-line-height);
    border-collapse: collapse;
}
.table-dense > thead > tr > th {
    font-size: var(--tbl-header-size);
    font-weight: var(--tbl-header-weight);
    text-transform: none;         /* all-caps costs legibility on long labels */
    color: var(--tbl-text-muted);
    text-align: left;
    padding: var(--tbl-cell-pad-y) var(--tbl-cell-pad-x);
    border-bottom: var(--tbl-border-width) solid var(--tbl-border-color);
    white-space: nowrap;
    background: var(--table-head-dense-bg);
    letter-spacing: .01em;
}
.table-dense > tbody > tr > td {
    height: var(--tbl-row-h);
    padding: var(--tbl-cell-pad-y) var(--tbl-cell-pad-x);
    border-bottom: var(--tbl-border-width) solid var(--tbl-border-color);
    vertical-align: middle;
}
.table-dense > tbody > tr {
    transition: background-color .12s ease, box-shadow .12s ease,
                transform .12s ease;
}
.table-dense > tbody > tr:hover { background: var(--tbl-hover-bg); }
.table-dense > tbody > tr.is-selected,
.table-dense > tbody > tr[aria-selected="true"] {
    background: var(--tbl-selected-bg);
    box-shadow: inset 3px 0 0 var(--action-accent);
}

/* The identity cell is a real link, never a JS click on the <tr>. That keeps
   middle-click, keyboard Enter and screen-reader link semantics — and adding
   role="button" to a <tr> drops it out of the table accessibility tree in two
   major screen readers. */
.table-dense td a { color: inherit; text-decoration: none; }
.table-dense td a:hover { text-decoration: underline; }

/* ── 2. .cell-num — numbers compared down a column ────────────────────── */
.cell-num {
    text-align: right;
    /* Tabular figures give each digit the same advance width, so the ones
       place lines up and the eye can hold one lane. */
    font-variant-numeric: tabular-nums;
}
.table-dense > thead > tr > th.cell-num { text-align: right; }

/* ── 3. .cell-truncate — one line, ellipsis, tooltip ──────────────────── */
/* Ragged rows (40-55px on /admin/documents) come from cells wrapping to two
   and three lines. Scanning is faster when the eye can predict where the next
   row starts. The full value must stay reachable via `title` on the cell. */
.cell-truncate {
    /* `max-width: 0` is the idiom that lets a cell truncate inside an
       auto-layout table. It also lets the algorithm shrink the column to its
       minimum, so the column that truncates needs a width hint on its <th>
       (`width: 100%` for "take the remainder"), or the most important column
       ends up the narrowest — which is exactly what happened on ip-logs. */
    max-width: 0;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* ── 4. .status-dot — replaces the coloured pill ──────────────────────── */
/* A unique hue pops out preattentively only while it stays RARE. At 345
   badges colour is everywhere, so nothing pops. A dot is a low-ink carrier of
   one hue; a pill adds a filled rectangle competing on every row. */
.status-dot { display: inline-flex; align-items: center; gap: 6px; white-space: nowrap; }
.status-dot::before {
    content: ''; flex: 0 0 auto;
    width: 7px; height: 7px; border-radius: 50%;
    background: var(--tbl-text-muted);
}
/* Tokens, not hex: these were the same status values as the shared indicators,
   written a second time. */
.status-dot--ok::before { background: var(--indicator-success); }
.status-dot--pending::before { background: var(--indicator-warning); }
.status-dot--info::before { background: var(--action-accent); }
/* Saturated fill is reserved for the state a biller must not miss. Once three
   things are urgent, none of them reads as urgent. */
.status-dot--alert { color: var(--indicator-danger); font-weight: 500; }
.status-dot--alert::before { background: var(--indicator-danger); }

/* ── 5. .table-sticky — headers that survive a long list ──────────────── */
/* Worth it past roughly 25-40 rows. Two traps: `position: sticky` resolves
   against the nearest SCROLLING ancestor, so a `.rt-scroll` wrapper becomes
   the reference rather than the viewport; and every engine drops collapsed
   borders on sticky headers (W3C csswg-drafts #3136, open since 2018,
   Chromium "Won\'t Fix"), so the rule is drawn with box-shadow, which moves
   with the element. The header also needs an opaque background or body rows
   show through it. */
.table-sticky { border-collapse: separate; border-spacing: 0; }
.table-sticky > thead > tr > th {
    position: sticky; top: 0; z-index: 2;
    background: var(--table-head-sticky-bg);
    box-shadow: inset 0 -1px 0 var(--tbl-border-color);
    border-bottom: 0;
}
}
