/* ==========================================================================
   1. DESIGN TOKENS: change the look here
   --------------------------------------------------------------------------
   This is the ONE place that sets the app's colors, fonts, text sizes,
   spacing, corners and shadows. Everything below this block uses only these
   names (var(--...)), never a color or pixel size of its own; a test fails
   the build if one slips in. To change a color or size, change it here.
   The PDF and Excel exports read the same values from
   src/Pgfd.ShopTracker.Core/Reporting/BrandStyle.cs: change it there too.

   Screen-width breakpoints cannot be variables (CSS does not allow them in
   @media), so they are written in section 6:
     1100px  home tiles go from 3 across to 2
      900px  the left menu folds behind the "Menu" button
      700px  home tiles go 1 across; the search box stacks
   ========================================================================== */
:root {
  /* Brand and page colors */
  --color-navy: #142B4C;            /* top bar, current menu item, main buttons, headings */
  --color-navy-2: #1E3A66;          /* hover on navy, keyboard focus ring */
  --color-red: #B3261E;             /* PGFD badge, "Report a Problem" and real alerts only */
  --color-bg: #F4F2EE;              /* page background */
  --color-card: #FFFFFF;            /* menu, tiles, boxes, form fields */
  --color-ink: #1A1D23;             /* body text */
  --color-muted: #5B6270;           /* secondary text */
  --color-line: #D9D5CC;            /* borders and dividers */
  --color-line-soft: #EEEBE5;       /* lines between table rows and list rows */
  --color-link: #1F5FAD;            /* text links */
  --color-input-border: #767D8A;    /* form field borders (at least 3:1 against white) */
  --color-hover: #EEF2F8;           /* hover on white buttons and menu items */
  --color-icon-bg: #E9EDF4;         /* square behind a home tile's icon */
  --color-on-dark: #FFFFFF;         /* text and icons on navy or red */
  --color-on-dark-line: rgba(255, 255, 255, 0.5);   /* outlines of buttons on the navy bar */
  --color-on-dark-hover: rgba(255, 255, 255, 0.14); /* hover on the navy bar */
  --color-on-red-muted: #FDE5E3;    /* description on the red tile */
  --color-on-red-icon-bg: rgba(255, 255, 255, 0.18);
  --color-warn-border: #EBC874;     /* edge of a "watch out" box */
  --color-warn-ink: #5C3A00;        /* text in a "watch out" box */

  /* Status pills: text color (fg) on background (bg). The words always say the status; color only helps. */
  --pill-amber-fg: #8A5300;
  --pill-amber-bg: #FFF1CF;
  --pill-blue-fg: #1F5FAD;
  --pill-blue-bg: #E3EEFB;
  --pill-green-fg: #1E7B3A;
  --pill-green-bg: #DFF3E4;
  --pill-red-fg: #B3261E;
  --pill-red-bg: #FBE3E1;
  --pill-gray-fg: #5B6270;
  --pill-gray-bg: #EEEBE5;

  /* Fonts (installed on every county PC; no web fonts) */
  --font-body: "Segoe UI", system-ui, sans-serif;
  --font-mono: Consolas, "Cascadia Mono", monospace;
  --weight-normal: 400;
  --weight-semibold: 600;
  --weight-bold: 700;
  --weight-heavy: 800;

  /* Text sizes (body text never below 16px) */
  --text-small: 15px;               /* pills, table column headings */
  --text-body: 16px;                /* normal text */
  --text-lead: 17px;                /* intro lines, messages, list titles */
  --text-menu: 17px;                /* left menu items */
  --text-label: 17px;               /* form field labels */
  --text-button: 17px;              /* buttons */
  --text-input: 18px;               /* what people type */
  --text-brand: 18px;               /* "Tracker" next to the PGFD badge in the top bar */
  --brand-letters-height: 18px;     /* the customer's logo picture in the badge (its width follows; the markup says 65 x 18) */
  --brand-letters-max-width: 160px; /* the widest the logo may be, so a wide picture cannot push the search box off the bar */
  --text-search: 19px;              /* the big search box */
  --text-button-big: 19px;          /* big buttons */
  --text-h2: 20px;                  /* section headings */
  --text-tile-title: 22px;          /* home tile titles */
  --text-h1: 26px;                  /* page headings and the greeting */
  --text-record-id: 34px;           /* a record's ID at the top of its page */
  --text-ticket: 48px;              /* the work order number on the "Report sent" page and on the ticket tag */
  --text-tag-station: 80px;         /* the station number on the pickup tag, on screen */
  --text-tag-station-print: 112px;  /* the station number on the printed pickup tag, readable across the cart */
  --line-height: 1.45;
  --line-height-tight: 1.15;

  /* Spacing steps */
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 22px;
  --space-6: 32px;

  /* Corners, lines and shadows */
  --radius-sm: 6px;
  --radius: 9px;
  --radius-lg: 14px;
  --radius-pill: 999px;
  --border-thin: 1px;
  --border-thick: 2px;
  --border-accent: 6px;             /* colored left edge of a message box */
  --shadow-card: 0 1px 3px rgba(0, 0, 0, 0.07);
  --shadow-menu: 0 8px 24px rgba(20, 43, 76, 0.2);

  /* Sizes of things */
  --target-min: 44px;               /* smallest button, link or field anyone has to hit */
  --target-big: 56px;               /* big buttons and the big search box */
  --menu-width: 230px;              /* the left menu */
  --topbar-search-min: 280px;       /* the top bar search box: narrowest */
  --topbar-search-max: 600px;       /* ... and widest */
  --form-max: 560px;                /* widest a form gets */
  --signed-out-max: 640px;          /* the sign-in card */
  --tile-min-height: 124px;         /* home tiles */
  --tile-icon-box: 54px;            /* the square behind a tile's icon */
  --checkbox-size: 24px;            /* checkboxes and radio buttons */
  --qr-size: 240px;                 /* the authenticator QR code */
  --article-max: 760px;             /* widest a help article gets (an easy line length) */
  --demo-button-min: 300px;         /* demo sign-in buttons line up */
  --tag-height: 5in;                /* the ticket tag is a half page of letter paper (11in tall) less the margins */
  --hairline: 1px;                  /* hidden-but-readable text (screen readers) */
  --email-field-min: 200px;         /* narrowest an address box or its "Who this is" box gets before the two stack */

  /* Keyboard focus: a thick ring around whatever the keyboard is on */
  --focus-ring: 3px solid var(--color-navy-2);
  --focus-ring-on-dark: 3px solid var(--color-on-dark);
  --focus-offset: 2px;
}

/* ==========================================================================
   2. BASE ELEMENTS
   Plain HTML elements, the focus ring, the minimum target size, and helpers
   used on every page.
   ========================================================================== */
*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  background: var(--color-bg);
  text-size-adjust: 100%;
}

body {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
  margin: 0;
  background: var(--color-bg);
  color: var(--color-ink);
  font-family: var(--font-body);
  font-size: var(--text-body);
  line-height: var(--line-height);
}

h1 {
  margin: 0 0 var(--space-4);
  color: var(--color-navy);
  font-size: var(--text-h1);
  font-weight: var(--weight-heavy);
  line-height: var(--line-height-tight);
}

