/**
 * crm — Customer health and the send guard. Shared primitives live in style.css.
 *
 * Three regions, in the order the screen reads:
 *
 *   1. The lifecycle board — a count per wallet lifecycle state.
 *   2. The send guard — the only control here that spends money or reaches a person.
 *   3. The at-risk queue — a call list, banded by health score.
 *
 * Nothing here invents a colour. Every rule uses a token from style.css, corners are
 * square without exception, and the one depth device on the screen is the registration
 * offset on the at-risk plate — hard, zero blur, as DESIGN.md permits on a document
 * plate and nowhere else.
 *
 * Marking Orange (`--mark`) appears once, on the Check button, because that is the
 * screen's single primary action. Every other signal takes Marking Ink (`--mark-ink`),
 * which is the only orange legal below 24px, and every one of them also prints its word.
 */

/* --------------------------------------------------------------------------
   1. Lifecycle board
   --------------------------------------------------------------------------
   Hairlines are the grid's own gaps over a `--rule` ground, so the divisions hold
   however the cells wrap. Ink rules top and bottom, as in the approved design.
   -------------------------------------------------------------------------- */

#view-crm #crm-lifecycle {
  display: grid;
  grid-auto-flow: row;
  grid-template-columns: repeat(6, minmax(0, 1fr));
  gap: var(--hair);
  background: var(--rule);
  border: 0;
  border-top: 2px solid var(--ink);
  border-bottom: 2px solid var(--ink);
  overflow: visible;
  margin-bottom: var(--lg);
}

#view-crm #crm-lifecycle .stage {
  background: var(--paper-lit);
  border: 0;
  padding: var(--md) var(--sm);
  text-align: center;
}

#view-crm #crm-lifecycle .stage .n {
  font-size: 1.75rem;
  line-height: 1.05;
  color: var(--ink);
}

#view-crm #crm-lifecycle .stage .label {
  color: var(--ink-secondary);
  overflow-wrap: anywhere;
}

/* The shared board paints its LAST cell in the Pula field, because on the sales board
   the last stage is the one that pays. On this board the last state is `churned`, so
   the rule has to be undone before it says the opposite of what it means. */
#view-crm .stage-board .stage:last-child { background: var(--paper-lit); }
#view-crm .stage-board .stage:last-child .n { color: var(--ink); }
#view-crm .stage-board .stage:last-child .label { color: var(--ink-secondary); }

/* Recessed states: the wallet has stopped, or stopped for good. Tonal layering only —
   the state's own word is printed under every count, so the tone adds nothing that is
   not already read. */
#view-crm .stage-board .stage[data-state='suspended'],
#view-crm .stage-board .stage[data-state='churned'] { background: var(--paper-sunk); }

/* `active` is the state that pays, so it takes the committed field. */
#view-crm .stage-board .stage[data-state='active'] { background: var(--pula); }
#view-crm .stage-board .stage[data-state='active'] .n { color: var(--paper-lit); }
#view-crm .stage-board .stage[data-state='active'] .label { color: var(--pula-tint); }

#view-crm .crm-board-loading {
  grid-column: 1 / -1;
  background: var(--paper-lit);
  margin: 0;
  padding: var(--md);
}

/* --------------------------------------------------------------------------
   2. Send guard
   -------------------------------------------------------------------------- */

/* The rule the guard enforces, quoted in a ruled inset. DESIGN.md asks for the rule to
   be quoted inside the verdict rather than summarised beside it. */
#view-crm .crm-rule {
  background: var(--paper-lit);
  border: 1px solid var(--rule);
  border-left: 2px solid var(--ink);
  padding: var(--sm) var(--md);
  color: var(--ink);
  max-width: 72ch;
}

#view-crm .crm-guard-row { align-items: stretch; }
#view-crm #crm-waid {
  font-family: var(--mono);
  font-size: 0.8125rem;
  letter-spacing: -0.01em;
  flex: 1 1 220px;
  max-width: 320px;
}

/* The single primary action on the screen, and the only Marking Orange on it.
   Ink on orange, which is both the accessible pairing and the authentic one. */
#view-crm #crm-guard-check { flex: 0 0 auto; }

/* The idle note sits outside the live region, so switching to this view does not
   announce a sentence nobody asked for. It hides itself the moment a real result
   lands in the box above it. */
#view-crm .crm-guard-idle {
  border-left: 2px solid var(--rule);
  padding: var(--sm) 0 var(--sm) var(--md);
  margin-bottom: var(--lg);
  font-size: 0.875rem;
  color: var(--ink-secondary);
  max-width: 72ch;
}
#view-crm #crm-guard:not(:empty) + .crm-guard-idle { display: none; }

