/*
 * Silverlining Stock — design system.
 *
 * Built mobile-first for the rep standing at a hospital, one-handed, in a
 * hurry. Touch targets are large, the primary action on every screen is
 * unmistakable, and destructive or irreversible actions are visually distinct
 * from routine ones.
 */

:root {
  --navy-900: #0f172a;
  --navy-800: #1e293b;
  --navy-700: #334155;
  --slate-600: #475569;
  --slate-500: #64748b;
  --slate-300: #cbd5e1;
  --slate-200: #e2e8f0;
  --slate-100: #f1f5f9;
  --slate-50: #f8fafc;
  --white: #ffffff;

  /* Silver Lining's own blue, sampled from the logo: the medallion runs from
     a deep navy at its edge to a bright azure at its centre, and the wordmark
     carries the same gradient. Measured, not guessed — #11669d is 6.16:1 on
     white, so it is safe for body text as well as for buttons, and 6.16:1 the
     other way for white text sitting on it. */
  --brand-900: #12314f;
  --brand-800: #194f7e;
  --brand-700: #185284;
  --brand-600: #11669d;
  --brand-500: #0a7bb7;
  --brand-50:  #e8f2f9;

  /* The gradient the logo itself uses. */
  --brand-gradient: linear-gradient(140deg, #194f7e 0%, #11669d 55%, #0a7bb7 100%);

  --amber-600: #d97706;
  --amber-100: #fef3c7;
  --red-600: #dc2626;
  --red-700: #b91c1c;
  --red-100: #fee2e2;
  --green-600: #16a34a;
  --green-100: #dcfce7;
  --blue-600: #2563eb;
  --blue-100: #dbeafe;

  --bg: var(--slate-100);
  --surface: var(--white);
  --text: var(--navy-900);
  /* Both of these are one step darker than they look like they should be.
     The obvious choices — slate-500 and a lighter brand blue — measure 4.34:1
     and 4.23:1 against the surfaces they sit on, just under the 4.5:1 WCAG AA
     floor for body text. This matters here: the app gets read on a phone in a
     hospital corridor and in a car park. */
  --text-muted: var(--slate-600);
  --border: var(--slate-200);
  /* Boundaries of things you can interact with. WCAG 1.4.11 wants 3:1 and
     slate-300 measures 1.48:1 on white — text contrast was checked when this
     was built, component boundaries were not, which is how "zero axe
     violations" and a form you cannot read in sunlight are both true.
     #7c8899 is 3.60:1 on white and 3.28:1 on the page background. */
  --border-strong: #7c8899;
  --accent: var(--brand-600);

  --radius: 12px;
  --radius-sm: 8px;
  --shadow-sm: 0 1px 2px rgb(15 23 42 / 0.06);
  --shadow: 0 4px 12px rgb(15 23 42 / 0.08);
  --shadow-lg: 0 12px 32px rgb(15 23 42 / 0.16);

  --tap: 48px;
  --header-h: 60px;
  --nav-h: 60px;
  --rail-w: 248px;

  /* Spacing scale. Its absence is why 175 hand-written `style="margin-top:…"`
     attributes accumulated across the templates — with no scale to reach for,
     every margin decision got made once, locally, by eye. */
  --s1: 0.25rem;
  --s2: 0.5rem;
  --s3: 0.75rem;
  --s4: 1rem;
  --s5: 1.5rem;
  --s6: 2rem;
  --s7: 3rem;

  /* Type scale. 1.125 ratio at the small end so dense tables stay legible,
     opening up at the display sizes. */
  --t-xs: 0.75rem;
  --t-sm: 0.8125rem;
  --t-base: 0.9375rem;
  --t-md: 1rem;
  --t-lg: 1.125rem;
  --t-xl: 1.375rem;
  --t-2xl: 1.75rem;
  --t-3xl: 2.25rem;

  --weight-normal: 400;
  --weight-medium: 530;
  --weight-semi: 620;
  --weight-bold: 700;

  --ease: cubic-bezier(0.32, 0.72, 0, 1);

  --font: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue",
    Arial, sans-serif;
  --mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
}

* { box-sizing: border-box; }

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

body {
  margin: 0;
  font-family: var(--font);
  font-size: 16px;
  line-height: 1.5;
  color: var(--text);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
  padding-bottom: calc(var(--nav-h) + env(safe-area-inset-bottom, 0px));
}

h1, h2, h3 { line-height: 1.25; margin: 0 0 0.5rem; font-weight: 650; }
h1 { font-size: 1.375rem; }
h2 { font-size: 1.125rem; }
h3 { font-size: 1rem; }
p { margin: 0 0 0.75rem; }
a { color: var(--accent); }

/* ---------- Shell ---------- */

/* One column on a phone, two once there is room for the rail. The rail is a
   sibling of the shell rather than a child, so it can be fixed on a phone
   (as the tab bar and sheet) without the content needing to know. */

.shell { min-height: 100vh; }

.topbar {
  position: sticky;
  top: 0;
  z-index: 30;
  min-height: var(--header-h);
  display: flex;
  align-items: center;
  gap: var(--s3);
  padding: var(--s2) var(--s4);
  padding-top: calc(var(--s2) + env(safe-area-inset-top, 0px));
  background: color-mix(in srgb, var(--surface) 88%, transparent);
  -webkit-backdrop-filter: saturate(180%) blur(12px);
  backdrop-filter: saturate(180%) blur(12px);
  border-bottom: 1px solid var(--border);
}

.topbar__titles { flex: 1; min-width: 0; }

.topbar__title {
  font-size: var(--t-lg);
  font-weight: var(--weight-semi);
  letter-spacing: -0.011em;
  margin: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.topbar__sub {
  margin: 0;
  font-size: var(--t-sm);
  color: var(--text-muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.topbar__back {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  margin-left: calc(var(--s2) * -1);
  flex: none;
  border-radius: 50%;
  color: var(--text);
  text-decoration: none;
}
.topbar__back:hover { background: var(--slate-100); }

.icon { width: 20px; height: 20px; flex: none; }

/* ---------- The rail (tablet and desktop) ---------- */

.rail { display: none; }

.rail__brand {
  display: flex;
  align-items: center;
  gap: var(--s3);
  padding: var(--s4) var(--s4) var(--s5);
  color: inherit;
  text-decoration: none;
}

.rail__mark {
  width: 34px;
  height: 34px;
  flex: none;
  object-fit: contain;
}

.rail__wordmark {
  display: flex;
  flex-direction: column;
  font-size: var(--t-base);
  font-weight: var(--weight-semi);
  letter-spacing: -0.01em;
  line-height: 1.2;
}
.rail__wordmark small {
  font-size: var(--t-xs);
  font-weight: var(--weight-normal);
  color: var(--text-muted);
  letter-spacing: 0;
}

.rail__scroll { flex: 1; overflow-y: auto; padding: 0 var(--s3); }

.rail__group + .rail__group { margin-top: var(--s5); }

.rail__heading {
  margin: 0 0 var(--s2);
  padding: 0 var(--s3);
  font-size: var(--t-xs);
  font-weight: var(--weight-semi);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--slate-500);
}

.rail__list { list-style: none; margin: 0; padding: 0; }
.rail__list > li + li { margin-top: 1px; }

.rail__item {
  position: relative;
  display: flex;
  align-items: center;
  gap: var(--s3);
  min-height: 38px;
  padding: var(--s2) var(--s3);
  border-radius: var(--radius-sm);
  font-size: var(--t-base);
  font-weight: var(--weight-medium);
  color: var(--slate-600);
  text-decoration: none;
  transition: background 120ms var(--ease), color 120ms var(--ease);
}

.rail__item:hover { background: var(--slate-100); color: var(--text); }
.rail__item .icon { color: var(--slate-500); transition: color 120ms var(--ease); }
.rail__item:hover .icon { color: var(--slate-600); }

.rail__item.is-current {
  background: var(--white);
  color: var(--text);
  font-weight: var(--weight-semi);
  box-shadow: var(--shadow-sm);
}
.rail__item.is-current .icon { color: var(--accent); }

/* The current-item marker. A 3px bar rather than a filled block, because at
   this density a filled row reads as a button someone is holding down. */
.rail__item.is-current::before {
  content: "";
  position: absolute;
  left: calc(var(--s3) * -1 + 2px);
  top: 50%;
  transform: translateY(-50%);
  width: 3px;
  height: 18px;
  border-radius: 2px;
  background: var(--accent);
}

.rail__foot {
  padding: var(--s3) var(--s4) var(--s4);
  border-top: 1px solid var(--border);
}

.rail__who, .sheet__who {
  display: flex;
  align-items: center;
  gap: var(--s3);
  margin: 0 0 var(--s2);
  font-size: var(--t-base);
  line-height: 1.25;
}
.rail__who strong, .sheet__who strong { display: block; font-weight: var(--weight-semi); }
.rail__who small, .sheet__who small { display: block; font-size: var(--t-xs); color: var(--text-muted); }

.rail__avatar {
  display: grid;
  place-items: center;
  width: 32px;
  height: 32px;
  flex: none;
  border-radius: 50%;
  background: var(--slate-200);
  color: var(--slate-600);
  font-size: var(--t-sm);
  font-weight: var(--weight-semi);
}

.rail__signout {
  width: 100%;
  min-height: 36px;
  padding: var(--s2) var(--s3);
  font: inherit;
  font-size: var(--t-sm);
  font-weight: var(--weight-medium);
  text-align: left;
  color: var(--text-muted);
  background: none;
  border: 0;
  border-radius: var(--radius-sm);
  cursor: pointer;
}
.rail__signout:hover { background: var(--slate-100); color: var(--text); }

/* ---------- The tab bar (phone) ---------- */

.tabbar {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  z-index: 40;
  display: flex;
  height: calc(var(--nav-h) + env(safe-area-inset-bottom, 0px));
  padding-bottom: env(safe-area-inset-bottom, 0px);
  background: color-mix(in srgb, var(--surface) 92%, transparent);
  -webkit-backdrop-filter: saturate(180%) blur(12px);
  backdrop-filter: saturate(180%) blur(12px);
  border-top: 1px solid var(--border);
}

.tabbar__item {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 3px;
  min-height: var(--tap);
  padding: 0 2px;
  font: inherit;
  font-size: 0.6875rem;
  font-weight: var(--weight-medium);
  letter-spacing: -0.006em;
  color: var(--slate-500);
  text-decoration: none;
  background: none;
  border: 0;
  cursor: pointer;
}

.tabbar__item .icon { width: 22px; height: 22px; }
.tabbar__item.is-current { color: var(--accent); font-weight: var(--weight-semi); }
.tabbar__item.is-current .icon { stroke-width: 2.1; }

/* ---------- The menu sheet (phone) ---------- */

.sheet { position: fixed; inset: 0; z-index: 60; }
.sheet[hidden] { display: none; }

.sheet__scrim {
  position: absolute;
  inset: 0;
  background: rgb(15 23 42 / 0.44);
  -webkit-backdrop-filter: blur(2px);
  backdrop-filter: blur(2px);
  animation: sheet-fade 200ms var(--ease);
}

.sheet__panel {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  max-height: 86vh;
  display: flex;
  flex-direction: column;
  background: var(--surface);
  border-radius: 20px 20px 0 0;
  box-shadow: var(--shadow-lg);
  padding-bottom: env(safe-area-inset-bottom, 0px);
  animation: sheet-rise 260ms var(--ease);
}

/* The grab handle. Signals "this drags down" even though the close control is
   the button — people try to swipe a sheet before they look for an X. */
.sheet__panel::before {
  content: "";
  position: absolute;
  top: var(--s2);
  left: 50%;
  transform: translateX(-50%);
  width: 36px;
  height: 4px;
  border-radius: 2px;
  background: var(--slate-200);
}

.sheet__head {
  display: flex;
  align-items: center;
  gap: var(--s3);
  padding: var(--s5) var(--s4) var(--s3);
  border-bottom: 1px solid var(--border);
}
.sheet__who { flex: 1; margin: 0; }

.sheet__close {
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  flex: none;
  border: 0;
  border-radius: 50%;
  background: var(--slate-100);
  color: var(--slate-600);
  cursor: pointer;
}

.sheet__scroll { overflow-y: auto; padding: var(--s3) var(--s3) var(--s5); }

.sheet__group + .sheet__group { margin-top: var(--s4); }

.sheet__heading {
  margin: var(--s3) 0 var(--s2);
  padding: 0 var(--s3);
  font-size: var(--t-xs);
  font-weight: var(--weight-semi);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--slate-500);
}

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

.sheet__item {
  display: flex;
  align-items: center;
  gap: var(--s3);
  min-height: var(--tap);
  padding: var(--s2) var(--s3);
  border-radius: var(--radius-sm);
  color: inherit;
  text-decoration: none;
}
.sheet__item:active { background: var(--slate-100); }
.sheet__item .icon { color: var(--slate-500); }
.sheet__item.is-current { background: var(--brand-50); }
.sheet__item.is-current .icon { color: var(--accent); }

.sheet__text { display: flex; flex-direction: column; line-height: 1.3; min-width: 0; }
.sheet__text strong { font-size: var(--t-md); font-weight: var(--weight-semi); }
.sheet__text small { font-size: var(--t-sm); color: var(--text-muted); }

.sheet__signout {
  width: 100%;
  min-height: var(--tap);
  margin-top: var(--s2);
  font: inherit;
  font-weight: var(--weight-semi);
  color: var(--red-700);
  background: var(--red-100);
  border: 0;
  border-radius: var(--radius-sm);
  cursor: pointer;
}

@keyframes sheet-rise { from { transform: translateY(100%); } to { transform: none; } }
@keyframes sheet-fade { from { opacity: 0; } to { opacity: 1; } }

/* ---------- Containers ---------- */

.container {
  max-width: 900px;
  margin: 0 auto;
  padding: 1rem;
}

.container--wide { max-width: 1200px; }

.stack > * + * { margin-top: 0.75rem; }
.stack-lg > * + * { margin-top: 1.5rem; }

.row {
  display: flex;
  align-items: center;
  gap: 0.75rem;
}
.row--between { justify-content: space-between; }
.row--wrap { flex-wrap: wrap; }
.spacer { flex: 1; }

.grid {
  display: grid;
  gap: 0.75rem;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
}

/* ---------- Cards ---------- */

.card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 1rem;
  box-shadow: var(--shadow-sm);
}

.card--flush { padding: 0; overflow: hidden; }
.card__header {
  padding: 0.875rem 1rem;
  border-bottom: 1px solid var(--border);
  font-weight: 650;
  display: flex;
  align-items: center;
  gap: 0.5rem;
}
.card__body { padding: 1rem; }

a.card { display: block; color: inherit; text-decoration: none; }
a.card:active { background: var(--slate-50); }

/* ---------- Tiles ---------- */

.tile {
  display: flex;
  flex-direction: column;
  gap: 0.125rem;
  padding: 0.875rem 1rem;
  background: var(--surface);
  border: 1px solid var(--border);
  border-left: 4px solid var(--accent);
  border-radius: var(--radius-sm);
  text-decoration: none;
  color: inherit;
}

.tile__value { font-size: 1.5rem; font-weight: 700; font-variant-numeric: tabular-nums; }
.tile__label { font-size: 0.8125rem; color: var(--text-muted); }
.tile--warn { border-left-color: var(--amber-600); }
.tile--danger { border-left-color: var(--red-600); }
.tile--ok { border-left-color: var(--green-600); }

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

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  min-height: var(--tap);
  padding: 0.6875rem 1.125rem;
  font: inherit;
  font-weight: 600;
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  cursor: pointer;
  text-decoration: none;
  background: var(--slate-200);
  color: var(--navy-900);
  transition: background 120ms ease, opacity 120ms ease;
}