h2 {
  margin: var(--space-5) 0 var(--space-3);
  color: var(--color-ink);
  font-size: var(--text-h2);
  font-weight: var(--weight-bold);
  line-height: var(--line-height-tight);
}

p {
  margin: 0 0 var(--space-4);
}

a {
  color: var(--color-link);
  text-underline-offset: 0.15em;
}

a:hover {
  color: var(--color-navy);
}

code {
  font-family: var(--font-mono);
}

img {
  max-width: 100%;
}

button {
  font: inherit;
}

/* Keyboard focus is always visible: a thick ring, never the browser's thin dotted line. */
:focus-visible {
  outline: var(--focus-ring);
  outline-offset: var(--focus-offset);
}

/* Every control is at least --target-min tall, so it is easy to hit with a mouse, a finger or a glove: buttons,
   fields, menu items, links that stand on their own (.action-link) and checkbox/radio rows (.check-row). A link
   inside a sentence is the one exception (WCAG 2.5.8 allows inline links); a link alone in its paragraph is not. */
button,
input:not([type="checkbox"], [type="radio"], [type="hidden"]),
select,
.btn,
.brand,
.menu-link,
.topbar-button,
.demo-banner-link,
.skip-link,
.result-link,
.action-link,
.check-row,
.wo-row-note summary,
.outbox-body summary {
  min-height: var(--target-min);
}

textarea {
  min-height: calc(var(--target-min) * 2);
}

input[type="checkbox"],
input[type="radio"] {
  width: var(--checkbox-size);
  height: var(--checkbox-size);
  accent-color: var(--color-navy);
}

.icon {
  flex-shrink: 0;
}

/* A link that stands on its own ("Lost your phone? Use a recovery code"): a full-height target, not a thin line of text. */
.action-link {
  display: inline-flex;
  align-items: center;
  font-weight: var(--weight-semibold);
}

/* Text for screen readers only (for example the search box's label, whose hint is shown inside the box). */
.visually-hidden {
  position: absolute !important;
  width: var(--hairline);
  height: var(--hairline);
  margin: calc(var(--hairline) * -1);
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* "Skip to main content": the first thing the Tab key reaches; hidden until then. */
.skip-link {
  position: absolute;
  top: var(--space-2);
  left: var(--space-2);
  z-index: 1000;
  display: inline-flex;
  align-items: center;
  padding: var(--space-2) var(--space-4);
  border-radius: var(--radius);
  background: var(--color-card);
  color: var(--color-navy);
  font-weight: var(--weight-bold);
  transform: translateY(-300%);
}

.skip-link:focus {
  transform: none;
}

/* ==========================================================================
   3. LAYOUT
   The navy top bar, the white left menu, and the page content beside it.
   Signed-out pages (sign in) show the top bar and one centered card.
   ========================================================================== */

/* Top bar */
.topbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3) var(--space-5);
  padding: var(--space-3) var(--space-5);
  background: var(--color-navy);
  color: var(--color-on-dark);
}

.topbar :focus-visible {
  outline: var(--focus-ring-on-dark);
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: var(--space-3);
  color: inherit;
  font-size: var(--text-brand);
  font-weight: var(--weight-bold);
  text-decoration: none;
  white-space: nowrap;
}

a.brand:hover {
  color: inherit;
  text-decoration: underline;
}

/* The red box round the customer's badge: their logo picture (Branding:LogoPath), or, with no logo, the badge text. */
.brand-badge {
  padding: var(--space-1) var(--space-2);
  border-radius: var(--radius-sm);
  background: var(--color-red);
  /* Backgrounds are left out of print by default, which would leave white letters on white paper. */
  print-color-adjust: exact;
}

.brand-letters {
  display: block;
  height: var(--brand-letters-height);
  width: auto;
  max-width: var(--brand-letters-max-width);
  object-fit: contain;
}

/* The badge text when the customer has no logo picture. */
.brand-badge-text {
  display: block;
  color: var(--color-on-dark);
  font-size: var(--text-small);
  font-weight: var(--weight-heavy);
  line-height: var(--brand-letters-height);
}

/* Windows high-contrast mode replaces background colors; without this the box would turn white under white letters. */
@media (forced-colors: active) {
  .brand-badge {
    forced-color-adjust: none;
  }
}

.topbar-search {
  display: flex;
  flex: 1 1 var(--topbar-search-min);
  align-items: center;
  gap: var(--space-2);
  max-width: var(--topbar-search-max);
  padding: var(--space-1) var(--space-1) var(--space-1) var(--space-3);
  border-radius: var(--radius);
  background: var(--color-card);
  color: var(--color-navy);
}

/* The ring goes around the whole white box (a ring inside it would be white on white). */
.topbar-search:focus-within {
  outline: var(--focus-ring-on-dark);
  outline-offset: var(--focus-offset);
}

.topbar-search-input {
  flex: 1;
  min-width: 0;
  border: 0;
  background: transparent;
  color: var(--color-ink);
  font: inherit;
  font-size: var(--text-input);
  appearance: none;
}

.topbar-search-input:focus {
  outline: none;
}

.topbar-search-input::placeholder {
  color: var(--color-muted);
  opacity: 1;
}

.topbar .topbar-find {
  padding-inline: var(--space-4);
}

.topbar .topbar-find:focus-visible {
  outline: var(--focus-ring);
}

.topbar-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3);
  margin-left: auto;
}

.topbar-button {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-1) var(--space-3);
  border: var(--border-thin) solid var(--color-on-dark-line);
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--color-on-dark);
  font-size: var(--text-body);
  text-decoration: none;
  cursor: pointer;
}

.topbar-button:hover {
  background: var(--color-on-dark-hover);
  color: var(--color-on-dark);
}

.topbar-user {
  font-size: var(--text-body);
}

.topbar-signout {
  margin: 0;
}

/* Shown only on narrow screens, and only once menu.js has marked the page (section 6). */
.menu-toggle {
  display: none;
}

/* Menu beside content */
.shell {
  display: grid;
  flex: 1;
  grid-template-columns: var(--menu-width) minmax(0, 1fr);
}

.menu {
  padding: var(--space-3) var(--space-2);
  border-right: var(--border-thin) solid var(--color-line);
  background: var(--color-card);
}

.menu-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  margin: 0;
  padding: 0;
  list-style: none;
}

.menu-item--after-divider {
  margin-top: var(--space-2);
  padding-top: var(--space-2);
  border-top: var(--border-thin) solid var(--color-line);
}

.menu-link {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-3);
  border-radius: var(--radius);
  color: var(--color-ink);
  font-size: var(--text-menu);
  font-weight: var(--weight-semibold);
  text-decoration: none;
}

.menu-link .icon {
  color: var(--color-navy);
}

.menu-link:hover {
  background: var(--color-hover);
  color: var(--color-ink);
}

/* The page you are on: navy fill (screen readers hear "current page" from aria-current). */
.menu-link[aria-current="page"],
.menu-link[aria-current="page"]:hover,
.menu-link[aria-current="page"] .icon {
  background: var(--color-navy);
  color: var(--color-on-dark);
}

.menu-link--alert,
.menu-link--alert .icon {
  color: var(--color-red);
}

