/* Bayline — Fonnebust brand system (wave 1).
   Palette per docs/contract.md — every color in this file is one of the
   variables in the token blocks below; no other hex or rgb() values are used
   (the QR box stays white on purpose). */

/* Palette tokens. Light is the default. The dark values live in the two
   blocks at the end of this block group (explicit "dark" and "auto" + OS dark);
   tests/test_theme_tokens.py keeps the three lists identical and checks that no
   hex or rgb() colour appears anywhere else in this file. */
:root {
  /* surfaces */
  --paper: #f3efe6;
  --card: #fffdf8;
  --surface-bar: #fffdf8; /* top bar, side menu, footer, table header */
  --surface-2: #f4f4f4; /* recovery codes box */
  --field-bg: #fffdf8; /* inputs, selects, textareas */
  /* text */
  --ink: #3d3a34;
  --muted: #6b6556; /* audit C: was #9d9686 (2.9:1), now 5:1+ on paper and card */
  --dark: #111418; /* headings, big numbers */
  --tile-sub: #57524a;
  --tile-sub-danger: #5a2a22;
  /* lines */
  --line: #cfc8b9; /* hairlines, not component boundaries */
  --line-strong: #857d6d; /* input borders: 4.0:1 on the card (was --line, 1.6:1) */
  /* web 0.23.1: a disabled button (flat, no fill, dim but readable text) */
  --disabled-bg: #f3efe6;
  --disabled-ink: #6b6556;
  --disabled-line: #cfc8b9;
  /* accent */
  --accent: #f0a13a;
  --focus-ring: #b85f00; /* keyboard focus outline: 3.9:1 on the page, 4.4:1 on the card (the orange --accent was 2.1:1) */
  --accent-text: #6a3203; /* links and labels on the page (audit C: was #9a4a08) */
  --on-accent: #6a3203; /* text on an orange fill (.btn-primary, .btn-use, active menu item) */
  /* status */
  --ok: #34d399;
  --ok-text: #0b7a55;
  --warn: #ffb85a;
  --warn-text: #8f5200; /* amber as text: --warn itself is 1.7:1 on the card */
  --danger: #c62828; /* audit C: was #ef4444, 3.8:1 as text */
  --danger-ink: #b42318; /* danger chip text */
  --scrap-ink: #9f1d1d;
  --danger-fill: #c62828; /* solid danger buttons and badges */
  --on-danger: #ffffff;
  --info: #163456;
  --info-fill: #163456;
  --on-info: #fffdf8;
  --on-dispatch: #111418;
  --move-out: #8b5cf6; /* stock movements */
  --move-count: #14b8a6;
  --diff-was: #b71c1c;
  --diff-now: #1b5e20;
  --sev-critical: #7f1d1d; /* fault severity fills */
  --sev-high: #c2410c;
  --sev-medium: #b45309;
  --sev-low: #e5e7eb;
  --on-sev: #ffffff;
  --on-sev-low: #1f2937;
  /* demo banner */
  --banner-bg: #fff4d6;
  --banner-line: #e8c766;
  --banner-ink: #5a4300;
  /* shadows, scrim, scrollbars */
  --shadow-ink: #111418; /* base of the color-mix() shadows */
  --shadow-sm: rgba(21, 36, 73, 0.18);
  --shadow-md: rgba(61, 58, 52, 0.12);
  --shadow-pop: rgba(0, 0, 0, 0.14);
  --scrim: rgba(0, 0, 0, 0.7);
  --scroll-thumb: #cfc8b9;
  --card-hl: transparent; /* hairline highlight on the top edge of cards (dark only) */
  --glow: transparent; /* soft blue glow behind the sign-in card (dark only) */
  /* type */
  --sans: "Inter", system-ui, -apple-system, sans-serif;
  --mono: "JetBrains Mono", ui-monospace, "SF Mono", monospace;
  --base: 15px;
  --page-max: 1360px; /* web 0.17.4: was 1200px; every page, tables and cards alike */
  color-scheme: light;
}

@font-face {
  font-family: "Inter";
  src: url("/static/fonts/Inter-Regular.woff2") format("woff2");
  font-weight: 400; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "Inter";
  src: url("/static/fonts/Inter-Medium.woff2") format("woff2");
  font-weight: 500; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "Inter";
  src: url("/static/fonts/Inter-SemiBold.woff2") format("woff2");
  font-weight: 600; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "JetBrains Mono";
  src: url("/static/fonts/JetBrainsMono-Regular.woff2") format("woff2");
  font-weight: 400; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "JetBrains Mono";
  src: url("/static/fonts/JetBrainsMono-Medium.woff2") format("woff2");
  font-weight: 500; font-style: normal; font-display: swap;
}

* { box-sizing: border-box; }
html { font-size: var(--base); }
body {
  margin: 0;
  font-family: var(--sans);
  font-size: 1rem;
  line-height: 1.5;
  color: var(--ink);
  background: var(--paper);
  display: flex;
  flex-direction: column;
  min-height: 100vh;
}
.mono, code { font-family: var(--mono); }
a { color: var(--accent-text); text-decoration: none; }
a:hover { text-decoration: underline; }
h1 { font-size: 1.5rem; font-weight: 700; margin: 0; letter-spacing: -0.01em; }
h2 { margin: 0 0 0.6rem; }

/* micro labels: 11px, letterspaced, uppercase */
.micro {
  font-family: var(--mono);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted);
}

/* Skip link (web 0.21.2). First child of the sticky top bar, so it is the first Tab stop and, as an absolutely positioned
   child, takes no layout space. Hidden by clipping (not by moving it off-screen: it stays in the accessibility tree and
   focusable). On focus it appears as a pill that hangs just BELOW the bar (over the page, never over the brand or the
   header buttons), above the side menu. */
.skip-link {
  position: absolute;
  left: 0.75rem;
  top: calc(100% + 0.4rem);
  z-index: 11;
  margin: -1px;
  padding: 0;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}
.skip-link:focus,
.skip-link:focus-visible {
  margin: 0;
  width: auto;
  height: auto;
  overflow: visible;
  clip-path: none;
  padding: 0.55rem 0.9rem;
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  background: var(--card);
  color: var(--ink);
  font-weight: 600;
  text-decoration: none;
  border: 1px solid var(--line);
  border-radius: 999px;
  box-shadow: 0 6px 18px var(--shadow-sm);
  outline: 2px solid var(--focus-ring);
  outline-offset: 2px;
}

/* The skip link moves focus here; the target itself shows no ring. */
main#main:focus { outline: none; }

/* ---------- top bar ---------- */
.topbar {
  display: flex;
  align-items: center;
  gap: 0.45rem 0.75rem;
  padding: 0.6rem 1.25rem;
  background: var(--surface-bar);
  border-bottom: 1px solid var(--line);
  position: sticky;
  top: 0;
  z-index: 10;
  flex-wrap: wrap;
}
.brand { display: flex; align-items: center; gap: 0.6rem; flex: 0 0 auto; min-width: max-content; }
.brand:hover { text-decoration: none; }
.brand-logo {
  height: 36px;
  width: auto;
  aspect-ratio: auto 1018 / 764;   /* circle-corrected Fonnebust mark (2026-10-27): intrinsic ratio wins once loaded, never stretched */
  object-fit: contain;
  flex: 0 0 auto;
  display: block;
}
.brand-name {
  font-family: var(--mono);
  font-weight: 500;
  font-size: 1rem;
  letter-spacing: 0.32em;
  color: var(--dark);
  white-space: nowrap;
  overflow: visible;
  text-overflow: clip;
  flex-shrink: 0;
}
.brand-tag {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.08em;
  color: var(--muted);
  border-left: 1px solid var(--line);
  padding-left: 0.6rem;
}
/* DOM order is brand, toggle, label, userbox, nav. The checkbox opens .nav
   with no script (.nav-toggle:checked ~ .nav). Closed: one row. Open: links
   on the next line. */
.nav {
  display: none;
  gap: 0.15rem;
  flex-wrap: wrap;
  flex: 1 0 100%;
  order: 3;
  align-items: center;
}
.nav-toggle:checked ~ .nav { display: flex; }
.nav a {
  padding: 0.4rem 0.7rem;
  border-radius: 6px;
  color: var(--ink);
  font-weight: 500;
  font-size: 0.92rem;
}
.nav a:hover { background: var(--paper); text-decoration: none; }
.nav a.active {
  background: var(--accent);
  color: var(--on-accent);
}
.userbox { display: flex; align-items: center; gap: 0.5rem; order: 2; margin-left: auto; min-width: 0; }
.user-name { font-weight: 500; font-size: 0.92rem; }
.inline-form { display: inline; }
.nav-toggle {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}
.nav-toggle-label {
  display: inline-flex;
  align-items: center;
  flex: 0 0 auto;
  order: 1;
  min-height: 44px;
  padding: 0 0.65rem;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--card);
  color: var(--ink);
  font-weight: 600;
  cursor: pointer;
}
.nav-toggle-label:hover { background: var(--paper); text-decoration: none; }
.nav-toggle:focus-visible + .nav-toggle-label {
  outline: 2px solid var(--focus-ring);
  outline-offset: 2px;
}
.nav-toggle:checked + .nav-toggle-label { background: var(--paper); }

/* ---------- page ---------- */
.page { flex: 1; padding: 1.25rem; max-width: var(--page-max); width: 100%; margin: 0 auto; min-width: 0; }
.page-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 1rem;
  margin-bottom: 1.1rem;
}
.page-head h1 { display: flex; align-items: center; gap: 0.6rem; flex-wrap: wrap; }
/* web 0.22.0: a title is never squeezed to make room for the text beside it ("Faul/ts"). The title keeps its own
   width (capped at the row, where a very long name still wraps), and the sub-text or the buttons drop to the next
   line when there is no room. */
.page-head { flex-wrap: wrap; row-gap: 0.3rem; }
.page-head > h1 { flex: 0 0 auto; max-width: 100%; }
.page-head > .page-sub { flex: 1 1 16rem; min-width: 0; margin-top: 0.3rem; }
.page-sub { color: var(--muted); font-size: 0.9rem; margin-top: 0.25rem; }
.section { margin-bottom: 1.4rem; }
.section h2 { font-family: var(--mono); font-size: 11px; }
.mt { margin-top: 1.4rem; }

/* ---------- footer ---------- */
.footer {
  display: flex;
  flex-wrap: wrap;
  gap: 0.25rem 1rem;
  justify-content: space-between;
  padding: 0.7rem 1.25rem;
  border-top: 1px solid var(--line);
  background: var(--surface-bar);
  color: var(--muted);
  font-size: 0.82rem;
}
.footer-ver { font-family: var(--mono); }

/* ---------- chips & badges ---------- */
.chip {
  display: inline-block;
  font-family: var(--mono);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.06em;
  padding: 2px 8px;
  border-radius: 999px;
  border: 1px solid transparent;
  white-space: nowrap;
}
.chip-sm { font-size: 10px; padding: 1px 6px; }
.chip-ok { background: color-mix(in srgb, var(--ok) 16%, var(--card)); color: var(--ink); border-color: var(--ok); }
.chip-warn { background: color-mix(in srgb, var(--warn) 20%, var(--card)); color: var(--accent-text); border-color: var(--warn); }
.chip-danger { background: color-mix(in srgb, var(--danger) 12%, var(--card)); color: var(--danger-ink); border-color: var(--danger); }
.chip-neutral, .chip-ok-mono { background: var(--paper); color: var(--muted); border-color: var(--line); }
/* checked_out: contract blue-grey (docs/contract.md web contract, chip-info) */
.chip-info { background: color-mix(in srgb, var(--info) 12%, var(--card)); color: var(--info); border-color: var(--info); }
.meter {
  font-family: var(--mono);
  font-size: 0.85em;
  color: var(--muted);
  white-space: nowrap;
}
.meter b { color: var(--ink); font-weight: 500; }

.badge {
  display: inline-block;
  font-family: var(--mono);
  font-size: 11px;
  padding: 1px 8px;
  border-radius: 4px;
  border: 1px solid transparent;
}
.badge-warn { background: color-mix(in srgb, var(--warn) 22%, var(--card)); border-color: var(--warn); color: var(--accent-text); }
.badge-danger { background: color-mix(in srgb, var(--danger) 12%, var(--card)); border-color: var(--danger); color: var(--danger); }
.badge-ok { background: color-mix(in srgb, var(--ok) 16%, var(--card)); border-color: var(--ok); }
.badge-neutral { background: var(--paper); border-color: var(--line); color: var(--muted); }
.badge-ok-mono { color: var(--muted); font-size: 11px; }

/* ---------- cards ---------- */
.card {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 0.9rem 1rem;
}
a.card:hover { border-color: var(--accent); text-decoration: none; }
.card, .stat-tile, .board-hero { box-shadow: inset 0 1px 0 var(--card-hl); }
.login-card { box-shadow: 0 0 60px -10px var(--glow), inset 0 1px 0 var(--card-hl); }
.machine-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  gap: 0.8rem;
}
.machine-card { display: block; }
.machine-card-top { display: flex; align-items: center; justify-content: space-between; gap: 0.5rem; }
.machine-name { font-weight: 600; font-size: 1.02rem; }
.machine-card-meta {
  display: flex;
  gap: 0.8rem;
  color: var(--muted);
  font-size: 0.8rem;
  margin-top: 0.3rem;
  flex-wrap: wrap;
}
.machine-badges { display: flex; gap: 0.4rem; margin-top: 0.55rem; flex-wrap: wrap; }

/* ---------- board strips ---------- */
.board-cols {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 0.8rem;
}
.board-cols .section {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 0.9rem 1rem;
  min-width: 0;
}
.strip-list { list-style: none; margin: 0; padding: 0; overflow-x: auto; max-width: 100%; min-width: 0; }
.strip-list li {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  padding: 0.42rem 0;
  border-bottom: 1px solid color-mix(in srgb, var(--line) 55%, transparent);
  flex-wrap: wrap;
  row-gap: 0.2rem;
  font-size: 0.92rem;
}
/* Audit 2026-10-12 board.md: rows wrap whole tokens, tokens never break. */
.strip-list li > a, .strip-name, .strip-due, .strip-when, .strip-qty,
.strip-list .badge, .strip-list .chip, .strip-list .mono { white-space: nowrap; }
.mt-sm { margin-top: 0.6rem; }
.where-line {
  margin: 0 0 0.9rem;
  max-width: 100%;
  min-width: 0;
  overflow-x: auto;
  white-space: nowrap;
}
.strip-list li:last-child { border-bottom: none; }
.strip-name { font-weight: 500; }
.strip-note { color: var(--muted); font-size: 0.85rem; }
.strip-dst { color: var(--muted); font-size: 0.85rem; }
.strip-when, .strip-due { color: var(--muted); font-size: 0.8rem; }
.strip-qty { color: var(--ink); font-size: 0.85rem; }
.due-days { color: var(--muted); font-size: 0.8rem; }

/* ---------- empty states ---------- */
.empty {
  border: 1px dashed var(--line);
  border-radius: 10px;
  color: var(--muted);
  padding: 1.1rem 1.2rem;
  font-size: 0.92rem;
  background: color-mix(in srgb, var(--card) 60%, var(--paper));
}
.empty-lg { padding: 2.5rem; text-align: center; }
.error-title { font-weight: 600; color: var(--danger); }

/* ---------- tables ---------- */
.data-table { width: 100%; border-collapse: collapse; background: var(--card); border: 1px solid var(--line); border-radius: 10px; overflow: hidden; }
.data-table th {
  font-family: var(--mono);
  font-size: 10.5px;
  font-weight: 500;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted);
  text-align: left;
  padding: 0.5rem 0.75rem;
  border-bottom: 1px solid var(--line);
  background: color-mix(in srgb, var(--paper) 55%, var(--card));
}
.data-table td { padding: 0.48rem 0.75rem; border-bottom: 1px solid color-mix(in srgb, var(--line) 55%, transparent); font-size: 0.92rem; }
.data-table tr:last-child td { border-bottom: none; }
.data-table .num { text-align: right; }
.th-num, .data-table th.num { text-align: right; }
tr.rowlink:hover td { background: color-mix(in srgb, var(--accent) 7%, var(--card)); }
tr.rowlink:hover { cursor: pointer; }
.total-row td { font-weight: 600; border-top: 1px solid var(--line); }
.kv-table { width: 100%; border-collapse: collapse; background: var(--card); border: 1px solid var(--line); border-radius: 10px; }
.kv-table td { padding: 0.45rem 0.75rem; border-bottom: 1px solid color-mix(in srgb, var(--line) 55%, transparent); font-size: 0.92rem; }
.kv-table tr:last-child td { border-bottom: none; }
.kv-table .k { color: var(--muted); width: 34%; font-size: 0.85rem; }
.ev-type { color: var(--accent-text); }
.events-table .ev-when, .events-table .ev-what { white-space: nowrap; }
.events-table .ev-thing { font-weight: 600; }
.events-table .ev-thing + .ev-bits::before {
  content: "·";
  color: var(--muted);
  margin: 0 0.4rem;
}

