:root {
  /* Brand palette — sourced from app.pointonenav.com tokens */
  --mine-shaft: #222222;
  --cerulean: #009de0;
  --cerulean-dark: #0075db;
  --point1-green: #19a866;
  --point1-green-dark: #148550;
  --lightning-yellow: #ffcc1d;
  --red-orange: #ff4c2d;
  --danger-red: #e22822;

  /* Surfaces (warm light theme to match app) */
  --bg: #ffffff;
  --bg-alt: #f6f6f4;
  --bg-soft: #f2f2f0;
  --bg-inverse: #141413;
  --border: #e7e7e4;
  --border-strong: #dededc;

  /* Text */
  --text: #0b0b0a;
  --text-muted: rgba(34, 34, 34, 0.65);
  --text-subtle: rgba(34, 34, 34, 0.5);

  /* Status surfaces */
  --good-bg: rgba(25, 168, 102, 0.10);
  --good-fg: var(--point1-green-dark);
  --warn-bg: rgba(255, 204, 29, 0.18);
  --warn-fg: #6b5400;
  --bad-bg: rgba(255, 76, 45, 0.10);
  --bad-fg: #b8311a;

  /* Misc */
  --radius: 12px;
  --radius-pill: 100px;
  --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.04);
  --shadow-md: 0 4px 14px rgba(34, 34, 34, 0.08);
  --safe-top: env(safe-area-inset-top, 0px);
  --safe-bottom: env(safe-area-inset-bottom, 0px);

  --font-sans: "Instrument Sans", -apple-system, BlinkMacSystemFont,
    "Segoe UI", Helvetica, Arial, sans-serif;
  --font-mono: "Azeret Mono", ui-monospace, "SF Mono", Menlo, Consolas, monospace;
}

* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
body {
  font-family: var(--font-sans);
  font-size: 16px;
  line-height: 1.45;
  background: var(--bg);
  color: var(--text);
  -webkit-font-smoothing: antialiased;
  min-height: 100vh;
}
.bg-station, .bg-admin { background: var(--bg); }

a { color: var(--cerulean); text-decoration: none; }
a:hover { text-decoration: underline; }

.muted { color: var(--text-muted); }
.small { font-size: 13px; }

/* ---------- Centered card layout (login screens) ---------- */
.card-screen {
  max-width: 420px;
  margin: 0 auto;
  padding: calc(48px + var(--safe-top)) 22px calc(28px + var(--safe-bottom));
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  justify-content: center;
}
.brand { display: flex; flex-direction: column; align-items: center;
  gap: 14px; margin-bottom: 32px; text-align: center; }
.brand-logo { height: 60px; width: auto; display: block; }
.brand-text { display: flex; flex-direction: column; gap: 2px; }
.brand-title { font-size: 18px; font-weight: 600; letter-spacing: -0.01em; }
.brand-sub { font-size: 13px; color: var(--text-muted); }

/* ---------- Topbar (logged-in screens) ---------- */
.topbar {
  position: sticky; top: 0; z-index: 5;
  display: flex; align-items: center; justify-content: space-between;
  padding: calc(14px + var(--safe-top)) 16px 14px;
  background: rgba(255, 255, 255, 0.9);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--border);
}
.topbar-left { display: flex; align-items: center; gap: 12px; min-width: 0; }
/* Point One Navigation mark in every page header. Decorative (the page
   title sits next to it) — alt="" so screen readers don't repeat the brand
   name on every page. Width auto so the PNG keeps its aspect; height caps
   it to the topbar's vertical room. */
.topbar-brand {
  flex: 0 0 auto;
  height: 32px;
  width: auto;
  display: block;
}
.topbar-title { font-weight: 600; font-size: 16px; max-width: 60vw;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  letter-spacing: -0.01em; }
.topbar-sub { font-size: 12px; color: var(--text-muted);
  font-family: var(--font-mono); font-variant-numeric: tabular-nums; }
.link-back { color: var(--text-muted); font-size: 14px; }

