﻿/*
 * AIM Unified Table System
 * Created: March 9, 2026
 * Location: AIM.Shared.UI â€” accessible to all RCL modules
 *
 * Visual benchmark: Estates Manager table (.sites-table in estates-consolidated.css)
 * Light grey header, sticky, scrollable, striped, hover, sort arrows, fixed layout
 *
 * Usage: Add modifier classes to .aim-table-wrapper to opt in to features.
 * Height budget: Set on your component container, not on these classes.
 *
 * HTML structure:
 *   div.aim-table-wrapper[.aim-table--scrollable][.aim-table--hover][...]
 *     div.aim-table-toolbar           (optional: filters, search, buttons)
 *     div.aim-table-scroll            (scroll container â€” scrollable tables only)
 *       table.aim-table
 *         colgroup > col              (when using aim-table--fixed)
 *         thead > tr > th.aim-th
 *         tbody > tr.aim-tr > td.aim-td
 *     div.aim-table-footer            (optional: pagination)
 */

/* ==========================================================================
 * LOCAL TOKENS â€” override on your wrapper to customise per-component
 * ========================================================================== */

/* ==========================================================================
 * 1. WRAPPER — outer container
 * Merged from two duplicate `.aim-table-wrapper` blocks (May 7 2026 cleanup).
 * Applies the same card recipe used by .aim-card so tables sit on the same
 * elevation tier with the same chrome.
 * ========================================================================== */

.aim-table-wrapper {
    /* Component-local tokens (spacing only — not theme-aware) */
    --aim-table-cell-padding: 0.5rem 0.625rem;
    --aim-table-cell-padding-compact: 0.375rem 0.5rem;
    --aim-table-row-height: 40px;

    /* Visual chrome — matches .aim-card recipe (slate-10 border, nearly-flat
       shadow, 12px radius). Brand swap re-tints via --primary-alpha-10 →
       --brand-identity. */
    display: flex;
    flex-direction: column;
    background: var(--raised);
    border: 1px solid var(--primary-alpha-10);
    border-radius: var(--radius-lg);
    box-shadow: 0 1px 2px color-mix(in srgb, var(--color-neutral-darkest) 4%, transparent);
    overflow: hidden;
}

/* ==========================================================================
 * 2. TOOLBAR â€” filters, search, action buttons (above scroll area)
 * ========================================================================== */

.aim-table-toolbar {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    padding: 0.625rem 0.875rem;
    border-bottom: 1px solid var(--line);
    background: var(--ground);
    flex-shrink: 0;
    flex-wrap: wrap;
}

