/* The console's look: its tokens, then each part ui.js builds, then the screens. Dark first.
   Gold is the customer's own figures and marks and Theasi's logo alone, never a button, a
   status, a note or decoration; green and red are status; a soft red marks a button that
   removes something; slate blue is people's initials; no amber. One typeface, in sentence
   case, never spaced out or in capitals, with figures of even width; and what an assistant is
   told, shown as sent, in the system's monospace. No font file is loaded: each stack falls back
   to the system's own. Motion is short, and none when
   the system asks for less. */

/* Tokens */

:root {
  color-scheme: dark;

  /* Colours: the live page's, and a few between them */
  --page: #0B0B0E;
  --bar: #0F0F13;
  --surface: #131317;
  --raised: #1B1B21;
  --hover: #23232B;
  --hair: #26262E;
  --hair-2: #34343F;
  --text: #EDEDF2;
  --text-2: #B9B9C6;
  --muted: #8A8A99;
  --gold: #EDBF72;
  --good: #22C55E;
  --good-ink: #04210F;
  --good-soft: rgba(34, 197, 94, .14);
  --bad: #DC2626;
  --bad-ink: #FFFFFF;
  --bad-text: #F87171;
  --remove: rgba(220, 38, 38, .14);
  --remove-hover: rgba(220, 38, 38, .24);
  --remove-ink: #F87171;
  --slate: #5B6B8C;
  --slate-ink: #FFFFFF;
  --focus: #EDEDF2;
  --scrim: rgba(5, 5, 7, .72);
  --shadow: 0 16px 40px rgba(0, 0, 0, .5);

  /* Type */
  --font: "Instrument Sans", ui-sans-serif, system-ui, sans-serif;
  --mono: ui-monospace, "SF Mono", SFMono-Regular, Menlo, "Cascadia Mono", "Roboto Mono", Consolas,
    monospace;
  --t-1: 12px;
  --t-2: 13px;
  --t-3: 14px;
  --t-4: 16px;
  --t-5: 20px;
  --t-6: 24px;
  --t-7: 32px;

  /* Space */
  --s-1: 4px;
  --s-2: 8px;
  --s-3: 12px;
  --s-4: 16px;
  --s-5: 24px;
  --s-6: 32px;
  --s-7: 48px;

  /* Radii */
  --r-1: 4px;
  --r-2: 6px;
  --r-3: 10px;
  --r-full: 999px;

  /* Sizes */
  --bar-h: 56px;
  --control: 34px;
  --row: 40px;

  /* Motion */
  --ease: cubic-bezier(.2, .7, .2, 1);
  --quick: 120ms;
  --calm: 200ms;
}

/* A finger needs a larger target than a pointer. */
@media (pointer: coarse) {
  :root {
    --control: 44px;
    --row: 44px;
  }
}

/* Base */