/* Page content */
.content {
  flex: 1;
  min-width: 0;
  padding: var(--space-5);
}

/* The skip link moves focus here; a ring around the whole page would only distract. */
.content:focus {
  outline: none;
}

.signed-out .content {
  flex: none;
  width: min(calc(100% - 2 * var(--space-4)), var(--signed-out-max));
  margin: var(--space-6) auto;
  padding: var(--space-6);
  border: var(--border-thin) solid var(--color-line);
  border-radius: var(--radius-lg);
  background: var(--color-card);
  box-shadow: var(--shadow-card);
}

/* The red "DEMO MODE" warning (Development only). */
.demo-banner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2) var(--space-4);
  padding: var(--space-2) var(--space-5);
  background: var(--color-red);
  color: var(--color-on-dark);
}

.demo-banner :focus-visible {
  outline: var(--focus-ring-on-dark);
}

.demo-banner-link {
  display: inline-flex;
  align-items: center;
  padding: 0 var(--space-3);
  border: var(--border-thin) solid var(--color-on-dark-line);
  border-radius: var(--radius-sm);
  color: var(--color-on-dark);
  font-weight: var(--weight-bold);
  text-decoration: none;
}

.demo-banner-link:hover {
  background: var(--color-on-dark-hover);
  color: var(--color-on-dark);
}

/* ==========================================================================
   4. COMPONENTS
   Buttons, forms, messages, status pills, boxes, tables, label/value lists,
   home tiles and the big search box. Pages build from these.
   ========================================================================== */

/* Buttons: .btn is outlined; add --primary (navy), --big. */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-5);
  border: var(--border-thick) solid var(--color-navy);
  border-radius: var(--radius);
  background: var(--color-card);
  color: var(--color-navy);
  font-size: var(--text-button);
  font-weight: var(--weight-bold);
  line-height: var(--line-height-tight);
  text-align: center;
  text-decoration: none;
  cursor: pointer;
}

.btn:hover {
  background: var(--color-hover);
  color: var(--color-navy);
}

.btn--primary {
  background: var(--color-navy);
  color: var(--color-on-dark);
}

.btn--primary:hover {
  border-color: var(--color-navy-2);
  background: var(--color-navy-2);
  color: var(--color-on-dark);
}

.btn--big {
  min-height: var(--target-big);
  padding: var(--space-3) var(--space-6);
  font-size: var(--text-button-big);
}

/* The red button that sends a problem report (red is for real alerts and "Report a Problem" only). */
.btn--alert {
  border-color: var(--color-red);
  background: var(--color-red);
  color: var(--color-on-dark);
}

.btn--alert:hover {
  border-color: var(--color-red);
  background: var(--color-red);
  color: var(--color-on-dark);
}

.btn-row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}

/* Report a Problem: the item card, the tappable problem list, the confirmation, and the ticket tag (Pages/Report). */
.report-form {
  width: 100%;
}

.problem-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  align-self: stretch;
  min-width: 0;
  margin: 0;
  padding: 0;
  border: 0;
}

.problem-list legend {
  margin-bottom: var(--space-2);
  padding: 0;
  font-size: var(--text-label);
  font-weight: var(--weight-bold);
}

.problem-list .check-row {
  padding: var(--space-2) var(--space-3);
  border: var(--border-thick) solid var(--color-line);
  border-radius: var(--radius);
  background: var(--color-card);
}

.item-card {
  max-width: var(--form-max);
  padding: var(--space-3) var(--space-4);
  border: var(--border-thick) solid var(--color-navy);
}

.item-card-id {
  margin: 0;
  color: var(--color-navy);
  font-size: var(--text-record-id);
  font-weight: var(--weight-heavy);
  line-height: var(--line-height-tight);
}

.item-card-lines {
  margin: 0;
  color: var(--color-muted);
}

.report-sent {
  max-width: var(--form-max);
  text-align: center;
}

.ticket-number {
  margin: 0 0 var(--space-2);
  color: var(--color-navy);
  font-size: var(--text-ticket);
  font-weight: var(--weight-heavy);
  line-height: var(--line-height-tight);
}

.report-sent-what,
.report-sent-email {
  color: var(--color-muted);
}

.report-steps {
  margin: var(--space-4) 0;
  padding: var(--space-4) var(--space-4) var(--space-4) var(--space-6);
  text-align: left;
}

.report-steps li {
  margin-bottom: var(--space-2);
  font-size: var(--text-lead);
}

.report-sent .btn-row {
  justify-content: center;
}

/* The ticket tag: a card on the screen, the top half of the sheet when printed (print.css). */
.tag {
  max-width: var(--form-max);
  margin: var(--space-4) 0;
  padding: var(--space-4);
  border: var(--border-thick) solid var(--color-ink);
  border-radius: var(--radius);
  background: var(--color-card);
}

.tag-number {
  margin: 0;
  font-size: var(--text-ticket);
  font-weight: var(--weight-heavy);
  line-height: var(--line-height-tight);
}

.tag-station {
  margin: 0;
  font-size: var(--text-tag-station);
  font-weight: var(--weight-heavy);
  line-height: var(--line-height-tight);
  overflow-wrap: anywhere;
}

.tag-lines {
  display: grid;
  grid-template-columns: max-content minmax(0, 1fr);
  gap: var(--space-1) var(--space-4);
  margin: var(--space-3) 0;
}

.tag-lines dt {
  color: var(--color-muted);
}

.tag-lines dd {
  margin: 0;
  font-weight: var(--weight-semibold);
}

.tag-equipment {
  font-size: var(--text-h2);
}

.tag-take {
  margin: 0;
  font-weight: var(--weight-bold);
}

/* Code 128 bars (Pgfd.ShopTracker.Core.Reporting.Code128): drawn in ink, shrinking to fit a narrow screen. */
.barcode {
  display: block;
  max-width: 100%;
  height: auto;
  fill: var(--color-ink);
}

/* Print / PDF / Excel above a list (Pages/Shared/_ExportButtons). Print needs JavaScript (print.js adds .export-js). */
.export-bar {
  margin: var(--space-4) 0;
}

.export-print {
  display: none;
}

.export-js .export-print {
  display: inline-flex;
}

/* Camera scanning (wwwroot/js/scanner.js): the "Use the camera" button the script adds to a data-scan box's field, the panel
   with what the camera sees and its Stop button, and the message when there is no camera. */
.scan-camera,
.scan-stop {
  align-self: flex-start;
}

.scan-panel {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.scan-video {
  display: block;
  width: 100%;
  max-width: var(--form-max);
  aspect-ratio: 4 / 3;
  object-fit: cover;
  border-radius: var(--radius);
  background: var(--color-ink);
}

.scan-status {
  margin: 0;
  color: var(--color-muted);
}

.scan-message {
  margin: 0;
}

/* Forms: a .form holds .field blocks (label, input, error) and its buttons. */
.form {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-4);
  max-width: var(--form-max);
  margin: var(--space-4) 0;
}

.field {
  display: flex;
  flex-direction: column;
  align-self: stretch;
  gap: var(--space-2);
}

.field label {
  font-size: var(--text-label);
  font-weight: var(--weight-bold);
}

