/* ---- What a list page is, around its table --------------------------------
   The List archetype of style guide 6.3 is a header, a create panel behind the
   page's one action, a filter bar, the table, and a pager. This file is
   everything in that sentence except the header and the table: `.create-panel`
   (6.3), `.filter-bar` and `.pager` (7.8), and the row's `.table__menu` (7.6),
   which is not the table either but the menu that floats out of it.

   Its own file rather than a section of `tables.css`: that file is the table
   primitive and nothing else. Linked after it on every shell, because a list
   page is a table plus these.

   Tokens only. Nothing here writes a colour, a size or a duration that
   `tokens.css` does not name.

   One thing this file does NOT own: how the bar's own controls are drawn. An
   input or a select inside `.filter-bar` is drawn by the control block in
   `forms.css`, which lists `.filter-bar` among its scopes. Writing a second
   control block here is exactly the duplication that file was made to end.
   -------------------------------------------------------------------------- */

/* ---- The create panel -----------------------------------------------------
   A list page's one primary action, and the panel it opens above the table
   (style guide 6.3). A native `<details>`: the button is the summary, so the
   panel needs no script and no id anything has to agree on.

   The summary is drawn by `buttons.css` (the markup hands it `.btn`); what is
   here is only the marker the browser draws beside it, the box the summary
   takes in flow, and where the panel sits relative to it. */

.create-panel { margin: 0 0 var(--sp-24); }

.create-panel > summary {
  list-style: none;
  cursor: pointer;
}
.create-panel > summary::-webkit-details-marker { display: none; }

.create-panel__body { margin-top: var(--sp-12); }

/* The panel's own heading: the page's `h1` is above it, so this is an `h2`,
   and it reads as the panel's name rather than a second page title. */
.create-panel__title {
  margin: 0;
  font-size: var(--fs-h3);
  line-height: var(--lh-h3);
  font-weight: var(--fw-semibold);
  color: var(--ink);
}

/* Below `sm` the action fills the width, the way a `.btn-row` does: a 38px
   box floating at the left of a 390px screen reads as an afterthought, and
   this is the page's one action. */
@media (max-width: 40rem) {
  .create-panel > summary { width: 100%; }
}

/* ---- The filter bar -------------------------------------------------------
   A `<form method="get">` on a sunk strip above the table: a search box, up to
   four selects, then Apply and Clear. Fields wrap rather than shrink, because
   a select squeezed to 60px is a control nobody can read the current value of.

   `static/js/filter-bar.js` submits it on change when scripts run; the Apply
   button stays in the markup and stays visible, so the bar works untouched
   with scripts off and a reader who has changed three selects can still say
   when to ask. Filtering is URL state (`?show=`), so the answer is a page a
   reader can reload, bookmark and send. */

.filter-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: var(--sp-12);
  margin: var(--sp-16) 0;
  padding: var(--sp-16);
  background: var(--surface-sunk);
  border-radius: var(--radius-lg);
}

/* One field: its label above its control, the pair kept together when the row
   wraps. `min-width: 0` because a select's intrinsic minimum is its longest
   option, which is what pushes a flex row wider than its container. */
.filter-bar__field {
  display: grid;
  gap: var(--sp-4);
  align-content: end;
  flex: 0 1 13rem;
  min-width: 0;
}

/* The search box is the field that takes the room the others leave. */
.filter-bar__field--search { flex: 1 1 18rem; }

.filter-bar__field > label {
  font-size: var(--fs-ui);
  font-weight: var(--fw-medium);
  color: var(--ink-2);
  line-height: var(--lh-snug);
}

/* Apply and Clear sit at the far end of the bar, on the control line. */
.filter-bar__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-8);
  margin-left: auto;
}

/* The notice sits directly under the bar and belongs to it, so the two are
   one gap apart rather than two: the notice gives up its own top margin and
   the bar's bottom one is the space between them. */
.filter-bar + .filter-notice { margin-top: 0; }

