/* Workspace table cards, adapted to native Rails tables and Kaminari. A card
 * scrolls sideways when its table is too wide, never vertically. */
.workspace .table-wrap { position: relative; max-width: 100%; overflow: auto hidden; border: 1px solid var(--line); border-radius: var(--card-radius); background: var(--surface); box-shadow: var(--card-shadow); container-type: scroll-state; }
.workspace table { width: 100%; border-collapse: separate; border-spacing: 0; color: var(--ink); font-size: .8125rem; text-align: left; }
.workspace caption { padding: .75rem; color: var(--muted); text-align: left; }
.workspace th, .workspace td { padding: .85rem 1.25rem; vertical-align: middle; overflow-wrap: normal; border-bottom: 1px solid var(--line); }
.workspace thead th { padding-block: .75rem; color: var(--table-heading); background: var(--canvas); font-size: .75rem; font-weight: 700; letter-spacing: .045em; text-transform: uppercase; }
.workspace thead a { color: inherit; }
.workspace tbody td, .workspace tbody th { height: 3.125rem; background: var(--surface); }
.workspace tbody tr:last-child > * { border-bottom: 0; }
.workspace tbody tr:hover > *, .workspace tbody tr:focus-within > * { background: var(--row-hover); }
.workspace tbody tr[aria-selected="true"] > * { background: var(--selected); }

/* A table that is too wide for its card scrolls under its actions column
 * (th.row-actions-column, always last), which sticks to the right edge and
 * keeps its row's background. While more of the table lies under it, a
 * scroll-state query draws a line on its left edge and a soft shadow (a
 * gradient beside each cell, over its bottom border so rows join up; the
 * last row's stops at the table's edge, so the card has nothing to scroll
 * vertically).
 * Browsers without the query always show the line. Scroll padding keeps
 * keyboard focus clear of the column. Narrow screens, where the column would
 * cover most of the card, scroll it with the rest. */
@media (width >= 48rem) {
  .workspace .table-wrap:has(th.row-actions-column:last-child) { scroll-padding-inline-end: 11rem; }
  .workspace table:has(th.row-actions-column:last-child) tr > :last-child { position: sticky; right: 0; }
  .workspace table:has(th.row-actions-column:last-child) tr > :last-child::before { position: absolute; inset: 0 100% -1px auto; width: .75rem; background: linear-gradient(to left, rgb(0 0 0 / 10%), transparent); content: ""; opacity: 0; pointer-events: none; }
  .workspace table:has(th.row-actions-column:last-child) tbody tr:last-child > :last-child::before { bottom: 0; }
  @supports not (container-type: scroll-state) {
    .workspace table:has(th.row-actions-column:last-child) tr > :last-child { box-shadow: inset 1px 0 var(--line); }
  }
  @container scroll-state(scrollable: inline-end) {
    .workspace table:has(th.row-actions-column:last-child) tr > :last-child { box-shadow: inset 1px 0 var(--line); }
    .workspace table:has(th.row-actions-column:last-child) tr > :last-child::before { opacity: 1; }
  }
}
.workspace tfoot th, .workspace tfoot td { padding-block: 1rem; border-top: 1px solid var(--line); font-weight: 700; }
.workspace .pagination { display: flex; flex-wrap: wrap; align-items: center; gap: .375rem; margin-block: 1rem; }
.workspace .pagination a, .workspace .pagination span[aria-current] { display: inline-flex; align-items: center; justify-content: center; min-width: 2.75rem; min-height: 2.75rem; padding: .5rem .75rem; border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface); text-decoration: none; }
.workspace .pagination span[aria-current="page"] { border-color: var(--action); color: var(--on-action); background: var(--action); font-weight: 700; }

/* Row actions (TablesHelper#table_row_actions): an "Actions" toggle opens the
 * row's links and buttons in a native popover. The popover is in the top layer,
 * so .table-wrap's scrolling cannot clip it, but it still inherits from the
 * cell. Only the toggle whose menu is open gets the anchor name. With anchor
 * positioning the menu opens below the toggle, aligned to its right edge, and
 * flips above when there is no room. Without it, the menu keeps the popover's
 * default position, centred in the viewport.
 *
 * After an Edit link (table_edit_link), the toggle joins it as one split
 * button: the two share a border, and the toggle shows only its chevron. Its
 * "Actions" label is hidden as .visually-hidden hides text, so it still names
 * the toggle. Edit alone, or the toggle alone, keeps its own rounded shape.
 * Menu icons are muted; a danger item (table_menu_button danger:) uses the
 * error color, after a divider when other items come first. */
