:root {
  --bg: #f4f5f2; --card: #ffffff; --ink: #1b1f1d; --muted: #6b726e; --line: #e2e5e0;
  --accent: #0f766e; --warn: #b45309; --bad: #b91c1c; --good: #15803d;
  --grid: #eceee9; --idle: #d6dad3; --past: #b9bdb7;
  --f1: #2563eb; --f2: #0f766e; --f3: #7c3aed; --f4: #c2410c;
  --f5: #be185d; --f6: #4d7c0f; --f7: #0369a1; --f8: #a16207;
}
@media (prefers-color-scheme: dark) {
  :root {
    --bg: #0f1211; --card: #171b19; --ink: #e6e9e5; --muted: #8d958f; --line: #262c29;
    --accent: #2dd4bf; --grid: #202623; --idle: #2b322e; --past: #59615c;
    --f1: #60a5fa; --f2: #2dd4bf; --f3: #a78bfa; --f4: #fb923c;
    --f5: #f472b6; --f6: #a3e635; --f7: #38bdf8; --f8: #facc15;
  }
}
* { box-sizing: border-box; }
html, body { margin: 0; background: var(--bg); color: var(--ink);
  font: 14px/1.4 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; }
.mono { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; }
.muted { color: var(--muted); }
.small { font-size: 12px; }
h1 { font-size: 17px; margin: 0; letter-spacing: -0.01em; }
h2 { font-size: 14px; margin: 0; font-weight: 600; }
.top { position: sticky; top: 0; z-index: 5; display: flex; flex-wrap: wrap; gap: 10px 20px;
  align-items: center; justify-content: space-between; padding: 12px 16px;
  background: var(--card); border-bottom: 1px solid var(--line); }
