/* Page-specific styling for the document-flow screens.
 * Tokens, typography, panels, tables and controls all live in base.css —
 * this file only adds what a particular screen needs on top. */

/* ── Lead timeline ───────────────────────────────────────────────────────── */
.meta { display: flex; gap: var(--s3); flex-wrap: wrap; align-items: center; margin-bottom: var(--s2); }

.timeline { list-style: none; }
.timeline li { display: flex; gap: var(--s3); padding: var(--s2) 0; border-bottom: 1px solid var(--border); }
.timeline li:last-child { border-bottom: none; }
.timeline .when {
	color: var(--text-dim); font-size: 10.5px; white-space: nowrap;
	padding-top: 2px; font-variant-numeric: tabular-nums;
}
.timeline .kind {
	font-size: 9.5px; letter-spacing: 1.5px; text-transform: uppercase;
	color: var(--text-dim); margin-right: var(--s2);
}
.timeline .what { flex: 1; min-width: 0; padding-left: var(--s2); }
.timeline li.inbound .what { border-left: 2px solid var(--blue); }
.timeline li.outbound .what { border-left: 2px solid var(--border-bright); }
.timeline li.auto { opacity: .55; }
.timeline .body { margin-top: var(--s1); white-space: pre-wrap; color: var(--text); }

/* ── Pipeline board ──────────────────────────────────────────────────────── */
.board {
	display: grid; grid-auto-flow: column; grid-auto-columns: minmax(210px, 1fr);
	gap: var(--s2); overflow-x: auto; padding-bottom: var(--s3); align-items: start;
}
@media (max-width: 760px) { .board { grid-auto-flow: row; grid-auto-columns: auto; } }

/* A column is a panel. What is inside it is a ruled list, not a stack of boxes:
   a card per lead drew four borders around every name, so a column of eight
   leads was thirty-two lines competing with the one rule that meant something. */
.col {
	background: var(--surface);
	backdrop-filter: blur(6px);
	border: 1px solid var(--border); border-radius: var(--radius);
	padding: var(--s3); min-width: 0;
}
.col.campaign { opacity: .55; }
.col header { border-bottom: 1px solid var(--border); padding-bottom: var(--s2); margin-bottom: var(--s2); }
.col h3 { font-size: 11px; letter-spacing: 1.5px; text-transform: uppercase; color: var(--text); font-weight: 400; }
.col .counts { font-size: 10px; color: var(--text-dim); margin-top: 2px; }
.col .counts strong { color: var(--text-bright); font-size: 15px; font-variant-numeric: tabular-nums; }
.col .empty { font-size: 10.5px; color: var(--text-dim); }

/* The stage colour belongs on a rule, not on the heading text — a coloured
   word reads as a link or an alert. As a hairline down the column edge it says
   "this stage" without claiming anything needs doing. */
.col.tinted { border-left: 2px solid var(--stage, var(--border-bright)); }

/* ── Spend chart ─────────────────────────────────────────────────────────── */
/* One series, so one hue and no legend — the heading names it. The bars are
   the app's blue and today is amber, because "which bar is today" is the only
   distinction on this chart that means anything. The previous var(--blue)/var(--green)
   pair was off-palette and read as pass/fail, which is not what it showed.
   Grid and axes stay recessive so the bars carry the reading. */
.chart { margin-bottom: var(--s3); max-width: 760px; overflow-x: auto; }
.chart svg { width: 100%; height: auto; display: block; }
.chart .bar { fill: var(--blue); fill-opacity: .55; }
.chart .bar.today { fill: var(--amber); fill-opacity: .85; }
.chart .bar.zero { fill: var(--border-bright); fill-opacity: 1; }
.chart .bar:hover { fill-opacity: 1; }
.chart .grid { stroke: var(--border); stroke-width: 1; }
.chart .axis-line { stroke: var(--border-bright); stroke-width: 1.5; }
.chart .axis { fill: var(--text-dim); font-size: 9.5px; font-family: var(--mono); }
.chart figcaption { margin-top: var(--s1); font-size: 10.5px; color: var(--text-dim); }