*, *::before, *::after { box-sizing: border-box; }
[hidden] { display: none !important; }
html { background: var(--page); -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }
body {
  margin: 0;
  min-height: 100vh;
  background: var(--page);
  color: var(--text);
  font: 400 var(--t-3)/1.5 var(--font);
  font-variant-numeric: tabular-nums;
  -webkit-font-smoothing: antialiased;
}
h1, h2, h3, p, dl, dd, ol, ul { margin: 0; }
h1 { font: 600 var(--t-6)/1.25 var(--font); letter-spacing: -.01em; }
h2 { font: 600 var(--t-4)/1.3 var(--font); }
a { color: inherit; }
button, input { font: inherit; color: inherit; }
:focus { outline: none; }
:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }
/* A title the page moves focus to, for screen readers, is not something to press. */
[tabindex="-1"]:focus-visible { outline: none; }
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}
.icon {
  width: 16px;
  height: 16px;
  flex: none;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.5;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.mark { display: block; width: auto; max-width: 100%; }
.noscript { padding: var(--s-6); text-align: center; color: var(--text-2); }

/* Top bar */

.topbar {
  position: sticky;
  top: 0;
  z-index: 10;
  display: flex;
  align-items: center;
  gap: var(--s-6);
  height: var(--bar-h);
  padding: 0 var(--s-5);
  background: var(--bar);
  border-bottom: 1px solid var(--hair);
}
.home { display: flex; align-items: center; flex: none; border-radius: var(--r-2); }
.home .mark { height: 36px; }
.tabs { display: flex; align-self: stretch; gap: var(--s-1); }
.tab {
  display: flex;
  align-items: center;
  gap: var(--s-2);
  padding: 0 var(--s-3);
  margin-bottom: -1px;
  border-bottom: 2px solid transparent;
  color: var(--text-2);
  font: 500 var(--t-3)/1 var(--font);
  text-decoration: none;
  transition: color var(--quick) var(--ease), border-color var(--quick) var(--ease);
}
.tab:hover { color: var(--text); }
.tab[aria-current="page"] { color: var(--text); border-bottom-color: var(--text); }
.tab:focus-visible { outline-offset: -4px; border-radius: var(--r-2); }
.topbar-end { display: flex; align-items: center; gap: var(--s-3); margin-left: auto; min-width: 0; }
.account-name {
  overflow: hidden;
  color: var(--text-2);
  font: 500 var(--t-2)/1 var(--font);
  text-overflow: ellipsis;
  white-space: nowrap;
}
.account-button {
  display: flex;
  padding: 2px;
  border: 0;
  border-radius: var(--r-full);
  background: none;
  cursor: pointer;
}
.account-button:hover .initials, .account-button[aria-expanded="true"] .initials {
  box-shadow: 0 0 0 2px var(--hair-2);
}
.btn.skip { position: absolute; z-index: 20; top: -100px; left: var(--s-4); }
.btn.skip:focus-visible { top: var(--s-2); }

/* Buttons */

.btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--s-2);
  min-height: var(--control);
  padding: 0 14px;
  border: 1px solid transparent;
  border-radius: var(--r-2);
  background: transparent;
  color: var(--text);
  font: 500 var(--t-2)/1 var(--font);
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  transition: background-color var(--quick) var(--ease), border-color var(--quick) var(--ease),
    color var(--quick) var(--ease);
}
.btn.primary { background: var(--text); color: var(--page); }
.btn.secondary { background: var(--raised); border-color: var(--hair-2); }
.btn.quiet { color: var(--text-2); }
.btn.remove { background: var(--remove); color: var(--remove-ink); }
.btn.wide { width: 100%; }
.btn.bare { width: var(--control); padding: 0; }
.btn:not([aria-disabled="true"], :disabled).primary:hover { background: #FFFFFF; }
.btn:not([aria-disabled="true"], :disabled).secondary:hover { background: var(--hover); }
.btn:not([aria-disabled="true"], :disabled).quiet:hover { background: var(--raised); color: var(--text); }
.btn:not([aria-disabled="true"], :disabled).remove:hover { background: var(--remove-hover); }
/* Not usable yet, or waiting: the same plain look for every kind. */
.btn[aria-disabled="true"], .btn:disabled {
  background: var(--raised);
  border-color: var(--hair);
  color: var(--muted);
  cursor: not-allowed;
}
.btn[aria-busy="true"] { cursor: progress; }
/* Why a button cannot be used yet, on hover or focus. Anchored to its right edge, so it never
   reaches past the screen's. */
.btn[data-reason]:hover::after, .btn[data-reason]:focus-visible::after {
  content: attr(data-reason);
  position: absolute;
  z-index: 20;
  top: calc(100% + 6px);
  right: 0;
  padding: 5px 8px;
  border: 1px solid var(--hair-2);
  border-radius: var(--r-1);
  background: var(--raised);
  color: var(--text);
  font: 500 var(--t-1)/1.3 var(--font);
  white-space: nowrap;
  pointer-events: none;
}
.spinner {
  width: 14px;
  height: 14px;
  flex: none;
  border: 2px solid currentColor;
  border-right-color: transparent;
  border-radius: var(--r-full);
  animation: spin .8s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

/* Inputs */

.field { display: grid; gap: 6px; }
.field label { color: var(--text-2); font: 500 var(--t-2)/1.3 var(--font); }
.input {
  width: 100%;
  min-height: var(--control);
  padding: 0 10px;
  border: 1px solid var(--hair-2);
  border-radius: var(--r-2);
  background: var(--raised);
  color: var(--text);
  font: 400 var(--t-3)/1 var(--font);
  transition: border-color var(--quick) var(--ease);
}
.input::placeholder { color: var(--muted); }
.input:hover { border-color: #44444F; }
.input:focus-visible { outline-offset: 1px; }
.field-hint { color: var(--muted); font-size: var(--t-1); }
.field-head { display: flex; justify-content: space-between; align-items: center; gap: var(--s-3); }
.file-template { display: inline-flex; align-items: center; gap: 6px; color: var(--text-2); font-size: var(--t-1); text-decoration: none; }
.file-template:hover { color: var(--text); }
.file-template .icon { width: 14px; height: 14px; }
/* The browser's own button, inset evenly in the box. */
.file-input { min-height: 0; padding: 4px; line-height: normal; cursor: pointer; }
.file-input::file-selector-button { margin-right: 10px; cursor: pointer; }
.field-error { color: var(--bad-text); font-size: var(--t-1); }
.field.invalid .input { border-color: var(--bad); }

/* Tables */

.table-wrap {
  overflow-x: auto;
  border: 1px solid var(--hair);
  border-radius: var(--r-3);
  background: var(--surface);
}
.table { width: 100%; border-collapse: collapse; }
.table th {
  padding: 10px 14px;
  border-bottom: 1px solid var(--hair);
  color: var(--muted);
  font: 500 var(--t-1)/1.2 var(--font);
  text-align: left;
  white-space: nowrap;
}
.table td {
  height: var(--row);
  padding: 0 14px;
  border-top: 1px solid var(--hair);
  white-space: nowrap;
}
.table tbody tr:first-child td { border-top: 0; }
.table tbody tr:hover td { background: rgba(255, 255, 255, .02); }
.table .end { text-align: right; }
.table .dim { color: var(--text-2); }
.table-none { position: sticky; left: 0; width: 100%; }
.table:has(tbody:empty) th { border-bottom: 0; }
.table:has(tbody:empty) + .table-none { border-top: 1px solid var(--hair); }

/* Status and figures */

.chip {
  display: inline-flex;
  align-items: center;
  height: 20px;
  padding: 0 7px;
  border-radius: var(--r-1);
  font: 600 var(--t-1)/1 var(--font);
  white-space: nowrap;
}
.chip.ok { background: var(--good); color: var(--good-ink); }
.chip.empty, .chip.untested { background: var(--bad); color: var(--bad-ink); }
/* An Empty chip is never the empty-state block, whose class it shares a name with. */
.chip.empty { display: inline-flex; gap: 0; padding: 0 7px; text-align: left; justify-items: normal; }
.chip.silent { color: var(--text-2); box-shadow: inset 0 0 0 1px var(--hair-2); }
.chip.notread { color: var(--text-2); border: 1px dashed var(--hair-2); }
.figure, .table .figure { color: var(--gold); font-weight: 600; }

/* Panels */

.panel { border: 1px solid var(--hair); border-radius: var(--r-3); background: var(--surface); }
.panel.floating { box-shadow: var(--shadow); animation: rise var(--calm) var(--ease) both; }
.panel-head {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  padding: var(--s-3) var(--s-4);
  border-bottom: 1px solid var(--hair);
}
.panel-title { margin-right: auto; font: 600 var(--t-3)/1.4 var(--font); }
.panel-actions { display: flex; gap: var(--s-2); }
.panel-body { padding: var(--s-4); }
.panel-foot {
  display: flex;
  justify-content: flex-end;
  gap: var(--s-2);
  padding: var(--s-3) var(--s-4);
  border-top: 1px solid var(--hair);
}
@keyframes rise { from { opacity: 0; transform: translateY(6px); } }

.page-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s-3) var(--s-4);
  min-height: var(--control);
  margin-bottom: var(--s-4);
}
.page-title { margin-right: auto; }
.page-actions { display: flex; flex-wrap: wrap; gap: var(--s-2); }

/* Empty states */

.empty {
  display: grid;
  justify-items: center;
  gap: var(--s-2);
  padding: var(--s-7) var(--s-5);
  text-align: center;
}
.empty-icon {
  display: grid;
  place-items: center;
  width: 40px;
  height: 40px;
  margin-bottom: var(--s-2);
  border-radius: var(--r-3);
  background: var(--raised);
  box-shadow: inset 0 0 0 1px var(--hair);
  color: var(--text-2);
}
.empty-icon .icon { width: 20px; height: 20px; }
.empty-title { font: 600 var(--t-4)/1.3 var(--font); }
.empty-text { max-width: 44ch; color: var(--text-2); text-wrap: balance; }
.empty-actions { display: flex; flex-wrap: wrap; justify-content: center; gap: var(--s-2); margin-top: var(--s-3); }
.empty-note { color: var(--muted); font-size: var(--t-1); }

/* Terms and values, and steps */

.facts {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: var(--s-2) var(--s-4);
  padding: var(--s-3) var(--s-4);
  border: 1px solid var(--hair);
  border-radius: var(--r-2);
  background: var(--raised);
}
.facts dt { color: var(--muted); }
.facts dd { text-align: right; overflow-wrap: anywhere; }

.steps { display: flex; gap: var(--s-2); padding: 0; list-style: none; }
.step {
  display: grid;
  flex: 1;
  gap: 6px;
  color: var(--muted);
  font: 500 var(--t-1)/1.3 var(--font);
}
.step::before {
  content: "";
  height: 2px;
  border-radius: 2px;
  background: var(--hair-2);
  transition: background-color var(--calm) var(--ease);
}
.step.done, .step[aria-current="step"] { color: var(--text); }
.step.done::before, .step[aria-current="step"]::before { background: var(--text); }

/* People */

.initials {
  display: inline-grid;
  place-items: center;
  flex: none;
  width: 28px;
  height: 28px;
  border-radius: var(--r-full);
  background: var(--slate);
  color: var(--slate-ink);
  font: 600 11px/1 var(--font);
  transition: box-shadow var(--quick) var(--ease);
}
.initials.large { width: 36px; height: 36px; font-size: var(--t-2); }

/* A panel shown below its button */

.pop-anchor { position: relative; }
.pop {
  position: absolute;
  z-index: 30;
  top: calc(100% + 8px);
  right: 0;
  display: grid;
  gap: var(--s-3);
  width: 288px;
  max-width: calc(100vw - 2 * var(--s-4));
  padding: var(--s-3);
  border: 1px solid var(--hair-2);
  border-radius: var(--r-3);
  background: var(--surface);
  box-shadow: var(--shadow);
  animation: rise var(--quick) var(--ease) both;
}
.pop-head { display: flex; align-items: center; gap: var(--s-3); padding: var(--s-1); }
.pop-who { min-width: 0; }
.pop-who strong { display: block; font-weight: 600; }
.pop-who span {
  display: block;
  overflow: hidden;
  color: var(--text-2);
  font-size: var(--t-2);
  text-overflow: ellipsis;
  white-space: nowrap;
}
.pop .facts { font-size: var(--t-2); }
.pop .facts dd { white-space: nowrap; }
.pop-actions { display: grid; gap: var(--s-1); }
.pop-actions .btn { justify-content: flex-start; }

/* Notices */

.toasts {
  position: fixed;
  z-index: 50;
  right: var(--s-5);
  bottom: var(--s-5);
  display: grid;
  gap: var(--s-2);
  width: min(380px, calc(100vw - 2 * var(--s-4)));
  pointer-events: none;
}
.toast {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  padding: 6px 6px 6px 14px;
  border: 1px solid var(--hair-2);
  border-radius: var(--r-3);
  background: var(--raised);
  box-shadow: var(--shadow);
  pointer-events: auto;
  animation: rise var(--calm) var(--ease) both;
}
.toast.good > .icon { color: var(--good); }
.toast.bad > .icon { color: var(--bad-text); }
.toast.info > .icon { color: var(--text-2); }
.toast-text { flex: 1; padding: 6px 0; }
.toast.leaving { animation: sink var(--quick) ease-in both; }
@keyframes sink { to { opacity: 0; transform: translateY(4px); } }

/* Dialogs */

.dialog {
  width: min(460px, calc(100vw - 2 * var(--s-4)));
  max-height: calc(100vh - 2 * var(--s-4));
  padding: 0;
  border: 1px solid var(--hair-2);
  border-radius: var(--r-3);
  background: var(--surface);
  color: var(--text);
  box-shadow: 0 24px 64px rgba(0, 0, 0, .6);
}
.dialog[open] { animation: rise var(--calm) var(--ease) both; }
.dialog::backdrop { background: var(--scrim); }
.dialog[open]::backdrop { animation: fade var(--calm) var(--ease) both; }
@keyframes fade { from { opacity: 0; } }
.dialog-head { display: flex; align-items: center; gap: var(--s-3); padding: var(--s-3) var(--s-3) var(--s-2) var(--s-5); }
.dialog-head h2 { margin-right: auto; }
.dialog-body { display: grid; gap: var(--s-3); padding: 0 var(--s-5) var(--s-5); color: var(--text-2); }
.dialog-foot {
  display: flex;
  justify-content: flex-end;
  gap: var(--s-2);
  padding: var(--s-3) var(--s-4);
  border-top: 1px solid var(--hair);
}

/* Add site: beside the map, which still shows the place picked. */
.dialog.side {
  width: min(420px, calc(100vw - 2 * var(--s-4)));
  margin: calc(var(--bar-h) + var(--s-4)) auto auto var(--s-4);
}
.dialog.side::backdrop { background: rgba(5, 5, 7, .35); }
.found {
  margin-top: var(--s-1);
  padding: 0;
  overflow: hidden;
  border: 1px solid var(--hair-2);
  border-radius: var(--r-2);
  background: var(--raised);
  list-style: none;
}
.found-row { display: grid; gap: 1px; padding: var(--s-2) var(--s-3); line-height: 1.3; cursor: pointer; }
.found-row + .found-row { border-top: 1px solid var(--hair); }
.found-row[aria-selected="true"], .found-row:hover { background: var(--hover); }
.picked .facts { font-size: var(--t-2); }
.form-problem { color: var(--bad-text); }

/* Signing in, joining and recovering */

.entry {
  display: grid;
  align-content: center;
  justify-items: center;
  gap: var(--s-6);
  min-height: 100vh;
  padding: var(--s-7) var(--s-4);
}
.entry-mark .mark { height: 128px; }
.entry-card {
  display: grid;
  gap: var(--s-4);
  width: min(420px, 100%);
  padding: var(--s-6);
  border: 1px solid var(--hair);
  border-radius: var(--r-3);
  background: var(--surface);
  animation: rise var(--calm) var(--ease) both;
}
.entry-card h1 { font-size: var(--t-5); }
.entry-lead { display: flex; align-items: center; gap: var(--s-2); color: var(--text-2); }
.entry-note { color: var(--text-2); font-size: var(--t-2); }
.entry-quiet { color: var(--muted); font-size: var(--t-2); }
.entry-problem { color: var(--bad-text); font-weight: 500; }
.entry-foot { display: grid; gap: var(--s-1); padding-top: var(--s-2); border-top: 1px solid var(--hair); color: var(--muted); font-size: var(--t-2); }
.entry-done {
  display: grid;
  place-items: center;
  width: 40px;
  height: 40px;
  border-radius: var(--r-full);
  background: var(--good-soft);
  color: var(--good);
}
.entry-done .icon { width: 20px; height: 20px; stroke-width: 2; }

/* The console's screens */

.main { padding: var(--s-5); }

/* Map, Sites and a site's page: panels over the one map of the account's sites, which fills
   what is below the bar. Until it is drawn, or where it cannot be, a plain background. The
   map is pointed at through the gaps between panels; a panel scrolls within itself. */
.stage.mapped { position: relative; height: calc(100vh - var(--bar-h)); overflow: hidden; }
.backdrop {
  position: absolute;
  inset: 0;
  z-index: 0;
  background-color: #0D0D11;
  background-image:
    linear-gradient(rgba(255, 255, 255, .025) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255, 255, 255, .025) 1px, transparent 1px);
  background-size: 64px 64px;
}
.backdrop .map-holder { position: absolute; inset: 0; min-height: 0; background: none; }
.backdrop .map-unavailable {
  position: absolute;
  right: var(--s-4);
  bottom: var(--s-3);
  padding: 0;
  color: var(--muted);
  font: 500 var(--t-2)/1.4 var(--font);
}
.stage.mapped .main {
  position: absolute;
  inset: 0;
  z-index: 1;
  display: flex;
  align-items: flex-start;
  gap: var(--s-4);
  padding: var(--s-4);
  pointer-events: none;
}
.float {
  max-height: 100%;
  overflow: auto;
  overscroll-behavior: contain;
  border-radius: var(--r-3);
  box-shadow: var(--shadow);
  pointer-events: auto;
  animation: rise var(--calm) var(--ease) both;
}
.float.side { width: 360px; flex: none; }
.float.side.end { margin-left: auto; }
.float.side .panel-body { padding: var(--s-1) var(--s-4); }
.float.side .panel-body > .empty { padding: var(--s-6) var(--s-3); }
/* An alert's time below what it is, in a panel this narrow. */
.float.side .alert-link { grid-template-columns: 76px minmax(0, 1fr); }
.float.side .alert-when { grid-column: 2; justify-items: start; }
.float.column, .site.float {
  padding: var(--s-4) var(--s-5) var(--s-5);
  border: 1px solid var(--hair);
  background: var(--bar);
}
.float.column { width: min(960px, 66%); }
.site.float { width: min(880px, 62%); }

