/* Tables. Density and scannability: sticky header, one line per row wherever a
   value has one spelling, counts on the right, and the WRAPPER scrolls so the
   page never does. */

.console-table {
  overflow-x: auto;
  border: 1px solid var(--console-rule-2);
  border-radius: var(--console-radius);
  /* ⚠️ THE EDGE SAYS THERE IS MORE. A scrollbar that only shows while a finger
     moves tells a phone nothing, so a shadow sits on the right edge while
     columns are hidden past it — and only then. The shadow is fixed to the box
     (`scroll`); the white that covers it is fixed to the end of the content
     (`local`), so it slides over the shadow exactly when the last column comes
     into view. A table that fits never shows it. No left shadow: the sticky
     column below is opaque and would hide it. */
  background:
    linear-gradient(to left, var(--console-surface) 40%, transparent) right center / 32px 100% no-repeat local,
    radial-gradient(farthest-side at 100% 50%, rgba(27, 26, 24, 0.16), transparent) right center / 12px 100% no-repeat scroll,
    var(--console-surface);
}

.console-table table { border-collapse: separate; border-spacing: 0; width: 100%; font-size: var(--console-text-sm); }

/* Each wide table declares the width it actually needs, or auto layout starves
   the flexible columns instead of handing the overflow to the wrapper.
   ⚠️ `table.` AND NOT THE BARE CLASS. `.console-leads` and `.console-conversions`
   are also the count cells of the contacts list (see the counts below), and
   unscoped these floors made each of those cells 1280px and 1240px wide — the
   contacts table near 3,800px on a desktop, its counts off the screen. */
.console-table table.console-payloads { min-width: 1240px; }
.console-table table.console-conversions { min-width: 1240px; }
.console-table table.console-intakes { min-width: 1260px; }
.console-table table.console-leads { min-width: 1280px; }
.console-table table.console-backlog { min-width: 1120px; }
.console-table table.console-accounts { min-width: 1080px; }
.console-table table.console-contacts { min-width: 980px; }
.console-table table.console-tripwire { min-width: 1000px; }
.console-table table.console-unjudged-keys { min-width: 760px; }
.console-table table.console-tokens { min-width: 860px; }
/* A Dispatch's attempts fit any desktop column, but on a phone their status
   note and response were squeezed to a word a line; the floor hands that
   overflow to the wrapper instead. */
.console-table table.console-attempts { min-width: 720px; }

.console-table thead th {
  position: sticky;
  top: 0;
  z-index: 1;
  background: var(--console-sunken);
  text-align: left;
  font-size: var(--console-label);
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--console-ink-3);
  padding: 9px var(--console-space-3);
  border-bottom: 1px solid var(--console-rule-3);
  white-space: nowrap;
}

.console-table tbody td {
  padding: 9px var(--console-space-3);
  border-bottom: 1px solid var(--console-rule);
  vertical-align: top;
  font-variant-numeric: tabular-nums;
}
.console-table tbody tr:last-child td { border-bottom: 0; }
.console-table tbody tr:hover { background: var(--console-hover); }

/* ⚠️ THE FIRST COLUMN STAYS WHERE THE EYE LEFT IT. Scrolled sideways on a phone,
   a row's later cells mean nothing without the cell that says whose row it is,
   so that cell sticks to the left edge and the rest pass under it. It must be
   opaque or the passing text shows through it, so it takes the row's surface —
   white, or the hover's ink while the row is hovered.
   ⚠️ `:where()` AND THE CHILD COMBINATORS ARE THE POINT. The child combinators
   keep it off a table nested in a cell (a Dispatch's plan steps, inside its
   attempts); `:where()` holds the rule at the weight of a bare `td:first-child`,
   so every highlight a cell already carries — `td.console-next-move-*`, an
   Unresolved contact, a token just issued, an ignored entry — still wins over
   the plain white, wherever it is declared. */
:where(.console-table > table > tbody > tr, .console-table > table > tfoot > tr) > :is(td, th):first-child {
  position: sticky;
  left: 0;
  background: var(--console-surface);
}
:where(.console-table > table > tbody > tr:hover) > :is(td, th):first-child { background: var(--console-hover); }
/* The header's own sticky rule above is heavier than `:where()`, so its corner
   is named in full; above the column and above the header row, both. */
.console-table > table > thead > tr > th:first-child { left: 0; z-index: 2; }

/* A selectable list's first column is a checkbox, which identifies nothing: the
   column after it sticks too, offset by the checkbox column's width (its 2rem
   plus a cell's padding either side — see `.console-select`). */
