/*
  The one stylesheet for every screen (not the certificates or the inventory PDF, which carry
  their own). No framework and no build step: edit this file and deploy.

  The visual language is the old Access system's: full-width accent bars with white text above
  each section, content in bordered panels, dense tables with thin rules and a solid dark header
  row, and the logo top right. The brand blue is the accent.

  White on the accent passes WCAG AA only as large text, so text on it is kept bold and at
  least 1.2rem (about 19px); small text on the accent uses the dark blue instead.
*/

:root {
  --accent: #299be2;        /* the brand blue, from the logo */
  --accent-dark: #1a6fa6;   /* links, focus rings, small text on white */
  --accent-deep: #145a87;   /* hover */
  --accent-wash: #e8f4fc;
  --ink: #1e2328;
  --ink-soft: #545d66;
  --head: #333333;          /* the logo's dark grey: table header rows */
  --rule: #d3d8dd;          /* thin table rules */
  --line: #9aa4ad;          /* panel and control borders */
  --ground: #f2f4f6;
  --paper: #ffffff;
  --ok: #0f7b4b;
  --ok-wash: #e9f7f0;
  --warn: #c77700;
  --warn-edge: #f59e0b;
  --warn-wash: #fff7e6;
  --alert: #b91c1c;
  --alert-wash: #fdeeee;
}

*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  font: 14px/1.4 system-ui, -apple-system, "Segoe UI", Roboto, Arial, sans-serif;
  color: var(--ink);
  background: var(--ground);
}

a { color: var(--accent-dark); }
a:hover { color: var(--accent-deep); }

:focus-visible { outline: 2px solid var(--accent-dark); outline-offset: 1px; }

/* The hidden attribute must win. Without this, .badge's display rule shows a badge that was
   hidden — an amber "0 not readable" on every item teaches people to ignore it. */
[hidden] { display: none !important; }

/* -- Header: navigation left, who is signed in, logo top right ------------------------------ */

.app-header {
  display: grid;
  grid-template-columns: 1fr auto auto;
  grid-template-areas: "nav user logo";
  align-items: center;
  gap: .4rem 1.2rem;
  padding: .45rem 1rem;
  background: var(--paper);
  border-bottom: 4px solid var(--accent);
}

