/* SAB Portal — What a narrow window does.
 *
 * This is the one file that is not a component. It is here, last of the page
 * files and before the map, exactly where it sat in app.css, because several of
 * its rules depend on losing a tie to the rule they narrow.
 *
 * One of the files listed in layers.css; read that first. Every rule below
 * is in the `app` cascade layer, so it beats Pico without needing to be
 * more specific than Pico. Sizes come from tokens.css and nowhere else. */

@layer app {

.sab-handoff-latest {
  color: var(--pico-muted-color);
  margin-left: auto;
}

/* --- Responsive ---------------------------------------------------------
 *
 * The page frame, the dashboard choices, the fact grids and the end/recording
 * cards are all `auto-fit` grids, so they reflow to one column on a phone
 * without a breakpoint. The listings need real work: a 15-column table is
 * genuinely wide, and the honest answer for an analytical table is to let it
 * scroll rather than to hide columns the reader came for.
 *
 * Two things make that scroll usable instead of merely possible: the first
 * column is pinned, so you never lose which row you are reading, and the page
 * says how many columns there are, so a reader knows to scroll at all. An
 * affordance nobody notices is the same as no affordance.
 */

/* Pin the identifying column. Applies at every width — a wide fleet table
 * benefits from it on a desktop too. */
.sab-table thead th:first-child,
.sab-table tbody td:first-child,
.sab-filter-row td:first-child {
  position: sticky;
  left: 0;
  z-index: var(--sab-layer-pinned);
  background: inherit;
}

/* No stripes: rows are told apart by a hairline and a generous height, and
 * the tint is kept for the row under the pointer. Opaque, for the pin. */
.sab-table tbody tr {
  background: var(--sab-row);
}

/* Pico paints every cell white, which hid the stripe on all but the pinned column. */
.sab-table tbody td,
.sab-table tbody th {
  background: inherit;
}

/* A row with a page behind it is a press, anywhere on it — row-link.js — and
 * says so the way the overview's rows do: a band, and its name in the accent. */
.sab-table tbody tr[data-href] {
  cursor: pointer;
}

.sab-table tbody tr[data-href] td {
  transition: background-color 120ms ease;
}

.sab-table tbody tr[data-href]:hover td:first-child a {
  color: var(--sab-action);
}

.sab-table tbody tr[data-href]:hover,
.sab-table tbody tr[data-href]:hover td {
  background: var(--sab-quiet-bg);
}

.sab-table thead tr,
.sab-table thead th,
.sab-filter-row,
.sab-filter-row td {
  background: var(--sab-row);
}

/* Shown at every width, not only on a phone. The table is wider than the
 * window on a desktop too, and there the scrollbar is worse than invisible:
 * macOS draws an overlay bar that appears only once you are already
 * scrolling, so the table reads as a table that was cut off rather than one
 * that continues. This line and the column chooser are the only two things
 * saying otherwise. */
.sab-scroll-hint {
  margin-left: auto;
  white-space: nowrap;
}

.sab-scroll-hint::after {
  content: " →";
}

@media (max-width: 48rem) {
  /* Two facts per row rather than one: still readable at this size, and it
   * halves how far a reader scrolls to see the whole record. */
  .sab-headline {
    grid-template-columns: repeat(auto-fit, minmax(8.5rem, 1fr));
    gap: .85rem var(--sab-gap-loose);
  }

  /* The hand-off card's four facts go to two columns in one step rather than
   * reflowing through three. Declared here because the row above it is the
   * same element, and the last rule wins. */
  .sab-handoff-facts {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--sab-gap-loose);
  }

  .sab-fact dd {
    font-size: var(--sab-text-body);
  }

  .sab-table th,
  .sab-table td {
    padding: .3rem var(--sab-gap);
    height: auto;
  }

  /* The advanced tables are label/value pairs with a fixed label column, which
   * cannot fit beside its value on a phone. Stack them instead. */
  .sab-advanced th,
  .sab-advanced td,
  .sab-record th,
  .sab-record td {
    display: block;
    width: auto;
    border-bottom: 0;
    padding: .1rem 0;
  }

  .sab-advanced th,
  .sab-record th {
    font-size: var(--sab-text-micro);
    text-transform: uppercase;
    letter-spacing: .04em;
    padding-top: .75rem;
  }

  .sab-advanced tr,
  .sab-record tr {
    display: block;
    border-bottom: var(--sab-hairline) solid var(--sab-rule);
    padding-bottom: var(--sab-gap);
  }

  .sab-login {
    margin: var(--sab-block) auto;
  }

  /* A column down the side needs a window with a side to spare. On a phone
   * there is none, so the shell stacks and the panel becomes a strip across
   * the top — the same panel, laid out the way it was before, rather than
   * something the reader has to open. */
  .sab-shell {
    display: block;
  }

  .sab-sidebar {
    position: static;
    flex-direction: row;
    flex-wrap: wrap;
    align-items: center;
    width: auto;
    height: auto;
    gap: var(--sab-gap);
    padding: var(--sab-gap) var(--sab-gap-loose);
    border-right: 0;
    border-bottom: var(--sab-hairline) solid var(--sab-rule);
  }

  /* The wordmark and the reader's corner share the first line; the sections
   * drop to their own row below, where they are wide enough to be tapped. */
  .sab-sidebar-brand {
    height: auto;
    padding: 0;
    border-bottom: 0;
  }

  .sab-sidebar-nav {
    order: 1;
    width: 100%;
    /* The sections scroll sideways inside the strip if the window is too
     * narrow for all of them. `min-width: 0` is what lets them: without it a
     * flex child refuses to shrink below its content and the strip — and with
     * it the whole page — grows wider than the phone instead. */
    min-width: 0;
    overflow-x: auto;
  }

  .sab-nav {
    flex-direction: row;
    align-items: center;
    gap: var(--sab-gap-tight);
  }

  .sab-nav a {
    margin: 0;
    white-space: nowrap;
  }

  /* Back to the top corner it came from, and its lists open downwards again
   * because there is a page below them now. */
  .sab-sidebar-end {
    flex-direction: row;
    align-items: center;
    margin-block-start: 0;
    margin-inline-start: auto;
    padding: 0;
    border-top: 0;
  }

  .sab-sidebar-end details.dropdown > summary + ul {
    top: 100%;
    bottom: auto;
    right: 0;
    left: auto;
    margin-top: var(--sab-gap-tight);
    margin-bottom: 0;
  }

  /* The search box fills the line and the two controls wrap to their own row
   * under it, where they are full-width taps rather than small inline buttons
   * pushed against one edge. */
  .sab-search-input {
    max-width: none;
  }

  /* Feedback sits beside the account on the top line, and its panel opens
   * down over the page from the strip's right edge, so it stays on screen. */
  .sab-sidebar-end {
    position: relative;
  }

  .sab-feedback {
    position: static;
  }

  .sab-feedback > summary {
    padding: var(--sab-gap-tight) var(--sab-gap);
  }

  .sab-feedback-panel {
    top: 100%;
    bottom: auto;
    right: 0;
    left: auto;
    margin-top: var(--sab-gap-tight);
    margin-bottom: 0;
  }

  .sab-filter-actions {
    width: 100%;
  }

  .sab-filter-actions button,
  .sab-filter-actions [role="button"],
  .sab-filter-actions .sab-columns {
    flex: 1 1 8rem;
    justify-content: center;
  }

  /* The chooser is the flex item; its summary is what is actually tapped, so
   * the item's share of the row has to be passed down to it. */
  .sab-filter-actions .sab-columns {
    padding-block: 0;
  }

  .sab-filter-actions .sab-columns.dropdown > summary:not([role]) {
    width: 100%;
    justify-content: center;
  }
}

/* The hand-off card holds two columns beside the two end cards. Below this
 * width that is three grids fighting for the same line, so the top row stacks
 * and the card's own two columns go one above the other. */
@media (max-width: 64rem) {
  .sab-detail-top {
    grid-template-columns: 1fr;
  }

  /* Stacked, the map's column is the whole screen, and a square of that is a
   * picture the reader scrolls past to reach the pipe. Held to the size it was
   * beside the card. Nothing beside it to match, so it goes back to a square. */
  .sab-detail-map {
    max-width: 24rem;
    flex: none;
    aspect-ratio: 1 / 1;
    min-height: 0;
  }

  /* A box's square was already small beside its facts, and stacking is not a
   * reason for it to grow past the size the reader met it at. */
  .sab-detail-top-brief .sab-detail-map {
    max-width: var(--sab-map-brief);
  }
}

@media (max-width: 30rem) {
  /* One card per row. Each card is already a whole end, so stacking them is
   * the same page in a column: the start box, then the end box. */
  .sab-pair {
    grid-template-columns: minmax(0, 1fr);
  }

  /* An audio player in half a phone is a row of controls with no track left
   * between them. One end above the other instead. */


  .sab-handoff-audio {
    grid-template-columns: 1fr;
  }
}
}
