/* What is particular to one screen: breadcrumbs, the calm empty states, the
   work-list prose, the command blocks, the one-time token, standing. */

.console-breadcrumb { margin: 0 0 var(--console-space-2); font-size: var(--console-text-xs); }

.console-current-account { font-size: 15px; color: var(--console-ink-2); max-width: 44ch; }

/* AN EMPTY WORK LIST IS THE GOOD STATE. It reads as a fact in the page's own
   voice, on the page's own surface — no icon, no dashed box, no "no data". */
.console-empty {
  margin: 20px 0 0;
  padding: 26px;
  background: var(--console-surface);
  border: 1px solid var(--console-rule-2);
  border-radius: var(--console-radius);
  color: var(--console-ink-2);
  font-size: 15px;
}
/* On a filtered list the same sentence is an answer to the filter, not a
   standing, so it does not take a surface of its own. */
.console-contacts-empty .console-empty,
.console-filters ~ .console-empty {
  margin: 0;
  padding: 22px 2px;
  background: none;
  border: 0;
  font-size: var(--console-text);
  color: var(--console-ink-3);
}

/* ⛔ AND THE SAME WORD INSIDE A CELL OR A CHECKLIST'S VALUE IS PROSE. There it
   is one run in a sentence rather than a standing of its own, and a padded,
   bordered box drawn around an INLINE run does not push the lines above and
   below it apart — it paints over them. So the surface comes off and what is
   left is the quiet ink an absent value is written in. */
td .console-empty,
.console-checklist dd .console-empty {
  display: inline;
  margin: 0;
  padding: 0;
  background: none;
  border: 0;
  border-radius: 0;
  font-size: inherit;
  color: var(--console-ink-3);
}

.console-work-list-note { color: var(--console-ink-2); max-width: 78ch; }
.console-capped { margin: 10px 0 0; font-size: var(--console-text-xs); color: var(--console-ink-3); }

.console-narrowed {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 0 0 14px;
  padding: 9px 14px;
  background: #eef3f8;
  border: 1px solid #cddcea;
  border-radius: var(--console-radius);
  font-size: var(--console-text-sm);
  color: #274c70;
}

.console-raw-layer {
  margin: 22px 0 0;
  padding-top: 14px;
  border-top: 1px solid var(--console-rule-2);
  font-size: var(--console-text-xs);
  color: var(--console-ink-3);
  max-width: 88ch;
}

.console-clears { max-width: 82ch; font-size: var(--console-text-sm); color: var(--console-ink-2); }
td.console-clears { max-width: none; }

/* ============================================================
   WORK SHOWN, NEVER DONE. The reprocess command is a thing to
   copy and run elsewhere, so it is full-width, selectable, and
   carries no button, no icon and no affordance that suggests
   this page will run it.
   ============================================================ */
code.console-reprocess {
  display: block;
  margin-top: var(--console-space-2);
  padding: var(--console-space-2) 10px;
  background: #f2f0ea;
  border: 1px solid #dcd8d0;
  border-radius: 5px;
  font-size: var(--console-text-xs);
  user-select: all;
  overflow-wrap: anywhere;
}
.console-tripwire code.console-reprocess { display: inline-block; margin-top: 0; }
/* Click-to-copy, when the Stimulus controller is attached. Still a code block:
   the only change is a cursor and a word afterwards. */
code.console-reprocess[data-controller~="copy"] { cursor: copy; }
code.console-reprocess[data-copy-copied-value="true"]::after {
  content: " copied";
  color: var(--console-ink-3);
  font-family: var(--console-sans);
  font-size: 11px;
}
.console-no-version { display: block; margin-top: var(--console-space-2); font-size: var(--console-text-xs); font-style: italic; color: var(--console-ink-3); }

/* Profile, standing, checklist: a dl is a two-column reading, not a form. */
.console-profile, .console-standing, .console-checklist section {
  max-width: 900px;
  padding: 18px 20px;
  background: var(--console-surface);
  border: 1px solid var(--console-rule-2);
  border-radius: var(--console-radius);
}
.console-profile h2, .console-standing h2 { margin-top: 0; }

dl.console-account, .console-profile dl, .console-checklist dl {
  display: grid;
  grid-template-columns: 13rem minmax(0, 1fr);
  column-gap: 20px;
  align-items: baseline;
  margin: 0;
}
dl.console-account, .console-checklist dl {
  max-width: 900px;
  padding: 16px 20px;
  background: var(--console-surface);
  border: 1px solid var(--console-rule-2);
  border-radius: var(--console-radius);
}
.console-profile dl { grid-template-columns: 11rem minmax(0, 1fr); }
dl.console-account dt, .console-profile dt, .console-checklist dt {
  margin-top: 14px;
  font-size: var(--console-label);
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--console-ink-3);
}
dl.console-account dd, .console-profile dd, .console-checklist dd { margin: 14px 0 0; }
dl.console-account dt:first-of-type, .console-profile dt:first-of-type, .console-checklist dt:first-of-type { margin-top: 0; }
dl.console-account dd:first-of-type, .console-profile dd:first-of-type, .console-checklist dd:first-of-type { margin-top: 0; }

/* ⚠️ THE VALUE IS ONE LINE AND THE REASON IS A PARAGRAPH, so they are not one
   run. Set inline, a four-line explanation of why a field is empty starts in
   the middle of the line the value ends on, and the eye cannot find where the
   answer stopped and the argument began — which is the whole readability of a
   checklist read top to bottom. The value keeps the row; the note sits under it,
   quieter, and measures to something a person reads rather than scans. */
.console-checklist dd .console-note {
  display: block;
  margin: 6px 0 0;
  max-width: 74ch;
  line-height: 1.55;
}
.console-checklist dd .console-note:first-child { margin-top: 0; }

.console-profile-phone, .console-rebuilt-at, .console-created-at, .console-suspended-at, .console-purged-at {
  font-family: var(--console-mono);
  font-size: var(--console-text-xs);
}
.console-e164 { color: var(--console-ink-3); }
.console-address { line-height: 1.6; }

/* THE STALENESS AGE IS NEVER COLOURED. A profile a few seconds behind is the
   sweeper's cadence, so this is prose and nothing else. */
.console-staleness {
  margin: 18px 0 0;
  padding-top: 14px;
  border-top: 1px solid var(--console-rule);
  color: var(--console-ink-2);
  font-size: var(--console-text-sm);
  max-width: 64ch;
  background: none;
}

/* UNATTRIBUTABLE IS NOT UNRESOLVED. It is not waiting for anything, so the
   cell stays plain prose; only Unresolved takes the treatment in
   console-3-tables.css. */
.console-conversions td.console-contact { font-size: 12.5px; color: var(--console-ink-2); }
.console-conversions td.console-contact a { font-size: var(--console-text-sm); }

/* What every policy would have answered, on one line, middle dots between
   them — #83. Quieter than `accepted` beside it, which is the one that decides. */
td.console-policies { font-size: var(--console-text-xs); color: var(--console-ink-2); white-space: nowrap; }

/* ============================================================
   THE ONE-TIME TOKEN. Shown once, unmistakable, and the only
   dark surface in the product — which is why it cannot be
   mistaken for an error and cannot be mistaken for a row.
   ============================================================ */