:where(.console-table > table > tbody > tr) > td.console-select + td,
.console-table > table > thead > tr > th.console-select + th {
  position: sticky;
  left: calc(2rem + 2 * var(--console-space-3));
}
:where(.console-table > table > tbody > tr) > td.console-select + td { background: var(--console-surface); }
:where(.console-table > table > tbody > tr:hover) > td.console-select + td { background: var(--console-hover); }
.console-table > table > thead > tr > th.console-select + th { z-index: 2; }
/* ⚠️ AND THE CHECKBOX COLUMN HOLDS THAT WIDTH. A table narrower than its
   content shrinks every column towards its narrowest, the checkbox's among
   them, and the offset above would then leave the column after it stuck a few
   pixels over its neighbour. */
.console-table > table > * > tr > .console-select { min-width: 2rem; }

/* ⚠️ A STICKY COLUMN AS WIDE AS THE SCREEN SCROLLS NOTHING INTO VIEW. An email
   held to one line is wider than a phone, and stuck to the left edge it covered
   the whole wrapper: scrolled sideways, the eye saw emails and only emails. So
   below the docked layout the identifying column is held to a measure that
   leaves the rest of the screen to the columns passing under it, and its text
   breaks inside the cell — an email over two lines is still one identifier in
   one row, where an ellipsis would hide the half that tells two apart.
   ⚠️ `width` AND NOT `max-width`: a table cell ignores `max-width`, and a fixed
   width is what auto layout honours and what it leaves out of the share of
   spare width the other columns get. `min-width` as well, or a table narrower
   than its content squeezes the column below the measure along with the rest.
   The measure still holds an instant on one line, when the first column is a
   time. Not on a row's position number, the one first column narrower than any
   measure, which the width would only widen. The child chain's weight is what
   puts this above the single-class `nowrap` the email and the Account name
   carry. */
@media (max-width: 1023px) {
  .console-table > table > :is(tbody, tfoot) > tr > :is(td, th):first-child:not(.console-select):not(.console-position),
  .console-table > table > tbody > tr > td.console-select + td {
    width: min(15rem, 45vw);
    min-width: min(15rem, 45vw);
    white-space: normal;
    overflow-wrap: anywhere;
  }
}

/* One spelling of an instant, in its Account's timezone, from the helper —
   styled, never reformatted. */
.console-received-at,
.console-observed-at,
.console-created-at,
.console-last-activity,
.console-last-seen-at,
.console-suspended-at,
.console-purged-at,
.console-oldest {
  font-family: var(--console-mono);
  font-size: var(--console-text-xs);
  white-space: nowrap;
}
.console-oldest { color: var(--console-ink); }

/* Counts read down the column. ⚠️ NOT `.console-leads` OR `.console-conversions`:
   those are the class of two whole tables as well as of the counts on the
   contacts list, and right-aligning them set every cell of both lists against
   its left-aligned header. ⚠️ And `td.` on the attempts: `.console-attempts` is
   also the whole table of a Dispatch's attempts, and right-aligned every cell
   of it — the response a ragged block against the right edge. */
td.console-attempts,
.console-readings,
.console-live-tokens,
.console-backlog-count,
.console-amount {
  text-align: right;
}
td.console-backlog-count { font-weight: 600; }
th.console-attempts, th.console-readings { text-align: right; }

/* ⚠️ `td.` on the anchor slot: on the Intake's page the same class is a
   sentence in a dd, and a sentence held to one line runs out of its box. */
.console-account,
.console-email,
.console-intake,
.console-source,
.console-method,
.console-surface,
.console-slug,
td.console-anchor-slot,
.console-creates-contacts,
.console-active,
.console-path {
  white-space: nowrap;
}
.console-account { color: var(--console-ink-2); }
.console-path, .console-method, .console-adapter-version { font-family: var(--console-mono); font-size: var(--console-text-xs); color: var(--console-ink-2); }
.console-payload-id { white-space: nowrap; }

/* A request whose path named no Account: shown because it arrived, italic
   because there is no Account behind it. */
.console-payloads td.console-account em { color: var(--console-ink-3); }

/* ============================================================
   ADR-0014's next move. FIVE OF THE THIRTEEN OUTCOMES ARE
   CORRECT AND FREQUENT, so four of these six classes carry no
   colour at all: quiet is the default and emphasis is spent
   only where somebody must act.
   ============================================================ */
td.console-outcome { min-width: 19rem; }
td.console-outcome code { background: transparent; border-color: transparent; padding-left: 0; font-weight: 600; }
.console-next-move { display: block; margin-top: 3px; font-size: var(--console-text-xs); opacity: 0.85; }

/* Calm — read correctly, or not yet read, or never work. */
td.console-next-move-pending,
td.console-next-move-suspended,
td.console-next-move-stored,
td.console-next-move-originated-nothing,
td.console-next-move-never-reprocessable {
  color: var(--console-ink-2);
}