.field input:not([type="checkbox"], [type="radio"]),
.field select,
.field textarea {
  width: 100%;
  padding: var(--space-2) var(--space-3);
  border: var(--border-thick) solid var(--color-input-border);
  border-radius: var(--radius);
  background: var(--color-card);
  color: var(--color-ink);
  font: inherit;
  font-size: var(--text-input);
}

.field input:focus-visible,
.field select:focus-visible,
.field textarea:focus-visible {
  border-color: var(--color-navy);
}

/* A field the server rejected: red edge plus the written reason below it. */
.field .input-validation-error {
  border-color: var(--color-red);
}

.field-hint {
  color: var(--color-muted);
}

.field-error {
  color: var(--color-red);
  font-weight: var(--weight-semibold);
}

.field-error:empty {
  display: none;
}

/* The type-to-search person picker (person-picker.js). The list opens just under the box and covers what follows; each choice is
   at least a finger tall. Without script the list stays hidden and the box is a plain text box the server reads. */
.person-picker {
  position: relative;
}

.picker-list {
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  z-index: 10;
  margin: 0;
  padding: 0;
  max-height: calc(var(--target-min) * 6);
  overflow-y: auto;
  list-style: none;
  border: var(--border-thick) solid var(--color-input-border);
  border-radius: var(--radius);
  background: var(--color-card);
  box-shadow: var(--shadow-menu);
}

.picker-option {
  display: flex;
  align-items: center;
  min-height: var(--target-min);
  padding: var(--space-2) var(--space-3);
  border-bottom: var(--border-thin) solid var(--color-line-soft);
  font-size: var(--text-input);
  cursor: pointer;
}

.picker-option:hover,
.picker-option[aria-selected="true"] {
  background: var(--color-hover);
}

.picker-option[aria-selected="true"] {
  outline: var(--focus-ring);
  outline-offset: calc(var(--border-thick) * -1);
}

/* A control that script reveals (for example station-emails.js's "Add another email") starts with the hidden attribute;
   this keeps .btn's display from overriding it. */
[hidden] {
  display: none !important;
}

/* The station and battalion forms' list of notification addresses: a fieldset of rows, each an address box with its "Who this
   is" box beside it (side by side when there is room, stacked on a phone), with the add button last. */
.email-list {
  min-width: 0;
  margin: 0;
  padding: 0;
  border: 0;
}

.email-list legend {
  padding: 0;
  font-size: var(--text-label);
  font-weight: var(--weight-bold);
}

.email-row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2) var(--space-3);
}

.email-row-address {
  flex: 3 1 var(--email-field-min);
}

.email-row-label {
  flex: 2 1 var(--email-field-min);
}

.email-list .btn {
  align-self: flex-start;
}

/* A checkbox or radio button with its words: <label class="check-row"><input type="checkbox" /> Show spares</label>.
   The whole row is the target, at least --target-min tall. */
.check-row {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  font-size: var(--text-label);
  font-weight: var(--weight-semibold);
  cursor: pointer;
}

/* Messages: --error (red), --ok (green), --warn (amber), --info (neutral). */
.alert {
  margin: var(--space-4) 0;
  padding: var(--space-3) var(--space-4);
  border: var(--border-thin) solid var(--color-line);
  border-left-width: var(--border-accent);
  border-radius: var(--radius);
  background: var(--color-card);
  color: var(--color-ink);
  font-size: var(--text-lead);
}

.alert--error {
  border-color: var(--color-red);
  background: var(--pill-red-bg);
}

.alert--ok {
  border-color: var(--pill-green-fg);
  background: var(--pill-green-bg);
}

.alert--warn {
  border-color: var(--color-warn-border);
  background: var(--pill-amber-bg);
  color: var(--color-warn-ink);
}

.alert--info {
  border-left-color: var(--color-navy-2);
}

/* Status pills: always a word ("Overdue"), never a color dot alone. */
.pill {
  display: inline-block;
  padding: var(--space-1) var(--space-3);
  border-radius: var(--radius-pill);
  font-size: var(--text-small);
  font-weight: var(--weight-bold);
  line-height: var(--line-height-tight);
  white-space: nowrap;
}

.pill--amber {
  background: var(--pill-amber-bg);
  color: var(--pill-amber-fg);
}

.pill--blue {
  background: var(--pill-blue-bg);
  color: var(--pill-blue-fg);
}

.pill--green {
  background: var(--pill-green-bg);
  color: var(--pill-green-fg);
}

.pill--red {
  background: var(--pill-red-bg);
  color: var(--pill-red-fg);
}

.pill--gray {
  background: var(--pill-gray-bg);
  color: var(--pill-gray-fg);
}

/* Boxes: a white panel with a title bar. */
.box {
  margin: var(--space-4) 0;
  overflow: hidden;
  border: var(--border-thin) solid var(--color-line);
  border-radius: var(--radius-lg);
  background: var(--color-card);
}

.box-title {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
  margin: 0;
  padding: var(--space-3) var(--space-4);
  border-bottom: var(--border-thin) solid var(--color-line);
  font-size: var(--text-lead);
  font-weight: var(--weight-bold);
}

.box-body {
  padding: var(--space-4);
}

/* Tables: wrap in .tbl-wrap so a wide table scrolls by itself instead of the whole page. It is also the place the
   screen-reader-only text in its cells (.visually-hidden, which is positioned) is measured from: otherwise that text in a
   column scrolled out of view would stick out past the wrapper and make the whole page scroll sideways. */
.tbl-wrap {
  position: relative;
  overflow-x: auto;
}

.tbl {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--text-body);
}

.tbl th {
  padding: var(--space-2) var(--space-3);
  border-bottom: var(--border-thick) solid var(--color-line);
  color: var(--color-muted);
  font-size: var(--text-small);
  font-weight: var(--weight-bold);
  letter-spacing: 0.04em;
  text-align: left;
  text-transform: uppercase;
}

.tbl td {
  padding: var(--space-3);
  border-bottom: var(--border-thin) solid var(--color-line-soft);
  vertical-align: top;
}

.tbl tr:last-child td {
  border-bottom: 0;
}

.tbl .num {
  text-align: right;
  white-space: nowrap;
}

.tbl .id {
  font-family: var(--font-mono);
  font-weight: var(--weight-bold);
  white-space: nowrap;
}

/* A text box inside a table cell (a part's name, a model's name): looks like a form field, shrinks with the cell. */
.tbl-input {
  width: 100%;
  min-width: 10em;
  padding: var(--space-2) var(--space-3);
  border: var(--border-thick) solid var(--color-input-border);
  border-radius: var(--radius);
  background: var(--color-card);
  color: var(--color-ink);
  font: inherit;
  font-size: var(--text-input);
}

.tbl-input:focus-visible {
  border-color: var(--color-navy);
}

/* The buttons of one table row, side by side and wrapping on a narrow screen. */
.row-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}

/* A form that holds only hidden fields; its visible fields and buttons sit in the table cells and name it with form="id". */
.row-form {
  margin: 0;
}

/* Label/value lists (<dl class="kv">): "In service since   01/02/2026". */
.kv {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: var(--space-2) var(--space-5);
  margin: 0;
}

.kv dt {
  color: var(--color-muted);
}

.kv dd {
  margin: 0;
  font-weight: var(--weight-semibold);
}