.console-token-issued {
  max-width: 900px;
  margin: 18px 0 0;
  padding: 18px 20px;
  background: var(--console-ink);
  border: 1px solid var(--console-ink);
  border-radius: var(--console-radius);
  color: #f5f2ec;
}
.console-token-issued h2 { margin: 0 0 var(--console-space-2); color: #c9c3b6; }
.console-token-issued .console-note { color: #cdc7ba; max-width: 74ch; }
.console-token-issued .console-plaintext, .console-token-issued .console-partner-url { margin: var(--console-space-2) 0 0; }
.console-token-issued .console-plaintext code, .console-token-issued .console-partner-url code {
  display: block;
  padding: 10px var(--console-space-3);
  background: #2a2724;
  border: 1px solid #454039;
  border-radius: 5px;
  color: #f5f2ec;
  font-size: var(--console-text-sm);
  user-select: all;
  overflow-wrap: anywhere;
}
.console-token-issued .console-partner-url code { color: #cdc7ba; font-size: var(--console-text-xs); }

.console-actions { display: flex; align-items: center; flex-wrap: wrap; gap: var(--console-space-4); margin-top: var(--console-space-4); }
.console-actions form { margin: 0; }
.console-actions .console-current { font-size: var(--console-text-sm); color: var(--console-ink-2); }

/* SUSPEND IS REVERSIBLE AND DOES NOT LOOK LIKE DELETE: it is the page's
   ordinary button, and the sentence under it says what it does. */
.console-standing { margin-top: 26px; }
.console-standing .console-suspend button,
.console-standing .console-resume button,
.console-suspend, .console-resume { font-weight: 600; }
.console-standing .console-note { margin: 10px 0 0; font-size: var(--console-text-sm); color: var(--console-ink-2); max-width: 72ch; }
.console-no-purge {
  margin: 18px 0 0;
  padding-top: 14px;
  border-top: 1px solid var(--console-rule);
  font-size: var(--console-text-sm);
  color: var(--console-ink-2);
  max-width: 72ch;
}

.console-intake-standing { color: var(--console-ink-2); font-size: var(--console-text-sm); }
.console-anchor-slot.console-unattributable { font-weight: 600; max-width: 74ch; }
.console-slot-map pre { max-width: 30rem; }
.console-heard-from { font-size: var(--console-text-sm); color: var(--console-ink-2); max-width: 80ch; }
p.console-heard-from.console-silent { font-weight: 600; color: var(--console-batch-ink); }
.console-url-shape { overflow-wrap: anywhere; }
/* Copying a partner URL is a button, because copying a URL does nothing to
   anything — unlike the reprocess command above, which stays a code block. */
.console-copy {
  margin-left: var(--console-space-2);
  padding: 2px 8px;
  font-size: 11px;
  font-weight: 600;
  line-height: 1.4;
  vertical-align: middle;
  white-space: nowrap;
}
.console-token-issued .console-partner-url { display: flex; align-items: center; gap: var(--console-space-2); }
.console-token-issued .console-partner-url code { flex: 1; min-width: 0; }
.console-token-issued .console-copy { margin-left: 0; background: #3a3630; border-color: #5a544b; color: #f5f2ec; }
.console-token-issued .console-copy:hover { background: #4a453e; }
/* The row of the token just issued carries its URL, once. */
.console-tokens tr.console-token-issued-now td { background: var(--console-good-bg); }
.console-tokens td.console-standing .console-token-url {
  display: flex;
  align-items: center;
  gap: var(--console-space-2);
  margin-top: 6px;
  font-weight: 400;
}
.console-tokens td.console-standing .console-token-url code {
  user-select: all;
  overflow-wrap: anywhere;
  white-space: normal;
  color: var(--console-ink);
}
.console-tokens td.console-standing .console-token-url .console-copy { margin-left: 0; }
.console-issue-token { display: flex; align-items: flex-end; gap: var(--console-space-3); max-width: 760px; margin-top: 14px; padding: 14px var(--console-space-4); }
.console-issue-token label { margin-bottom: 5px; }
.console-issue-token input[type="text"] { max-width: 18rem; }

/* INTEGRATIONS. A document and not a table: it reads on the page's own surface,
   and the only chrome is the block that gets copied. The snippet is dark for
   the same reason the one-time token is — it is text to be taken away rather
   than text to be read here — and it scrolls in place so that the page below
   it stays reachable. */
.console-integration {
  max-width: 900px;
  margin-top: 26px;
  padding: 18px 20px;
  background: var(--console-surface);
  border: 1px solid var(--console-rule-2);
  border-radius: var(--console-radius);
}
.console-integration h2 { margin: 0; }
.console-integration h3 {
  margin: 26px 0 var(--console-space-2);
  font-size: var(--console-label);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--console-ink-3);
}
.console-integration p { max-width: 78ch; color: var(--console-ink-2); }

/* One line worth copying, beside the button that copies it. */
.console-snippet-line { display: flex; align-items: center; flex-wrap: wrap; gap: var(--console-space-2); }
.console-snippet-line code {
  padding: 6px 10px;
  background: var(--console-sunken);
  border: 1px solid var(--console-rule-2);
  border-radius: var(--console-radius-sm);
  font-size: var(--console-text-xs);
  user-select: all;
  overflow-wrap: anywhere;
}

.console-snippet-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--console-space-3);
  margin: 0 0 var(--console-space-2);
  font-size: var(--console-text-xs);
  color: var(--console-ink-3);
}
.console-snippet pre {
  max-height: 460px;
  margin: 0;
  padding: 16px 18px;
  overflow: auto;
  background: #2a2724;
  border: 1px solid #454039;
  border-radius: 5px;
  color: #f5f2ec;
  font-size: var(--console-text-sm);
  line-height: 1.65;
  tab-size: 2;
}
/* ⛔ THE CHIP IS TURNED OFF HERE, AND IT HAD TO BE. `code` carries a pale chip
   background site-wide, and an INLINE element paints that background once per
   LINE FRAGMENT — so two hundred lines of near-white text landed on two hundred
   pale bars, one per line, and the snippet was a block of stripes with the code
   invisible inside them. It is a block of text here, not a chip: the box around
   it is the `pre`, drawn once. */
.console-snippet pre code {
  display: block;
  padding: 0;
  background: none;
  border: 0;
  border-radius: 0;
  color: inherit;
  font-size: inherit;
  user-select: all;
  white-space: pre;
}

.console-sections { max-width: 78ch; margin: 0 0 var(--console-space-4); padding-left: 22px; color: var(--console-ink-2); }
.console-sections li { margin: var(--console-space-1) 0; }
.console-sections code { font-size: var(--console-text-sm); }

/* The paragraph that says what is NOT opened. It is the one thing on this page
   somebody can get wrong without anything reporting it, so it is marked. */
.console-sections-note {
  padding: var(--console-space-3) var(--console-space-4);
  background: var(--console-batch-bg);
  border: 1px solid var(--console-batch-edge);
  border-radius: var(--console-radius-sm);
  color: var(--console-batch-ink);
  font-size: var(--console-text-sm);
}

/* ============================================================
   THE LEAD SHEET. One payload's worth of columns, grouped, and
   the fields that never arrived left standing empty — the empty
   cell IS the answer to "did the map catch it?", so it is dimmed
   and never dropped.

   A CELL WRAPS RATHER THAN OVERFLOWS. A transaction id and a
   page_url are both longer than any column a grid can promise,
   and two values sliding over each other is the one failure this
   screen cannot survive: it makes a wrong value look like a real
   one. Hence `minmax(0, ...)` on the track and
   `overflow-wrap: anywhere` on the value.
   ============================================================ */
.console-lead-account { color: var(--console-ink-2); }

.console-lead-arrival, .console-lead-group, .console-lead-reading {
  max-width: 900px;
  margin-bottom: var(--console-space-4);
  padding: 18px 20px;
  background: var(--console-surface);
  border: 1px solid var(--console-rule-2);
  border-radius: var(--console-radius);
}
.console-lead-arrival h2, .console-lead-group h2, .console-lead-reading h2 { margin-top: 0; }

dl.console-fields {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(11rem, 1fr));
  gap: 1px;
  margin: 0;
  /* ⚠️ THE GAP IS THE PAGE SHOWING THROUGH, NOT A RULE. A group rarely fills
     its last row, and a grid whose gaps are dark paints the leftover track in
     the same ink as a cell — an empty box under no label, on the screen whose
     empty boxes mean *this field never arrived*. So the sheet behind the cells
     is the card's own surface, and a gap reads as nothing. */
  background: var(--console-surface);
  border: 1px solid var(--console-rule-2);
  border-radius: var(--console-radius-sm);
  overflow: hidden;
}

.console-field { min-width: 0; padding: 8px 11px; background: var(--console-sunken); }

/* The label is the column's own name, so it is not a chip: on this screen every
   label would be one, and a page of chips reads as decoration. */
.console-field dt code {
  padding: 0;
  background: none;
  border: 0;
  font-size: var(--console-label);
  letter-spacing: 0.02em;
  color: var(--console-ink-3);
}
.console-field dd {
  margin: 2px 0 0;
  font-family: var(--console-mono);
  font-size: var(--console-text-sm);
  line-height: 1.45;
  overflow-wrap: anywhere;
}
.console-field-empty dd { color: var(--console-ink-4); }

/* The handle a person takes to a shell on the host — the whole of what the
   console offers of the raw layer, so it takes its own row and selects whole. */
.console-lead-payload-id { grid-column: 1 / -1; }
.console-lead-payload-id dd code { user-select: all; }

/* The Acceptance section is a section like the sheet's others; only the reason
   beside a policy's word is quieter than the word — #83. */
.console-policy-reason { font-size: var(--console-text-xs); color: var(--console-ink-2); }

/* The CRM Lookup — #139. Each query sits above what the org answered to it, and
   both wrap: a SOQL string and a response are read and pasted, not scanned. */
.console-lead-lookup { max-width: 900px; }
.console-lookup-queries { margin: var(--console-space-3) 0 0; padding-left: 1.5rem; }
.console-lookup-query { margin-bottom: var(--console-space-3); }
.console-lookup-query pre { max-width: 46rem; white-space: pre-wrap; overflow-wrap: anywhere; }
.console-lookup-soql { margin-bottom: var(--console-space-2); }

/* ============================================================
   THE TIMELINE'S TRACKING COLUMN. One event's block per cell,
   in the order `Console::Contacts::TOUCH` names, so that two
   rows can be compared straight down the page — which is the
   whole of what makes first and last touch readable here.

   A chip carries its field name because a canonical name IS a
   column name (ADR-0021), and a value with no name is a value
   somebody has to guess the meaning of.
   ============================================================ */
/* A contact's consent (#342): one block per address the contact holds, its
   standing in the heading and the facts behind it below, the deciding one
   marked. */
.console-consent-address { margin: 0 0 var(--console-space-4); }
.console-consent-address h3 { margin: 0 0 8px; font-size: var(--console-text-sm); }
.console-consent-standing { font-weight: 700; }
.console-consent-deciding {
  font-size: var(--console-label);
  letter-spacing: 0.06em;
  text-transform: uppercase;
}
.console-remove-from-everything { margin-top: 24px; }

/* ⚠️ THE TIMELINE GREW A COLUMN AND HAD NO WIDTH OF ITS OWN. Every other table
   in the console declares a `min-width` and scrolls inside `.console-table`;
   this one fitted until now. Without one the capture surface — an id and a URL
   joined, `white-space: nowrap` like every other surface cell — takes whatever
   it wants and squeezes the tracking chips into a column one word wide. So the
   table gets a floor, and the surface cell alone is allowed to wrap: it is the
   only cell here whose content has no bound. */
.console-timeline .console-table table { min-width: 1180px; }
.console-timeline td.console-surface {
  max-width: 26rem;
  white-space: normal;
  overflow-wrap: anywhere;
}

td.console-touches { min-width: 21rem; white-space: normal; }

.console-touch {
  display: inline-flex;
  align-items: baseline;
  gap: 5px;
  margin: 0 var(--console-space-1) var(--console-space-1) 0;
  padding: 1px 7px;
  border-radius: var(--console-radius-sm);
  background: #f2f0ea;
  border: 1px solid #e0dcd4;
  max-width: 100%;
}
.console-touch-field {
  font-family: var(--console-mono);
  font-size: 10.5px;
  color: var(--console-ink-4);
  white-space: nowrap;
}
.console-touch-value {
  font-family: var(--console-mono);
  font-size: 11.5px;
  color: var(--console-ink-2);
  overflow-wrap: anywhere;
}

/* ⚠️ A WORD, NOT A BLANK. An untracked lead and a tracked one must never look
   alike here: whether the first counts as a touch at all is the question this
   column exists to be read for. */
.console-no-touch { font-size: var(--console-text-xs); font-style: italic; color: var(--console-ink-4); }

/* ============================================================
   The Relay's screens — #45. A Relay is read as a checklist,
   the same way an Intake is; a Dispatch is read as two halves,
   what left and what came back.
   ============================================================ */

.console-relay-standing, .console-dispatch-standing { color: var(--console-ink-2); font-size: var(--console-text-sm); }

/* THE STANDING IS A SENTENCE AND NOT A BADGE. Delivered, failed, exhausted and
   attempting are read off the attempts and never stored, so the page says what
   is true of the rows rather than showing a status somebody has to trust. */
p.console-dispatch-standing {
  margin-top: var(--console-space-3);
  padding: 9px 14px;
  border-radius: var(--console-radius);
  font-size: var(--console-text-sm);
  max-width: 78ch;
}
p.console-dispatch-delivered { background: var(--console-good-bg); border: 1px solid var(--console-good-rule); color: var(--console-good-ink); font-weight: 600; }
/* ⚠️ BARRED IS SAID AS LOUDLY AS A STOP: nothing left, and an Operator who
   came to ask why must not have to find the reason further down. */
p.console-dispatch-failed, p.console-dispatch-exhausted, p.console-dispatch-barred {
  background: var(--console-person-bg);
  border: 1px solid #e8c9bd;
  color: var(--console-person-ink);
  font-weight: 600;
}
p.console-dispatch-barred { font-size: var(--console-text); }

/* Why a barred Dispatch sent nothing, directly under its headline: the
   meaning first, then the bar's exact facts, then that it is final. */
.console-dispatch-bar {
  max-width: 78ch;
  margin-top: var(--console-space-2);
  padding: 4px 14px;
  border-left: 3px solid var(--console-person-edge);
}
.console-dispatch-bar p { margin: 6px 0; }
.console-dispatch-bar-at, .console-dispatch-bar-final { color: var(--console-ink-2); font-size: var(--console-text-sm); }
p.console-dispatch-attempting, p.console-dispatch-unattempted {
  background: var(--console-sunken);
  border: 1px solid var(--console-rule-2);
  color: var(--console-ink-2);
}

/* A frozen document is read, not scanned: it wraps, it keeps its indentation,
   and it is selectable whole because the next thing anybody does with it is
   paste it into a support ticket with the Receiver. */
.console-relay-headers pre, .console-relay-body pre,
.console-dispatch-headers pre, .console-dispatch-body pre {
  max-width: 46rem;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}
.console-url-template code, .console-dispatch-id code, .console-relay-version code { overflow-wrap: anywhere; }

/* ⚠️ *NO LIMIT* IS AN ANSWER AND MUST NOT READ AS AN OMISSION. It is set in the
   page's own ink rather than greyed, because a blank meaning *nobody asked* is
   the exact failure the field exists to prevent. */
.console-receiver-deadline.console-no-deadline { color: var(--console-ink); }

/* ⛔ THE SENTENCE THAT SAYS NOTHING HERE SENDS, in the place a button would be —
   the same shape `console-no-purge` takes on an Account's page. */
.console-never-fires {
  margin: 14px 0 0;
  padding: 10px 14px;
  background: var(--console-batch-bg);
  border: 1px solid var(--console-batch-edge);
  border-radius: var(--console-radius);
  color: var(--console-batch-ink);
  font-size: var(--console-text-sm);
  max-width: 82ch;
}

.console-new-version { max-width: 82ch; }
.console-no-conditions { max-width: 82ch; }

/* The addressable fields, folded away beside the box they are the vocabulary
   for. Open is the wrong default: a person editing one condition does not want
   forty rows between them and the submit button. */
.console-addressable { margin: 0 0 22px; max-width: 46rem; }
.console-addressable summary { font-size: var(--console-text-sm); font-weight: 600; color: var(--console-ink-2); cursor: pointer; }
.console-snapshot-text { margin-top: var(--console-space-3); max-width: 78ch; }
.console-snapshot-text summary { font-size: var(--console-text-sm); font-weight: 600; color: var(--console-ink-2); cursor: pointer; }
.console-snapshot-text-content { white-space: pre-wrap; overflow-wrap: anywhere; max-height: 22rem; overflow-y: auto; }
.console-addressable .console-table { margin-top: var(--console-space-3); max-height: 22rem; overflow-y: auto; }

/* JSON is typed in a monospaced box wide enough to read a nested document in. */
.console-form textarea.console-code {
  font-family: var(--console-mono);
  font-size: var(--console-text-xs);
  max-width: 46rem;
}
.console-form input[type="text"].console-wide { max-width: 46rem; font-family: var(--console-mono); font-size: var(--console-text-xs); }
.console-form input[type="text"].console-instant { max-width: 14rem; font-family: var(--console-mono); }
.console-form #relay_first_touch_window, .console-form #relay_receiver_deadline { max-width: 10rem; }
/* Border-box, so a full-width box's padding and border stay inside the field
   it sits in rather than spilling past its edge. */
.console-form textarea.console-code, .console-form input.console-wide { box-sizing: border-box; }
/* A Relay's request documents open tall enough to read without scrolling:
   headers are a handful of lines, the body is a nested document. */
.console-form textarea#relay_headers { height: 250px; }
.console-form textarea#relay_body { height: 300px; }

/* Credentials — #47. A screen that STORES a secret and can never show one, so
   there is no reveal affordance to style and deliberately no place for one.
   The panel is `console-standing`'s box, and the warning variant is the only
   colour on the page: a reference naming no credential is the one thing here
   that is going to fail hours from now in a work list. */
.console-panel {
  max-width: 900px;
  margin: 18px 0 0;
  padding: 18px 20px;
  background: var(--console-surface);
  border: 1px solid var(--console-rule-2);
  border-radius: var(--console-radius);
}
.console-panel h2 { margin-top: 0; }

/* ⚠️ ONE COLUMN PER SCREEN THAT IS READ AS A COLUMN — a checklist's dls, a
   provisioning screen's panel — and a table or an empty state among them is in
   it and stops where they stop. Left at the page's width, a four-row table runs
   past the box beside it and a one-sentence empty state is drawn a screen wide.
   A table wider than the column scrolls inside its wrapper, as every table
   does. The lists read as reports — leads, conversions, contacts — keep the
   page's width and are not named here.
   The boxes' 900px is their CONTENT box, so the outer edge is that plus 20px
   of padding and 1px of border on each side. */
.console-checklist > .console-table,
.console-checklist > .console-empty,
.console-panel ~ .console-table,
.console-panel ~ .console-empty {
  box-sizing: border-box;
  max-width: calc(900px + 2 * 20px + 2 * 1px);
}
.console-panel-warning { background: var(--console-batch-bg); border-color: #e6d9b4; color: var(--console-batch-ink); }

/* Rotation sits in the row it rotates: a person reading *last rotated* is the
   person about to type a new one, and a second screen between the two is where
   the wrong credential gets rotated. */
.console-inline-form { display: flex; gap: var(--console-space-2); align-items: center; margin: 0; }
.console-inline-form input[type="password"] { max-width: 12rem; font-family: var(--console-mono); font-size: var(--console-text-xs); }
.console-form input[type="password"].console-wide { max-width: 46rem; font-family: var(--console-mono); font-size: var(--console-text-xs); }
.console-submit-inline { font-size: var(--console-text-xs); padding: 4px 10px; }

/* The Mapping editor — #57. One row per line of the document: our name on the
   left as a picklist of the fields a Mapping may be keyed by, their spelling on
   the right against a `<datalist>` holding this org's own Catalog.

   ⛔ A `<datalist>` AND NOT A `<select>`, WHICH IS THE DECISION AND NOT THE
   STYLING. The Receiver is the authority on its own fields and the Catalog is a
   snapshot the lane refreshed, so a spelling the org has since added — or one an
   Integration with no Catalog yet has no list for at all — has to stay typeable.
   The picklist removes the typo; it does not become a gate. */
.console-mapping-editor { width: 100%; max-width: 46rem; }
.console-mapping-editor th { font-size: var(--console-text-xs); color: var(--console-ink-3); text-align: left; }
.console-mapping-editor select { max-width: 15rem; }
.console-mapping-editor input[type="text"] { max-width: 17rem; }
.console-mapping-editor td { vertical-align: middle; }
.console-mapping-remove { padding: 2px 8px; font-size: var(--console-text-xs); line-height: 1.4; }

/* ⚠️ THE FLAG IS A MARK AND NEVER A REFUSAL. A target the Catalog no longer
   offers is still sent, and it is a gauge beside the stopped work lists as well
   as a line here — knowing before the first broken send is the difference
   between a backlog and an incident.
   ⚠️ A META CAPI PIXEL IN TEST MODE (#167) WEARS THE SAME MARK on its line
   under the Meta CAPI card: it is sending, and what it sends counts for
   nothing. And so does every Relay through it, on its own row (#163, story 6). */
.console-target-gone,
.console-service-cards .console-test-mode,
.console-relays .console-test-mode {
  display: inline-block;
  margin-left: var(--console-space-2);
  padding: 1px 6px;
  font-size: 11.5px;
  background: var(--console-batch-bg);
  border: 1px solid #e6d9b4;
  border-radius: var(--console-radius);
  color: var(--console-batch-ink);
}

/* ONE CARD PER SERVICE — #173. The Integrations screen is four cards in a grid
   rather than a table: the table's columns belonged to one service and were
   dashes for the other two, and the provisioning links had piled up above it.
   A card is `console-panel`'s box, and holds what the service is, its one
   action, and the Account's Integrations of that kind as a list of lines.

   ⚠️ THE GRID NEVER OVERFLOWS THE PAGE. The column minimum is the smaller of
   16rem and the full width, so at phone width the cards stack one to a row
   inside the 16px gutters `main` keeps there, and nothing scrolls sideways.
   `minmax(0, …)` on the line's parts is the same care one level down: a long
   name or a long answer wraps inside its card rather than widening it. */
.console-service-cards {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(16rem, 100%), 1fr));
  gap: var(--console-space-4);
  margin-top: 18px;
}
.console-service-card {
  box-sizing: border-box;
  min-width: 0;
  padding: 18px 20px;
  background: var(--console-surface);
  border: 1px solid var(--console-rule-2);
  border-radius: var(--console-radius);
}
.console-service-card h2 { margin: 0 0 var(--console-space-2); }
.console-service-description { margin: 0; color: var(--console-ink-2); }
.console-service-action { margin: var(--console-space-3) 0 0; }
.console-service-action .console-new { font-weight: 600; }
.console-service-action .console-note { margin: 0; }