/* ---------- detail layout ---------- */
.detail-cols {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
  gap: 1rem;
  margin-bottom: 1.2rem;
  min-width: 0;
}
.detail-cols .section {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 0.9rem 1rem;
  min-width: 0;
  overflow-x: auto;
}
.photo-card { margin-bottom: 1rem; padding: 0.4rem; }
.photo-card img { width: 100%; max-height: 340px; object-fit: cover; border-radius: 8px; display: block; }
.photo-card .cert-file-link { display: flex; align-items: center; gap: 0.6rem; width: 100%; justify-content: center; padding: 1.4rem 1rem; font-size: 1rem; }
.cert-glyph { font-size: 1.3rem; color: var(--accent); }
.plan-card { border: 1px solid var(--line); border-radius: 8px; padding: 0.45rem 0.65rem; margin-bottom: 0.5rem; background: var(--paper); min-width: 0; max-width: 100%; }
.plan-head { display: flex; align-items: center; justify-content: flex-start; gap: 0.4rem 0.6rem; flex-wrap: wrap; min-width: 0; max-width: 100%; }
.plan-name { font-weight: 600; min-width: 0; overflow-wrap: anywhere; }
.task-list { list-style: none; margin: 0.25rem 0 0; padding: 0; font-size: 0.88rem; color: var(--ink); max-width: 100%; }
.task-line {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.35rem 0.55rem;
  list-style: none;
  padding: 0.2rem 0;
  min-width: 0;
  max-width: 100%;
}
.task-title { min-width: 0; overflow-wrap: anywhere; }
/* wave 7.1 — plan editor: inline edit form, per-task rows, add-task row.
   Edit stays a small summary in the row; the form wraps under it when open. */
.plan-edit, .task-edit, .add-task { margin-top: 0.4rem; min-width: 0; max-width: 100%; }
.plan-head > .plan-edit,
.task-line > .task-edit { flex: 0 0 auto; width: auto; margin: 0; }
.plan-head > form,
.task-line > form { margin: 0; flex: 0 0 auto; }
.plan-head > .plan-edit[open],
.task-line > .task-edit[open] { flex: 1 1 100%; width: 100%; max-width: 100%; min-width: 0; }
.plan-head .btn,
.task-line .btn { flex: 0 0 auto; }
.plan-edit summary, .task-edit summary, .add-task summary { cursor: pointer; display: inline-block; }
.plan-edit > summary,
.task-edit > summary { list-style: none; }
.plan-edit > summary::-webkit-details-marker,
.task-edit > summary::-webkit-details-marker { display: none; }
.task-edit .task-form, .plan-edit .plan-form { margin-top: 0.5rem; max-width: 100%; min-width: 0; }
.task-form { margin-top: 0.5rem; border-top: 1px solid var(--line); padding-top: 0.6rem; max-width: 100%; min-width: 0; }
.plan-card .field input,
.plan-card .field select,
.plan-card .field textarea { min-width: 0; max-width: 100%; }
@media (max-width: 480px) {
  .plan-card .form-grid-3 { grid-template-columns: 1fr; }
}
.meter-form { display: flex; gap: 0.8rem; align-items: flex-end; flex-wrap: wrap; }
.meter-form .field { flex: 1; min-width: 160px; }
.issue-block { border: 1px solid var(--danger); border-radius: 8px; padding: 0.8rem; background: color-mix(in srgb, var(--danger) 5%, var(--card)); }
.issue-block p { margin: 0 0 0.6rem; }

/* ---------- forms ---------- */
.form-card { max-width: none; margin-left: 0; margin-right: 0; }   /* web 0.22.1: the page width, like the Board (was a 720px centred column) */
.form-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 0.8rem;
  margin-bottom: 0.8rem;
}
.form-grid-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.field { display: flex; flex-direction: column; gap: 0.3rem; min-width: 0; }
.field[hidden] { display: none; }
.field-wide { margin-bottom: 0.8rem; }
.field input, .field select, .field textarea {
  font-family: var(--sans);
  font-size: 0.95rem;
  color: var(--ink);
  background: var(--field-bg);
  border: 1px solid var(--line-strong);
  border-radius: 7px;
  padding: 0.5rem 0.65rem;
  width: 100%;
  max-width: 100%;
  min-width: 0;
}
.field input[type="checkbox"],
.field input[type="radio"],
.field input[type="hidden"] {
  width: auto;
  max-width: none;
}
.field textarea { font-family: var(--mono); font-size: 0.85rem; }
.field input:focus, .field select:focus, .field textarea:focus {
  outline: 2px solid var(--focus-ring);
  outline-offset: -1px;
}
.field-check { flex-direction: row; align-items: center; gap: 0.5rem; }
.on-machine-check { margin-bottom: 0.6rem; }
.on-machine-label {
  font-family: var(--sans);
  font-size: 0.95rem;
  letter-spacing: 0;
  text-transform: none;
  color: var(--ink);
}
.on-machine {
  border-top: 1px solid var(--line);
  margin: 0 0 0.8rem;
  padding-top: 0.8rem;
}
.on-machine[hidden], .on-machine [hidden] { display: none; }
.form-error {
  border: 1px solid var(--danger);
  background: color-mix(in srgb, var(--danger) 7%, var(--card));
  color: var(--danger);
  border-radius: 8px;
  padding: 0.6rem 0.8rem;
  margin-bottom: 0.8rem;
  font-size: 0.9rem;
}
.form-actions { display: flex; gap: 0.6rem; margin-top: 0.4rem; }
.section-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.6rem 1rem;
  flex-wrap: wrap;
  margin-bottom: 0.6rem;
}
.section-head h2 { margin: 0; }
.title-line { display: flex; align-items: center; gap: 0.4rem 0.55rem; flex-wrap: wrap; }
.title-line h1 { margin: 0; }
.star-col, .star-cell { width: 1%; white-space: nowrap; text-align: center; vertical-align: middle; }
.star-form { display: inline-flex; margin: 0; vertical-align: middle; }
.star-btn {
  appearance: none;
  background: transparent;
  border: 1px solid transparent;
  border-radius: 8px;
  color: var(--accent-text);
  font-size: 1.05rem;
  line-height: 1;
  min-width: 2rem;
  min-height: 2rem;
  padding: 0 0.2rem;
  cursor: pointer;
}
.star-btn:hover { border-color: var(--line); text-decoration: none; }
.param-rows { display: flex; flex-direction: column; gap: 0.45rem; margin: 0 0 0.55rem; }
.param-row {
  display: grid;
  grid-template-columns: minmax(0, 1.1fr) minmax(0, 1.4fr) minmax(0, 0.8fr) auto;
  gap: 0.2rem 0.45rem;
  align-items: end;
}
.param-add { margin: 0 0 0.8rem; }
/* tool-form-ux: the parameter block on the new-tool form. */
.param-box { border: 1px solid var(--line); border-radius: 10px; padding: 0.75rem 0.9rem 0.4rem;
  margin: 0.4rem 0 0.9rem; min-width: 0; }
.param-box legend { padding: 0 0.35rem; }
.param-box .page-sub { margin: 0 0 0.5rem; }
.param-row .param-remove { margin-bottom: 0.15rem; }
.param-desc { grid-column: 1 / -1; margin: 0; font-size: 0.8rem; color: var(--muted); min-height: 0; }
.param-desc:empty { display: none; }
.param-suggest { margin: 0 0 0.6rem; }
.param-suggest .chips { display: flex; flex-wrap: wrap; gap: 0.35rem; margin-top: 0.3rem; }
.param-suggest .chip { cursor: pointer; border: 1px solid var(--line); font: inherit; font-size: 0.8rem;
  color: var(--ink); background: var(--card); padding: 0.2rem 0.6rem; }
.param-suggest .chip .mono { font-weight: 700; color: var(--accent-text); }
.param-suggest .chip[aria-pressed="true"] { background: color-mix(in srgb, var(--accent) 22%, var(--card));
  border-color: var(--accent); }
.param-suggest .chip:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 2px; }
.param-help { margin: 0 0 0.6rem; font-size: 0.85rem; }
.param-help summary { cursor: pointer; color: var(--accent-text); }
.param-glossary { margin: 0.4rem 0 0; display: grid; gap: 0.25rem; }
.param-glossary > div { display: grid; grid-template-columns: 7.5rem 1fr; gap: 0.5rem; }
.param-glossary dd { margin: 0; }
.loc-serials { display: block; margin-top: 0.15rem; font-size: 0.75rem; color: var(--muted); }
@media (max-width: 480px) {
  /* Phone: code + unit on one line, value full width, Remove under it. */
  .param-row { grid-template-columns: minmax(0, 1fr) minmax(0, 0.8fr);
    padding-bottom: 0.5rem; border-bottom: 1px solid var(--line); }
  .param-row .param-value { grid-column: 1 / -1; grid-row: 2; }
  .param-row .param-desc { grid-row: 3; }
  .param-row .param-remove { grid-column: 1 / -1; grid-row: 4; justify-self: start; min-height: 44px; }
  .param-suggest .chip, .param-add { min-height: 44px; }
  .param-glossary > div { grid-template-columns: 1fr; gap: 0; }
}
.add-plan summary { cursor: pointer; display: inline-block; margin-top: 0.4rem; }
.plan-form { margin-top: 0.6rem; border-top: 1px solid var(--line); padding-top: 0.6rem; }

/* ---------- buttons ---------- */
.btn {
  display: inline-block;
  font-family: var(--sans);
  font-size: 0.92rem;
  font-weight: 600;
  border-radius: 8px;
  border: 1px solid var(--line);
  padding: 0.5rem 0.95rem;
  cursor: pointer;
  background: var(--card);
  color: var(--ink);
  min-height: 40px;
}
.btn:hover { text-decoration: none; border-color: var(--accent); }
.btn:disabled { opacity: 0.55; cursor: not-allowed; }
.btn-primary { background: var(--accent); border-color: var(--accent); color: var(--on-accent); }
.btn-primary:hover { filter: brightness(1.04); }
.btn-warn { background: color-mix(in srgb, var(--warn) 22%, var(--card)); border-color: var(--warn); color: var(--accent-text); }
.btn-ghost { background: transparent; }
/* S4 verb colors. Issue uses the contract checked_out blue-grey already in
   .chip-info. Dispatch is that blue mixed with --ok so it is not the same
   blue and not the amber primary. Use is the existing accent. Scrap is danger. */
.btn-issue { background: var(--info-fill); border-color: var(--info-fill); color: var(--on-info); }
.btn-issue:hover { border-color: var(--info-fill); filter: brightness(1.15); }
.btn-dispatch {
  background: color-mix(in srgb, var(--info-fill) 28%, var(--ok));
  border-color: color-mix(in srgb, var(--info-fill) 40%, var(--ok));
  color: var(--on-dispatch);
}
.btn-dispatch:hover { border-color: color-mix(in srgb, var(--info-fill) 40%, var(--ok)); filter: brightness(1.05); }
.btn-use { background: var(--accent); border-color: var(--accent); color: var(--on-accent); }
.btn-use:hover { border-color: var(--accent); filter: brightness(1.04); }
.btn-scrap {
  background: color-mix(in srgb, var(--danger) 16%, var(--card));
  border-color: var(--danger);
  color: var(--danger);
}
.btn-scrap:hover { border-color: var(--danger); background: color-mix(in srgb, var(--danger) 26%, var(--card)); }
/* S5 relocate. Neutral: card, ink, line. Not Issue blue and not Use amber. */
.btn-move { background: var(--card); border-color: var(--line); color: var(--ink); }
.btn-move:hover { border-color: var(--ink); filter: none; }
.verb-open { margin: 0 0 0.9rem; }
.verb-open > .page-sub { margin: 0.15rem 0 0.7rem; }
.use-form .btn-use { margin-top: 0.8rem; }
.verb-stack {
  display: flex;
  flex-direction: column;
  gap: 0.85rem;
  min-width: 0;
  max-width: 100%;
}
.verb-stack > .verb-open,
.verb-stack > details.add-plan,
.verb-stack > details.correct-stock {
  margin: 0;
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 0.8rem 0.95rem;
}
.verb-stack > details.add-plan > summary,
.verb-stack > details.correct-stock > summary { margin-top: 0; }
.table-scroll { display: block; width: 100%; max-width: 100%; min-width: 0; overflow-x: auto; }
.table-scroll .data-table { width: max-content; min-width: 100%; }
.table-scroll .data-table th,
.table-scroll .data-table td { white-space: nowrap; }
.table-scroll .data-table tr.band-row > td { white-space: normal; }
th.col-off, td.col-off { display: none; }
.col-menu { margin: 0 0 0.55rem; max-width: 100%; }
.col-menu > summary {
  display: inline-flex;
  align-items: center;
  cursor: pointer;
  list-style: none;
  width: fit-content;
  min-height: 32px;
  padding: 0.3rem 0.7rem;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--card);
  color: var(--ink);
  font-size: 0.85rem;
  font-weight: 600;
}
.col-menu > summary::-webkit-details-marker { display: none; }
.col-menu > summary:hover { background: var(--paper); }
.col-menu[open] > summary { margin-bottom: 0.4rem; }
.col-menu-panel {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem 0.9rem;
  width: fit-content;
  max-width: 100%;
  padding: 0.7rem 0.85rem;
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: 10px;
  font-size: 0.82rem;
  color: var(--muted);
}
.col-menu-panel label { display: inline-flex; align-items: center; gap: 0.3rem; white-space: nowrap; }
.page-head .page-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.45rem;
  min-width: 0;
  max-width: 100%;
}
.page-head .page-actions > .inline-form {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.45rem;
  min-width: 0;
  max-width: 100%;
  flex: 1 1 auto;
}
.page-head .page-actions .list-search {
  flex: 1 1 10rem;
  width: auto;
  min-width: 0;
  max-width: min(220px, 100%);
  margin: 0;
}
.loc-new {
  margin: 0 0 1rem;
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 0.75rem 0.95rem;
}
.loc-new > summary { list-style: none; cursor: pointer; width: fit-content; }
.loc-new > summary::-webkit-details-marker { display: none; }
.loc-new > form { margin-top: 0.75rem; }
tr.band-row[hidden] { display: none; }
.band-row td { background: color-mix(in srgb, var(--paper) 70%, var(--card)); }
.band-row form { max-width: 100%; }
.part-actions { white-space: nowrap; }
.part-actions .inline-form { margin-left: 0.35rem; }
/* S6: correction is available, not a minus on Receive. */
.correct-stock { margin: 0.15rem 0 0.7rem; }
.correct-stock > summary {
  cursor: pointer;
  color: var(--muted);
  font-size: 0.82rem;
  width: fit-content;
}
.correct-stock > summary:hover { color: var(--ink); }
.correct-stock form { margin-top: 0.45rem; }
.history-list { margin: 0.35rem 0 0; padding-left: 1.1rem; font-size: 0.85rem; }
.history-list li { margin: 0.15rem 0; }
.latest-use { font-size: 0.85rem; color: var(--muted); }
.btn-sm { min-height: 32px; padding: 0.3rem 0.7rem; font-size: 0.85rem; }

/* ---------- login ---------- */
.login-wrap {
  min-height: 70vh;
  display: flex;
  align-items: center;
  justify-content: center;
}
.login-card { width: 380px; max-width: 92vw; padding: 1.6rem; }
.login-brand { display: flex; align-items: center; gap: 0.8rem; margin-bottom: 1.2rem; }
.login-logo {
  height: 48px;
  width: auto;
  aspect-ratio: auto 1018 / 764;   /* circle-corrected Fonnebust mark (2026-10-27): intrinsic ratio wins once loaded, never stretched */
  object-fit: contain;
  flex: 0 0 auto;
  display: block;
}
.login-title .brand-name { font-size: 1.15rem; }
.login-h1 { font-size: 1.1rem; margin: 0 0 1rem; font-weight: 600; }
.login-card .field { margin-bottom: 0.9rem; }
.login-card .btn { width: 100%; }
.login-hint { color: var(--muted); font-size: 0.82rem; margin-top: 1rem; }
.login-hint code { font-size: 0.78rem; }

/* ---------- wave-2/3 additions ---------- */
.mt { margin-top: 1.4rem; }
.banner { border-radius: 8px; padding: 0.6rem 0.9rem; font-size: 0.9rem; margin-bottom: 0.8rem; }
.banner-error { border: 1px solid var(--danger); background: color-mix(in srgb, var(--danger) 7%, var(--card)); color: var(--danger); }
.form-card { padding: 1.2rem; }
.form-row { display: flex; gap: 0.6rem; align-items: center; margin: 0.6rem 0; flex-wrap: wrap; }

/* correlations */
.corr-cols { display: grid; grid-template-columns: minmax(220px, 260px) 1fr; gap: 1.2rem; align-items: start; }
.corr-left { border: 1px solid var(--line); border-radius: 10px; padding: 0.9rem; background: var(--card); }
/* form controls outside a .field (picker rows, search filters, lightbox note)
   share the .field input styling (fix wave item 14) */
.corr-search, .asm-pick, .asm-qty, .asm-role, .lb-note, .lb-photo {
  font-family: var(--sans);
  font-size: 0.95rem;
  color: var(--ink);
  background: var(--field-bg);
  border: 1px solid var(--line-strong);
  border-radius: 7px;
  padding: 0.5rem 0.65rem;
}
.asm-pick, .asm-qty, .asm-role { font-family: var(--mono); font-size: 0.85rem; }
.lb-note { font-family: var(--mono); font-size: 0.85rem; width: 100%; margin-top: 0.6rem; }
.corr-search:focus, .asm-pick:focus, .asm-qty:focus, .asm-role:focus, .lb-note:focus, .lb-photo:focus {
  outline: 2px solid var(--focus-ring);
  outline-offset: -1px;
}
.corr-search { width: 100%; margin-bottom: 0.6rem; }
.corr-search.list-search { width: min(220px, 100%); }
.corr-list { list-style: none; max-height: 60vh; overflow: auto; }
@media (max-width: 820px) {
  .corr-cols { grid-template-columns: 1fr; }
  .corr-list { max-height: 30vh; }
}
.corr-right .empty-lg { padding: 1rem; }
.corr-list li { border-bottom: 1px solid var(--line); }
.corr-item { display: flex; justify-content: space-between; gap: 0.5rem; padding: 0.5rem 0.3rem; text-decoration: none; }
.corr-item:hover { background: color-mix(in srgb, var(--accent) 10%, var(--card)); }
.corr-item.active { background: color-mix(in srgb, var(--accent) 18%, var(--card)); box-shadow: inset 3px 0 0 var(--accent); }
.add-corr { border-top: 1px solid var(--line); padding-top: 0.6rem; }

