/* ═══════════════════════════════════════════════════════════
   Tables — extracted from TNonline (DataTable / Settings)
   Card-wrapped data table with sticky uppercase headers, hover
   rows, and a pagination footer.
   ═══════════════════════════════════════════════════════════ */

.tn-table-wrapper {
    position: relative;
    background: var(--tn-bg-card);
    border: 1px solid var(--tn-border);
    border-radius: var(--tn-radius-lg);
    overflow: hidden;
}

.tn-table-scroll {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
}

.tn-table {
    width: 100%;
    border-collapse: collapse;
    font-size: var(--tn-font-size-sm);
}

.tn-table thead {
    position: sticky;
    top: 0;
    z-index: 5;
}

.tn-table th {
    padding: 10px var(--tn-space-md);
    text-align: left;
    font-weight: 600;
    font-size: var(--tn-font-size-xs);
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--tn-text-secondary);
    background: var(--tn-bg-page);
    border-bottom: 1px solid var(--tn-border);
    white-space: nowrap;
    user-select: none;
}

.tn-table td {
    padding: 9px var(--tn-space-md);
    color: var(--tn-text-primary);
    border-bottom: 1px solid var(--tn-border-light);
    vertical-align: middle;
}

.tn-table tbody tr {
    transition: background-color var(--tn-transition);
}

.tn-table tbody tr:hover {
    background-color: var(--tn-bg-hover);
}

.tn-table tbody tr:last-child td {
    border-bottom: none;
}

/* Highlighted / current row */
.tn-table tr.is-current {
    background: var(--tn-bg-active);
}

.tn-table tr.is-current:hover {
    background: var(--tn-bg-active);
}

/* Monospace cell (IDs, codes) */
.tn-cell-mono {
    font-family: var(--tn-font-mono);
    font-size: var(--tn-font-size-xs);
    color: var(--tn-text-secondary);
}

/* Alignment & emphasis helpers */
.tn-table .text-right,
.tn-cell-right {
    text-align: right;
}

.tn-table .text-muted {
    color: var(--tn-text-secondary);
}

/* Numeric cell — tabular figures, dimmed unless emphasised */
.tn-cell-num {
    text-align: right;
    font-variant-numeric: tabular-nums;
    color: var(--tn-text-secondary);
}

.tn-cell-num strong {
    color: var(--tn-text-primary);
}

/* ═══════════════════════════════════════════════════════════
   Dividers & information elements
   (from the dense environment / fraction report tables)
   ═══════════════════════════════════════════════════════════ */

/* Group header row — strong top divider, teal icon, opens a section */
.tn-table tr.tn-group-header {
    background: var(--tn-bg-hover);
    border-top: 2px solid var(--tn-border);
}

.tn-table tr.tn-group-header td {
    padding: 10px var(--tn-space-md);
    font-size: var(--tn-font-size-base);
    font-weight: 600;
    color: var(--tn-text-primary);
}

.tn-table tr.tn-group-header .bi {
    margin-right: 6px;
    color: var(--tn-accent);
}

/* Subtotal row — closes a section with a strong bottom divider */
.tn-table tr.tn-subtotal-row {
    background: var(--tn-bg-hover);
    border-bottom: 2px solid var(--tn-border);
}

.tn-table tr.tn-subtotal-row td {
    padding: 8px var(--tn-space-md);
    font-size: var(--tn-font-size-sm);
    font-weight: 600;
    color: var(--tn-text-secondary);
}

/* Plain section divider row (a visual break with no content) */
.tn-table tr.tn-divider-row td {
    padding: 0;
    height: 0;
    border-bottom: 2px solid var(--tn-border);
}

/* Hazardous / flagged row — soft red wash */
.tn-table tr.tn-row--hazard {
    background-color: #FFF5F5;
}

.tn-table tr.tn-row--hazard:hover {
    background-color: #FEE2E2;
}

/* Category dot — small colored marker in a cell (set color inline) */
.tn-category-dot {
    display: inline-block;
    width: 7px;
    height: 7px;
    border-radius: 50%;
    margin-right: 5px;
    flex-shrink: 0;
    vertical-align: middle;
}