/* The lines under a card: one Integration each, told apart by its name, with
   the line's facts in the quiet ink a row's secondary cells use. */
.console-service-none { margin: var(--console-space-4) 0 0; padding-top: 12px; border-top: 1px solid var(--console-rule); font-size: var(--console-text-sm); color: var(--console-ink-3); }
.console-service-integrations { margin: var(--console-space-4) 0 0; padding: 0; list-style: none; border-top: 1px solid var(--console-rule); }
.console-service-integration {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--console-space-1) var(--console-space-3);
  padding: 10px 0;
  border-bottom: 1px solid var(--console-rule);
  font-size: var(--console-text-sm);
  overflow-wrap: anywhere;
}
.console-service-integration .console-name { min-width: 0; font-weight: 600; }
.console-service-integration .console-account,
.console-service-integration .console-active,
.console-service-integration .console-last-checked { min-width: 0; color: var(--console-ink-3); }
.console-service-integration .console-last-checked code { font-size: 11.5px; }
/* A switched-off Integration is set back, as a switched-off Relay's row is. */
.console-service-integration.console-integration-inactive .console-name a { color: var(--console-ink-2); }
.console-service-integration .console-test-mode { margin-left: 0; }

/* *Last checked at*, and what it answered — never a stored `connected`. It is a
   fact about then, so it is set in the page's ordinary ink and given no colour
   of its own: nothing here is an alarm, and nothing gates on it. */