/* The result plate. style.css already gives #crm-guard its sheet; this only sets the
   left rule per verdict, and the rule is never the only difference — the verdict word
   is printed at the head of the plate. */
#view-crm #crm-guard[data-verdict='free'] { border-left-color: var(--ink); }
#view-crm #crm-guard[data-verdict='paid'] { border-left-color: var(--pula); }
#view-crm #crm-guard[data-verdict='blocked'],
#view-crm #crm-guard[data-verdict='denied'],
#view-crm #crm-guard[data-verdict='failed'] { border-left-color: var(--mark-ink); }
#view-crm #crm-guard[data-verdict='unknown'],
#view-crm #crm-guard[data-verdict='checking'],
#view-crm #crm-guard[data-verdict='empty'] { border-left-color: var(--rule); }

#view-crm .crm-verdict { margin-bottom: var(--md); }

#view-crm .crm-verdict-line {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: var(--sm) var(--md);
  margin: 0 0 var(--sm);
}

#view-crm .crm-verdict-label {
  font-family: var(--mono);
  font-size: 0.625rem;
  font-weight: 500;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-secondary);
}

#view-crm .crm-verdict-word {
  font-family: var(--display);
  font-size: 1.75rem;
  font-weight: 700;
  font-variation-settings: 'wdth' 118;
  letter-spacing: -0.025em;
  line-height: 1;
  text-transform: uppercase;
  color: var(--ink);
}
#view-crm .crm-verdict[data-verdict='paid'] .crm-verdict-word { color: var(--pula-deep); }
#view-crm .crm-verdict[data-verdict='blocked'] .crm-verdict-word,
#view-crm .crm-verdict[data-verdict='denied'] .crm-verdict-word,
#view-crm .crm-verdict[data-verdict='failed'] .crm-verdict-word { color: var(--mark-ink); }
#view-crm .crm-verdict[data-verdict='checking'] .crm-verdict-word,
#view-crm .crm-verdict[data-verdict='empty'] .crm-verdict-word,
#view-crm .crm-verdict[data-verdict='idle'] .crm-verdict-word { color: var(--ink-secondary); }

/* What this send costs, as a word. Never a colour on its own. */
#view-crm .crm-verdict-cost {
  display: inline-block;
  font-family: var(--mono);
  font-size: 0.625rem;
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  padding: 2px 6px;
  border: 1px solid var(--rule);
  color: var(--ink-secondary);
  white-space: nowrap;
}
#view-crm .crm-verdict[data-verdict='free'] .crm-verdict-cost { border-color: var(--ink); color: var(--ink); }
#view-crm .crm-verdict[data-verdict='paid'] .crm-verdict-cost { border-color: var(--pula); color: var(--pula-deep); }
#view-crm .crm-verdict[data-verdict='blocked'] .crm-verdict-cost,
#view-crm .crm-verdict[data-verdict='denied'] .crm-verdict-cost,
#view-crm .crm-verdict[data-verdict='failed'] .crm-verdict-cost { border-color: var(--mark-ink); color: var(--mark-ink); }

/* The system's own sentence, then the rule that produced it. */
#view-crm .crm-verdict-say {
  margin: 0 0 var(--xs);
  font-size: 1rem;
  line-height: 1.45;
  color: var(--ink);
  max-width: 68ch;
}
#view-crm .crm-verdict-why {
  margin: 0;
  font-size: 0.875rem;
  line-height: 1.55;
  color: var(--ink-secondary);
  max-width: 68ch;
}

/* The facts the guard read, as a ruled key. Labels and values are measured, so both
   set in mono; the notes beside them are prose and set in Archivo. */
#view-crm ul.guard {
  border-top: 1px solid var(--rule);
  margin-top: var(--md);
}
#view-crm ul.guard li {
  display: grid;
  grid-template-columns: 152px minmax(0, 1fr);
  gap: var(--xs) var(--md);
  padding: var(--sm) 0;
  border-bottom: 1px solid var(--rule);
}
#view-crm ul.guard li:last-child { border-bottom: 0; }

/* A line the parser did not recognise keeps its own words, in one column, rather than
   being forced under a label it does not have. */
#view-crm ul.guard li.crm-fact-plain { grid-template-columns: 1fr; }

