/* Table */

table
{
  margin: 1rem 0;
  border-collapse: collapse;
}
table th,
table td
{
  padding: 0;
  text-align: left;
}
table th
{
  font-weight: bold;
  color: var(--text-secondary)
}
table td div.preserve-newlines
{
  max-width: 48rem;
}
table td.number
{
  text-align: right;
}
table th > a,
table td > a
{
  display: block;
}

/* The listing table fills the full viewport width. Each column fits its content with the last
   column taking up any remaining space. This isn’t possible with the table layout algorithm, so
   grid layout is used instead, requiring the number of columns to be set as a CSS variable. */

table.listing
{
  display: grid;
  grid-template-columns: repeat(calc(var(--columns) - 1), auto) 1fr;
  width: calc(100% + var(--inset-left) + var(--inset-right));
  margin: 1rem calc(-1 * var(--inset-right)) 1rem calc(-1 * var(--inset-left));
}
table.listing thead,
table.listing tbody,
table.listing tr
{
  display: grid;
  grid-column: 1 / -1;
  grid-template-columns: subgrid;
}
table.listing td
{
  display: block;
}
table.listing td:has(button),
table.listing td:has(a.button)
{
  align-self: center;
}

/* Padding is applied to the table cell, or instead to the “row link” inside it if present. An
   anchor element immediately inside a table cell in a “link row” is a “row link” when it has a
   href value with an absolute path and no class attribute value */

table th,
table tr:not(.link) td,
table tr.link td:not(:has(> a[href^="/"]:not([class]))),  /* regular link inside a link row */
table tr.link > td > a[href^="/"]:not([class])  /* row link inside a link row */
{
  padding: 0.25rem 0.5625rem;
}
table th:first-child,
table tr:not(.link) td:first-child,
table tr.link td:not(:has(> a[href^="/"]:not([class]))):first-child,
table tr.link > td:first-child > a[href^="/"]:not([class])
{
  padding-left: 0.25rem;
}
table th:last-child,
table tr:not(.link) td:last-child,
table tr.link td:not(:has(> a[href^="/"]:not([class]))):last-child,
table tr.link > td:last-child > a[href^="/"]:not([class])
{
  padding-right: 0.25rem;
}
table.listing th:first-child,
table.listing tr:not(.link) td:first-child,
table.listing tr.link td:not(:has(> a[href^="/"]:not([class]))):first-child,
table.listing tr.link > td:first-child > a[href^="/"]:not([class])
{
  padding-left: var(--inset-left);
}
table.listing th:last-child,
table.listing tr:not(.link) td:last-child,
table.listing tr.link td:not(:has(> a[href^="/"]:not([class]))):last-child,
table.listing tr.link > td:last-child > a[href^="/"]:not([class])
{
  padding-right: var(--inset-right);
}

/* Make sure empty row links fill the full height of the table cell they’re in */

table:has(tr.link)
{
  height: fit-content;
}
table tr.link > td > a[href^="/"]:not([class])
{
  height: 100%;
}

/* Hover and active styling for a row link is applied to the link row */

table.listing tr.link > td > a[href^="/"]:not([class]),
table.listing tr.link > td > a[href^="/"]:not([class]):active
{
  color: inherit;
  text-decoration: none;
}
table.listing tr.link:has(td > a[href^="/"]:not([class]):hover)
{
  background: var(--listing-background-hover);
}
table.listing tr.link:has(td > a[href^="/"]:not([class]):active)
{
  color: inherit;
  background: var(--listing-background-active);
}

/* A listing table has a sticky header row with smaller bold labels */

table.listing thead
{
  position: sticky;
  top: 0;
  background: var(--main-overlay);
  backdrop-filter: blur(0.4rem);
  font-size: var(--size-tiny);
}

/* Make a listing table with mostly empty columns easier to scan using dashes in empty cells. Note
   that the `:empty` psuedo-class requires the table cell to have no children (nodes or text) */

table.listing tbody td:empty:before,
table.listing tbody td > a:empty:before
{
  content: "–";
  color: var(--text-tertiary);
}

/* Borders above and below each listing table row with a stronger borders between the table head
   and table body. Note that we can’t rely on collapsing borders because grid layout is used instead
   if the table layout algorithm. */

table.listing tbody > tr
{
  border-bottom: 1px solid var(--border-secondary);
}
table.listing thead:has(+ tbody)
{
  border-bottom: 1px solid var(--border);
}
table.listing tbody:has(+ thead) > tr:last-of-type
{
  border-bottom: none;
}
table.listing tbody + thead
{
  border-top: 1px solid var(--border);
}

/* The sort Stimulus controller allow drag-and-drop changes to the order of listing table rows */

table.listing tr.ghosted td
{
  visibility: hidden;
}
table.listing tr.ghost
{
  border-bottom: 1px solid var(--border-secondary);
  background: var(--main-overlay);
  backdrop-filter: blur(0.4rem);
  pointer-events: none;
}
table.listing tr.ghost:before
{
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  top: -1px;
  border-top: 1px solid var(--border-secondary);
}
table.listing button.drag
{
  cursor: grab;
}
html:has(tr.ghosted) *
{
  cursor: grabbing !important;
}

/* A details table has top-aligned cell content and regular weight, right-aligned labels */

table.details tbody th,
table.details tbody td
{
  vertical-align: top;
}
table.details tbody th:first-child
{
  text-align: right;
  font-weight: normal;
  text-wrap: nowrap;
}

/* Allow details labels to wrap on narrower viewports */

@media (max-width: 24rem)
{
  table.details tbody th:first-child
  {
    text-wrap: wrap;
  }
}

/* Borders above and below each details table row */

table.details tbody > tr
{
  border-top: 1px solid var(--border-secondary);
  border-bottom: 1px solid var(--border-secondary);
}