/* Second strongest: a batch clears it. */
td.console-next-move-owes-a-batch {
  background: var(--console-batch-bg);
  box-shadow: inset 3px 0 0 var(--console-batch-edge);
  color: var(--console-batch-ink);
}

/* Strongest, and the only one: a person must decide something. */
td.console-next-move-owes-a-person {
  background: var(--console-person-bg);
  box-shadow: inset 3px 0 0 var(--console-person-edge);
  color: var(--console-person-ink);
  font-weight: 600;
}
td.console-next-move-owes-a-batch code,
td.console-next-move-owes-a-person code { color: inherit; }

/* A conversion that could have resolved and did not. UNATTRIBUTABLE IS NOT
   THIS: it is not waiting for anything, so it stays plain — see
   console-5-screens.css. */
.console-conversions tr.console-unresolved td.console-contact {
  background: var(--console-person-bg);
  box-shadow: inset 3px 0 0 var(--console-person-edge);
  color: var(--console-person-ink);
  font-size: 12.5px;
}

/* Standing on an Account row: a state, told in a chip, with no severity. */
td.console-status {
  font-variant-numeric: normal;
}
td.console-status::first-line { line-height: inherit; }
.console-accounts tr.console-account-active td.console-status,
.console-accounts tr.console-account-suspended td.console-status,
.console-accounts tr.console-account-purged td.console-status {
  white-space: nowrap;
}
.console-accounts tr.console-account-suspended td.console-name a,
.console-accounts tr.console-account-purged td.console-name a { color: var(--console-ink-2); border-bottom-color: rgba(74, 71, 64, 0.3); }
.console-accounts tr.console-account-purged { color: var(--console-ink-4); }

/* An Intake switched off is expected to be quiet; it recedes, it is not
   flagged. */
.console-intakes tr.console-intake-inactive { color: var(--console-ink-4); }
.console-intakes tr.console-intake-inactive td.console-name a { color: var(--console-ink-2); }
.console-intakes td.console-heard-from { min-width: 26rem; font-size: 12.5px; color: var(--console-ink-2); white-space: normal; }
/* Silence past an Intake's own ceiling owes a person a message. */
.console-intakes td.console-heard-from.console-silent {
  background: var(--console-batch-bg);
  box-shadow: inset 3px 0 0 var(--console-batch-edge);
  color: var(--console-batch-ink);
  font-weight: 600;
}

/* The contact timeline. A conversion is the row that carried money. */
.console-timeline tr.console-event-conversion td.console-kind {
  box-shadow: inset 3px 0 0 var(--console-link);
  color: #274c70;
  font-weight: 600;
}
/* The lines of a purchase's Order, one per product, inside its row. */
.console-order ul {
  margin: 0;
  padding: 0;
  list-style: none;
}
.console-order .console-amount {
  margin-left: var(--console-space-2);
  font-family: var(--console-mono);
  font-size: var(--console-text-xs);
}

.console-timeline .console-amount {
  display: inline-block;
  margin-left: var(--console-space-2);
  font-family: var(--console-mono);
  font-size: var(--console-text-xs);
  font-weight: 600;
}

/* Tokens. Live is the standing that matters; revoked is history and greys. */
.console-tokens tr.console-token-live td.console-standing {
  display: table-cell;
}
.console-tokens tr.console-token-live td.console-standing,
.console-accounts tr.console-account-active td.console-status {
  color: var(--console-good-ink);
  font-weight: 600;
}
.console-tokens tr.console-token-revoked { color: var(--console-ink-4); }
.console-tokens td.console-revoke { text-align: right; }

/* ============================================================
   The Relay context's tables — #45.
   ============================================================ */

/* A switched-off Relay still holds its Dispatches, so it stays on the list and
   greys rather than disappearing — the same reading a switched-off Intake gets. */
.console-relays tr.console-relay-inactive { color: var(--console-ink-4); }
.console-relays tr.console-relay-inactive td.console-name a { color: var(--console-ink-2); }

/* A URL is long and is read left to right; it wraps rather than widening the
   table past the screen. */
.console-relays td.console-request .console-url,
.console-dispatches td.console-request .console-url,
.console-exhausted-or-failed td.console-request .console-url {
  font-family: var(--console-mono);
  font-size: var(--console-text-xs);
  color: var(--console-ink-2);
  overflow-wrap: anywhere;
}

.console-relays td.console-conditions-count,
.console-relays td.console-dispatch-count,
.console-dispatches td.console-attempts,
.console-dispatches td.console-generation,
.console-exhausted-or-failed td.console-attempts,
.console-stale-versions td.console-generation {
  font-variant-numeric: tabular-nums;
  text-align: right;
}

/* ⚠️ DELIVERED IS THE ONLY GREEN, and the two that stopped are the person's
   colour rather than the batch's: what clears them is somebody correcting a
   Relay and resending, never a command run over a version. */