.console-catalog details summary { font-size: var(--console-text-sm); font-weight: 600; color: var(--console-ink-2); cursor: pointer; }
.console-catalog-fields { margin: var(--console-space-3) 0 0; max-height: 18rem; overflow-y: auto; columns: 3; font-size: var(--console-text-xs); }
.console-check-note { max-width: 78ch; }

/* JSON, coloured — #112. The spans change ink and tint only, never padding,
   weight or size, so that a coloured document occupies exactly the space the
   grey one did — and so that the editor's layer lies character for character
   under the text being typed. */
.console-json-key { color: var(--console-json-key); }
.console-json-string { color: var(--console-json-string); }
.console-json-number { color: var(--console-json-number); }
.console-json-literal { color: var(--console-json-literal); }
.console-json-punctuation { color: var(--console-json-punctuation); }
.console-json-variable { color: var(--console-json-variable-ink); background: var(--console-json-variable-bg); border-radius: 2px; }
.console-json-credential { color: var(--console-json-credential-ink); background: var(--console-json-credential-bg); border-radius: 2px; }
.console-json-unaddressable {
  text-decoration: underline wavy var(--console-json-unaddressable);
  text-decoration-skip-ink: none;
  text-underline-offset: 2px;
}

/* The editor, once its controller runs. The textarea stays on top and stays the
   field: its text goes transparent and its caret does not, and the layer behind
   it is drawn in the same box by the controller. Without JavaScript none of
   these classes is present. */