/* A panel over the map folds to a slim bar, its title and its counts, so the map behind it can be
   used; a click on the bar, or its button, opens it again. Its button to fold it sits at the
   right of its head. */
.fold-head { display: flex; align-items: flex-start; gap: var(--s-2); }
.fold-head > :first-child { flex: 1; min-width: 0; }
.fold-bar { display: none; }
.float.folded {
  width: auto;
  max-width: min(560px, 100%);
  padding: 0;
  overflow: hidden;
  border: 0;
  background: none;
}
.float.folded > :not(.fold-bar) { display: none !important; }
.float.folded > .fold-bar {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  padding: var(--s-1) var(--s-1) var(--s-1) var(--s-4);
  border: 1px solid var(--hair);
  border-radius: var(--r-3);
  background: var(--bar);
  cursor: pointer;
}
.fold-title {
  flex: none;
  max-width: 24ch;
  overflow: hidden;
  font: 600 var(--t-3)/1.3 var(--font);
  text-overflow: ellipsis;
  white-space: nowrap;
}
.fold-counts {
  min-width: 0;
  overflow: hidden;
  color: var(--text-2);
  font-size: var(--t-2);
  text-overflow: ellipsis;
  white-space: nowrap;
}
.fold-counts .chips { margin-right: var(--s-2); vertical-align: middle; }
.fold-bar .fold-button { margin-left: auto; }
.fold-bar:hover .fold-button { background: var(--raised); color: var(--text); }