/* ── Drafts and lead actions ─────────────────────────────────────────────── */
.draft-card {
	background: var(--surface);
	border: 1px solid var(--border); border-left: 2px solid var(--amber);
	border-radius: var(--radius-sm);
	padding: var(--s3); margin-bottom: var(--s2);
}
.draft-card .draft-to { display: flex; gap: var(--s2); align-items: baseline; }
.draft-card .draft-body { white-space: pre-wrap; margin: var(--s2) 0; color: var(--text); }

.snooze-box { margin-bottom: var(--s3); }
.snooze-form { display: flex; gap: var(--s3); align-items: flex-end; flex-wrap: wrap; margin-top: var(--s2); }
.snooze-form label { margin-bottom: 0; }
.snooze-form input, .snooze-form select { width: auto; }


/* ── Messages, wherever they are shown ───────────────────────────────────────
 * The messaging screen has its own stylesheet, but a message itself also
 * appears in the Discussion panel on a lead and on a quote — and those pages do
 * not load messages.css. These three live here so one note looks the same
 * whichever page it is read from. */

/* A person's name inside a sentence. Not a link — there is no page for a
   person — so it is marked rather than coloured like one. */
.msg-mention {
	color: var(--text-bright);
	background: var(--white-wash);
	border-radius: 3px; padding: 0 3px;
}
.msg-mention.me { color: var(--warn); background: var(--warn-wash); }

/* A record, which IS a page. This is the whole point of the feature: "the Jack
   Luu thing" becomes a click through to his record. */
.msg-chip {
	color: var(--blue);
	border-bottom: 1px dotted var(--blue-line);
}
.msg-chip:hover { color: var(--text-bright); border-bottom-color: var(--text-bright); }

/* References whose words are no longer in the sentence — somebody picked a lead
   and then rewrote the line. Still real links, shown under the message rather
   than dropped. */
.msg-orphans { margin-top: var(--s1); display: flex; flex-wrap: wrap; gap: var(--s2); font-size: 11px; }

/* ── "Do not contact" ────────────────────────────────────────────────────────
 * The one card in the app that is allowed to be loud. A customer who asked us
 * to stop is the single most expensive thing to get wrong, and a rep who only
 * finds out when their approved message is blocked has already written it. */
.stopcard {
	background: var(--red-plate);
	border: 1px solid var(--red-line);
	border-left: 3px solid var(--red);
	border-radius: var(--radius-sm);
	padding: var(--s3) var(--s4);
}
.stopcard-hd { color: var(--red-ink); font-weight: 500; margin-bottom: var(--s1); }
.stopcard .muted { color: var(--text-dim); }

/* ── The evidence ledger ─────────────────────────────────────────────────────
 *
 * A value and where it came from are ONE thing on screen, because they are one
 * thing in the data: `f.display` is "60 ft — Chris, from a call, 4 Aug". The
 * attribution is dimmer than the number but it is on the same line, not a
 * tooltip and not a hover. Chris's ruling made a rep's word strong on condition
 * that it never renders anonymously, and something you have to hover to see is
 * anonymous in every way that matters at a glance.
 *
 * A suggestion looks DIFFERENT, not smaller. Amber, indented, with the field it
 * would fill left empty above. A guess formatted like a fact is the failure this
 * whole feature exists to prevent. */
.evidence .ev-group + .ev-group { margin-top: var(--s4); }
.ev-group-name {
	font-size: 11px; font-weight: 500; letter-spacing: .08em; text-transform: uppercase;
	color: var(--text-dim); margin: 0 0 var(--s2);
}

/* Label left, value right, on a baseline grid. A definition list because that
   is what this is — the markup should say so to a screen reader too. */
.ev-facts { display: grid; grid-template-columns: max-content 1fr; gap: var(--s1) var(--s4); margin: 0; }
.ev-facts dt { color: var(--text-dim); font-size: 12px; }
.ev-facts dd { margin: 0; min-width: 0; }