/* bar charts (charts page) */
.bar-list { list-style: none; max-width: 760px; }
.bar-list li { display: grid; grid-template-columns: minmax(8rem, 14rem) minmax(4rem, 1fr) auto; gap: 0.3rem 0.6rem; align-items: center; padding: 0.3rem 0; }
.bar-lbl { font-size: 0.88rem; overflow-wrap: anywhere; }
.bar-fill.bar-late { background: var(--danger); }
.bar-fill.bar-soon { background: var(--accent); }
@media (max-width: 480px) {
  .bar-list li { grid-template-columns: minmax(0, 1fr) auto; }
  .bar-list li .bar-lbl { grid-column: 1 / -1; }
  .day-toggle .btn { min-height: 44px; }
}
.bar-track { height: 14px; background: color-mix(in srgb, var(--line) 45%, var(--card)); border-radius: 4px; overflow: hidden; }
.bar-fill { display: block; height: 100%; background: var(--accent); border-radius: 4px; }
.bar-val { text-align: right; font-size: 0.8rem; }
.kpi { background: var(--card); border: 1px solid var(--line); border-radius: 10px; padding: 0.9rem 1rem; }
.kpi-num { font-size: 1.5rem; font-weight: 700; }
.kpi-lbl { color: var(--muted); font-size: 0.75rem; letter-spacing: 0.08em; text-transform: uppercase; }

/* service lightbox */
#lightbox { max-width: 640px; margin: 0 auto 1.4rem; }
.lb-dots { text-align: center; color: var(--muted); font-size: 0.8rem; margin-bottom: 0.4rem; }
.lb-stage { perspective: 1200px; min-height: 320px; display: flex; align-items: center; justify-content: center; }
.lb-card {
  width: 100%; background: var(--card); border: 1px solid var(--line); border-radius: 14px;
  padding: 1.4rem 1.6rem; box-shadow: 0 12px 30px var(--shadow-md);
  transition: transform 0.18s ease, opacity 0.18s ease; touch-action: pan-y;
}
.lb-card-top { display: flex; justify-content: space-between; align-items: center; margin-bottom: 0.6rem; }
.lb-card h3 { margin: 0 0 0.5rem; font-size: 1.25rem; }
.lb-instr { color: var(--muted); font-size: 0.95rem; line-height: 1.5; }
.lb-last { font-size: 0.8rem; color: var(--accent-text); }
.lb-note { width: 100%; margin-top: 0.6rem; }
.lb-photo { margin-top: 0.6rem; }
.lb-photo-msg { font-size: 0.8rem; color: var(--muted); display: block; margin-top: 0.3rem; }
/* Service comments and photos (2026-10-12 service-uploads) */
.lb-note-wrap .field { margin-top: 0.6rem; }
.lb-photo { min-height: 44px; }
.svc-notes { flex-basis: 100%; margin: 0.3rem 0 0; }
.svc-note { margin: 0.2rem 0; font-size: 0.85rem; overflow-wrap: anywhere; }
.svc-thumb { display: block; max-width: 160px; max-height: 120px; margin-top: 0.3rem; border-radius: 4px; border: 1px solid var(--line); object-fit: cover; }
.svc-note .mono { white-space: normal; }
.lb-controls { display: flex; justify-content: center; gap: 0.8rem; margin-top: 1rem; }
.lb-hint { text-align: center; color: var(--muted); font-size: 0.75rem; margin-top: 0.7rem; }
#finish-card { max-width: 640px; margin: 0 auto; padding: 1.2rem; }
#fin-add-line { margin: 0.2rem 0 0.9rem; }

/* service list rows */
.svc-open { font-weight: 600; }

/* ---------- issues & returns (tools / machine pages) ---------- */
.issue-form { margin-top: 0.6rem; border-top: 1px solid var(--line); padding-top: 0.6rem; }
.inline-return summary { cursor: pointer; }
.inline-return form { margin-top: 0.5rem; }
.banner-ok { border: 1px solid var(--ok); background: color-mix(in srgb, var(--ok) 8%, var(--card)); color: var(--ink); }

/* ---------- wave 7.4 — dispatch recall surfaces, mobile (390px) ----------
   The NEW Recall targets (tool-page "Dispatched — recall any time" section and
   the /out "On machines" strip) are the row's primary action on a phone: bump
   their summary/submit to 40px tap targets at <=480px. Existing styles are
   reused everywhere else; the wave-7.2 machine-page Recall keeps its own size.
   No new nav item. */
@media (max-width: 480px) {
  .dispatched-strip details.inline-return summary,
  .out-dispatch details.inline-return summary,
  .dispatched-strip .band-open,
  .out-dispatch .band-open,
  .dispatched-strip details.inline-return button[type="submit"],
  .out-dispatch details.inline-return button[type="submit"],
  .dispatched-strip .band-row button[type="submit"],
  .out-dispatch .band-row button[type="submit"] {
    min-height: 40px;
    padding: 0.4rem 0.9rem;
  }
}

/* ---------- charts day toggle ---------- */
.day-toggle { display: flex; gap: 0.4rem; margin-bottom: 0.8rem; }
.day-active { border-color: var(--accent) !important; color: var(--accent-text) !important; background: color-mix(in srgb, var(--accent) 12%, var(--card)); }

/* ---------- people + what's-out (wave 7.3) ---------- */
.muted { color: var(--muted); }
.form-grid-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
@media (max-width: 480px) {
  .form-grid-2,
  .form-grid-3 { grid-template-columns: 1fr; }
  /* Service lightbox finish grid keeps two columns. Do not restyle it. */
  #finish-card .form-grid-2,
  #lightbox .form-grid-2,
  #lightbox .form-grid-3 { grid-template-columns: repeat(2, 1fr); }
}
.row-actions { white-space: nowrap; text-align: right; }
.row-actions .inline-details { display: inline-block; margin-left: 0.4rem; }
.inline-details summary { cursor: pointer; }
.inline-details form { margin-top: 0.5rem; }
.user-name { text-decoration: none; color: inherit; }
.user-name:hover { text-decoration: underline; }
.people-table td { vertical-align: top; }
.out-dispatch { margin-top: 1rem; border-top: 1px solid var(--line); padding-top: 0.6rem; }
tr.row-overdue { background: color-mix(in srgb, var(--danger) 8%, var(--card)); }
tr.row-overdue td:first-child { border-left: 3px solid var(--danger); }

/* drills geometry list — filter row */
.drill-filters { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem 0.75rem; margin: 0 0 0.85rem; }
.drill-kinds { display: flex; flex-wrap: wrap; gap: 0.35rem; }
.drill-kinds a.chip { text-decoration: none; }
.drill-kinds a.chip-on { background: color-mix(in srgb, var(--accent) 18%, var(--card)); color: var(--accent-text); border-color: var(--accent); }
.drill-filters .corr-search { width: 16rem; margin: 0; }
.drill-dc {
  display: inline-flex;
  flex-wrap: nowrap;
  align-items: center;
  gap: 0.55rem;
  margin: 0;
  padding: 0.3rem 0.6rem;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--card);
  color: var(--ink);
}
.drill-dc-name {
  font-family: var(--mono);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.08em;
  color: var(--muted);
}
.drill-dc label {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  font-size: 0.82rem;
  color: var(--muted);
  white-space: nowrap;
}
.drill-filters .drill-dc input { width: 5.2rem; margin: 0; }
.data-table th a.sort-link { color: inherit; text-decoration: none; }
.data-table th a.sort-link.sort-on { color: var(--accent-text); }

/* ---------- phone (820px): menu, page stack, table scroll ---------- */
@media (max-width: 820px) {
  .topbar, .page, .footer { min-width: 0; max-width: 100%; }
  .topbar {
    flex-wrap: wrap;
    align-items: center;
    gap: 0.25rem 0.6rem;
    padding: 0.4rem 0.75rem;
  }
  .brand { flex: 0 0 auto; max-width: none; overflow: visible; }
  .topbar .brand-name {
    letter-spacing: 0.12em;
    overflow: visible;
    white-space: nowrap;
  }
  .userbox {
    order: 2;
    flex: 1 1 0;
    min-width: 0;
    justify-content: flex-end;
  }
  .userbox .user-name {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
  .nav {
    flex-direction: column;
    align-items: stretch;
    gap: 0.1rem;
  }
  .drill-filters .drill-dc { flex-basis: 100%; }
  .nav a {
    display: flex;
    align-items: center;
    width: 100%;
    min-height: 44px;
  }
  .page {
    padding: 0.75rem;
    overflow-x: clip;
    overflow-y: visible;
  }
  .page-head {
    flex-direction: column;
    align-items: flex-start;
  }
  .page-head > .page-sub { flex: 0 1 auto; }   /* a column: the 16rem row basis would be a 16rem tall gap */
  .page-head .btn,
  .btn.btn-primary,
  .btn.btn-issue,
  .btn.btn-dispatch,
  .btn.btn-use,
  .btn.btn-scrap,
  .btn.btn-move,
  .verb-stack .btn,
  .verb-open .btn,
  .dispatched-strip button.btn.btn-primary,
  .out-dispatch button.btn.btn-primary {
    min-height: 44px;
  }
  .detail-cols { grid-template-columns: repeat(auto-fit, minmax(min(100%, 320px), 1fr)); }
  .board-cols { grid-template-columns: repeat(auto-fit, minmax(min(100%, 280px), 1fr)); }
  .machine-grid { grid-template-columns: repeat(auto-fill, minmax(min(100%, 240px), 1fr)); }
  .section:has(table),
  .table-scroll,
  .dispatched-strip:has(table) {
    max-width: 100%;
    min-width: 0;
    overflow-x: auto;
  }
}
/* Audit 2026-10-12 login.md: an open phone menu is not sticky, so it scrolls
   away instead of covering the buttons under it. */
@media (max-width: 820px) {
  .topbar:has(.nav-toggle:checked) { position: static; }
  .login-card .field input { min-height: 44px; }
}
@media (max-width: 480px) {
  .topbar .brand-tag { display: none; }
  .topbar .brand-name { letter-spacing: 0.06em; font-size: 0.9rem; }
  .userbox .chip { display: none; }
  /* Audit 2026-10-12 web-gui/login/machines/gages/charts: stack the footer so
     "Fonnebust AS" and "Europe/Oslo" stay whole phrases. */
  .footer { flex-direction: column; align-items: flex-start; }
  .footer > span { white-space: nowrap; }
}

/* Audit 2026-10-12 machine-detail.md: plan name on its own line; Deactivate
   off the button row. */
.plan-head > .plan-name-line { flex: 1 0 100%; }
.plan-deactivate { margin: 0.35rem 0 0.2rem; }
.fixed-value { display: block; padding: 0.35rem 0; font-weight: 500; }
/* Audit 2026-10-12 machine-detail.md / tool-detail.md: open issues stack on
   a phone so Return/Recall and its band stay inside the column. */
@media (max-width: 480px) {
  .table-scroll .data-table.issue-table,
  .issue-table, .issue-table tbody, .issue-table tr, .issue-table td { display: block; width: 100%; }
  .issue-table tr.issue-head { display: none; }
  .issue-table tr.issue-row { display: flex; flex-wrap: wrap; gap: 0.25rem 0.6rem; align-items: center;
    padding: 0.5rem 0.75rem; border-bottom: 1px solid var(--line); }
  .issue-table tr.issue-row > td { width: auto; padding: 0; border: 0; white-space: normal; }
  .issue-table tr.issue-row > td:last-child { margin-left: auto; }
  .issue-table tr.band-row[hidden] { display: none; }
  .issue-table .band-open { min-height: 44px; }
}

/* Audit 2026-10-12 tools.md: on a phone NAME wraps so KIND and STOCK stay in
   the first screen of the table. */
@media (max-width: 480px) {
  .table-scroll .tool-table td[data-col="name"] { white-space: normal; min-width: 7rem; max-width: 10rem; }
}
.due-late { color: var(--danger); font-weight: 600; }
@media (max-width: 820px) {
  .gage-table .row-anchor { display: inline-flex; align-items: center; min-height: 44px; }
}

/* Audit 2026-10-12 tool-detail.md: serial, history, and parts tables fit the
   card. Cells wrap; row actions and their bands stay in view. */
/* Root fix 0.4.3: never let a table squeeze columns to one letter. The table
   is at least the card's width but grows to its content and the
   .table-scroll wrapper scrolls sideways. Headers, dates, numbers and chips
   never wrap; long free text wraps only between words, up to 24rem wide. */
.table-scroll .data-table.wrap-table { width: max-content; min-width: 100%; }
.table-scroll .data-table.wrap-table th { white-space: nowrap; }
.table-scroll .data-table.wrap-table td { white-space: normal; overflow-wrap: break-word; word-break: normal; max-width: 24rem; }
.table-scroll .data-table.wrap-table td.mono,
.table-scroll .data-table.wrap-table td.num,
.table-scroll .data-table.wrap-table td .chip { white-space: nowrap; }
.table-scroll .data-table.wrap-table td .btn { white-space: nowrap; }
.wrap-table .band-row input, .wrap-table .band-row select { max-width: 100%; min-width: 0; }
@media (max-width: 820px) {
  .correct-stock > summary { display: inline-flex; align-items: center; min-height: 44px; }
}

.table-scroll .band-row > td > form.band-pinned { position: sticky; left: 0; box-sizing: border-box; }
.table-scroll .data-table td.sticky-action { position: sticky; right: 0; background: var(--card); }
/* Audit 2026-10-12 service.md: 44px Start on a phone. */
@media (max-width: 820px) {
  .strip-list .btn-sm { min-height: 44px; display: inline-flex; align-items: center; }
}

/* Audit 2026-10-12 events.md: the feed fits a phone; detail wraps. */
.table-scroll .data-table.events-table { width: 100%; }
.table-scroll .data-table.events-table td.ev-detail { white-space: normal; overflow-wrap: break-word; min-width: 12rem; }
@media (max-width: 480px) {
  .table-scroll .data-table.events-table td.ev-when { white-space: normal; }
}
/* web 0.24.4: Undo save + a short grouped summary of the rest of the save; the full breakdown in
   <details>. It wraps inside its cell and never widens the table (was a raw nowrap type list). */
.table-scroll .data-table.events-table td.ev-undo { white-space: normal; vertical-align: top; }
.ev-save { max-width: 15rem; margin-top: 0.25rem; font-size: 0.8rem; color: var(--muted); overflow-wrap: anywhere; }
.ev-save > summary { cursor: pointer; line-height: 1.35; }
.ev-save > summary:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 2px; border-radius: 3px; }
.ev-save[open] > summary { color: var(--ink); }
.ev-save-k { margin: 0.35rem 0 0.15rem; color: var(--ink); font-weight: 600; }
.ev-save-list { margin: 0; padding-left: 1.1rem; color: var(--ink); }
.ev-save-list li { margin: 0.05rem 0; }
@media (min-width: 821px) { .table-scroll .data-table.events-table td.ev-undo { min-width: 12rem; } }
@media (max-width: 820px) { .ev-save { max-width: none; } }
/* a 44 px tap target (Audit C) with the text centred, not one 44 px line per wrapped line */
@media (pointer: coarse), (max-width: 767px) {
  .ev-save { margin-top: 0.1rem; }
  .ev-save > summary { line-height: 1.35; padding: 0.7rem 0; min-height: 44px; box-sizing: border-box; }
  .ev-save-k { margin-top: 0.1rem; }
}
/* Audit 2026-10-18 events.md L3: stack one event on a narrow screen so
   Recorded by is in the first screen. Other tables stay one line. */
@media (max-width: 820px) {
  .table-scroll .data-table.events-table {
    display: block;
    width: 100%;
    min-width: 0;
  }
  .table-scroll .data-table.events-table tbody,
  .table-scroll .data-table.events-table tr,
  .table-scroll .data-table.events-table td {
    display: block;
    width: 100%;
    min-width: 0;
    box-sizing: border-box;
  }
  .table-scroll .data-table.events-table tr:first-child { display: none; }
  .table-scroll .data-table.events-table tr {
    padding: 0.55rem 0.75rem 0.7rem;
    border-top: 1px solid var(--line);
  }
  .table-scroll .data-table.events-table td {
    padding: 0.12rem 0;
    border: 0;
    white-space: normal;
    overflow-wrap: anywhere;
  }
  .table-scroll .data-table.events-table td.ev-detail,
  .table-scroll .data-table.events-table td.ev-when,
  .table-scroll .data-table.events-table td.ev-what,
  .table-scroll .data-table.events-table td.ev-who { min-width: 0; white-space: normal; }
  .table-scroll .data-table.events-table td.ev-who::before {
    content: "Recorded by";
    display: block;
    color: var(--muted);
    font-size: 0.72rem;
    font-weight: 600;
    letter-spacing: 0.04em;
    text-transform: uppercase;
  }
}