.btn:active { transform: translateY(1px); }
.btn:disabled { opacity: 0.5; cursor: not-allowed; }

.btn--primary { background: var(--accent); color: var(--white); }
.btn--primary:active { background: var(--brand-500); }
.btn--danger { background: var(--red-600); color: var(--white); }
.btn--ghost { background: transparent; border-color: var(--border); }
.btn--block { width: 100%; }
.btn--sm { min-height: 36px; padding: 0.375rem 0.75rem; font-size: 0.875rem; }

/* The one action a screen exists for, pinned above the nav on mobile. */
/*
 * The primary action, pinned above the tab bar.
 *
 * This was `position: sticky`, which only travels while its own containing
 * block has room below it. On `deliver` and `collect` the bar is a direct
 * child of the page stack and it pinned correctly; on `move_stock` it sits
 * inside a form inside a card and is the last thing in it, so it had nowhere
 * to travel and simply scrolled away — the primary action was off-screen at
 * the top of the page. Fixed positioning does not care what it is nested in.
 */
.action-bar {
  position: fixed;
  left: 0;
  right: 0;
  bottom: calc(var(--nav-h) + env(safe-area-inset-bottom, 0px));
  z-index: 30;
  padding: var(--s3) var(--s4);
  background: color-mix(in srgb, var(--surface) 94%, transparent);
  -webkit-backdrop-filter: saturate(180%) blur(12px);
  backdrop-filter: saturate(180%) blur(12px);
  border-top: 1px solid var(--border);
}