.console-json-editor-box { position: relative; }
.console-json-editor-live textarea { position: relative; z-index: 1; background: transparent; color: transparent; caret-color: var(--console-ink); }
.console-json-editor-live textarea::selection { color: transparent; background: rgba(47, 93, 138, 0.22); }
.console-json-layer {
  position: absolute;
  z-index: 0;
  margin: 0;
  overflow: hidden;
  white-space: pre-wrap;
  overflow-wrap: break-word;
  border-color: transparent;
  pointer-events: none;
}
/* The line numbers, in the textarea's own left padding: four digits' width and
   a rule, then the textarea's ordinary 9px before the text. */
.console-json-editor-live textarea { padding-left: calc(4ch + 19px); }
.console-json-gutter {
  position: absolute;
  z-index: 2;
  width: calc(4ch + 10px);
  overflow: hidden;
  border-right: 1px solid var(--console-rule-2);
  background: var(--console-sunken);
  color: var(--console-ink-4);
  pointer-events: none;
}
.console-json-gutter div { position: absolute; right: 6px; }
.console-json-gutter .console-json-gutter-break { color: var(--console-json-unaddressable); font-weight: 600; }

/* Where the document broke — the same mark an unaddressable Variable gets. */
.console-json-break, .console-json-break-end::after {
  text-decoration: underline wavy var(--console-json-unaddressable);
  text-decoration-skip-ink: none;
  text-underline-offset: 2px;
}
.console-json-break-end::after { content: "\00a0\00a0"; }

.console-json-status .console-json-jump {
  padding: 0;
  border: 0;
  background: none;
  font: inherit;
  color: inherit;
  text-decoration: underline;
  cursor: pointer;
}
.console-json-status .console-json-jump:hover { background: none; }

.console-json-editor-bar { display: flex; align-items: baseline; gap: var(--console-space-3); margin-top: 6px; max-width: 46rem; }
.console-json-editor-bar button { padding: 2px 10px; font-size: var(--console-text-xs); }
.console-json-status { margin: 0; font-size: var(--console-text-xs); color: var(--console-ink-3); }
.console-json-status.console-json-broken { color: var(--console-person-ink); font-weight: 600; }

/* ============================================================
   The leads and conversions lists — #115: a filter per field,
   the summary, the pills, and the pager.
   ============================================================ */

/* Each field wraps its own label, so the label sits over its control however
   the line wraps — the sibling pairing above breaks once fields wrap. */
.console-list-filters .console-filter { display: flex; flex-direction: column; gap: var(--console-space-1); }
.console-list-filters .console-filter[hidden] { display: none; }
.console-list-filters .console-filter label { align-self: auto; margin: 0; padding: 0; }
.console-list-filters input[type="search"] { min-width: 18rem; }
.console-list-filters input[type="text"] { width: 8rem; }
.console-list-filters select { min-width: 10rem; }

.console-summary {
  display: flex;
  flex-wrap: wrap;
  gap: var(--console-space-3) var(--console-space-6);
  margin: 0 0 18px;
  padding: 14px var(--console-space-4);
  background: var(--console-surface);
  border: 1px solid var(--console-rule-2);
  border-radius: var(--console-radius);
}
.console-summary dt {
  font-size: var(--console-label);
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--console-ink-3);
}
.console-summary dd { margin: 2px 0 0; font-size: 22px; font-weight: 600; font-variant-numeric: tabular-nums; }