.brand { display: flex; align-items: center; gap: 10px; }
.dot { width: 10px; height: 10px; border-radius: 50%; background: var(--bad); }
.dot.ok { background: var(--good); box-shadow: 0 0 0 3px color-mix(in srgb, var(--good) 25%, transparent); }
.scanbar { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.pill { display: flex; gap: 6px; align-items: baseline; padding: 4px 10px; border: 1px solid var(--line);
  border-radius: 999px; }
.pill .k { color: var(--muted); font-size: 12px; }
.pill .v { font-weight: 600; }
.btn { background: var(--accent); color: var(--card); border: 0; border-radius: 8px; padding: 7px 12px;
  font: inherit; font-weight: 600; cursor: pointer; text-decoration: none; display: inline-block; }
.btn.ghost { background: transparent; color: var(--ink); border: 1px solid var(--line); }
.btn.small { padding: 4px 10px; font-size: 12px; }
main { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 16px; padding: 16px;
  max-width: 1500px; margin: 0 auto; }
.card { background: var(--card); border: 1px solid var(--line); border-radius: 12px; padding: 14px;
  min-width: 0; }
.span2 { grid-column: span 2; }
.cardhead { display: flex; justify-content: space-between; align-items: center; gap: 10px;
  margin-bottom: 10px; flex-wrap: wrap; }
canvas { width: 100%; display: block; }
/* 0.1.87: the waterfall scrolls back through the whole scan (the canvas stays put, the spacer gives the scroll range) */
.wfbox { position: relative; margin-top: 6px; }
.wfwrap { height: 260px; overflow-y: auto; border-radius: 6px; overscroll-behavior: contain; }
#waterfall { position: sticky; top: 0; display: block; width: 100%; border-radius: 6px; }
.wflive { position: absolute; top: 8px; right: 22px; box-shadow: 0 1px 4px rgba(0,0,0,.18); }
.axisnote { font-size: 11px; margin-top: 6px; }
.legend { display: flex; flex-wrap: wrap; gap: 4px 12px; font-size: 12px; color: var(--muted); }
.legend i { display: inline-block; width: 10px; height: 10px; border-radius: 2px; margin-right: 4px;
  vertical-align: -1px; }
.tbl { width: 100%; border-collapse: collapse; }
.tbl th { text-align: left; font-weight: 500; color: var(--muted); font-size: 12px;
  border-bottom: 1px solid var(--line); padding: 5px 6px; white-space: nowrap; }
.tbl td { padding: 5px 6px; border-bottom: 1px solid var(--grid); white-space: nowrap;
  font-variant-numeric: tabular-nums; }
.tbl tr.cur td { background: color-mix(in srgb, var(--accent) 10%, transparent); }
.bar { display: inline-block; height: 8px; border-radius: 2px; background: var(--accent);
  vertical-align: middle; margin-right: 6px; }
.scrollx { overflow-x: auto; }
.scroll { max-height: 340px; overflow: auto; }
.crc-bad { color: var(--bad); }
.sel { background: var(--card); color: var(--ink); border: 1px solid var(--line); border-radius: 6px;
  padding: 4px 6px; font: inherit; }
dialog { border: 1px solid var(--line); border-radius: 12px; background: var(--card); color: var(--ink);
  width: min(420px, calc(100vw - 32px)); }
dialog::backdrop { background: rgb(0 0 0 / 40%); }
dialog label { display: block; margin: 10px 0; font-size: 13px; color: var(--muted); }
dialog select, dialog input { display: block; width: 100%; margin-top: 4px; padding: 7px;
  border: 1px solid var(--line); border-radius: 6px; background: var(--bg); color: var(--ink); font: inherit; }
.row { display: flex; gap: 8px; }
.row.end { justify-content: flex-end; }
.err { color: var(--bad); min-height: 1em; }
footer { padding: 4px 16px 20px; max-width: 1500px; margin: 0 auto; }
@media (max-width: 900px) {
  main { grid-template-columns: minmax(0, 1fr); padding: 12px; }
  .span2 { grid-column: span 1; }
}
[hidden] { display: none !important; }

/* Password field with show/hide eye button */
.pw { position: relative; display: block; }
.pw input { width: 100%; padding-right: 2.4em; box-sizing: border-box; }
.pw .eye { position: absolute; right: 4px; top: 50%; transform: translateY(-50%); border: 0; background: none;
  cursor: pointer; line-height: 0; padding: 4px; color: inherit; opacity: .55; }
.pw .eye:hover, .pw .eye.on { opacity: 1; }

/* Chart title links → explanation dialog */
.helplink { all: unset; cursor: pointer; display: inline-flex; align-items: center; gap: 5px; color: var(--accent);
  text-decoration: underline; text-underline-offset: 3px; font: inherit; }
.helplink:hover { opacity: .8; }
.helplink:focus-visible { outline: 2px solid currentColor; outline-offset: 2px; border-radius: 3px; }
#helpDlg { max-width: 560px; width: calc(100% - 32px); }
#helpDlg .helpbody { max-height: 70vh; overflow-y: auto; }
#helpDlg h3 { font-size: .95em; margin: 14px 0 4px; }
#helpDlg p, #helpDlg li { line-height: 1.45; }
#helpDlg ul { padding-left: 1.2em; margin: 4px 0; }
#helpDlg h2 { font-size: 1.25em; margin: 0 0 6px; }

/* Report menu */
.menu { position: relative; }
.menulist { position: absolute; right: 0; top: calc(100% + 4px); z-index: 10; min-width: 200px; padding: 4px;
  background: var(--card); border: 1px solid var(--line); border-radius: 10px; box-shadow: 0 8px 24px rgb(0 0 0 / 15%); }
.menulist a { display: block; padding: 8px 10px; border-radius: 6px; color: var(--ink); text-decoration: none; }
.menulist a:hover, .menulist a:focus-visible { background: color-mix(in srgb, var(--accent) 12%, transparent); outline: none; }

/* Banner when no packets arrive */
.banner { display: flex; flex-wrap: wrap; gap: 8px 14px; align-items: center; justify-content: space-between;
  max-width: 1500px; margin: 12px auto 0; padding: 10px 14px; border-radius: 10px;
  background: color-mix(in srgb, var(--warn) 12%, var(--card)); border: 1px solid color-mix(in srgb, var(--warn) 40%, var(--line)); }
@media (max-width: 1532px) { .banner { margin-left: 16px; margin-right: 16px; } }
/* Scan settings that don't apply to the chosen mode */
dialog label.off { opacity: .45; }
dialog label.off select, dialog label.off input { cursor: not-allowed; }

/* Hover box on the live spectrum and waterfall */
.tip { position: fixed; z-index: 20; max-width: 320px; padding: 6px 9px; border-radius: 8px; pointer-events: none;
  background: var(--card); color: var(--ink); border: 1px solid var(--line); box-shadow: 0 6px 18px rgb(0 0 0 / 18%);
  font-size: 12px; line-height: 1.4; }
.tip b { display: block; font-size: 12.5px; margin-bottom: 1px; }
.tip div { color: var(--muted); }

/* Short notice after signing in */
#toast { position: fixed; left: 50%; bottom: 20px; transform: translateX(-50%); z-index: 30; max-width: min(560px, calc(100vw - 32px));
  padding: 10px 14px; border-radius: 10px; background: var(--ink); color: var(--card); box-shadow: 0 8px 24px rgb(0 0 0 / 25%);
  font-size: 13px; line-height: 1.4; }