/* Breadcrumb trail above a page heading ("Admin > Users"); the last item is the current page. */
.crumbs {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
  margin: 0 0 var(--space-2);
  padding: 0;
  color: var(--color-muted);
  list-style: none;
}

.crumbs li + li::before {
  content: "\203A" / "";
  margin-right: var(--space-2);
}

.crumbs [aria-current="page"] {
  color: var(--color-ink);
  font-weight: var(--weight-bold);
}

/* A page heading with its big buttons beside it. */
.page-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
}

/* A list's filters straight under its heading and big buttons (no message between them) keep a gap, instead of the buttons
   sitting on the filters' box. */
.page-head + .filters {
  margin-top: var(--space-4);
}

/* A small form inside a box (one action per form, so each button posts only its own fields). */
.form--inline {
  max-width: none;
  margin: 0;
}

/* The equipment list's filters: boxes side by side, wrapping to fit the width. */
.filters {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(14em, 1fr));
  align-items: end;
  gap: var(--space-3) var(--space-4);
  padding: var(--space-4);
  border: var(--border-thin) solid var(--color-line);
  border-radius: var(--radius-lg);
  background: var(--color-card);
}

/* A second, smaller line inside a table cell (a compressor's serial under "Station 810 compressor"). */
.cell-sub {
  display: block;
  color: var(--color-muted);
  font-family: var(--font-mono);
  font-size: var(--text-small);
}

/* A second line that is words, not a serial (a place, a person's name, on My station and Reports I sent): the body's font. */
.cell-sub--plain {
  font-family: inherit;
}

/* A date and time kept on one line, so "3:23 AM" never breaks between the time and AM. */
.wo-when {
  white-space: nowrap;
}

/* The top of an equipment record: the ID, its status pill, and what it is and where. */
.record-head {
  margin: var(--space-4) 0;
  padding: var(--space-4) var(--space-5);
  border: var(--border-thin) solid var(--color-line);
  border-radius: var(--radius-lg);
  background: var(--color-card);
}

.record-id {
  margin: 0;
  font-family: var(--font-mono);
}

/* A bigger status pill for the record's header. */
.pill--large {
  padding: var(--space-2) var(--space-4);
  font-size: var(--text-lead);
}

/* Label/value lines in the record header: "Type   SCBA Pack". */
.record-lines {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: var(--space-2) var(--space-5);
  margin: var(--space-3) 0;
}

.record-lines dt {
  color: var(--color-muted);
}

.record-lines dd {
  margin: 0;
  font-weight: var(--weight-semibold);
}

/* The line under a retired record's details: "Retired on 11/07/2026: Damaged beyond repair". */
.record-retired {
  margin: var(--space-3) 0;
  font-size: var(--text-lead);
  font-weight: var(--weight-semibold);
}

/* The part boxes on the Add form: a fieldset like the station's address list, one serial and part number pair per slot. */
.component-boxes {
  min-width: 0;
  margin: 0;
  padding: 0;
  border: 0;
}

.component-boxes legend {
  padding: 0;
  font-size: var(--text-label);
  font-weight: var(--weight-bold);
}

/* One slot's two boxes sit side by side where there is room and stack on a narrow screen. */
.component-box {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr));
  gap: var(--space-3);
  margin: var(--space-3) 0;
}

/* "This pack will be PG2021" on the Add form. */
.next-number {
  margin: 0;
  font-size: var(--text-lead);
}

/* The parts screens: a part's description under its number, and the count on the shelf in big type. */
.record-description {
  margin: var(--space-2) 0;
  font-size: var(--text-lead);
}

.on-hand-line {
  margin: var(--space-3) 0;
  font-size: var(--text-lead);
}

.on-hand {
  font-size: var(--text-record-id);
  font-weight: var(--weight-heavy);
}

.on-hand-where {
  color: var(--color-muted);
}

/* The part Receive stock found: "REG-100 First-stage regulator. 8 on the shelf now." */
.found-part {
  margin: var(--space-3) 0;
  font-size: var(--text-lead);
}

.found-count {
  font-weight: var(--weight-semibold);
}

/* Home tiles: big buttons, 3 across (section 6 narrows them). */
.tiles {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--space-4);
  margin: var(--space-5) 0 0;
  padding: 0;
  list-style: none;
}

.tile {
  display: flex;
  align-items: flex-start;
  gap: var(--space-4);
  height: 100%;
  min-height: var(--tile-min-height);
  padding: var(--space-5);
  border: var(--border-thin) solid var(--color-line);
  border-radius: var(--radius-lg);
  background: var(--color-card);
  box-shadow: var(--shadow-card);
  color: var(--color-ink);
  text-decoration: none;
}

.tile:hover {
  border-color: var(--color-navy);
  color: var(--color-ink);
}

.tile-icon {
  display: flex;
  flex-shrink: 0;
  align-items: center;
  justify-content: center;
  width: var(--tile-icon-box);
  height: var(--tile-icon-box);
  border-radius: var(--radius-lg);
  background: var(--color-icon-bg);
  color: var(--color-navy);
}

.tile-body {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  min-width: 0;
}

.tile-title {
  font-size: var(--text-tile-title);
  font-weight: var(--weight-heavy);
  line-height: var(--line-height-tight);
}

.tile-text {
  color: var(--color-muted);
}

.tile-badges {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}

/* "Report a Problem": the one red tile. */
.tile--alert,
.tile--alert:hover {
  border-color: var(--color-red);
  background: var(--color-red);
  color: var(--color-on-dark);
}

.tile--alert .tile-text {
  color: var(--color-on-red-muted);
}

.tile--alert .tile-icon {
  background: var(--color-on-red-icon-bg);
  color: var(--color-on-dark);
}

/* The big search box (Home and the search page). Its label is for screen readers on wide screens (the hint inside
   the box says what to type) and is shown above the box on phones, where that hint is cut off (section 6). */
.big-search-label {
  position: absolute;
  width: var(--hairline);
  height: var(--hairline);
  margin: calc(var(--hairline) * -1);
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.big-search {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-3) var(--space-3) var(--space-4);
  border: var(--border-thick) solid var(--color-navy);
  border-radius: var(--radius-lg);
  background: var(--color-card);
  color: var(--color-navy);
}

.big-search:focus-within {
  outline: var(--focus-ring);
  outline-offset: var(--focus-offset);
}

.big-search-input {
  flex: 1;
  min-width: 0;
  min-height: var(--target-big);
  border: 0;
  background: transparent;
  color: var(--color-ink);
  font: inherit;
  font-size: var(--text-search);
  appearance: none;
}

.big-search-input:focus {
  outline: none;
}

.big-search-input::placeholder {
  color: var(--color-muted);
  opacity: 1;
}

/* ==========================================================================
   5. PAGE-SPECIFIC HELPERS (kept minimal)
   ========================================================================== */

/* An intro line under a page heading. */
.lead {
  margin: var(--space-4) 0;
  font-size: var(--text-lead);
}

/* Search results */
.result-list {
  margin: 0;
  padding: 0;
  list-style: none;
}

.result {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0 var(--space-3);
  padding: var(--space-1) var(--space-4);
  border-bottom: var(--border-thin) solid var(--color-line-soft);
}

