/* Complement to style.css with what only exists in the web server: the login
   screen, the dashboard around the table, sending the list, the query selector
   and the progress of the running batch.

   The page has two states that never share the screen: the login, alone on a
   centered card, and the dashboard, a sidebar with the sections next to it.
   Everything below belongs to one of the two. */

/* The :not([hidden]) repeats through this file, on every element the script
   shows and hides. It is required: a display of its own beats the hidden
   attribute, and the section would show up out of turn. */

/* ---------- login ---------- */

.signin-screen:not([hidden]) {
  min-height: 100vh;
  display: flex;
  justify-content: center;
  padding: 24px;
}

.signin-card {
  width: 100%;
  max-width: 380px;
  /* Centered with a margin and not with align-items: a card taller than the
     window - the enrollment, with the QR and the key - would have its top
     pushed above the edge and out of reach, and this is what keeps it
     scrollable instead. */
  margin: auto;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 28px 26px 16px;
}

.signin-brand { display: flex; align-items: center; gap: 9px; }

.signin-name {
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-3);
  font-weight: 600;
}

.signin-card h1 {
  margin: 18px 0 2px;
  font-family: var(--font-title);
  font-size: 27px;
  font-weight: 600;
  line-height: 1.1;
}

.signin-hint { margin: 0 0 18px; font-size: 13px; color: var(--ink-2); }

.signin-card form { display: flex; flex-direction: column; gap: 14px; }
.signin-card input { width: 100%; }

/* The message sits outside the steps, at the foot of the card, so that it says
   the same thing in the same place at every step of the login. */
.signin-card .message { margin: 14px 0 0; text-align: center; min-height: 19px; }

/* One step on screen at a time. The gap is what the form had, since a step may
   carry more than the form. */
.signin-step:not([hidden]) { display: flex; flex-direction: column; gap: 14px; }

/* The QR of the enrollment. It is a PNG of a fixed size that the server draws;
   pixelated keeps the browser from blurring the modules when it scales, which
   is what makes a camera lose the code. */
.signin-qr {
  width: 180px;
  height: 180px;
  align-self: center;
  image-rendering: pixelated;
  border: 8px solid #fff; /* the quiet zone the reader needs, white in both themes */
  border-radius: 4px;
}

.signin-secret-hint { margin: 0; font-size: 13px; color: var(--ink-2); text-align: center; }

/* The key is read to be typed, so it wraps between the blocks of four and
   never inside one: a block split across two lines is where the eye loses its
   place. */
.signin-secret {
  display: block;
  text-align: center;
  font-size: 14px;
  line-height: 1.6;
  letter-spacing: 0.06em;
  color: var(--ink);
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 8px 10px;
}

/* Two columns of codes, so the ten of them are read at a glance and fit the
   card without scrolling. */
.recovery-list {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 6px 12px;
  margin: 0;
  padding: 12px;
  list-style: none;
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  font-family: var(--font-data);
  font-size: 14px;
  text-align: center;
}

/* The mark is the same square of the favicon, drawn with type instead of an
   image so it follows the accent colour in both themes. */
.mark {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  flex: none;
  border-radius: var(--radius);
  background: var(--accent);
  color: var(--surface);
  font-family: var(--font-title);
  font-size: 16px;
  font-weight: 600;
  line-height: 1;
}

/* ---------- dashboard ---------- */

/* Wide enough for the name of the firm to fit on one line beside the mark and
   the toggle, which is more than the longest section name asks for; wrapped in
   two, both read as two entries. Collapsed, the column is only what one icon
   button needs, plus the padding of the sidebar. */
:root { --sidebar: 280px; }

.shell:not([hidden]) {
  display: grid;
  grid-template-columns: var(--sidebar) minmax(0, 1fr);
  min-height: 100vh;
  transition: grid-template-columns 160ms ease;
}

.sidebar {
  display: flex;
  flex-direction: column;
  gap: 22px;
  padding: 22px 16px;
  background: var(--surface);
  border-right: 1px solid var(--line);
  position: sticky;
  top: 0;
  height: 100vh;
}