/* Audit 2026-10-12 people.md: one person per block under 820px, form inside. */
@media (max-width: 820px) {
  .table-scroll .data-table.people-table,
  .people-table, .people-table tbody, .people-table tr, .people-table td { display: block; width: 100%; }
  .people-table tr:first-child { display: none; }
  .people-table tr.people-row { display: flex; flex-wrap: wrap; gap: 0.3rem 0.6rem; align-items: center;
    padding: 0.6rem 0.75rem; border-top: 1px solid var(--line); }
  .people-table tr.people-row > td { width: auto; padding: 0; border: 0; white-space: normal; }
  .people-table tr.people-row > td:first-child { flex: 1 0 100%; }
  .people-table td.row-actions { flex: 1 0 100%; text-align: left; white-space: normal;
    display: grid; grid-template-columns: repeat(auto-fit, minmax(9.5rem, 1fr)); gap: 0.5rem; }
  .people-table td.row-actions > .btn,
  .people-table td.row-actions > form.inline-form { width: 100%; margin: 0; }
  .people-table td.row-actions > :last-child:nth-child(odd):not(:first-child) { grid-column: 1 / -1; }
  .people-table td.row-actions .btn { min-height: 44px; width: 100%; justify-content: center;
    display: inline-flex; align-items: center; text-align: center; white-space: nowrap; }
  .people-table tr.band-row[hidden] { display: none; }
}

.corr-main { display: flex; flex-direction: column; min-width: 0; }
.corr-sku { display: none; }
.corr-count { color: var(--muted); font-weight: 400; margin-left: 0.3rem; }
/* tool-form-ux: the correlations tool list on a phone. Full-width rows, no
   bullet indent, name over sku, kind as a quiet tag on the right, 48px rows,
   and a taller scroll box with a visible edge. Desktop is unchanged. */
@media (max-width: 820px) {
  .corr-left { padding: 0.75rem; }
  .corr-list { padding: 0; margin: 0; max-height: 55vh; overscroll-behavior: contain;
    border-top: 1px solid var(--line); }
  .corr-list li:last-child { border-bottom: 0; }
  .corr-item { align-items: center; min-height: 48px; padding: 0.45rem 0.25rem; }
  .corr-item .strip-name { font-weight: 600; overflow-wrap: anywhere; line-height: 1.25; }
  .corr-sku { display: block; font-size: 0.75rem; color: var(--muted); margin-top: 0.1rem;
    overflow-wrap: anywhere; }
  .corr-kind { flex: none; font-size: 0.72rem; color: var(--muted); border: 1px solid var(--line);
    border-radius: 999px; padding: 0.1rem 0.5rem; white-space: nowrap; }
  .corr-right { scroll-margin-top: 4.5rem; }
}

/* Audit 2026-10-12 correlations.md: wider tool column. */
@media (min-width: 821px) {
  .corr-cols { grid-template-columns: minmax(360px, 42%) 1fr; }
}

/* ---------- sortable columns (web/sorting.py, every table) ----------
   Same look as the original /tools name sort: the header text is the link,
   the active column takes the accent and an arrow. A faint ↕ hints that an
   inactive header sorts. Headers are 44px tall touch targets on a phone. */
/* The scroller is the containing block, so a hidden label in a wide table
   does not stretch the page on a phone. */
.table-scroll { position: relative; }
.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0; }
/* Header text may wrap (long labels like EDGE STARTS 30D) so a sortable
   header never makes a phone page wider than the screen. */
.data-table th, .data-table th a.sort-link { white-space: nowrap; }
.data-table th a.sort-link { display: inline-block; }
.data-table th .sort-ind { white-space: nowrap; }
.data-table th a.sort-link:hover { color: var(--accent-text); text-decoration: underline; }
.data-table th a.sort-link:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 2px; }
.data-table th[aria-sort="none"] a.sort-link::after { content: "↕"; opacity: 0.35; font-size: 0.8em; }
/* Shared SORT pill row (sort_strip / sort_link in web/sorting.py): one compact
   row that scrolls sideways instead of wrapping. Same on every page. */
.sort-strip { display: flex; flex-wrap: nowrap; gap: 6px; align-items: center; margin-bottom: 0.75rem; max-width: 100%; min-width: 0; width: 100%; box-sizing: border-box; position: relative;
  overflow-x: auto; scrollbar-width: none; -webkit-overflow-scrolling: touch; padding-bottom: 2px; }
.sort-strip::-webkit-scrollbar { display: none; }
.sort-strip > .micro { flex: 0 0 auto; }
.sort-strip .sort-link.chip { flex: 0 0 auto; display: inline-flex; align-items: center; box-sizing: border-box;
  min-height: 30px; padding: 4px 10px; font-size: 12px; line-height: 1; text-decoration: none; white-space: nowrap; }
.sort-strip .sort-link.chip-on { background: color-mix(in srgb, var(--accent) 18%, var(--card)); color: var(--accent-text); border-color: var(--accent); }
@media (max-width: 820px) {
  .data-table th a.sort-link { display: inline-flex; align-items: center; min-height: 44px; }
  /* People stack per person on a phone: the header row is replaced by the
     shared SORT pill strip (sort_strip in web/sorting.py), as on Machines. */
  .people-table tr:first-child { display: none; }
}
/* Pill strips that stand in for a stacked table's header only on a phone. */
.sort-strip-m820, .sort-strip-m480 { display: none; }
@media (max-width: 820px) { .sort-strip-m820 { display: flex; } }
@media (max-width: 480px) {
  .sort-strip-m480 { display: flex; }
  /* Open issues stack on a phone: same treatment as People. */
  .issue-table tr.issue-head { display: none; }
}
/* Stock movements: one colour + icon per action so they are not mixed up.
   Receive = green (stock in), Move to machine = violet (Issue is blue), Put back = amber,
   Scrap = danger red, Correct = teal. */
.mv-desc { display: block; font-size: 0.8rem; color: var(--muted); margin: 0.15rem 0 0.4rem; }
.btn-mv-in   { background: color-mix(in srgb, var(--ok) 16%, var(--card)); border-color: var(--ok); color: var(--ink); }
.btn-mv-out  { background: color-mix(in srgb, var(--move-out) 16%, var(--card)); border-color: var(--move-out); color: var(--ink); }
.btn-mv-back { background: color-mix(in srgb, var(--warn) 20%, var(--card)); border-color: var(--warn); color: var(--ink); }
.btn-mv-in:hover, .btn-mv-out:hover, .btn-mv-back:hover { filter: brightness(0.95); }
.mv-ico { display: inline-block; margin-right: 0.35em; font-weight: 700; }
details.mv-action { border-left: 3px solid var(--line); padding-left: 0.6rem; }
details.mv-in { border-left-color: var(--ok); }
details.mv-out { border-left-color: var(--move-out); }
details.mv-back { border-left-color: var(--warn); }
details.mv-scrap { border-left-color: var(--danger); }
/* Correct stock (set to counted) = teal, ✎. */
.btn-mv-count { background: color-mix(in srgb, var(--move-count) 16%, var(--card)); border-color: var(--move-count); color: var(--ink); }
.btn-mv-count:hover { filter: brightness(0.95); }
details.mv-count { border-left-color: var(--move-count); }
details.correct-stock > summary.btn-mv-count { list-style: none; color: var(--ink); font-size: 0.82rem; }
details.correct-stock > summary.btn-mv-count:hover { color: var(--ink); }
/* tool-form-ux: JS-only controls stay hidden until the script reveals them. */
.param-add[hidden], .param-remove[hidden], .param-suggest[hidden] { display: none; }
/* consumables-entry: a field the chosen kind does not use. */
.kind-off { display: none !important; }
.field-note { display: block; font-size: 0.78rem; color: var(--muted); margin-top: 0.2rem; }
tr.row-added > td { background: color-mix(in srgb, var(--ok) 12%, var(--card)); }

/* Phase 2 B: pending agent changes */
.nav-badge { display: inline-block; min-width: 18px; padding: 0 5px; margin-left: 4px;
  border-radius: 9px; background: var(--danger-fill); color: var(--on-danger); font-size: 11px; line-height: 18px;
  text-align: center; font-weight: 700; }
.nav-badge[hidden] { display: none; }
.prop-card { margin-bottom: 12px; }
.prop-head { display: flex; flex-wrap: wrap; gap: 6px 10px; align-items: center; }
.prop-ops { margin: 8px 0; padding-left: 18px; }
.prop-diff td, .prop-diff th { font-size: 13px; }
.prop-diff .was { color: var(--diff-was); text-decoration: line-through; }
.prop-diff .now { color: var(--diff-now); font-weight: 600; }
.prop-actions { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 8px; }
.prop-actions .btn { min-height: 44px; }

/* Phase 3 B: media strip, photo gallery, labels picker. */
.media-strip { display: flex; align-items: center; gap: 0.75rem; padding: 0.6rem 0.75rem; margin-bottom: 1rem; }
.media-thumb { flex: 0 0 64px; width: 64px; height: 64px; border-radius: 8px; overflow: hidden; display: flex; align-items: center; justify-content: center;
  background: color-mix(in srgb, var(--muted) 12%, var(--card)); border: 1px solid color-mix(in srgb, var(--muted) 30%, transparent); }
.media-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.media-thumb-empty { font-size: 1.5rem; filter: grayscale(1); color: var(--muted); }
.media-meta { display: flex; flex-direction: column; gap: 0.15rem; min-width: 0; flex: 1 1 auto; }
.media-photos { font-weight: 600; min-height: 32px; display: inline-flex; align-items: center; }
.media-code { font-size: 0.8rem; color: var(--muted); letter-spacing: 0.04em; }
.media-print { flex: 0 0 auto; min-height: 44px; display: inline-flex; align-items: center; }
.photo-upload { display: grid; gap: 0.5rem; margin-bottom: 1rem; }
.photo-take { min-height: 52px; display: inline-flex; align-items: center; justify-content: center; cursor: pointer; font-size: 1rem; }
.photo-filter { margin-top: 0.25rem; }
.photo-grid { list-style: none; margin: 0 0 1rem; padding: 0; display: grid; gap: 0.6rem; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); }
.photo-cell { min-width: 0; }
.photo-open { display: block; width: 100%; aspect-ratio: 1 / 1; padding: 0; border: 1px solid color-mix(in srgb, var(--muted) 30%, transparent); border-radius: 8px; overflow: hidden; background: var(--card); cursor: zoom-in; }
.photo-open img { width: 100%; height: 100%; object-fit: cover; display: block; }
.photo-cap { margin-top: 0.3rem; line-height: 1.35; overflow-wrap: anywhere; }
.photo-view { max-width: min(96vw, 900px); padding: 0; border: 0; border-radius: 12px; }
.photo-view::backdrop { background: var(--scrim); }
.photo-view-inner { padding: 0.75rem; display: grid; gap: 0.5rem; }
.photo-view-inner img { max-width: 100%; max-height: 70vh; object-fit: contain; margin: 0 auto; }
.photo-view-actions { display: flex; flex-wrap: wrap; gap: 0.4rem; }
.photo-view-actions .btn { min-height: 44px; }
.label-list { list-style: none; margin: 0.5rem 0; padding: 0; max-height: 55vh; overflow-y: auto; border-top: 1px solid color-mix(in srgb, var(--muted) 25%, transparent); }
.label-list li { border-bottom: 1px solid color-mix(in srgb, var(--muted) 25%, transparent); }
.label-list .field-check { display: flex; flex-wrap: wrap; gap: 0.25rem 0.6rem; min-height: 44px; padding: 0.35rem 0; }
.label-code { font-weight: 600; letter-spacing: 0.04em; }
.label-title { min-width: 0; overflow-wrap: anywhere; }
.label-filter, .label-pick { margin-bottom: 1rem; }
@media (max-width: 480px) {
  .photo-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .media-strip { flex-wrap: wrap; }
  .media-print { margin-left: auto; }
}

/* Phase 4: fault reports + webhooks */
.fault-banner { display: block; text-decoration: none; margin-bottom: 12px; font-weight: 600; }
.banner-warn { background: color-mix(in srgb, var(--warn) 12%, var(--card)); border: 1px solid var(--warn); color: var(--warn-text); padding: 10px 12px; border-radius: 8px; }
.fault-badge { font-size: .55em; vertical-align: middle; padding: 2px 8px; border-radius: 999px; border: 1px solid var(--danger); color: var(--danger); background: color-mix(in srgb, var(--danger) 12%, var(--card)); text-decoration: none; }
.fault-row { margin-bottom: 8px; border-left: 4px solid var(--warn); }
.fault-row.sev-high, .fault-row.sev-critical { border-left-color: var(--danger); }
.fault-row.sev-low { border-left-color: var(--muted); }
/* web 0.22.0: the severity palette moved here from the faults page so it follows the theme */
.fault-sev-critical { background: var(--sev-critical); color: var(--on-sev); }
.fault-sev-high { background: var(--sev-high); color: var(--on-sev); }
.fault-sev-medium { background: var(--sev-medium); color: var(--on-sev); }
.fault-sev-low { background: var(--sev-low); color: var(--on-sev-low); }
.fault-row.sev-critical { border-left: 4px solid var(--sev-critical); }
.fault-row.sev-high { border-left: 4px solid var(--sev-high); }
.fault-pics img { max-height: 96px; margin: 4px; }
.fault-desc { white-space: pre-wrap; margin: 6px 0; overflow-wrap: anywhere; }
.fault-actions, .hook-actions { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 8px; }
.hook-row { margin-bottom: 10px; }
.hook-url { overflow-wrap: anywhere; }
.secret-box { font-family: var(--mono, monospace); overflow-wrap: anywhere; padding: 8px; border: 1px dashed var(--line-strong); border-radius: 6px; }

/* break-it pass 2026-10-13: voided calibrations read as voided */
tr.cal-voided > td { color: var(--muted); text-decoration: line-through; }
tr.cal-voided > td .chip { text-decoration: none; }
/* break-it pass: a long unbroken name (SKU, pasted serial) must wrap, not widen the page */
.machine-name, .page-head h1, .page-head .page-sub, .kv-table td, .card h2, .card h3 { overflow-wrap: anywhere; min-width: 0; }

/* 2026-10-13 phone pass: header = logo · Menu · account, one row at 390 px.
   Agent keys moved into the nav. The name collapses to an initial avatar. */
.avatar { display: none; width: 30px; height: 30px; border-radius: 50%; background: var(--ink); color: var(--paper);
          font-weight: 700; font-size: 0.85rem; align-items: center; justify-content: center; flex: none; }
.user-name { display: inline-flex; align-items: center; gap: 0.35rem; min-width: 0; }
.user-full { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 14em; }
@media (max-width: 820px) {
  .topbar { flex-wrap: wrap; }
  .userbox { flex-wrap: nowrap; gap: 0.4rem; }
  .userbox .avatar { display: inline-flex; }
  .userbox .user-full, .userbox .chip { display: none; }
  .userbox .btn { white-space: nowrap; }
}

/* Service plans on a phone: name + meta, then one compact actions row. */
.plan-top { gap: 0.15rem 0.6rem; }
.plan-top .plan-name { flex: 1 1 100%; }
.plan-meta { color: var(--muted); font-size: 0.85rem; }
.plan-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 0.4rem; margin-top: 0.4rem; min-width: 0; }
.plan-actions > form, .plan-actions > details { margin: 0; flex: 0 0 auto; }
.plan-actions > details[open] { order: 9; flex: 1 1 100%; }
.plan-actions > details > summary { list-style: none; }
.task-row { display: grid; grid-template-columns: 1.6rem minmax(0, 1fr) auto auto; align-items: center; gap: 0.25rem 0.4rem;
            border-top: 1px solid var(--line); padding: 0.3rem 0; }
.task-row .task-pos { color: var(--muted); text-align: right; }
.task-row > .task-edit, .task-row > .task-remove-form { margin: 0; }
.task-row > .task-edit[open] { grid-column: 1 / -1; grid-row: 2; }
.task-row .btn-sm { padding: 0.15rem 0.5rem; min-height: 30px; font-size: 0.8rem; }
.task-row > .task-edit > summary { list-style: none; }
.plan-actions summary.btn, .task-row summary.btn { display: inline-flex; align-items: center; line-height: 1.2; }
/* ---------- gage usage (usage-based calibration, migration 024) ---------- */
.interval-pick { border: 1px solid var(--line); border-radius: 10px; padding: 0.7rem 0.8rem 0.8rem; margin: 0.8rem 0; min-width: 0; }
.interval-pick legend { padding: 0 0.3rem; }
.seg { display: flex; flex-wrap: wrap; gap: 0.35rem; margin-bottom: 0.7rem; }
.seg-opt { position: relative; flex: 1 1 0; min-width: 6.5rem; }
.seg-opt input { position: absolute; opacity: 0; inset: 0; margin: 0; cursor: pointer; }
.seg-opt span { display: flex; align-items: center; justify-content: center; text-align: center; min-height: 44px; padding: 0.35rem 0.6rem;
  border: 1px solid var(--line); border-radius: 8px; background: var(--card); font-size: 0.88rem; line-height: 1.2; }
.seg-opt input:checked + span { border-color: var(--accent); color: var(--accent-text); font-weight: 600;
  background: color-mix(in srgb, var(--accent) 14%, var(--card)); }
.seg-opt input:focus-visible + span { outline: 2px solid var(--focus-ring); outline-offset: 2px; }
.interval-fields { gap: 0.6rem 0.8rem; }
.check-row { display: flex; align-items: center; gap: 0.5rem; min-height: 44px; grid-column: 1 / -1; }
.check-row input { width: 1.2rem; height: 1.2rem; flex: none; }
/* Show only the fields of the picked mode (no JS; :has is in every current phone browser). */
.interval-pick:has(input[value="time"]:checked) [data-show]:not([data-show~="time"]),
.interval-pick:has(input[value="uses"]:checked) [data-show]:not([data-show~="uses"]),
.interval-pick:has(input[value="either"]:checked) [data-show]:not([data-show~="either"]) { display: none; }