.result:last-child {
  border-bottom: 0;
}

.result-link {
  display: inline-flex;
  align-items: center;
  font-size: var(--text-lead);
  font-weight: var(--weight-bold);
}

.result-subtitle {
  color: var(--color-muted);
}

.search-more {
  margin: 0;
  padding: var(--space-3) var(--space-4);
  border-top: var(--border-thin) solid var(--color-line-soft);
  color: var(--color-muted);
}

/* The plain sentences an import preview shows above its result ("PG0001 becomes PG2001.") */
.plain-list {
  margin: 0 0 var(--space-4);
  padding-left: var(--space-6);
}

.plain-list li {
  margin-bottom: var(--space-1);
}

/* Authenticator setup and recovery codes */
.steps li {
  margin-bottom: var(--space-2);
}

.qr-code {
  display: block;
  width: var(--qr-size);
  height: var(--qr-size);
  margin: var(--space-4) 0;
  padding: var(--space-2);
  border: var(--border-thin) solid var(--color-line);
  border-radius: var(--radius);
  background: var(--color-card);
}

.authenticator-key {
  font-size: var(--text-input);
  font-weight: var(--weight-bold);
  overflow-wrap: anywhere;
}

/* Help articles (Markdown turned into HTML by HelpCatalog): readable lists, a clear gap above each section heading,
   and a shaded box for a "watch out" block quote. Links inside lists use .action-link like every standalone link. */
.article {
  max-width: var(--article-max);
}

.article ol,
.article ul {
  margin: 0 0 var(--space-4);
  padding-left: var(--space-6);
}

.article li {
  margin-bottom: var(--space-2);
}

.article h2 {
  margin-top: var(--space-6);
}

.article blockquote {
  margin: var(--space-4) 0;
  padding: var(--space-3) var(--space-4);
  border: var(--border-thin) solid var(--color-warn-border);
  border-left-width: var(--border-accent);
  border-radius: var(--radius);
  background: var(--pill-amber-bg);
  color: var(--color-warn-ink);
}

.article blockquote p:last-child {
  margin-bottom: 0;
}

/* A screenshot in a help article. The width and height attributes reserve its space; this keeps it inside the article
   column on a narrow screen without stretching it, and a thin edge keeps a pale screenshot from blending into the page. */
.help-screenshot {
  display: block;
  max-width: 100%;
  height: auto;
  margin: var(--space-4) 0;
  border: var(--border-thin) solid var(--color-line);
  border-radius: var(--radius);
}

/* A printable one-page cheat sheet (Help/Content/cheat-sheet-*.md, HelpArticle.IsCheatSheet). On screen it looks like the
   sheet of paper it prints as: white, with an edge. print.css fits it on one page, in two columns under its title. */
.cheat-sheet {
  margin: var(--space-4) 0;
  padding: var(--space-4) var(--space-5);
  border: var(--border-thin) solid var(--color-line);
  border-radius: var(--radius-lg);
  background: var(--color-card);
  box-shadow: var(--shadow-card);
}

.cheat-sheet h1 {
  margin-top: 0;
}

.recovery-codes {
  columns: 2;
  font-size: var(--text-input);
}

.recovery-codes li {
  margin-bottom: var(--space-2);
}

.recovery-codes code {
  font-weight: var(--weight-bold);
  letter-spacing: 0.05em;
}

/* Demo sign-in (Development only): one big button per role, the account's name beside it. */
.demo-roles {
  gap: var(--space-3);
  max-width: none;
}

.demo-roles p {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2) var(--space-4);
  margin: 0;
}

.demo-role-button {
  min-width: var(--demo-button-min);
  min-height: var(--target-big);
  font-size: var(--text-button-big);
}

.demo-role-name {
  color: var(--color-muted);
  font-size: var(--text-lead);
}

/* The work order screen (Pages/WorkOrders, design 6, mockup 3): the line under the heading, the status bar, two columns (what
   was reported, notes, the equipment at a glance and the timeline on the left; the work, the parts and the buttons on the
   right), the checklist's radio rows, and the equipment record's open-ticket banner. Where a step or row stands is always
   said in words too; the colors and marks only help. */
.wo-subline {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
  margin: var(--space-2) 0 var(--space-4);
  color: var(--color-muted);
  font-size: var(--text-lead);
}

.wo-subline strong {
  color: var(--color-ink);
  font-family: var(--font-mono);
}

.wo-vendor {
  font-weight: var(--weight-semibold);
}

.wo-pointer {
  margin: 0 0 var(--space-4);
}

.wo-status {
  margin: var(--space-4) 0;
  overflow: hidden;
  border: var(--border-thin) solid var(--color-line);
  border-radius: var(--radius-lg);
  background: var(--color-card);
}

.wo-steps {
  display: grid;
  grid-auto-columns: minmax(0, 1fr);
  grid-auto-flow: column;
  margin: 0;
  padding: 0;
  list-style: none;
}

.wo-step {
  display: grid;
  grid-template-columns: var(--checkbox-size) minmax(0, 1fr);
  gap: var(--space-1) var(--space-3);
  padding: var(--space-3) var(--space-4);
  border-left: var(--border-thin) solid var(--color-line);
}

.wo-step:first-child {
  border-left: 0;
}

/* The round mark before each step's name: filled for a step done, ringed for where it is now, empty for what's to come. */
.wo-step::before {
  content: "";
  grid-row: 1;
  align-self: center;
  width: var(--checkbox-size);
  height: var(--checkbox-size);
  border: var(--border-thick) solid var(--color-line);
  border-radius: var(--radius-pill);
}

.wo-step-name {
  grid-column: 2;
  grid-row: 1;
  font-size: var(--text-lead);
  font-weight: var(--weight-bold);
}

.wo-step-detail {
  grid-column: 2;
  color: var(--color-muted);
  font-size: var(--text-small);
}

.wo-step--done::before {
  border-color: var(--pill-green-fg);
  background: var(--pill-green-fg);
}

.wo-step--current {
  background: var(--pill-blue-bg);
}

.wo-step--current::before {
  border-width: var(--border-accent);
  border-color: var(--pill-blue-fg);
  background: var(--color-card);
}

.wo-step--current .wo-step-name {
  color: var(--pill-blue-fg);
}

.wo-step--notreached .wo-step-name,
.wo-step--next .wo-step-name {
  color: var(--color-muted);
}

.wo-columns {
  display: grid;
  grid-template-columns: minmax(0, 2fr) minmax(0, 3fr);
  align-items: start;
  gap: 0 var(--space-5);
}

.wo-left > .box:first-child,
.wo-right > .box:first-child {
  margin-top: 0;
}

.wo-report p {
  margin: var(--space-2) 0;
}

.wo-problems {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin: 0 0 var(--space-3);
  padding: 0;
  list-style: none;
}

.wo-report-note {
  margin: var(--space-3) 0;
  padding: var(--space-3) var(--space-4);
  border-left: var(--border-accent) solid var(--color-red);
  border-radius: var(--radius-sm);
  background: var(--color-bg);
  white-space: pre-line;
}

.wo-report-by,
.wo-empty {
  color: var(--color-muted);
}

.wo-notes {
  margin: 0;
  padding: 0;
  list-style: none;
}