/* A state is a colour, an icon and a word — never the colour alone. */
.console-pill {
  --pill-bg: var(--console-sunken);
  --pill-edge: var(--console-rule-3);
  --pill-ink: var(--console-ink-2);
  display: inline-flex;
  align-items: center;
  gap: 4px;
  margin: 1px 6px 1px 0;
  padding: 0 8px 0 5px;
  border: 1.5px solid var(--pill-edge);
  border-radius: var(--console-radius-pill);
  background: var(--pill-bg);
  color: var(--pill-ink);
  font-size: var(--console-text-xs);
  font-weight: 600;
  line-height: 20px;
  white-space: nowrap;
}
/* An outbound pill is a link to its Dispatch; it keeps the pill's ink. */
a.console-pill { text-decoration: none; }
a.console-pill:hover { border-color: var(--pill-ink); }
.console-pill svg {
  width: 14px;
  height: 14px;
  flex: none;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.console-pill-accepted-yes,
.console-pill-outbound-delivered { --pill-bg: #f1f8f1; --pill-edge: #a8d8ab; --pill-ink: #2f6b33; }
.console-pill-accepted-no,
.console-pill-outbound-exhausted { --pill-bg: #fdf3f2; --pill-edge: #eea7a2; --pill-ink: #a8322b; }
.console-pill-accepted-not-yet,
.console-pill-outbound-retrying { --pill-bg: #fef8e6; --pill-edge: #f0cf6a; --pill-ink: #6b4a0c; }
/* Never asked: not_yet with nothing coming, so neither the amber of waiting
   nor the red of a refusal. */
.console-pill-accepted-never-asked,
/* Barred (#338): the guard refused it and nothing left, which is neither a
   failure to fix nor a delivery — final, so not the amber of waiting either.
   Refused (#358) is the Receiver's refusal of the contact, final the same way. */
.console-pill-outbound-refused,
.console-pill-outbound-barred { --pill-bg: #f3f2ef; --pill-edge: #cfccc4; --pill-ink: #5c5a54; }
.console-pill-outbound-failed { --pill-bg: #b93a31; --pill-edge: #b93a31; --pill-ink: #ffffff; }
/* Redundant keeps the neutral default: the Receiver already had it, which is
   neither a delivery nor anything to correct. */

td.console-transaction-id { font-family: var(--console-mono); font-size: var(--console-text-xs); }
.console-leads td.console-accepted,
.console-leads td.console-outbound,
.console-timeline td.console-outbound { white-space: nowrap; }

/* The frame the summary loads into holds its place while it counts, so the
   table does not jump when the numbers arrive. */
.console-summary-frame { display: block; min-height: 78px; margin: 0 0 18px; }
.console-summary-frame .console-summary { margin: 0; }
.console-summary-loading { margin: 0; padding: 26px var(--console-space-4); color: var(--console-ink-3); font-size: var(--console-text-sm); }
/* The same bar above the table and below it: where the page sits on the
   left, the way on to the right. */
.console-pager { display: flex; align-items: baseline; gap: var(--console-space-4); margin: 10px 0; font-size: var(--console-text-sm); }
.console-pager .console-showing { margin: 0 auto 0 0; color: var(--console-ink-3); font-variant-numeric: tabular-nums; }

/* An Order status other than the ordinary one — a refund, say — under the
   Order's lines. */
.console-order .console-order-status {
  display: inline-block;
  margin-top: var(--console-space-1);
  padding: 0 6px;
  border-radius: var(--console-radius-sm);
  background: var(--console-person-bg);
  color: var(--console-person-ink);
  font-size: var(--console-text-xs);
  font-weight: 600;
}

/* ============================================================
   The conditions on the leads and conversions lists — #145.
   What is applied reads as a pill each, under the bar; one
   popover builds or edits a single condition.

   ⚠️ SCOPED TO `.console-list-filters` ON PURPOSE. `.console-conditions` is
   already a table on the Relay sheet and `.console-condition-builder` already a
   pane on the Relay form (#114), and neither wants any of this. The bar is the
   only place these names mean pills and a popover.

   ⚠️ THE BUILDER IS HIDDEN BY THE CONTROLLER AND NEVER BY THIS FILE. It is an
   ordinary set of filter controls, and with JavaScript off it is how a condition
   is added (ADR-0072) — so the only rule about it here is what `hidden` means
   once `condition_filters_controller` sets it.
   ============================================================ */

/* The wrapper carries the vocabulary and nothing visual, so its three children
   sit on the filter bar's own flex line: the *Add filter* button beside the other
   filters, the pills and the fieldset on lines of their own below. */
.console-list-filters .console-conditions { display: contents; }

.console-list-filters .console-condition-pills {
  order: 98;
  flex-basis: 100%;
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-top: 2px;
  padding-top: 10px;
  border-top: 1px solid var(--console-rule);
}
.console-list-filters .console-condition-pills:empty { display: none; }

/* A pill is the anchor for its own popover, which is why it is positioned. */
.console-list-filters .console-condition {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 2px 4px 2px 9px;
  border: 1px solid var(--console-rule-3);
  border-radius: var(--console-radius-pill);
  background: var(--console-sunken);
  font-size: var(--console-text-sm);
  line-height: 20px;
}
.console-list-filters .console-condition-reads { display: inline-flex; align-items: center; gap: 5px; cursor: pointer; }
.console-list-filters .console-condition-reads code { background: none; border: 0; padding: 0; }
.console-list-filters .console-condition-operator { color: var(--console-ink-3); }
.console-list-filters .console-condition:hover { background: var(--console-hover); border-color: var(--console-ink-4); }

/* A condition the list cannot read is shown and never dropped, so the pill says
   so three ways: the refusal's colour, a mark before the sentence, and the
   message itself in `.console-condition-fault` — a state is never the colour
   alone. The mark is generated content because the pill is the view's own markup
   and the controller adds no element to it; the word carries the meaning, and the
   mark only draws the eye. */
.console-list-filters .console-condition-refused {
  border-color: var(--console-person-edge);
  background: var(--console-person-bg);
  color: var(--console-person-ink);
}
.console-list-filters .console-condition-refused .console-condition-reads::before {
  content: "\26A0";
  font-size: 12px;
  line-height: 1;
}
.console-list-filters .console-condition-refused .console-condition-operator { color: var(--console-person-ink); }
.console-list-filters .console-condition-fault {
  padding-left: 6px;
  border-left: 1px solid var(--console-person-edge);
  color: var(--console-person-ink);
  font-size: var(--console-text-xs);
  font-weight: 600;
}

/* The `×` is a link, so it drops its condition with JavaScript off too — and it
   gives up the link's underline to read as the pill's own button. */
.console-list-filters .console-condition-drop {
  padding: 0 5px;
  border: 0;
  color: var(--console-ink-4);
  font-size: 15px;
  line-height: 1;
}
.console-list-filters .console-condition-drop:hover { border: 0; color: var(--console-person-edge); }
.console-list-filters .console-condition-refused .console-condition-drop { color: var(--console-person-ink); }

/* The button the controller puts where the fieldset was, and the box it anchors. */
.console-list-filters .console-condition-anchor { position: relative; align-self: flex-end; }
.console-list-filters .console-condition-add { font-weight: 600; }

/* The fieldset the three controls live in: on its own line under the pills, and
   presentable as itself, because with JavaScript off it is the whole gesture. */
.console-list-filters .console-condition-builder {
  order: 99;
  flex-basis: 100%;
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: var(--console-space-3) 14px;
  margin: 2px 0 0;
  padding: 4px 0 0;
  border: 0;
  border-top: 1px solid var(--console-rule);
}
.console-list-filters .console-condition-builder[hidden] { display: none; }
.console-list-filters .console-condition-builder legend {
  padding: 0;
  font-size: var(--console-label);
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--console-ink-3);
}

/* The popover: step one finds a field, step two says how it is asked. */
.console-list-filters .console-condition-popover {
  position: absolute;
  top: calc(100% + 6px);
  left: 0;
  z-index: 50;
  display: grid;
  gap: var(--console-space-2);
  width: 22rem;
  padding: 10px;
  background: var(--console-surface);
  border: 1px solid var(--console-rule-3);
  border-radius: var(--console-radius);
  box-shadow: 0 10px 30px rgba(27, 26, 24, 0.14);
  text-align: left;
}
/* The bar sizes its own controls by what they hold; inside the box they are all
   one column wide. */
.console-list-filters .console-condition-popover input[type="search"],
.console-list-filters .console-condition-popover input[type="text"],
.console-list-filters .console-condition-popover select {
  box-sizing: border-box;
  width: 100%;
  min-width: 0;
}

.console-list-filters .console-condition-fields { display: grid; max-height: 15rem; overflow-y: auto; }
.console-list-filters .console-condition-fields button {
  padding: 3px 6px;
  border: 0;
  border-radius: var(--console-radius-sm);
  background: none;
  font-family: var(--console-mono);
  font-size: var(--console-text-xs);
  text-align: left;
}
.console-list-filters .console-condition-fields button:hover { background: var(--console-sunken); }
.console-list-filters .console-condition-group {
  padding: 6px 6px 2px;
  font-size: var(--console-label);
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--console-ink-4);
}

.console-list-filters .console-condition-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--console-space-2);
}
.console-list-filters .console-condition-head code { background: none; border: 0; padding: 0; font-size: var(--console-text-sm); }
.console-list-filters .console-condition-back {
  padding: 1px 6px;
  border: 0;
  background: none;
  color: var(--console-link);
  font-size: var(--console-text-xs);
}
.console-list-filters .console-condition-back:hover { background: var(--console-sunken); color: var(--console-link-hover); }

.console-list-filters .console-condition-ops { display: grid; gap: 1px; }
/* The bar's labels are uppercase captions above a control; these are the reading
   of an operator, beside its radio. */
.console-list-filters .console-condition-ops label {
  display: flex;
  align-items: center;
  gap: 6px;
  align-self: auto;
  margin: 0;
  padding: 0;
  font-size: var(--console-text-sm);
  font-weight: 400;
  letter-spacing: 0;
  text-transform: none;
  color: var(--console-ink);
}
.console-list-filters .console-condition-ops input[type="radio"] { margin: 0; accent-color: var(--console-link); }

.console-list-filters .console-condition-slot { display: grid; gap: var(--console-space-1); }
.console-list-filters .console-condition-slot:empty { display: none; }
.console-list-filters .console-condition-hint { color: var(--console-ink-3); font-size: var(--console-label); }

.console-list-filters .console-condition-foot { display: flex; justify-content: flex-end; gap: 6px; }
.console-list-filters .console-condition-apply { font-weight: 600; }

/* Sending facts for Relay evaluation — #161. The selection bar sits between the
   list's filters and its table; the count is a reading, not a control. */
.console-evaluation { margin-top: var(--console-space-2); }
.console-evaluation-count {
  align-self: flex-end;
  color: var(--console-ink-2);
  font-size: var(--console-text-sm);
  font-variant-numeric: tabular-nums;
}
.console-select { width: 2rem; text-align: center; }
.console-visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}
.console-inactive { color: var(--console-ink-3); font-size: var(--console-text-xs); }
.console-evaluation-preview td:not(.console-relay-name) { font-variant-numeric: tabular-nums; text-align: right; }
.console-evaluation-opened { margin-top: var(--console-space-3); }

/* *Render again* on one Dispatch — #160. On a sheet's row it is the last cell and
   takes no more width than its button; on the Dispatch's page it is the last
   section. */
.console-render-again-cell { width: 1%; white-space: nowrap; }
.console-render-again-section { margin-top: var(--console-space-3); }

/* An Integration's Product Mapping — #206, #200's variant C. The entry page is a
   column of cards, one per field write, beside a rail holding the names, the
   Receiver's product, Save and Ignore; below 860px the rail follows the cards. */
.console-section-head { display: flex; justify-content: space-between; align-items: baseline; margin: var(--console-space-4) 0 var(--console-space-2); }
.console-section-head h2 { margin: 0; }
.console-count { font-variant-numeric: tabular-nums; color: var(--console-ink-3); font-size: var(--console-text-xs); }
.console-chip {
  display: inline-block;
  padding: 0 8px;
  border: 1px solid var(--console-rule-3);
  border-radius: var(--console-radius-pill);
  font-size: var(--console-text-xs);
  background: var(--console-surface);
}
.console-tag { display: inline-block; padding: 0 6px; border-radius: 3px; font-size: 11.5px; font-weight: 400; vertical-align: middle; }
.console-tag-ignored { background: var(--console-sunken); color: var(--console-ink-3); border: 1px dashed var(--console-rule-3); }
.console-tag-new { background: var(--console-good-bg); color: var(--console-good-ink); border: 1px solid var(--console-good-rule); }
.console-entry-ignored td { background: var(--console-sunken); }
.console-awaiting-actions { white-space: nowrap; }
.console-add-to-entry { display: inline-flex; gap: var(--console-space-1); margin-left: var(--console-space-2); }

.console-entry-layout { display: grid; grid-template-columns: minmax(0, 1fr) 310px; gap: 22px; align-items: start; }
@media (max-width: 860px) { .console-entry-layout { grid-template-columns: 1fr; } }
.console-entry-side h2 { margin: var(--console-space-4) 0 var(--console-space-1); }
.console-card {
  border: 1px solid var(--console-rule-2);
  border-radius: var(--console-radius);
  background: var(--console-surface);
  padding: 12px 14px;
  margin: 10px 0;
}
.console-write-draft { border-style: dashed; border-color: var(--console-link); }
.console-card-head { display: flex; justify-content: space-between; align-items: baseline; gap: 10px; }
.console-card-head h3 { margin: 0; font-size: var(--console-text); }
.console-type {
  font-size: 11.5px;
  font-weight: 400;
  color: var(--console-ink-3);
  background: var(--console-sunken);
  border-radius: 3px;
  padding: 1px 6px;
  margin-left: 6px;
}
.console-remove-write { font-size: var(--console-text-xs); color: var(--console-ink-3); }
.console-write-value { display: flex; flex-wrap: wrap; gap: 6px 10px; align-items: center; padding-top: 8px; }
.console-field-picker { display: flex; gap: var(--console-space-2); margin-top: var(--console-space-2); }
/* A Price table (#209): each value of a card, the prices that lead to it as
   chips, and the cost of an edit beside the value. */
.console-value { border-top: 1px solid var(--console-rule); }
.console-value:first-of-type { border-top: 0; }
.console-prices { flex-basis: 100%; display: flex; flex-wrap: wrap; gap: 5px; align-items: center; }
.console-price { font-family: var(--console-mono); }
.console-price label { cursor: pointer; color: var(--console-ink-4); margin-left: 3px; }
.console-add-price { display: inline-flex; gap: 3px; align-items: center; }
.console-add-price input { width: 80px; text-align: right; font-family: var(--console-mono); }
.console-tag-changed { background: var(--console-person-bg); color: var(--console-person-ink); border: 1px solid var(--console-person-edge); }
.console-link-button { border: 0; background: none; color: var(--console-link); padding: 2px; cursor: pointer; font-size: var(--console-text-sm); }
.console-entry-rail .console-panel h3 { margin: 0 0 6px; font-size: var(--console-text-sm); }
.console-entry-rail textarea, .console-entry-rail select, .console-entry-rail input[type="text"] { width: 100%; box-sizing: border-box; }
.console-entry-rail .console-save-entry { width: 100%; }
.console-entry-ignored-panel { background: var(--console-sunken); border-style: dashed; }
.console-ignore { margin-top: var(--console-space-3); }
/* A pixel's match quality (#249): the page shown to a client. Two large
   numbers per event, the baseline and the latest, and a quiet curve under them
   on Meta's whole 0–10 scale. The curve's ink is the page's own, and the
   numbers are text, never the line's colour. */
.console-match-quality-facts {
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: 4px var(--console-space-4);
  margin: var(--console-space-4) 0 var(--console-space-5);
  color: var(--console-ink-2);
}
.console-match-quality-facts dt { color: var(--console-ink-3); }
.console-match-quality-facts dd { margin: 0; }
.console-match-quality-facts .console-empty,
.console-match-quality-event .console-empty {
  margin: 0;
  padding: 0;
  background: none;
  border: 0;
  font-size: var(--console-text);
  color: var(--console-ink-3);
}
.console-match-quality-event {
  margin: 0 0 var(--console-space-5);
  padding: var(--console-space-4) var(--console-space-5);
  background: var(--console-surface);
  border: 1px solid var(--console-rule-2);
  border-radius: var(--console-radius);
}
.console-match-quality-event h2 { margin: 0 0 var(--console-space-3); }
.console-match-quality-numbers { display: flex; flex-wrap: wrap; gap: var(--console-space-4) var(--console-space-6); }
.console-match-quality-numbers > div { min-width: 12rem; max-width: 36ch; }
.console-match-quality-label {
  display: block;
  font-size: var(--console-label);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--console-ink-3);
}
.console-match-quality-score { font-size: 48px; font-weight: 600; line-height: 1.1; font-variant-numeric: tabular-nums; }
.console-match-quality-out-of { font-size: 18px; color: var(--console-ink-3); }
.console-match-quality-not-receiving { margin: 8px 0 4px; font-size: 17px; color: var(--console-ink-2); }
.console-match-quality-curve { margin: var(--console-space-4) 0 0; }
.console-match-quality-curve svg { display: block; width: 100%; max-width: 640px; height: auto; }
.console-match-quality-grid { stroke: var(--console-rule-2); stroke-width: 1; }
.console-match-quality-axis { fill: var(--console-ink-4); font-size: 11px; }
.console-match-quality-line { fill: none; stroke: var(--console-link); stroke-width: 2; stroke-linejoin: round; }
.console-match-quality-point { fill: var(--console-link); stroke: var(--console-surface); stroke-width: 2; }
.console-match-quality-days { margin-top: var(--console-space-2); font-size: var(--console-text-sm); color: var(--console-ink-3); }
.console-match-quality-days td, .console-match-quality-days th { padding: 2px var(--console-space-4) 2px 0; text-align: left; }
/* Our key coverage beside Meta's score (#250): one small table per
   `action_source`, the keys down the side and the two windows across, the
   shares right-aligned in tabular figures so a column reads as a column. */