/* Keep the last of the page clear of the bar that now floats over it. */
body:has(.action-bar:not(.action-bar--inline)) .container { padding-bottom: 148px; }

/* Use this instead when the screen still has fields below the button. A
   pinned bar would float over them, and on the signature screen that means
   covering the name of the person signing. */
.action-bar--inline {
  position: static;
  padding: var(--s3) 0 0;
  background: none;
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
  border-top: 0;
}

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

.field { display: block; margin-bottom: 1rem; }
.field__label {
  display: block;
  font-size: 0.8125rem;
  font-weight: 600;
  color: var(--navy-700);
  margin-bottom: 0.3125rem;
}
.field__hint { font-size: 0.75rem; color: var(--text-muted); margin-top: 0.25rem; }
.field__error { font-size: 0.8125rem; color: var(--red-700); margin-top: 0.25rem; }

input[type="text"], input[type="number"], input[type="date"], input[type="datetime-local"],
input[type="password"], input[type="email"], input[type="search"], select, textarea {
  width: 100%;
  min-height: var(--tap);
  padding: 0.625rem 0.75rem;
  font: inherit;
  color: var(--text);
  background: var(--surface);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
}

input:focus-visible, select:focus-visible, textarea:focus-visible, .btn:focus-visible,
a:focus-visible {
  outline: 2px solid var(--brand-500);
  outline-offset: 2px;
}