/* Counts the cloud gave, each the customer's own figure. */
.metrics {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 1px;
  margin-bottom: var(--s-4);
  overflow: hidden;
  border: 1px solid var(--hair);
  border-radius: var(--r-3);
  background: var(--hair);
}
.metric { display: grid; gap: 2px; padding: var(--s-3) var(--s-4); background: var(--surface); }
.metric dt { color: var(--muted); font: 500 var(--t-1)/1.3 var(--font); }
.metric dd { margin: 0; font: 600 var(--t-6)/1.15 var(--font); }

/* Signed readings as they arrive. */
.feed { display: grid; padding: 0; list-style: none; }
.feed-row + .feed-row { border-top: 1px solid var(--hair); }
.feed-row > .signal { padding: var(--s-2) 0; }
.feed-link {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: var(--s-3);
  padding: var(--s-2) 0;
  text-decoration: none;
  border-radius: var(--r-1);
}
.feed-link:hover .cell-main { text-decoration: underline; text-underline-offset: 3px; }
.feed-time { color: var(--text-2); font-size: var(--t-2); white-space: nowrap; }
.feed-what { display: grid; gap: 1px; min-width: 0; line-height: 1.3; }
.feed-what > span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.feed-count { font-weight: 600; text-align: right; white-space: nowrap; }