/* Code pill — compact code/meta chip inside a cell */
.tn-code-pill {
    display: inline-block;
    padding: 1px 5px;
    margin-right: 3px;
    background: var(--tn-bg-page);
    border: 1px solid var(--tn-border);
    border-radius: var(--tn-radius-sm);
    font-size: var(--tn-font-size-xs);
    font-family: var(--tn-font-mono);
    color: var(--tn-text-secondary);
    vertical-align: middle;
}

.tn-code-pill--treat {
    background: #F0F9FF;
    border-color: #BAE6FD;
    color: #0369A1;
}

.tn-code-pill--hazard {
    background: var(--tn-danger-light);
    border-color: #FECACA;
    /* --tn-danger-text, not --tn-danger — this is body text on the pill's
       own fill, same rule as alerts.css. Was 4.99:1, passing by 0.49. */
    color: var(--tn-danger-text);
    font-weight: 600;
}

/* Truncating cell */
.tn-cell-truncate {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    max-width: 160px;
}

/* ── Summary band — headline figure above a table ── */
.tn-table-summary {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 10px;
    padding: 12px 18px;
    margin-bottom: var(--tn-space-md);
    background: linear-gradient(135deg, rgba(16, 185, 129, 0.06), rgba(var(--tn-accent-rgb), 0.06));
    border: 1px solid rgba(16, 185, 129, 0.18);
    border-radius: var(--tn-radius);
    font-size: var(--tn-font-size-base);
}

.tn-table-summary .bi {
    font-size: 1.1em;
    color: var(--tn-success);
}

.tn-table-summary-label {
    color: var(--tn-text-secondary);
    font-weight: 500;
}

.tn-table-summary-value {
    font-weight: 700;
    color: var(--tn-text-primary);
    font-variant-numeric: tabular-nums;
}

/* ── Legend — keyed list of series, sits beside/above a table ── */
.tn-legend {
    display: flex;
    flex-direction: column;
    gap: 10px;
}

.tn-legend-item {
    display: flex;
    align-items: center;
    gap: 10px;
    font-size: var(--tn-font-size-sm);
}

.tn-legend-dot {
    width: 12px;
    height: 12px;
    border-radius: var(--tn-radius-sm);
    flex-shrink: 0;
}

.tn-legend-label {
    color: var(--tn-text-primary);
    font-weight: 500;
    min-width: 140px;
}

.tn-legend-value {
    color: var(--tn-text-secondary);
    font-variant-numeric: tabular-nums;
}

/* ── Totals footer band — sits below the table (the "Totalt" row) ── */
.tn-table-totals {
    display: flex;
    align-items: center;
    gap: var(--tn-space-md);
    flex-wrap: wrap;
    padding: 16px 24px;
    margin-top: var(--tn-space-md);
    background: var(--tn-bg-hover);
    border: 1px solid var(--tn-border);
    border-radius: var(--tn-radius);
}

.tn-table-totals-label {
    font-weight: 700;
    font-size: var(--tn-font-size-base);
    color: var(--tn-text-primary);
}

.tn-table-totals-values {
    display: flex;
    gap: var(--tn-space-lg);
    flex-wrap: wrap;
    font-size: var(--tn-font-size-sm);
    color: var(--tn-text-secondary);
}

.tn-table-totals-values strong {
    color: var(--tn-text-primary);
    font-variant-numeric: tabular-nums;
}

@media (max-width: 768px) {
    .tn-table-totals {
        flex-direction: column;
        align-items: flex-start;
    }

    .tn-table-totals-values {
        flex-direction: column;
        gap: var(--tn-space-sm);
    }
}