/* Forwarder status box in the header and its details dialog */
.pillbtn { background: transparent; color: var(--ink); font: inherit; cursor: pointer; }
.pillbtn:hover { border-color: var(--muted); }
.pillbtn.ok .v { color: var(--good); }
.pillbtn.warn .v { color: var(--warn, #b45309); }
.pillbtn.bad .v { color: var(--bad); }
table.kv { width: 100%; border-collapse: collapse; margin: 8px 0; font-size: 13px; }
table.kv th { text-align: left; font-weight: 400; color: var(--muted); padding: 4px 8px 4px 0; }
table.kv td { text-align: right; font-weight: 600; padding: 4px 0; font-variant-numeric: tabular-nums; }
#fwdDlg .row { gap: 8px; }

/* Gateway setup check page (browser-only use) */
body.setup-on main, body.setup-on #setupBanner { display: none; }
.setup { max-width: 860px; margin: 0 auto; padding: 16px; }
.setup .card { padding: 20px 22px; }
.setup h3 { font-size: 13px; margin: 18px 0 6px; }
.setup p { margin: 6px 0; }
.setup-h { font-size: 18px; margin-bottom: 6px; }
.setup-sum { font-size: 15px; font-weight: 600; }
.setup-sum.ok { color: var(--good); }
.setup-sum.bad { color: var(--bad); }
.setup-note { padding: 10px 12px; border-radius: 8px; background: color-mix(in srgb, var(--accent) 9%, transparent); }
.setup-prod { margin: 12px 0; padding: 10px 14px; border: 1px solid var(--bad); border-radius: 8px;
  background: color-mix(in srgb, var(--bad) 7%, transparent); }
.setup-prod h3 { margin-top: 2px; color: var(--bad); }
.setup-prod ul { margin: 6px 0; padding-left: 18px; }
.setup-prod .ack { display: flex; gap: 8px; align-items: flex-start; margin-top: 8px; font-weight: 600; color: var(--ink); }
.setup-prod .ack input { margin-top: 2px; }
.tablewrap { overflow-x: auto; }
.setup-tbl { width: 100%; border-collapse: collapse; font-size: 13px; }
.setup-tbl th { text-align: left; font-weight: 500; color: var(--muted); border-bottom: 1px solid var(--line); padding: 6px 8px 6px 0; }
.setup-tbl td { padding: 7px 8px 7px 0; border-bottom: 1px solid var(--line); vertical-align: top; }
.setup-tbl td.st { font-weight: 700; white-space: nowrap; }
.setup-tbl td.st.ok { color: var(--good); }
.setup-tbl td.st.bad { color: var(--bad); }
.setup-tbl .where { display: block; color: var(--muted); font-size: 12px; font-weight: 400; margin-top: 2px; }
.setup-fix { margin: 12px 0; padding: 10px 12px; border: 1px solid var(--line); border-radius: 8px; }
.setup-login { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 0 12px; }
.setup-login label { display: block; margin: 8px 0; font-size: 13px; color: var(--muted); }
.setup-login input { display: block; width: 100%; margin-top: 4px; padding: 7px; border: 1px solid var(--line);
  border-radius: 6px; background: var(--bg); color: var(--ink); font: inherit; }
.setup-restore { margin-top: 14px; padding: 10px 12px; border-radius: 8px; background: var(--bg); }
.setup-restore h3 { margin-top: 0; }
.setup-actions { margin-top: 16px; }
.btn:disabled { opacity: .45; cursor: not-allowed; }
/* Resume / Pause / Stop: tape-deck symbols. Grey = not available now; a green Resume symbol = running. */
.vcr { display: inline-flex; gap: 4px; }
.vcrbtn { display: inline-flex; align-items: center; justify-content: center; width: 36px; height: 32px; padding: 0;
  border: 1px solid var(--line); border-radius: 8px; background: var(--card); color: var(--ink); cursor: pointer; }
.vcrbtn:hover:not(:disabled) { background: color-mix(in srgb, var(--ink) 7%, var(--card)); }
.vcrbtn:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.vcrbtn:disabled { background: var(--idle); color: var(--muted); cursor: default; }
.vcrbtn.running, .vcrbtn.running:disabled { color: var(--good); }
.vcrbody p { margin: 8px 0; }
/* First-run wizard */
.wizsteps { display: flex; flex-wrap: wrap; gap: 6px; list-style: none; padding: 0; margin: 6px 0 14px; counter-reset: wz; }
.wizsteps li { counter-increment: wz; font-size: 12px; color: var(--muted); padding: 3px 10px; border: 1px solid var(--line); border-radius: 999px; }
.wizsteps li::before { content: counter(wz) ". "; }
.wizsteps li.cur { color: var(--card); background: var(--accent); border-color: var(--accent); font-weight: 600; }
.wizsteps li.done { color: var(--good); }
.wizbtns { flex-wrap: wrap; align-items: center; margin-top: 16px; }
.wizbtns .grow { flex: 1; }
.wizform label { display: block; margin: 8px 0; font-size: 13px; color: var(--muted); max-width: 360px; }
.wizform input { display: block; width: 100%; margin-top: 4px; padding: 7px; border: 1px solid var(--line); border-radius: 6px;
  background: var(--card); color: var(--ink); font: inherit; }
.wizcards { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 12px; }
.wizcard { all: unset; box-sizing: border-box; cursor: pointer; display: flex; flex-direction: column; gap: 6px; padding: 14px;
  border: 1px solid var(--line); border-radius: 10px; font-size: 13px; }
.wizcard:hover:not(:disabled), .wizcard:focus-visible { border-color: var(--accent); box-shadow: 0 0 0 2px color-mix(in srgb, var(--accent) 25%, transparent); }
.wizcard:disabled { opacity: .5; cursor: not-allowed; }
.wizcard-t { font-weight: 700; font-size: 15px; }
.wizopts { display: flex; flex-direction: column; gap: 4px; }
.wizopt { display: flex; align-items: center; gap: 8px; padding: 6px 0; }
.wizopt label { display: inline-flex; align-items: center; gap: 8px; font-weight: 600; cursor: pointer; }
.infobtn { all: unset; cursor: pointer; width: 20px; height: 20px; border-radius: 50%; border: 1.5px solid var(--accent); color: var(--accent);
  font: italic 700 12px Georgia, serif; display: inline-flex; align-items: center; justify-content: center; }
.infobtn[aria-expanded="true"] { background: var(--accent); color: var(--card); }
.wizinfo { margin: 0 0 6px 26px; padding: 8px 12px; border-radius: 8px; font-size: 13px;
  background: color-mix(in srgb, var(--accent) 8%, transparent); }
.wizinfo p { margin: 4px 0; }
.wizsub { margin: 0 0 8px 26px; }
.wizsub label { display: block; margin: 6px 0; font-size: 13px; color: var(--muted); max-width: 320px; }
.wizsub input, .wizsub select { display: block; margin-top: 4px; padding: 6px; border: 1px solid var(--line); border-radius: 6px;
  background: var(--card); color: var(--ink); font: inherit; width: 100%; }
.wizq { font-size: 16px; font-weight: 600; }
/* While the wizard is open it is the whole page: no header (logo, pills, buttons), banners or dashboard. */
body.wiz-on main, body.wiz-on #setupPage, body.wiz-on header.top, body.wiz-on .banner { display: none !important; }
body.wiz-on .wiz { padding-top: 24px; }
.wizlogo { display: block; height: 40px; width: auto; margin: 4px 0 14px; }
@media (prefers-color-scheme: dark) { .wizlogo { background: #fff; padding: 6px 10px; border-radius: 6px; } }
.wizwelcome { margin: 0 0 14px; }
a.mlink { color: var(--accent); font-weight: 600; white-space: nowrap; text-decoration: none; }
a.mlink:hover { text-decoration: underline; }
.where a.mlink { margin-left: 4px; }
/* Spectrum baseline progress (dialog and banner) */
.prog { margin: 10px 0 4px; }
.progbar { position: relative; height: 10px; border-radius: 5px; overflow: hidden; background: var(--grid);
  border: 1px solid var(--line); }
.progbar > span { position: absolute; left: 0; top: 0; bottom: 0; width: 0; background: var(--accent);
  border-radius: 5px; transition: width 1s linear; }
.progbar.indet > span { width: 30%; animation: progslide 1.4s ease-in-out infinite; }
@keyframes progslide { 0% { left: -30%; } 100% { left: 100%; } }
@media (prefers-reduced-motion: reduce) { .progbar.indet > span { animation: none; left: 0; width: 100%; opacity: .4; } }
.proginfo { margin-top: 4px; color: var(--muted); }
.banner .prog { flex: 1 1 100%; margin: 4px 0 0; }
.banner .progbar { height: 8px; }
/* Spectrum baseline dialog */
/* Spectrum page: while it's open (and always while a baseline runs) it is the focus: the pills bar, banners and
   the dashboard's charts are hidden; the title row with the logo stays. */
body.spec-on .scanbar, body.spec-on main, body.spec-on .banner, body.spec-on #setupPage { display: none !important; }
.specpage .card { max-width: 1100px; }
.specintro { margin: 6px 0 8px; }
.specintro .infobtn { margin-left: 4px; vertical-align: -3px; }
.specinfo { margin: 0 0 8px; }
dialog textarea { display: block; width: 100%; margin-top: 4px; padding: 7px; border: 1px solid var(--line);
  border-radius: 6px; background: var(--card); color: var(--ink); font: inherit; resize: vertical; }
#specRepDlg { width: min(520px, 94vw); }
.specfoot { align-items: center; gap: 12px; margin-top: 14px; }
#specDlg h3 { font-size: 13px; margin: 14px 0 4px; font-weight: 600; }
#specDlg canvas { width: 100%; display: block; }
.specctl { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; margin: 10px 0; }
.specctl label, label.inline { display: inline-flex; gap: 6px; align-items: center; margin: 0; color: var(--ink); }
.specctl select, label.inline select { display: inline-block; width: auto; margin: 0; }
.specmeta { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; margin-top: 6px; }
.specsum { padding: 0; }
.speclegend { display: flex; flex-wrap: wrap; gap: 4px 12px; margin: 6px 0 10px; }
.speclegend i { display: inline-block; width: 10px; height: 10px; border-radius: 2px; margin-right: 4px; vertical-align: -1px; }
#specTbl td.v-quiet { color: var(--sev0); }
#specTbl td.v-light { color: var(--sev1t); }
#specTbl td.v-moderate { color: var(--sev2t); }
#specTbl td.v-heavy { color: var(--sev3); font-weight: 600; }
#specTbl td.v-busy { color: var(--sev4); font-weight: 600; }
#vcrDlg { max-width: 520px; }
@media (max-width: 600px) {
  .setup { padding: 10px; }
  .setup .card { padding: 16px; }
  .setup-tbl thead { display: none; }
  .setup-tbl tr { display: grid; grid-template-columns: 1fr auto; column-gap: 10px; padding: 8px 0;
    border-bottom: 1px solid var(--line); }
  .setup-tbl td { border: 0; padding: 1px 0; overflow-wrap: anywhere; }
  .setup-tbl td:nth-child(1) { grid-column: 1 / -1; font-weight: 600; }
  .setup-tbl td:nth-child(2), .setup-tbl td:nth-child(3) { grid-column: 1; }
  .setup-tbl td:nth-child(4) { grid-column: 2; grid-row: 2 / span 2; align-self: center; }
  .setup-tbl td:nth-child(2)::before { content: "Now: "; color: var(--muted); }
  .setup-tbl td:nth-child(3)::before { content: "Needed: "; color: var(--muted); }
}

/* Scan settings: Seconds per FSB help */
.dwellhelp { margin: -4px 0 10px; }
.dwellhelp p { margin: 4px 0; }
.dwellhelp .roundest { color: var(--ink); font-weight: 600; }
.dwellhelp.off { display: none; }

/* Generate report: period choice */
#repDlg .radios { display: grid; gap: 2px; margin: 8px 0 14px; }
#repDlg .radios label { display: grid; grid-template-columns: auto 1fr; column-gap: 8px; margin: 0; padding: 6px 4px;
  border-radius: 6px; color: var(--ink); font-size: 14px; cursor: pointer; }
#repDlg .radios label:hover { background: var(--bg); }
#repDlg .radios input { display: inline; width: auto; margin: 2px 0 0; }
#repDlg .radios .small { grid-column: 2; }

/* MultiTech logo */
.mtlogo { height: 20px; width: auto; display: block; }
@media (prefers-color-scheme: dark) { .mtlogo { background: #fff; border-radius: 4px; padding: 3px 6px; box-sizing: content-box; } }
@media (max-width: 520px) {
  .brand { flex-wrap: wrap; row-gap: 6px; }
  .mtlogo { height: 18px; flex: 0 0 100%; object-fit: contain; object-position: left center; }
}
@media (max-width: 520px) and (prefers-color-scheme: dark) { .mtlogo { flex-basis: auto; } }

.setup-tbl td.st.warn { color: var(--warn); }
.setup-tbl .warnline { display: block; color: var(--warn); font-size: 12px; margin-top: 3px; }

/* Header: gateway EUI · serial · Ethernet IP */
.gwid { font-size: 12px; display: flex; flex-wrap: wrap; gap: 2px 12px; }
.gwid b { font-weight: 500; color: var(--ink); font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; }
@media (max-width: 760px) { .gwid { flex-basis: 100%; } }

/* 0.1.46: Settings menu items, and Start Scan / Stop Scan with its duration list */
.menulist .mi { display: block; width: 100%; text-align: left; padding: 8px 10px; border: 0; border-radius: 6px;
  background: transparent; color: var(--ink); font: inherit; cursor: pointer; }
.menulist .mi[hidden] { display: none; }
.menulist .mi:hover:not(:disabled), .menulist .mi:focus-visible { background: color-mix(in srgb, var(--accent) 12%, transparent); outline: none; }
.menulist .mi:disabled { color: var(--muted); cursor: default; }
.menulist .mi-danger { color: var(--bad); border-top: 1px solid var(--line); border-radius: 0 0 6px 6px; margin-top: 4px; }
.runctl { display: inline-flex; gap: 6px; align-items: center; padding-left: 10px; margin-left: 2px;
  border-left: 1px solid var(--line); }
.runctl .sel { max-width: 210px; }
.runbtn { display: inline-flex; align-items: center; gap: 7px; color: #fff; min-width: 116px; justify-content: center; }
.runbtn.start { background: var(--good); }
.runbtn.stop { background: var(--bad); }
.runico { width: 0; height: 0; border-style: solid; border-width: 6px 0 6px 10px;
  border-color: transparent transparent transparent currentColor; }
.runbtn.stop .runico { width: 11px; height: 11px; border: 0; background: currentColor; border-radius: 2px; }
.pill.live { border-color: color-mix(in srgb, var(--good) 55%, var(--line)); }
.pill.live .v { color: var(--good); }
.wizdur { display: flex; gap: 8px; align-items: center; margin: 10px 0 4px; }

/* 0.1.48: the Scan pill fills up while a scan runs (stripes move across the filled part) */
.runpill { position: relative; overflow: hidden; }
.runpill > :not(.runfill) { position: relative; z-index: 1; }
.runfill { position: absolute; left: 0; top: 0; bottom: 0; width: 0; z-index: 0;
  background-color: color-mix(in srgb, var(--good) 16%, var(--card));
  background-image: repeating-linear-gradient(-45deg, transparent 0 8px, color-mix(in srgb, var(--good) 22%, transparent) 8px 16px);
  background-size: 22.6px 22.6px; transition: width 1s linear; }
.runpill.filling .runfill { animation: runstripes 1s linear infinite; }
.runpill.open .runfill { background-color: color-mix(in srgb, var(--good) 9%, var(--card)); }
@keyframes runstripes { to { background-position: 22.6px 0; } }
@media (prefers-reduced-motion: reduce) { .runpill.filling .runfill { animation: none; transition: none; } }

/* 0.1.49: Save the scan; Generate report with saved scans */
#saveDlg, #repDlg { max-width: 560px; width: calc(100% - 32px); }
#saveDlg textarea { width: 100%; font: inherit; }
.btn.danger { color: var(--bad); }
.scanpick { margin: 4px 0 6px 24px; }
.scanlist { max-height: 240px; overflow: auto; border: 1px solid var(--line); border-radius: 8px; }
.scanrow { display: flex !important; gap: 10px; align-items: flex-start; padding: 8px 10px; border-bottom: 1px solid var(--line); }
.scanrow:last-child { border-bottom: 0; }
.scanrow > span { display: flex; flex-direction: column; min-width: 0; }
.scanrow b { overflow-wrap: anywhere; }
.repmode { margin-top: 8px; }
#repDlg .radios #repPeriod { grid-column: 2; justify-self: start; margin-top: 4px; }
#saveDlg .grow { flex: 1; }
.menulist a, .menulist .mi { white-space: nowrap; }
.btn.iconbtn { display: inline-flex; align-items: center; justify-content: center; padding: 6px 8px; }

/* 0.1.51: Scan Settings page (header button green, no icon until it turns into Stop Scan) */
.runbtn.start:not(.playbtn) .runico { display: none; }
body.scan-on main, body.scan-on .banner, body.scan-on #setupPage, body.scan-on #specDlg { display: none !important; }
.scanpage .card { max-width: 760px; }
.scansum { margin: 8px 0 16px; }
.scansum th { width: 38%; }
.sctypes { margin: 8px 0 12px; }
.sctype { cursor: pointer; }
.sctype.on { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent); }
.sctype .wizcard-t { display: flex; gap: 8px; align-items: center; }
.sctype input { margin: 0; }
.scsub { margin: 4px 0 12px; }
.scanauth { margin: 4px 0 14px; padding-top: 10px; border-top: 1px solid var(--line); }
.playbtn { min-width: 0; }

/* 0.1.52: live view choice, progress-only view, empty dashboard before the first scan, Live Scan */
body.noscan main, body.progress-on main { display: none !important; }
.dashnote .card { max-width: 760px; margin: 16px auto; }
.bigbar { height: 14px; margin: 10px 0 6px; }
#liveBtn[hidden] { display: none; }
.scstart .sclabel { pointer-events: none; }
body.scan-on .dashnote, body.wiz-on .dashnote, body.spec-on .dashnote, body.setup-on .dashnote { display: none !important; }

/* 0.1.53: Start Scan grey until the scan is chosen; the scan page reached from the wizard hides the pill/button row */
.runbtn.start:disabled { background: var(--idle); color: var(--muted); opacity: 1; cursor: not-allowed; }
body.wizflow header.top .scanbar, body.wiz-on header.top { display: none !important; }
.specmeta .livemeta { display: block; color: var(--good); font-weight: 600; margin-top: 4px; }

/* 0.1.54: start card on an empty dashboard; Settings gear at the far right of the header row */
/* 0.1.67: Choose a Task: each button with a short explanation under it */
.tasktitle { margin: 0 0 14px; font-size: 20px; }
.startlist { list-style: none; margin: 0; padding: 0; display: grid; gap: 16px 20px;
  grid-template-columns: repeat(2, minmax(0, 1fr)); }
@media (max-width: 560px) { .startlist { grid-template-columns: 1fr; } }
.startlist li { display: flex; flex-direction: column; align-items: stretch; gap: 8px; }
.startlist .btn { width: 100%; text-align: center; padding-top: 10px; padding-bottom: 10px; }
.startlist li > span { color: var(--muted); font-size: 13px; line-height: 1.4; }
.btn.start-rec { background: var(--good); color: #fff; }

/* 0.1.57: wizard backup step, tick what to save */
.savepick { display: grid; gap: 4px; margin: 6px 0 4px; }
.savechk { display: flex; gap: 10px; align-items: flex-start; padding: 10px 12px; border: 1px solid var(--line, #ddd); border-radius: 8px; cursor: pointer; }
.savechk input { margin-top: 3px; width: 18px; height: 18px; flex: none; }
.savechk > span { display: grid; gap: 2px; }
.savest { margin: 0 0 6px 40px; }
.savest:empty { display: none; }
/* 0.1.57: Next step after a wizard scan */
#nextDlg .nextopts { display: grid; gap: 10px; margin: 10px 0 16px; }
#nextDlg { width: min(460px, calc(100vw - 32px)); }
#nextDlg .nextopts label { display: flex; gap: 10px; align-items: center; margin: 0; font-size: 15px; color: var(--ink); cursor: pointer; }
#nextDlg .nextopts input { display: inline-block; width: 18px; height: 18px; margin: 0; padding: 0; flex: none; }
#nextDlg .nextopts label.off { opacity: .45; }
#nextDlg .nextnote { margin: -6px 0 0 28px; }

/* 0.1.60: Record a Scan chooser */
.recpick { display: grid; gap: 10px; margin: 8px 0 16px; }
.recopt { display: flex; gap: 10px; align-items: center; font-size: 16px; cursor: pointer; }
.recopt input { width: 18px; height: 18px; margin: 0; flex: none; }
.recopt.off { opacity: .45; cursor: not-allowed; }
.recsum { margin: -4px 0 4px 28px; width: auto; max-width: 420px; }
.recna { margin: -6px 0 0 28px; }

/* 0.1.72: wizard sign-in wait */
.wizwait { margin: 12px 0 4px; display: grid; gap: 8px; }
.wizwait p { margin: 0; }

/* 0.1.73: sign-in inside a confirmation box */
.vcrlogin { margin: 8px 0 4px; }
.vcrlogin p { margin: 6px 0; }
.resetov { position: fixed; inset: 0; z-index: 1000; background: var(--bg); display: grid; place-items: start center; padding: 15vh 16px 0; }
.resetov .card { max-width: 560px; padding: 24px; }

/* 0.1.77: spectral summary as a table */
.specsum p { margin: 0; }
.sumtbl { width: 100%; border-collapse: collapse; font-size: 14px; }
.sumtbl th { text-align: left; font-weight: 600; white-space: nowrap; padding: 4px 16px 4px 0; vertical-align: top; width: 1%; }
.sumtbl td { padding: 4px 0; }
.sumtbl tr + tr th, .sumtbl tr + tr td { border-top: 1px solid color-mix(in srgb, var(--accent) 18%, transparent); }
@media (max-width: 560px) { .sumtbl th { white-space: normal; width: 40%; } }

/* 0.1.78: findings coloured green (quiet) → red (noisy), first column only */
:root { --sev0: #1f8a4c; --sev1: #7cb342; --sev2: #e0b100; --sev3: #ef7d22; --sev4: #d03a2b; --sev1t: #4f7f1f; --sev2t: #9a7400; }
.sumtbl { border: 1px solid var(--line); border-radius: 8px; overflow: hidden; border-collapse: separate; border-spacing: 0; }
.sumtbl th, .sumtbl td { padding: 7px 12px; }
.sumtbl tr + tr th, .sumtbl tr + tr td { border-top: 1px solid var(--line); }
.sumtbl th.sev0 { background: var(--sev0); color: #fff; }
.sumtbl th.sev1 { background: var(--sev1); color: #10210a; }
.sumtbl th.sev2 { background: var(--sev2); color: #2a2000; }
.sumtbl th.sev3 { background: var(--sev3); color: #2a1300; }
.sumtbl th.sev4 { background: var(--sev4); color: #fff; }
.sumnote { margin: 6px 2px 0; }
@media print { .sumtbl th { -webkit-print-color-adjust: exact; print-color-adjust: exact; } }

/* 0.1.80: the sub-band table's verdicts wrap inside the page instead of running past its edge */
#specTbl td, .report .spectbl td { vertical-align: top; }
#specTbl td:last-child, .report .spectbl td:last-child { white-space: normal; min-width: 16em; overflow-wrap: anywhere; }
.report .spectbl td:not(:last-child), .report .spectbl th:not(:last-child) { white-space: nowrap; }

/* 0.1.81: Live analysis */
.anahead { margin: 0 0 10px; font-size: 15px; }
.anarows { display: grid; gap: 8px; }
.anarow { display: grid; grid-template-columns: 74px minmax(120px, 260px) 1fr; gap: 12px; align-items: center; }
.anarow.now .anafsb { font-weight: 700; }
.anafsb { font-weight: 600; white-space: nowrap; }
.nowtag { font-size: 11px; font-weight: 600; color: #fff; background: var(--accent); border-radius: 6px; padding: 1px 5px; margin-left: 2px; }
.anameter { position: relative; height: 12px; border-radius: 6px; background: var(--grid); overflow: hidden; }
.anameter > span { position: absolute; left: 0; top: 0; bottom: 0; border-radius: 6px; }
.anameter > i { position: absolute; top: 0; bottom: 0; width: 1px; background: color-mix(in srgb, var(--ink) 25%, transparent); }
.sev0b { background: var(--sev0); } .sev1b { background: var(--sev1); } .sev2b { background: var(--sev2); } .sev3b { background: var(--sev3); } .sev4b { background: var(--sev4); }
.sevt0 { color: var(--sev0); } .sevt1 { color: var(--sev0); } .sevt2 { color: var(--sev2t); } .sevt3 { color: var(--sev3); } .sevt4 { color: var(--sev4); }
.anatext { font-size: 13px; }
.anakey { margin: 10px 0 0; }
@media (max-width: 640px) { .anarow { grid-template-columns: 64px 1fr; } .anatext { grid-column: 1 / -1; } }
#anaInfo { margin: 0 4px; vertical-align: -3px; font-size: 13px; }

/* 0.1.87: consolidated scan and report */
.comboinfo { max-width: 760px; }
.comboinfo h4 { margin: 14px 0 4px; font-size: 14px; }
.comboinfo p, .comboinfo li { font-size: 14px; line-height: 1.45; }
.comboinfo ol, .comboinfo ul { padding-left: 22px; margin: 4px 0; }
.combomin { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; font-weight: 600; }
.combofsbs { border: 1px solid var(--line); border-radius: 8px; padding: 8px 12px; margin: 10px 0; max-width: 560px; }
.combofsbs legend { font-weight: 600; padding: 0 4px; }
.fsbchecks { display: grid; grid-template-columns: repeat(4, minmax(90px, 1fr)); gap: 6px 12px; }
@media (max-width: 520px) { .fsbchecks { grid-template-columns: repeat(2, 1fr); } }
.fsbcheck { display: flex; gap: 6px; align-items: center; }
.fsbcheck.fsball { grid-column: 1 / -1; font-weight: 600; }   /* 0.1.89: "All" on its own row, above FSB 1-8 */
.linkbtn { background: none; border: 0; padding: 0; color: var(--accent); cursor: pointer; font: inherit; text-decoration: underline; }
.comboest { font-weight: 600; }
.combonow { margin: 0 0 8px; }
/* 0.1.90: 30-second test runs; the consolidated scan's live spectral card */
.testwarn { color: var(--bad, #c0392b); font-weight: 600; margin: 4px 0 8px; }
.testbanner { border: 2px solid var(--bad, #c0392b); color: var(--bad, #c0392b); border-radius: 8px; padding: 8px 12px;
  font-weight: 700; margin: 8px 0 12px; }
.csph { font-size: 13px; margin: 10px 0 4px; }
#cspOcc, #cspFloor { width: 100%; }
.cspverdicts { display: flex; flex-wrap: wrap; gap: 6px; margin: 10px 0 6px; }
.cspv { border: 1px solid var(--line); border-radius: 6px; padding: 3px 8px; font-size: 12px; display: inline-flex; gap: 6px; align-items: center; }
.cspv i { width: 10px; height: 10px; border-radius: 2px; display: inline-block; }
.combosteps { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 10px; }
.combostep { border: 1px solid var(--line); border-radius: 6px; padding: 3px 8px; font-size: 12px; color: var(--muted); }
.combostep.done { color: var(--sev0); border-color: color-mix(in srgb, var(--sev0) 40%, transparent); }
.combostep.now { color: var(--ink); border-color: var(--accent); background: color-mix(in srgb, var(--accent) 10%, transparent); }
#comboDlg { max-width: 760px; width: calc(100% - 32px); }
#comboTbl td.row { display: flex; gap: 6px; }
/* 0.1.96: sign-in in progress */
.signbusy { display: flex; align-items: center; gap: 8px; }
.signbusy[hidden] { display: none; }
.spin { flex: none; width: 14px; height: 14px; border-radius: 50%; border: 2px solid var(--line);
  border-top-color: var(--accent); animation: spin 0.8s linear infinite; }
@keyframes spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .spin { animation-duration: 2.5s; } }
/* 0.1.94: sign-in gate */
.gate { position: fixed; inset: 0; z-index: 50; background: var(--bg); display: flex; align-items: flex-start;
  justify-content: center; padding: 8vh 16px 16px; overflow: auto; }
.gatecard { width: 100%; max-width: 420px; display: flex; flex-direction: column; gap: 10px; }
.gatecard h1 { font-size: 20px; margin: 4px 0 0; }
.gatecard label { display: flex; flex-direction: column; gap: 4px; font-size: 14px; }
.gatecard input { font: inherit; padding: 8px 10px; border: 1px solid var(--line); border-radius: 6px; }
/* 0.1.93: consolidated summary: the FSB cell split in two colours (spectral scan left, LoRaWAN scan right) */
.sumtbl th.splitsev { text-align: center; -webkit-print-color-adjust: exact; print-color-adjust: exact; }
.sumtbl th.splitsev span { background: rgba(255, 255, 255, 0.88); color: #111; border-radius: 4px; padding: 1px 6px; }
.splitkey { margin: 8px 0 0; }
.splitdemo { display: inline-flex; vertical-align: -2px; margin-right: 4px; -webkit-print-color-adjust: exact; print-color-adjust: exact; }
.splitdemo i { display: inline-block; width: 9px; height: 12px; }
.splitdemo i:first-child { border-radius: 2px 0 0 2px; } .splitdemo i:last-child { border-radius: 0 2px 2px 0; }