/* Keep the actions column only as wide as its controls. */
.workspace .row-actions-column { width: 1%; }
.workspace .table-row-actions { display: flex; align-items: center; }
/* When no row on the page has an actions menu, each lone pencil sits centred
 * under the column's header, which is wider. With menus, the column stays
 * left-aligned so lone pencils line up with the split buttons' pencils. */
.workspace table:has(th.row-actions-column:last-child):not(:has(.row-actions-toggle)) tr > :last-child { text-align: center; }
.workspace table:not(:has(.row-actions-toggle)) .table-row-actions { justify-content: center; }
.workspace .row-edit, .workspace .row-actions-toggle { padding: .5rem .75rem; white-space: nowrap; }
.workspace .row-edit:has(+ .row-actions-toggle) { border-start-end-radius: 0; border-end-end-radius: 0; }
/* The pencil, and the chevron joined to it, are square: their minimum width
 * matches every button's minimum height, and buttons center their content. */
.workspace .row-edit { min-width: max(2.75em, 44px); padding-inline: .625rem; }
.workspace .row-edit + .row-actions-toggle { min-width: max(2.75em, 44px); margin-inline-start: -1px; padding-inline: .625rem; border-start-start-radius: 0; border-end-start-radius: 0; }
.workspace .row-edit + .row-actions-toggle .row-actions-label { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0; }
.workspace th[scope="row"] > a { display: inline-flex; align-items: center; min-height: 1.5rem; }
.workspace .row-actions-toggle:has(+ :popover-open) { color: var(--on-action); background: var(--action); anchor-name: --row-actions; }
.workspace .row-actions-toggle:has(+ :popover-open) .icon { rotate: 180deg; }
.workspace .row-actions-menu { min-width: 12rem; max-width: calc(100vw - 2rem); padding: .375rem; border: 1px solid var(--border); border-radius: var(--radius); color: var(--ink); background: var(--surface); box-shadow: 0 .5rem 1.5rem rgb(0 0 0 / .18); }
.workspace .row-actions-menu:popover-open { display: flex; flex-direction: column; gap: .125rem; }
.workspace .row-actions-menu .button_to { display: block; }
.workspace .row-actions-menu .button_to:has(> .row-action-danger):not(:first-child) { margin-top: .25rem; padding-top: .25rem; border-top: 1px solid var(--line); }
.workspace .row-actions-menu .menu-item { min-height: max(2.75em, 44px); padding-inline: .75rem; border-radius: var(--radius); overflow-wrap: normal; }
.workspace .row-actions-menu .menu-item:hover { background: var(--selected); }
.workspace .row-actions-menu button:not(.row-action-danger) .icon { color: var(--muted); }
.workspace .row-actions-menu .row-action-danger, .workspace .row-actions-menu .row-action-danger:hover { color: var(--error); }
/* The popover clips overflow, so draw focus inside each item. */
.workspace .row-actions-menu :focus-visible { outline-offset: -2px; }
/* The open menu joins its button: they overlap by their 1px border, which
 * takes the button's color, and the corners where they meet are square.
 * index_table_controller.js marks a menu that flipped above its button. */
@supports (anchor-name: --row-actions) {
  .workspace .row-actions-menu { margin: -1px 0; border-color: var(--action); border-start-end-radius: 0; position-anchor: --row-actions; position-area: block-end span-inline-start; position-try-fallbacks: flip-block; }
  .workspace .row-actions-menu[data-placement="above"] { border-start-end-radius: var(--radius); border-end-end-radius: 0; }
  .workspace :is(.row-edit, .row-actions-toggle):has(~ .row-actions-menu:popover-open:not([data-placement="above"])) { border-end-start-radius: 0; border-end-end-radius: 0; }
  .workspace :is(.row-edit, .row-actions-toggle):has(~ .row-actions-menu:popover-open[data-placement="above"]) { border-start-start-radius: 0; border-start-end-radius: 0; }
}

/* Shared index table search and filters. Fields sit in a row and
 * wrap on narrow screens. The visible summary sits above the page links, as
 * the table card's footer. */