/* ═══════════════════════════════════════════════════════════
   .tn-table--cards — table becomes a card list on phones.

   Without this, a table on a phone can only sideways-scroll: the user
   pans a spreadsheet through a 390px window, seeing two columns at a
   time and losing the row they were reading. Horizontal scroll is still
   correct for genuinely wide numeric/reporting tables where comparing
   columns IS the task — that's what plain .tn-table-scroll stays for.
   For record-shaped tables (one row = one thing), add --cards and each
   row restacks as a labelled card instead.

   REQUIRED: every <td> needs data-label="<its column heading>" — the
   header row is hidden on mobile, so the label has to travel with the
   cell. A td with no data-label renders its value with no context.

   REQUIRED for tap-to-expand: only the row's summary cell shows by
   default — .tn-cell-primary if the row has one, else its first <td> —
   and every other cell needs something in your app to toggle .is-open on
   the <tr> (a click/tap handler). CSS can't do this alone, since a <tr>
   can't be a <button>. A row nothing ever toggles permanently shows just
   its summary cell — wire the handler before you ship, not after.
   .tn-cell-primary is where you'll usually want it: it also gets the
   title styling (bigger, bold, no label prefix) and is what a row's
   optional chevron keys off (see below). It matters for more than looks
   here, though — a row that leads with something that isn't the
   identifying value (a select-all checkbox column, say) needs
   .tn-cell-primary to point at the real summary cell, or the collapsed
   card is just a bare checkbox with nothing to tell one row from the
   next. A consumer whose markup comes from a shared/opaque row template
   that genuinely can't guarantee the class lands anywhere still falls
   back to column order alone — same promise as before, just not the
   first thing reached for.

     <table class="tn-table tn-table--cards">
       <thead><tr><th>Artikel</th><th>Lager</th></tr></thead>
       <tbody>
         <tr class="is-open">
           <td data-label="Artikel" class="tn-cell-primary">
             Pallyft 2000
             <i class="bi bi-chevron-down tn-cards-chevron"></i>
           </td>
           <td data-label="Lager">142 st</td>
         </tr>
       </tbody>
     </table>

   The <i class="tn-cards-chevron"> is optional — place it anywhere in the
   row and it rotates on .is-open the same way .tn-record-chevron does.
   Can't place it (row markup comes from an opaque per-column template —
   a shared <DataTable> component, say — and injecting a child element
   from JS gets clobbered on re-render)? Put .tn-cell-primary on the first
   cell and a structural fallback chevron (a plain CSS border-corner
   shape, no icon font needed) appears there for free, rotating the same
   way. It backs off automatically the moment a real <i class="tn-cards-
   chevron"> is present, so you never get two.

   Prefer .tn-record (record.css) when building fresh — it's designed for
   this shape. --cards is the retrofit path for an existing table you
   don't want to re-author, now with the same expand-on-tap behaviour.
   ═══════════════════════════════════════════════════════════ */