#view-crm .crm-fact-k {
  font-family: var(--mono);
  font-size: 0.625rem;
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-secondary);
  padding-top: 3px;
}
#view-crm .crm-fact-v {
  font-family: var(--mono);
  font-size: 0.8125rem;
  font-variant-numeric: tabular-nums;
  color: var(--ink);
  overflow-wrap: anywhere;
}
#view-crm .crm-fact-v .crm-fact-word { font-weight: 600; }
#view-crm .crm-fact-v .crm-fact-alarm { color: var(--mark-ink); font-weight: 600; }
#view-crm .crm-fact-v .crm-fact-stamp { color: var(--ink-secondary); margin-left: var(--sm); }
#view-crm .crm-fact-note {
  grid-column: 2;
  font-family: var(--display);
  font-size: 0.875rem;
  line-height: 1.5;
  color: var(--ink-secondary);
}
#view-crm .crm-fact-note .crm-fact-classes {
  font-family: var(--mono);
  font-size: 0.75rem;
  color: var(--ink);
}

#view-crm .crm-guard-foot {
  margin: var(--md) 0 0;
  padding-top: var(--sm);
  border-top: 1px solid var(--rule);
  font-size: 0.8125rem;
  line-height: 1.5;
  color: var(--ink-secondary);
  max-width: 68ch;
}

/* --------------------------------------------------------------------------
   3. At risk
   -------------------------------------------------------------------------- */

#view-crm .crm-head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--md);
  flex-wrap: wrap;
  margin: var(--lg) 0 var(--md);
  padding-bottom: var(--sm);
}
#view-crm .crm-head-main { flex: 1 1 320px; min-width: 0; }
#view-crm .crm-head-main h3 { margin-top: 0; }
#view-crm .crm-head-main p { margin-bottom: 0; max-width: 66ch; }
#view-crm .crm-lede {
  font-size: 0.9375rem;
  line-height: 1.55;
  color: var(--ink-secondary);
}
#view-crm .crm-head-aside {
  flex: 0 0 auto;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--xs);
}

/* A band name is a classification, not prose. It sets in mono wherever it is printed. */
#view-crm .crm-band-name {
  font-family: var(--mono);
  font-size: 0.75rem;
  color: var(--ink);
}

#view-crm .crm-count {
  font-family: var(--mono);
  font-size: 0.625rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-secondary);
  font-variant-numeric: tabular-nums;
  margin: 0;
}

/* The queue is refreshing. `aria-busy` on the section carries this to a screen reader
   already; this is the same fact for everyone else. */
#view-crm[aria-busy='true'] .crm-count::after {
  content: ' · updating';
  color: var(--ink);
}

/* The watch toggle. A native checkbox recoloured by `accent-color` renders with a
   radius on most platforms, and radius is the one thing this system never allows. */
#view-crm #crm-include-watch {
  appearance: none;
  -webkit-appearance: none;
  position: relative;
  width: 15px;
  height: 15px;
  flex: 0 0 auto;
  background-color: var(--paper-lit);
  border: 1px solid var(--ink);
  /* The two bars of the checked mark run corner to corner and are trimmed at the
     box, exactly as a printed cross on a form is trimmed by its own rule. */
  overflow: hidden;
}

/* The checked mark is a struck cross, drawn as two ruled ink bars rather than as a
   glyph or an icon font: a 2.6px bar the length of the box's diagonal, turned 45° each
   way. Both take their colour from `--ink` directly, so nothing here is a gradient,
   a fade or a shadow. */
#view-crm #crm-include-watch:checked::before,
#view-crm #crm-include-watch:checked::after {
  content: '';
  position: absolute;
  left: 50%;
  top: 50%;
  width: 2.6px;
  height: 19px;
  background-color: var(--ink);
  transform: translate(-50%, -50%) rotate(45deg);
}
#view-crm #crm-include-watch:checked::after {
  transform: translate(-50%, -50%) rotate(-45deg);
}

/* The document plate. Registration crosses at the head and a hard 3px ink offset with
   zero blur — the only depth device DESIGN.md permits, and only here. */
#view-crm .crm-plate {
  position: relative;
  background: var(--paper-lit);
  border: 1px solid var(--ink);
  box-shadow: 3px 3px 0 0 var(--ink);
  padding: 24px var(--md) var(--sm);
  margin: 0 3px var(--md) 0;
}
/* Each cross is one 9px square of flat ink cut down to a 1px horizontal and a 1px
   vertical arm. Solid colour and a clip, so there is no gradient, no fade and no
   second paint technique to explain. */