.aim-table-toolbar__actions {
    margin-left: auto;
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.aim-table-toolbar__search {
    position: relative;
    flex: 0 1 220px;
    min-width: 140px;
}

.aim-table-toolbar__search input {
    width: 100%;
    padding: 0.375rem 0.625rem;
    font-size: var(--font-size-sm, 0.875rem);
    border: 1px solid var(--line);
    border-radius: var(--radius-sm, 4px);
    background: var(--raised);
    color: var(--ink);
}

/* Halo tier — see aim-consolidated.css § Focus. Also drops a hex literal from
   a var() fallback (feedback_no_hex_in_var_fallbacks). */
.aim-table-toolbar__search input:focus {
    outline: none;
    border-color: var(--focus-ring-color);
    box-shadow: 0 0 0 var(--focus-ring-halo-width) var(--focus-ring-halo);
}

.aim-table-toolbar__filter {
    padding: 0.375rem 0.625rem;
    font-size: var(--font-size-sm, 0.875rem);
    border: 1px solid var(--line);
    border-radius: var(--radius-sm, 4px);
    background: var(--raised);
    color: var(--ink);
    appearance: auto;
}

/* ==========================================================================
 * 3. SCROLL CONTAINER â€” overflow region
 * ========================================================================== */

.aim-table-scroll {
    flex: 1;
    min-height: 0;
    overflow-x: auto;
    overflow-y: auto;
}

/* ==========================================================================
 * 4. TABLE â€” base element
 * ========================================================================== */

.aim-table {
    width: 100%;
    border-collapse: separate;
    border-spacing: 0;
    font-size: var(--font-size-sm, 0.875rem);
    color: var(--ink);
    background: var(--raised);
}

/* ==========================================================================
 * 5. HEADER CELLS â€” light grey by default (matches Estates Manager)
 * ========================================================================== */

.aim-th {
    padding: 12px 14px;                              /* up from 10px — band feels framed */
    text-align: left;
    font-size: var(--font-size-xs, 0.75rem);
    font-weight: 600;
    letter-spacing: 0.3px;                           /* polished header tracking */
    white-space: nowrap;
    background: var(--aim-table-header-bg);          /* vertical gradient (per-cell, joins seamlessly) */
    color: var(--aim-table-header-color);
    box-shadow: var(--aim-table-header-groove);      /* inset top 1px slate highlight per cell */
    /* Sticky header — losing column labels after one screen-scroll on long
       tables forces users to scroll back up. Position-sticky on cells (not
       thead) so the groove+bg+padding all stay attached when scrolling. */
    position: sticky;
    top: 0;
    z-index: 2;
}

/* Vertical column dividers removed (May 7 2026 design refresh).
   They added 1995-spreadsheet weight without adding clarity — columns are
   already separated by alignment + whitespace + the gradient strip. The
   `.aim-table--bordered` modifier still adds them back if any consumer
   needs the legacy spreadsheet look. */

/* Header band — `.aim-th` carries the slate@12% bg + groove + sticky.
   STRIP REMOVED FROM TABLES (May 7 2026): the slate@12% → white value drop
   from header to first row in the new internal ladder is significant
   enough to define the boundary on its own. Rows have their own grid
   doing that visual work. The strip is reserved for `.aim-card-header`
   where the boundary is harder to draw (no rows to do it). */
.aim-table thead {
    position: relative;
}

/* ==========================================================================
 * 6. BODY ROWS & CELLS
 * ========================================================================== */

.aim-tr {
    height: var(--aim-table-row-height);
    min-height: var(--aim-table-row-height);
    max-height: var(--aim-table-row-height);
}

.aim-td {
    padding: var(--aim-table-cell-padding);
    border-bottom: 1px solid var(--aim-table-cell-border);
    vertical-align: middle;
    font-size: 0.875rem;
}

/* Cell that truncates overflow with ellipsis â€” opt-in per cell */
.aim-td--truncate {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    max-width: 0;
}

/* Cell that allows text wrapping (descriptions, names) */
.aim-td--wrap {
    white-space: normal;
    overflow: visible;
    text-overflow: clip;
    max-width: none;
}

/* Numeric cell â€” right-aligned, digits lined up by place value */
.aim-td--numeric,
.aim-th--numeric {
    text-align: right;
    font-variant-numeric: tabular-nums;
}

/* Center-aligned cell (actions, checkboxes) */
.aim-td--center,
.aim-th--center {
    text-align: center;
}

/* Clickable row */
.aim-tr--clickable {
    cursor: pointer;
}

/* Selected row â€” theme-adaptive amber tint mixed into --surface-raised so
   light mode shows pale amber on white, dark mode shows tinted amber on
   dracula-bg. Text inherits the row's adaptive --color-text-primary; no
   forced override needed. */
.aim-tr--selected .aim-td {
    background-color: color-mix(in srgb, var(--warn) 15%, var(--raised));
}

/* Selected row marker: the 4px border-left rail became a blue mini slot (§21).
   It sits on the first cell because pseudo-elements on a <tr> are unreliable. */
.aim-tr--selected .aim-td:first-child {
    position: relative;
    padding-left: calc(0.625rem + 12px);
    --slot-c: var(--action);
}

.aim-tr--selected .aim-td:first-child::before {
    content: "";
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    width: 14px;
    pointer-events: none;
    background: linear-gradient(200deg,
        var(--slot-c, transparent) 0%,
        color-mix(in srgb, var(--slot-c, transparent) 55%, var(--raised)) 100%);
    -webkit-mask: var(--slot-mask-left) no-repeat 0 0 / 100% 100%;
    mask: var(--slot-mask-left) no-repeat 0 0 / 100% 100%;
}

/* ==========================================================================
 * 7. EMPTY & LOADING STATES
 * ========================================================================== */

.aim-table-empty {
    text-align: center;
    padding: 2rem;
    color: var(--ink-muted);
    font-style: italic;
}

.aim-table-loading {
    text-align: center;
    padding: 2rem;
    color: var(--ink-muted);
}

/* ==========================================================================
 * 8. PAGINATION FOOTER â€” below scroll area
 * ========================================================================== */

.aim-table-footer {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0.5rem 0.875rem;
    border-top: 1px solid var(--line);
    background: var(--ground);
    font-size: var(--font-size-xs, 0.75rem);
    color: var(--ink-muted);
    flex-shrink: 0;
    flex-wrap: wrap;
    gap: 0.5rem;
}

.aim-table-footer__info {
    flex: 1;
    font-weight: 500;
}

.aim-table-footer__pages {
    display: flex;
    align-items: center;
    gap: 0.25rem;
}

.aim-table-footer__page-btn {
    padding: 0.25rem 0.5rem;
    font-size: var(--font-size-xs, 0.75rem);
    /* 2026-07-27 — control-grade boundary, not the divider token. See the
       matching note on .tg-page-btn in TrackerGrid.razor.css. */
    border: 1px solid var(--line-strong);
    background: var(--raised);
    color: var(--ink);
    cursor: pointer;
    border-radius: var(--radius-sm, 4px);
    min-width: 28px;
    height: 28px;
    display: flex;
    align-items: center;
    justify-content: center;
}

.aim-table-footer__page-btn:hover:not(:disabled) {
    background: var(--brand-fill-on-surface);
    color: var(--color-white);
    border-color: var(--brand-border-on-surface);
}

.aim-table-footer__page-btn:disabled {
    opacity: 0.4;
    cursor: not-allowed;
}

.aim-table-footer__page-btn--active {
    background: var(--brand-fill-on-surface);
    color: var(--color-white);
    border-color: var(--brand-border-on-surface);
    font-weight: 700;
}

.aim-table-footer__size-select {
    padding: 0.25rem 0.5rem;
    font-size: var(--font-size-xs, 0.75rem);
    border: 1px solid var(--line);
    border-radius: var(--radius-sm, 4px);
    background: var(--raised);
    color: var(--ink);
    cursor: pointer;
}

/* ==========================================================================
 * MODIFIERS â€” opt-in features applied to .aim-table-wrapper
 * ========================================================================== */

/* --scrollable: sticky headers + scroll container */
.aim-table--scrollable .aim-th {
    position: sticky;
    top: 0;
    z-index: 2;
    box-shadow: var(--lift-1, 0 1px 3px color-mix(in srgb, var(--color-black) 10%, transparent));
}

/* --striped: zebra rows */
.aim-table--striped .aim-tr:nth-child(odd) .aim-td {
    background-color: var(--aim-table-stripe-bg);
}

/* --hover: row hover highlight.
   Per design language Â§9: hover lands on --surface-base (one tier DOWN from
   the row), producing a subtle DARKENING in BOTH themes:
     Light: white card â†’ blue-tinted page bg
     Dark:  dracula-bg â†’ deeper page-deep navy
   --aim-table-row-hover resolves to --surface-row-hover â†’ --surface-anchor â†’
   --surface-base, so the cascade is mode-aware. Text colour inherits normally
   (dark text in light mode, light text in dark mode) â€” no forced !important
   override needed because the hover bg is now mode-appropriate. Status pills
   inside the row keep their own explicit colours and are unaffected. */
.aim-table--hover .aim-tr:hover .aim-td {
    background-color: var(--aim-table-row-hover);
}

/* --compact: tighter padding */
.aim-table--compact .aim-th,
.aim-table--compact .aim-td {
    padding: var(--aim-table-cell-padding-compact);
}

.aim-table--compact .aim-tr {
    height: 32px;
    min-height: 32px;
    max-height: 32px;
}

/* --bordered: borders on all cell sides */
.aim-table--bordered .aim-td {
    border-right: 1px solid var(--aim-table-cell-border);
}

.aim-table--bordered .aim-td:last-child {
    border-right: none;
}

/* --fixed: table-layout fixed (requires <colgroup>) */
.aim-table--fixed .aim-table {
    table-layout: fixed;
    /* `table-layout: fixed` + `width: 100%` with no floor CRUSHES cells on a narrow viewport
       instead of letting the wrapper scroll — the failure named in .claude/rules/responsive.md §3
       ("tables need a min-width floor or they crush cells instead of scrolling").
       `min-width: max-content` makes the table at least as wide as its columns want to be, so
       `.aim-table-scroll { overflow-x: auto }` gets something to scroll and the columns keep their
       colgroup widths. Override per-component if a table should compress instead. */
    min-width: max-content;
}

/* --dark-header: dark navy header (for admin tables) */
.aim-table--dark-header {
    --aim-table-header-bg: var(--color-bg-header, var(--color-neutral-dark));
    --aim-table-header-color: var(--color-text-on-primary, var(--raised));
    --aim-table-header-border: color-mix(in srgb, var(--raised) 15%, transparent);
}

.aim-table--dark-header .aim-th {
    letter-spacing: 0.05em;
}

/* ==========================================================================
 * SORTABLE â€” sort indicators on header cells
 * ========================================================================== */

.aim-table--sortable .aim-th {
    cursor: pointer;
    -webkit-user-select: none;
    user-select: none;
    position: relative;
    padding-right: 1.5rem;
}

.aim-table--sortable .aim-th:hover {
    background: var(--aim-table-header-accent-bg);
    color: var(--aim-table-header-accent-color);
}

/* Sort arrow — hidden by default, fades in on header hover, full opacity
   when the column is actively sorted. Pre-May 2026 design showed paired
   up/down chevrons on every column simultaneously — every column shouting
   "I'm sortable" at once. Modern tables show the indicator only on the
   active column with a faint hint on hover for the others. ~40% drop in
   visual noise. */
.aim-th__sort-arrow {
    font-size: 10px;
    color: var(--ink-faint);
    margin-left: 0.25rem;
    opacity: 0;
    transition: opacity 0.15s ease;
}

.aim-table--sortable .aim-th:hover .aim-th__sort-arrow {
    opacity: 0.6;
}

.aim-th__sort-arrow.active {
    opacity: 1;
    color: var(--aim-table-sort-indicator-color);
}

/* Active-sort header CELL stays at the band's light text colour — the chevron
   alone carries the indicator. Earlier behaviour over-rode the cell text to
   --interactive-base which on the dark navy header band rendered slate-on-slate
   (invisible), and the hover state couldn't repaint it because single-class
   specificity ties tipped to the sorted rule. Hover now consistently lights
   the cell via --aim-table-header-accent-color. */
.aim-th.aim-th--sort-asc,
.aim-th.aim-th--sort-desc {
    color: var(--aim-table-header-color);
}

/* Column-level sortable / sorted modifiers (per design refresh).
   Use these when only some columns of a table are sortable, vs the
   table-level `.aim-table--sortable` which makes ALL columns sortable.
   `.aim-th--sortable`  — column accepts sort; chevron hidden, faint on hover
   `.aim-th--sorted`    — column is the active sort; chevron at full opacity */
.aim-th--sortable {
    cursor: pointer;
    -webkit-user-select: none;
    user-select: none;
}

.aim-th--sortable:hover .aim-th__sort-arrow {
    opacity: 0.6;
}

/* Sorted column cell — stay on header-color (light on the band). Chevron
   carries the indicator (rule below). */
.aim-th--sorted {
    color: var(--aim-table-header-color);
}

.aim-th--sorted .aim-th__sort-arrow {
    opacity: 1;
    color: var(--aim-table-sort-indicator-color);
}

/* Column header inner wrapper (for flex layout with sort arrow) */
.aim-th__content {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 0.25rem;
}

.aim-th__text {
    flex: 1;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* Non-sortable + actions columns — no click affordance, no blue hover.
   The default rule at L399 paints every .aim-th in a sortable table with
   the action-blue accent on hover; that's wrong for cells that aren't
   clickable. We reset BOTH bg and color so the cell stays as plain
   header chrome (was: only bg was reset, leaking white text onto a light
   bg for non-sort columns). */
.aim-th--no-sort,
.aim-th--actions {
    cursor: default;
}

.aim-table--sortable .aim-th--no-sort:hover,
.aim-table--sortable .aim-th--actions:hover {
    background: var(--aim-table-header-bg);
    color: var(--aim-table-header-color);
}

/* ==========================================================================
 * FILTER ICONS â€” per-column filter indicators
 *
 * Per-column filter chevrons read as alert/error noise (especially when
 * rendered in red — that colour means "alert" in every other UI context).
 * The new pattern: a single Filter button in the toolbar handles filtering
 * for the whole table. Per-column icons are hidden by default and fade in
 * on header-hover for power users; an actively-filtered column gets the
 * --interactive-base accent (matching the sort indicator).
 * ========================================================================== */

.aim-th__filter-icon {
    font-size: 10px;
    color: var(--ink-faint);
    cursor: pointer;
    opacity: 0;
    transition: opacity 0.15s ease;
}

.aim-table--sortable .aim-th:hover .aim-th__filter-icon {
    opacity: 0.5;
}

.aim-th__filter-icon.filtered {
    opacity: 1;
    color: var(--brand-on-surface);
}

.aim-table--dark-header .aim-th__filter-icon.filtered {
    color: var(--info-wash);
}

/* Action / non-filterable columns — never show the filter chevron */
.aim-th--no-filter .aim-th__filter-icon,
.aim-th--actions .aim-th__filter-icon,
.aim-th.actions-column .aim-th__filter-icon {
    display: none;
}

/* ==========================================================================
 * DARK-MODE SORT/FILTER ACCENT
 *
 * Sort + filter active states use --interactive-base / --action-primary,
 * which in dark mode both alias to --brand-identity (dark slate). Same hue
 * family as the dark header bg means the sorted-column text and filtered
 * chevron go invisible. Dracula has no "blue" — Cyan is its chrome accent
 * (used for selection markers, info indicators), and gives the same "active
 * sort" feel that --interactive-base blue does in light mode.
 * ========================================================================== */
/* Dark-mode chevron + filter-icon accent — pulls from the dark redeclaration
   of --aim-table-sort-indicator-color in theme-definitions.css (which itself
   aliases to --aim-table-header-color so the active marker reads bright on
   the dark band). The previous block forced a hardcoded #8be9fd Dracula cyan
   and also coloured the header CELL text the same colour — making the cell
   text invisible against the same-hue header bg. Header cell text now stays
   on --aim-table-header-color (light) via the light-mode rule above; only
   the chevron + filter icon need a dark-mode token swap, which the token
   alias handles transparently. */
[data-theme="aim-dark"] .aim-th__sort-arrow.active,
[data-theme="aim-dark"] .aim-th--sorted .aim-th__sort-arrow,
[data-theme="aim-dark"] .aim-th__filter-icon.filtered {
    color: var(--aim-table-sort-indicator-color);
}

/* ==========================================================================
 * RESPONSIVE â€” height tier (720p-tall laptops)
 * ========================================================================== */

/* Wave 4 (responsive plan §4.2): the width tiers are handled by the root
   font-size steps, but row height + header padding are px/token-fixed, so
   short viewports (≤799px tall — the 14" laptop is 720) get a compact step.
   One token change cascades to every aim-table consumer. */
@media (max-height: 799px) {
    .aim-table-wrapper {
        --aim-table-row-height: 32px;
        --aim-table-cell-padding: 0.375rem 0.625rem;
    }

    .aim-th {
        padding: 8px 14px;
    }
}

/* ==========================================================================
 * RESPONSIVE â€” mobile card layout
 * ========================================================================== */

/* ⚠ ADOPTION NOTE (2026-08-23, card mode reworked 2026-10-07 to follow ADR-0151) —
 * `aim-table--responsive` is opt-in AND has a markup contract.
 *
 * Audited 2026-08-23: **0 of 84 files that render `.aim-td` supply `data-label`**, and 0 used
 * this modifier. That is not an oversight to "switch on": the rules below turn each row into a
 * card whose label/value pairs are filled from `attr(data-label)`. So adopting it is per-table
 * markup work (a `data-label` on every `<td>`), not a CSS switch. responsive.md §3's DEFAULT recipe
 * for a wide table is the scroll wrapper, which `.aim-table-scroll { overflow-x: auto }` already
 * provides — cards are the upgrade, not the baseline.
 *
 * Card mode (ADR-0151 / docs/MOBILE_LANGUAGE_PLAN.md W1, "aim-table → Card list, three type
 * sizes"): each row is a white rounded card; the FIRST cell is the card's primary line (the row's
 * identity, no label); every other cell is a label/value pair; an actions cell (`.aim-td--actions`,
 * or a cell whose direct children are buttons) spans the full width with tap-sized buttons.
 * Three type sizes only: primary (--text-m-body / 600), value (--text-m-label), label
 * (--text-m-caption / 600, sentence case).
 *
 * Cells without `data-label` simply stack full-width with no label column, so a table can be
 * converted a few columns at a time instead of all-or-nothing.
 */
@media (max-width: 767px) {
    .aim-table--responsive .aim-table,
    .aim-table--responsive tbody,
    table.aim-table--responsive {
        display: block;
        width: 100%;
        min-width: 0;
        background: transparent;
    }

    /* Header hidden visually but kept for assistive tech; each cell carries its own label. */
    .aim-table--responsive thead {
        position: absolute;
        width: 1px;
        height: 1px;
        padding: 0;
        margin: -1px;
        overflow: hidden;
        clip: rect(0 0 0 0);
        clip-path: inset(50%);
        white-space: nowrap;
        border: 0;
    }

    .aim-table--responsive .aim-tr {
        display: block;
        height: auto;
        min-height: 0;
        max-height: none;
        margin: 0 0 8px;
        padding: 12px 16px;
        background: var(--raised);
        border: 0;
        border-radius: var(--radius-card-m);
        box-shadow: var(--lift-1);
    }

    /* No zebra or hover tint in card mode: the card is the unit, not the stripe.
       `:nth-child(n)` lifts specificity to beat `--striped`/`--hover`, which sit earlier. */
    .aim-table--responsive .aim-tr:nth-child(n) .aim-td,
    .aim-table--responsive .aim-tr:nth-child(n):hover .aim-td {
        background-color: transparent;
    }

    .aim-table--responsive .aim-td {
        display: block;
        max-width: none;
        overflow: visible;
        white-space: normal;
        text-overflow: clip;
        border-bottom: none;
        padding: 4px 0;
        font-size: var(--text-m-label);
        color: var(--ink);
        text-align: left;
    }

    /* Label/value pair: label column, value column. Element children go to the value column;
       a bare text node follows the ::before into the value column by auto-placement. */
    .aim-table--responsive .aim-td[data-label] {
        display: grid;
        grid-template-columns: minmax(0, 2fr) minmax(0, 3fr);
        column-gap: 12px;
        align-items: baseline;
    }

    .aim-table--responsive .aim-td[data-label] > * {
        grid-column: 2;
    }

    .aim-table--responsive .aim-td[data-label]::before {
        content: attr(data-label);
        grid-column: 1;
        font-size: var(--text-m-caption);
        font-weight: 600;
        letter-spacing: 0.03em;
        text-transform: none;
        color: var(--ink-muted);
    }

    .aim-table--responsive .aim-td--numeric {
        font-variant-numeric: tabular-nums;
    }

    /* Primary line: the first cell is the card's identity — larger, bold, no label. */
    .aim-table--responsive .aim-td:first-child {
        display: block;
        padding: 0 0 4px;
        font-size: var(--text-m-body);
        font-weight: 600;
        color: var(--ink);
    }

    .aim-table--responsive .aim-td:first-child::before {
        content: none;
    }

    /* Actions cell: full width under the pairs, buttons at the tap floor. */
    .aim-table--responsive .aim-td--actions,
    .aim-table--responsive .aim-td:not(:first-child):has(> button) {
        display: flex;
        flex-wrap: wrap;
        gap: 8px;
        padding-top: 8px;
    }

    .aim-table--responsive .aim-td--actions::before,
    .aim-table--responsive .aim-td:not(:first-child):has(> button)::before {
        content: none;
    }

    .aim-table--responsive .aim-td--actions > button,
    .aim-table--responsive .aim-td--actions > a,
    .aim-table--responsive .aim-td:not(:first-child):has(> button) > button {
        min-height: var(--tap);
    }
}

/* ==========================================================================
 * LOADING OVERLAY â€” applied to wrapper
 * ========================================================================== */

.aim-table-wrapper--loading {
    position: relative;
    pointer-events: none;
}

.aim-table-wrapper--loading::after {
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background: color-mix(in srgb, var(--raised) 70%, transparent);
    z-index: 3;
}

/* ==========================================================================
 * ACCESSIBILITY
 * ========================================================================== */

.aim-th:focus-visible {
    outline: 2px solid var(--brand-border-on-surface);
    outline-offset: -2px;
}

@media (prefers-contrast: high) {
    .aim-th,
    .aim-td {
        border-width: 2px;
    }
}

@media (prefers-reduced-motion: reduce) {
    .aim-th,
    .aim-td,
    .aim-table-footer__page-btn {
        transition: none;
    }
}