.app-nav { grid-area: nav; display: flex; flex-wrap: wrap; gap: .25rem; }
.app-nav a {
  display: inline-flex;
  align-items: center;
  gap: .35rem;
  padding: .4rem .7rem;
  border: 1px solid transparent;
  border-radius: 2px;
  color: var(--ink);
  font-weight: 600;
  text-decoration: none;
  white-space: nowrap;
}
.app-nav a:hover { border-color: var(--line); background: var(--ground); color: var(--ink); }
.app-nav a[aria-current="page"] { background: var(--accent); border-color: var(--accent); color: #fff; }

.app-user { grid-area: user; display: flex; align-items: center; gap: .6rem; color: var(--ink-soft); }
.app-user form { margin: 0; }

.app-logo { grid-area: logo; display: block; line-height: 0; }
.app-logo img { display: block; height: 40px; width: auto; }

/* -- Page ---------------------------------------------------------------------------------- */

main { max-width: 1280px; margin: 0 auto; padding: 1rem; }

h1 {
  margin: .2rem 0 1rem;
  padding-bottom: .35rem;
  border-bottom: 2px solid var(--accent);
  font-size: 1.45rem;
  line-height: 1.25;
}

/* The accent bar above a section. */
h2 {
  margin: 1.4rem 0 0;
  padding: .3rem .7rem;
  background: var(--accent);
  color: #fff;
  font-size: 1.2rem;
  font-weight: 700;
  line-height: 1.3;
  text-align: center;
}
h2 a, h2 a:hover {
  margin-left: .6rem;
  color: #fff;
  font-size: 1.2rem;
  font-weight: 700;
  text-decoration: underline;
  text-underline-offset: 2px;
}
h2 .badge { background: #fff; color: var(--ink); vertical-align: middle; }

/* On the page itself, what follows a bar sits in a bordered panel under it, whatever element it
   happens to be. Inside a panel the panel is already the box. */
main > h2 + table, main > h2 + dl, main > h2 + p, main > h2 + ul, main > h2 + form,
main > h2 + div:not(.panel) {
  margin-top: 0;
}
main > h2 + dl.fields, main > h2 + p, main > h2 + form:not(.actions) {
  padding: .6rem .8rem;
  border: 1px solid var(--line);
  border-top: none;
  background: var(--paper);
}
main > h2 + .panel { margin-top: 0; border-top: none; }

h3 { margin: 1rem 0 .4rem; font-size: 1rem; }

p { margin: .5rem 0; }

.muted { color: var(--ink-soft); }
.helptext { display: block; color: var(--ink-soft); font-size: .85rem; }

kbd {
  padding: 0 .3rem;
  border: 1px solid var(--line);
  border-radius: 2px;
  background: var(--paper);
  font: .85em ui-monospace, SFMono-Regular, Menlo, monospace;
}

/* -- Panels -------------------------------------------------------------------------------- */

.panel {
  margin: 1rem 0;
  padding: .7rem .9rem;
  border: 1px solid var(--line);
  background: var(--paper);
}
.panel > h2:first-child { margin: -.7rem -.9rem .7rem; }
.panel.alert { border-color: var(--alert); border-left-width: 5px; background: var(--alert-wash); }
.panel.warn { border-color: var(--warn-edge); border-left-width: 5px; background: var(--warn-wash); }
.panel ul { margin: .4rem 0 0; padding-left: 1.2rem; }
.panel table { background: var(--paper); }

/* -- Field lists --------------------------------------------------------------------------- */

dl.fields { display: grid; grid-template-columns: max-content 1fr; gap: .15rem 1rem; margin: 0; }
dl.fields dt { color: var(--ink-soft); }
dl.fields dd { margin: 0; overflow-wrap: anywhere; }

/* -- Tables: dense, thin rules, a solid dark header row ------------------------------------ */

table {
  width: 100%;
  border-collapse: collapse;
  border: 1px solid var(--line);
  background: var(--paper);
  font-size: .95em;
}
th, td {
  padding: .25rem .5rem;
  border-bottom: 1px solid var(--rule);
  text-align: left;
  vertical-align: top;
}
th { font-weight: 600; }
thead th {
  background: var(--head);
  color: #fff;
  border-bottom: none;
  white-space: nowrap;
}
tbody th { background: var(--ground); }
tfoot th, tfoot td { background: var(--ground); border-top: 1px solid var(--line); }
tbody tr:hover td { background: var(--accent-wash); }

tr.severe td, tr.severe:hover td { background: #fde2e2; }
tr.editing td, tr.editing:hover td { background: #f6f9fb; }
tr.correcting td, tr.correcting:hover td { background: var(--warn-wash); }

.row-actions { white-space: nowrap; }
.row-actions button { padding: .1rem .5rem; font-size: .85rem; }

/* -- Badges -------------------------------------------------------------------------------- */

.badge {
  display: inline-block;
  padding: .05rem .45rem;
  border: 1px solid var(--line);
  border-radius: 2px;
  background: var(--ground);
  color: var(--ink);
  font-size: .8rem;
  font-weight: 600;
  line-height: 1.4;
  vertical-align: middle;
}
.badge.alert { background: var(--alert); border-color: var(--alert); color: #fff; }
.badge.warn { background: var(--warn-edge); border-color: var(--warn-edge); color: var(--ink); }
.badge.count { font-size: .95rem; padding: .2rem .6rem; align-self: center; }
h1 .badge { font-size: .85rem; background: var(--accent-wash); border-color: var(--accent); color: var(--ink); }
.app-nav a .badge { font-size: .75rem; }
.app-nav a[aria-current="page"] .badge:not(.alert):not(.warn) { background: #fff; border-color: #fff; }

/* -- Messages ------------------------------------------------------------------------------ */

.messages { list-style: none; margin: 0 0 1rem; padding: 0; }
.messages li {
  margin-bottom: .4rem;
  padding: .45rem .75rem;
  border: 1px solid var(--ok);
  border-left-width: 5px;
  background: var(--ok-wash);
}
.messages li.warning { border-color: var(--warn-edge); background: var(--warn-wash); }
.messages li.error { border-color: var(--alert); background: var(--alert-wash); }

/* -- Buttons ------------------------------------------------------------------------------- */

button, .button {
  display: inline-block;
  padding: .35rem .85rem;
  border: 1px solid var(--line);
  border-radius: 2px;
  background: linear-gradient(#fff, #e9ecef);
  color: var(--ink);
  font: inherit;
  font-weight: 600;
  line-height: 1.3;
  text-decoration: none;
  cursor: pointer;
}
button:hover, .button:hover { border-color: var(--accent-dark); background: var(--accent-wash); color: var(--ink); }
button:active, .button:active { background: #dde3e8; }
button:disabled { opacity: .55; cursor: not-allowed; }

/* A form's own save button is the primary action on the screen. */
form.stacked > button[type=submit],
form.stacked > p > button[type=submit],
form.stacked > .actions > button[type=submit]:first-child {
  border-color: var(--accent-dark);
  background: var(--accent-dark);
  color: #fff;
}
form.stacked > button[type=submit]:hover,
form.stacked > p > button[type=submit]:hover,
form.stacked > .actions > button[type=submit]:first-child:hover {
  background: var(--accent-deep);
  color: #fff;
}

.app-user button { padding: .25rem .6rem; font-weight: 400; }

.actions { display: flex; flex-wrap: wrap; gap: .5rem; align-items: flex-start; }
.actions form { margin: 0; }

/* -- Forms --------------------------------------------------------------------------------- */

input:not([type=checkbox]):not([type=radio]):not([type=hidden]):not([type=file]),
select, textarea {
  max-width: 100%;
  padding: .3rem .45rem;
  border: 1px solid var(--line);
  border-radius: 2px;
  background: var(--paper);
  color: var(--ink);
  font: inherit;
}
input:focus, select:focus, textarea:focus {
  border-color: var(--accent-dark);
  outline: 2px solid var(--accent-wash);
  outline-offset: 0;
}
input[type=file] { max-width: 100%; font: inherit; }
input[type=checkbox], input[type=radio] { accent-color: var(--accent-dark); }
input[type=search] { width: 24rem; }

form.stacked p, form.stacked .field { margin: 0 0 .7rem; }
form.stacked label { display: block; font-weight: 600; }
form.stacked ul { list-style: none; margin: .2rem 0 0; padding: 0; }
form.stacked ul label { display: flex; align-items: center; gap: .35rem; font-weight: 400; }

.errorlist { margin: .2rem 0; padding-left: 1.2rem; color: var(--alert); font-weight: 600; }

details { margin: .5rem 0; }
summary { cursor: pointer; color: var(--accent-dark); font-weight: 600; }

/* A bar of fields: the defaults above item capture, and the scan bar. */
.defaults-bar, .scan-bar { display: flex; flex-wrap: wrap; gap: .5rem 1rem; align-items: flex-end; margin: .5rem 0; }
.defaults-bar label, .scan-bar label { display: flex; flex-direction: column; gap: .15rem; font-size: .85rem; color: var(--ink-soft); }
/* Inside a stacked form, form.stacked label would otherwise win on specificity and run each
   label into its select. */
form.stacked .defaults-bar label { display: flex; flex-direction: column; font-weight: normal; }
/* A tick reads along the line with its words, not stacked above them like a typed field. It has
   to out-specify the rule above, which would otherwise put the box on a line of its own. */
.defaults-bar label.tick,
form.stacked .defaults-bar label.tick { flex-direction: row; align-items: center; gap: .35rem; }

.scan-bar {
  position: sticky;
  top: 0;
  z-index: 5;
  padding: .6rem .8rem;
  border: 1px solid var(--line);
  border-top: 3px solid var(--accent);
  background: var(--paper);
  box-shadow: 0 2px 4px rgba(0, 0, 0, .06);
}
.scan-bar label.tick { flex-direction: row; align-items: center; gap: .3rem; }
#scan-serial { width: 22rem; font: 1.3rem ui-monospace, SFMono-Regular, Menlo, monospace; }

#scan-log { list-style: none; margin: .3rem 0; padding: 0; }
#scan-log li { margin-bottom: .25rem; padding: .3rem .6rem; background: var(--paper); border-left: 4px solid var(--ok); }
#scan-log li.refused { background: var(--alert-wash); border-left-color: var(--alert); }
#scan-log li.warning { background: var(--warn-wash); border-left-color: var(--warn-edge); }

.media-tools { display: flex; flex-wrap: wrap; gap: 1rem 2rem; align-items: flex-start; margin: 1rem 0; }
.resolve { margin-top: .6rem; padding-top: .4rem; border-top: 1px solid var(--rule); }

/* Search results to choose from. */
ul.results { list-style: none; max-width: 40rem; margin: .3rem 0 0; padding: 0; }
ul.results li button {
  display: block;
  width: 100%;
  padding: .35rem .6rem;
  border: 1px solid var(--line);
  border-top: none;
  border-radius: 0;
  background: var(--paper);
  font-weight: 400;
  text-align: left;
}
ul.results li:first-child button { border-top: 1px solid var(--line); }
ul.results li button:hover, ul.results li button:focus { background: var(--accent-wash); }
ul.results li.muted { padding: .3rem 0; }
.chosen { display: inline-block; margin-left: .5rem; font-weight: 600; }

ul.plain { list-style: none; margin: 0; padding: 0; }

.correction-note { margin: 0 0 .5rem; }
.correction-reason { margin: .5rem 0; }
.correction-reason label { display: block; font-weight: 600; }
.correction-reason textarea { width: 32rem; }

/* -- The inventory sheet page (its template is shared with the PDF and is not restyled) ----- */

#inventory-filter { align-items: center; margin-bottom: 1rem; }
.inventory-sheet table.summary { width: auto; min-width: 20rem; }
.inventory-sheet .num { text-align: right; }
.inventory-sheet table.job-details th { background: none; color: var(--ink-soft); font-weight: normal; }
.inventory-sheet table.job-details { margin-bottom: 1rem; }

/* -- Sign-in ------------------------------------------------------------------------------- */

.app-header.signed-out { grid-template-columns: 1fr auto; grid-template-areas: "nav logo"; }

/* -- Narrow screens (phones, down to 380px) ------------------------------------------------- */

@media (max-width: 760px) {
  .app-header {
    grid-template-columns: 1fr auto;
    grid-template-areas: "user logo" "nav nav";
    padding: .4rem .6rem;
  }
  .app-header.signed-out { grid-template-areas: "nav logo"; }
  .app-logo img { height: 32px; }
  .app-nav a { padding: .35rem .5rem; }

  main { padding: .75rem .6rem; }
  h1 { font-size: 1.25rem; }

  /* A wide table scrolls sideways inside itself; the page never does. */
  table { display: block; max-width: 100%; overflow-x: auto; }

  dl.fields { grid-template-columns: 1fr; gap: 0; }
  dl.fields dt { margin-top: .35rem; font-size: .85rem; }

  input[type=search], #scan-serial, .correction-reason textarea { width: 100%; }
  textarea { width: 100%; }
  .inventory-sheet table.summary { min-width: 0; }
}

/* -- The Secure Waste Transfer Form: the screen is the form --------------------------------- */
/* The blocks sit where they sit on the paper form (HW1453). Below 960px they stack in the
   order a driver or the desk reads them: header, figures, breakdown, notes, tags, signing. */

:root { --document: #8b1a1a; }

a.doc, button.doc, .button.doc { color: var(--document); }

.swtf-documents { align-items: center; margin-bottom: .6rem; }

.swtf-sheet {
  display: grid;
  gap: .7rem 1.1rem;
  padding: .8rem;
  border: 1px solid var(--line);
  background: var(--paper);
}
.swtf-sheet > * { min-width: 0; }

.swtf table { width: 100%; border: none; background: none; font-size: 1em; }
.swtf th, .swtf td { border-bottom: none; }
.swtf tbody tr:hover td { background: none; }
.swtf input:not([type=radio]):not([type=file]), .swtf select, .swtf textarea { width: 100%; }
.swtf [aria-invalid="true"] { border-color: var(--alert); outline: 2px solid var(--alert-wash); }

table.swtf-fields th {
  width: 8.5rem;
  padding: .12rem .5rem .12rem 0;
  background: none;
  color: var(--ink-soft);
  font-weight: 400;
  vertical-align: middle;
  white-space: nowrap;
}
table.swtf-fields td {
  height: 2.1rem;
  padding: .1rem .35rem;
  border: 1px solid var(--line);
  vertical-align: middle;
  overflow-wrap: anywhere;
}
table.swtf-fields td.strong { font-weight: 700; }

.swtf-book table.swtf-fields th { width: 10rem; color: var(--ink); font-size: 1.08rem; }
.swtf-book table.swtf-fields td { text-align: center; font-size: 1.08rem; }
.swtf-book tr.contact td { text-align: left; font-size: 1rem; }
.swtf-book tr.spacer td { height: .5rem; border: none; }
.swtf-book th.swtf-dim { color: #9aa4ad; font-weight: 700; }
.swtf-date, .swtf-date input { color: #c00000; font-weight: 700; }

.swtf-rule { height: .45rem; background: var(--head); }

.swtf-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .25rem .75rem;
  padding: .25rem .5rem;
  background: var(--head);
  color: #fff;
  font-weight: 700;
}
.swtf-bar.center { flex-direction: column; justify-content: center; gap: 0; text-align: center; }
.swtf-bar small { font-weight: 400; }
.swtf-bar-field {
  flex: 1 1 10rem;
  min-height: 1.9rem;
  padding: .1rem .3rem;
  background: var(--paper);
  color: var(--ink);
  font-weight: 400;
}
.swtf-box {
  min-height: 5.5rem;
  padding: .4rem;
  border: 1px solid var(--line);
  border-top: none;
  overflow-wrap: anywhere;
}
.swtf-box textarea { display: block; min-height: 5rem; resize: vertical; }

.swtf-grid thead th, .swtf-misc thead th {
  padding: .2rem .3rem;
  background: var(--head);
  color: #fff;
  text-align: center;
}
.swtf-grid tbody th, .swtf-misc tbody th {
  padding: .15rem .5rem .15rem 0;
  background: none;
  font-weight: 400;
  white-space: nowrap;
  vertical-align: middle;
}
.swtf-grid tbody th { font-size: 1.08rem; }
.swtf-grid tr.misc-total th { font-weight: 700; }
.swtf-grid td, .swtf-misc td {
  height: 2.5rem;
  padding: .1rem .2rem;
  border: 1px solid var(--line);
  text-align: center;
  vertical-align: middle;
}
.swtf-grid td { width: 32%; font-size: 1.08rem; }
/* Fixed layout, so the three breakdown tables keep the same columns when they stack. */
.swtf-misc { table-layout: fixed; }
.swtf-misc tr > :first-child { width: 40%; }
.swtf-misc tr > :not(:first-child) { width: 30%; }
.swtf-misc tbody th { white-space: normal; line-height: 1.2; }
.swtf-misc tr.empty th, .swtf-misc tr.empty td { height: 2.5rem; }
.swtf thead td { border: none; }
.swtf input.count { min-height: 2.5rem; padding: .2rem; text-align: center; font-size: 1.05rem; }

.swtf-misc-cols { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 0 .6rem; }
.swtf-signed-figures { margin: .3rem .4rem .4rem; font-size: .9rem; color: var(--ink-soft); }
.swtf-misc-note { margin: .3rem 0 0; font-size: .9rem; color: var(--ink-soft); }
.swtf-misc-note:empty { display: none; }
.swtf-misc-note.mismatch { color: var(--alert); font-weight: 600; }

.swtf-tags td { height: 2.5rem; padding: .1rem .3rem; border: 1px solid var(--line); vertical-align: middle; }
.swtf-tags td.cpt { width: 7.8rem; white-space: nowrap; letter-spacing: .2em; }
.swtf-tags td.initials { width: 4.5rem; }
.cpt .chosen { font-weight: 700; text-decoration: underline; }
.cpt .unchosen { color: var(--ink-soft); }
.cpt-choice { display: inline-flex; align-items: center; gap: .1rem; margin-right: .2rem; letter-spacing: 0; font-weight: 600; }

.swtf-duty { min-height: 0; font-size: .92rem; }
.swtf-duty p { margin: 0 0 .2rem; }
.swtf-prod, .swtf-co { padding-bottom: .4rem; border: 1px solid var(--line); }
.swtf-declaration { margin: .4rem .5rem; font-size: .92rem; }
.swtf-signing { margin: 0 .5rem; width: calc(100% - 1rem) !important; }
.swtf-signing th { width: 7rem !important; }
.swtf-sign { height: 2.8rem !important; }
.swtf-scan, .swtf-amend { padding: .5rem .6rem; border: 1px dashed var(--line); }
.swtf-scan input[type=file] { display: block; margin-top: .3rem; }
.swtf-amend ul { margin: .3rem 0 0; padding-left: 1.2rem; }

.swtf-save {
  position: sticky;
  bottom: 0;
  z-index: 4;
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: .6rem 1rem;
  margin-top: .7rem;
  padding: .6rem .8rem;
  border: 1px solid var(--line);
  border-top: 3px solid var(--accent);
  background: var(--paper);
  box-shadow: 0 -2px 4px rgba(0, 0, 0, .06);
}
.swtf-save .field { flex: 1 1 20rem; margin: 0; }
.swtf-save label { display: block; font-weight: 600; }

button.primary {
  min-height: 2.75rem;
  border-color: var(--accent-dark);
  background: var(--accent-dark);
  color: #fff;
}
button.primary:hover { background: var(--accent-deep); color: #fff; }

@media (min-width: 960px) {
  .swtf-sheet {
    grid-template-columns: repeat(12, minmax(0, 1fr));
    grid-template-areas:
      "src  src  src  src  src  src  book book book book book book"
      "rule rule rule rule rule rule rule rule rule rule rule rule"
      "com  com  com  com  com  com  com  com  cnt  cnt  cnt  cnt"
      "tag  tag  tag  tag  prc  prc  prc  prc  cnt  cnt  cnt  cnt"
      "tag  tag  tag  tag  msc  msc  msc  msc  msc  msc  msc  msc"
      "doc  doc  doc  doc  doc  doc  doc  doc  doc  doc  doc  doc"
      "prod prod prod prod prod prod prod prod co   co   co   co"
      "scan scan scan scan scan scan scan scan scan scan scan scan"
      "amnd amnd amnd amnd amnd amnd amnd amnd amnd amnd amnd amnd";
  }
  .swtf-src { grid-area: src; }
  .swtf-book { grid-area: book; }
  .swtf-rule { grid-area: rule; }
  .swtf-com { grid-area: com; }
  .swtf-cnt { grid-area: cnt; }
  .swtf-tag { grid-area: tag; }
  .swtf-prc { grid-area: prc; }
  .swtf-msc { grid-area: msc; }
  .swtf-doc { grid-area: doc; }
  .swtf-prod { grid-area: prod; }
  .swtf-co { grid-area: co; }
  .swtf-scan { grid-area: scan; }
  .swtf-amend { grid-area: amnd; }
}

@media (max-width: 959px) {
  .swtf-src { order: 1; }
  .swtf-book { order: 2; }
  .swtf-rule { display: none; }
  .swtf-cnt { order: 3; }
  .swtf-msc { order: 4; }
  .swtf-com { order: 5; }
  .swtf-prc { order: 6; }
  .swtf-tag { order: 7; }
  .swtf-doc { order: 8; }
  .swtf-prod { order: 9; }
  .swtf-co { order: 10; }
  .swtf-scan { order: 11; }
  .swtf-amend { order: 12; }
  .swtf-misc-cols { grid-template-columns: 1fr; }
  .swtf-misc-cols table + table thead { display: none; }
}

@media (max-width: 760px) {
  .swtf table { display: table; overflow: visible; }
  .swtf-sheet { padding: .5rem; }
  table.swtf-fields th, .swtf-book table.swtf-fields th { width: 7.2rem; font-size: .95rem; white-space: normal; }
  .swtf-book table.swtf-fields td { font-size: 1rem; }
  .swtf input.count, .swtf-tags td input, table.swtf-fields td input, table.swtf-fields td select { min-height: 44px; }
  .swtf-tags td.cpt { width: 6.6rem; }
  .swtf-tags td.initials { width: 3.6rem; }
  .swtf-signing th { width: 5.5rem !important; }
}

/* -- Goods in: the counts table, and forms that save from a bar at the foot ------------------- */

.field-row { display: flex; flex-wrap: wrap; gap: .6rem 1.2rem; align-items: flex-end; }
.field-row > label { display: flex; flex-direction: column; gap: .2rem; font-weight: 600; }
.field-row input, .field-row select { min-height: 2.5rem; }
label.stacked-label { display: block; font-weight: 600; }
label.stacked-label textarea { width: 100%; margin-top: .2rem; }

table.counts th[scope=row] { background: none; font-weight: 400; }
table.counts td { text-align: center; vertical-align: middle; }
table.counts th:first-child, table.counts td:first-child { text-align: left; }
table.counts input.count { width: 100%; min-height: 44px; padding: .2rem; text-align: center; font-size: 1.05rem; }
table.counts tr.informational th, table.counts tr.informational td { color: var(--ink-soft); }
table.counts .diff { color: var(--alert); font-weight: 700; }
#job-counts .diff { white-space: nowrap; }

.save-bar {
  position: sticky;
  bottom: 0;
  z-index: 4;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .6rem 1rem;
  margin-top: .8rem;
  padding: .6rem .8rem;
  border: 1px solid var(--line);
  border-top: 3px solid var(--accent);
  background: var(--paper);
  box-shadow: 0 -2px 4px rgba(0, 0, 0, .06);
}

@media (max-width: 760px) {
  .field-row > label { flex: 1 1 100%; }
  /* The counts table keeps its five columns and scrolls inside itself, as every wide table does.
     Forcing it to the screen's width would push the whole page sideways. */
  table.counts th[scope=row] { font-size: .95rem; white-space: nowrap; }
  table.counts input.count { min-width: 4.5rem; }
}

/* -- The balance ----------------------------------------------------------------------------- */

table.balance td.processed { white-space: nowrap; }
table.balance td.processed input.count { width: 4.5rem; display: inline-block; }
table.balance td.processed .muted { display: block; font-size: .8rem; }
table.balance td.explanation { width: 22rem; text-align: left; }
table.balance td.explanation input { width: 100%; min-height: 2.25rem; }
table.balance tr.outstanding th[scope=row] { font-weight: 700; }
table.balance tfoot th, table.balance tfoot td { font-weight: 700; }

#misc-breakdown { margin: .8rem 0; }
#misc-breakdown summary { padding: .3rem 0; }
#balance-informational { margin-top: .8rem; }

/* -- The WIP board --------------------------------------------------------------------------- */

/* Fourteen columns and nine categories: the board scrolls inside itself at any width, so the
   page never does. */
.table-scroll { overflow-x: auto; }
.table-scroll > table.board { width: auto; min-width: 100%; }
table.board td, table.board th { white-space: nowrap; }
table.board td.cell { text-align: center; width: 3.2rem; }
table.board td.cell .diff { color: var(--alert); font-weight: 700; }
table.board td.cell .clear { color: var(--ink-soft); }
table.board tr.overdue td.target { color: var(--alert); font-weight: 700; }
table.board tr.complete th[scope=row] a { color: var(--ok); }
table.board .blockers { color: var(--alert); font-weight: 600; }
table.board th[scope=row] { background: none; }

/* -- What is left in the category being captured --------------------------------------------- */

.capture-progress {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: .3rem .8rem;
  margin: .6rem 0;
  padding: .5rem .8rem;
  border: 1px solid var(--line);
  border-left: 5px solid var(--accent);
  background: var(--paper);
  font-size: 1.15rem;
}
.capture-progress .count { font-weight: 700; }
.capture-progress .left { color: var(--alert); font-weight: 700; }
.capture-progress .over { color: var(--warn); font-weight: 700; }
.capture-progress .done { color: var(--ok); font-weight: 600; }
.capture-progress.balanced { border-left-color: var(--ok); }

/* Administration is a different kind of thing from the working links: staff only, set apart. */
.app-nav .admin-link {
  margin-left: .5rem;
  padding-left: .9rem;
  border-left: 1px solid var(--rule);
  border-radius: 0 2px 2px 0;
  color: var(--ink-soft);
  font-weight: 400;
}
.app-nav .admin-link:hover { color: var(--ink); }

/* -- Stepping through a job's items, and the failure toggle ---------------------------------- */

.item-nav { display: flex; flex-wrap: wrap; align-items: center; gap: .6rem; margin: .6rem 0; }
.item-nav .position { color: var(--ink-soft); font-weight: 600; }
.item-nav .spent { opacity: .45; pointer-events: none; }
.row-actions .fail-toggle { color: var(--alert); }

/* -- The drive table scrolls in its own panel, never behind the scan bar --------------------- */
/* The bar carries the count and the serial field and stays put; the drives scroll beneath it.
   Capping the panel is what keeps them clear: a table that grows with 48 drives pushes the page
   down and slides its own rows under the pinned bar. */

/* Nothing here is pinned. The bar sits directly above the drives and the drives scroll inside
   their own panel, so the section stays compact at 48 drives and no row can ever pass behind the
   bar. Pinning the bar was what put rows behind it; pinning the workspace instead would have
   painted over the paste tools below. */
.media-workspace { display: flex; flex-direction: column; gap: .3rem; }
.media-scroll {
  max-height: min(60vh, 34rem);
  overflow-y: auto;
  overscroll-behavior: contain;
  border: 1px solid var(--line);
}
.media-scroll > table { border: none; }
/* Column headings stay while the drives scroll under them, beneath the bar, never over it. */
.media-scroll thead th { position: sticky; top: 0; z-index: 1; }
/* The bar no longer pins on its own: the workspace around it does. */
.scan-bar { position: static; }
#scan-log { max-height: 7rem; overflow-y: auto; }

/* Accounts tables: money reads down a right-aligned column, and an overdue row is marked
   without colour being the only signal — the days-overdue badge says it too. */
td.num, th.num { text-align: right; white-space: nowrap; font-variant-numeric: tabular-nums; }
tr.alert-row > td { background: #fdf3f3; }
tr.alert-row > td:first-child { box-shadow: inset 3px 0 0 #c0392b; }

/* -- The stock picker on an order ------------------------------------------------------------ */
/* Results scroll inside their own panel so the price box and the Add button stay put while you
   tick your way down a long list. The same reason the drive table scrolls in its own panel. */
.picker-scroll { max-height: min(50vh, 26rem); overflow-y: auto; border: 1px solid var(--line); }
.picker-scroll > table { border: none; }
.picker-scroll thead th { position: sticky; top: 0; z-index: 1; }
#picker-table td.tick-cell, #picker-table th.tick-cell { width: 2.5rem; text-align: center; }
/* A tap target you can hit without aiming, because this gets used a hundred rows at a time. */
#picker-table input[type="checkbox"] { width: 1.15rem; height: 1.15rem; }
.add-bar { align-items: end; gap: .75rem; padding: .35rem 0; }
#ticked-count { font-weight: 600; }
#bulk-price { width: 7rem; }

/* Units under a grouped line. */
.line-units summary { cursor: pointer; padding: .25rem 0; }
.units-row > td { padding-top: 0; }
table.unit-list { margin: .3rem 0 .6rem; width: auto; min-width: 28rem; }
table.unit-list th, table.unit-list td { padding: .2rem .5rem; }
/* Said explicitly: inside the expander the heading row was inheriting white text without the
   dark ground behind it, which left it near-invisible against the panel. */
table.unit-list thead th { background: var(--head); color: #fff; }

/* An internal order is a write-off, not a sale, and must never be mistaken for one. */
.badge.internal { background: var(--head); color: #fff; }

/* What a label print is doing, said on the page. A label that silently fails to print is the
   fault this replaces, so there is always somewhere for it to say so. */
.label-status {
  display: inline-block;
  margin: .3rem 0;
  padding: .15rem .45rem;
  font-size: .85rem;
  background: #eef4fb;
  border-left: 3px solid #2f9ae0;
}
.label-status[hidden] { display: none; }
.label-status a { margin-left: .3rem; }

/* The help page: the setup guide, rendered from markdown. Tables and numbered lists carry most
   of it, so they are styled to be read rather than skimmed. */
.help { max-width: 60rem; }
.help h1 { margin-top: 0; }
.help h2 { margin-top: 1.6rem; padding-top: .8rem; border-top: 1px solid #dfe4ea; }
.help table { border-collapse: collapse; margin: .8rem 0; width: 100%; }
.help th, .help td { border: 1px solid #cfd6de; padding: .4rem .6rem; text-align: left; vertical-align: top; }
/* The app's tables are white on dark; the guide's are read at length, so they are dark on pale
   and need the colour set as well as the background. */
.help th { background: #f2f5f8; color: #111; }
.help ol, .help ul { margin: .6rem 0 .6rem 1.4rem; padding-left: .6rem; }
.help li { margin: .25rem 0; }
.help code { background: #f2f5f8; padding: .05rem .25rem; }
/* A command or a URL is one long unbreakable word. On a phone it widened the whole page, so a
   code block scrolls inside itself and an inline one breaks rather than pushing the page out. */
.help pre { background: #f2f5f8; padding: .5rem .6rem; margin: .6rem 0; max-width: 100%;
            overflow-x: auto; }
.help pre code { background: none; padding: 0; white-space: pre; }
.help p > code, .help li code, .help td code { overflow-wrap: anywhere; }
.help-source { margin-top: 1.5rem; }

/* A rate's category belongs to one basis. Hidden for the others rather than asked and ignored. */
label:has([data-only-for][hidden]) { display: none; }

/* --- Custody and signatures on device -----------------------------------
   Read on an iPad in a yard, in daylight, by somebody wearing gloves: big
   targets, one column when the screen is narrow, nothing that scrolls sideways. */
.warn-box { border: 2px solid #8b1a1a; background: #fdf1f1; color: #6b1010;
            padding: .6rem .8rem; margin: 0 0 1rem; font-weight: bold; border-radius: 4px; }
.stage-list { list-style: none; margin: 0; padding: 0; display: grid; gap: .8rem;
              grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); }
.stage-card { border: 1px solid #c8d0d8; border-radius: 6px; padding: .8rem; background: #fff; }
.stage-card.done { border-color: #9bb89b; background: #f6fbf6; }
.stage-card .stage-open { font-size: 1.1rem; display: block; margin-bottom: .2rem; }
.stage-card .stage-who { color: #444; }
.stage-card .stage-state { margin-top: .4rem; }
.counts-grid { width: 100%; border-collapse: collapse; margin-bottom: .6rem; }
.counts-grid th, .counts-grid td { padding: .35rem .4rem; border-bottom: 1px solid #dde3e8;
                                   text-align: left; }
.counts-grid td.num, .counts-grid th.num { text-align: right; }
.counts-grid input[type=number] { width: 5rem; font-size: 1.1rem; padding: .45rem; }
.counts-grid .difference.over { color: #0a6b21; font-weight: bold; }
.counts-grid .difference.under { color: #8b1a1a; font-weight: bold; }
.photo-strip { list-style: none; margin: 0 0 .8rem; padding: 0; display: flex; flex-wrap: wrap;
               gap: .6rem; }
.photo-strip li { max-width: 140px; font-size: .78rem; color: #555; }
.photo-strip img { width: 100%; height: auto; border: 1px solid #c8d0d8; border-radius: 4px;
                   display: block; }
.signature-block { border-top: 1px solid #dde3e8; padding-top: .8rem; margin-top: .8rem; }
.signature-block h3 { margin: 0 0 .4rem; }
.pad-wrap { margin: .5rem 0; }
canvas.signature-pad { width: 100%; max-width: 600px; height: 200px; display: block;
                       border: 2px dashed #8a97a3; border-radius: 6px; background: #fff;
                       touch-action: none; }
.pad-clear { margin-top: .4rem; }
.signature-preview { border: 1px solid #c8d0d8; border-radius: 4px; background: #fff;
                     max-width: 100%; height: auto; }
.signed-already { margin: 0 0 .4rem; }
#stage-signatures .signature-form p { margin: .4rem 0; }
#stage-signatures input[type=text] { font-size: 1.05rem; padding: .45rem; max-width: 100%; }
#stage-complete button, #stage-signatures button[type=submit] { font-size: 1.05rem;
                                                                padding: .6rem 1rem; }
.change-reason { display: block; color: #6b1010; font-size: .85rem; }
@media (max-width: 820px) {
  .stage-list { grid-template-columns: 1fr; }
  .counts-grid input[type=number] { width: 4.5rem; }
  canvas.signature-pad { height: 170px; }
}

/* Offline: what is held on the device, and what it is waiting for. */
#waiting-to-sync ul { margin: .4rem 0 .6rem; padding-left: 1.2rem; font-weight: normal; }
#waiting-to-sync .refused { color: #6b1010; font-style: italic; }
#offline-ready { display: flex; align-items: center; gap: .8rem; flex-wrap: wrap; }
#prepare-offline { font-size: 1.05rem; padding: .6rem 1rem; }
.queued-note { margin: .4rem 0 0; font-weight: bold; color: #6b4a00; }

/* Movement projects: the scope is read before anything else on the page. */
.scope { font-size: 1.05rem; font-weight: 600; white-space: pre-wrap; margin: 0 0 .8rem;
         padding: .6rem .8rem; background: #fffbe6; border-left: 4px solid #c8a200;
         border-radius: 4px; }
.job-site { margin-bottom: 1rem; }
.job-site h3 { margin: .8rem 0 .3rem; }
table.personnel { width: 100%; border-collapse: collapse; margin-bottom: .6rem; }
table.personnel th, table.personnel td { text-align: left; padding: .3rem .4rem;
                                         border-bottom: 1px solid #dde3e8; }
.add-person { display: flex; gap: .6rem; flex-wrap: wrap; align-items: end; }
button.link { background: none; border: 0; color: #1f5f8b; text-decoration: underline;
              cursor: pointer; padding: 0; font: inherit; }
.field.internal { background: #fff4f4; padding: .4rem .6rem; border-radius: 4px; }

/* On site: the scope ticked off, the seals, the exceptions. */
#scope-tasks tr.done td { background: #f4faf4; }
#scope-tasks .initials { font-weight: bold; }
#container-list td { vertical-align: top; }
#exception-list { padding-left: 1.1rem; }

/* A blocker's own list: the things it means, to go and put right. */
.blocker-group { margin: .4rem 0 0; font-size: .92rem; }
.blocker-group a { margin-right: .1rem; }

/* A link that does what a button does, where the step needs a screen in between. */
a.button { display: inline-block; padding: .45rem .9rem; border: 1px solid #1f5f8b;
           border-radius: 4px; background: #1f7bc1; color: #fff; text-decoration: none; }
a.button:hover { background: #1a6aa8; }

/* The far end of a movement, before the load has left: shown so the night reads as one list,
   greyed because nobody at the loading bay can book anything in. */
.steps .step.waiting > details > summary { opacity: .55; }
.steps .step.waiting .step-waiting { background: #777; }

/* A rack, drawn. Every U is shown, empty ones included: a rack is mostly space, and where a
   unit goes is only legible against the space around it. An estimated position is dashed and
   says "estimated" in words — a colour on its own says nothing in a cold aisle at 4am. */
.rack-sides { display: flex; flex-wrap: wrap; gap: 1rem; }
.rack-side { min-width: 340px; }
.rack-side > summary { cursor: pointer; font-weight: bold; padding: .3rem 0; }
.rack-elevation { background: #fbfbfc; border: 1px solid #c9ced6; border-radius: 3px; }
.rack-elevation .u-slot { fill: #fff; stroke: #e6e9ee; stroke-width: 1; }
.rack-elevation .u-row.empty .u-slot { fill: #f6f7f9; }
.rack-elevation .u-number { font-size: 9px; fill: #6b7280; }
.rack-elevation .device rect { fill: #dbeafe; stroke: #1f5f8b; stroke-width: 1; }
.rack-elevation .device.estimated rect { stroke-dasharray: 4 3; }
.rack-elevation .device.highlight rect { fill: #fde68a; stroke: #b45309; stroke-width: 2; }
.rack-elevation .device.status-installed rect { fill: #dcfce7; stroke: #15803d; }
.rack-elevation .device.status-on-load rect { fill: #e0e7ff; stroke: #4338ca; }
.rack-elevation .device.status-delivered rect { fill: #ede9fe; stroke: #6d28d9; }
.rack-elevation .device.status-not-matched-yet rect { fill: #f3f4f6; stroke: #9ca3af;
                                                      stroke-dasharray: 3 3; }
.rack-elevation .device-label { font-size: 10px; fill: #11181f; }
.rack-elevation .device-status { font-size: 9px; fill: #374151; }
.rack-positions tr.highlight td { background: #fef3c7; }
.rack-note { margin: .4rem 0; }

/* The rack a unit came out of: U1 at the bottom, filled in as units are scanned out. The
   customer's list gives heights and not positions, so this starts empty on every job. */
.source-rack { width: 100%; }
.source-rack th { width: 3.2rem; text-align: right; font-weight: normal; color: #6b7280;
                  font-size: .85rem; padding: .1rem .4rem; }
.source-rack td { padding: .1rem .4rem; }
.source-rack tr.filled td { background: #dbeafe; }
.source-rack tr.highlight td, .source-rack tr.highlight th { background: #fde68a; }
.source-rack button.pick-u { padding: 0 .4rem; font-size: .8rem; color: #1f5f8b;
                             background: #fff; border: 1px dashed #c9ced6; }
.source-rack button.pick-u:hover { background: #eef5fb; border-style: solid; }

/* Scan to place: one screen, read at arm's length with a server in your arms. Everything on it
   is either the answer or the way to ask the next question. */
body.place-screen { margin: 0; background: #11181f; color: #f7f9fb; }
.place-scan { display: flex; align-items: center; gap: .6rem; padding: .5rem .8rem;
              background: #1f2a33; position: sticky; top: 0; z-index: 2; }
.place-scan label { font-size: .8rem; color: #9fb0bd; }
.place-scan input { flex: 1; font-size: 1.4rem; padding: .5rem .6rem; border-radius: 4px;
                    border: 2px solid #3b4d5c; background: #0b1116; color: #f7f9fb; }
.place-scan .place-out { color: #9fb0bd; text-decoration: underline; font-size: .9rem; }
#place-answer { padding: .8rem 1rem 3rem; }
/* Quiet labels, not banners: the rack and the U are the only loud things on this screen. */
.place-heading { font-size: .95rem; letter-spacing: .14em; color: #9fb0bd; margin: 1.1rem 0 .2rem;
                 font-weight: normal; background: none; border: 0; padding: 0; text-align: left;
                 text-transform: none; }
.place-where { font-size: 3.4rem; line-height: 1.05; margin: 0; font-weight: bold; }
.place-where .place-side { font-size: 1.3rem; color: #9fb0bd; font-weight: normal; }
.place-where .place-estimated { font-size: 1.3rem; color: #ffd37a; font-weight: normal; }
.place-what { font-size: 1.5rem; margin: .3rem 0 0; color: #d7e2ea; }
.place-cables { width: 100%; border-collapse: collapse; font-size: 1.3rem;
                background: none; color: #f7f9fb; border: 0; }
.place-cables tr { background: none; border-bottom: 1px solid #26323c; }
.place-cables td { padding: .4rem .4rem .4rem 0; vertical-align: top; background: none;
                   color: #f7f9fb; border: 0; }
.place-cables .cable-port { font-weight: bold; white-space: nowrap; }
.place-cables .cable-type { color: #9fb0bd; font-size: 1rem; }
.place-from { font-size: 1.2rem; color: #d7e2ea; margin-top: 1rem; }
.place-small { color: #9fb0bd; font-size: 1rem; }
.place-drawing { margin-top: .8rem; }
.place-drawing .rack-elevation { background: #0b1116; border-color: #3b4d5c; max-width: 100%; }
.place-drawing .rack-elevation .u-slot { fill: #11181f; stroke: #26323c; }
.place-drawing .rack-elevation .u-row.empty .u-slot { fill: #0e151b; }
.place-drawing .rack-elevation .u-number { fill: #6f8190; }
.place-drawing .rack-elevation .device rect { fill: #1d4e6b; stroke: #4f93bd; }
.place-drawing .rack-elevation .device.highlight rect { fill: #e2a93b; stroke: #ffd37a; }
.place-drawing .rack-elevation .device.highlight .device-label,
.place-drawing .rack-elevation .device.highlight .device-status { fill: #11181f; }
.place-drawing .rack-elevation .device-label { fill: #eaf2f7; }
.place-drawing .rack-elevation .device-status { fill: #9fb0bd; }
.place-shout { text-align: center; padding: 2rem 1rem; }
.place-shout h1 { font-size: 3.6rem; margin: 0 0 .4rem; letter-spacing: .04em; }
.place-shout.amber { background: #e2a93b; color: #11181f; border-radius: 6px; }
.place-shout.amber .place-small { color: #3a3120; }
.place-pick { list-style: none; padding: 0; display: grid; gap: .6rem; }
.place-pick a.button { display: block; font-size: 1.2rem; padding: .8rem; }
.place-done { display: flex; gap: .8rem; align-items: center; margin-top: 1.4rem;
              flex-wrap: wrap; }
.place-done button { font-size: 1.1rem; padding: .6rem 1rem; }
.place-done input[type=text] { font-size: 1.1rem; padding: .5rem; width: 4.5rem; }

/* Rack size: the common ones a press each, the real number in the box beside them. */
.rack-size .quick-size { padding: .35rem .7rem; }
.rack-size .quick-size.is-set { background: #1f7bc1; color: #fff; border-color: #1f5f8b; }
.rack-size input[type=number] { width: 4.5rem; }

/* Staging: impossible to mistake for live. */
.staging-banner { background: #b45309; color: #fff; font-weight: 700; text-align: center;
  padding: .4rem 1rem; letter-spacing: .02em; }