.console-match-quality-keys { margin-top: var(--console-space-5); }
.console-match-quality-keys h3 { margin: 0 0 var(--console-space-2); }
.console-match-quality-keys .console-note { max-width: 72ch; color: var(--console-ink-3); }
.console-match-quality-coverage { margin: var(--console-space-4) var(--console-space-6) 0 0; display: inline-table; border-collapse: collapse; vertical-align: top; }
.console-match-quality-coverage caption { text-align: left; font-weight: 600; padding-bottom: var(--console-space-2); }
.console-match-quality-coverage th, .console-match-quality-coverage td { padding: 3px var(--console-space-4) 3px 0; text-align: left; border-bottom: 1px solid var(--console-rule-2); }
.console-match-quality-coverage thead th { vertical-align: bottom; color: var(--console-ink-3); font-weight: 600; }
.console-match-quality-coverage thead th span { display: block; font-weight: 400; font-size: var(--console-text-sm); }
.console-match-quality-coverage tbody th { font-weight: 400; color: var(--console-ink-2); }
.console-match-quality-coverage td { text-align: right; font-variant-numeric: tabular-nums; min-width: 7rem; }
.console-match-quality-coverage thead th + th { text-align: right; }
/* Reports (#286): the header as a two-column reading, the rows stepped by the
   level Reporting gave them, and every metric right-aligned in tabular
   figures. The indent is the only thing the level decides here. */