.wo-note {
  padding: var(--space-3) 0;
  border-bottom: var(--border-thin) solid var(--color-line-soft);
}

.wo-note:last-child {
  border-bottom: 0;
}

.wo-note p {
  margin: 0;
}

.wo-note-who {
  color: var(--color-muted);
  font-size: var(--text-small);
}

/* Notes, reports and the tech's text keep their line breaks as typed; the text itself is always encoded by the page. */
.wo-note-text,
.wo-text {
  white-space: pre-line;
}

.wo-note--shop .wo-note-who {
  color: var(--color-navy);
  font-weight: var(--weight-semibold);
}

.wo-note-form {
  max-width: none;
  margin-bottom: 0;
}

.wo-serial {
  font-family: var(--font-mono);
}

.wo-texts {
  margin-top: var(--space-4);
}

/* The work form: each checklist row is a fieldset of answers that read as big buttons, with its own note below. */
.wo-work-form {
  max-width: none;
  margin: 0;
}

.wo-group {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  align-self: stretch;
  min-width: 0;
  margin: 0;
  padding: 0;
  border: 0;
}

.wo-group-title {
  margin-bottom: var(--space-2);
  padding: 0;
  font-size: var(--text-h2);
  font-weight: var(--weight-bold);
}

.wo-group > .btn {
  align-self: flex-start;
}

.wo-row {
  min-width: 0;
  margin: 0;
  padding: var(--space-2) var(--space-3) var(--space-3);
  border: var(--border-thin) solid var(--color-line);
  border-radius: var(--radius);
}

.wo-row--missing {
  border: var(--border-thick) solid var(--color-red);
}

/* After a stale save (rulings R42, R45): a row both people changed, and the words saying what the other one saved. A post that
   couldn't be saved at all because the ticket moved on is shown read-only in .wo-posted. The words always say it; the amber
   only helps. */
.wo-row--changed {
  border: var(--border-thick) solid var(--color-warn-border);
  background: var(--pill-amber-bg);
}

.wo-saved-by {
  margin: 0 0 var(--space-2);
  color: var(--color-warn-ink);
  font-weight: var(--weight-semibold);
  white-space: pre-line;
}

.wo-posted {
  margin-bottom: var(--space-4);
  padding: var(--space-3) var(--space-4);
  border: var(--border-thick) solid var(--color-warn-border);
  border-radius: var(--radius);
  background: var(--pill-amber-bg);
}

.wo-posted-title {
  margin: 0 0 var(--space-2);
  font-size: var(--text-lead);
}

.wo-row-name {
  padding: 0 var(--space-1);
  font-size: var(--text-label);
  font-weight: var(--weight-bold);
}

.wo-row .field-error,
.wo-row .field-hint {
  margin: 0 0 var(--space-2);
}

.wo-answers {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin-bottom: var(--space-2);
}

.wo-answer {
  padding: 0 var(--space-4) 0 var(--space-3);
  border: var(--border-thick) solid var(--color-line);
  border-radius: var(--radius);
  background: var(--color-card);
}

.wo-answer:has(input:checked) {
  border-color: var(--color-navy);
  background: var(--color-hover);
}

.wo-answer:has(input:disabled) {
  color: var(--color-muted);
  cursor: not-allowed;
}

.wo-row-note summary {
  display: inline-flex;
  align-items: center;
  color: var(--color-link);
  font-weight: var(--weight-semibold);
  cursor: pointer;
}

.wo-row-note textarea {
  width: 100%;
  padding: var(--space-2) var(--space-3);
  border: var(--border-thick) solid var(--color-input-border);
  border-radius: var(--radius);
  font: inherit;
}

/* The Email outbox (Admin): the date sits over the time, each on one line; To and Subject get room for a whole address and a
   subject line, so an address only breaks when it is longer than that, and an opened email reads at a normal width; the status
   pill may wrap (as a rounded box), so the long "Not sent: email is turned off" doesn't take their room (Task 9b). An opened
   row shows the email's text as it was sent, line breaks kept. */
.outbox-when {
  white-space: nowrap;
}

.outbox-day {
  display: block;
}

.outbox-to {
  min-width: 12em;
  overflow-wrap: anywhere;
}

.outbox-about {
  min-width: 15em;
}

.outbox-status .pill {
  border-radius: var(--radius);
  white-space: normal;
}

.outbox-subject {
  display: block;
  font-weight: var(--weight-semibold);
}

.outbox-body summary {
  display: inline-flex;
  align-items: center;
  color: var(--color-link);
  font-weight: var(--weight-semibold);
  cursor: pointer;
}

.outbox-text {
  margin-top: var(--space-2);
  padding: var(--space-3);
  border: var(--border-thin) solid var(--color-line);
  border-radius: var(--radius);
  background: var(--color-bg);
  overflow-wrap: anywhere;
  white-space: pre-wrap;
}

.wo-replaced {
  margin: 0 0 var(--space-2);
  font-weight: var(--weight-semibold);
}

.wo-form-buttons {
  align-self: stretch;
}

/* Mark Ready for Pickup (or Mark Done): the green "go" button of mockup 3. */
.btn--ready {
  border-color: var(--pill-green-fg);
  background: var(--pill-green-fg);
  color: var(--color-on-dark);
}

.btn--ready:hover {
  border-color: var(--pill-green-fg);
  background: var(--pill-green-fg);
  color: var(--color-on-dark);
}

.wo-actions {
  margin: var(--space-4) 0;
}

/* A button that posts on its own (Received, Start, Change to on-site) sits in a row of buttons as if it were one. */
.wo-inline-form {
  display: contents;
}

.wo-checklist .wo-group-row th {
  padding-top: var(--space-4);
  color: var(--color-ink);
}

/* The equipment record's open ticket: "Open ticket BA-1052: In Shop", with Received beside it. */
.wo-banner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2) var(--space-4);
}

.wo-banner p {
  margin: 0;
}

.wo-banner a {
  font-weight: var(--weight-bold);
}

/* Can't Be Fixed: each choice is a box with its own form; Link to equipment lists what the scan matched. */
.wo-choice .form {
  max-width: var(--form-max);
  margin: 0;
}

.wo-match {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2) var(--space-4);
}

.wo-print-buttons {
  margin-bottom: var(--space-4);
}

/* Parts used (design 6.4, mockup 3): the scan box with Add Part beside it, the matches to pick from, and the lines with their
   own small buttons. They are no form of their own (they belong to the work form, ruling R47), so they stack like one here.
   What's left on the shelf is red at the reorder level; the words always say "at reorder level" too. */
.wo-parts-hint {
  margin: 0 0 var(--space-3);
}

.wo-part-add {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  margin: 0 0 var(--space-4);
}

.wo-part-find {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}

.wo-part-find input {
  flex: 1 1 auto;
  width: auto;
}

.wo-part-matches {
  align-self: stretch;
}

/* "2 left on the shelf" under a part's description. (Not .wo-left, which is the work order's left column.) */
.wo-onhand {
  display: block;
  color: var(--color-muted);
  font-size: var(--text-small);
}

.wo-onhand--low {
  color: var(--color-red);
  font-weight: var(--weight-semibold);
}

.wo-qty,
.wo-yesno {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
}