/* The number is bright; the provenance trailing it is not. Same string, two
   weights — the em dash inside `display` is the seam. */
.ev-value { color: var(--text-bright); font-family: var(--mono); font-size: 13px; }
.ev-value.proposed { color: var(--amber); }

/* Their words, verbatim, so somebody can check what we made of them. */
.ev-excerpt {
	display: block; margin-top: 2px;
	color: var(--text-dim); font-size: 12px; font-style: italic;
	border-left: 1px solid var(--border); padding-left: var(--s2);
}

.ev-suggestions {
	margin-top: var(--s4); padding: var(--s3) var(--s4);
	background: var(--amber-wash);
	border: 1px solid var(--amber-line);
	border-left: 3px solid var(--amber);
	border-radius: var(--radius-sm);
}
.ev-suggestion { display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--s2) var(--s3); }
.ev-suggestion .ev-excerpt { flex-basis: 100%; }
.ev-actions { margin-left: auto; display: flex; gap: var(--s2); }
.ev-actions form { margin: 0; }

.ev-form select, .ev-form input { font-family: var(--mono); }
/* The checkbox that turns a fact into a suggestion. It sits on its own line
   because it changes what the whole form does, and a control that changes the
   meaning of a submit button should not be tucked between two text fields. */
.ev-derived { display: flex; align-items: center; gap: var(--s2); flex-basis: 100%; }
.ev-derived input { width: auto; margin: 0; }

/* ── One price, changed by hand ──────────────────────────────────────────────
 *
 * Collapsed by default and one per row. After the bulk load this is the only way
 * a price ever moves, so it lives ON the rate rather than on a separate screen —
 * the number you are changing and the cost floor you are checking it against are
 * the two things you need in front of you, and they are already in that row. */
.rate-actions { white-space: nowrap; }
.rate-edit { display: inline-block; margin-left: var(--s2); }
.rate-edit > summary { cursor: pointer; list-style: none; }
.rate-edit > summary::-webkit-details-marker { display: none; }
.rate-edit[open] > summary { color: var(--amber); }

/* Anchored, so opening one on row 900 does not push the other 116 rows down. */
.rate-edit[open] > form,
.rate-edit[open] > p {
	position: absolute; z-index: 20; right: var(--s4); width: min(420px, calc(100vw - var(--s5) * 2));
	background: var(--surface-solid);
	border: 1px solid var(--border-bright); border-radius: var(--radius);
	box-shadow: 0 18px 44px var(--scrim-shadow);
	padding: var(--s3) var(--s4); margin: 0;
	display: flex; flex-direction: column; gap: var(--s2);
	text-align: left; white-space: normal;
}
.rate-edit[open] > p {
	transform: translateY(calc(100% + var(--s1)));
	font-size: 11px; box-shadow: none; border-color: var(--border);
}
.rate-edit label { display: flex; flex-direction: column; gap: 2px; font-size: 12px; }
.rate-edit input { font-family: var(--mono); }

/* ── Rate card: scope, and a flag that has been settled ─────────────────────
   Red on this page has to mean "a human still has to decide this". A settled
   flag keeps its text as history rather than shouting alongside the open ones,
   because once both looked the same nobody could tell them apart. */
.scope-tag {
	display: inline-block; padding: 1px 6px; border-radius: var(--radius-sm);
	font-size: 9.5px; letter-spacing: 0.02em;
	border: 1px solid var(--border-bright); color: var(--text-dim);
}
.scope-tag.scope-default { color: var(--text-bright); border-color: var(--text-dim); }
.scope-tag.scope-future { color: var(--amber); border-color: var(--amber-line); }
.scope-tag.scope-excluded { color: var(--text-dim); border-color: var(--border); text-decoration: line-through; }

.audit-history { display: inline; margin-left: 6px; }
.audit-history > summary { display: inline; cursor: pointer; color: var(--text-dim); font-size: 9.5px; }
.scope-filter .muted { font-variant-numeric: tabular-nums; }