.brand { display: flex; align-items: center; gap: 10px; }
.brand-text { display: flex; flex-direction: column; line-height: 1.2; min-width: 0; }
.brand-text strong { font-family: var(--font-title); font-size: 16px; font-weight: 600; }
.brand-text small { font-size: 11px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--ink-3); }

.nav { display: flex; flex-direction: column; gap: 3px; }

.nav-item {
  display: flex;
  align-items: center;
  gap: 8px;
  font: inherit;
  font-size: 14px;
  text-align: left;
  color: var(--ink-2);
  background: none;
  border: 0;
  border-radius: var(--radius);
  padding: 9px 11px;
  white-space: nowrap;
  cursor: pointer;
}

/* The two items of the administration are taken out of the sidebar of whoever
   is not an administrator. The display above beats the hidden attribute, which
   is the trap the note at the top of the file is about. */
.nav-item[hidden] { display: none; }

.nav-item:hover { background: var(--surface-2); color: var(--ink); }

.nav-item[aria-current="true"] {
  background: var(--accent-soft);
  color: var(--accent);
  font-weight: 600;
}

/* How many queries are stored, next to the section that shows them. */
.nav-badge {
  margin-left: auto;
  font-size: 11.5px;
  font-variant-numeric: tabular-nums;
  color: var(--ink-3);
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 0 7px;
}

.nav-item[aria-current="true"] .nav-badge { color: var(--accent); background: var(--surface); border-color: var(--accent-soft); }

/* A running query pulls the eye to the section that follows it: the dot is the
   same one the status badges of the table use. */
.nav-badge--running { color: var(--active); border-color: var(--active); background: none; }

/* The current item repaints its badge, so the running state has to say it
   again from inside it or the green would only show on the other section. */
.nav-item[aria-current="true"] .nav-badge--running { color: var(--active); border-color: var(--active); }

.nav-badge--running::before {
  content: "";
  display: inline-block;
  width: 6px;
  height: 6px;
  margin-right: 5px;
  vertical-align: 1px;
  border-radius: 50%;
  background: currentColor;
}

/* ---------- the foot of the sidebar: theme and session ---------- */

.sidebar-foot {
  margin-top: auto;
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding-top: 16px;
  border-top: 1px solid var(--line);
}

/* The three choices sit in one strip, like a switch with three positions: the
   pressed one is the theme in force, and there is always exactly one. */
.theme {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 2px;
  padding: 2px;
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: var(--radius);
}

.theme-option {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 6px 0;
  color: var(--ink-3);
  background: none;
  border: 0;
  border-radius: calc(var(--radius) - 1px);
  cursor: pointer;
}

/* The icons are drawn as strokes so that a single colour, the one the button
   already carries, is enough to follow the state and the theme. */