input[aria-invalid="true"] { border-color: var(--red-600); }

/* A choice row: the whole line is the tap target, not the 13px dot. */
.choice {
  display: flex;
  align-items: center;
  gap: 0.625rem;
  min-height: var(--tap);
  padding: 0.25rem 0;
  cursor: pointer;
}

.choice input[type="radio"],
.choice input[type="checkbox"] {
  flex: none;
  width: 22px;
  height: 22px;
  min-height: 22px;
  margin: 0;
  accent-color: var(--accent);
}

/* Small buttons are fine under a mouse and too small under a thumb. */
@media (pointer: coarse) {
  .btn--sm { min-height: var(--tap); padding: 0.5rem 0.875rem; }
  input[type="radio"], input[type="checkbox"] { width: 22px; height: 22px; }
  /* Inline row forms shrink their controls to fit a table cell. On a touch
     screen that has to give way to something a finger can actually hit. */
  table.data input, table.data select, table.data .btn,
  .list__item input, .list__item select, .list__item .btn,
  form.row input, form.row select, form.row .btn {
    min-height: var(--tap);
    height: auto;
  }
}

/* Quantity stepper — big targets, no keyboard needed. */
.stepper { display: flex; align-items: stretch; gap: 0.5rem; }
.stepper button {
  width: var(--tap);
  min-height: var(--tap);
  font-size: 1.5rem;
  font-weight: 600;
  border: 1px solid var(--slate-300);
  border-radius: var(--radius-sm);
  background: var(--surface);
  cursor: pointer;
}
.stepper input {
  flex: 1;
  text-align: center;
  font-size: 1.25rem;
  font-weight: 650;
  font-variant-numeric: tabular-nums;
}