@media (max-width: 640px) {
    /* The wrapper's frame and clipping would fight free-standing cards */
    .tn-table--cards-wrapper {
        background: none;
        border: none;
        border-radius: 0;
        overflow: visible;
    }

    .tn-table--cards-wrapper .tn-table-scroll {
        overflow-x: visible;
    }

    .tn-table--cards,
    .tn-table--cards tbody,
    .tn-table--cards tr,
    .tn-table--cards td {
        display: block;
        width: auto;
    }

    /* Headings move into each cell's ::before, so the row is gone.
       clip, not display:none — a screen reader should still associate
       the header cells with the data. */
    .tn-table--cards thead {
        position: absolute;
        width: 1px;
        height: 1px;
        overflow: hidden;
        clip: rect(0 0 0 0);
        clip-path: inset(50%);
        white-space: nowrap;
    }

    .tn-table--cards tr {
        margin-bottom: var(--tn-space-sm);
        padding: var(--tn-space-sm) var(--tn-space-md);
        background: var(--tn-bg-card);
        border: 1px solid var(--tn-border);
        border-radius: var(--tn-radius-lg);
        cursor: pointer;
    }

    .tn-table--cards tbody tr:last-child {
        margin-bottom: 0;
    }

    .tn-table--cards td {
        display: flex;
        align-items: baseline;
        justify-content: space-between;
        gap: var(--tn-space-md);
        padding: 7px 0;
        border-bottom: 1px solid var(--tn-border-light);
        text-align: right;
    }

    .tn-table--cards tr td:last-child {
        border-bottom: none;
    }

    .tn-table--cards td::before {
        content: attr(data-label);
        flex-shrink: 0;
        font-size: var(--tn-font-size-xs);
        font-weight: 600;
        text-transform: uppercase;
        letter-spacing: 0.04em;
        color: var(--tn-text-secondary);
        text-align: left;
    }

    /* The identifying cell reads as the card's title: full width, larger,
       no label, sitting above the labelled fields. Flex (not block) so an
       optional .tn-cards-chevron lands at the end instead of wrapping
       under the title. */
    .tn-table--cards td.tn-cell-primary {
        display: flex;
        align-items: center;
        justify-content: space-between;
        gap: var(--tn-space-sm);
        padding-top: 0;
        padding-bottom: var(--tn-space-sm);
        font-size: var(--tn-font-size-lg);
        font-weight: 700;
        letter-spacing: -0.01em;
        text-align: left;
    }

    .tn-table--cards td.tn-cell-primary::before {
        display: none;
    }

    /* Optional disclosure indicator — same rotate-on-open as
       .tn-record-chevron / .tn-accordion-chevron. Put it anywhere inside
       the row; it doesn't have to live in .tn-cell-primary specifically. */
    .tn-table--cards .tn-cards-chevron {
        flex-shrink: 0;
        color: var(--tn-text-muted);
        font-size: 1rem;
        transition: transform var(--tn-transition);
    }

    .tn-table--cards tr.is-open .tn-cards-chevron {
        transform: rotate(180deg);
    }

    /* Structural fallback — same rotate-on-open cue as .tn-cards-chevron,
       but requires no markup at all. For a consumer whose row content
       comes from an opaque per-column template that can set a class on
       .tn-cell-primary but can't inject a child element into it (Blazor's
       DataTable BodyTemplate, for one — a JS-inserted node gets clobbered
       on re-render), this is the only affordance option available.
       :not(:has(...)) backs off automatically when a real <i> chevron is
       present, so the two never double up — a border-corner shape rather
       than an icon-font glyph, since a consumer this constrained can't
       necessarily guarantee an icon font is loaded either. */
    .tn-table--cards tr td.tn-cell-primary:not(:has(.tn-cards-chevron))::after {
        content: "";
        flex-shrink: 0;
        width: 7px;
        height: 7px;
        margin-left: var(--tn-space-sm);
        border-right: 2px solid var(--tn-text-muted);
        border-bottom: 2px solid var(--tn-text-muted);
        transform: rotate(45deg);
        transition: transform var(--tn-transition);
    }

    .tn-table--cards tr.is-open td.tn-cell-primary:not(:has(.tn-cards-chevron))::after {
        transform: rotate(225deg);
    }

    /* ── Tap-to-expand — only the row's summary cell shows until it's
       opened, matching .tn-record. Something in the app must toggle
       .is-open on the <tr> (see the REQUIRED note above the breakpoint);
       this only supplies the resulting states.

       The summary cell is .tn-cell-primary when a row has one, falling
       back to :first-child when it doesn't. :first-child alone isn't
       enough — a row can legitimately lead with something that isn't the
       identifying value (a select-all checkbox column, say), and
       collapsing to THAT shows a bare checkbox with nothing to tell one
       card from the next, with no chevron either, since that's keyed on
       .tn-cell-primary too. Preferring .tn-cell-primary when it's present
       fixes that without giving up the fallback: a consumer whose row
       markup comes from a shared/opaque template (a generic <DataTable>
       component, say) that truly can't guarantee the class lands anywhere
       can still rely on column order alone, same promise as before.

       Selectors spell out "tr td" rather than the shorter ".tn-table--cards
       td" so they outrank .tn-cell-actions's own unconditional
       `display: flex` below on specificity (both are two classes; adding
       the `tr` element makes this one win on element count) instead of
       depending on which rule happens to sit later in the file. ── */
    .tn-table--cards tr:has(td.tn-cell-primary) td:not(.tn-cell-primary) {
        display: none;
    }

    .tn-table--cards tr:not(:has(td.tn-cell-primary)) td:not(:first-child) {
        display: none;
    }

    .tn-table--cards tr.is-open:has(td.tn-cell-primary) td:not(.tn-cell-primary) {
        display: flex;
        animation: tnCardsReveal 0.18s ease;
    }

    .tn-table--cards tr.is-open:not(:has(td.tn-cell-primary)) td:not(:first-child) {
        display: flex;
        animation: tnCardsReveal 0.18s ease;
    }

    @keyframes tnCardsReveal {
        from { opacity: 0; transform: translateY(-4px); }
        to   { opacity: 1; transform: translateY(0); }
    }

    /* An actions cell shouldn't be squeezed against its label */
    .tn-table--cards td.tn-cell-actions {
        display: flex;
        justify-content: flex-end;
        gap: var(--tn-space-sm);
        padding-top: var(--tn-space-sm);
    }

    .tn-table--cards td.tn-cell-actions::before {
        display: none;
    }

    .tn-table--cards td.tn-cell-actions .tn-btn {
        flex: 1;
        /* Redundant since .tn-btn itself floors to --tn-touch-target
           (buttons.css, see #80) -- this call-site patch predates that
           base-rule fix and was how the same symptom got treated the
           first time it was felt here, without being traced back to the
           root cause. Left in place as a harmless no-op; safe to delete,
           but know why it existed before you do. */
        min-height: var(--tn-touch-target);
    }

    /* Row states repaint the card, not a table row */
    .tn-table--cards tr.is-current {
        border-color: var(--tn-accent);
        box-shadow: 0 0 0 3px rgba(var(--tn-accent-rgb), 0.1);
    }

    /* Hover is meaningless on touch and leaves a stuck highlight */
    .tn-table--cards tbody tr:hover {
        background: var(--tn-bg-card);
    }
}