.theme-option svg,
.nav-item svg,
.icon-button svg {
  width: 16px;
  height: 16px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.7;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.theme-option:hover { color: var(--ink); background: var(--surface); }

/* The theme in force is marked the same way as the section on screen, right
   above it: the soft accent behind it and the accent itself in the icon. In
   dark that also keeps the chosen one lighter than the strip, which is what
   reads as pressed. */
.theme-option[aria-pressed="true"] { color: var(--accent); background: var(--accent-soft); }

.session { display: flex; align-items: center; gap: 9px; min-width: 0; }

/* The initial of whoever is logged in, in the same square as the brand mark but
   quieter: it names the session, it is not the mark of the product. */
.avatar {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  flex: none;
  border-radius: 50%;
  background: var(--accent-soft);
  color: var(--accent);
  font-size: 13px;
  font-weight: 600;
  line-height: 1;
  text-transform: uppercase;
}

.session-text { display: flex; flex-direction: column; min-width: 0; line-height: 1.25; }

/* The name of the user comes from the database and can be anything: it is cut
   with an ellipsis instead of widening the sidebar or wrapping under itself. */
.session-user {
  font-size: 13.5px;
  font-weight: 600;
  color: var(--ink);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.session-text small { font-size: 11px; color: var(--ink-3); }

.icon-button {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  flex: none;
  margin-left: auto;
  color: var(--ink-3);
  background: none;
  border: 1px solid transparent;
  border-radius: var(--radius);
  padding: 0;
  cursor: pointer;
}

.icon-button:hover { color: var(--accent); border-color: var(--line-strong); background: var(--surface-2); }
.icon-button:disabled { opacity: 0.5; cursor: default; }
.icon-button:disabled:hover { color: var(--ink-3); border-color: transparent; background: none; }

.main {
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 20px;
  padding: 30px 28px 56px;
  max-width: 1240px;
}

/* The title on one side and the state selector on the other, which is the one
   control that governs the whole dashboard and not just the section on screen.
   Below 700px the selector drops to its own line and takes the full width. */
.main-head {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: 8px 24px;
}

.main-head-text { display: flex; flex-direction: column; gap: 4px; min-width: 0; flex: 1 1 320px; }

.main-head .scope { flex: 0 0 auto; }
.main-head .scope select { width: 260px; }

@media (max-width: 700px) {
  .main-head .scope, .main-head .scope select { width: 100%; flex: 1 1 100%; }
}

.main-head h1 {
  margin: 0;
  font-family: var(--font-title);
  font-size: clamp(24px, 3vw, 32px);
  font-weight: 600;
  letter-spacing: -0.01em;
  line-height: 1.1;
}

.main-head p { margin: 0; max-width: 68ch; color: var(--ink-2); font-size: 14px; }

.view:not([hidden]) { display: flex; flex-direction: column; gap: 20px; }

/* The footer sits at the bottom of the column, however short the section is. */
.main .footer { margin-top: auto; padding-top: 8px; }

/* ---------- the green notice ---------- */

.toasts:not(:empty) { display: flex; flex-direction: column; gap: 8px; }

.toast {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  max-width: 720px;
  padding: 12px 14px;
  border: 1px solid var(--active);
  border-left-width: 3px;
  border-radius: var(--radius);
  background: var(--surface);
  box-shadow: var(--shadow);
  color: var(--ink);
  font-size: 14px;
  animation: toast-in 180ms ease-out;
}

.toast::before {
  content: "";
  width: 8px;
  height: 8px;
  margin-top: 6px;
  flex: none;
  border-radius: 50%;
  background: var(--active);
}

.toast strong { font-weight: 600; }
.toast p { margin: 2px 0 0; font-size: 13px; color: var(--ink-2); }
.toast .toast-body { min-width: 0; }

.toast button {
  margin-left: auto;
  font: inherit;
  font-size: 13px;
  color: var(--ink-3);
  background: none;
  border: 0;
  padding: 0 2px;
  cursor: pointer;
}

.toast button:hover { color: var(--ink); }

@keyframes toast-in {
  from { opacity: 0; transform: translateY(-4px); }
  to { opacity: 1; transform: none; }
}

/* ---------- sending the list ---------- */

/* The form does not follow the width of the table: a line of a case number is
   short, and a text box as wide as the screen only makes it harder to read. */
.upload { padding: 18px; max-width: 940px; }

.upload-fields { display: flex; flex-wrap: wrap; gap: 18px; align-items: flex-start; }
.upload-fields .field--wide { flex: 2 1 360px; }
.upload-side { display: flex; flex-direction: column; gap: 14px; flex: 1 1 240px; min-width: 240px; }

.upload textarea {
  width: 100%;
  min-height: 200px;
  resize: vertical;
  font-family: var(--font-data);
  font-size: 13px;
  line-height: 1.6;
}

.upload input[type="file"] {
  padding: 6px 8px;
  font-size: 13px;
  color: var(--ink-2);
  background: none;
  border-style: dashed;
}

/* Without this the browser draws its own button, of another size and another
   colour, right next to the ones the page draws. */
.upload input[type="file"]::file-selector-button {
  font: inherit;
  font-size: 12.5px;
  font-weight: 500;
  color: var(--ink);
  background: var(--surface-2);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  padding: 4px 10px;
  margin-right: 10px;
  cursor: pointer;
}

.upload input[type="file"]::file-selector-button:hover { border-color: var(--accent); color: var(--accent); }

.help { font-size: 12px; color: var(--ink-3); }

.upload-actions { display: flex; align-items: center; gap: 10px; margin-top: 16px; }

.message { margin: 0 auto 0 0; font-size: 13px; color: var(--ink-2); }
.message--error { color: var(--failed); }

/* ---------- query selector ---------- */

.batches:not([hidden]) { padding: 14px 18px; display: flex; flex-direction: column; gap: 12px; }

.batches-row { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 14px; }
.batches-row .field--wide { flex: 1 1 320px; }
.batches select { width: 100%; }

.batches-state { display: flex; flex-direction: column; gap: 2px; padding-bottom: 7px; }
.batches-numbers { font-size: 12px; color: var(--ink-3); font-variant-numeric: tabular-nums; }

.progress {
  height: 4px;
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: 999px;
  overflow: hidden;
}

.progress span {
  display: block;
  height: 100%;
  width: 0;
  background: var(--accent);
  transition: width 240ms ease;
}

/* ---------- empty state ---------- */

#noData { color: var(--ink-2); }
#noData strong { display: block; color: var(--ink); font-weight: 600; margin-bottom: 4px; }
#noData .button { margin-top: 14px; }

/* ---------- administration ---------- */

/* The two sections of the administrator, drawn by admin.js: the users of the
   office and the trail of what everybody did. Both are built out of what
   style.css already has - the card, the fields, the buttons, the framed table -
   and only what is theirs alone is written here. */

/* The court chosen in the header, and the note about it in the footer, only
   mean something to the two sections that talk to a court. Both carry a
   display of their own, which beats the hidden attribute app.js sets: this is
   the same trap the note at the top of the file is about. */
.scope[hidden], .footer[hidden] { display: none; }

.admin-card { padding: 14px 18px; display: flex; flex-direction: column; gap: 12px; }

.admin-new { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 14px; }
.admin-new .field--wide { flex: 1 1 240px; }
.admin-new select { width: 180px; }

.admin-list { display: flex; flex-direction: column; gap: 10px; }

.admin-title {
  margin: 0;
  font-size: 11px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-3);
  font-weight: 600;
}

/* The head of the case table holds a button that carries its own padding; the
   ones here are plain text and have to be given theirs. */
.admin-table thead th { padding: 10px 12px; }
.admin-table tbody td { vertical-align: middle; }

/* The selector inside a row has no .field around it, so it is given the same
   look here: a control drawn by the browser next to the ones of the panel is
   the kind of thing that reads as a different page. */
.admin-role {
  font: inherit;
  font-size: 13px;
  color: var(--ink);
  background: var(--surface-2);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  padding: 5px 8px;
  min-width: 154px;
}
.admin-actions { width: 1%; }
.row-actions { display: flex; gap: 6px; justify-content: flex-end; }
.row-actions .button { padding: 5px 9px; font-size: 12px; white-space: nowrap; }

/* Removing somebody does not undo, unlike a batch, so the button says so once
   it is armed. */
.button--danger, .button--danger:hover { color: var(--failed); border-color: var(--failed); }

.admin-count { margin: 0; font-size: 13px; color: var(--ink-2); }
.admin-detail { color: var(--ink-2); font-size: 12.5px; }
/* A refused entry and a recovery code are what whoever opens this screen is
   looking for. */
.admin-watched { color: var(--suspended); }

/* Where a password just drawn stays. It is not a toast: one that fades after a
   few seconds is no place to read a password off, so this one only leaves when
   it is closed. */
.credential:not([hidden]) {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 14px;
  padding: 14px 18px;
  background: var(--accent-soft);
  border: 1px solid var(--accent);
  border-radius: var(--radius);
}

.credential-text { display: flex; flex-direction: column; gap: 4px; min-width: 240px; flex: 1 1 320px; }
.credential-text strong { font-weight: 600; }
.credential-text p { margin: 0; font-size: 13px; color: var(--ink-2); }

.credential-secret {
  font-family: var(--font-data);
  font-size: 16px;
  letter-spacing: 0.08em;
  word-break: break-all;
  color: var(--ink);
}

.credential .actions { margin-left: auto; }

/* ---------- the page of one case ---------- */

/* The two rules below are the table's, and are here and not in style.css
   because they only exist where there is a case page to open: the static
   report embeds that file and has nowhere to go. */
.row--open { cursor: pointer; }

/* The number of the case is a button so that the page is one Tab and one Enter
   away, and it is drawn as the plain number it replaced: a button that looks
   like a button in every line would turn the first column into a bank of them. */
.opener {
  font: inherit;
  font-family: var(--font-data);
  font-size: 12.5px;
  color: var(--accent);
  background: none;
  border: 0;
  padding: 0;
  text-align: left;
  cursor: pointer;
}

.opener:hover { text-decoration: underline; }

.case-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; }

