@scope (table-ui) {
  :where(:scope) {
    /* ── Tokens ── */
    --table-font-size-default:        var(--a-ui-size);
    --table-heading-size-default:     var(--a-ui-xs);
    --table-heading-weight-default:   var(--a-weight-medium);
    --table-heading-tracking-default: 0.06em;
    --table-heading-fg-default:       var(--a-fg-muted);
    --table-heading-bg-default:       transparent;

    --table-fg-default:               var(--a-fg);
    --table-fg-hover-default:         var(--a-fg-strong);
    --table-fg-secondary-default:     var(--a-fg-muted);
    --table-border-default:           var(--a-border-subtle);
    --table-border-strong-default:    var(--a-border);
    --table-py-default:               var(--a-space-3);
    --table-px-default:               var(--a-space-4);

    --table-row-bg-default:           transparent;
    --table-row-bg-hover-default:     var(--a-bg-hover);
    --table-row-bg-selected-default:  var(--a-bg-selected);
    --table-row-bg-striped-default:   var(--a-bg-subtle);

    --table-sort-fg-default:          var(--a-fg-muted);
    --table-accent-default:           var(--a-primary);
    --table-fg-disabled-default:      var(--a-ui-text-disabled);
    --table-bg-default:               var(--a-bg);
    --table-radius-default:           var(--a-radius-lg);

    /* ── Resize + pinned-column intrinsics ── */
    --table-resize-width-default:     var(--a-space-1);
    --table-pin-shadow-width-default: var(--a-space-1);
    --table-cell-min-width-default:   11.25rem;

    /* ── Filter popover ── */
    --table-filter-bg-default:        var(--a-canvas);
    --table-filter-fg-default:        var(--a-canvas-text);
    --table-filter-border-default:    var(--a-border);
    --table-filter-radius-default:    var(--a-radius-md);
    --table-filter-inset-default:     var(--a-space-2);
    --table-filter-gap-default:       var(--a-space-1);
    --table-filter-shadow-default:    var(--a-shadow-md);
    --table-filter-input-py-default:  var(--a-space-1);
    --table-filter-input-px-default:  var(--a-space-2);
    --table-filter-input-radius-default: var(--a-radius-sm);
    --table-filter-input-size-default: var(--a-ui-tiny);
    --table-filter-btn-px-default:    var(--a-space-1);
    --table-filter-clear-fg-default:  var(--a-accent);

    /* ── Chips / filter bar ── */
    --table-chip-bar-bg-default:      var(--a-canvas-subtle);
    --table-chip-bar-border-default:  var(--a-border);
    --table-chip-bar-gap-default:     var(--a-space-1);
    --table-chip-bar-py-default:      var(--a-space-1);
    --table-chip-bar-px-default:      var(--a-space-2);
    --table-chip-dismiss-gap-default: var(--a-space-1);

    /* ── Detail / expansion row ── */
    --table-detail-bg-default:        var(--a-canvas-subtle);
    --table-detail-border-default:    var(--a-border);
    --table-detail-py-default:        var(--a-space-3);
    --table-detail-px-default:        var(--a-space-4);

    /* ── Pinning ── */
    --table-pinned-bg-default:        var(--a-canvas);
    --table-pinned-shadow-default:    var(--a-chrome-shadow-soft);

    /* ── Aggregation row ── */
    --table-agg-border-default:       var(--a-border);
    --table-agg-size-default:         var(--a-ui-tiny);
    --table-agg-py-default:           var(--a-space-2);
    --table-agg-px-default:           var(--a-space-3);

    /* ── Sort priority badge ── */
    --table-sort-priority-fg-default: var(--a-chrome-light);

    /* ── Sort icon gap ── */
    --table-sort-icon-gap-default:    var(--a-space-1);

    /* ── Footer / pagination ── */
    --table-footer-py-default:        var(--a-space-3);

    /* ── Overlays ── */
    --table-overlay-gap-default:      var(--a-space-3);
    --table-overlay-pad-default:      var(--a-space-8);

    /* ── Transitions ── */
    --table-duration-default:         var(--a-duration-fast);
    --table-easing-default:           var(--a-easing);

    /* ── State ── */
    --table-focus-ring-default:       var(--a-focus-ring);

    /* ── Z-index layers ── */
    --_z-cell:                0;
    --_z-pinned:              1;
    --_z-header:              2;
    --_z-header-pinned:       3;
  }

  /* ═══════ Base ═══════ */

  :scope {
    box-sizing: border-box;
    display: grid;
    overflow-x: auto;
    font-size: var(--table-font-size, var(--table-font-size-default));
    color: var(--table-fg, var(--table-fg-default));
    background: var(--table-bg, var(--table-bg-default));
    border: 1px solid var(--table-border, var(--table-border-default));
    border-radius: var(--table-radius, var(--table-radius-default));
    position: relative;
    /* Own stacking context — sticky headers, pinned columns, and filter
       dropdowns use internal z-indices that must not leak to parents. */
    isolation: isolate;
  }

  /* ═══════ Raw (no chrome — for embedding inside card-ui) ═══════ */

  :scope[raw] {
    background: none;
    border: none;
    border-radius: 0;
  }

  /* ═══════ Subgrid passthrough ═══════ */

  /* Rowgroup wrappers (header, body, footer) must participate in the
     parent grid so their children can use subgrid. */
  [data-header],
  [data-body] {
    display: grid;
    grid-template-columns: subgrid;
    grid-column: 1 / -1;
  }

  [role="row"] {
    display: grid;
    grid-template-columns: subgrid;
    grid-column: 1 / -1;
    align-items: center;
  }

  /* ═══════ Header row ═══════ */

  [data-header] {
    border-bottom: 1px solid var(--table-border-strong, var(--table-border-strong-default));
    position: sticky;
    top: 0;
    z-index: var(--_z-header);
    background: var(--table-bg, var(--table-bg-default));
  }

  /* ═══════ Column headers ═══════ */

  [role="columnheader"] {
    box-sizing: border-box;
    text-align: left;
    padding: var(--table-py, var(--table-py-default)) var(--table-px, var(--table-px-default));
    font-size: var(--table-heading-size, var(--table-heading-size-default));
    font-weight: var(--table-heading-weight, var(--table-heading-weight-default));
    color: var(--table-heading-fg, var(--table-heading-fg-default));
    background: var(--table-heading-bg, var(--table-heading-bg-default));
    text-transform: uppercase;
    letter-spacing: var(--table-heading-tracking, var(--table-heading-tracking-default));
    white-space: nowrap;
    position: relative;
    display: flex;
    align-items: center;
  }

  /* Label span truncates; sort icon + filter button remain visible.
     Cannot put overflow:hidden on the columnheader itself — it would
     clip the position:absolute filter dropdown. */
  [role="columnheader"] > span {
    flex: 1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  /* ═══════ Sortable headers ═══════ */

  [data-sort-key] {
    cursor: pointer;
    user-select: none;
    -webkit-user-select: none;
    transition: color var(--table-duration, var(--table-duration-default)) var(--table-easing, var(--table-easing-default));
  }

  [data-sort-key]:hover {
    color: var(--table-fg, var(--table-fg-default));
  }

  /* ═══════ Sort indicator ═══════ */

  [data-sort-icon] {
    color: var(--table-sort-fg, var(--table-sort-fg-default));
    margin-inline-start: var(--table-sort-icon-gap, var(--table-sort-icon-gap-default));
    vertical-align: middle;
    --a-icon-size: 0.75em;
  }

  [aria-sort] [data-sort-icon] {
    color: var(--table-fg, var(--table-fg-default));
  }

  [data-sort-priority] {
    display: inline-flex;
    font-size: 0.6em;
    background: var(--table-accent, var(--table-accent-default));
    color: var(--table-sort-priority-fg, var(--table-sort-priority-fg-default));
    width: 1em;
    height: 1em;
    border-radius: 50%;
    align-items: center;
    justify-content: center;
    margin-inline-start: 2px;
  }

  /* ═══════ Body cells ═══════ */

  [data-body] [role="gridcell"] {
    box-sizing: border-box;
    display: flex;
    align-items: center;
    align-self: stretch;
    padding: var(--table-py, var(--table-py-default)) var(--table-px, var(--table-px-default));
    border-bottom: 1px solid var(--table-border, var(--table-border-default));
    min-width: 0;
    /* Default: single line with ellipsis. Authors opt in to wrapping
       via [wrap] on the host (whole table) or [data-wrap] on a column /
       individual cell. Matches `<select-ui>` / `<nav-item-ui>` single-line
       row convention; long unbreakable strings (URLs, IDs) clip gracefully
       rather than rewrapping the row. */
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }

  /* text-overflow on a flex container doesn't reach text nodes (anonymous
     flex items). Built-in cell types now wrap text in <span>; link type
     creates <a>; avatar/progress composite types use row-ui > span. */
  [data-body] [role="gridcell"] > span,
  [data-body] [role="gridcell"] > a {
    min-width: 0;
    flex: 1;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  [data-body] [role="gridcell"] > row-ui {
    min-width: 0;
    overflow: hidden;
  }

  [data-body] [role="gridcell"] > row-ui > span {
    flex: 1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  /* Wrap opt-in: per-table (all body cells) or per-cell (one column).
     Restores the legacy `overflow-wrap: anywhere` behavior so wrapped
     content can break inside long unbroken tokens (URLs, IDs). Row
     height auto-grows to fit. */
  :scope[wrap] [data-body] [role="gridcell"],
  [data-body] [role="gridcell"][data-wrap] {
    white-space: normal;
    overflow: visible;
    text-overflow: clip;
    overflow-wrap: anywhere;
  }

  :scope[wrap] [data-body] [role="gridcell"] > span,
  :scope[wrap] [data-body] [role="gridcell"] > a,
  [data-body] [role="gridcell"][data-wrap] > span,
  [data-body] [role="gridcell"][data-wrap] > a {
    white-space: normal;
    overflow: visible;
    text-overflow: clip;
    overflow-wrap: anywhere;
  }

  [data-align="right"] {
    text-align: right;
    justify-content: flex-end;
  }

  [data-align="center"] {
    text-align: center;
    justify-content: center;
  }

  /* ═══════ Row states ═══════ */

  [data-body] > [role="row"] {
    background: var(--table-row-bg, var(--table-row-bg-default));
    transition: background var(--table-duration, var(--table-duration-default)) var(--table-easing, var(--table-easing-default));
  }

  [data-body] > [role="row"]:hover {
    background: var(--table-row-bg-hover, var(--table-row-bg-hover-default));
    color: var(--table-fg-hover, var(--table-fg-hover-default));
  }

  [data-selected] {
    background: var(--table-row-bg-selected, var(--table-row-bg-selected-default));
  }

  /* ═══════ Striped ═══════ */

  :scope[striped] [data-body] [role="gridcell"] {
    border-bottom: none;
  }

  :scope[striped] [data-body] > [role="row"]:nth-child(even) {
    background: var(--table-row-bg-striped, var(--table-row-bg-striped-default));
  }

  :scope[striped] [data-body] > [role="row"]:nth-child(even):hover {
    background: var(--table-row-bg-hover, var(--table-row-bg-hover-default));
  }

  /* ═══════ Selection checkboxes ═══════ */

  [data-check-col] {
    width: 2.5rem;
    text-align: center;
    flex-shrink: 0;
  }

  /* Selectable: checkbox column width is handled by the parent grid-template-columns.
     Subgrid rows inherit it automatically — no override needed. */

  /* ═══════ Density ═══════ */

  :scope[density="compact"] {
    --table-py-default: var(--a-space-1);
    --table-px-default: var(--a-space-2);
  }

  :scope[density="comfortable"] {
    --table-py-default: var(--a-space-4);
  }

  /* ═══════ Pinned cells ═══════ */

  [data-pinned="left"] {
    position: sticky;
    left: var(--_pin-left, 0);
    z-index: var(--_z-pinned);
    background: var(--table-bg, var(--table-bg-default));
  }

  [data-pinned="right"] {
    position: sticky;
    right: var(--_pin-right, 0);
    z-index: var(--_z-pinned);
    background: var(--table-bg, var(--table-bg-default));
  }

  [data-header] [data-pinned] {
    z-index: var(--_z-header-pinned);
  }

  /* ═══════ Resize handle ═══════ */

  [data-resize-handle] {
    position: absolute;
    right: calc(-1 * var(--table-resize-width, var(--table-resize-width-default)) / 2);
    top: 0;
    bottom: 0;
    width: var(--table-resize-width, var(--table-resize-width-default));
    cursor: col-resize;
    z-index: 1;
  }

  [data-resize-handle]:hover,
  [data-resize-handle][data-resizing] {
    background: var(--table-accent, var(--table-accent-default));
  }

  /* ═══════ Footer / pagination ═══════ */

  [data-footer] {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: var(--table-footer-py, var(--table-footer-py-default)) var(--table-px, var(--table-px-default));
    font-size: var(--table-heading-size, var(--table-heading-size-default));
    color: var(--table-heading-fg, var(--table-heading-fg-default));
    border-top: 1px solid var(--table-border, var(--table-border-default));
  }

  /* ═══════ Overlays (empty / loading / error) ═══════ */

  [data-overlay],
  [data-empty],
  [data-loading] {
    grid-column: 1 / -1;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: var(--table-overlay-gap, var(--table-overlay-gap-default));
    padding: var(--table-overlay-pad, var(--table-overlay-pad-default));
    color: var(--table-heading-fg, var(--table-heading-fg-default));
  }

  /* ═══════ Keyboard focus ═══════ */

  [data-focused] {
    outline: 2px solid var(--table-accent, var(--table-accent-default));
    outline-offset: -2px;
  }

  /* ═══════ Disabled ═══════ */

  :scope[disabled] {
    pointer-events: none;
    color: var(--table-fg-disabled, var(--table-fg-disabled-default));
  }

  :scope[disabled] [data-body] > [role="row"]:hover {
    background: var(--table-row-bg, var(--table-row-bg-default));
    color: var(--table-fg-disabled, var(--table-fg-disabled-default));
  }

  /* ═══════ Loading (skeleton rows) ═══════
     Skeleton rows replace real rows while [loading] is set on the host
     (see table.class.js #renderOverlays). Each row is a [data-skeleton-row]
     containing <skeleton-ui> cells. Inherit body-row layout so column
     widths track the header, then suppress hover/striping/click states
     (no real data to interact with). */

  [data-body] > [data-skeleton-row] {
    pointer-events: none;
  }

  [data-body] > [data-skeleton-row]:hover {
    background: transparent;
  }

  :scope[striped] [data-body] > [data-skeleton-row]:nth-child(even) {
    background: transparent;
  }

  /* No-op the dim-when-loading rule the old overlay relied on: with skeleton
     rows, the body IS the loading affordance — dimming it would just blur
     the shimmer. */

  /* ═══════ Filter UI ═══════ */

  [data-filter-btn] {
    all: unset;
    cursor: pointer;
    opacity: 0.5;
    padding: 0 var(--table-filter-btn-px, var(--table-filter-btn-px-default));
    &:hover { opacity: 1; }
  }

  [role="columnheader"] { position: relative; }

  [data-filter-dropdown] {
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    min-width: var(--table-cell-min-width, var(--table-cell-min-width-default));
    z-index: 10;
    background: var(--table-filter-bg, var(--table-filter-bg-default));
    border: 1px solid var(--table-filter-border, var(--table-filter-border-default));
    border-radius: var(--table-filter-radius, var(--table-filter-radius-default));
    padding: var(--table-filter-inset, var(--table-filter-inset-default));
    box-shadow: var(--table-filter-shadow, var(--table-filter-shadow-default));
    display: flex;
    flex-direction: column;
    gap: var(--table-filter-gap, var(--table-filter-gap-default));
  }

  [data-filter-input] {
    width: 100%;
    padding: var(--table-filter-input-py, var(--table-filter-input-py-default)) var(--table-filter-input-px, var(--table-filter-input-px-default));
    border: 1px solid var(--table-filter-border, var(--table-filter-border-default));
    border-radius: var(--table-filter-input-radius, var(--table-filter-input-radius-default));
    font: inherit;
    font-size: var(--table-filter-input-size, var(--table-filter-input-size-default));
    background: var(--table-filter-bg, var(--table-filter-bg-default));
    color: var(--table-filter-fg, var(--table-filter-fg-default));
  }

  [data-filter-op] {
    padding: var(--table-filter-input-py, var(--table-filter-input-py-default));
    border: 1px solid var(--table-filter-border, var(--table-filter-border-default));
    border-radius: var(--table-filter-input-radius, var(--table-filter-input-radius-default));
    font: inherit;
    font-size: var(--table-filter-input-size, var(--table-filter-input-size-default));
    background: var(--table-filter-bg, var(--table-filter-bg-default));
    color: var(--table-filter-fg, var(--table-filter-fg-default));
  }

  [data-filter-option] {
    display: flex;
    align-items: center;
    gap: var(--table-filter-gap, var(--table-filter-gap-default));
    font-size: var(--table-filter-input-size, var(--table-filter-input-size-default));
    cursor: pointer;
    padding: var(--table-filter-input-py, var(--table-filter-input-py-default)) 0;
  }

  [data-filter-clear] {
    all: unset;
    cursor: pointer;
    font-size: var(--table-filter-input-size, var(--table-filter-input-size-default));
    color: var(--table-filter-clear-fg, var(--table-filter-clear-fg-default));
    text-align: center;
    padding: var(--table-filter-input-py, var(--table-filter-input-py-default));
    &:hover { text-decoration: underline; }
  }

  /* ═══════ Filter Chips Bar ═══════ */

  [data-filter-bar] {
    grid-column: 1 / -1;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--table-chip-bar-gap, var(--table-chip-bar-gap-default));
    padding: var(--table-chip-bar-py, var(--table-chip-bar-py-default)) var(--table-chip-bar-px, var(--table-chip-bar-px-default));
    border-bottom: 1px solid var(--table-chip-bar-border, var(--table-chip-bar-border-default));
    background: var(--table-chip-bar-bg, var(--table-chip-bar-bg-default));
  }

  [data-chip-dismiss] {
    all: unset;
    cursor: pointer;
    margin-left: var(--table-chip-dismiss-gap, var(--table-chip-dismiss-gap-default));
    opacity: 0.6;
    &:hover { opacity: 1; }
  }

  [data-filter-clear-all] {
    all: unset;
    cursor: pointer;
    font-size: var(--table-filter-input-size, var(--table-filter-input-size-default));
    color: var(--table-filter-clear-fg, var(--table-filter-clear-fg-default));
    padding: var(--table-chip-bar-py, var(--table-chip-bar-py-default)) var(--table-chip-bar-px, var(--table-chip-bar-px-default));
    &:hover { text-decoration: underline; }
  }

  /* ═══════ Row Expansion ═══════ */

  [data-detail-row] {
    grid-column: 1 / -1;
    padding: var(--table-detail-py, var(--table-detail-py-default)) var(--table-detail-px, var(--table-detail-px-default));
    background: var(--table-detail-bg, var(--table-detail-bg-default));
    border-bottom: 1px solid var(--table-detail-border, var(--table-detail-border-default));
  }

  [data-expand-toggle] {
    all: unset;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: transform var(--table-duration, var(--table-duration-default)) var(--table-easing, var(--table-easing-default));
  }

  [data-expanded] [data-expand-toggle] {
    transform: rotate(90deg);
  }

  /* ═══════ Column Pinning ═══════ */

  [data-pinned] {
    position: sticky;
    z-index: 1;
    background: var(--table-pinned-bg, var(--table-pinned-bg-default));
  }

  [data-pinned="left"]::after {
    content: '';
    position: absolute;
    right: calc(-1 * var(--table-pin-shadow-width, var(--table-pin-shadow-width-default))); top: 0; bottom: 0;
    width: var(--table-pin-shadow-width, var(--table-pin-shadow-width-default));
    pointer-events: none;
    background: linear-gradient(to right, var(--table-pinned-shadow, var(--table-pinned-shadow-default)), transparent);
  }

  [data-pinned="right"]::before {
    content: '';
    position: absolute;
    left: calc(-1 * var(--table-pin-shadow-width, var(--table-pin-shadow-width-default))); top: 0; bottom: 0;
    width: var(--table-pin-shadow-width, var(--table-pin-shadow-width-default));
    pointer-events: none;
    background: linear-gradient(to left, var(--table-pinned-shadow, var(--table-pinned-shadow-default)), transparent);
  }

  /* ═══════ Aggregation Footer ═══════ */

  [data-agg-row] {
    display: grid;
    grid-template-columns: subgrid;
    grid-column: 1 / -1;
    border-top: 2px solid var(--table-agg-border, var(--table-agg-border-default));
    font-weight: 600;
    font-size: var(--table-agg-size, var(--table-agg-size-default));
    color: var(--table-fg-secondary, var(--table-fg-secondary-default));
  }

  [data-agg-row] > [role="gridcell"] {
    padding: var(--table-agg-py, var(--table-agg-py-default)) var(--table-agg-px, var(--table-agg-px-default));
  }
}