/* ---------- Forms ---------- */
.form { display: flex; flex-direction: column; gap: 14px; }
.field { display: flex; flex-direction: column; gap: 6px; }
.field span { font-size: 13px; color: var(--text-muted); }
.field input, .field textarea, .field select {
  width: 100%;
  font: inherit; color: var(--text);
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 13px 14px;
  outline: none;
  transition: border-color 120ms, box-shadow 120ms;
}
.field input::placeholder { color: var(--text-subtle); }
.field input:focus, .field textarea:focus, .field select:focus {
  border-color: var(--mine-shaft);
  box-shadow: 0 0 0 3px rgba(34, 34, 34, 0.08);
}
/* Strip the browser-native chrome on <select> so it matches the text
   inputs above, then draw our own caret with an inline SVG so it renders
   identically across Mac/Windows/Linux. Right padding leaves room for it. */
.field select {
  -webkit-appearance: none;
  -moz-appearance: none;
  appearance: none;
  padding-right: 38px;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%23666' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'><polyline points='6 9 12 15 18 9'/></svg>");
  background-repeat: no-repeat;
  background-position: right 14px center;
  background-size: 12px 12px;
  cursor: pointer;
}
.field select:disabled {
  color: var(--text-muted);
  cursor: not-allowed;
  opacity: 0.7;
}
.input-row { display: flex; gap: 8px; align-items: stretch; }
.input-row input { flex: 1; }
.input-row .btn-icon { flex: 0 0 auto; }

/* ---------- Station locked (PIN-only login) ---------- */
.station-locked {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px;
  background: var(--bg-alt);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 12px 14px;
}
.station-locked-label {
  font-size: 12px; color: var(--text-muted);
  letter-spacing: 0.02em; margin-bottom: 2px;
}
.station-locked-cas {
  font-family: var(--font-mono); font-size: 15px; font-weight: 600;
  background: transparent; padding: 0;
}

