/* SAB Portal — Sign in. The one page a reader sees before anything else works.
 *
 * 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 {

/* --- Sign in ------------------------------------------------------------
 *
 * The one page with a photograph on it. It is the only page an anonymous
 * visitor can reach, it carries no data, and it has one job — so it is the one
 * place where a picture costs nothing and says whose portal this is.
 *
 * Two marks, both on the card, at opposite ends of it: the S.A.B wordmark at
 * the top, centred, which portal this is; the Jensen mark at the foot, under a
 * hairline, whose it is. Neither goes on the photograph — the card is the one
 * surface on this page whose colour the portal controls.
 */

/* The blur is baked into the file, not applied here. A CSS `filter` on a
 * full-viewport layer is repainted by the compositor on every scroll and
 * resize, and it would force the browser to download the sharp original in
 * order to throw the detail away. Blurring first is also why the file is small:
 * a soft image has little high-frequency detail left for the encoder to spend
 * bytes on. See docs/30-procedures.md § 16 for how the file is produced. */
.sab-login-page {
  /* Behind the photograph, and what remains if it never arrives: the page is
   * still a light card on a dark ground, not white text on white. */
  background-color: var(--sab-login-ground);
  /* The scrim is part of the background, not an element over it. It darkens a
   * picture the portal does not control to a predictable ground: enough for the
   * language choice to be read in the corner, and enough for the card to read
   * as paper on top of it rather than as another pale patch. */
  background-image: linear-gradient(
      180deg,
      rgba(8, 11, 16, 0.62) 0%,
      rgba(8, 11, 16, 0.34) 45%,
      rgba(8, 11, 16, 0.62) 100%
    ),
    url("../img/login-background.ca941237929c.webp");
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
  min-height: 100vh;
}

/* The card sits in the middle of the window, not hung from the top of it. */
.sab-login-page .sab-shell-page > main {
  display: grid;
  place-items: center;
  min-height: 100vh;
}

/* The card. Everything a reader sees on this page sits on it, so that nothing
 * is ever read against the photograph. The overview's card corner. */
.sab-login {
  width: 100%;
  max-width: 22rem;
  margin: 0;
  padding: var(--sab-block-loose);
  background: var(--sab-login-card);
  border-radius: var(--sab-radius-card);
  box-shadow: var(--sab-login-card-shadow);
}

.sab-login input:not([type="checkbox"], [type="radio"]),
.sab-login button {
  border-radius: var(--sab-radius);
}

.sab-login button {
  font-weight: var(--sab-weight-medium);
}

/* The portal's name, as its mark. Centred and alone at the head of the card:
 * it is the page's heading, and the only thing on the card that is not part of
 * the form. */
.sab-login-wordmark {
  margin: 0 0 var(--sab-gap-loose);
  line-height: 0;
}

.sab-login-wordmark img {
  display: block;
  width: 7.5rem;
  height: auto;
  margin-inline: auto;
}

/* Centred under the wordmark: the head of the card is one centred group, the
 * form under it is left-aligned. */
.sab-login p.sab-login-sub {
  color: var(--pico-muted-color);
  font-size: var(--sab-text-body);
  text-align: center;
  margin-bottom: var(--sab-block);
}

.sab-login form :last-child {
  margin-bottom: 0;
}

/* Who runs the portal, under a hairline at the foot. Quiet by size and
 * position rather than by fading it: a company mark is either shown or it is
 * not. */
.sab-login-operator {
  margin: var(--sab-block) 0 0;
  padding-top: var(--sab-gap-wide);
  border-top: 1px solid var(--sab-rule);
  line-height: 0;
}

.sab-login-operator img {
  display: block;
  width: 5.25rem;
  height: auto;
  margin-inline: auto;
}

/* The language choice, in the corner of the page rather than in the card.
 *
 * It is the only control that sits on the photograph, so it brings its own
 * ground: a dark panel dark enough for white type whatever the picture behind
 * it is doing. `position: fixed` and not `absolute` because the corner of the
 * window is what was asked for, and this page never scrolls far. */
.sab-login-language {
  position: fixed;
  top: var(--sab-gap-wide);
  right: var(--sab-gap-wide);
  z-index: var(--sab-layer-panel);
}

.sab-login-language .sab-language {
  /* Pico draws the open list from these three; setting them here is the whole
   * of the dark skin, and it cannot drift from the summary above it. */
  --pico-dropdown-background-color: rgba(12, 16, 22, 0.92);
  --pico-dropdown-border-color: rgba(255, 255, 255, 0.18);
  --pico-dropdown-color: #ffffff;
}

.sab-login-language .sab-language details.dropdown > summary:not([role]) {
  border-color: rgba(255, 255, 255, 0.22);
  background: rgba(12, 16, 22, 0.62);
  color: rgba(255, 255, 255, 0.86);
  backdrop-filter: blur(6px);
}

/* The dark skin's own hover. Without it the sidebar's light one wins on
 * specificity and the button flashes a pale grey box on the photograph. */
.sab-login-language .sab-language details.dropdown > summary:not([role]):hover,
.sab-login-language .sab-language details.dropdown > summary:not([role]):focus-visible,
.sab-login-language .sab-language details[open].dropdown > summary:not([role]) {
  background: rgba(12, 16, 22, 0.82);
  color: #ffffff;
}

.sab-login-language .sab-language-choice {
  color: rgba(255, 255, 255, 0.78);
}

.sab-login-language .sab-language-choice:hover {
  background: rgba(255, 255, 255, 0.1);
  color: #ffffff;
}

.sab-login-language .sab-language-current {
  background: rgba(255, 255, 255, 0.16);
  color: #ffffff;
}

/* The tick, on the dark panel. `--sab-action` is a mid blue that all but
 * disappears against it. */
.sab-login-language .sab-language-current::after {
  color: #ffffff;
}

/* On a phone the card is the page: pushed clear of the top rather than centred
 * in a viewport it nearly fills, and clear of the language choice in the
 * corner above it. */
@media (max-width: 30rem) {
  .sab-login-page .sab-shell-page > main {
    place-items: start center;
    padding-top: var(--sab-page);
  }

  .sab-login {
    padding: var(--sab-block) var(--sab-gap-wide);
  }
}

/* The last row of a listing: where the list is up to, and the way to the rest
 * of it. Deliberately part of the table rather than a control below it — the
 * reader who has run out of rows is looking at the bottom of the table, and
 * that is where the answer should be.
 *
 * It is styled the same whether it is offering more rows or reporting that
 * there are none, because both are the same fact told at different times, and
 * a reader should not have to notice a change of appearance to read it. */
.sab-more td {
  padding: 0.9rem var(--sab-gap);
  text-align: center;
  background: var(--sab-quiet-bg);
  border-bottom: 0;
}

.sab-more-link {
  font-weight: var(--sab-weight-strong);
  margin-right: 0.75rem;
}

/* Only visible while a batch is in flight. htmx sets `htmx-request` on the
 * element for exactly that long, which is the whole of the loading state:
 * nothing is hidden, nothing moves, the row it will become simply takes a
 * moment to arrive. */

}