/* Lists and cells, on every screen that reads the account's data */

.dim { color: var(--text-2); }
.quiet-line { color: var(--muted); font-size: var(--t-2); }
.problem-line { color: var(--bad-text); }
.alerts-slot, .list-slot { margin-bottom: var(--s-4); }
.more { display: flex; justify-content: center; padding: var(--s-3) 0 0; }
.cell-stack, .cell-link { display: grid; justify-items: start; gap: 1px; line-height: 1.3; }
.cell-link { text-decoration: none; border-radius: var(--r-1); }
.cell-link:hover .cell-main { text-decoration: underline; text-underline-offset: 3px; }
.cell-main { color: var(--text); font-weight: 500; }
.cell-sub { color: var(--muted); font-size: var(--t-1); }
.cell-wrap { display: block; min-width: 14ch; max-width: 30ch; white-space: normal; line-height: 1.3; }
/* An address written out in full, on two lines at most, as a site's name and ID take: cut short
   past them where its cell is narrow, the whole on hover. */
.cell-address {
  display: -webkit-box;
  min-width: 16ch;
  max-width: 30ch;
  overflow: hidden;
  line-height: 1.3;
  white-space: normal;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  line-clamp: 2;
}
.table td .cell-stack, .table td .cell-link { padding: 6px 0; }
.table tr.gone td, .table tr.gone .cell-main { color: var(--muted); }
.chips { display: inline-flex; flex-wrap: wrap; gap: var(--s-1); }
.est { color: var(--text-2); font-size: var(--t-1); }
.fingerprint { color: var(--text-2); font-variant-numeric: tabular-nums; }
.signal { display: inline-flex; align-items: center; gap: 6px; color: var(--text-2); font-size: var(--t-2); }
.signal .dot { width: 6px; height: 6px; flex: none; border-radius: var(--r-full); background: var(--muted); }
.signal.good .dot { background: var(--good); }
.signal.bad { color: var(--bad-text); }
.signal.bad .dot { background: var(--bad); }

.alerts { display: grid; padding: 0; list-style: none; }
.alert + .alert { border-top: 1px solid var(--hair); }
.alert-link {
  display: grid;
  grid-template-columns: 76px minmax(0, 1fr) auto;
  align-items: center;
  gap: var(--s-3);
  padding: var(--s-2) 0;
  text-decoration: none;
}
.alert-link .chip { justify-self: start; }
.alert-link:hover .cell-main { text-decoration: underline; text-underline-offset: 3px; }
.alert-what, .alert-when { display: grid; gap: 1px; min-width: 0; line-height: 1.3; }
.alert-when { justify-items: end; color: var(--text-2); font-size: var(--t-2); white-space: nowrap; }
.alerts-slot .panel-body { padding: var(--s-1) var(--s-4); }

/* A checked fact: "Checked", and one click away what was verified, and where, opened in its
   own cell so no table's edge ever cuts it. */