/* ── Dense modifier — compact reporting tables ── */
.tn-table--dense {
    font-size: var(--tn-font-size-xs);
    line-height: 1.25;
}

.tn-table--dense th {
    padding: 5px 6px;
    font-size: 0.62rem;
}

.tn-table--dense td {
    padding: 3px 6px;
}

/* ── Pagination footer ── */
.tn-pagination {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 10px var(--tn-space-md);
    border-top: 1px solid var(--tn-border);
    flex-wrap: wrap;
    gap: var(--tn-space-sm);
}

.tn-pagination-info {
    font-size: var(--tn-font-size-xs);
    color: var(--tn-text-secondary);
}

.tn-pagination-controls {
    display: flex;
    align-items: center;
    gap: 2px;
}

.tn-page-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 30px;
    height: 30px;
    padding: 0 var(--tn-space-xs);
    border: 1px solid var(--tn-border);
    border-radius: var(--tn-radius-sm);
    background: var(--tn-bg-card);
    color: var(--tn-text-primary);
    font-size: var(--tn-font-size-sm);
    font-weight: 500;
    cursor: pointer;
    transition: all var(--tn-transition);
}

.tn-page-btn:hover:not(:disabled):not(.is-active) {
    background: var(--tn-bg-hover);
    border-color: var(--tn-accent);
    color: var(--tn-accent);
}

.tn-page-btn:disabled {
    opacity: 0.35;
    cursor: not-allowed;
}

.tn-page-btn:focus-visible {
    outline: none;
    box-shadow: 0 0 0 2px var(--tn-accent);
}

.tn-page-btn.is-active {
    background: var(--tn-accent);
    border-color: var(--tn-accent);
    color: var(--tn-accent-contrast, #fff);
    cursor: default;
}

@media (max-width: 640px) {
    .tn-pagination {
        justify-content: center;
    }

    .tn-pagination-info {
        width: 100%;
        text-align: center;
    }

    /* Tighten cell gutters on phones so more of each row is content,
       not padding (pairs with .tn-bleed-mobile for the edge-to-edge look). */
    .tn-table th,
    .tn-table td {
        padding-left: 12px;
        padding-right: 12px;
    }
}