/* ---------- Buttons ---------- */
.btn, .btn-ghost, .btn-icon, .btn-danger, .link-btn {
  font: inherit; cursor: pointer; border: 1px solid transparent;
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  transition: background-color 120ms, color 120ms, border-color 120ms,
    transform 100ms;
}
.btn {
  border-radius: var(--radius-pill);
  padding: 13px 26px;
  font-weight: 500;
  font-size: 15px;
}
.btn-primary {
  background: var(--mine-shaft);
  color: #fff;
}
.btn-primary:hover { background: #000; }
.btn-primary:active { transform: translateY(1px); }
/* Prominent QR-scan CTA. Green tint distinguishes it from the standard
   primary submit button so users can find it at a glance. */
.btn-scan {
  width: 100%;
  background: var(--point1-green);
  color: #fff;
  padding: 16px 22px;
  font-size: 16px;
  font-weight: 600;
  letter-spacing: 0.01em;
}
.btn-scan:hover { background: var(--point1-green-dark); }
.btn-scan:active { transform: translateY(1px); }
.btn-scan svg { stroke-width: 2.2; }

/* "or enter manually" divider used on the station login screen. */
.form-or {
  display: flex; align-items: center; gap: 12px;
  color: var(--text-muted); font-size: 11px;
  letter-spacing: 0.08em; text-transform: uppercase;
  margin: 2px 0;
}
.form-or::before, .form-or::after {
  content: ''; flex: 1; height: 1px; background: var(--border);
}
.btn-ghost {
  background: var(--bg);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: var(--radius-pill);
  padding: 11px 18px;
  font-size: 14px;
  font-weight: 500;
}
.btn-ghost:hover { background: var(--bg-alt); border-color: var(--border-strong); }
.btn-danger {
  background: var(--bg);
  color: var(--red-orange);
  border: 1px solid var(--border);
  border-radius: var(--radius-pill);
  padding: 11px 16px;
  font-size: 14px;
  font-weight: 500;
}
.btn-danger:hover { background: rgba(255, 76, 45, 0.06);
  border-color: rgba(255, 76, 45, 0.4); }
.btn-icon {
  background: var(--bg-alt); border: 1px solid var(--border);
  color: var(--text);
  border-radius: 10px;
  padding: 0 14px; min-width: 50px;
}
.btn-icon:hover { background: var(--border); }
.link-btn { background: transparent; border: none; padding: 0;
  color: var(--cerulean); font-size: inherit; }
.link-btn:hover { text-decoration: underline; }

.tiny-link { text-align: center; margin-top: 22px; font-size: 13px;
  color: var(--text-muted); }

/* ---------- Page layout ---------- */
.page {
  max-width: 720px;
  margin: 0 auto;
  padding: 18px 16px calc(36px + var(--safe-bottom));
  display: flex; flex-direction: column; gap: 14px;
}
.card {
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 18px;
  box-shadow: var(--shadow-sm);
}
.card-title {
  font-size: 12px; font-weight: 600; letter-spacing: 0.08em;
  text-transform: uppercase; color: var(--text-muted); margin-bottom: 14px;
}
.card-header {
  display: flex; align-items: center; justify-content: space-between;
  gap: 10px; margin-bottom: 12px;
}
.card-header .card-title { margin-bottom: 0; }
.card-meta { font-size: 12px; }

/* ---------- Alerts ---------- */
.alert { padding: 12px 14px; border-radius: 10px; font-size: 14px;
  border: 1px solid transparent; }
.alert-error { background: var(--bad-bg); color: var(--bad-fg);
  border-color: rgba(255, 76, 45, 0.25); }
.alert-ok { background: var(--good-bg); color: var(--good-fg);
  border-color: rgba(25, 168, 102, 0.25); }
.alert-info { background: rgba(0, 157, 224, 0.08); color: var(--cerulean-dark);
  border-color: rgba(0, 157, 224, 0.25); }

/* ---------- Pills & dots ---------- */
.pill { display: inline-flex; align-items: center; gap: 6px;
  font-size: 12px; padding: 3px 10px; border-radius: 999px;
  background: var(--bg-alt); color: var(--text);
  font-weight: 500; letter-spacing: 0.02em; }
.pill-good { background: var(--good-bg); color: var(--good-fg); }
.pill-warn { background: var(--warn-bg); color: var(--warn-fg); }
.pill-bad  { background: var(--bad-bg); color: var(--bad-fg); }
/* ---------- Location card ---------- */
.location-coords {
  font-family: var(--font-mono); font-variant-numeric: tabular-nums;
  margin-bottom: 10px;
}
.location-map {
  width: 100%;
  height: 240px;
  border-radius: 10px;
  overflow: hidden;
  background: var(--bg-soft);
  border: 1px solid var(--border);
}
.location-map iframe {
  width: 100%; height: 100%;
  border: 0; display: block;
}

/* ---------- CNO card ---------- */
.cno-header { display: flex; align-items: center;
  justify-content: space-between; gap: 12px; margin-bottom: 12px; }
.cno-header .card-title { margin-bottom: 0; }
.band-selector {
  display: inline-flex; padding: 3px;
  background: var(--bg-soft); border: 1px solid var(--border);
  border-radius: 999px;
}
.band-btn {
  border: 0; background: transparent; cursor: pointer;
  font: inherit; font-size: 13px; font-weight: 500;
  padding: 6px 14px; border-radius: 999px;
  color: var(--text-muted);
  transition: background-color 120ms, color 120ms;
}
.band-btn:hover { color: var(--text); }
.band-btn.is-active {
  background: var(--bg);
  color: var(--text);
  box-shadow: var(--shadow-sm);
}

.cno-chart { display: flex; flex-direction: column; gap: 6px;
  min-height: 60px; }
.cno-empty { padding: 14px 0; text-align: center; }

.cno-row {
  display: grid;
  grid-template-columns: 70px 1fr 56px;
  align-items: center;
  gap: 10px;
  font-size: 13px;
}
.cno-sat { font-family: var(--font-mono); color: var(--text-muted);
  white-space: nowrap; }
.cno-bar-wrap {
  position: relative;
  height: 14px;
  background: var(--bg-soft);
  border-radius: 999px;
  overflow: hidden;
}
.cno-bar {
  position: absolute; inset: 0 auto 0 0;
  border-radius: 999px;
  transition: width 240ms ease, background-color 120ms;
  background: var(--point1-green);
}
.cno-bar.warn { background: var(--lightning-yellow); }
.cno-bar.bad  { background: var(--red-orange); }
.cno-value { font-family: var(--font-mono); font-variant-numeric: tabular-nums;
  text-align: right; color: var(--text); }

.cno-meta { margin-top: 10px; min-height: 1.2em; text-align: right; }

/* ---------- Summary card (top of station view) ---------- */
.summary-card {
  padding: 24px 20px;
  text-align: center;
  border: 1px solid var(--border);
  transition: background-color 200ms, border-color 200ms, color 200ms;
}
.summary-headline {
  font-size: 28px; line-height: 1.15; font-weight: 700;
  letter-spacing: -0.02em;
  margin-bottom: 8px;
}
.summary-message {
  font-size: 14px; line-height: 1.5;
  margin: 0 auto; max-width: 60ch;
  /* Lets the JS emit "\n\n" between paragraphs without resorting to
     innerHTML, since setSummary uses textContent. */
  white-space: pre-line;
}
.summary-details {
  font-size: 13px; line-height: 1.5;
  margin: 14px auto 0; max-width: 60ch;
  text-align: left;
  white-space: pre-line;
}
.summary-bullets {
  font-size: 13px; line-height: 1.5;
  margin: 8px auto 0; max-width: 60ch;
  padding-left: 22px;
  text-align: left;
}
.summary-bullets li { margin: 4px 0; }

.summary-action {
  font-size: 14px; line-height: 1.5;
  margin: 14px auto 0; max-width: 60ch;
}
.summary-action a { font-weight: 600; }

/* ---------- Install (confirm-installation) page ---------- */
.install-page .card { padding: 18px 18px; }
.install-form { display: flex; flex-direction: column; gap: 18px; }

.photo-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 12px;
  margin-top: 14px;
}
.photo-slot {
  display: flex; flex-direction: column; align-items: center;
  justify-content: center;
  aspect-ratio: 1 / 1;
  border: 2px dashed var(--border);
  border-radius: 12px;
  background: var(--bg-soft);
  cursor: pointer;
  position: relative;
  overflow: hidden;
  text-align: center;
  padding: 12px;
}
.photo-slot input[type="file"] {
  position: absolute;
  inset: 0; opacity: 0;
  cursor: pointer;
}
.photo-slot-label {
  font-weight: 600;
  text-transform: capitalize;
  font-size: 16px;
}
.photo-slot-hint {
  font-size: 12px;
  color: var(--text-muted);
  margin-top: 4px;
}
.photo-slot-preview {
  position: absolute;
  inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
}
.photo-slot-filled {
  border-style: solid;
  border-color: var(--point1-green, #19a866);
}
.photo-slot-filled .photo-slot-label,
.photo-slot-filled .photo-slot-hint {
  position: relative;
  z-index: 1;
  background: rgba(0, 0, 0, 0.55);
  color: #fff;
  padding: 2px 8px;
  border-radius: 6px;
}
.photo-slot-filled .photo-slot-hint { margin-top: 6px; }

.install-submit { align-self: stretch; }

/* Multi-select distributor picker on the install form. Each row is a
   tap-friendly card with a checkbox; on phones the entire row counts as a
   hit target so the user doesn't have to aim at the tiny native checkbox. */
.distributor-picker {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin-top: 12px;
}
.distributor-option {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 12px;
  border-radius: 8px;
  border: 1px solid var(--border);
  background: var(--bg-soft);
  cursor: pointer;
  font-size: 14px;
}
.distributor-option input[type="checkbox"] {
  width: 18px; height: 18px;
  flex: 0 0 auto;
  cursor: pointer;
}
.distributor-option:hover { background: var(--surface, #fff); }
.distributor-option:has(input:checked) {
  border-color: var(--cerulean, #009de0);
  background: rgba(0, 157, 224, 0.06);
}

/* Inline validation error shown directly under the offending field. Larger
   and more prominent than .muted so it's hard to miss on mobile, where the
   native HTML5 popup is small and easily obscured by the keyboard. */
.field-error {
  margin: 8px 0 0;
  padding: 8px 12px;
  font-size: 14px;
  font-weight: 500;
  border-radius: 8px;
  background: var(--bad-bg);
  color: var(--bad-fg);
  border: 1px solid rgba(255, 76, 45, 0.35);
}

.confirm-card { text-align: center; }
.confirm-card .btn { min-width: 220px; }

/* Install-card status boxes for the submitted/active states. The whole
   card body is the colored box; .install-status-* override the card's
   background so it's unambiguously green or yellow. */
.install-status { padding: 6px 4px; }
.install-status-headline {
  font-size: 20px;
  font-weight: 700;
  margin-bottom: 6px;
  letter-spacing: -0.01em;
}
.install-status-body {
  margin: 0;
  font-size: 14px;
  line-height: 1.5;
}
.confirm-card .install-status-active {
  background: var(--good-bg);
  color: var(--good-fg);
  border-radius: 10px;
  border: 1px solid rgba(25, 168, 102, 0.35);
  margin: -6px -10px;
  padding: 16px 18px;
}
.confirm-card .install-status-pending {
  background: rgba(255, 196, 0, 0.12);
  color: #8a5a00;
  border-radius: 10px;
  border: 1px solid rgba(255, 196, 0, 0.45);
  margin: -6px -10px;
  padding: 16px 18px;
}
.confirm-result {
  margin: 12px auto 0; max-width: 60ch;
  font-size: 14px; line-height: 1.45;
  padding: 10px 14px; border-radius: 8px;
  border: 1px solid var(--border);
}
.confirm-result.confirm-pass {
  background: var(--good-bg); color: var(--good-fg);
  border-color: rgba(25, 168, 102, 0.35);
}
.confirm-result.confirm-fail {
  background: var(--bad-bg); color: var(--bad-fg);
  border-color: rgba(255, 76, 45, 0.35);
}
.confirm-result.confirm-error {
  background: var(--bg-soft); color: var(--text-muted);
}
.summary-card[data-status="loading"] {
  background: var(--bg-soft);
  color: var(--text-muted);
}
.summary-card[data-status="loading"] .summary-headline { color: var(--text); }
.summary-card[data-status="pass"] {
  background: var(--good-bg);
  border-color: rgba(25, 168, 102, 0.35);
  color: var(--good-fg);
}
.summary-card[data-status="fail"] {
  background: var(--bad-bg);
  border-color: rgba(255, 76, 45, 0.4);
  color: var(--bad-fg);
}

/* ---------- Quality cards ---------- */
.quality-card { padding: 14px 16px; }
/* When liveness is bad the underlying values are stale; gray out the card's
   data (the title/pill row + the details) but keep the stale-note readable
   at full opacity. Dimming the children individually avoids the cascade-into-
   child-opacity gotcha that an opacity on .quality-card itself would cause. */
.quality-card.is-stale .quality-row,
.quality-card.is-stale .quality-details {
  opacity: 0.5;
  transition: opacity 200ms;
}
.quality-stale-note {
  margin: 8px 0 0;
  font-style: italic;
}
.quality-row {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px; min-height: 32px;
}
.quality-title {
  font-size: 16px; font-weight: 600; letter-spacing: -0.01em;
}
.quality-pill {
  font-size: 13px; padding: 5px 14px; font-weight: 600;
}

.quality-details { margin-top: 10px; }
.quality-details > summary {
  font-size: 12px; color: var(--text-muted); cursor: pointer;
  list-style: none; padding: 4px 0;
  display: inline-flex; align-items: center; gap: 4px;
  user-select: none;
}
.quality-details > summary::-webkit-details-marker { display: none; }
.quality-details > summary::before {
  content: '›'; display: inline-block;
  transition: transform 120ms; font-size: 14px; line-height: 1;
}
.quality-details[open] > summary::before { transform: rotate(90deg); }
.quality-details > summary:hover { color: var(--text); }

.quality-sub-list {
  list-style: none; padding: 0; margin: 8px 0 0;
  display: flex; flex-direction: column; gap: 4px;
  border-top: 1px solid var(--border);
}
.quality-sub {
  display: grid;
  grid-template-columns: 1fr auto auto;
  gap: 10px;
  align-items: center;
  padding: 8px 0;
  border-bottom: 1px solid var(--border);
  font-size: 14px;
}
.quality-sub:last-child { border-bottom: 0; }
.quality-sub-name { color: var(--text); }
.quality-sub-value {
  font-family: var(--font-mono); font-size: 13px;
  font-variant-numeric: tabular-nums; color: var(--text-muted);
}
.quality-sub-pill { font-size: 11px; padding: 2px 9px; }

/* ---------- KV ---------- */
.kv { display: grid; grid-template-columns: 110px 1fr;
  row-gap: 8px; column-gap: 12px; margin: 0; }
.kv dt { color: var(--text-muted); font-size: 13px; }
.kv dd { margin: 0; word-break: break-word; font-size: 14px; }

/* ---------- Admin station list ---------- */
/* ---------- Admin hub tiles ---------- */
.admin-tiles {
  display: grid;
  grid-template-columns: 1fr;
  gap: 14px;
}
@media (min-width: 720px) {
  .admin-tiles { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
.admin-tile {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 22px;
  border-radius: 14px;
  background: var(--surface, #fff);
  border: 1px solid var(--border);
  color: inherit;
  text-decoration: none;
  transition: transform 120ms, box-shadow 120ms, border-color 120ms;
  min-height: 140px;
}
.admin-tile:hover {
  transform: translateY(-1px);
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.06);
  border-color: var(--cerulean, #009de0);
}
.admin-tile-title {
  font-size: 18px;
  font-weight: 600;
  letter-spacing: -0.01em;
}
.admin-tile-desc {
  font-size: 13px;
  line-height: 1.45;
  color: var(--text-muted);
  flex: 1;
}
.admin-tile-badge {
  align-self: flex-start;
  font-size: 12px;
  font-weight: 500;
  padding: 3px 10px;
  border-radius: 999px;
  background: var(--bg-soft);
  color: var(--text-muted);
}

/* ---------- Admin stations list ---------- */
.station-search {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 8px 0 14px;
}
.station-search input[type="search"] {
  flex: 1;
  padding: 8px 12px;
  border-radius: 8px;
  border: 1px solid var(--border);
  background: var(--surface, #fff);
  font: inherit;
  font-size: 14px;
}
.station-search input[type="search"]:focus {
  outline: 2px solid var(--cerulean, #009de0);
  outline-offset: 0;
  border-color: var(--cerulean, #009de0);
}
.station-search-count { white-space: nowrap; }

.btn-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  padding: 0;
  border-radius: 8px;
  border: 1px solid var(--border);
  background: var(--surface, #fff);
  color: var(--text);
  cursor: pointer;
  transition: background 120ms, border-color 120ms, color 120ms;
}
.btn-icon:hover {
  background: var(--bg-soft);
  border-color: var(--text-muted);
}
/* Destructive icon button — always visibly red, deepens slightly on hover
   so the affordance is obvious without relying on hover (which doesn't
   exist on touch). */
.btn-icon-danger {
  background: var(--bad-bg);
  color: var(--bad-fg);
  border-color: rgba(255, 76, 45, 0.45);
}
.btn-icon-danger:hover {
  background: rgba(255, 76, 45, 0.18);
  border-color: rgba(255, 76, 45, 0.65);
}

/* When .btn-icon is used as a <details><summary>, hide the native
   disclosure triangle so the pencil/icon sits alone. The summary is still
   keyboard-toggleable; this is a pure visual cleanup. */
summary.btn-icon { list-style: none; }
summary.btn-icon::-webkit-details-marker { display: none; }
summary.btn-icon::marker { display: none; }
/* Expanded edit form sits below the row's action strip and spans the row
   width so the form controls aren't squeezed into the icon's column. */
.user-edit[open] {
  flex-basis: 100%;
  margin-top: 12px;
}
.user-edit[open] > summary {
  background: var(--bg-soft);
  border-color: var(--text-muted);
}

/* Force this element onto its own flex line within .station-actions. */
.station-actions .action-newline {
  flex-basis: 100%;
  display: flex;
  justify-content: flex-end;
}

.station-badges {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  align-items: center;
  margin-top: 6px;
}
.station-badges .pill {
  font-size: 11px;
  padding: 3px 8px;
  display: inline-flex;
  align-items: center;
  gap: 5px;
}
.station-badges .pill .pill-icon {
  flex: 0 0 auto;
  opacity: 0.85;
}
.station-badges .meta {
  font-size: 11px;
  color: var(--text-muted);
}
.station-submission {
  margin-top: 6px;
  word-break: break-word;
}
.station-distributors { margin-top: 4px; }
.distributor-chip {
  display: inline-block;
  padding: 1px 8px;
  border-radius: 999px;
  background: var(--bg-soft);
  font-size: 11px;
  color: var(--text);
}

/* Activation event log table. Horizontally scrollable on phones so wide
   tables don't break the layout. */
.activation-log {
  margin-top: 8px;
  overflow-x: auto;
  border: 1px solid var(--border);
  border-radius: 10px;
}
.activation-log table {
  border-collapse: collapse;
  width: 100%;
  font-size: 13px;
}
.activation-log th, .activation-log td {
  text-align: left;
  padding: 8px 10px;
  border-bottom: 1px solid var(--border);
  vertical-align: top;
}
.activation-log thead th {
  background: var(--bg-soft);
  font-weight: 600;
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--text-muted);
}
.activation-log tbody tr:last-child td { border-bottom: none; }
.activation-log-detail {
  max-width: 280px;
  word-break: break-word;
}

/* ---------- Submission modal ---------- */
/* Native <dialog> handles focus trap + ESC; we only style the chrome. */
.submission-modal {
  border: none;
  padding: 0;
  background: transparent;
  max-width: min(720px, calc(100vw - 32px));
  width: 100%;
}
.submission-modal::backdrop {
  background: rgba(20, 22, 28, 0.55);
  backdrop-filter: blur(2px);
}
.submission-modal-inner {
  background: var(--surface, #fff);
  border-radius: 14px;
  box-shadow: 0 10px 40px rgba(0, 0, 0, 0.25);
  overflow: hidden;
  display: flex;
  flex-direction: column;
  max-height: calc(100vh - 32px);
}
.submission-modal-header {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: 12px;
  padding: 18px 20px;
  border-bottom: 1px solid var(--border);
}
.submission-modal-title {
  font-size: 18px; font-weight: 600;
  letter-spacing: -0.01em;
}
.submission-modal-sub {
  font-size: 12px;
  color: var(--text-muted);
  font-family: var(--font-mono);
  margin-top: 2px;
}
.submission-modal-body {
  padding: 18px 20px 24px;
  overflow-y: auto;
}
.submission-modal-body .kv {
  display: grid;
  grid-template-columns: max-content 1fr;
  column-gap: 16px;
  row-gap: 8px;
  margin: 0 0 16px;
  font-size: 14px;
}
.submission-modal-body .kv dt {
  color: var(--text-muted);
  font-weight: 500;
}
.submission-modal-body .kv dd { margin: 0; word-break: break-word; }

.submission-section-title {
  font-size: 13px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--text-muted);
  margin: 14px 0 8px;
}
.submission-notes {
  margin: 16px 0;
  padding: 12px 14px;
  border-radius: 10px;
  background: var(--bg-soft);
  border: 1px solid var(--border);
}
.submission-notes-body {
  margin: 0;
  white-space: pre-wrap;
  font-size: 14px;
  line-height: 1.5;
}

.submission-photo-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px;
}
.submission-photo {
  position: relative;
  display: block;
  border-radius: 10px;
  overflow: hidden;
  background: var(--bg-soft);
  border: 1px solid var(--border);
  aspect-ratio: 1 / 1;
  text-decoration: none;
  color: inherit;
}
.submission-photo img {
  display: block;
  width: 100%; height: 100%;
  object-fit: cover;
}
.submission-photo-label {
  position: absolute;
  left: 8px; bottom: 8px;
  padding: 3px 8px;
  border-radius: 999px;
  background: rgba(0, 0, 0, 0.55);
  color: #fff;
  font-size: 11px;
  font-weight: 500;
  text-transform: capitalize;
}
.submission-photo-missing {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 14px;
  text-align: center;
  gap: 4px;
}
.station-submission a { color: inherit; text-decoration: underline; }
.station-submission a:hover { color: var(--text); }

.station-list { list-style: none; padding: 0; margin: 0;
  display: flex; flex-direction: column; gap: 8px; }
.station-row {
  display: flex; gap: 10px; justify-content: space-between; align-items: center;
  padding: 12px 14px; border-radius: var(--radius);
  background: var(--bg);
  border: 1px solid var(--border);
}
/* `display: flex` above outranks the browser-default `[hidden]{display:none}`,
   so explicitly re-hide the row when the search filter sets hidden. */
.station-row[hidden] { display: none; }
/* When the Refresh POST/redirect lands the browser on #cas-... we want
   the row to clear the sticky .topbar (which is ~70px tall on desktop +
   safe-area on iOS). 80px gives a small breathing-room gap above. */
.station-row[id^="cas-"] { scroll-margin-top: 80px; }
.station-meta { min-width: 0; }
.station-cas { font-weight: 600; font-family: var(--font-mono); font-size: 14px; }
.station-label { font-size: 13px; color: var(--text-muted); margin-top: 2px; }
.station-actions { display: flex; gap: 6px; flex-wrap: wrap; justify-content: flex-end; }
code { font-family: var(--font-mono);
  background: var(--bg-soft); padding: 1px 6px; border-radius: 6px;
  font-size: 12px; }

/* ---------- Status row (admin creds card) ---------- */
.status-row { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.status-row .pill { font-size: 13px; padding: 4px 12px; }
.status-row .meta { color: var(--text-muted); font-size: 13px;
  font-family: var(--font-mono); }

/* ---------- QR modal ---------- */
.modal {
  position: fixed; inset: 0; display: none;
  background: rgba(34, 34, 34, 0.45); backdrop-filter: blur(4px);
  z-index: 50; align-items: center; justify-content: center;
  padding: 16px;
}
.modal.open { display: flex; }
.modal-body {
  width: 100%; max-width: 480px;
  background: var(--bg); border: 1px solid var(--border);
  border-radius: var(--radius); padding: 14px;
  box-shadow: var(--shadow-md);
}
.modal-header { display: flex; justify-content: space-between;
  align-items: center; font-weight: 600; margin-bottom: 10px; }
#qr-reader { width: 100%; min-height: 280px; border-radius: 10px; overflow: hidden;
  background: var(--bg-soft); }
#qr-reader video { width: 100% !important; border-radius: 10px; }
#qr-status { margin-top: 8px; min-height: 1.4em; color: var(--text-muted); font-size: 13px; }

/* ---------- Wider screens ---------- */
@media (min-width: 600px) {
  .metrics-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .station-row { align-items: center; }
}

/* ---------- Factory activation card ---------- */
.sheet-page { max-width: 760px; }
.sheet {
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 28px;
  display: flex; flex-direction: column; gap: 22px;
}
.sheet-header { display: flex; align-items: center; gap: 18px; }
.sheet-logo { height: 36px; width: auto; }
.sheet-header-text h1 { margin: 0; font-size: 22px; font-weight: 700;
  letter-spacing: -0.01em; }
.sheet-subtitle { margin: 2px 0 0; color: var(--text-muted); font-size: 13px; }

.sheet-ids {
  display: grid; grid-template-columns: 1fr 1fr; gap: 14px;
}
.sheet-id-block {
  background: var(--bg-alt);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 14px 18px;
}
.sheet-id-label { font-size: 11px; color: var(--text-muted);
  letter-spacing: 0.08em; text-transform: uppercase; margin-bottom: 6px; }
.sheet-id-value { font-family: var(--font-mono); font-size: 24px;
  font-weight: 600; font-variant-numeric: tabular-nums; letter-spacing: -0.01em;
  word-break: break-all; }
.sheet-pin .sheet-pin-value { font-size: 34px; letter-spacing: 0.04em; }
.sheet-label { font-size: 14px; }

.sheet-qr {
  display: flex; align-items: center; gap: 20px;
  background: var(--bg-alt);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 18px;
}
.sheet-qr-img { display: block; width: 180px; height: 180px;
  background: #fff; padding: 8px; border-radius: 8px; }
.sheet-qr-headline { font-weight: 600; margin-bottom: 4px; }
.sheet-qr-url code { background: transparent; padding: 0; font-size: 12px; }

.sheet-instructions h2 {
  margin: 0 0 8px; font-size: 14px; text-transform: uppercase;
  letter-spacing: 0.06em; color: var(--text-muted); font-weight: 600;
}
.sheet-instructions ol { margin: 0; padding-left: 22px;
  display: flex; flex-direction: column; gap: 6px; font-size: 14px; }
.sheet-footer { padding-top: 8px; border-top: 1px solid var(--border); }

/* ---------- Print rules ---------- */
@media print {
  body, .bg-station, .bg-admin { background: #fff !important; color: #000 !important; }
  .topbar, .sheet-screen-only, .scan-modal, .modal,
  .btn-ghost, #refresh-btn { display: none !important; }
  .page { padding: 0; max-width: none; }
  .sheet {
    border: 0; padding: 0; box-shadow: none;
    page-break-inside: avoid;
  }
  .sheet-id-block, .sheet-qr {
    border-color: #999 !important; background: #fff !important;
    box-shadow: none !important;
  }
  .sheet-id-value, .sheet-pin-value { color: #000 !important; }
  a, code { color: #000 !important; }
  @page { margin: 16mm; }
}