.use-meter { display: inline-flex; align-items: center; gap: 0.4rem; vertical-align: middle; white-space: nowrap; }
.use-bar { display: inline-block; width: 4.5rem; height: 6px; border-radius: 3px; background: color-mix(in srgb, var(--line) 60%, var(--card)); overflow: hidden; }
.use-bar > span { display: block; height: 100%; background: var(--ok); }
.use-soon .use-bar > span { background: var(--warn); }
.use-late .use-bar > span { background: var(--danger); }
.use-num { font-size: 0.8rem; color: var(--muted); }
.use-late .use-num { color: var(--danger); }
.gage-table td .use-meter { display: flex; margin-top: 0.2rem; }

.usage-card .use-meter { display: flex; margin: 0.3rem 0 0.8rem; }
.usage-card .use-bar { flex: 1; height: 10px; border-radius: 5px; width: auto; }
.usage-big { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.3rem 0.8rem; }
.usage-count { font-size: 1.8rem; font-weight: 600; }
.usage-of { font-size: 1rem; color: var(--muted); font-weight: 400; }
.usage-actions { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 0.6rem; }
.usage-actions form { margin: 0; }
.usage-actions .use-plus { min-height: 44px; min-width: 7rem; }
.usage-n { display: flex; align-items: flex-end; gap: 0.4rem; }
.usage-n .field input { width: 6rem; }
.usage-n .btn { min-height: 44px; }
.gage-settings > summary { margin-bottom: 0.6rem; }
@media (max-width: 480px) {
  .usage-actions { flex-direction: column; align-items: stretch; }
  .usage-actions .use-plus { width: 100%; }
  .usage-n .field { flex: 1; }
  .usage-n .field input { width: 100%; }
  .interval-pick .interval-fields { grid-template-columns: 1fr; }
}

/* 1.8.3 photo retention page */
.btn-danger { background: var(--danger-fill); color: var(--on-danger); border-color: var(--danger-fill); }
.btn-danger:hover { filter: brightness(0.92); }
.ret-list { list-style: none; padding: 0; margin: 0; display: grid; gap: .5rem; }
.ret-list li { display: flex; gap: .6rem; align-items: baseline; }
.ret-list .chip { flex: 0 0 auto; min-width: 5.5rem; text-align: center; }
.ret-form { display: grid; gap: .8rem; }
.ret-form input { width: 100%; max-width: 14rem; }
.ret-actions { display: flex; flex-wrap: wrap; gap: .5rem; margin-top: .8rem; }
.ret-kv { display: grid; grid-template-columns: 1fr auto; gap: .3rem 1rem; margin: 0; }
.ret-kv dd { margin: 0; text-align: right; font-variant-numeric: tabular-nums; }
.ret-audit-row { padding: .45rem 0; border-top: 1px solid var(--line); overflow-wrap: anywhere; }
.ret-audit-row:first-child { border-top: 0; }
.ret-form .field input:invalid:not(:placeholder-shown) { outline: 2px solid var(--danger); }

/* 1.9.0 account security */
.qr-box { background: #fff; display: inline-block; padding: 8px; border-radius: 8px; margin: 4px 0 8px; }
.qr-box svg { display: block; width: 240px; height: 240px; max-width: 70vw; max-height: 70vw; shape-rendering: crispEdges; }
.mfa-secret { word-break: break-all; font-size: 0.95em; }
.recovery-codes { font-size: 1.1em; line-height: 1.7; padding: 12px; background: var(--surface-2); border-radius: 8px; user-select: all; }
#sessions td.ua { max-width: 260px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.login-mfa[hidden] { display: none; }
.login-mfa .check { display: flex; gap: 8px; align-items: center; margin: 8px 0 12px; }

/* ---- type-to-search picker (static/combo.js) ---- */
.combo { position: relative; width: 100%; }
.combo-input { width: 100%; padding-right: 2.2rem; font-size: 16px; min-height: 40px; }
/* web 0.23.2: .field input sets the padding too (more specific), which put long names under the × */
.field .combo-input { padding-right: 2.4rem; text-overflow: ellipsis; }
.combo-clear { position: absolute; right: 4px; top: 50%; transform: translateY(-50%); width: 32px; height: 32px; border: 0; background: transparent;
  color: var(--muted); font-size: 20px; line-height: 1; cursor: pointer; }
.combo-clear[hidden] { display: none; }
.combo-native { position: absolute !important; left: 0; bottom: 0; width: 100% !important; height: 1px !important;
  opacity: 0; pointer-events: none; padding: 0 !important; border: 0 !important; }
.combo-list { position: absolute; z-index: 60; left: 0; right: 0; top: calc(100% + 2px); margin: 0; padding: 4px 0;
  list-style: none; background: var(--card); border: 1px solid var(--line); border-radius: 6px;
  box-shadow: 0 8px 24px var(--shadow-pop); max-height: min(360px, 50vh); overflow-y: auto; overscroll-behavior: contain; }
.combo-list[hidden] { display: none; }
.combo-opt { display: flex; flex-wrap: wrap; align-items: center; gap: 2px 8px; padding: 8px 10px; min-height: 44px;
  box-sizing: border-box; cursor: pointer; border-left: 3px solid transparent; }
.combo-opt.combo-active, .combo-opt:hover { background: var(--paper); border-left-color: var(--accent); }
.combo-opt[aria-selected="true"] .combo-main { font-weight: 600; }
.combo-main { flex: 1 1 auto; min-width: 0; overflow-wrap: anywhere; }
.combo-sub { flex-basis: 100%; font-size: 12px; color: var(--muted); }
.combo-chip { flex: 0 0 auto; font-size: 11px; }
.combo-recent .combo-sub { color: var(--accent-text); }
.combo-more { padding: 8px 10px; font-size: 12px; color: var(--muted); }
.combo-invalid .combo-input { border-color: var(--danger); }
.combo-sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }

/* 1.9.0 vendor support card + restore preview */
.support-card dl.kv, .restore-compare { display: grid; grid-template-columns: max-content 1fr; gap: 4px 16px; margin: 8px 0 12px; }
.support-card dl.kv dt { color: var(--muted); }
.support-card dl.kv dd { margin: 0; }
.restore-danger { border: 2px solid var(--danger); background: color-mix(in srgb, var(--danger) 10%, var(--card)); padding: 12px 14px; border-radius: 8px; margin: 0 0 12px; }
.restore-danger strong { color: var(--danger); font-size: 1.1em; }
table.restore-table { border-collapse: collapse; margin: 8px 0 12px; }
table.restore-table th, table.restore-table td { padding: 4px 12px; border-bottom: 1px solid var(--line); text-align: left; }
table.restore-table td.num { text-align: right; font-variant-numeric: tabular-nums; }
table.restore-table tr.lose td { color: var(--danger); font-weight: 600; }

/* 1.9.1: card action buttons on desktop sit in one tidy row. */
.people-table td.row-actions { white-space: normal; min-width: 14rem; }
.people-table td.row-actions .btn, .people-table td.row-actions .inline-form { margin-top: 0.15rem; margin-bottom: 0.15rem; }
.row-actions .inline-form { display: inline-block; }
.people-table td.row-actions .btn + .btn, .people-table td.row-actions .btn + .inline-form,
.people-table td.row-actions .inline-form + .btn { margin-left: 0.3rem; }
@media (max-width: 820px) {
  .people-table td.row-actions .btn + .btn, .people-table td.row-actions .btn + .inline-form,
  .people-table td.row-actions .inline-form + .btn { margin-left: 0; }
}
.people-2fa-note { font-size: 0.8rem; color: var(--muted); }

/* 1.9.1: sessions as stacked cards under 820px; dates stay on one line. */
.sessions-table td.when { white-space: nowrap; }
.sessions-table td.ua { max-width: 22rem; overflow-wrap: anywhere; }
.sessions-table .muted-unknown { color: var(--muted); font-style: italic; }
@media (max-width: 820px) {
  .sessions-table, .sessions-table tbody, .sessions-table tr, .sessions-table td { display: block; width: 100%; }
  .sessions-table thead { display: none; }
  .sessions-table tr.session-row { border: 1px solid var(--line); border-radius: 10px; padding: 0.6rem 0.75rem;
    margin-bottom: 0.6rem; box-sizing: border-box; }
  .sessions-table tr.session-row > td { display: flex; justify-content: space-between; gap: 0.75rem;
    padding: 0.2rem 0; border: 0; text-align: right; max-width: none; }
  .sessions-table tr.session-row > td::before { content: attr(data-label); color: var(--muted);
    font-size: 0.75rem; letter-spacing: 0.04em; text-transform: uppercase; text-align: left; flex: none; }
  .sessions-table tr.session-row > td.s-action { justify-content: flex-end; padding-top: 0.4rem; }
  .sessions-table tr.session-row > td.s-action::before { content: none; }
  .sessions-table td.s-action .btn { min-height: 44px; }
  #sessions .table-wrap { overflow: visible; }
}

/* ---------- web 0.11.0: section spacing (global) ---------- */
.page-head { margin-bottom: 1.4rem; }
.section { margin-bottom: 2rem; }
.page > h2, .page > .section-head, .card > h2 { margin-top: 0; }
.page > * + h2, .page > .empty + h2, .page > .table-scroll + h2, .page > .table-wrap + h2,
.page > .empty + .section-head, .page > .table-scroll + .section-head, .page > .banner + h2 { margin-top: 1.9rem; }
.page > .empty, .page > .table-scroll, .page > .table-wrap { margin-bottom: 0.4rem; }
.page > .card + .card, .page > .card + .section, .page > .section + .card { margin-top: 1.25rem; }
.page-head + .empty, .page-head + .banner { margin-top: 0.2rem; }
.info-line { color: var(--muted); font-size: 0.82rem; margin: 0.9rem 0 0; padding-top: 0.6rem;
  border-top: 1px solid color-mix(in srgb, var(--line) 55%, transparent); }

/* ---------- web 0.11.0: framed panels (Service) ---------- */
.panel {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 0.9rem 1rem;
  min-width: 0;
}
.panel > h2 { margin-bottom: 0.5rem; }
.svc-list { list-style: none; margin: 0; padding: 0; }
.svc-row {
  display: flex; align-items: center; flex-wrap: wrap; gap: 0.35rem 0.8rem;
  padding: 0.6rem 0;
  border-bottom: 1px solid color-mix(in srgb, var(--line) 55%, transparent);
}
.svc-row:last-child { border-bottom: none; padding-bottom: 0.2rem; }
.svc-main { display: flex; flex-direction: column; gap: 0.1rem; flex: 1 1 14rem; min-width: 0; }
.svc-machine { font-weight: 600; }
.svc-task { color: var(--ink); font-size: 0.9rem; }
.svc-status { flex: 0 0 auto; }
.svc-start { flex: 0 0 auto; margin-left: auto; min-width: 5rem; justify-content: center; }
.svc-when { color: var(--muted); font-size: 0.8rem; flex: 0 0 8.5rem; }
.svc-event .svc-notes { flex-basis: 100%; margin: 0; padding-left: 9.3rem; color: var(--muted); }
@media (min-width: 700px) {
  .svc-main { flex-direction: row; align-items: baseline; gap: 0.8rem; }
  .svc-main .svc-machine { flex: 0 0 11rem; }
}
@media (max-width: 699px) {
  .svc-when { flex-basis: 100%; }
  .svc-event .svc-notes { padding-left: 0; }
}

/* ---------- web 0.11.0: Account security sessions ---------- */
.session-list { list-style: none; margin: 0; padding: 0; }
.session-row {
  display: flex; align-items: center; gap: 0.6rem 1rem; flex-wrap: wrap;
  padding: 0.75rem 0.9rem; margin-bottom: 0.55rem;
  border: 1px solid color-mix(in srgb, var(--line) 70%, transparent); border-radius: 8px;
  background: var(--card);
}
.session-row.session-current { border-color: var(--ok); background: color-mix(in srgb, var(--ok) 6%, var(--card)); }
.session-main { flex: 1 1 18rem; min-width: 0; }
.session-title { display: flex; align-items: center; gap: 0.45rem; flex-wrap: wrap; font-weight: 600; }
.session-meta { display: flex; flex-wrap: wrap; gap: 0.3rem 1.6rem; margin: 0.35rem 0 0; }
.session-meta div { min-width: 0; }
.session-meta dt { font-family: var(--mono); font-size: 10px; letter-spacing: 0.12em; text-transform: uppercase; color: var(--muted); }
.session-meta dd { margin: 0; font-size: 0.88rem; white-space: nowrap; }
.session-action { margin-left: auto; flex: 0 0 auto; }
#sessions .section-head { margin-bottom: 0.8rem; flex-wrap: wrap; gap: 0.5rem; }

/* ---------- web 0.11.0: desktop side panel menu ----------
   Default on desktop (>= 1024 px). Revert: BAYLINE_SIDENAV=0 (renderer env),
   or delete this block + sidenav.js. Phone/tablet keep the header Menu. */
.nav-group { display: none; }
@media (min-width: 1024px) {
  .has-sidenav .topbar { flex-wrap: nowrap; height: 58px; }
  .has-sidenav .nav-toggle-label { display: none; }
  .has-sidenav .brand { order: 0; }
  .has-sidenav .nav {
    display: flex; flex-direction: column; align-items: stretch; flex-wrap: nowrap; gap: 0;
    position: fixed; top: 58px; left: 0; bottom: 0; width: 220px; z-index: 9;
    padding: 0.6rem 0.6rem 1.5rem; overflow-y: auto;
    background: var(--surface-bar); border-right: 1px solid var(--line);
  }
  .has-sidenav .nav a { padding: 0.28rem 0.7rem; font-size: 0.9rem; display: flex; align-items: center; gap: 0.4rem; border-radius: 6px; }
  .has-sidenav .nav a.active { box-shadow: inset 3px 0 0 var(--accent-text); }
  /* web 0.12.0: group headings stand out: bold small caps in the accent ink, with a divider. */
  .has-sidenav .nav .nav-group {
    display: flex; align-items: center; gap: 0.5rem;
    margin: 0.85rem 0.7rem 0.3rem; padding-top: 0.75rem;
    border-top: 1px solid var(--line);
    font-family: var(--mono); font-size: 10.5px; font-weight: 700; letter-spacing: 0.16em;
    text-transform: uppercase; color: var(--accent-text);
  }
  .has-sidenav .nav .nav-group::before {
    content: ""; width: 6px; height: 6px; border-radius: 2px; background: var(--accent); flex: none;
  }
  .has-sidenav .nav .nav-group:first-child { margin-top: 0.1rem; padding-top: 0; border-top: 0; }
  .has-sidenav .page, .has-sidenav .footer { margin-left: 220px; width: auto; }
  .has-sidenav .demo-banner { margin-left: 220px; width: calc(100% - 220px); }
  /* web 0.14.1: every page as wide as the Board. body is a flex column, so with
     auto margins the page shrank to its content (tables 780-960 px wide). */
  .has-sidenav .page { width: calc(100% - 220px); max-width: var(--page-max); margin-right: auto; }
}
@media (min-width: 1024px) and (max-width: 1600px) {
  .has-sidenav .page { margin-right: 0; }
}

/* web 0.12.0: one avatar everywhere (same size and style on desktop and phone). */
.userbox .avatar { display: inline-flex; width: 30px; height: 30px; font-size: 0.85rem; }
/* web 0.12.0: on phone/tablet the Menu button and Sign out are the same size. */
@media (max-width: 1023px) {
  .topbar .nav-toggle-label, .userbox #sign-out-btn {
    height: 44px; min-height: 44px; box-sizing: border-box; padding: 0 0.8rem;
    font-size: 0.9rem; font-weight: 600; border-radius: 8px; line-height: 1;
    display: inline-flex; align-items: center; justify-content: center;
  }
}

/* ---------- web 0.11.0: shared list header (Tools, Drills & taps, Consumables) ---------- */
.list-head { flex-wrap: wrap; align-items: center; margin-bottom: 0.5rem; }
.list-head .page-actions { flex-wrap: wrap; align-items: center; gap: 0.5rem; }
.list-intro { margin: 0 0 0.9rem; max-width: 70ch; }
.list-filters { margin-bottom: 1rem; }
.chip-fav { margin-left: 0.4rem; }
.list-count { margin-top: 0.8rem; display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem; }

/* ---------- web 0.11.0: one control height in every filter bar ----------
   input / select / date / Search button share --ctl-h; one row on desktop,
   wrapping whole controls on phone. */
:root { --ctl-h: 38px; }
.list-search-form, .filter-bar { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 0.5rem; }
.list-search-form { align-items: center; }
.list-search-form input:not([type=hidden]):not([type=checkbox]), .list-search-form select,
.filter-bar input:not([type=hidden]):not([type=checkbox]), .filter-bar select {
  height: var(--ctl-h); min-height: var(--ctl-h); box-sizing: border-box; margin: 0;
  padding-top: 0; padding-bottom: 0; line-height: calc(var(--ctl-h) - 2px);
}
.list-search-form .btn, .filter-bar .btn {
  height: var(--ctl-h); min-height: var(--ctl-h); box-sizing: border-box; margin: 0;
  display: inline-flex; align-items: center; padding-top: 0; padding-bottom: 0;
}
.list-search-form .drill-dc { display: inline-flex; align-items: center; gap: 0.4rem; flex-wrap: nowrap; margin: 0; padding: 0; border: 0; background: none; }
.list-search-form .drill-dc label { display: inline-flex; align-items: center; gap: 0.3rem; margin: 0; }
.list-search-form .drill-dc input { width: 5.2rem; }
.filter-bar .field { margin: 0; }
@media (max-width: 600px) {
  .list-head .page-actions, .list-search-form { width: 100%; }
  .list-head .list-search-form .list-search { flex: 1 1 10rem; width: auto; }
  .list-search-form .drill-dc { flex-basis: 100%; }
  .list-search-form .drill-dc label { flex: 1 1 0; }
  .list-search-form .drill-dc input { flex: 1 1 auto; width: 100%; min-width: 0; }
}
/* web 0.11.0: with the side panel open the content is ~220 px narrower; let
   People cells wrap so the action buttons stay on screen. */