/* Below `sm` a row of controls is a column of them: two 38px targets side by
   side on a 390px screen are neither reachable nor readable translated. */
@media (max-width: 40rem) {
  .filter-bar { align-items: stretch; }
  .filter-bar__field,
  .filter-bar__field--search { flex: 1 1 100%; }
  .filter-bar__actions { margin-left: 0; flex: 1 1 100%; }
  .filter-bar__actions > .btn { flex: 1 1 auto; }
}

/* ---- The pager ------------------------------------------------------------
   "21 to 40 of 191" at the left, Previous and Next at the right. A direction
   with nowhere to go is a `<span>` carrying `aria-disabled`, never a dead
   link: `buttons.css` already dims it, and this stops a pointer reaching it.

   Both directions are words, not arrows: no typed arrow anywhere, and no
   glyph either, so there is nothing here to turn the right way round. */

.pager {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-8) var(--sp-12);
  margin-top: var(--sp-16);
}

.pager__count {
  margin: 0;
  color: var(--slate);
  font-size: var(--fs-small);
  font-variant-numeric: tabular-nums;
}

.pager__nav {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-8);
  margin-left: auto;
}

.pager__nav [aria-disabled="true"] { pointer-events: none; }

@media (max-width: 40rem) {
  .pager__nav { margin-left: 0; width: 100%; }
  .pager__nav > * { flex: 1 1 auto; }
}

/* ---- An identifier column that is not a requirement ID --------------------
   `.table__id` and `.tag-id` both refuse to break, which is right for
   `PRE-6-RQ-01` and wrong for what a manufacturer actually records: a purl
   (`pkg:generic/helios/hx-2200-firmware@4.1.0`) is sixty characters that no
   line-breaking rule will split on its own, and a pill that may not break is a
   pill that pushes a 390px card sideways. This modifier is the one place the
   two give that up, on the cell that holds such a value. */

.table__id--free { white-space: normal; }
.table__id--free .tag-id {
  white-space: normal;
  overflow-wrap: anywhere;
}

/* ---- The row's action menu (style guide 7.6) ------------------------------
   More than two actions at the end of a row is one `<details>`, not a run of
   links. Native: it opens, closes and takes a keyboard with no script, and
   the summary is drawn by `buttons.css` because the markup hands it
   `.btn .btn-ghost .btn-small` rather than a fifth button kind being invented
   here. */

.table__menu {
  position: relative;
  display: inline-block;
  text-align: left;
}

.table__menu > summary {
  list-style: none;
  cursor: pointer;
}
.table__menu > summary::-webkit-details-marker { display: none; }

.table__menu__list {
  position: absolute;
  top: calc(100% + var(--sp-4));
  right: 0;
  z-index: var(--z-popover);
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 12rem;
  padding: var(--sp-4);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-pop);
}

.table__menu__item {
  display: block;
  padding: var(--sp-8) var(--sp-12);
  border-radius: var(--radius-sm);
  color: var(--ink);
  font-size: var(--fs-small);
  text-decoration: none;
  white-space: nowrap;
}
.table__menu__item:hover {
  background: var(--accent-soft);
  color: var(--accent-deep);
}

/* An absolutely positioned menu inside a scroll box is clipped by that box:
   `overflow-x: auto` computes `overflow-y` to `auto` as well, and there is no
   pair of values that scrolls sideways and lets a child out downwards. So the
   box gives up its scrolling for exactly as long as a menu is open, which is
   the only moment anything needs to leave it. */
.table-scroll:has(.table__menu[open]) { overflow: visible; }

/* Below 48rem the row is a card and the menu is the quiet block at the bottom
   of it: no floating, nothing to clip, and the card grows to hold it. */
@media screen and (max-width: 48rem) {
  .table__menu { display: block; }
  .table__menu__list {
    position: static;
    min-width: 0;
    margin-top: var(--sp-4);
    box-shadow: none;
  }
  .table__menu__item { white-space: normal; }
}