.case-identity { padding: 18px; display: flex; flex-direction: column; gap: 14px; }

.case-number {
  margin: 0;
  font-family: var(--font-data);
  font-size: 19px;
  font-weight: 600;
  letter-spacing: -0.01em;
  word-break: break-all;
}

/* The legacy code and the date of the query: what identifies the case besides
   its number, in one line under it. */
.case-marks {
  margin: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 4px 16px;
  font-size: 12.5px;
  color: var(--ink-3);
}

.case-marks code { font-family: var(--font-data); }

.case-facts {
  margin: 0;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
  gap: 14px 20px;
  padding-top: 4px;
  border-top: 1px solid var(--line);
}

.fact { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.fact--wide { grid-column: 1 / -1; }

.fact dt {
  font-size: 11px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-3);
  font-weight: 600;
}

.fact dd { margin: 0; font-size: 13.5px; }

.case-link { margin: 0; }

.case-block { display: flex; flex-direction: column; gap: 10px; }
.case-body { padding: 14px 18px; }

.case-title {
  margin: 0;
  font-size: 11px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-3);
  font-weight: 600;
}

.case-parties, .case-entries {
  margin: 0;
  padding: 0;
  list-style: none;
  display: flex;
  flex-direction: column;
}

.case-parties li {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 4px 12px;
  padding: 8px 0;
  border-bottom: 1px solid var(--line);
}