.workspace .table-controls { display: flex; flex-wrap: wrap; align-items: flex-end; gap: .5rem .75rem; }
.workspace .table-controls .field { flex: 1 1 12rem; margin: 0; }
.workspace .table-controls .actions { margin: 0; }
.workspace .table-summary { margin-block: 1rem 0; color: var(--muted); }
/* After a table, the summary is its card's footer band, like the header row:
 * the card's bottom corners move to it. It is not dimmed while results load,
 * so its "Updating results…" stays readable. Alone, as the empty result, it
 * stays plain text. */
.workspace .table-wrap:has(+ .table-summary) { border-end-start-radius: 0; border-end-end-radius: 0; }
.workspace .table-wrap + .table-summary { margin-block: 0; padding: .75rem 1.25rem; border: 1px solid var(--line); border-top: 0; border-radius: 0 0 var(--card-radius) var(--card-radius); color: var(--table-heading); background: var(--canvas); box-shadow: var(--card-shadow); font-size: .75rem; }
.workspace td .hint, .workspace th .hint { display: block; font-weight: 400; }
.workspace caption .hint { margin-left: .25em; }
.workspace .sort-indicator { margin-left: .25em; }
/* Turbo replaces a table frame's contents on each search, sort, or page
 * change. Browser scroll anchoring then shifts the page by any change in the
 * table's height, so pages with an index table keep their scroll position. */
.workspace main:has(.index-table) { overflow-anchor: none; }
/* Turbo sets aria-busy on the frame while it loads new results. */
.workspace .index-table[aria-busy="true"] .table-wrap { opacity: .6; cursor: progress; transition: opacity .15s; }
.workspace .index-table[aria-busy="true"] .table-summary::after { content: " Updating results…"; }
@media (prefers-reduced-motion: reduce) { .workspace .index-table[aria-busy="true"] .table-wrap { transition: none; } }

/* A compact search toolbar sits directly on the page, without a card. Keep
 * the labelled field from stretching across wide tables. Secondary filters
 * open in a native modal drawer on the right, with focus containment and Escape. */
.workspace .index-table > search { display: block; margin-bottom: 1rem; }
.workspace .table-controls .table-search { flex: 0 1 26rem; min-width: 0; max-width: 100%; }
.workspace .search-input-group { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem; }
.workspace .search-input-group input[type="search"] { flex: 1 1 12rem; }
.workspace .search-input-group input[type="submit"] { flex: none; width: auto; }
.workspace .table-filters { position: fixed; inset: 0 0 0 auto; width: min(26rem, 100%); max-width: 100%; height: 100dvh; max-height: 100dvh; margin: 0; padding: 1.5rem; overflow-y: auto; border: 0; border-left: 1px solid var(--panel-edge); border-radius: 1rem 0 0 1rem; color: var(--ink); background: var(--surface); box-shadow: var(--panel-shadow); }
.workspace .table-filters[open] { display: flex; flex-direction: column; gap: 1.5rem; }
.workspace .table-filters::backdrop { background: var(--backdrop); }
.workspace:has(.table-filters[open]) { overflow: hidden; }
.workspace .table-filter-header { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: .75rem; }
.workspace .table-filter-header h2 { margin: 0; font-size: 1.25rem; }
.workspace .table-filter-fields { display: grid; gap: 1.25rem; }
.workspace .table-filter-fields .field { min-width: 0; }
.workspace .table-filters .table-filter-actions { margin-top: auto; padding-top: 1rem; border-top: 1px solid var(--line); }
.workspace .table-clear { display: inline-flex; align-items: center; min-height: 2.75rem; margin-top: .75rem; }
.workspace .filter-pills { padding: 0; list-style: none; display: flex; flex-wrap: wrap; gap: .5rem; margin-top: .75rem; }
.workspace .filter-pill { display: inline-flex; align-items: center; gap: .5rem; min-height: 2rem; max-width: 100%; padding: .35rem .8rem; border: 1px solid var(--line); border-radius: 100px; background: var(--canvas); font-size: .8125rem; }
.workspace .index-table > search > .button_to { display: block; margin-top: .75rem; }
@media (max-width: 35rem) {
  .workspace .table-filters { padding: 1rem; }
  .workspace th, .workspace td, .workspace .table-wrap + .table-summary { padding-inline: .85rem; }
}
/* At full width the filters drawer has no left side to soften. */
@media (max-width: 26rem) {
  .workspace .table-filters { border-radius: 0; }
}