#view-crm .crm-plate::before,
#view-crm .crm-plate::after {
  content: '';
  position: absolute;
  top: 7px;
  width: 9px;
  height: 9px;
  background-color: var(--ink);
  clip-path: polygon(
    4px 0, 5px 0, 5px 4px, 9px 4px,
    9px 5px, 5px 5px, 5px 9px, 4px 9px,
    4px 5px, 0 5px, 0 4px, 4px 4px
  );
  pointer-events: none;
}
#view-crm .crm-plate::before { left: 7px; }
#view-crm .crm-plate::after { right: 7px; }

#view-crm .crm-plate .scroller {
  border-top: 0;
  margin-bottom: 0;
}

/* Shown only where the table cannot fit, so nobody is told the page scrolls when it
   does not. Hidden content with no way to know it is there is a failure, not a detail. */
#view-crm .crm-scroll-note {
  display: none;
  font-family: var(--mono);
  font-size: 0.625rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-secondary);
  margin: 0 0 var(--lg);
}
@media (max-width: 760px) {
  #view-crm .crm-scroll-note { display: block; }
}

#view-crm #crm-atrisk { min-width: 620px; }
#view-crm #crm-atrisk th {
  border-bottom: 2px solid var(--ink);
  padding: 10px var(--md) 10px 0;
}
#view-crm #crm-atrisk td { padding: 11px var(--md) 11px 0; }
#view-crm #crm-atrisk th:last-child,
#view-crm #crm-atrisk td:last-child { padding-right: 0; }
#view-crm #crm-atrisk tbody tr:last-child td { border-bottom: 0; }

/* A critical row is marked three times over: the ink-orange left rule style.css sets
   on `tr.warn`, the band tag, and the score. The ground is the fourth, not the first. */
#view-crm #crm-atrisk tr.crm-row-critical > td { background: var(--paper); }

#view-crm .crm-company .link {
  font-family: var(--display);
  font-size: 0.9375rem;
  font-weight: 600;
  color: var(--ink);
  text-decoration: none;
  border-bottom: 1px solid var(--rule);
  padding: 0;
  text-align: left;
}
#view-crm .crm-company .link:hover,
#view-crm .crm-company .link:focus-visible {
  background: transparent;
  color: var(--ink);
  border-bottom-color: var(--ink);
}

#view-crm .crm-score {
  font-family: var(--mono);
  font-size: 0.9375rem;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
#view-crm .crm-score[data-band='critical'] { color: var(--mark-ink); font-weight: 700; }

#view-crm .crm-band { margin-left: 0; }
#view-crm .crm-band[data-band='critical'] {
  border-color: var(--mark-ink);
  color: var(--mark-ink);
  font-weight: 700;
}
#view-crm .crm-band[data-band='at_risk'] { border-color: var(--ink); color: var(--ink); }
#view-crm .crm-band[data-band='watch'] { border-color: var(--rule); color: var(--ink-secondary); }

/* A signal is a sentence an operator acts on, so it is prose and it gets its own line.
   "digest unopened for 6 days" is the thing that earns a call; the score is not. */
#view-crm .crm-signals { font-family: var(--display); font-size: 0.875rem; min-width: 200px; }
#view-crm .crm-signal-list { list-style: none; margin: 0; padding: 0; }
#view-crm .crm-signal-list li {
  color: var(--ink-secondary);
  line-height: 1.45;
  padding-left: var(--md);
  text-indent: calc(var(--md) * -1);
}
#view-crm .crm-signal-list li + li { margin-top: var(--xs); }
#view-crm .crm-signal-list li::before {
  content: '—';
  color: var(--rule);
  margin-right: var(--sm);
}

#view-crm .crm-state { white-space: nowrap; }
#view-crm .crm-window .pill { margin-left: 0; }
#view-crm .crm-action { white-space: nowrap; }

#view-crm .crm-empty {
  font-family: var(--display);
  font-size: 0.875rem;
  color: var(--ink-secondary);
  padding: var(--md) 0;
  max-width: 62ch;
}

/* Focus rings must not be clipped by the plate's scroll box. */
#view-crm .crm-plate :focus-visible { outline-offset: 1px; }

/* --------------------------------------------------------------------------
   Narrow. Reviewers work from phones in the field, so 320px is a normal case.
   -------------------------------------------------------------------------- */

@media (max-width: 900px) {
  #view-crm #crm-lifecycle { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  #view-crm #crm-lifecycle .stage { border: 0; padding: 12px var(--xs); }
  #view-crm #crm-lifecycle .stage .n { font-size: 1.375rem; }
}