.verified > summary { list-style: none; cursor: pointer; }
.verified > summary::-webkit-details-marker { display: none; }
.passed { display: inline-flex; align-items: center; gap: 6px; color: var(--good); font-size: var(--t-2); }
.badge-check { width: 14px; height: 14px; flex: none; }
.badge-check circle { fill: var(--good); }
.badge-check path {
  fill: none;
  stroke: var(--page);
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.verified-list {
  display: grid;
  grid-template-columns: auto auto;
  gap: 2px var(--s-3);
  margin: var(--s-2) 0 0;
  padding: var(--s-2) var(--s-3);
  border: 1px solid var(--hair);
  border-radius: var(--r-2);
  background: var(--raised);
  white-space: nowrap;
}
.verified-list dt { color: var(--muted); font-size: var(--t-2); }
.verified-list dd { display: flex; gap: var(--s-2); align-items: center; margin: 0; }
.verified-where { color: var(--muted); font-size: var(--t-1); }

/* A site's page */

.site-head { margin-bottom: var(--s-2); }
.site-head .page-head { align-items: flex-start; margin-bottom: 0; }
.site-title { display: grid; gap: 2px; margin-right: auto; min-width: 0; }
.back {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-bottom: var(--s-2);
  color: var(--text-2);
  font: 500 var(--t-2)/1.4 var(--font);
  text-decoration: none;
  border-radius: var(--r-1);
}
.back:hover { color: var(--text); }
.site-sub { color: var(--text-2); font-size: var(--t-2); }
.site-status { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-2) var(--s-3); margin-top: var(--s-3); }
.site-facts { color: var(--text-2); font-size: var(--t-2); }
.page-tabs {
  display: flex;
  gap: var(--s-1);
  margin-bottom: var(--s-4);
  overflow-x: auto;
  border-bottom: 1px solid var(--hair);
}
.page-tab {
  display: flex;
  align-items: center;
  height: 40px;
  padding: 0 var(--s-3);
  margin-bottom: -1px;
  border-bottom: 2px solid transparent;
  color: var(--text-2);
  font: 500 var(--t-3)/1 var(--font);
  text-decoration: none;
  white-space: nowrap;
  transition: color var(--quick) var(--ease), border-color var(--quick) var(--ease);
}
.page-tab:hover { color: var(--text); }
.page-tab[aria-current="page"] { color: var(--text); border-bottom-color: var(--text); }
.page-tab:focus-visible { outline-offset: -4px; border-radius: var(--r-2); }
.tab-slot { display: grid; gap: var(--s-3); }

/* Setting cameras up: a camera's zone and products, its one-time link as a QR code, and the
   links waiting at a site. A QR code is dark squares on a light ground, whatever the page around
   it, as a phone's camera reads one. */