/* ── Service modes: a switch a person can find and read ─────────────────────
   This panel was read-only "by design" until Chris went looking for the switch
   to turn his own system on and could not find it. */
.mode-row { padding: 8px 0; border-bottom: 1px solid var(--border); }
.mode-row:last-child { border-bottom: none; }
.mode-head { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; }
.mode-name { font-weight: 600; text-transform: capitalize; }
.mode-state { font-size: 10px; letter-spacing: 0.04em; padding: 1px 7px; border-radius: var(--radius-sm); border: 1px solid var(--border-bright); }
.mode-state.on { color: var(--amber); border-color: var(--amber-line); }
.mode-state.off { color: var(--text-dim); }
.mode-note { margin: 3px 0 6px; max-width: var(--measure); }

/* ── Vault notes ────────────────────────────────────────────────────────────
   Chris's hand-written customer notes, imported. The visual job is separation:
   the Activity section of a note is a handwritten log of texts and calls that
   sits on the same page as the LIVE timeline of the same events, and a rep must
   never take one for the other. So a note is set apart with a rule down the
   left, in the reading face rather than the UI face, and its body is preserved
   verbatim — these are markdown bullets Chris wrote, and reflowing them loses
   the structure he put there. */
.vault-note { border-left: 2px solid var(--border-bright); padding: var(--s2) 0 var(--s2) var(--s3); margin: var(--s3) 0; }
.vault-hdr { display: flex; gap: var(--s2); align-items: baseline; flex-wrap: wrap; margin-bottom: var(--s2); }
.vault-hdr .kind { font-size: 11px; letter-spacing: 0.04em; text-transform: uppercase; color: var(--text-dim); }
.vault-body {
	white-space: pre-wrap;        /* his line breaks are meaning, not accident */
	overflow-wrap: anywhere;      /* long URLs and ids must not push the page sideways */
	font: inherit; margin: 0; max-width: var(--measure); color: var(--text);
}

/* ── Personal settings ──────────────────────────────────────────────────────
   The first page in this app that is about the person using it rather than the
   work. It is a form-dense screen, so the job is grouping: a briefing is ONE
   thing with a time, some days and some sections, and it has to read as one
   row rather than as fourteen loose controls sharing a panel. */
.briefing-row {
	padding: var(--s2) 0;
	border-bottom: 1px solid var(--border);
	display: grid; gap: 6px;
}
.briefing-head { display: flex; align-items: baseline; gap: var(--s2); flex-wrap: wrap; }
.briefing-name { font-weight: 600; text-transform: capitalize; min-width: 6rem; }
.briefing-days, .briefing-sections { display: flex; gap: var(--s2); flex-wrap: wrap; }
.briefing-foot { display: flex; align-items: baseline; gap: var(--s2); justify-content: space-between; flex-wrap: wrap; }
/* A checkbox and its word are one target, and they must not break across a line
   between the box and the label — a stray "fri" under a tick reads as a heading. */
.toggle { display: inline-flex; align-items: center; gap: 4px; white-space: nowrap; }
/* Mandatory sections are shown ticked and disabled. Dimmed rather than hidden:
   "you cannot turn this off" is information, and a section that silently is not
   on the list reads as one somebody forgot. */
.toggle.fixed { color: var(--text-dim); }
.add-briefing { margin-top: var(--s2); }

/* The briefing itself, as text. Preserved verbatim — it is column-aligned and
   reflowing it destroys the alignment that makes it scannable. */
.briefing-pre {
	white-space: pre-wrap;
	overflow-wrap: anywhere;
	font-family: var(--mono); font-size: 12px; line-height: 1.55;
	color: var(--text); margin: 0;
}

/* ── Why a quote line costs what it costs ───────────────────────────────────
   A kit multiplied by an eave curve and a span curve no longer multiplies out
   on the page. A rep who cannot reconstruct a price cannot defend it, so the
   chain is shown under the line rather than left to be trusted. */
.qline-why td { padding-top: 0; border-top: none; }
.qline-why .sep { color: var(--text-dim); margin: 0 4px; }