@media (max-width: 760px) {
  #view-crm .crm-head { align-items: flex-start; }
  #view-crm ul.guard li { grid-template-columns: 1fr; }
  #view-crm .crm-fact-note { grid-column: 1; }
  #view-crm .crm-verdict-word { font-size: 1.5rem; }
}

@media (max-width: 480px) {
  #view-crm #crm-lifecycle { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  #view-crm .crm-plate { padding-left: var(--sm); padding-right: var(--sm); }
  #view-crm #crm-waid { max-width: none; }
  #view-crm #crm-guard-check { width: 100%; }
}

/* ---------------------------------------------------------------------------
   The four registers: handoffs, expiring documents, win-back, verbatims.

   These reuse `.crm-plate`, `.crm-head`, `.crm-count`, `.crm-rule`, `.crm-company`
   and `.crm-empty`, which the at-risk queue already established. What follows is
   only what those four need and the first three did not: a group header inside a
   table body, a word set in marking ink beside a measured value, and a quote that
   has to read as prose in a grid built for numbers.
   --------------------------------------------------------------------------- */

/* A band header inside the table body. It is a `th[scope=colgroup]`, so it is
   structure rather than a styled row: a screen reader announces the band before
   the rows it covers. */
#view-crm .crm-group > th {
  background: var(--paper-sunk);
  border-top: 2px solid var(--ink);
  border-bottom: 1px solid var(--rule);
  padding: var(--xs) var(--sm);
  text-align: left;
  font-family: var(--mono);
  font-size: 0.625rem;
  letter-spacing: 0.1em;
  font-weight: 700;
  color: var(--ink);
}
#view-crm .crm-group-count {
  margin-left: var(--xs);
  color: var(--ink-secondary);
  font-variant-numeric: tabular-nums;
}
/* Said once, on the band, rather than on each of its rows. Below 24px the accent
   is Marking Ink, never Marking Orange. */
#view-crm .crm-group-urgent {
  margin-left: var(--sm);
  color: var(--mark-ink);
  font-weight: 700;
}

/* Measured values. Codes, wa_ids, dates, day counts and minute counts — never a
   sentence, which sets in Archivo like the rest of the prose on this screen. */
#view-crm .crm-mono {
  font-family: var(--mono);
  font-size: 0.75rem;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
#view-crm .crm-days { text-align: right; }
#view-crm .crm-left { white-space: nowrap; }

/* A state word beside a number, because colour is never the only carrier of
   meaning and a row about to lapse has to say so in words. */
#view-crm .crm-word-urgent {
  margin-left: var(--xs);
  font-family: var(--mono);
  font-size: 0.5625rem;
  letter-spacing: 0.1em;
  font-weight: 700;
  color: var(--mark-ink);
}

/* The quote is the product's one success metric, and it is prose. DESIGN.md:
   past about six words it is not a measured value and does not set in mono. */
#view-crm .crm-quote {
  font-family: var(--display);
  font-size: 0.9375rem;
  line-height: 1.5;
  color: var(--ink);
  max-width: 52ch;
  white-space: normal;
  min-width: 24ch;
}
#view-crm .crm-tag { color: var(--ink-secondary); }

/* The capture form is a ruled sheet with its labels above the inputs, not a bare
   row of placeholders. A placeholder disappears the moment someone types, which
   on a form that takes someone's exact words is the wrong moment to lose the
   question. */
#view-crm .crm-capture {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: var(--sm);
  background: var(--paper-lit);
  border: 1px solid var(--rule);
  padding: var(--sm) var(--md);
  margin-bottom: var(--sm);
}
#view-crm .crm-field {
  display: flex;
  flex-direction: column;
  gap: var(--xs);
  flex: 1 1 12rem;
  min-width: 0;
}
#view-crm .crm-field:nth-child(2) { flex: 3 1 20rem; }
#view-crm .crm-field-label {
  font-family: var(--mono);
  font-size: 0.5625rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-secondary);
}
#view-crm .crm-field input,
#view-crm .crm-field select { width: 100%; }

/* Narrow. Reviewers work from phones in the field, so the capture form stacks
   rather than scrolls and the quote gives up its minimum width. */
@media (max-width: 40rem) {
  #view-crm .crm-capture { flex-direction: column; align-items: stretch; }
  #view-crm .crm-field,
  #view-crm .crm-field:nth-child(2) { flex: 1 1 auto; }
  #view-crm .crm-quote { min-width: 0; }
}