.console-dispatches tr.console-dispatch-delivered td.console-standing,
.console-exhausted-or-failed tr.console-dispatch-delivered td.console-standing {
  color: var(--console-good-ink);
  font-weight: 600;
}
.console-dispatches tr.console-dispatch-failed td.console-standing,
.console-dispatches tr.console-dispatch-exhausted td.console-standing,
.console-exhausted-or-failed tr.console-dispatch-failed td.console-standing,
.console-exhausted-or-failed tr.console-dispatch-exhausted td.console-standing {
  color: var(--console-person-ink);
  font-weight: 600;
}
/* ⚠️ REDUNDANT IS NEITHER, AND THE COLOUR SAYS SO. The Receiver already had the
   fact: it is not a delivery, so it is not green, and there is nothing for
   anybody to correct, so it is not the person's colour either. It reads as
   recorded and closed. Refused (#358) reads the same: the Receiver will not
   take the contact, and nothing about it is anybody's to correct. */
.console-dispatches tr.console-dispatch-redundant td.console-standing,
.console-dispatches tr.console-dispatch-refused td.console-standing,
.console-dispatches tr.console-dispatch-barred td.console-standing,
.console-exhausted-or-failed tr.console-dispatch-redundant td.console-standing {
  color: var(--console-ink-2);
  font-weight: 600;
}
.console-dispatches tr.console-dispatch-unattempted { color: var(--console-ink-4); }

/* The version is a digest and is read by its first characters; the whole of it
   is on the Dispatch's own page. */
.console-dispatches td.console-relay-version code,
.console-stale-versions td.console-sent-version code,
.console-stale-versions td.console-current-version code { font-size: 11px; }
.console-dispatches .console-stale,
.console-stale-versions td.console-sent-version {
  color: var(--console-batch-ink);
  font-weight: 600;
}

/* The attempts of one Dispatch: the answer is the column that decides what
   happens next, so it carries the weight and the response sits beside it. */
.console-attempts td.console-status { white-space: nowrap; font-variant-numeric: tabular-nums; }
.console-attempts td.console-status .console-note { display: block; font-size: 11.5px; color: var(--console-ink-3); white-space: normal; }
.console-attempts td.console-duration { text-align: right; font-variant-numeric: tabular-nums; }
.console-attempts td.console-response pre {
  margin: 0;
  max-width: 44rem;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  font-size: 11.5px;
}
/* The four words of the Answer, which since ADR-0060 is a column the sender
   wrote rather than a status this stylesheet's helper re-read. An `exhausted`
   attempt takes no colour: on its own it is one rung of the ladder. */
/* What a `redundant`'s duplicate rule matched (#140), above the response it
   was read from. ⚠️ A DL INSIDE A CHECKLIST SECTION, which would otherwise be
   drawn as the checklist's own panel — a bordered box inside a table cell. */
.console-attempts td.console-response .console-duplicate { margin: 0 0 10px; max-width: 44rem; }
.console-attempts td.console-response .console-duplicate dl {
  grid-template-columns: 8rem minmax(0, 1fr);
  max-width: none;
  padding: 0;
  background: none;
  border: 0;
}
.console-attempts td.console-response .console-duplicate dt,
.console-attempts td.console-response .console-duplicate dd { margin-top: 4px; }
.console-attempts td.console-response .console-duplicate dt:first-of-type,
.console-attempts td.console-response .console-duplicate dd:first-of-type { margin-top: 0; }
.console-attempts td.console-response .console-duplicate ul { margin: 0; padding: 0; list-style: none; }
.console-matched-record { font-family: var(--console-mono); font-size: var(--console-text-xs); }
.console-matched-confidence { color: var(--console-ink-3); }
.console-attempts tr.console-attempt-delivered td.console-status { color: var(--console-good-ink); font-weight: 600; }
.console-attempts tr.console-attempt-redundant td.console-status,
.console-attempts tr.console-attempt-refused td.console-status { color: var(--console-ink-2); font-weight: 600; }
.console-attempts tr.console-attempt-failed td.console-status { color: var(--console-person-ink); font-weight: 600; }

/* The conditions of one Relay, and the settling table beside the form. Both are
   short, dense and read as lists rather than as reports. */
.console-conditions td.console-position,
.console-attempts td.console-position { color: var(--console-ink-4); text-align: right; }
/* An Intake condition's ids, one per line with the Intake's name beside each —
   #246. */
.console-conditions .console-intake-value { display: block; }
.console-conditions .console-intake-name { margin-left: var(--console-space-2); }
.console-settling { font-size: var(--console-text-xs); }
.console-settling td.console-settles code { color: var(--console-ink-2); }