/* ---------- Badges and pills ---------- */

.badge {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  padding: 0.1875rem 0.5rem;
  font-size: 0.75rem;
  font-weight: 650;
  border-radius: 999px;
  background: var(--slate-200);
  color: var(--navy-700);
  white-space: nowrap;
}

.badge--ok { background: var(--green-100); color: #14532d; }
.badge--warn { background: var(--amber-100); color: #78350f; }
.badge--danger { background: var(--red-100); color: #7f1d1d; }
.badge--info { background: var(--blue-100); color: #1e3a8a; }
.badge--accent { background: var(--brand-50); color: #134e4a; }

.lot {
  font-family: var(--mono);
  font-size: 0.8125rem;
  font-weight: 600;
  letter-spacing: 0.02em;
}

/* ---------- Lists ---------- */

.list { list-style: none; margin: 0; padding: 0; }
.list__item {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.875rem 1rem;
  border-bottom: 1px solid var(--border);
  color: inherit;
  text-decoration: none;
  min-height: var(--tap);
}
.list > .list__item:last-child,
.list > li:last-child > .list__item { border-bottom: 0; }
a.list__item:active { background: var(--slate-50); }
.list__main { flex: 1; min-width: 0; }
.list__title { font-weight: 600; }
.list__meta { font-size: 0.8125rem; color: var(--text-muted); }
.list__qty { font-size: 1.125rem; font-weight: 700; font-variant-numeric: tabular-nums; }

/* ---------- Tables (office / desktop) ---------- */

.table-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; }
.table-wrap:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
table.data {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.875rem;
}
table.data th, table.data td {
  padding: 0.625rem 0.75rem;
  text-align: left;
  border-bottom: 1px solid var(--border);
  white-space: nowrap;
}
table.data th {
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--text-muted);
  background: var(--slate-50);
  position: sticky;
  top: 0;
}
table.data td.num, table.data th.num { text-align: right; font-variant-numeric: tabular-nums; }
table.data tbody tr:hover { background: var(--slate-50); }

/* ---------- Tables on a phone ---------- */
/*
 * Below 768px a data table stops being a table and becomes one card per row,
 * each cell a label/value pair. The alternative — the horizontal scroller
 * that was here — measured 1 988px of hidden content on Stock by location at
 * 360px wide, which is to say you could see about a seventh of it, and the
 * buttons that are the whole point of the uninvoiced worklist were off-screen
 * entirely.
 *
 * The labels come from `data-label`, written onto every cell from its own
 * column heading, so a cell can never disagree with the header it belongs to.
 */

/* 899px, not 767px. An iPad in portrait gives the content column 718px, and
   the uninvoiced worklist wants 2 029px of it — so tablet portrait needs the
   cards just as much as a phone does. Tables become tables again at 900px,
   where there is finally width for columns. */
@media (max-width: 899px) {
  .table-wrap { overflow-x: visible; }

  table.data,
  table.data tbody,
  table.data tfoot,
  table.data tr,
  table.data td { display: block; width: auto; }

  /* The headings are repeated into every cell, so the header row is now
     duplicate information — and a screen reader would read it twice. */
  table.data thead { display: none; }

  table.data tr {
    padding: var(--s3) var(--s4);
    border-bottom: 1px solid var(--border);
  }
  table.data tr:last-child { border-bottom: 0; }

  table.data td {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--s4);
    padding: var(--s1) 0;
    border: 0;
    white-space: normal;
    overflow-wrap: break-word;
    min-width: 0;
    text-align: right;
    min-height: 1.5rem;
  }

  table.data td::before {
    content: attr(data-label);
    /* Never shrinks. Letting the label flex produced "REFERE NCES" and
       "STA TUS" — the value is the variable-length half of the pair, so the
       value is the half that wraps. */
    flex: 0 0 auto;
    max-width: 50%;
    text-align: left;
    font-size: var(--t-xs);
    font-weight: var(--weight-semi);
    letter-spacing: 0.02em;
    text-transform: uppercase;
    color: var(--slate-500);
    line-height: 1.45;
  }

  /* A cell with nothing in it is noise on a card, where it was a necessary
     placeholder in a grid. Only hide truly empty ones — a dash is a value. */
  table.data td:empty { display: none; }

  /* The first cell is the row's identity: give it the weight of a heading and
     drop its label, because "PRODUCT · Cancellous chips" reads worse than the
     product name on its own line. */
  table.data td:first-child {
    display: block;
    text-align: left;
    padding-bottom: var(--s2);
    font-size: var(--t-md);
    font-weight: var(--weight-semi);
  }
  table.data td:first-child::before { display: none; }

  /* Numbers stay right-aligned against their label, which is what makes a
     column of figures scannable when it is no longer in a column. */
  table.data td.num { font-variant-numeric: tabular-nums; }

  /* Controls inside a card get the full width rather than being squeezed
     against the right edge. */
  table.data td form { width: 100%; }
  table.data td .btn { min-height: var(--tap); width: 100%; }

  /* A `.row` inside a cell is a flex row built for a wide column. In a card
     it has about 180px, which turned "Reported by Sr. N. Ndlovu" into three
     stacked words in a 60px lane. Stack it instead. */
  table.data td .row {
    width: 100%;
    flex-direction: column;
    align-items: flex-end;
    gap: var(--s1);
  }

  /* A link that is the entire value of a cell is a navigation control, not
     prose, so it gets a real target. Links inside a sentence keep their
     inline size — WCAG 2.5.8 exempts those, and padding them would wreck
     the line spacing of the paragraph they sit in. */
  table.data td > a:only-child {
    display: inline-flex;
    align-items: center;
    min-height: var(--tap);
    padding: 0 var(--s1);
  }

  table.data tfoot tr {
    background: var(--slate-50);
    border-top: 2px solid var(--border);
    font-weight: var(--weight-semi);
  }

  /* The empty-state row keeps its colspan cell and should not be labelled. */
  table.data td[colspan] { display: block; text-align: left; }
  table.data td[colspan]::before { display: none; }
}

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

.alert {
  padding: 0.75rem 1rem;
  border-radius: var(--radius-sm);
  border: 1px solid transparent;
  font-size: 0.9375rem;
}
.alert--success { background: var(--green-100); border-color: #86efac; color: #14532d; }
.alert--warning { background: var(--amber-100); border-color: #fcd34d; color: #78350f; }
.alert--error { background: var(--red-100); border-color: #fca5a5; color: #7f1d1d; }
.alert--info { background: var(--blue-100); border-color: #93c5fd; color: #1e3a8a; }

.empty {
  padding: 2.5rem 1rem;
  text-align: center;
  color: var(--text-muted);
}

/* ---------- Signature pad ---------- */

.signature {
  border: 2px dashed var(--slate-300);
  border-radius: var(--radius-sm);
  background: var(--white);
  touch-action: none;
}
.signature--signed { border-style: solid; border-color: var(--brand-500); }

/* ---------- Print (delivery / collection notes) ---------- */

@media print {
  .topbar, .tabbar, .rail, .sheet, .action-bar, .no-print { display: none !important; }
  body { background: var(--white); padding: 0; }
  .shell { padding: 0; }
  .card { box-shadow: none; border: 1px solid #999; }
  .container { max-width: none; padding: 0; }
}

/* ---------- Breakpoints ---------- */
/*
 * 640  — phone to large phone: cards gain breathing room, tiles go two-up.
 * 768  — tablet portrait: the office tables stop being cards and become
 *        tables again, because there is finally width for columns.
 * 1024 — the rail appears and the tab bar retires. Chosen over 900 because
 *        an iPad in portrait is 768 and should keep the touch layout, and
 *        1024 is where a 248px rail stops stealing from the content.
 * 1440 — the content column stops growing; long table rows get unreadable
 *        past about 1200px and nobody scans that far across.
 */

@media (min-width: 640px) {
  .container { padding: var(--s5) var(--s5); }
}

@media (min-width: 1024px) {
  body { padding-bottom: 0; }
  body:has(.action-bar:not(.action-bar--inline)) .container { padding-bottom: var(--s7); }

  /* Sticky column headings only work if something actually scrolls. The
     wrapper is the scrollport — `overflow-x: auto` computes `overflow-y` to
     `auto` as well — and it had no vertical overflow, so `position: sticky`
     on the heading row had been inert on all 25 tables. Capping the height
     gives it a scrollport to stick inside. A table shorter than the cap is
     untouched, so short tables never gain a nested scrollbar. */
  .table-wrap { max-height: min(72vh, 680px); }

  .rail {
    position: fixed;
    top: 0;
    bottom: 0;
    left: 0;
    z-index: 40;
    width: var(--rail-w);
    display: flex;
    flex-direction: column;
    background: var(--slate-50);
    border-right: 1px solid var(--border);
  }

  .tabbar, .sheet { display: none !important; }

  /* Only when there IS a rail. The sign-in page has no navigation, and the
     shell was still reserving 248px for it — leaving a grey gutter down the
     left of a page that is supposed to be full bleed. */
  body.has-nav .shell { margin-left: var(--rail-w); }

  .topbar {
    padding-left: var(--s6);
    padding-right: var(--s6);
    min-height: 68px;
  }
  .topbar__title { font-size: var(--t-xl); letter-spacing: -0.018em; }

  .container { padding: var(--s5) var(--s6) var(--s7); }
  .action-bar { position: static; }
}

@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; animation: none !important; }
}

.visually-hidden {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

/* The stock-value figure. Deliberately the quietest number on any screen it
   appears on: this is an inventory system, and the valuation exists for one
   monthly tie-back to Pastel, not as a figure anyone is meant to watch. */
.tile__value--quiet {
  font-size: var(--t-lg);
  font-weight: var(--weight-semi);
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
}

/* An iPad in landscape is 1024px wide and gets the rail — but it is still a
   finger. Everything the rail offers has to be a 44px target there, even
   though 38px is right for a mouse. */
@media (pointer: coarse) {
  .topbar__back { width: 44px; height: 44px; }
}

@media (min-width: 1024px) and (pointer: coarse) {
  .rail__item { min-height: 44px; }
  .rail__signout { min-height: 44px; }
}

/* ---------- Help ---------- */

.lede {
  font-size: var(--t-lg);
  line-height: 1.5;
  color: var(--text-muted);
  max-width: 62ch;
  margin: 0 0 var(--s2);
}

.steps { list-style: none; counter-reset: step; margin: 0; padding: 0; }

.steps__item {
  counter-increment: step;
  position: relative;
  padding: 0 0 var(--s4) var(--s6);
  border-left: 2px solid var(--border);
  margin-left: 13px;
}
.steps__item:last-child { border-left-color: transparent; padding-bottom: 0; }

.steps__item::before {
  content: counter(step);
  position: absolute;
  left: -15px;
  top: -2px;
  display: grid;
  place-items: center;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  background: var(--accent);
  color: var(--white);
  font-size: var(--t-sm);
  font-weight: var(--weight-bold);
  font-variant-numeric: tabular-nums;
}

.steps__text { display: block; font-size: var(--t-md); }
.steps__detail {
  display: block;
  margin-top: var(--s1);
  font-size: var(--t-base);
  color: var(--text-muted);
  max-width: 60ch;
}

.faq { padding: 0; }
.faq__q {
  display: flex;
  align-items: center;
  gap: var(--s3);
  min-height: var(--tap);
  padding: var(--s3) var(--s4);
  font-size: var(--t-md);
  font-weight: var(--weight-semi);
  cursor: pointer;
  list-style: none;
}
.faq__q::-webkit-details-marker { display: none; }
.faq__q::after {
  content: "";
  margin-left: auto;
  width: 9px;
  height: 9px;
  flex: none;
  border-right: 2px solid var(--slate-500);
  border-bottom: 2px solid var(--slate-500);
  transform: rotate(45deg) translate(-2px, -2px);
  transition: transform 160ms var(--ease);
}
.faq[open] .faq__q::after { transform: rotate(-135deg) translate(-3px, -3px); }
.faq__a { padding: 0 var(--s4) var(--s4); max-width: 68ch; }
.faq__a p { margin: 0 0 var(--s3); }
.faq__a p:last-child { margin-bottom: 0; }

.field__error {
  display: block;
  margin-top: var(--s1);
  font-size: var(--t-sm);
  font-weight: var(--weight-medium);
  color: var(--red-700);
}

/* A checkbox is a 13px box by default. On a phone that is a miss waiting to
   happen, so the box grows and the whole label row becomes the target. */
input[type="checkbox"], input[type="radio"] {
  width: 22px;
  height: 22px;
  accent-color: var(--accent);
  flex: none;
}

@media (pointer: coarse) {
  .field > input[type="checkbox"],
  .field > input[type="radio"] { width: 24px; height: 24px; }

  /* The label is what a thumb actually aims at. */
  .field:has(> input[type="checkbox"]),
  .field:has(> input[type="radio"]) {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--s3);
    min-height: var(--tap);
    cursor: pointer;
  }
  .field:has(> input[type="checkbox"]) .field__hint,
  .field:has(> input[type="radio"]) .field__hint { flex-basis: 100%; }
}

/* A badge that is a link is a control, not a label — the recall list on the
   lot trace is exactly that, and a 24px pill is not a thumb target. */
@media (pointer: coarse) {
  a.badge {
    min-height: var(--tap);
    padding-inline: var(--s3);
    display: inline-flex;
    align-items: center;
  }
}
a.badge { text-decoration: none; }
a.badge:hover { filter: brightness(0.94); }

/* The signed-in name is a link to your own account. */
a.rail__who, a.sheet__who {
  color: inherit;
  text-decoration: none;
  border-radius: var(--radius-sm);
  padding: var(--s2);
  margin-left: calc(var(--s2) * -1);
}
a.rail__who:hover { background: var(--slate-100); }

/* ---------- Sign in ---------- */
/*
 * Its own layout, not the app shell. Two panels at 900px and up; on a phone
 * the brand half is dropped entirely and the form gets the screen, because
 * that is what somebody standing in a hospital corridor came here to do.
 */

.container.login { max-width: none; padding: 0; }

.login__panels {
  display: grid;
  grid-template-columns: 1fr;
  min-height: 100vh;
  min-height: 100dvh;
}

.login__brand { display: none; }

.login__form {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--s5) var(--s4) calc(var(--s5) + env(safe-area-inset-bottom, 0px));
  background: var(--surface);
}

.login__form-inner { width: 100%; max-width: 25rem; }

.login__logo {
  display: block;
  width: auto;
  height: 58px;
  max-width: 100%;
  margin-bottom: var(--s6);
}

.login__heading {
  font-size: var(--t-2xl);
  font-weight: var(--weight-bold);
  letter-spacing: -0.021em;
  margin: 0 0 var(--s1);
}

.login__sub {
  margin: 0 0 var(--s5);
  color: var(--text-muted);
  font-size: var(--t-md);
}

/* A password field with a reveal button living inside it. */
.field__with-button { position: relative; display: block; }
.field__with-button input { padding-right: 4.75rem; }

.field__reveal {
  position: absolute;
  top: 50%;
  right: var(--s2);
  transform: translateY(-50%);
  min-height: 36px;
  padding: 0 var(--s3);
  font: inherit;
  font-size: var(--t-sm);
  font-weight: var(--weight-semi);
  color: var(--accent);
  background: none;
  border: 0;
  border-radius: var(--radius-sm);
  cursor: pointer;
}
.field__reveal:hover { background: var(--brand-50); }

.btn--lg { min-height: 52px; font-size: var(--t-md); }

.login__help,
.login__foot {
  margin: var(--s5) 0 0;
  font-size: var(--t-sm);
  color: var(--text-muted);
}
.login__foot {
  margin-top: var(--s6);
  padding-top: var(--s4);
  border-top: 1px solid var(--border);
  font-size: var(--t-xs);
}

@media (min-width: 900px) {
  .login__panels { grid-template-columns: 1.05fr 1fr; }

  .login__brand {
    display: flex;
    align-items: center;
    padding: var(--s7);
    background: var(--brand-gradient);
    color: #fff;
    position: relative;
    overflow: hidden;
  }

  /* The disc column from the medallion, echoed large and very faint. It is a
     spine, which is the right motif for a company that sells bone grafts. */
  .login__brand::after {
    content: "";
    position: absolute;
    right: -12%;
    top: -18%;
    width: 78%;
    aspect-ratio: 1;
    border-radius: 50%;
    background: radial-gradient(circle at 30% 30%, rgb(255 255 255 / 0.14), transparent 62%);
    pointer-events: none;
  }

  .login__brand-inner { position: relative; max-width: 30rem; }

  .login__mark {
    width: 92px;
    height: 92px;
    margin-bottom: var(--s5);
    padding: 10px;
    border-radius: 50%;
    /* The medallion is blue, and it was sitting on blue. On their own site it
       has white around it; this gives it the same separation. */
    background: rgb(255 255 255 / 0.94);
    box-shadow: 0 10px 30px rgb(0 0 0 / 0.22);
  }

  .login__brand-title {
    margin: 0 0 var(--s3);
    font-size: var(--t-3xl);
    font-weight: var(--weight-bold);
    letter-spacing: -0.024em;
    line-height: 1.1;
  }

  .login__brand-copy {
    margin: 0 0 var(--s6);
    font-size: var(--t-lg);
    line-height: 1.5;
    color: rgb(255 255 255 / 0.86);
    max-width: 26rem;
  }

  .login__points { list-style: none; margin: 0; padding: 0; }
  .login__points li {
    position: relative;
    padding-left: var(--s5);
    margin-bottom: var(--s3);
    font-size: var(--t-base);
    color: rgb(255 255 255 / 0.82);
  }
  .login__points li::before {
    content: "";
    position: absolute;
    left: 0;
    top: 0.55em;
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: rgb(255 255 255 / 0.62);
  }

  .login__form { padding: var(--s7); }
  .login__logo { height: 64px; }
}

/* The sign-in page is full bleed at every width — no shell padding, no rail. */
@media (min-width: 1024px) {
  body:not(.has-nav) .shell { margin-left: 0; }
  .container.login { padding: 0; }
}

/* The form panel keeps its own scroll on a short laptop screen rather than
   pushing the sign-in button below the fold. */
@media (min-width: 900px) and (max-height: 620px) {
  .login__panels { min-height: 0; }
  .login__form { align-items: flex-start; }
}

/* ---------- Two-factor ---------- */

/* A six-digit code, spaced so it can be read back over a phone line. */
.code-input {
  font-family: var(--mono);
  font-size: 1.5rem;
  letter-spacing: 0.42em;
  text-align: center;
  font-variant-numeric: tabular-nums;
}

.qr {
  display: inline-block;
  margin: var(--s3) 0;
  padding: var(--s3);
  background: #fff;
  border: 1px solid var(--border);
  border-radius: var(--radius);
}
.qr svg { display: block; width: 200px; height: 200px; }