.console-report-result { margin-top: var(--console-space-5); }
.console-report-header, .console-report-definitions { display: grid; grid-template-columns: 11rem minmax(0, 1fr); gap: 4px var(--console-space-4); margin: 0 0 var(--console-space-4); }
.console-report-header div, .console-report-definitions div { display: contents; }
.console-report-header dt, .console-report-definitions dt { color: var(--console-ink-3); }
.console-report-header dd, .console-report-definitions dd { margin: 0; }
.console-report-definitions { font-size: var(--console-text-sm); margin-top: var(--console-space-4); }
.console-report .console-report-metric { text-align: right; font-variant-numeric: tabular-nums; }
.console-report tbody tr.console-report-level-0 { font-weight: 600; }
.console-report tfoot td { font-weight: 600; border-top: 2px solid var(--console-rule-2); }

/* ============================================================
   THE PAGE NEVER SCROLLS SIDEWAYS — #347. Below are the screens'
   rules that assumed a desktop's width: a two-column reading, a
   row that never wraps, a box with a fixed width. Only a table's
   wrapper and a code block scroll inside themselves; everything
   else stacks or wraps. The breakpoints are the Console's two:
   1023px (the sidebar becomes a drawer) and 759px (a phone).
   ============================================================ */

/* A block of code or JSON scrolls in its own box rather than widening the page;
   a screen's own `max-width` on a `pre` still caps it where it is narrower. */
:where(main) pre { max-width: 100%; overflow-x: auto; }

/* ⚠️ A TOKEN, A DIGEST OR A URL HAS NO PLACE TO BREAK, so outside a table it is
   allowed to break anywhere rather than run past its box. Not inside a table:
   there `anywhere` would shrink a column's minimum and wrap an id letter by
   letter instead of letting the wrapper scroll — which is what the tables'
   declared widths in console-3-tables.css exist to prevent. */
/* ⛔ NOT THE JSON EDITOR'S LAYER, which must break its lines exactly where the
   textarea above it does. */
:where(main) :where(dd, p, li, code, pre, h1, h2, h3):not(.console-table *):not(.console-json-layer) { overflow-wrap: anywhere; }

@media (max-width: 1023px) {
  /* Three columns of field names need a desktop's width to be columns. */
  .console-catalog-fields { columns: 2; }

  /* A lead carried by several Relays holds their pills on one line, and that
     line alone can push the leads list and a contact's timeline far past
     their floors. Without a desktop's width the pills stack in their cell,
     each still one unbroken word, and the row grows down rather than across. */
  .console-leads td.console-outbound,
  .console-timeline td.console-outbound { white-space: normal; }
}

@media (max-width: 759px) {
  /* A checklist, a profile and an Account read as label over value: a 13rem
     label column leaves a phone a value column a few words wide. */
  dl.console-account, .console-profile dl, .console-checklist dl,
  .console-report-header, .console-report-definitions,
  .console-match-quality-facts {
    grid-template-columns: minmax(0, 1fr);
  }
  dl.console-account dd, .console-profile dd, .console-checklist dd { margin-top: 2px; }
  dl.console-account dd:first-of-type, .console-profile dd:first-of-type, .console-checklist dd:first-of-type { margin-top: 2px; }
  .console-report-header dd, .console-report-definitions dd, .console-match-quality-facts dd { margin-bottom: var(--console-space-2); }

  /* The boxes keep their surface and give back the padding a phone cannot spare. */
  .console-profile, .console-standing, .console-checklist section,
  dl.console-account, .console-checklist dl,
  .console-token-issued, .console-integration, .console-panel,
  .console-lead-arrival, .console-lead-group, .console-lead-reading,
  .console-service-card, .console-match-quality-event {
    padding: 14px var(--console-space-3);
  }
  .console-empty { padding: 18px var(--console-space-3); }

  /* Rows that were one line on a desktop wrap onto the next. */
  .console-narrowed,
  .console-pager,
  .console-section-head,
  .console-card-head,
  .console-snippet-head,
  .console-json-editor-bar,
  .console-field-picker,
  .console-issue-token {
    flex-wrap: wrap;
  }
  .console-issue-token { align-items: stretch; }
  .console-issue-token > * { flex: 1 1 100%; }
  .console-issue-token input[type="text"] { max-width: none; }

  /* The list's summary: one number to a row, read down. */
  .console-summary { flex-direction: column; gap: var(--console-space-2); padding: var(--console-space-3); }
  .console-summary > div { display: flex; align-items: baseline; justify-content: space-between; gap: var(--console-space-3); }
  .console-summary dd { margin: 0; font-size: 18px; }

  /* The list filters: each field the screen's width. The 18rem search and the
     8rem text boxes were sized for one wrapping line. */
  .console-list-filters .console-filter { flex: 1 1 100%; min-width: 0; }
  .console-list-filters input[type="search"],
  .console-list-filters input[type="text"],
  .console-list-filters select {
    box-sizing: border-box;
    width: 100%;
    min-width: 0;
  }
  .console-list-filters .console-condition-anchor { align-self: stretch; }

  /* The selection bar above the leads and conversions lists wraps each field
     in a div of its own, which the filter bar's sibling rules never reach: each
     takes the line, and the Relay's caption sits over its select. */
  .console-evaluation .console-filter { flex: 1 1 100%; min-width: 0; }
  .console-evaluation .console-filter > label:not(input[type="checkbox"] + label) { display: block; margin-bottom: var(--console-space-1); }
  /* The popover hangs from its button; on a phone it is never wider than the
     screen between the gutters. */
  .console-list-filters .console-condition-popover { width: min(22rem, calc(100vw - 2 * var(--console-space-3) - 2px)); box-sizing: border-box; }

  /* Field names in one column; a phone has no width for two. */
  .console-catalog-fields { columns: 1; }

  /* Meta's coverage tables sit side by side on a desktop; on a phone each takes
     the width and gives up the floor under its share columns. */
  .console-match-quality-coverage { display: table; width: 100%; margin-right: 0; }
  .console-match-quality-coverage td { min-width: 0; }
  .console-match-quality-score { font-size: 40px; }

  /* The dark one-time token's URL and its Copy button stack. */
  .console-token-issued .console-partner-url { flex-wrap: wrap; }
}

/* ============================================================
   A THUMB IS NOT A CURSOR. On a phone, or wherever the pointer is
   a finger, a control in the page is at least 40px tall, so it can
   be hit without zooming. A desktop with a mouse keeps its dense
   controls. Links that are controls — the pager, a screen's
   actions, a breadcrumb — trade the underline border, which would
   sit at the foot of the taller box, for a text underline.
   ============================================================ */
@media (max-width: 759px), (pointer: coarse) {
  main :is(button, input[type="submit"], input[type="button"], select):not(.console-json-jump),
  main input:not([type="checkbox"]):not([type="radio"]):not([type="hidden"]) {
    min-height: 40px;
  }
  main input[type="checkbox"], main input[type="radio"] { width: 20px; height: 20px; }
  /* A fold's summary is a control too; the padding lifts it without a box. */
  main summary { padding: 10px 0; }

  .console-pager a,
  .console-actions a,
  .console-breadcrumb a,
  .console-service-action a,
  .console-section-head a {
    display: inline-flex;
    align-items: center;
    min-height: 40px;
    border-bottom: 0;
    text-decoration: underline;
    text-decoration-color: rgba(47, 93, 138, 0.3);
    text-underline-offset: 3px;
  }
  .console-list-filters .console-condition-drop { min-width: 32px; min-height: 32px; display: inline-flex; align-items: center; justify-content: center; text-decoration: none; }
}