.wo-qty-btn,
.wo-yesno-btn {
  min-width: var(--target-min);
  padding: 0 var(--space-2);
}

.wo-qty-count {
  min-width: var(--space-6);
  font-weight: var(--weight-bold);
  text-align: center;
}

/* The pressed half of Yes / No is the line's answer: a navy edge and the hover shade, and aria-pressed says it in words. */
.wo-yesno-btn[aria-pressed="true"] {
  border-color: var(--color-navy);
  background: var(--color-hover);
  font-weight: var(--weight-bold);
}

.wo-part-note {
  display: block;
  color: var(--color-muted);
  font-size: var(--text-small);
}

.wo-parts tfoot td {
  border-top: var(--border-thick) solid var(--color-line);
  font-weight: var(--weight-bold);
}

/* The zero-on-hand prompt (mockup 4) takes the scan box's place, in the "watch out" colors. */
.wo-zero {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  margin: 0 0 var(--space-4);
  padding: var(--space-3) var(--space-4);
  border: var(--border-thick) solid var(--color-warn-border);
  border-radius: var(--radius);
  background: var(--pill-amber-bg);
}

.wo-zero p {
  margin: 0;
}

.wo-zero-title {
  margin: 0;
  font-size: var(--text-h2);
}

.wo-count-box {
  max-width: calc(var(--target-big) * 2);
}

/* The "Replaced" (and "Replace again") button on a slot-linked part row sits with the row's answers. */
.wo-replace-open {
  align-self: center;
}

/* The Replace step (design 6.2): "How was it replaced?", then the swap's choices, each source with its own fields indented under
   it. While Rebuilt is picked the swap's choices are hidden; a browser without :has() shows them, and the server still refuses a
   rebuild with a swap's field filled in. */
.wo-replace-now {
  font-size: var(--text-lead);
}

.wo-choices {
  margin: 0;
  padding: 0;
  border: 0;
}

.wo-choices legend {
  margin-bottom: var(--space-2);
  padding: 0;
  font-size: var(--text-label);
  font-weight: var(--weight-bold);
}

.wo-choice-hint {
  margin: 0 0 var(--space-2) calc(var(--checkbox-size) + var(--space-3));
}

.wo-source {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  margin-bottom: var(--space-4);
}

.wo-choice-field {
  margin-left: calc(var(--checkbox-size) + var(--space-3));
}

.wo-swap {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  align-self: stretch;
}

.wo-replace-form:has(#Swapped_No:checked) .wo-swap {
  display: none;
}

/* ==========================================================================
   6. RESPONSIVE RULES
   Narrower screens, including a laptop zoomed to 200%. (Breakpoints are
   listed in the DESIGN TOKENS comment; CSS cannot use variables here.)
   ========================================================================== */
@media (max-width: 1099px) {
  .tiles {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .wo-columns {
    grid-template-columns: minmax(0, 1fr);
  }
}

@media (max-width: 899px) {
  .topbar {
    gap: var(--space-2) var(--space-3);
    padding: var(--space-2) var(--space-4);
  }

  /* Without JavaScript there is no working Menu button, so the menu stays open above the page instead. */
  .menu-js .menu-toggle {
    display: inline-flex;
  }

  /* The search box takes its own full-width row under the bar's other items. */
  .topbar-search {
    flex-basis: 100%;
    order: 1;
    max-width: none;
  }

  .shell {
    grid-template-columns: minmax(0, 1fr);
    align-content: start;
  }

  .menu {
    border-right: 0;
    border-bottom: var(--border-thin) solid var(--color-line);
  }

  /* The menu folds away until the Menu button opens it (menu.js marks the page menu-js and adds menu--open). */
  .menu-js .menu {
    display: none;
    box-shadow: var(--shadow-menu);
  }

  .menu-js .menu.menu--open {
    display: block;
  }

  .content {
    padding: var(--space-4);
  }
}

@media (max-width: 699px) {
  .tiles {
    grid-template-columns: minmax(0, 1fr);
  }

  /* Phone top bar, laid out as in the approved phone mockup: the brand ("PGFD Tracker", short enough to show in full)
     on the left and Menu on the right, then a row with Help, who is signed in, and Sign out, then the search box. */
  .brand {
    flex: 1;
  }

  .menu-toggle {
    order: 1;
  }

  .signed-in .topbar-actions {
    flex-basis: 100%;
    justify-content: space-between;
    order: 2;
    margin-left: 0;
  }

  .topbar-search {
    order: 3;
  }

  .big-search-label {
    position: static;
    display: block;
    width: auto;
    height: auto;
    margin: 0 0 var(--space-2);
    overflow: visible;
    clip-path: none;
    font-size: var(--text-label);
    font-weight: var(--weight-bold);
    white-space: normal;
  }

  .big-search {
    flex-wrap: wrap;
  }

  .big-search > .icon {
    display: none;
  }

  .big-search-input {
    flex-basis: 100%;
  }

  .big-search .btn {
    flex: 1;
  }

  .signed-out .content {
    margin-top: var(--space-4);
    padding: var(--space-4);
  }

  .kv,
  .record-lines {
    grid-template-columns: minmax(0, 1fr);
  }

  .demo-role-button {
    width: 100%;
    min-width: 0;
  }

  .wo-steps {
    grid-auto-flow: row;
  }

  .wo-step {
    border-top: var(--border-thin) solid var(--color-line);
    border-left: 0;
  }

  .wo-step:first-child {
    border-top: 0;
  }

  /* The Ready for Pickup list becomes one card per pack (the same cells, so there is one copy of the data): the header row is
     hidden, each row is a block, and each cell shows its column heading from its data-label. The Picked up button is last
     and full width. */
  /* The form shrinks its children to fit; the cards should fill the screen's width. */
  .wo-cart > .box {
    align-self: stretch;
  }

  .wo-list,
  .wo-list tbody,
  .wo-list tr,
  .wo-list td {
    display: block;
  }

  .wo-list thead {
    display: none;
  }

  /* Each card keeps its words and button off the box's edges. */
  .wo-list tr {
    padding: var(--space-3) var(--space-4);
    border-bottom: var(--border-thick) solid var(--color-line);
  }

  .wo-list tr:last-child {
    border-bottom: 0;
  }

  /* A long equipment or place name wraps inside its card instead of widening it past a 360px screen: the values may shrink below
     their longest word (min-width: 0) and break anywhere. */
  .wo-list td,
  .wo-list tr:last-child td {
    display: flex;
    min-width: 0;
    gap: var(--space-3);
    justify-content: space-between;
    padding: var(--space-1) 0;
    border-bottom: 0;
    overflow-wrap: anywhere;
    text-align: right;
  }

  .wo-list td > * {
    min-width: 0;
  }

  .wo-list td::before {
    flex: none;
    color: var(--color-muted);
    content: attr(data-label);
    font-size: var(--text-small);
    font-weight: var(--weight-bold);
    letter-spacing: 0.04em;
    text-align: left;
    text-transform: uppercase;
  }

  .wo-list td.cell-action::before {
    display: none;
  }

  .wo-list td.cell-action .btn {
    flex: 1;
    justify-content: center;
  }

  .wo-list .cell-title {
    font-weight: var(--weight-bold);
  }
}