.case-entries li { padding: 10px 0; border-bottom: 1px solid var(--line); }
.case-parties li:last-child, .case-entries li:last-child { border-bottom: 0; }
.case-parties li:first-child, .case-entries li:first-child { padding-top: 0; }

.case-role { font-size: 12.5px; color: var(--ink-2); }

.case-entry-type { margin-left: 10px; }
.case-entry-order { margin-left: 10px; font-size: 12px; color: var(--ink-3); }

/* The wording of the act, as the court wrote it: the line breaks of a
   certificate are part of the document, so they are kept. */
.case-entry-text {
  margin: 8px 0 0;
  white-space: pre-wrap;
  font-size: 13px;
  color: var(--ink-2);
  max-width: 88ch;
}

.case-empty, .case-note, .case-hint { margin: 0; font-size: 13px; color: var(--ink-2); max-width: 88ch; }
.case-note { color: var(--ink-3); }

.case-failure { padding: 14px 18px; display: flex; flex-direction: column; gap: 8px; }
.case-failure h3 { margin: 0; font-size: 14px; font-weight: 600; }
.case-error { margin: 0; font-size: 13px; color: var(--failed); }

/* ---------- the collapsed menu ---------- */

/* Collapsed, the sidebar is a rail of icons: what named them is clipped instead
   of removed, so the names stay in the accessibility tree and each item keeps
   the accessible name it had open. The tooltip in app.js is what says the same
   thing to the mouse.
   Only in the column layout: below, the sidebar is already a bar and there is
   nothing to collapse. */