@media (min-width: 1024px) {
  .has-sidenav .table-scroll .data-table.people-table { width: 100%; }
  .has-sidenav .table-scroll .data-table.people-table td { white-space: normal; }
  .has-sidenav .people-table td.row-actions { min-width: 0; }
}

/* ---------- web 0.12.0: Board grids progress monotonically ----------
   The old auto-fit grids counted columns from the CONTENT width, which shrinks
   by 220 px when the side panel appears at 1024 px: 3 columns at 1000 px, then
   2 at 1024 px. Columns now follow the viewport only, never fewer when wider. */
.board-cols, .machine-grid, .stat-tiles { display: grid; gap: 0.8rem; }
.board-cols { grid-template-columns: 1fr; }
.machine-grid { grid-template-columns: 1fr; }
.stat-tiles { grid-template-columns: repeat(2, minmax(0, 1fr)); }
@media (min-width: 560px) { .machine-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
                            .stat-tiles { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (min-width: 680px) { .board-cols { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 900px) { .machine-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
                            .stat-tiles { grid-template-columns: repeat(5, minmax(0, 1fr)); } }
@media (min-width: 1280px) { .board-cols { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (min-width: 1360px) { .machine-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); } }

/* ---------- web 0.12.0: Board hero, tiles, health ring, kudos, today ---------- */
.board-hero { display: flex; align-items: center; justify-content: space-between; gap: 1rem; flex-wrap: wrap;
  margin-bottom: 1.1rem; padding: 1rem 1.2rem; border-radius: 14px; border: 1px solid var(--line);
  background: linear-gradient(120deg, color-mix(in srgb, var(--accent) 16%, var(--card)), var(--card) 65%); }
.board-hello { min-width: 0; flex: 1 1 16rem; }
.board-hello h1 { font-size: 1.6rem; }
.board-date { margin: 0 0 0.2rem; color: var(--accent-text); }
.board-tagline { margin: 0.35rem 0 0; color: color-mix(in srgb, var(--ink) 80%, var(--paper)); }
.board-hero-side { display: flex; align-items: center; gap: 0.9rem; }
.wave { display: inline-block; transform-origin: 70% 70%; }
.health-ring { display: flex; flex-direction: column; align-items: center; gap: 0.35rem; margin: 0; flex: none; }
/* web 0.17.4: the label sits under the ring, not inside it (it was as wide as the ring's inner circle and touched the figure). */
.health-ring .ring-disc { position: relative; width: 92px; height: 92px; }
.health-ring svg { width: 100%; height: 100%; display: block; }
.health-ring .ring-bg { stroke: color-mix(in srgb, var(--line) 70%, transparent); }
.health-ring .ring-fg { stroke: var(--ok); }
.health-ring.tone-warn .ring-fg { stroke: var(--warn); }
.health-ring.tone-danger .ring-fg { stroke: var(--danger); }
.health-ring .ring-num { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; font-size: 1.3rem; line-height: 1; color: var(--dark); font-variant-numeric: tabular-nums; }
.health-ring .ring-label { font-size: 10px; letter-spacing: 0.1em; line-height: 1.1; white-space: nowrap; text-align: center; }
.stat-tiles { margin-bottom: 1rem; }

/* ---------- web 0.23.0: Board quick use (consumable | gauge), under the hero ---------- */
.quick-use { margin-bottom: 1.1rem; position: relative; z-index: 5; }   /* the open picker list stays over the tiles below (under the header, 10) */
.quick-use > .section-head { margin-bottom: 0.45rem; }
.quick-grid { display: grid; gap: 0.8rem; grid-template-columns: repeat(2, minmax(0, 1fr)); align-items: stretch; }
@media (max-width: 760px) { .quick-grid { grid-template-columns: 1fr; } }
.quick-card { display: flex; flex-direction: column; gap: 0.6rem; }
.quick-title { margin: 0; font-size: 1rem; display: flex; align-items: center; gap: 0.4rem; }
.quick-form { display: flex; flex-direction: column; gap: 0.6rem; }
.quick-row { display: flex; gap: 0.6rem; flex-wrap: wrap; }
.quick-row .quick-qty { flex: 0 0 7.5rem; }
.quick-row .quick-grow { flex: 1 1 12rem; }
.quick-meta { display: flex; flex-wrap: wrap; align-items: center; gap: 0.25rem 0.5rem; margin: 0;
  font-size: 0.86rem; color: var(--muted); }
.quick-meta[hidden] { display: none; }
.quick-meta .mono, .quick-meta .quick-v { color: var(--ink); }
.quick-meta .quick-k { margin-left: 0.3rem; }
.quick-meta .quick-empty, .quick-meta .quick-v.quick-empty { color: var(--danger-ink); font-weight: 600; }
.quick-sep { color: var(--muted); }
.quick-chip { font-weight: 600; }
.quick-actions { display: flex; align-items: center; gap: 0.6rem 0.8rem; flex-wrap: wrap; }
.quick-actions .btn-use[disabled] { cursor: not-allowed; }
.quick-block, .quick-warn { margin: 0; font-weight: 600; }
.quick-blocked .combo-input { border-color: var(--danger); }
/* A blocked gauge: the button loses its orange so nothing about it reads "go". */
.quick-blocked .btn-use[disabled] { background: var(--disabled-bg); border-color: var(--disabled-line); color: var(--disabled-ink); filter: none; opacity: 1; box-shadow: none; }
.quick-msg:empty { display: none; }
.quick-banner { display: flex; align-items: center; justify-content: space-between; gap: 0.6rem; flex-wrap: wrap; margin: 0 0 0.4rem; }
.quick-banner:last-child { margin-bottom: 0; }
.quick-undo-form { margin: 0; }
.quick-off { margin: 0; }
@media (max-width: 480px) {
  .quick-row .quick-qty { flex: 1 1 6rem; }
  .quick-actions .btn-use { width: 100%; }
}
/* web 0.24.3: the picked consumable / gauge as a card (quickuse.js) with an ✕ to change it. Built from the
   theme variables, so it follows light and dark. The search box is hidden while something is picked. */
.quick-pick { position: relative; display: flex; flex-direction: column; gap: 0.35rem; margin-top: -0.3rem;
  padding: 0.55rem 3.1rem 0.6rem 0.75rem; min-height: 44px; border: 1px solid var(--line); border-left: 3px solid var(--accent);
  border-radius: 8px; background: var(--paper); }
.quick-pick[hidden] { display: none; }
.quick-pick-head { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.1rem 0.5rem; min-width: 0; }
.quick-pick-code { font-weight: 700; color: var(--ink); overflow-wrap: anywhere; }
.quick-pick-code[hidden] { display: none; }
.quick-pick-name { color: var(--ink); overflow-wrap: anywhere; }
.quick-pick .quick-meta { margin: 0; }
.quick-pick .quick-meta .quick-k:first-of-type { margin-left: 0; }
.quick-pick-x { position: absolute; top: 4px; right: 4px; width: 44px; height: 44px; border: 0; border-radius: 6px;
  background: transparent; color: var(--muted); font-size: 18px; line-height: 1; cursor: pointer; }
.quick-pick-x:hover { color: var(--ink); background: var(--card); }
.quick-pick-x:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: -2px; color: var(--ink); }
.quick-pick.quick-pick-bad { border-color: var(--danger); border-left-color: var(--danger); }
/* web 0.24.3: on a phone the Quick use lists are short (5 rows, combo.js data-combo-phone; combo.js scrolls the
   box up to just under the sticky header when its list opens), so the list does not cover the card and Log use. */
@media (max-width: 640px) {
  .quick-use .combo-list { max-height: min(300px, 42vh); }
}
.stat-tile { position: relative; display: flex; flex-direction: column; gap: 0.1rem; min-width: 0;
  padding: 0.8rem 0.9rem 0.75rem; border-radius: 12px; border: 1px solid var(--line); background: var(--card);
  color: var(--ink); text-decoration: none; border-top: 4px solid var(--tone, var(--line));
  transition: transform 0.15s ease, box-shadow 0.15s ease; }
.stat-tile:hover { text-decoration: none; transform: translateY(-2px); box-shadow: 0 6px 16px color-mix(in srgb, var(--shadow-ink) 10%, transparent); }
.stat-tile:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 2px; }
.stat-tile.tone-ok { --tone: var(--ok); }
.stat-tile.tone-warn { --tone: var(--warn); }
.stat-tile.tone-danger { --tone: var(--danger); background: color-mix(in srgb, var(--danger) 6%, var(--card)); }
.stat-tile.tone-info { --tone: var(--accent); }
.tile-icon { position: absolute; top: 0.65rem; right: 0.75rem; font-size: 1.3rem; }
.tile-num { font-size: 1.9rem; font-weight: 700; color: var(--dark); line-height: 1.1; font-variant-numeric: tabular-nums; }
.tile-of { font-size: 1.05rem; color: var(--muted); font-weight: 600; }
.tile-label { font-weight: 600; font-size: 0.9rem; }
.tile-sub { color: var(--muted); font-size: 0.78rem; overflow-wrap: anywhere; }
.stat-tiles .stat-tile:last-child:nth-child(odd) { grid-column: 1 / -1; }
@media (min-width: 560px) { .stat-tiles .stat-tile:last-child:nth-child(odd) { grid-column: auto; } }
.kudos { list-style: none; margin: 0 0 1.2rem; padding: 0; display: flex; flex-wrap: wrap; gap: 0.5rem; }
.kudos li { padding: 0.35rem 0.75rem; border-radius: 999px; font-size: 0.85rem; font-weight: 500;
  background: color-mix(in srgb, var(--ok) 14%, var(--card)); border: 1px solid color-mix(in srgb, var(--ok) 55%, var(--line)); }
.board-today .section-head { display: flex; justify-content: space-between; align-items: baseline; }
.feed { list-style: none; margin: 0; padding: 0; }
.feed li { display: flex; align-items: center; gap: 0.65rem; padding: 0.45rem 0;
  border-bottom: 1px solid color-mix(in srgb, var(--line) 55%, transparent); }
.feed li:last-child { border-bottom: 0; }
.feed-avatar { display: inline-flex; width: 30px; height: 30px; font-size: 0.85rem; }
.avatar-agent { background: var(--accent-text); }
.feed-text { flex: 1 1 auto; min-width: 0; font-size: 0.9rem; overflow-wrap: anywhere; }
.feed-what { color: var(--accent-text); }
.feed-when { color: var(--muted); font-size: 0.78rem; flex: none; }
.empty-fun { display: flex; align-items: center; gap: 0.6rem; }
.empty-emoji { font-size: 1.5rem; flex: none; }
@media (max-width: 480px) {
  .board-hero { padding: 0.85rem 0.9rem; }
  .board-hello h1 { font-size: 1.3rem; }
  .health-ring .ring-disc { width: 76px; height: 76px; }
  .health-ring .ring-num { font-size: 1.2rem; }
  .tile-num { font-size: 1.6rem; }
}
/* load animation; nothing moves with prefers-reduced-motion */
@media (prefers-reduced-motion: no-preference) {
  .anim-in { animation: rise-in 0.45s ease-out both; }
  .stat-tiles .anim-in:nth-child(2) { animation-delay: 0.05s; }
  .stat-tiles .anim-in:nth-child(3) { animation-delay: 0.1s; }
  .stat-tiles .anim-in:nth-child(4) { animation-delay: 0.15s; }
  .stat-tiles .anim-in:nth-child(5) { animation-delay: 0.2s; }
  .health-ring .ring-fg { animation: ring-draw 0.9s ease-out both; }
  .wave { animation: wave 1.6s ease-in-out 0.4s 1; }
}
@keyframes rise-in { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }
@keyframes ring-draw { from { stroke-dasharray: 0 100; } }
@keyframes wave { 0%, 100% { transform: rotate(0); } 20%, 60% { transform: rotate(14deg); } 40%, 80% { transform: rotate(-8deg); } }

/* ---------- web 0.12.1: Board Signals panel (data from /api/stats, like /stats) ---------- */
.board-signals .section-head { display: flex; justify-content: space-between; align-items: baseline; }
.sig-cols { display: grid; grid-template-columns: 1fr; gap: 0.4rem 1.6rem; }
@media (min-width: 680px) { .sig-cols { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.sig-col h3 { margin: 0.2rem 0 0.35rem; display: flex; align-items: center; gap: 0.4rem; }
.sig-count { font-weight: 700; color: var(--accent-text); }
.sig-list { list-style: none; margin: 0; padding: 0; }
.sig-list li { display: flex; align-items: center; flex-wrap: wrap; gap: 0.15rem 0.6rem; padding: 0.4rem 0;
  border-bottom: 1px solid color-mix(in srgb, var(--line) 55%, transparent); }
.sig-list li:last-child { border-bottom: 0; }
.sig-name { font-weight: 600; flex: 1 1 10rem; min-width: 0; overflow-wrap: anywhere; }
.sig-meta { color: var(--muted); font-size: 0.8rem; line-height: 1.35; order: 3; flex-basis: 100%; min-width: 0;
  font-family: var(--sans); letter-spacing: 0; font-variant-numeric: tabular-nums; }
/* web 0.17.4: meta lines in the UI font (the mono face made every space a full character cell), numbers in ink,
   number and unit joined by a no-break space, groups never split, a quiet dot between them. */
.sig-meta .sg { white-space: nowrap; }
.sig-meta .sg-where { white-space: normal; overflow-wrap: anywhere; }
.sig-meta .n { font-weight: 600; color: var(--ink); }
.sig-meta .dot { font-style: normal; margin: 0 0.02em; color: var(--muted); }
.sig-meta .sl { font-style: normal; color: var(--muted); }
.sig-none { color: var(--muted); font-size: 0.9rem; margin: 0.3rem 0 0.6rem; }

/* web 0.12.1: confirmation toast (keeps the page where it was) */
.toast.toast-on { position: fixed; right: 1rem; bottom: 1rem; z-index: 50; max-width: min(420px, calc(100vw - 2rem));
  margin: 0; box-shadow: 0 8px 24px color-mix(in srgb, var(--shadow-ink) 18%, transparent); cursor: pointer; }
.toast.toast-off { opacity: 0; pointer-events: none; transition: opacity 0.4s; }
@media (prefers-reduced-motion: no-preference) { .toast.toast-on { animation: rise-in 0.3s ease-out both; } }

/* ---------- web 0.13.0: tool preview panel (desktop >= 1280 px) ---------- */
.preview-panel { display: none; }
@media (min-width: 1280px) {
  tr[data-preview] { cursor: pointer; }
  .data-table tr.row-previewed > td,
  .table-scroll .data-table tr.row-previewed > td.sticky-action,
  .data-table tr.row-previewed > td.star-cell { background: color-mix(in srgb, var(--accent) 16%, var(--card)); }
  /* 0.13.1: while the panel is open, drop low-priority columns so Status fits. */
  .page.preview-open .data-table [data-col="tracking"],
  .page.preview-open .data-table [data-col="where"],
  .page.preview-open .data-table [data-col="min"],
  .page.preview-open .data-table [data-col="latest"],
  .page.preview-open .data-table [data-col="point"],
  .page.preview-open .data-table [data-col="kind"] { display: none; } /* kind is in the panel */
  tr.row-previewed > td:first-child { box-shadow: inset 3px 0 0 var(--accent-text); }
  .page.preview-open { padding-right: calc(380px + 1.25rem); max-width: none; }
  .page.preview-open .preview-panel {
    display: block; position: fixed; top: 58px; right: 0; bottom: 0; width: 380px; z-index: 8;
    overflow-y: auto; padding: 1rem 1.1rem 1.5rem; background: var(--card);
    border-left: 1px solid var(--line); box-shadow: -8px 0 24px color-mix(in srgb, var(--shadow-ink) 8%, transparent);
  }
  .preview-panel:focus { outline: none; }
  .pv-head { display: flex; align-items: flex-start; gap: 0.7rem; margin-bottom: 0.8rem; }
  .pv-photo { width: 72px; height: 72px; border-radius: 8px; object-fit: cover; border: 1px solid var(--line); flex: none; }
  .pv-nophoto { display: flex; align-items: center; justify-content: center; font-size: 1.8rem; background: var(--paper); }
  .pv-title { display: flex; flex-direction: column; gap: 0.2rem; flex: 1 1 auto; min-width: 0; }
  .pv-name { font-size: 1.05rem; overflow-wrap: anywhere; }
  .pv-sku { color: var(--muted); font-size: 0.82rem; }
  .pv-title .chip { align-self: flex-start; }
  .pv-star { font-size: 1.3rem; }
  .pv-close { flex: none; }
  .preview-panel h3 { margin: 0.9rem 0 0.3rem; display: flex; gap: 0.4rem; align-items: center; }
  .pv-total { margin: 0 0 0.3rem; }
  .pv-qty { font-size: 1.4rem; }
  .pv-list { list-style: none; margin: 0; padding: 0; }
  .pv-list li { display: flex; justify-content: space-between; gap: 0.6rem; padding: 0.3rem 0; font-size: 0.9rem;
    border-bottom: 1px solid color-mix(in srgb, var(--line) 55%, transparent); }
  .pv-actions { display: flex; gap: 0.4rem; margin: 1rem 0 0.5rem; flex-wrap: wrap; }
  .pv-form { display: grid; gap: 0.45rem; padding: 0.7rem; border: 1px solid var(--line); border-radius: 8px; background: var(--paper); margin-bottom: 0.6rem; }
  .pv-form[hidden] { display: none; }
  .pv-form .field { margin: 0; }
  .pv-form input, .pv-form select { width: 100%; box-sizing: border-box; }
  .pv-msg { margin: 0 0 0.5rem; }
  .pv-open { display: flex; justify-content: center; margin-top: 1rem; }
}

/* web 0.13.1: service history */
.micro-link { margin-left: .75rem; font-weight: 500; letter-spacing: 0; text-transform: none; }
.svc-history-table td { vertical-align: top; }
.svc-history-table .svc-result { display: flex; flex-wrap: wrap; align-items: center; gap: .35rem; margin: .1rem 0; }
.svc-history-table .svc-thumb { width: 40px; height: 40px; object-fit: cover; border-radius: 4px; }
.svc-history-table .svc-note { color: inherit; overflow-wrap: anywhere; }
.pager { display: flex; gap: .75rem; align-items: center; justify-content: center; margin: .75rem 0; }
.svc-hist-filters .form-actions { display: flex; flex-wrap: wrap; gap: .5rem; margin-top: .75rem; }
@media (max-width: 679px) {
  .svc-history-table thead { display: none; }
  .svc-history-table, .svc-history-table tbody, .svc-history-table tr, .svc-history-table td { display: block; width: 100%; box-sizing: border-box; }
  .svc-history-table tr { border-bottom: 1px solid var(--line); padding: .5rem 0; }
  .svc-history-table td { border: 0; padding: .15rem .5rem; }
}
.svc-history-table .svc-pass-line { display: flex; flex-wrap: wrap; align-items: center; gap: .2rem .5rem; margin: .1rem 0; }
.svc-history-table .svc-pass-task + .svc-pass-task::before { content: "· "; color: var(--line); }
.svc-history-table .svc-results { min-width: 16rem; max-width: 30rem; }
@media (min-width: 680px) { .svc-history-table td.svc-note { min-width: 8rem; max-width: 16rem; } }
.svc-history-table td, .svc-history-table th { white-space: normal; }
.svc-history-table td.svc-when { white-space: nowrap; }
.svc-history-table .svc-results { min-width: 14rem; max-width: 26rem; }
.svc-history-table td *, .svc-history-table td { white-space: normal !important; }
.svc-history-table .svc-when { white-space: nowrap !important; }
.svc-history-table .svc-results { min-width: 12rem; max-width: 18rem; }
.svc-history-table .svc-who { color: inherit; }
@media (min-width: 680px) { .svc-history-table td.svc-note { min-width: 6rem; max-width: 12rem; } }

/* Audit C (final pre-workshop): glove-size controls on touch screens and
   phones. One rule instead of per-page patches; 44 px is the WCAG/Apple
   target. 16 px text in fields stops iOS zooming in on focus. */
@media (pointer: coarse), (max-width: 767px) {
  button, .btn, .btn-sm, summary.btn, details > summary,
  input:not([type=checkbox]):not([type=radio]):not([type=hidden]):not([type=range]),
  select, textarea { min-height: 44px; }
  input:not([type=checkbox]):not([type=radio]), select, textarea { font-size: 16px; }
  .btn, .btn-sm { display: inline-flex; align-items: center; justify-content: center; }
  details > summary { display: list-item; line-height: 44px; }
  :root { --ctl-h: 44px; }
  .star-btn { min-width: 44px; min-height: 44px; }
  input[type=checkbox], input[type=radio] { width: 22px; height: 22px; }
}

/* Audit C: links inside running text must not rely on colour alone (axe
   link-in-text-block); keyboard users can scroll wide tables. */
p a:not(.btn), .page-sub a:not(.btn), .empty a:not(.btn), .micro-link { text-decoration: underline; text-underline-offset: 2px; }
.table-scroll:focus-visible { outline: 2px solid var(--accent-text); outline-offset: 2px; }
.btn-scrap { color: var(--scrap-ink); }
.tile-sub { color: var(--tile-sub); }
.stat-tile.tone-danger .tile-sub { color: var(--tile-sub-danger); }
/* Audit C: long real names (æøå, 100+ chars) must wrap, not push Status under the preview. */
.page.preview-open .data-table td[data-col="name"], .page.preview-open .data-table td[data-col="sku"] { white-space: normal; overflow-wrap: anywhere; min-width: 8rem; }
.page.preview-open .data-table td[data-col="name"] * { white-space: normal; }
.page.preview-open .table-scroll .data-table { width: 100%; }
.page.preview-open .data-table td[data-col="name"] { max-width: 22rem; }

/* web 0.14.1: tables and lists use the full page width (same as the Board);
   forms and reading blocks keep their own narrower max-width on purpose. */
.table-scroll > table.data-table, .page > table.data-table { min-width: 100%; }

/* web 0.15.0: disclaimer page and login notice */
.disclaimer-card { max-width: 820px; }
.disclaimer-text h2 { font-size: 1rem; margin: 1.1em 0 .3em; }
.disclaimer-text p { line-height: 1.5; }
.disclaimer-form { margin-top: 1.2em; display: flex; flex-direction: column; gap: .8em; align-items: flex-start; }
.login-notice { margin-top: 1em; font-size: .82rem; color: var(--muted); text-align: center; }

/* web 0.17.0: public demo edition */
.demo-banner { background: var(--banner-bg); border-bottom: 1px solid var(--banner-line); color: var(--banner-ink); padding: .45rem 1rem; font-size: .9rem; text-align: center; }
.contact-btn { margin-left: auto; margin-right: .6rem; white-space: nowrap; }
.topbar .contact-btn + .nav-toggle + .nav-toggle-label, .topbar .contact-btn ~ .userbox { margin-left: 0; }
.demo-login { font-size: .9rem; }
/* web 0.17.3: demo header on phone/tablet. Menu, Sign out and Contact keep a 44 px tap height; the
   three never share a row they cannot fit in. <= 600 px: a two-row grid, brand + Contact on row 1,
   Menu (left) + account (right) on row 2, so nothing overlaps from 320 px up. */
@media (max-width: 1023px) { .topbar .contact-btn { min-height: 44px; display: inline-flex; align-items: center; justify-content: center; box-sizing: border-box; } }
@media (max-width: 600px) {
  .topbar.has-contact { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; align-items: center; gap: 0.3rem 0.5rem; }
  .topbar.has-contact .brand { grid-column: 1; grid-row: 1; }
  .topbar.has-contact .contact-btn { grid-column: 2 / 4; grid-row: 1; justify-self: end; margin: 0; font-size: .85rem; padding: 0 .75rem; min-width: 0; }
  .topbar.has-contact .nav-toggle-label { grid-column: 1; grid-row: 2; justify-self: start; }
  .topbar.has-contact .userbox { grid-column: 2 / 4; grid-row: 2; justify-self: end; margin: 0; flex: 0 1 auto; }
  .topbar.has-contact .nav { grid-column: 1 / -1; grid-row: 3; }
}

/* ---------- web 0.17.4: phone/tablet menu = the desktop side panel, in a column ----------
   Same groups (Overview, Shop floor, ...), same heading style, same active marker. Role/demo visibility
   is decided in layout.html, so both menus always list the same links. */
@media (max-width: 1023px) {
  .nav-toggle:checked ~ .nav {
    display: grid; grid-template-columns: repeat(auto-fill, minmax(11rem, 1fr)); gap: 0 0.6rem;
    padding: 0.35rem 0 0.6rem; border-top: 1px solid var(--line); margin-top: 0.15rem;
  }
  .nav a { display: flex; align-items: center; gap: 0.4rem; min-height: 44px; font-size: 0.9rem; padding: 0.28rem 0.7rem; }
  .nav a.active { box-shadow: inset 3px 0 0 var(--accent-text); }
  .nav .nav-group {
    display: flex; align-items: center; gap: 0.5rem; grid-column: 1 / -1;
    margin: 0.7rem 0.7rem 0.15rem; padding-top: 0.65rem; border-top: 1px solid var(--line);
    font-family: var(--mono); font-size: 10.5px; font-weight: 700; letter-spacing: 0.16em;
    text-transform: uppercase; color: var(--accent-text);
  }
  .nav .nav-group::before { content: ""; width: 6px; height: 6px; border-radius: 2px; background: var(--accent); flex: none; }
  .nav .nav-group:first-child { margin-top: 0.1rem; padding-top: 0; border-top: 0; }
}
@media (max-width: 820px) { .nav-toggle:checked ~ .nav { grid-template-columns: minmax(0, 1fr); } }

/* ---------- web 0.17.4: a little denser on phones ----------
   Smaller base type and tighter rows. Buttons, inputs and links keep their 44 px tap height (they set
   min-height themselves), so only the text and the padding around it shrink. */
@media (max-width: 600px) {
  :root { --base: 14.5px; }
  body { line-height: 1.42; }
  .panel, .board-cols .section, .card { padding: 0.7rem 0.8rem; }
  .data-table td { padding: 0.36rem 0.6rem; font-size: 0.9rem; }
  .data-table th { padding: 0.4rem 0.6rem; }
  .strip-list li { padding: 0.3rem 0; gap: 0.45rem; }
  .svc-row { padding: 0.45rem 0; gap: 0.25rem 0.6rem; }
  .sig-list li { padding: 0.3rem 0; gap: 0.05rem 0.5rem; }
  .sig-name { font-size: 0.95rem; }
  .stat-tile { padding: 0.65rem 0.75rem 0.6rem; }
  .stat-tiles { margin-bottom: 0.75rem; }
  .page-head { margin-bottom: 1rem; }
  .section { margin-bottom: 1.5rem; }
  .kudos { margin-bottom: 0.9rem; }
}

/* ---------- web 0.17.5: "Report a bug" link (BAYLINE_BUG_REPORT_URL) ----------
   Last entry of the Settings group (desktop side panel and phone menu: same link, same 44 px row
   from phone widths) and a footer entry on every page. External link: a small arrow, opens in a new tab. */
.ext-arrow { font-size: 0.85em; margin-left: 0.3em; color: var(--muted); }
.nav a.nav-ext { color: var(--muted); }
.nav a.nav-ext:hover .ext-arrow, .footer-bug a:hover .ext-arrow { color: inherit; }
.footer-bug a { color: inherit; text-decoration: underline; text-underline-offset: 2px; }
@media (max-width: 820px) {
  .footer-bug a { display: inline-flex; align-items: center; min-height: 44px; padding-right: 0.6rem; }
}

/* ---------- web 0.18.0: gauge status (manual hold with a comment, failed calibration) ----------
   Badges reuse .chip-ok/-warn/-danger/-neutral: out for calibration = warn (amber), damaged /
   quarantined / other / failed = danger (red), retired = neutral. Every control is 44 px. */
.gage-status .status-card { border: 1px solid var(--danger); border-left-width: 4px; border-radius: 8px;
  padding: 0.7rem 0.9rem; background: color-mix(in srgb, var(--danger) 5%, var(--card)); }
.gage-status-hold .status-card { border-color: var(--danger); }
.gage-status .status-line { margin: 0 0 0.35rem; display: flex; flex-wrap: wrap; gap: 0.4rem 0.6rem; align-items: center; }
.gage-status .status-comment { margin: 0 0 0.35rem; font-size: 1.02rem; overflow-wrap: anywhere; white-space: pre-wrap; }
.gage-status .status-card .strip-note { margin: 0; }
.status-actions { display: flex; flex-wrap: wrap; gap: 0.6rem; align-items: flex-start; margin-top: 0.8rem; }
.status-actions .strip-note { align-self: center; }
details.status-panel { flex: 1 1 100%; max-width: 640px; }
details.status-panel > summary { list-style: none; cursor: pointer; display: inline-flex; align-items: center; justify-content: center;
  min-height: 44px; min-width: 44px; width: auto; }
details.status-panel > summary::-webkit-details-marker { display: none; }
details.status-panel[open] > summary { margin-bottom: 0.6rem; }
.status-form { display: grid; gap: 0.6rem; border: 1px solid var(--line); border-radius: 8px;
  padding: 0.8rem; background: var(--card); }
.status-form select, .status-form textarea, .status-form input { width: 100%; box-sizing: border-box; min-height: 44px; font-size: 16px; }
.status-form textarea { min-height: 5.5rem; resize: vertical; }
.status-form .form-actions { margin: 0; }
.status-form .form-actions .btn { min-height: 44px; }
@media (min-width: 700px) { details.status-panel { flex: 0 1 auto; width: 100%; } }
.status-log li { flex-wrap: wrap; align-items: baseline; gap: 0.25rem 0.6rem; white-space: normal; }
.status-log .log-comment { flex: 1 1 100%; white-space: pre-wrap; overflow-wrap: anywhere; }
.hold-note { display: block; max-width: 22ch; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  color: var(--muted); font-size: 0.8rem; margin-top: 0.15rem; }
.strip-list li .hold-note { display: inline-block; max-width: 28ch; vertical-align: middle; margin-top: 0; }
.issue-override { margin-top: 0.7rem; }
.cal-failed-note[hidden], .cal-release[hidden] { display: none; }
.cal-failed-note { margin: 0.6rem 0; }
.cal-release { margin: 0.4rem 0; }
.cal-release .check-row { align-items: flex-start; padding: 0.4rem 0; }
/* web 0.22.1: form pages. Sections (fieldset + legend), three columns on a computer, two on a tablet, one on a phone; the
   save button sits in a bar that sticks to the bottom of the card, so it is in view without hunting for it. */
.form-legend { margin: 0 0 0.9rem; font-size: 0.85rem; color: var(--muted); }
.req { color: var(--danger-ink); font-weight: 700; }
.form-section { border: 0; padding: 0; margin: 0 0 1.2rem; min-width: 0; }
.form-section > legend { width: 100%; padding: 0 0 0.45rem; margin: 0 0 0.7rem; border-bottom: 1px solid var(--line);
  font-family: var(--mono); font-size: 11px; letter-spacing: 0.1em; text-transform: uppercase; color: var(--accent-text); }
.cal-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 0.9rem 1rem; margin-bottom: 0.6rem; }
.cal-cert-field { grid-column: 1 / -1; }
.form-help { font-size: 0.92rem; line-height: 1.45; max-width: 75ch; margin: 0.1rem 0 0.4rem; }
.form-section .banner { margin: 0.6rem 0 0; }
.form-card { --cp-x: 1.2rem; --cp-y: 1.2rem; }   /* the card's padding, so the sticky bar reaches exactly its edges */
@media (max-width: 600px) { .form-card { --cp-x: 0.8rem; --cp-y: 0.7rem; } }
.form-actions-bar { position: sticky; bottom: 0; z-index: 2; margin: 0 calc(var(--cp-x) * -1) calc(var(--cp-y) * -1); padding: 0.8rem var(--cp-x);
  background: var(--card); border-top: 1px solid var(--line); border-radius: 0 0 12px 12px; }
@media (max-width: 900px) { .cal-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 560px) {
  .cal-grid { grid-template-columns: 1fr; }
  .cal-cert-field { grid-column: auto; }
  .form-actions-bar .btn { width: 100%; min-height: 44px; }
}
@media (min-width: 900px) { .stat-tiles.tiles-6 { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (min-width: 1280px) { .stat-tiles.tiles-6 { grid-template-columns: repeat(6, minmax(0, 1fr)); } }

/* ---------- web 0.19.0: gauge page (header, summary, two columns, timeline, documents) ----------
   One header with the state and the actions, four facts, then the main column (status, calibrations,
   history, checkouts) beside a side column (check out, usage, documents, details). Under 1000 px the
   two columns collapse into one list in a useful order (status, check out, usage, calibrations, ...).
   Every control is 44 px on phones. Out for calibration is amber (warn), like the badge. */
.gd-crumb { margin: 0 0 0.35rem; font-size: 0.9rem; }
.gd-crumb a { display: inline-flex; align-items: center; color: var(--muted); text-decoration: none; }
.gd-crumb a:hover { color: var(--ink); text-decoration: underline; }
.gd-hero { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 0.9rem 1.2rem;
  background: var(--card); border: 1px solid var(--line); border-left-width: 6px; border-radius: 12px;
  padding: 1rem 1.2rem; margin-bottom: 0.9rem; min-width: 0; }
.gd-tone-ok { border-left-color: var(--ok); }
.gd-tone-warn { border-left-color: var(--warn); }
.gd-tone-danger { border-left-color: var(--danger); }
.gd-tone-neutral { border-left-color: var(--line); }
.gd-hero-main { display: flex; align-items: center; gap: 1rem; min-width: 0; flex: 1 1 340px; }
.gd-thumb img { width: 72px; height: 72px; object-fit: cover; border-radius: 10px; border: 1px solid var(--line); display: block; }
.gd-title { min-width: 0; }
.gd-title h1 { margin: 0; overflow-wrap: anywhere; }
.gd-spec { margin-top: 0.1rem; }
.gd-actions { display: flex; flex-wrap: wrap; gap: 0.5rem; }
.gd-actions .btn { min-height: 44px; display: inline-flex; align-items: center; justify-content: center; text-decoration: none; }
.gd-summary { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 0.75rem; margin-bottom: 1rem; }
.gd-fact { background: var(--card); border: 1px solid var(--line); border-radius: 10px; padding: 0.65rem 0.9rem;
  display: flex; flex-direction: column; gap: 0.2rem; min-width: 0; }
.gd-fact-main { font-size: 1.2rem; font-weight: 600; line-height: 1.3; overflow-wrap: anywhere; }
.gd-fact-sub { font-size: 0.82rem; color: var(--muted); overflow-wrap: anywhere; }
.gd-late { color: var(--danger); font-weight: 600; }
.gd-cols { display: grid; grid-template-columns: minmax(0, 1fr) 360px; gap: 1rem; align-items: start; }
.gd-main, .gd-side { display: flex; flex-direction: column; gap: 1rem; min-width: 0; }
.gd-card { background: var(--card); border: 1px solid var(--line); border-radius: 10px; padding: 0.9rem 1rem; margin: 0; min-width: 0; }
.gd-card .section-head { margin-bottom: 0.6rem; }
.gd-side .card { margin: 0; }
.gd-nostatus { margin: 0; }
.gage-status .status-card-cal { border-color: var(--warn); background: color-mix(in srgb, var(--warn) 12%, var(--card)); }
.cal-facts { display: flex; flex-wrap: wrap; gap: 0.15rem 1.1rem; margin: 0 0 0.35rem; font-size: 0.9rem; }
.cal-extra[hidden] { display: none; }
.cal-extra { display: grid; gap: 0.6rem; }
.cal-list, .doc-list, .co-list { list-style: none; margin: 0; padding: 0; }
.cal-item { padding: 0.7rem 0; border-bottom: 1px solid color-mix(in srgb, var(--line) 55%, transparent); }
.cal-item:first-child { padding-top: 0; }
.cal-item:last-child { border-bottom: none; padding-bottom: 0; }
.cal-row { display: flex; flex-wrap: wrap; align-items: center; gap: 0.4rem 0.7rem; }
.cal-date { font-weight: 600; }
.cal-results { display: inline-flex; flex-wrap: wrap; align-items: center; gap: 0.3rem; }
.cal-arrow { color: var(--muted); }
.cal-cert { margin-left: auto; }
.cal-meta { display: flex; flex-wrap: wrap; gap: 0.15rem 1rem; margin-top: 0.3rem; font-size: 0.86rem; color: var(--muted); }
.cal-meta b { color: var(--ink); font-weight: 500; }
.cal-note { margin: 0.3rem 0 0; font-size: 0.9rem; overflow-wrap: anywhere; white-space: pre-wrap; }
li.cal-voided .cal-date, li.cal-voided .cal-meta, li.cal-voided .doc-link { text-decoration: line-through; color: var(--muted); }
li.cal-voided .chip { text-decoration: none; }
.timeline { list-style: none; margin: 0; padding: 0; }
.tl-item { position: relative; padding: 0 0 1.05rem 1.3rem; margin-left: 0.45rem; border-left: 2px solid var(--line); }
.tl-item:last-child { padding-bottom: 0; border-left-color: transparent; }
.tl-item::before { content: ""; position: absolute; left: -7px; top: 0.3rem; width: 12px; height: 12px; border-radius: 50%;
  background: var(--card); border: 2px solid var(--muted); }
.tl-cal::before { border-color: var(--warn); }
.tl-hold::before { border-color: var(--danger); }
.tl-clear::before { border-color: var(--ok); }
.tl-head { display: flex; flex-wrap: wrap; align-items: center; gap: 0.25rem 0.6rem; }
.timeline .log-comment { margin: 0.3rem 0 0; white-space: pre-wrap; overflow-wrap: anywhere; }
.timeline .cal-facts { margin: 0.3rem 0 0; color: var(--muted); }
.doc-row { display: flex; flex-wrap: wrap; gap: 0.4rem; margin-top: 0.45rem; }
.doc-link { display: inline-flex; align-items: center; gap: 0.45rem; min-height: 36px; padding: 0.25rem 0.65rem; max-width: 100%;
  border: 1px solid var(--line); border-radius: 8px; background: var(--paper); color: var(--ink); text-decoration: none; }
.doc-link:hover { border-color: var(--accent); }
.doc-kind { font-size: 10px; font-weight: 600; letter-spacing: 0.06em; color: var(--accent-text);
  background: color-mix(in srgb, var(--accent) 22%, var(--card)); border-radius: 4px; padding: 1px 5px; }
.doc-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; max-width: 26ch; }
.doc-list { display: grid; gap: 0.7rem; }
.doc-item { display: flex; flex-direction: column; align-items: flex-start; gap: 0.2rem; min-width: 0; }
.co-item { display: flex; flex-wrap: wrap; align-items: flex-end; justify-content: space-between; gap: 0.5rem 1rem;
  padding: 0.6rem 0; border-bottom: 1px solid color-mix(in srgb, var(--line) 55%, transparent); }
.co-item:first-child { padding-top: 0; }
.co-item:last-child { border-bottom: none; padding-bottom: 0; }
.co-main { display: flex; flex-wrap: wrap; align-items: center; gap: 0.25rem 0.6rem; min-width: 0; }
.co-return { display: flex; align-items: flex-end; gap: 0.5rem; margin: 0; }
.co-return select, .co-return .btn { min-height: 44px; }
.gd-side .kv-table .k { width: 38%; }
@media (max-width: 820px) {
  .gage-settings > summary { min-height: 44px; display: inline-flex; align-items: center; }
  .usage-n .field input, .co-return select { min-height: 44px; }
}
@media (max-width: 1000px) {
  .gd-cols { display: flex; flex-direction: column; align-items: stretch; gap: 1rem; }
  .gd-main, .gd-side { display: contents; }
  .gd-summary { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 820px) {
  .gd-crumb a { min-height: 44px; }
  .doc-link { min-height: 44px; }
}
@media (max-width: 600px) {
  .gd-hero { padding: 0.8rem 0.9rem; }
  .gd-actions { width: 100%; display: grid; grid-template-columns: 1fr 1fr; }
  .gd-actions .btn-primary { grid-column: 1 / -1; }
  .gd-fact { padding: 0.55rem 0.7rem; }
  .gd-fact-main { font-size: 1.05rem; }
  .gd-card { padding: 0.75rem 0.8rem; }
  .cal-cert { margin-left: 0; }
}
.hold-late { color: var(--danger); }
.gd-card .kv-table { border: none; border-radius: 0; background: transparent; }
.gd-card .kv-table td { padding-left: 0; padding-right: 0.4rem; }

/* web 0.20.0: shop ID help, gauge name under the ID, due today */
.field-help { display: block; font-size: 0.78rem; color: var(--muted); font-weight: 400; margin-top: 0.2rem; line-height: 1.3; }
.gage-desc { display: block; font-size: 0.8rem; color: var(--muted); font-family: inherit; font-weight: 400;
  max-width: 28ch; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.due-today { color: var(--warn-text); font-weight: 600; }
.gd-desc { font-size: 1.05rem; color: var(--ink); margin: 0.1rem 0 0.2rem; overflow-wrap: anywhere; }
.gd-aka { margin-top: 0; }

/* ---------- appearance (web 0.22.0) ---------- */
.logo-dark { display: none; }
.brand-logo.logo-dark, .login-logo.logo-dark { aspect-ratio: auto 571 / 417; }   /* the white mark is cropped tighter than logo.png; 2026-10-27: circle-corrected file, the intrinsic ratio wins */
.theme-form { display: inline-flex; align-items: center; gap: 0.5rem; margin: 0; }
.theme-label { font-family: var(--mono); font-size: 11px; letter-spacing: 0.14em; text-transform: uppercase; color: var(--muted); }
.theme-seg { display: inline-flex; border: 1px solid var(--line-strong); border-radius: 999px; overflow: hidden; background: var(--card); }
.theme-opt { appearance: none; border: 0; background: transparent; color: var(--muted); font: 500 0.82rem var(--sans);
  padding: 0.28rem 0.8rem; min-height: 32px; cursor: pointer; }
.theme-opt + .theme-opt { border-left: 1px solid var(--line-strong); }
.theme-opt:hover { color: var(--ink); }
.theme-opt.on, .theme-opt[aria-pressed="true"] { background: var(--accent); color: var(--on-accent); font-weight: 600; }
.theme-opt:focus-visible { outline: 2px solid var(--accent-text); outline-offset: -2px; }
.footer-theme { display: inline-flex; align-items: center; }
.nav-theme { display: block; padding: 0.7rem 0.7rem 0.3rem; }
.nav-theme .theme-form { flex-wrap: wrap; }
@media (min-width: 1024px) {
  .has-sidenav .nav .nav-theme { display: none; }          /* desktop: the control is in the footer */
}
@media (max-width: 1023px) {
  .footer-theme-wide { display: none; }                    /* signed in on a phone/tablet: it is in the Menu */
  .theme-opt { min-height: 44px; padding: 0.3rem 1rem; }
}
.theme-card .theme-seg { display: flex; max-width: 22rem; }
.theme-card .theme-opt { flex: 1 1 0; min-height: 44px; font-size: 0.95rem; }

/* ---------- dark theme (web 0.22.0) ----------
   The dark values only exist inside @media screen, so print is always light. */
/* ==== DARK (explicit): begin ==== */
@media screen {
:root[data-theme="dark"] {
  color-scheme: dark;
  /* surfaces (the intro's navy) */
  --paper: #0e1424;
  --card: #152449;
  --surface-bar: #101a36;
  --surface-2: #1b2d5c;
  --field-bg: #0e1424;
  /* text */
  --ink: #e9edf8;
  --muted: #b7c2de;
  --dark: #ffffff;
  --tile-sub: #b7c2de;
  --tile-sub-danger: #b7c2de;
  /* lines */
  --line: #2f4478;
  --line-strong: #667cb6;
  /* web 0.23.1: disabled buttons sit flat on the card, dashed edge, dimmer text (4.9:1) */
  --disabled-bg: #152449;
  --disabled-ink: #8592b6;
  --disabled-line: #2f4478;
  /* accent */
  --accent: #f0a13a;
  --focus-ring: #f0a13a;
  --accent-text: #f6b45a;
  --on-accent: #121a2c;
  /* status */
  --ok: #34d399;
  --ok-text: #6ee7b7;
  --warn: #ffb85a;
  --warn-text: #ffb85a;
  --danger: #ff8a80;
  --danger-ink: #ff8a80;
  --scrap-ink: #ff8a80;
  --danger-fill: #c62828;
  --on-danger: #ffffff;
  --info: #8db7ff;
  --info-fill: #2a5aa8;
  --on-info: #ffffff;
  --on-dispatch: #121a2c;
  --move-out: #a78bfa;
  --move-count: #14b8a6;
  --diff-was: #ff8a80;
  --diff-now: #6ee7b7;
  --sev-critical: #ff8a80;
  --sev-high: #ffa65c;
  --sev-medium: #f2c14e;
  --sev-low: #2f4478;
  --on-sev: #121a2c;
  --on-sev-low: #e9edf8;
  /* demo banner */
  --banner-bg: #3b3322;
  --banner-line: #8a6a2e;
  --banner-ink: #ffd98a;
  /* shadows, scrim, scrollbars */
  --shadow-ink: #000000;
  --shadow-sm: rgba(0, 0, 0, 0.5);
  --shadow-md: rgba(0, 0, 0, 0.6);
  --shadow-pop: rgba(0, 0, 0, 0.55);
  --scrim: rgba(0, 0, 0, 0.78);
  --scroll-thumb: #3a4f86;
  --card-hl: rgba(255, 255, 255, 0.07);
  --glow: rgba(80, 130, 230, 0.28);
}
:root[data-theme="dark"] .logo-light { display: none; }
:root[data-theme="dark"] .logo-dark { display: block; }
:root[data-theme="dark"] input:not([type="checkbox"]):not([type="radio"]):not([type="hidden"]):not([type="range"]):not([type="file"]):not([type="submit"]):not([type="button"]),
:root[data-theme="dark"] select,
:root[data-theme="dark"] textarea { background-color: var(--field-bg); color: var(--ink); border-color: var(--line-strong); }
:root[data-theme="dark"] ::placeholder { color: var(--muted); opacity: 0.75; }
:root[data-theme="dark"] * { scrollbar-color: var(--scroll-thumb) var(--paper); }
:root[data-theme="dark"] ::selection { background: color-mix(in srgb, var(--accent) 35%, transparent); }
:root[data-theme="dark"] .board-hero,
:root[data-theme="dark"] .login-card { border-top: 3px solid var(--accent); }
/* web 0.23.1: fading with opacity reads as "enabled" on navy, so a disabled button is flat and dashed instead */
:root[data-theme="dark"] .btn:disabled,
:root[data-theme="dark"] .btn[disabled] { background: var(--disabled-bg); border-color: var(--disabled-line); border-style: dashed; color: var(--disabled-ink); box-shadow: none; filter: none; opacity: 1; }
}
/* ==== DARK (explicit): end ==== */

/* Auto = the same rules while the OS prefers dark. Generated: scripts/sync_theme_css.py */
/* ==== DARK (auto): begin ==== */
@media screen and (prefers-color-scheme: dark) {
:root[data-theme="auto"] {
  color-scheme: dark;
  /* surfaces (the intro's navy) */
  --paper: #0e1424;
  --card: #152449;
  --surface-bar: #101a36;
  --surface-2: #1b2d5c;
  --field-bg: #0e1424;
  /* text */
  --ink: #e9edf8;
  --muted: #b7c2de;
  --dark: #ffffff;
  --tile-sub: #b7c2de;
  --tile-sub-danger: #b7c2de;
  /* lines */
  --line: #2f4478;
  --line-strong: #667cb6;
  /* web 0.23.1: disabled buttons sit flat on the card, dashed edge, dimmer text (4.9:1) */
  --disabled-bg: #152449;
  --disabled-ink: #8592b6;
  --disabled-line: #2f4478;
  /* accent */
  --accent: #f0a13a;
  --focus-ring: #f0a13a;
  --accent-text: #f6b45a;
  --on-accent: #121a2c;
  /* status */
  --ok: #34d399;
  --ok-text: #6ee7b7;
  --warn: #ffb85a;
  --warn-text: #ffb85a;
  --danger: #ff8a80;
  --danger-ink: #ff8a80;
  --scrap-ink: #ff8a80;
  --danger-fill: #c62828;
  --on-danger: #ffffff;
  --info: #8db7ff;
  --info-fill: #2a5aa8;
  --on-info: #ffffff;
  --on-dispatch: #121a2c;
  --move-out: #a78bfa;
  --move-count: #14b8a6;
  --diff-was: #ff8a80;
  --diff-now: #6ee7b7;
  --sev-critical: #ff8a80;
  --sev-high: #ffa65c;
  --sev-medium: #f2c14e;
  --sev-low: #2f4478;
  --on-sev: #121a2c;
  --on-sev-low: #e9edf8;
  /* demo banner */
  --banner-bg: #3b3322;
  --banner-line: #8a6a2e;
  --banner-ink: #ffd98a;
  /* shadows, scrim, scrollbars */
  --shadow-ink: #000000;
  --shadow-sm: rgba(0, 0, 0, 0.5);
  --shadow-md: rgba(0, 0, 0, 0.6);
  --shadow-pop: rgba(0, 0, 0, 0.55);
  --scrim: rgba(0, 0, 0, 0.78);
  --scroll-thumb: #3a4f86;
  --card-hl: rgba(255, 255, 255, 0.07);
  --glow: rgba(80, 130, 230, 0.28);
}
:root[data-theme="auto"] .logo-light { display: none; }
:root[data-theme="auto"] .logo-dark { display: block; }
:root[data-theme="auto"] input:not([type="checkbox"]):not([type="radio"]):not([type="hidden"]):not([type="range"]):not([type="file"]):not([type="submit"]):not([type="button"]),
:root[data-theme="auto"] select,
:root[data-theme="auto"] textarea { background-color: var(--field-bg); color: var(--ink); border-color: var(--line-strong); }
:root[data-theme="auto"] ::placeholder { color: var(--muted); opacity: 0.75; }
:root[data-theme="auto"] * { scrollbar-color: var(--scroll-thumb) var(--paper); }
:root[data-theme="auto"] ::selection { background: color-mix(in srgb, var(--accent) 35%, transparent); }
:root[data-theme="auto"] .board-hero,
:root[data-theme="auto"] .login-card { border-top: 3px solid var(--accent); }
/* web 0.23.1: fading with opacity reads as "enabled" on navy, so a disabled button is flat and dashed instead */
:root[data-theme="auto"] .btn:disabled,
:root[data-theme="auto"] .btn[disabled] { background: var(--disabled-bg); border-color: var(--disabled-line); border-style: dashed; color: var(--disabled-ink); box-shadow: none; filter: none; opacity: 1; }
}
/* ==== DARK (auto): end ==== */

/* ---------- web 0.24.0: item notes (tool detail, under Identity) ---------- */
.item-notes .notes-text {
  background: var(--card); border: 1px solid var(--line); border-radius: 10px;
  padding: 0.6rem 0.75rem; font-size: 0.92rem; line-height: 1.5; color: var(--ink);
  white-space: pre-wrap; overflow-wrap: anywhere;
}
.item-notes .notes-empty { padding: 0.6rem 0.75rem; font-size: 0.9rem; }
.item-notes .notes-edit { margin-top: 0.1rem; }
.item-notes .notes-form { margin-top: 0.6rem; }
.item-notes .field textarea.notes-input {
  font-family: var(--sans); font-size: 0.92rem; line-height: 1.5; width: 100%; min-height: 6.5rem; resize: vertical;
}
.item-notes .notes-help { margin: 0.35rem 0 0.6rem; }
.item-notes .notes-actions { display: flex; gap: 0.5rem; align-items: center; flex-wrap: wrap; }
/* While the editor is open, the textarea holds the text: hide the read view and the opener (Cancel / Esc closes). */
.item-notes:has(> details.notes-edit[open]) > .notes-text,
.item-notes:has(> details.notes-edit[open]) > .notes-empty { display: none; }
.item-notes details.notes-edit[open] > summary { display: none; }
.item-notes details.notes-edit[open] > .notes-form { margin-top: 0; }
