@layer components {
  .table-wrapper {
    border: 1px solid var(--color-ink-lighter);
    border-radius: 1em;
    overflow: hidden;
    overflow-x: auto;
  }

  .table {
    border-collapse: collapse;
    inline-size: 100%;

    th,
    td {
      padding-block: var(--block-space-half);
      padding-inline: var(--inline-space);
      text-align: start;
      vertical-align: middle;
    }

    th {
      background-color: var(--color-ink-lightest);
      border-block-end: 1px solid var(--color-ink-lighter);
      color: var(--color-ink-dark);
      font-size: var(--text-small);
      font-weight: 600;
      white-space: nowrap;
    }

    td {
      border-block-end: 1px solid var(--color-ink-lighter);
    }

    tbody tr:last-child td {
      border-block-end: none;
    }

    @media (any-hover: hover) {
      tbody tr:hover td {
        background-color: var(--color-ink-lightest);
      }
    }

    .table__actions {
      text-align: end;
      white-space: nowrap;
    }

    .table__actions-header {
      inline-size: 1%;
    }

    /* Leading checkbox column — collapsed until select mode */
    .table__select {
      display: none;
      inline-size: 1%;
    }
  }

  .records-grid {
    display: grid;
    gap: var(--block-space);
    grid-template-columns: repeat(auto-fill, minmax(20rem, 1fr));
  }

  .record-thumbs {
    display: flex;
    flex-wrap: wrap;
    gap: var(--block-space-half);
  }

  .record-thumb {
    block-size: 3rem;
    border-radius: 0.4em;
    inline-size: 3rem;
    object-fit: cover;
  }

  /* Bulk selection */
  .bulk-bar {
    align-items: center;
    background-color: var(--color-ink-lightest);
    border-radius: 0.75em;
    display: none;
    gap: var(--block-space);
    margin-block-end: var(--block-space);
    padding: var(--block-space-half) var(--block-space);
  }

  .bulk-bar__count {
    color: var(--color-ink-dark);
    font-size: var(--text-small);
  }

  /* Select-all sits in a flex-centered label — drop the baseline nudge so the
     box lines up with the "Select all" text. */
  .bulk-bar .checkbox {
    transform: none;
  }

  /* Select-mode toggle: a small icon pill that fills in when active */
  .select-toggle {
    --btn-border-radius: 0.5em;
    --btn-padding: 0.35em;
  }

  .select-toggle[aria-pressed="true"] {
    --btn-background: var(--color-selected);
    --btn-color: var(--color-link);
  }

  /* Per-record checkbox — hidden until "Select" is toggled. Drop the base
     checkbox's baseline nudge so it sits centered in a table cell / card. */
  .record-select {
    display: none;
    transform: none;
  }

  /* Card checkbox pinned to the top-left corner (panel is already positioned) */
  .records-grid .record-select {
    inset-block-start: var(--block-space-half);
    inset-inline-start: var(--block-space-half);
    position: absolute;
  }

  .selecting .bulk-bar {
    display: flex;
  }

  .selecting .record-select {
    /* inline-grid (not flex) keeps the base checkbox's place-content centering of
       the checkmark, and being inline lets the table cell center it vertically. */
    display: inline-grid;
  }

  .selecting .table__select {
    display: table-cell;
  }

  [data-selectable].selected {
    box-shadow: 0 0 0 1px var(--color-link);
    border-color: var(--color-link);
  }

  .table tr[data-selectable].selected td {
    background-color: var(--color-selected);
  }

  /* A record's title link (grid cards and the table's first column): looks
     exactly like the surrounding text — no underline, ever. */
  .record-link {
    color: inherit;
    text-decoration: none;
  }

  /* Whole-card click: in the grid the title link stretches an invisible
     ::after over the panel, so the entire card navigates to the record while
     staying a real link (middle click, cmd-click, right-click all behave).
     Interactive children are raised above the cover below. */
  .records-grid .record-link::after {
    content: "";
    inset: 0;
    position: absolute;
  }

  /* Interactive elements inside a card stay clickable above the stretched
     cover. The menu and checkbox are already positioned (absolute) — they
     only need the z-index; static ones also need a positioning context. */
  .records-grid .panel :is(.record-menu, .record-select) {
    z-index: 1;
  }

  .records-grid .panel :is(a, button, label):not(.record-link) {
    position: relative;
    z-index: 1;
  }

  /* In a grid card the action menu is pinned to the corner, out of the
     content flow; the panel becomes its positioning context. */
  .panel:has(> .record-menu) {
    position: relative;
  }

  .panel > .record-menu {
    position: absolute;
    inset-block-start: var(--block-space-half);
    inset-inline-end: var(--block-space-half);
  }

  .record-menu__dropdown {
    --panel-padding-block: var(--block-space-half);
    --panel-padding-inline: var(--block-space-half);

    inline-size: max-content;
    min-inline-size: min(14rem, calc(100vw - var(--main-padding) * 2));

    /* Override the popover UA defaults (inset: 0; margin: auto) so the
       controller can pin it under the trigger with top/right. */
    &:popover-open {
      inset: auto;
      margin: 0;
    }

    form {
      display: contents;
    }
  }

  .callout {
    margin-inline: auto;
    max-inline-size: 42ch;
    padding-block-start: calc(20% - var(--header-height));
    text-align: center;
  }

  .modal {
    background: var(--color-canvas);
    border: 0;
    border-radius: 1em;
    box-shadow: var(--shadow);
    max-inline-size: min(42ch, 90vw);
    overflow-y: auto;
    padding: 0;
    width: min(42ch, 90vw);

    &[open] {
      animation: slide-up-fade-in 200ms ease;
    }

    &::backdrop {
      backdrop-filter: blur(2px);
      background: oklch(var(--lch-black) / 15%);
    }
  }

  .modal__content {
    padding: var(--block-space-double);
  }

  .modal__header {
    align-items: center;
    display: flex;
    justify-content: space-between;
    margin-block-end: var(--block-space);
  }
}