@media (min-width: 861px) {
  :root[data-sidebar="collapsed"] { --sidebar: 64px; }

  [data-sidebar="collapsed"] .sidebar { padding: 22px 10px; }

  [data-sidebar="collapsed"] .brand-text,
  [data-sidebar="collapsed"] .nav-label,
  [data-sidebar="collapsed"] .session-text {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }

  /* With no text to sit beside, the mark and everything under it line up in the
     middle of the rail, and the toggle drops below the mark. */
  [data-sidebar="collapsed"] .brand,
  [data-sidebar="collapsed"] .session {
    flex-direction: column;
    align-items: center;
    gap: 8px;
  }

  [data-sidebar="collapsed"] .icon-button { margin-left: 0; }
  [data-sidebar="collapsed"] .sidebar-toggle svg { transform: rotate(180deg); }

  [data-sidebar="collapsed"] .nav-item { position: relative; justify-content: center; padding: 9px 0; }

  /* The count has no room next to the icon, so it becomes a dot in the corner:
     it only says there are queries, and green says one of them is running. */
  [data-sidebar="collapsed"] .nav-item .nav-badge {
    position: absolute;
    top: 5px;
    right: 9px;
    width: 8px;
    height: 8px;
    margin: 0;
    padding: 0;
    font-size: 0;
    background: var(--ink-3);
    border-color: transparent;
    border-radius: 50%;
  }

  [data-sidebar="collapsed"] .nav-item .nav-badge--running { background: var(--active); }
  [data-sidebar="collapsed"] .nav-badge--running::before { display: none; }

  /* The strip of three becomes a column of three: side by side they would be
     narrower than the icons inside them. */
  [data-sidebar="collapsed"] .theme { grid-template-columns: 1fr; }
}

/* The sidebar turns into a bar over the content when there is no room for a
   column of its own. */
@media (max-width: 860px) {
  /* A bar has room for the names, wrapping when it needs to: there is nothing
     to collapse, so the toggle has nothing to do. */
  .sidebar-toggle { display: none; }

  .shell:not([hidden]) { grid-template-columns: minmax(0, 1fr); }

  .sidebar {
    position: static;
    height: auto;
    flex-direction: row;
    align-items: center;
    flex-wrap: wrap;
    gap: 12px;
    border-right: 0;
    border-bottom: 1px solid var(--line);
    padding: 14px 16px;
  }

  /* The names wrap onto a second line instead of running off the side: two
     items fit a phone in one row, and the four of an administrator do not. */
  .nav { flex-direction: row; flex-wrap: wrap; }

  .sidebar-foot {
    margin-top: 0;
    margin-left: auto;
    flex-direction: row;
    align-items: center;
    gap: 14px;
    padding-top: 0;
    border-top: 0;
  }

  /* In a row the strip has no column to fill, so each choice keeps the width of
     its icon instead of stretching across what is left of the bar. */
  .theme { grid-template-columns: repeat(3, auto); }
  .theme-option { padding: 6px 9px; }

  /* A bar has less room than a column: the session keeps the name and drops the
     line that only says the session is open. */
  .session-text small { display: none; }
  .session-user { max-width: 12ch; }

  .main { padding: 22px 16px 44px; }
}

@media (max-width: 700px) {
  .upload-actions { flex-wrap: wrap; }
  .batches .actions { margin-left: 0; }
}

/* Printing a section keeps only the table: the navigation, the form and the
   selector have nothing to say on paper. The :not([hidden]) repeats here
   because the rule it has to beat is the one that shows them on screen. */
@media print {
  .sidebar, .toasts, .main-head { display: none; }
  .upload, .batches:not([hidden]) { display: none; }
  .main { padding: 0; }
}