.field-label { color: var(--text-2); font: 500 var(--t-2)/1.3 var(--font); }
.input:disabled { opacity: .6; }
select.input { padding-right: var(--s-2); }
.camera-form, .camera-forms, .link-state, .import-preview, .import-done { display: grid; gap: var(--s-3); }
.product-rows { display: grid; gap: var(--s-2); }
.product-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) 72px var(--control);
  gap: var(--s-2);
  align-items: center;
}
.camera-block { display: grid; gap: var(--s-2); padding-top: var(--s-3); border-top: 1px solid var(--hair); }
.block-title { margin: 0; color: var(--text); font: 600 var(--t-3)/1.3 var(--font); }
.block-head { display: flex; align-items: center; justify-content: space-between; gap: var(--s-3); }
.link-secret { display: grid; justify-items: center; gap: var(--s-2); }
.qr-frame { width: min(240px, 100%); }
.qr { display: block; width: 100%; height: auto; }
.qr-ground { fill: #FFFFFF; }
.qr-dark { fill: #000000; }
.link-copy { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: var(--s-2); width: 100%; }

/* Importing sites: the file's rows, each ready, needing a pick or with its errors. */
.dialog.wide { width: min(880px, calc(100vw - 2 * var(--s-4))); }
.import-summary { display: flex; flex-wrap: wrap; gap: var(--s-2) var(--s-4); }
.import-preview:empty { display: none; }
.import-preview .table-wrap { max-height: 50vh; overflow: auto; }
.import-state { display: grid; justify-items: start; gap: var(--s-1); white-space: normal; }
.import-state .cell-wrap { min-width: 0; }
.import-preview select.input { width: 100%; min-width: 0; max-width: 40ch; }

/* A QR pack: a sheet of paper, on the screen as in print, white with black ink. */
.pack-sheet {
  position: fixed;
  inset: 0;
  z-index: 30;
  overflow: auto;
  padding: var(--s-5);
  background: #FFFFFF;
  color: #000000;
  color-scheme: light;
}
.pack-tools { display: flex; flex-wrap: wrap; justify-content: space-between; gap: var(--s-3); margin-bottom: var(--s-5); }
.pack-title { display: grid; gap: var(--s-1); }
.pack-title .page-title, .pack-title p { margin: 0; color: #000000; }
.pack-actions { display: flex; flex-wrap: wrap; align-items: flex-start; gap: var(--s-2); }
.pack-sheet .btn.primary { background: #000000; color: #FFFFFF; }
.pack-sheet .btn.secondary { border-color: #000000; background: #FFFFFF; color: #000000; }
.pack-sheet .btn.remove { background: #FDECEC; color: #A61B1B; }
.pack-sheet .btn:focus-visible { outline-color: #000000; }
.pack-sheet .form-problem { color: #A61B1B; }
.pack-cards { display: grid; grid-template-columns: repeat(auto-fill, minmax(360px, 1fr)); gap: var(--s-4); }
.pack-card {
  display: grid;
  grid-template-columns: 136px minmax(0, 1fr);
  gap: var(--s-3);
  padding: var(--s-3);
  border: 1px solid #000000;
  border-radius: var(--r-2);
  break-inside: avoid;
}
.pack-label { display: grid; align-content: start; gap: var(--s-1); }
.pack-label h2 { margin: 0; font: 600 var(--t-4)/1.3 var(--font); overflow-wrap: anywhere; }
.pack-label p { margin: 0; font-size: var(--t-2); overflow-wrap: anywhere; }
.pack-zone, .pack-note { font-weight: 600; }
.pack-cancel { justify-self: start; }

@media print {
  html, body { background: #FFFFFF; color-scheme: light; }
  body > :not(.pack-sheet) { display: none !important; }
  .pack-sheet { position: static; padding: 0; overflow: visible; }
  .pack-tools, .pack-cancel { display: none; }
  .pack-cards { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 6mm; }
  @page { margin: 12mm; }
}

/* Routing: every site's tasks, a site's routing, the endpoints its events go to, and the tasks
   waiting for this member, counted on the Tasks tab in the status red. */
.metric-plain { color: var(--text); font-size: var(--t-5); }
/* A demo account's note, on every screen: plain, never a status colour or gold. */
.demo-note {
  padding: 2px 8px;
  border: 1px solid var(--hair-2);
  border-radius: var(--r-1);
  color: var(--text-2);
  font: 500 var(--t-1)/1.4 var(--font);
  white-space: nowrap;
}
.count-badge {
  display: inline-grid;
  place-items: center;
  min-width: 18px;
  height: 18px;
  padding: 0 5px;
  border-radius: var(--r-full);
  background: var(--bad);
  color: var(--bad-ink);
  font: 600 var(--t-1)/1 var(--font);
}
button.page-tab { border-top: 0; border-right: 0; border-left: 0; background: none; cursor: pointer; }
.row-actions { display: inline-flex; gap: var(--s-1); }
.routing-slot { margin-bottom: var(--s-3); }
.routing-slot .panel-body { padding: var(--s-2) var(--s-4); }
.endpoints { display: grid; padding: 0; list-style: none; }
.endpoint {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: var(--s-3);
  padding: var(--s-2) 0;
}
.endpoint + .endpoint { border-top: 1px solid var(--hair); }
.endpoint-url { overflow-wrap: anywhere; }
.connect { display: grid; gap: var(--s-4); }
.connect .panel-body { display: grid; gap: var(--s-3); }
.connect-address { display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: center; gap: var(--s-1) var(--s-2); }
.connect-address > .cell-sub { grid-column: 1 / -1; }
.key-list { display: grid; gap: var(--s-3); justify-items: start; }
.key-list > .endpoints, .key-list > .field { width: 100%; }
.endpoint-secret { display: grid; justify-items: start; gap: var(--s-2); }
.endpoint-key {
  display: block;
  width: 100%;
  padding: var(--s-2) var(--s-3);
  border: 1px solid var(--hair-2);
  border-radius: var(--r-2);
  background: var(--raised);
  overflow-wrap: anywhere;
  user-select: all;
}

/* Public AI answers: what an assistant is told of each published product, its attestation
   checked here, and the cloud's count of its replies today. Each term beside its value, read
   across in one line; the answer itself as sent, in the monospace. */
.answers { display: grid; gap: var(--s-3); }
.answers .panel .cell-sub { margin-bottom: var(--s-2); }
.answer-facts { grid-template-columns: minmax(7rem, 11rem) minmax(0, 1fr); }
.answer-facts dd { min-width: 0; text-align: left; }
.asked { overflow-wrap: anywhere; white-space: normal; }
.answer-told { margin-top: var(--s-4); }
.answer-told summary { color: var(--text-2); font-size: var(--t-2); cursor: pointer; }
.answer-json {
  margin: var(--s-2) 0 0;
  padding: var(--s-4) var(--s-5);
  overflow-x: auto;
  border: 1px solid var(--hair);
  border-radius: var(--r-2);
  background: var(--raised);
  color: var(--text-2);
  font: 400 var(--t-2)/1.7 var(--mono);
  font-variant-ligatures: none;
  tab-size: 2;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

/* Phones */

/* Sharing: what the account shares with other accounts, and what they share with it. A shared
   count is another account's figure, never the customer's own: in the text's colour, never gold,
   with figures of even width as the customer's own are. */
.page-lead { margin: 0 0 var(--s-4); color: var(--text-2); font-size: var(--t-3); }
.shares-slot { margin-bottom: var(--s-4); }
.shared-slot { margin-top: var(--s-4); }
.shared-figure { color: var(--text); font-weight: 600; font-variant-numeric: tabular-nums; }
.shared-note {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin: var(--s-3) 0 0;
  color: var(--text-2);
  font-size: var(--t-2);
}
.share-form { display: grid; gap: var(--s-3); }
.share-choice { display: grid; gap: var(--s-2); min-width: 0; margin: 0; padding: 0; border: 0; }
.share-products { max-height: 40vh; overflow: auto; }
.share-option { display: flex; align-items: center; gap: var(--s-2); min-height: 32px; cursor: pointer; }
.share-option input { width: 18px; height: 18px; margin: 0; accent-color: var(--text); }
.share-state { display: inline-flex; align-items: center; gap: var(--s-3); padding: var(--s-1) 0; }
.site-pick { display: grid; gap: var(--s-2); min-width: 0; padding-left: 26px; }
.site-list {
  display: grid;
  max-height: 216px;
  overflow: auto;
  padding: var(--s-1) var(--s-3);
  border: 1px solid var(--hair-2);
  border-radius: var(--r-2);
  background: var(--raised);
}
.site-list .share-option { min-height: 40px; }
.site-list .cell-main, .site-list .cell-sub { overflow-wrap: anywhere; }
.site-pick .btn { justify-self: start; }

/* A new request: its site picked as a share's is, its fields beneath. */
.request-form { display: grid; gap: var(--s-3); }
.request-form .site-pick { padding-left: 0; }

/* The verification report: its totals, then every row of the file, scrolled in its frame. */
.claims-report { min-width: 0; }
.claims-report:empty { display: none; }
.claims-report .metrics { margin-bottom: var(--s-2); }
.claims-report .table-wrap { max-height: 50vh; margin-top: var(--s-3); overflow: auto; }

@media (max-width: 760px) {
  .pack-sheet { padding: var(--s-4); }
  .pack-cards { grid-template-columns: minmax(0, 1fr); }
  .pack-card { grid-template-columns: 112px minmax(0, 1fr); }
  .topbar { flex-wrap: wrap; gap: 0 var(--s-3); height: auto; padding: 0 var(--s-4); }
  .home { height: 52px; }
  .home .mark { height: 26px; }
  .topbar-end { height: 52px; }
  .account-name { max-width: 40vw; }
  .tabs {
    order: 3;
    justify-content: space-between;
    width: calc(100% + 2 * var(--s-4));
    height: 44px;
    margin: 0 calc(-1 * var(--s-4));
    border-top: 1px solid var(--hair);
  }
  .tab { flex: 1; justify-content: center; padding: 0 var(--s-1); }
  .main { padding: var(--s-4); }
  .page-head .page-actions { width: 100%; }
  .page-head .page-actions .btn { flex: 1; }
  .alert-link { grid-template-columns: 76px minmax(0, 1fr); }
  .alert-when { grid-column: 2; justify-items: start; }
  .page-tab { flex: 1; justify-content: center; padding: 0 var(--s-1); }
  /* On a phone the panels take the screen, in the page's own scroll, and the map is a band
     above them, never under them: a panel over a map this narrow would hide it whole. */
  .stage.mapped { display: flex; flex-direction: column; height: auto; overflow: visible; }
  .stage.mapped .backdrop { position: relative; order: 0; height: 38vh; min-height: 220px; }
  /* No cursor to follow under a finger, and no room beside the scale and credits. */
  .backdrop .map-coordinates { display: none; }
  .stage.mapped .main { position: static; order: 1; display: block; padding: var(--s-4); pointer-events: auto; }
  .float { max-height: none; overflow: visible; box-shadow: none; animation: none; }
  .float + .float { margin-top: var(--s-4); }
  .float.side, .float.column, .site.float { width: auto; }
  .float.column, .site.float { padding: var(--s-4); }
  .metrics { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .dialog.side { margin: auto; }
  .toasts { right: var(--s-4); bottom: var(--s-4); left: var(--s-4); width: auto; }
  .entry { gap: var(--s-5); padding: var(--s-6) var(--s-4); }
  .entry-mark .mark { height: 104px; }
  .entry-card { padding: var(--s-5); }
  /* Folded on a phone, a panel is a slim bar below the map, its button to fold it at the top
     right of its head, over the line its actions leave free. With every panel of the screen
     folded, the map takes the screen between the top bar and those bars, its own controls still
     clear of them, and each bar peeks up from the foot, opening its panel upwards, as its arrow
     says. */
  .fold-head { position: relative; display: block; }
  .fold-head > .fold-button { position: absolute; top: 0; right: 0; }
  .fold-head .page-title, .fold-head .back { margin-right: calc(var(--control) + var(--s-2)); }
  .float.folded { max-width: none; padding: 0; }
  #app:has(.stage.mapped > .main > .float.folded):not(:has(.stage.mapped > .main > .float:not(.folded))) {
    display: flex;
    flex-direction: column;
    height: 100vh;
    height: 100dvh;
  }
  #app:has(.stage.mapped > .main > .float.folded):not(:has(.stage.mapped > .main > .float:not(.folded))) .stage.mapped { flex: 1; min-height: 0; overflow: hidden; }
  #app:has(.stage.mapped > .main > .float.folded):not(:has(.stage.mapped > .main > .float:not(.folded))) .stage.mapped .backdrop { flex: 1; height: auto; min-height: 0; }
  #app:has(.stage.mapped > .main > .float.folded):not(:has(.stage.mapped > .main > .float:not(.folded))) .stage.mapped .main { display: grid; gap: var(--s-2); padding: var(--s-2) var(--s-3) var(--s-3); }
  #app:has(.stage.mapped > .main > .float.folded):not(:has(.stage.mapped > .main > .float:not(.folded))) .float + .float { margin-top: 0; }
  #app:has(.stage.mapped > .main > .float.folded):not(:has(.stage.mapped > .main > .float:not(.folded))) .fold-bar .icon { transform: rotate(180deg); }
}

@media (max-width: 480px) {
  .dialog-foot { flex-direction: column-reverse; }
  .dialog-foot .btn { width: 100%; }
  .product-row { grid-template-columns: minmax(0, 1fr) 72px var(--control); }
  .product-row > :nth-child(2) { grid-column: 1 / -1; grid-row: 2; }
}

/* Less motion, when the system asks for it: nothing moves, and nothing fades. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0s !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0s !important;
    scroll-behavior: auto !important;
  }
}

/* The Operator screen: a checker chosen and given a check, side by side. */
.operator-assign { display: inline-flex; align-items: center; gap: 8px; }
.operator-assign select { width: 150px; }
