/* =============================================================================
 * Call Intelligence — prototype stylesheet
 * =============================================================================
 *
 * The token block below is lifted from ~/clawd/projects/voice-agent-dashboard,
 * which is the design source of truth for anything of ours that gets framed
 * inside Shopmonkey. It is copied rather than reinterpreted on purpose: the
 * point of having a reference is that two of our pages sitting in the same
 * product do not quietly disagree about what a card looks like.
 *
 * Two tiers of token, and they behave differently:
 *
 *   NEUTRALS — the eight marked "host-repaintable" are what the hlx-theme
 *   receiver in index.html writes to when we are framed. They follow the host.
 *
 *   SEMANTICS — --status-red / --status-amber / --status-green carry meaning
 *   (an alert's severity), so they are excluded from the push. The host does
 *   not get to repaint meaning. They are identical in the light and dark
 *   blocks for the same reason as in the reference: one value has to read on a
 *   white card and on a near-black one, so each is used as a solid fill or as
 *   large figure text, never as small copy.
 * ========================================================================== */

* { margin: 0; padding: 0; box-sizing: border-box; }
:root {
    color-scheme: light;

    /* host-repaintable neutrals */
    --bg-primary: #f4f5fa;      /* the page canvas */
    --bg-secondary: #f8f9fc;    /* tiles sitting on a card */
    --bg-card: #ffffff;         /* cards sitting on the canvas */
    --text-primary: #161c2d;    /* headings and body */
    --text-secondary: #475467;  /* secondary copy, summaries */
    --text-muted: #5f6a7d;      /* labels, captions, timestamps */
    --border-color: #e6e8ef;    /* every hairline */
    --accent-blue: #2240ff;     /* SM royal — buttons and links only */

    /* neutrals the host never sends; they track the base theme */
    --accent-blue-text: #2240ff;
    --accent-blue-hover: #1a33d9;
    --on-accent: #ffffff;
    --bg-tertiary: #eceef5;     /* progress troughs, bar chart troughs */
    --ctl-hover: #f6f7fb;
    --disabled: #c3c8d6;

    /* semantics — never repainted, identical in both base themes */
    --status-red: #d92d20;
    --status-amber: #b45309;
    --status-green: #0f7a45;

    /* tint pairs — a badge tint has to sit on the surface under it or it glows */
    --tone-pos: #0e7040;  --tone-pos-bg: #e3f7ec;
    --tone-neu: #475467;  --tone-neu-bg: #f0f1f6;
    --tone-neg: #b42318;  --tone-neg-bg: #fdeaea;
    --tone-info: #2240ff; --tone-info-bg: #dfe3ff;
    --tone-warn: #92400e; --tone-warn-bg: #fdf2e3;

    --shadow-sm: 0 1px 2px rgba(16, 24, 40, .04);
    --border-radius: 12px;

    /* chart series — validated as a pair (CVD ΔE ≥ 21, both ≥ 3:1 on the card).
       Slot 1 is the accent; slot 2 differs in hue AND lightness. */
    --chart-1: #2240ff;
    --chart-2: #0f9bb5;
    /* Slots 3-7 exist because the rail became multi-select — up to seven
       metrics can be on one chart at once. Each is separated from its
       neighbours in hue and in lightness so the lines stay tellable apart
       both in colour-vision deficiency and in a grayscale printout. */
    --chart-3: #c2620f;
    --chart-4: #7b3fd4;
    --chart-5: #0e7a45;
    --chart-6: #b02a37;
    --chart-7: #5b6472;
}
/* The base the receiver flips to when the host's page colour comes in dark. It
   exists so the tokens the host does NOT send — troughs, chip tints, control
   hovers — come from a matching palette instead of staying light under a dark
   surface. The pushed values then fine-tune on top, as inline style. */
:root[data-theme="dark"] {
    color-scheme: dark;

    --bg-primary: #0f121b;
    --bg-secondary: #171b26;
    --bg-card: #161a24;
    --text-primary: #f2f3f7;
    --text-secondary: #c3cad8;
    --text-muted: #98a1b3;
    --border-color: #262b3a;
    --accent-blue: #3b55ff;

    --accent-blue-text: #93a5ff;
    --accent-blue-hover: #4b62ff;
    --on-accent: #ffffff;
    --bg-tertiary: #232838;
    --ctl-hover: #1e2331;
    --disabled: #343a4b;

    /* unchanged on purpose — see the note at the top */
    --status-red: #d92d20;
    --status-amber: #b45309;
    --status-green: #0f7a45;

    --tone-pos: #6ee7b7;  --tone-pos-bg: #10352a;
    --tone-neu: #c3cad8;  --tone-neu-bg: #1e2331;
    --tone-neg: #fca5a5;  --tone-neg-bg: #3a1a1a;
    --tone-info: #93a5ff; --tone-info-bg: #232a52;
    --tone-warn: #fcd9a5; --tone-warn-bg: #3a2c14;

    --shadow-sm: 0 1px 2px rgba(0, 0, 0, .3);

    --chart-1: #3b55ff;
    --chart-2: #1aa3bd;
    --chart-3: #e08a35;
    --chart-4: #a479ec;
    --chart-5: #35b877;
    --chart-6: #f0737f;
    --chart-7: #97a1b0;
}
body {
    font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
    background: var(--bg-primary);
    color: var(--text-primary);
    line-height: 1.55;
    letter-spacing: -0.004em;
    min-height: 100vh;
    -webkit-font-smoothing: antialiased;
}
.container {
    max-width: 1400px;
    margin: 0 auto;
    padding: 1.5rem;
}
/* ── page header ──────────────────────────────────────────────────────────── */

.header { margin-bottom: 1rem; }
.header-row {
    display: flex;
    align-items: flex-start;
    gap: 1rem;
    flex-wrap: wrap;
}
.header-text { flex: 1; min-width: 0; }
.header h1 {
    font-size: 1.25rem;
    font-weight: 600;
    letter-spacing: -0.02em;
    color: var(--text-primary);
    margin-bottom: 0.125rem;
}
.header p {
    color: var(--text-muted);
    font-size: 0.8125rem;
}
/* ── the disclosure the brief requires on anything that reads as measured ──
   Deliberately not styleable away by the host theme push: it is a compliance
   affordance, not decoration. Amber tint rather than red — it is a caveat,
   not an error. */
.illus {
    display: inline-flex;
    align-items: center;
    gap: 0.375rem;
    padding: 0.1875rem 0.5rem;
    border-radius: 999px;
    background: var(--tone-warn-bg);
    color: var(--tone-warn);
    font-size: 0.6875rem;
    font-weight: 500;
    line-height: 1.4;
    white-space: nowrap;
}
/* ── icon baseline ───────────────────────────────────────────────────────────
 * Every icon in this app is a stroked outline in its own label's colour. This
 * rule is the default for all of them; the component rules further down only
 * adjust size and weight, and each has the same specificity so a later one
 * wins. Without a baseline, a component that has no rule of its own renders
 * the SVG default — a black FILLED glyph at replaced-element size, which is
 * exactly what the evidence chips in the owner feed were doing: enormous, and
 * invisible once a host pushed a dark surface underneath them. */
.container svg {
    width: 14px;
    height: 14px;
    flex: none;
    fill: none;
    stroke: currentColor;
    stroke-width: 1.75;
    stroke-linecap: round;
    stroke-linejoin: round;
}
/* The long-form version, sat under a figure grid rather than beside a heading. */
.illus-note {
    font-size: 0.6875rem;
    color: var(--text-muted);
    margin-top: 0.75rem;
    padding-top: 0.75rem;
    border-top: 1px solid var(--border-color);
    line-height: 1.5;
}
/* ── tab nav ──────────────────────────────────────────────────────────────── */

.tabs {
    display: flex;
    align-items: center;
    gap: 0.375rem;
    background: var(--bg-card);
    border: 1px solid var(--border-color);
    border-radius: var(--border-radius);
    padding: 0.375rem;
    margin-bottom: 1rem;
    box-shadow: var(--shadow-sm);
    flex-wrap: wrap;
}
.tab {
    display: inline-flex;
    align-items: center;
    gap: 0.4375rem;
    height: 34px;
    padding: 0 0.8125rem;
    border: 1px solid transparent;
    border-radius: 8px;
    background: transparent;
    color: var(--text-secondary);
    font-family: inherit;
    font-size: 0.8125rem;
    font-weight: 500;
    cursor: pointer;
    text-decoration: none;
    white-space: nowrap;
}
.tab:hover { background: var(--ctl-hover); }
.tab:focus-visible { outline: 2px solid var(--accent-blue); outline-offset: 1px; }
/* Selected tab is a solid accent fill — SM fills exactly one thing per group. */
.tab.active {
    background: var(--accent-blue);
    border-color: var(--accent-blue);
    color: var(--on-accent);
}
.tab svg { width: 15px; height: 15px; flex: none; fill: none; stroke: currentColor; stroke-width: 1.75; stroke-linecap: round; stroke-linejoin: round; }
/* ── cards ────────────────────────────────────────────────────────────────── */

.card {
    background: var(--bg-card);
    border: 1px solid var(--border-color);
    border-radius: var(--border-radius);
    box-shadow: var(--shadow-sm);
    margin-bottom: 1rem;
    overflow: hidden;
}
.card-head {
    padding: 0.875rem 1.125rem;
    border-bottom: 1px solid var(--border-color);
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    flex-wrap: wrap;
}
.card-title {
    font-size: 0.9375rem;
    font-weight: 600;
    letter-spacing: -0.01em;
    margin-bottom: 0.0625rem;
}
.card-sub { color: var(--text-muted); font-size: 0.8125rem; }
.card-body { padding: 1.125rem; }
/* ── controls ─────────────────────────────────────────────────────────────── */

.filters {
    display: flex;
    align-items: center;
    gap: 0.625rem;
    flex-wrap: wrap;
}
.field-label {
    font-size: 0.75rem;
    font-weight: 500;
    color: var(--text-muted);
    margin-bottom: 0.25rem;
    display: block;
}
.select, .input {
    background: var(--bg-card);
    border: 1px solid var(--border-color);
    border-radius: 8px;
    padding: 0 0.75rem;
    height: 36px;
    color: var(--text-primary);
    font-family: inherit;
    font-size: 0.8125rem;
    font-weight: 500;
    cursor: pointer;
    min-width: 150px;
}
.input { cursor: text; font-weight: 400; min-width: 220px; }
.select:hover, .input:hover { background: var(--ctl-hover); }
.select:focus-visible, .input:focus-visible { outline: 2px solid var(--accent-blue); outline-offset: 1px; border-color: var(--accent-blue); }
.input::placeholder { color: var(--text-muted); }
.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.375rem;
    height: 36px;
    padding: 0 0.875rem;
    background: var(--bg-card);
    border: 1px solid var(--border-color);
    border-radius: 8px;
    color: var(--text-secondary);
    font-family: inherit;
    font-size: 0.8125rem;
    font-weight: 500;
    cursor: pointer;
    white-space: nowrap;
    text-decoration: none;
}
.btn:hover { background: var(--ctl-hover); }
.btn:focus-visible { outline: 2px solid var(--accent-blue); outline-offset: 1px; }
.btn svg { width: 15px; height: 15px; flex: none; fill: none; stroke: currentColor; stroke-width: 1.75; stroke-linecap: round; stroke-linejoin: round; }
.btn-primary {
    background: var(--accent-blue);
    border-color: var(--accent-blue);
    color: var(--on-accent);
}
.btn-primary:hover { background: var(--accent-blue-hover); border-color: var(--accent-blue-hover); }
/* ── badges ───────────────────────────────────────────────────────────────── */

.badge {
    display: inline-block;
    padding: 0.1875rem 0.625rem;
    border-radius: 999px;
    font-size: 0.75rem;
    font-weight: 500;
    white-space: nowrap;
}
.badge-pos  { background: var(--tone-pos-bg);  color: var(--tone-pos); }
.badge-neu  { background: var(--tone-neu-bg);  color: var(--tone-neu); }
.badge-neg  { background: var(--tone-neg-bg);  color: var(--tone-neg); }
.badge-info { background: var(--tone-info-bg); color: var(--tone-info); }
.badge-warn { background: var(--tone-warn-bg); color: var(--tone-warn); }
/* A tag is quieter than a badge — it is a fact, not a status. */
.tag {
    display: inline-block;
    padding: 0.125rem 0.5rem;
    border: 1px solid var(--border-color);
    border-radius: 999px;
    background: var(--bg-secondary);
    color: var(--text-muted);
    font-size: 0.6875rem;
    font-weight: 500;
    white-space: nowrap;
}
/* ── KPI tiles ────────────────────────────────────────────────────────────── */

.stat-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
    gap: 0.75rem;
}
.stat {
    padding: 0.875rem 1rem 1rem;
    background: var(--bg-secondary);
    border: 1px solid var(--border-color);
    border-radius: 10px;
}
.stat-label {
    display: flex;
    align-items: center;
    gap: 0.4375rem;
    font-weight: 500;
    color: var(--text-muted);
    font-size: 0.78125rem;
    line-height: 1.3;
    margin-bottom: 0.5rem;
}
.stat-label svg { width: 15px; height: 15px; flex: none; fill: none; stroke: currentColor; stroke-width: 1.75; stroke-linecap: round; stroke-linejoin: round; }
.stat-value {
    font-weight: 600;
    font-size: 1.375rem;
    line-height: 1.15;
    letter-spacing: -0.025em;
    white-space: nowrap;
}
.stat-sub { font-size: 0.75rem; color: var(--text-muted); margin-top: 0.375rem; line-height: 1.4; }
.stat-trough { height: 6px; background: var(--bg-tertiary); border-radius: 3px; overflow: hidden; margin-top: 0.625rem; }
.stat-fill { height: 100%; border-radius: 3px; background: var(--accent-blue); }
.stat-fill.good { background: var(--status-green); }
.stat-fill.warn { background: var(--status-amber); }
.stat-fill.bad  { background: var(--status-red); }
/* Direction of travel. Green/red here is movement, not severity, so it uses
   the tone pair rather than the status fills. */
.delta { font-size: 0.75rem; font-weight: 500; }
.delta.up   { color: var(--tone-pos); }
.delta.down { color: var(--tone-neg); }
.delta.flat { color: var(--text-muted); }
/* ── call log table ───────────────────────────────────────────────────────── */

.table-wrap { overflow-x: auto; }
table.log { width: 100%; border-collapse: collapse; font-size: 0.8125rem; }
table.log th {
    text-align: left;
    font-weight: 500;
    font-size: 0.75rem;
    color: var(--text-muted);
    padding: 0.5rem 0.75rem;
    border-bottom: 1px solid var(--border-color);
    white-space: nowrap;
    background: var(--bg-card);
    position: sticky;
    top: 0;
    z-index: 1;
}
table.log td {
    padding: 0.6875rem 0.75rem;
    border-bottom: 1px solid var(--border-color);
    vertical-align: top;
}
table.log tbody tr { cursor: pointer; }
table.log tbody tr:hover { background: var(--ctl-hover); }
table.log tbody tr:last-child td { border-bottom: none; }
table.log tbody tr:focus-visible { outline: 2px solid var(--accent-blue); outline-offset: -2px; }
.cell-time { color: var(--text-muted); white-space: nowrap; }
.cell-caller { font-weight: 500; }
.cell-phone { color: var(--text-muted); font-size: 0.75rem; letter-spacing: 0.06em; }
.cell-tags { display: flex; flex-wrap: wrap; gap: 0.25rem; max-width: 320px; }
.avatar {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 24px;
    height: 24px;
    border-radius: 50%;
    background: var(--bg-tertiary);
    color: var(--text-secondary);
    font-size: 0.625rem;
    font-weight: 600;
    letter-spacing: 0.02em;
    flex: none;
}
.advisor-cell { display: inline-flex; align-items: center; gap: 0.4375rem; white-space: nowrap; }
.empty {
    padding: 2.5rem 1rem;
    text-align: center;
    color: var(--text-muted);
    font-size: 0.8125rem;
}
/* ── call detail ──────────────────────────────────────────────────────────── */

/* Transcript left, extraction right. Below 960px it stacks with the extraction
   panel FIRST — on a narrow screen the fields are the summary and the
   transcript is the appendix. */
.detail-grid {
    display: grid;
    grid-template-columns: minmax(0, 1.35fr) minmax(0, 1fr);
    gap: 1rem;
    align-items: start;
}
.transcript-scroll {
    max-height: 60vh;
    overflow-y: auto;
    padding: 0.5rem 1.125rem 1.125rem;
    /* Contain scroll chaining so reaching the end of the transcript does not
       start scrolling the Shopmonkey page behind our iframe. */
    overscroll-behavior: contain;
}
.tline {
    display: grid;
    grid-template-columns: 46px minmax(0, 1fr);
    gap: 0.75rem;
    padding: 0.625rem 0.75rem;
    margin: 0 -0.75rem;
    border-radius: 8px;
    scroll-margin-top: 1rem;
}
.tline + .tline { margin-top: 0.125rem; }
.tline-at { font-size: 0.6875rem; color: var(--text-muted); font-variant-numeric: tabular-nums; padding-top: 0.125rem; }
.tline-who { font-size: 0.6875rem; font-weight: 600; color: var(--text-muted); margin-bottom: 0.125rem; }
.tline-text { font-size: 0.8125rem; color: var(--text-secondary); line-height: 1.6; }
.tline.advisor .tline-who { color: var(--accent-blue-text); }
.tline.caller  .tline-text { color: var(--text-primary); }
/* The link-back target. Blue rather than a semantic colour: this is a
   navigation result, not a status. The left rule is what the eye actually
   catches when the pane scrolls. */
.tline.is-evidence {
    background: var(--tone-info-bg);
    box-shadow: inset 3px 0 0 var(--accent-blue);
}
/* A short flash on arrival, so clicking the *same* field twice still reads as
   a response rather than as a dead control. Animates an outline rather than
   the background, because the background is already the persistent evidence
   tint and animating it would just fight .is-evidence. Honours reduced-motion
   below. */
.tline.is-flash { animation: flash 0.9s ease-out; }
@keyframes flash {
    0%   { outline: 2px solid var(--accent-blue); outline-offset: 0; }
70%  { outline: 2px solid var(--accent-blue); outline-offset: 0; }
100% { outline: 2px solid transparent; outline-offset: 0; }
}
.transcript-hint {
    padding: 0.625rem 1.125rem;
    border-bottom: 1px solid var(--border-color);
    font-size: 0.75rem;
    color: var(--text-muted);
    display: flex;
    align-items: center;
    gap: 0.4375rem;
    min-height: 40px;
}
.transcript-hint svg { width: 14px; height: 14px; flex: none; fill: none; stroke: currentColor; stroke-width: 1.75; stroke-linecap: round; stroke-linejoin: round; }
.transcript-hint b { color: var(--text-secondary); font-weight: 600; }
/* ── extracted fields ─────────────────────────────────────────────────────── */

.fields { display: flex; flex-direction: column; }
/* A field is a button, not a div with a click handler — it has to be reachable
   from the keyboard, because the link-back is the whole demo. */
.field {
    display: block;
    width: 100%;
    text-align: left;
    background: transparent;
    border: 0;
    border-bottom: 1px solid var(--border-color);
    padding: 0.75rem 1.125rem;
    font-family: inherit;
    cursor: pointer;
    color: inherit;
}
.field:last-child { border-bottom: none; }
.field:hover { background: var(--ctl-hover); }
.field:focus-visible { outline: 2px solid var(--accent-blue); outline-offset: -2px; }
.field.is-active { background: var(--tone-info-bg); }
.field.no-evidence { cursor: default; }
.field.no-evidence:hover { background: transparent; }
.field-top {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin-bottom: 0.1875rem;
}
.field-name {
    display: inline-flex;
    align-items: center;
    gap: 0.4375rem;
    font-size: 0.75rem;
    font-weight: 500;
    color: var(--text-muted);
}
.field-name svg { width: 14px; height: 14px; flex: none; fill: none; stroke: currentColor; stroke-width: 1.75; stroke-linecap: round; stroke-linejoin: round; }
.field-value { font-size: 0.875rem; font-weight: 500; color: var(--text-primary); }
/* "Where this came from" — the affordance that says the field is clickable at
   all. Muted until hover so the panel does not read as a wall of links. */
.field-cite {
    display: inline-flex;
    align-items: center;
    gap: 0.3125rem;
    margin-top: 0.3125rem;
    font-size: 0.6875rem;
    font-weight: 500;
    color: var(--accent-blue-text);
}
.field-cite svg { width: 12px; height: 12px; flex: none; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.field-cite.none { color: var(--text-muted); }
.conf {
    margin-left: auto;
    font-size: 0.6875rem;
    color: var(--text-muted);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}
/* ── action items ─────────────────────────────────────────────────────────── */

.action {
    display: flex;
    gap: 0.625rem;
    width: 100%;
    text-align: left;
    background: transparent;
    border: 0;
    border-bottom: 1px solid var(--border-color);
    padding: 0.75rem 1.125rem;
    font-family: inherit;
    font-size: 0.8125rem;
    color: var(--text-secondary);
    cursor: pointer;
    line-height: 1.5;
}
.action:last-child { border-bottom: none; }
.action:hover { background: var(--ctl-hover); }
.action:focus-visible { outline: 2px solid var(--accent-blue); outline-offset: -2px; }
.action.is-active { background: var(--tone-info-bg); }
.action-dot { width: 6px; height: 6px; border-radius: 50%; background: var(--accent-blue); flex: none; margin-top: 0.5rem; }
/* ── the mocked Shopmonkey side ───────────────────────────────────────────
   Given its own visual treatment — dashed hairline — because everywhere else
   on the page is invented-but-plausible, and this bit is invented AND stands
   in for a system we have not connected yet. It should not look settled. */
.mock-panel { border-top: 1px dashed var(--border-color); background: var(--bg-secondary); }
.mock-row {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 0.75rem;
    padding: 0.4375rem 1.125rem;
    font-size: 0.8125rem;
}
.mock-row dt { color: var(--text-muted); font-size: 0.75rem; }
.mock-row dd { font-weight: 500; text-align: right; }
/* ── alerts / early-warning feed ──────────────────────────────────────────── */

.alert {
    display: grid;
    grid-template-columns: 4px minmax(0, 1fr);
    gap: 0 0.875rem;
    border-bottom: 1px solid var(--border-color);
    padding: 0;
}
.alert:last-child { border-bottom: none; }
.alert-rail { background: var(--status-amber); }
.alert.sev-red .alert-rail   { background: var(--status-red); }
.alert.sev-amber .alert-rail { background: var(--status-amber); }
.alert.sev-green .alert-rail { background: var(--status-green); }
.alert-body { padding: 0.9375rem 1.125rem 0.9375rem 0; }
.alert-head {
    display: flex;
    align-items: baseline;
    gap: 0.625rem;
    flex-wrap: wrap;
    margin-bottom: 0.3125rem;
}
.alert-title { font-size: 0.875rem; font-weight: 600; letter-spacing: -0.01em; }
.alert-text { font-size: 0.8125rem; color: var(--text-secondary); line-height: 1.6; }
.alert-metrics {
    display: flex;
    align-items: center;
    gap: 1.25rem;
    margin: 0.625rem 0 0.5rem;
    flex-wrap: wrap;
}

/* ── alert sparkline ──────────────────────────────────────────────────────
   Pushed to the right edge of the metrics row rather than given its own
   block: the number and the shape that produced it belong on one line. */
.spark-wrap { margin-left: auto; flex: 0 1 240px; min-width: 160px; }
/* Scoped under .container for the same reason .mx-svg is: the base
   `.container svg` rule sizes every inline icon at 14px and would win
   against a bare .spark. */
.container .spark { display: block; width: 100%; height: auto; flex: auto; fill: none; stroke: none; overflow: visible; }
.spark-label {
    font-size: 0.625rem;
    color: var(--text-muted);
    text-align: right;
    margin-top: 0.125rem;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
/* The shaded band is the fortnight the headline figure is quoting. */
.spark-window { fill: var(--text-primary); opacity: 0.05; }
.spark-line { fill: none; stroke: var(--spark, var(--status-amber)); stroke-width: 1.75; stroke-linecap: round; stroke-linejoin: round; }
.spark-fill { fill: var(--spark, var(--status-amber)); opacity: 0.1; stroke: none; }
.spark-dot { fill: var(--spark, var(--status-amber)); stroke: var(--bg-card); stroke-width: 1.5; }
.spark.sev-red   { --spark: var(--status-red); }
.spark.sev-amber { --spark: var(--status-amber); }
.spark.sev-green { --spark: var(--status-green); }
.alert-metric-value { font-size: 1.125rem; font-weight: 600; letter-spacing: -0.02em; }
.alert-metric-label { font-size: 0.6875rem; color: var(--text-muted); display: block; }
.alert-links { display: flex; align-items: center; gap: 0.375rem; flex-wrap: wrap; margin-top: 0.5rem; }
.alert-links-label { font-size: 0.6875rem; color: var(--text-muted); margin-right: 0.125rem; }
/* A chip that booked is the good outcome; the tick is the second icon on it. */
.chip-booked { border-color: var(--status-green); }
.chip-booked svg:last-child { color: var(--status-green); }
.chip-link {
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
    padding: 0.125rem 0.5rem;
    border: 1px solid var(--border-color);
    border-radius: 999px;
    background: var(--bg-card);
    color: var(--accent-blue-text);
    font-size: 0.6875rem;
    font-weight: 500;
    font-family: inherit;
    cursor: pointer;
    text-decoration: none;
}
/* The quote mark sits beside a caller name at 11px — smaller and lighter than
   the baseline, or it reads as the content rather than the marker. */
.chip-link svg { width: 11px; height: 11px; stroke-width: 2; color: var(--text-muted); }
.chip-link:hover { background: var(--ctl-hover); border-color: var(--accent-blue); }
.chip-link:focus-visible { outline: 2px solid var(--accent-blue); outline-offset: 1px; }
/* "Which side did this come from" — the brief asks every alert to say so, and
   a two-sided one gets a filled chip because it is the only kind neither
   system could have produced alone. */
.side-chip {
    display: inline-flex;
    align-items: center;
    gap: 0.3125rem;
    padding: 0.125rem 0.5rem;
    border-radius: 999px;
    font-size: 0.6875rem;
    font-weight: 500;
    white-space: nowrap;
    background: var(--bg-secondary);
    border: 1px solid var(--border-color);
    color: var(--text-muted);
}
.side-chip svg { width: 11px; height: 11px; flex: none; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.side-chip.both { background: var(--accent-blue); border-color: var(--accent-blue); color: var(--on-accent); }
.mock-flag {
    display: inline-block;
    margin-top: 0.5rem;
    padding: 0.3125rem 0.625rem;
    border: 1px dashed var(--border-color);
    border-radius: 8px;
    background: var(--bg-secondary);
    color: var(--text-muted);
    font-size: 0.6875rem;
    line-height: 1.5;
}
/* ── bar charts ───────────────────────────────────────────────────────────
   Flat rules, one accent, no gradients — the same vocabulary as the KPI
   trough above, just longer. There is no charting library here on purpose:
   the reference has none, and a second visual grammar arriving with a library
   is exactly what "match the reference" is meant to prevent. */

.bars { display: flex; flex-direction: column; gap: 0.625rem; }
.bar-row {
    display: grid;
    grid-template-columns: minmax(90px, 150px) minmax(0, 1fr) 58px;
    align-items: center;
    gap: 0.75rem;
    font-size: 0.8125rem;
}
.bar-label { color: var(--text-secondary); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bar-track { height: 8px; background: var(--bg-tertiary); border-radius: 4px; overflow: hidden; }
.bar-fill { height: 100%; border-radius: 4px; background: var(--accent-blue); min-width: 2px; }
.bar-fill.good { background: var(--status-green); }
.bar-fill.warn { background: var(--status-amber); }
.bar-fill.muted { background: var(--disabled); }
.bar-value { text-align: right; color: var(--text-muted); font-variant-numeric: tabular-nums; font-size: 0.75rem; }
/* Month-over-month: grouped columns, one column per month. */
.mom {
    display: grid;
    grid-auto-flow: column;
    grid-auto-columns: 1fr;
    gap: 0.75rem;
    align-items: end;
    min-height: 130px;
    padding-top: 0.5rem;
}
.mom-col { display: flex; flex-direction: column; align-items: center; gap: 0.4375rem; }
.mom-bar-wrap { width: 100%; display: flex; align-items: flex-end; justify-content: center; height: 96px; }
.mom-bar {
    width: 100%;
    max-width: 54px;
    background: var(--accent-blue);
    border-radius: 6px 6px 0 0;
    min-height: 3px;
}
.mom-bar.muted { background: var(--bg-tertiary); }
.mom-figure { font-size: 0.8125rem; font-weight: 600; letter-spacing: -0.01em; }
.mom-month { font-size: 0.6875rem; color: var(--text-muted); }
/* ── metric explorer (owner view "Trends") ────────────────────────────────
   A rail of metric buttons on the left at a fifth of the width, one chart on
   the right at four fifths. Under 900px the rail becomes a scrolling row
   above the chart. Every SVG mark below sets its own fill and stroke because
   the `.container svg` baseline paints any svg as a 14px stroked icon. */

.mx {
    display: grid;
    grid-template-columns: minmax(200px, 1fr) minmax(0, 4fr);
    gap: 1.25rem;
    align-items: stretch;
}
.mx-rail { display: flex; flex-direction: column; gap: 0.375rem; }
/* Dave, 2026-09: seven of these have to clear the fold together, and stacked
   as label-then-figure only five did. Grid instead of a column: the label and
   the figure share the top line, the trough and the caption run full width
   under it. Three tight rows rather than four loose ones — same tile face,
   about two-thirds the height. */
.mx-btn {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: center;
    column-gap: 0.625rem;
    row-gap: 0;
    width: 100%;
    min-height: 0;
    padding: 0.5rem 0.75rem 0.5625rem 0.8125rem;
    border: 1px solid var(--border-color);
    border-radius: 10px;
    background: var(--bg-card);
    color: var(--text-primary);
    font: inherit;
    text-align: left;
    cursor: pointer;
    transition: background .12s ease, border-color .12s ease;
}
.mx-btn:hover { background: var(--ctl-hover); border-color: var(--accent-blue); }
.mx-btn:focus-visible { outline: 2px solid var(--accent-blue); outline-offset: 1px; }
/* The pressed bar is the metric's own series colour, not the generic accent —
   with several lines on one chart the rail has to say which line is which. */
.mx-btn[aria-pressed="true"] {
    background: var(--tone-info-bg);
    border-color: var(--series, var(--accent-blue));
    box-shadow: inset 3px 0 0 var(--series, var(--accent-blue));
}
/* The button wears the stat tile's face — same icon row, same figure size,
   same trough. It has to read as the tile it replaced, because it is now the
   only place these shop-wide numbers appear. */
.mx-btn-label {
    grid-column: 1;
    display: flex;
    align-items: center;
    gap: 0.375rem;
    min-width: 0;
    font-weight: 500;
    color: var(--text-muted);
    font-size: 0.75rem;
    line-height: 1.25;
}
.mx-btn-label svg { width: 13px; height: 13px; flex: none; fill: none; stroke: currentColor; stroke-width: 1.75; stroke-linecap: round; stroke-linejoin: round; }
.mx-btn-value {
    grid-column: 2;
    justify-self: end;
    font-weight: 600;
    font-size: 1.0625rem;
    line-height: 1.2;
    letter-spacing: -0.02em;
    white-space: nowrap;
    color: var(--text-primary);
    font-variant-numeric: tabular-nums;
}
.mx-btn-trough {
    grid-column: 1 / -1;
    display: block;
    width: 100%;
    height: 4px;
    background: var(--bg-tertiary);
    border-radius: 2px;
    overflow: hidden;
    margin-top: 0.375rem;
}
.mx-btn-fill { display: block; height: 100%; border-radius: 2px; background: var(--accent-blue); }
.mx-btn-fill.good { background: var(--status-green); }
.mx-btn-fill.warn { background: var(--status-amber); }
.mx-btn-fill.bad  { background: var(--status-red); }
/* One line, clipped. A caption that wraps to three lines on one button and one
   on the next is what made the rail uneven and pushed the last two off screen;
   the full text is still on the chart's own caption when you click it. */
.mx-btn-sub {
    grid-column: 1 / -1;
    font-size: 0.6875rem;
    color: var(--text-muted);
    line-height: 1.35;
    margin-top: 0.25rem;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
/* The pressed button keeps the tile's label muted but lifts its figure, so
   the selected metric is legible without the rail turning into six shouts. */
.mx-btn[aria-pressed="true"] .mx-btn-label { color: var(--text-secondary); }

.mx-chart {
    display: flex;
    flex-direction: column;
    justify-content: center;
    min-height: 280px;
    min-width: 0;
    transition: opacity .14s ease;
}
.mx-chart.is-swapping { opacity: 0; }
/* The standalone advisor chart carries its own height in its spec, so the
   explorer's 280px floor would only add air under three short columns. */
.mx-chart-solo { min-height: 0; }

/* Specificity note: `.container .mx-svg` (0,2,0) beats `.container svg`. */
.container .mx-svg {
    display: block;
    width: 100%;
    height: auto;
    fill: none;
    stroke: none;
    overflow: visible;
}
.mx-s1 { --series: var(--chart-1); }
.mx-s2 { --series: var(--chart-2); }
.mx-s3 { --series: var(--chart-3); }
.mx-s4 { --series: var(--chart-4); }
.mx-s5 { --series: var(--chart-5); }
.mx-s6 { --series: var(--chart-6); }
.mx-s7 { --series: var(--chart-7); }
.mx-bar { fill: var(--series); stroke: none; }
.mx-hatch-bg { fill: var(--series); opacity: .22; stroke: none; }
.mx-hatch-line { stroke: var(--series); stroke-width: 1.5; fill: none; }
.mx-line { fill: none; stroke: var(--series); stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.mx-line.is-dashed { stroke-dasharray: 5 5; }
.mx-dot { fill: var(--bg-card); stroke: var(--series); stroke-width: 2; }
.mx-hit { fill: transparent; stroke: none; cursor: default; }
.mx-pt:hover .mx-dot { stroke-width: 3; }
.mx-pt.is-thin .mx-dot { stroke: var(--disabled); stroke-dasharray: 2 2; }
.mx-baseline { stroke: var(--border-color); stroke-width: 1; fill: none; }
.mx-grid { stroke: var(--border-color); stroke-width: 1; fill: none; opacity: .7; }
.mx-svg text { fill: var(--text-muted); stroke: none; font-family: inherit; font-size: 11px; }
.mx-svg .mx-value { fill: var(--text-primary); font-size: 12px; font-weight: 600; font-variant-numeric: tabular-nums; }
.mx-svg .mx-seg-label { fill: var(--on-accent); font-size: 11px; font-weight: 600; }
.mx-svg .mx-tick { font-size: 10px; }
.mx-svg .mx-month.is-partial { font-style: italic; }
.mx-col.is-partial .mx-value { fill: var(--text-secondary); }
/* On the combined chart only the newest point of each curve is labelled, so
   the label takes its own line's colour — otherwise three numbers stack in
   the same ink and none of them says which curve it belongs to. */
.mx-svg .mx-value.mx-s1, .mx-svg .mx-value.mx-s2, .mx-svg .mx-value.mx-s3,
.mx-svg .mx-value.mx-s4, .mx-svg .mx-value.mx-s5, .mx-svg .mx-value.mx-s6,
.mx-svg .mx-value.mx-s7 { fill: var(--series); }

.mx-legend {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 0.5rem 1.5rem;
    margin-top: 0.5rem;
    font-size: 0.75rem;
    color: var(--text-secondary);
}
.mx-legend-item { display: inline-flex; align-items: center; gap: 0.4rem; cursor: pointer; }
.mx-legend-item input { accent-color: var(--accent-blue); margin: 0; }
.mx-swatch { width: 10px; height: 10px; border-radius: 2px; background: var(--series); display: inline-block; }
.mx-foot { margin-top: 0.5rem; font-size: 0.75rem; color: var(--text-muted); text-align: center; }

@media (max-width: 900px) {
    .mx { grid-template-columns: minmax(0, 1fr); gap: 0.875rem; }
    .mx-rail {
        flex-direction: row;
        overflow-x: auto;
        padding-bottom: 0.25rem;
        scrollbar-width: thin;
        -webkit-overflow-scrolling: touch;
    }
    .mx-btn { flex: 0 0 auto; width: auto; min-width: 190px; }
}
/* ── advisor privacy note ─────────────────────────────────────────────────── */

.privacy {
    display: flex;
    align-items: flex-start;
    gap: 0.625rem;
    background: var(--bg-secondary);
    border: 1px solid var(--border-color);
    border-radius: 10px;
    padding: 0.75rem 0.875rem;
    font-size: 0.75rem;
    color: var(--text-secondary);
    line-height: 1.55;
}
.privacy svg { width: 15px; height: 15px; flex: none; margin-top: 1px; fill: none; stroke: currentColor; stroke-width: 1.75; stroke-linecap: round; stroke-linejoin: round; color: var(--text-muted); }
/* ── two-column layout helper ─────────────────────────────────────────────── */

.split { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 1rem; align-items: start; }
/* ── back link ────────────────────────────────────────────────────────────── */

.crumb {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    margin-bottom: 0.875rem;
    flex-wrap: wrap;
}
/* ── footer ───────────────────────────────────────────────────────────────── */

.foot {
    margin-top: 1.5rem;
    padding-top: 1rem;
    border-top: 1px solid var(--border-color);
    font-size: 0.6875rem;
    color: var(--text-muted);
    line-height: 1.6;
}
/* ── embedded mode (?embed=1) ─────────────────────────────────────────────
   The extension appends embed=1 to every framed page (config.js,
   appendEmbedParam). Drops our own page chrome and tightens the gutter so this
   reads as a page of Shopmonkey rather than a site sitting in a box. The
   standing demo-data banner deliberately survives — an unlabelled screen of
   invented figures inside the real product is the one thing that must not
   happen. */
body.embed .header { display: none; }
body.embed .foot { display: none; }
body.embed .container { padding: 0.875rem; max-width: none; }
body.embed .transcript-scroll { max-height: 66vh; }
/* =============================================================================
 * THE LIVE COCKPIT (#/) — region 1
 * =============================================================================
 *
 * No new tokens and no new type scale: every colour below resolves to one that
 * was already here. The only genuinely new vocabulary is the red/green status
 * dot, and both ends of it come from --status-red / --status-green, which the
 * host theme is not allowed to repaint — because on this screen red and green
 * are not decoration, they are whether the advisor asked the question.
 * ========================================================================== */

.cockpit {
    background: var(--bg-card);
    border: 1px solid var(--border-color);
    border-radius: var(--border-radius);
    box-shadow: var(--shadow-sm);
    margin-bottom: 1rem;
    overflow: hidden;
}
/* ── header: state, clock, and the marker that must never come off ────────── */

.ck-head {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    flex-wrap: wrap;
    padding: 0.75rem 1.125rem;
    border-bottom: 1px solid var(--border-color);
}
.ck-head-text { flex: 1 1 200px; min-width: 0; }
.ck-status { display: inline-flex; align-items: center; gap: 0.625rem; }
.ck-pill {
    display: inline-flex;
    align-items: center;
    gap: 0.4375rem;
    padding: 0.1875rem 0.625rem;
    border-radius: 999px;
    font-size: 0.75rem;
    font-weight: 500;
    white-space: nowrap;
    background: var(--tone-neu-bg);
    color: var(--tone-neu);
}
.ck-pill.tone-pos  { background: var(--tone-pos-bg);  color: var(--tone-pos); }
.ck-pill.tone-warn { background: var(--tone-warn-bg); color: var(--tone-warn); }
.ck-pill-dot { width: 7px; height: 7px; border-radius: 50%; background: currentColor; flex: none; }
.ck-pill.tone-warn .ck-pill-dot { animation: ck-blink 1s steps(2, start) infinite; }
.ck-timer {
    font-size: 0.9375rem;
    font-weight: 600;
    letter-spacing: -0.01em;
    font-variant-numeric: tabular-nums;
    color: var(--text-primary);
}
.ck-controls { display: inline-flex; align-items: center; gap: 0.5rem; flex-wrap: wrap; }
.ck-speed {
    display: inline-flex;
    border: 1px solid var(--border-color);
    border-radius: 8px;
    overflow: hidden;
    background: var(--bg-card);
}
.ck-speed-btn {
    border: 0;
    background: transparent;
    color: var(--text-muted);
    font-family: inherit;
    font-size: 0.75rem;
    font-weight: 500;
    height: 34px;
    padding: 0 0.5625rem;
    cursor: pointer;
}
.ck-speed-btn + .ck-speed-btn { border-left: 1px solid var(--border-color); }
.ck-speed-btn:hover { background: var(--ctl-hover); }
.ck-speed-btn:focus-visible { outline: 2px solid var(--accent-blue); outline-offset: -2px; }
.ck-speed-btn.is-on { background: var(--accent-blue); color: var(--on-accent); }
/* ── state 1: idle ────────────────────────────────────────────────────────── */

.ck-idle { padding: 1.125rem; display: grid; gap: 1rem; }
.ck-idle-title { font-size: 0.875rem; font-weight: 600; margin-bottom: 0.25rem; }
.ck-idle-copy { font-size: 0.8125rem; color: var(--text-secondary); line-height: 1.6; max-width: 76ch; }
.ck-picker {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    gap: 0.625rem;
}
.ck-script {
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
    text-align: left;
    padding: 0.75rem 0.875rem;
    background: var(--bg-secondary);
    border: 1px solid var(--border-color);
    border-radius: 10px;
    font-family: inherit;
    color: inherit;
    cursor: pointer;
}
.ck-script:hover { background: var(--ctl-hover); border-color: var(--accent-blue); }
.ck-script:focus-visible { outline: 2px solid var(--accent-blue); outline-offset: 1px; }
.ck-script-top {
    display: inline-flex;
    align-items: center;
    gap: 0.4375rem;
    font-size: 0.8125rem;
    font-weight: 600;
}
.ck-script-top svg { width: 13px; height: 13px; color: var(--accent-blue-text); }
.ck-script-blurb { font-size: 0.75rem; color: var(--text-muted); line-height: 1.5; }
.ck-idle-base { border-top: 1px solid var(--border-color); padding-top: 0.875rem; }
.ck-idle-base-label { font-size: 0.75rem; font-weight: 500; color: var(--text-muted); margin-bottom: 0.5rem; }
/* ── chips: cliff notes, captured values, the idle preview ────────────────── */

.ck-chiplist { list-style: none; display: flex; flex-wrap: wrap; gap: 0.375rem; margin: 0; padding: 0; }
.ck-chip {
    display: inline-flex;
    align-items: center;
    gap: 0.375rem;
    padding: 0.25rem 0.5625rem;
    border: 1px solid var(--border-color);
    border-radius: 999px;
    background: var(--bg-secondary);
    color: var(--text-secondary);
    font-size: 0.75rem;
    font-weight: 500;
    line-height: 1.35;
}
.ck-chip svg { width: 12px; height: 12px; color: var(--text-muted); }
.ck-chip.is-idle { color: var(--text-muted); background: transparent; }
.ck-chip.is-idle .ck-dot { background: var(--disabled); }
/* A cliff note is a fact that just landed — accent hairline so the eye catches
   the arrival even after the pop animation has finished. */
.ck-chip.is-note { border-color: var(--accent-blue); color: var(--text-primary); background: var(--bg-card); }
.ck-chip.is-note svg { color: var(--accent-blue-text); }
/* A signal is awareness, not a task: amber, so it never reads as a red row
   waiting to go green or a blue fact that just landed. */
.ck-chip.is-signal { border-color: var(--status-amber); background: var(--tone-warn-bg); color: var(--tone-warn); }
.ck-chip.is-signal svg { color: var(--status-amber); }
.ck-chip.is-signal.is-fresh { animation: ck-pop 220ms ease-out; }
.ck-chip.is-leaving { animation: ck-fade 360ms ease-in forwards; pointer-events: none; }
/* A cue is a signal with something to say: the label, and under it the line
   to say next. It takes the whole strip so the ask reads as a sentence, and
   the text wraps — at 520px there is never a scrollbar. */
.ck-chip.is-signal.is-cue { flex-basis: 100%; min-width: 0; align-items: flex-start; border-radius: 10px; padding: 0.375rem 0.625rem; }
.ck-chip.is-signal.is-cue svg { flex: none; margin-top: 0.1875rem; }
.ck-chip-body { display: flex; flex-direction: column; gap: 0.125rem; min-width: 0; }
.ck-chip-sub { font-weight: 400; color: var(--text-primary); overflow-wrap: anywhere; }
/* ── state 2: incoming ────────────────────────────────────────────────────── */

.ck-incoming {
    padding: 1.125rem;
    display: grid;
    grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr);
    gap: 1rem;
    align-items: start;
}
.ck-ringing {
    display: flex;
    align-items: center;
    gap: 0.875rem;
    padding: 1rem;
    border: 1px solid var(--border-color);
    border-radius: 10px;
    background: var(--bg-secondary);
    flex-wrap: wrap;
}
.ck-ringing-icon {
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 44px;
    border-radius: 50%;
    flex: none;
    background: var(--tone-warn-bg);
    color: var(--tone-warn);
}
/* The ring. Drawn in currentColor off the token above rather than a glow in a
   colour of its own — a new literal here would be a new palette entry, and the
   host theme could never reach it. */
.ck-ringing-icon::after {
    content: '';
    position: absolute;
    inset: 0;
    border-radius: 50%;
    border: 2px solid currentColor;
    animation: ck-ring-pulse 1.2s ease-out infinite;
}
.ck-ringing-icon svg { width: 20px; height: 20px; }
.ck-ringing-label { font-size: 0.75rem; font-weight: 500; color: var(--text-muted); }
.ck-number {
    font-size: 1.25rem;
    font-weight: 600;
    letter-spacing: 0.12em;
    line-height: 1.3;
}
.ck-ringing .btn { margin-left: auto; }
.ck-known {
    padding: 0.875rem 1rem;
    border: 1px solid var(--border-color);
    border-radius: 10px;
    background: var(--bg-card);
}
.ck-known-head { display: flex; align-items: center; gap: 0.5rem; flex-wrap: wrap; margin-bottom: 0.5rem; }
.ck-known-name { font-size: 0.9375rem; font-weight: 600; letter-spacing: -0.01em; }
.ck-known-rows { display: grid; gap: 0.25rem; }
.ck-kv { display: flex; align-items: baseline; justify-content: space-between; gap: 0.75rem; font-size: 0.8125rem; }
.ck-kv dt { display: inline-flex; align-items: center; gap: 0.375rem; color: var(--text-muted); font-size: 0.75rem; }
.ck-kv dd { font-weight: 500; text-align: right; }
.ck-known-note { font-size: 0.6875rem; color: var(--text-muted); margin-top: 0.625rem; line-height: 1.5; }

/* ── the customer card (shared.js ckCustomerCard) ──────────────────────────
 * Drawn on the Preview's ringing stage, above the Live call's grid, and in
 * the Recent tab's detail. Same rules everywhere: it grows, it never scrolls;
 * compact is one head line and three short rows; a link is a link out of the
 * frame. The .ck-known* rules above are its base — .ck-cust adds the states.
 * SVG rules are written `.container .ck-cust-… svg` on purpose: the app-wide
 * `.container svg` (0,1,1) beats a bare class selector, same as .mx-svg. */
.ck-cust { padding: 0.75rem 0.875rem; border: 1px solid var(--border-color); border-radius: 10px; background: var(--bg-card); }
.ck-cust.is-fresh { animation: ck-pop 260ms ease-out; }
.ck-cust.is-checking { border-style: dashed; }
.ck-cust.is-checking .ck-known-name { color: var(--text-muted); font-weight: 500; }
.ck-cust.is-warn { border-color: var(--status-amber); }
.ck-cust.is-ambiguous { border-color: var(--status-amber); }
.ck-cust-head { margin-bottom: 0.375rem; }
.ck-cust-head .ck-known-name { min-width: 0; overflow-wrap: anywhere; }
/* The whole number, selectable, and a tel: link when it is one — the advisor
   is on the phone with it, and one click calls it back. */
.ck-cust-phone { margin-left: auto; font-size: 0.75rem; color: var(--text-muted); font-variant-numeric: tabular-nums; letter-spacing: 0.06em; white-space: nowrap; user-select: text; }
a.ck-cust-phone { color: var(--accent-blue-text); text-decoration: none; }
a.ck-cust-phone:hover { text-decoration: underline; }
a.ck-cust-phone:focus-visible { outline: 2px solid var(--accent-blue); outline-offset: 2px; border-radius: 3px; }
.ck-cust-link { display: inline-flex; align-items: center; gap: 0.25rem; color: var(--accent-blue-text); text-decoration: none; }
.ck-cust-link:hover { text-decoration: underline; }
.ck-cust-link:focus-visible { outline: 2px solid var(--accent-blue); outline-offset: 2px; border-radius: 3px; }
.container .ck-cust-link svg { width: 11px; height: 11px; opacity: 0.8; }
/* Compact rows read across at any width the card gets: label left, value
   right, wrapping to two lines rather than clipping a long vehicle name. */
.ck-cust-rows { gap: 0.1875rem; }
.ck-cust-rows .ck-kv { flex-wrap: wrap; }
.ck-cust-rows .ck-kv dd { margin: 0; min-width: 0; overflow-wrap: anywhere; }
.ck-cust-cue { display: flex; align-items: flex-start; gap: 0.375rem; margin-top: 0.5rem; padding: 0.375rem 0.5rem; border-radius: 6px; background: var(--tone-warn-bg); color: var(--tone-warn); font-size: 0.75rem; line-height: 1.4; }
.container .ck-cust-cue svg { width: 12px; height: 12px; margin-top: 2px; color: var(--status-amber); }
.ck-cust-note { font-size: 0.6875rem; color: var(--text-muted); margin-top: 0.5rem; line-height: 1.5; }
/* The open state: two lists, the vehicles and the orders. Rows are flex and
   wrap, so a plate + mileage + date tail drops under the name on a narrow
   card instead of forcing a horizontal scroll. */
.ck-cust-body { margin-top: 0.625rem; padding-top: 0.5rem; border-top: 1px solid var(--border-color); }
.ck-cust-sub { font-size: 0.6875rem; font-weight: 600; color: var(--text-muted); margin: 0.375rem 0 0.25rem; }
.ck-cust-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.25rem; }
.ck-cust-list li { display: flex; align-items: center; gap: 0.375rem 0.5rem; flex-wrap: wrap; font-size: 0.8125rem; min-width: 0; }
.ck-cust-list li.is-oncall .ck-cust-main { font-weight: 600; }
/* A link in a list row is a row, not a headline: same size as its neighbours. */
.ck-cust-list .ck-cust-link { font-size: 0.8125rem; font-weight: 500; }
.ck-cust-main { font-weight: 500; }
.ck-cust-dim { font-size: 0.6875rem; color: var(--text-muted); min-width: 0; overflow-wrap: anywhere; }
.ck-cust-toggle { margin-top: 0.5rem; }
/* "Confirm these N": the rows the server offered from this record, and one
   yes for the lot. A line of its own so it is never mistaken for a fact. */
.ck-cust-suggest { display: flex; align-items: center; flex-wrap: wrap; gap: 0.375rem 0.625rem; margin-top: 0.5rem; padding: 0.375rem 0.5rem; border-radius: 6px; background: var(--tone-info-bg); }
.ck-cust-suggest-text { font-size: 0.75rem; color: var(--tone-info); flex: 1 1 12rem; min-width: 0; }
.ck-cust-confirm { flex: none; }
.container .ck-cust-confirm svg { width: 12px; height: 12px; }
/* "Use" on a candidate: the advisor's pick. */
.ck-cust-use { margin-left: auto; padding: 0.125rem 0.5rem; }
.container .ck-cust-use svg { width: 11px; height: 11px; }
/* "Find by name": one input, one button, results under. Grows, never scrolls. */
.ck-cust-search { margin-top: 0.5rem; display: grid; gap: 0.375rem; }
.ck-cust-search-row { display: flex; align-items: center; gap: 0.375rem; flex-wrap: wrap; }
.ck-cust-search-in { width: auto; flex: 1 1 10rem; min-width: 0; }
.container .ck-cust-search-row .ck-copy svg { width: 12px; height: 12px; }
.ck-cust-note.is-error { color: var(--status-red); }
/* ── states 3–5: the working layout ───────────────────────────────────────── */

.ck-work { padding: 1.125rem; }
.ck-connected {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.5rem 0.75rem;
    margin-bottom: 0.875rem;
    border-radius: 8px;
    background: var(--tone-pos-bg);
    color: var(--tone-pos);
    font-size: 0.8125rem;
    animation: ck-pop 260ms ease-out;
}
.ck-grid {
    display: grid;
    grid-template-columns: minmax(0, 1.15fr) minmax(0, 0.95fr) minmax(0, 0.9fr);
    gap: 0.875rem;
    align-items: stretch;
}
.ck-pane {
    display: flex;
    flex-direction: column;
    min-height: 0;
    border: 1px solid var(--border-color);
    border-radius: 10px;
    background: var(--bg-secondary);
    overflow: hidden;
}
/* The transcript column carries the RO note under it: the words on top, the
   note written from those words directly beneath. */
.ck-col { display: grid; grid-template-rows: auto auto; gap: 0.875rem; min-height: 0; align-content: start; }
.ck-pane-head { padding: 0.625rem 0.875rem; border-bottom: 1px solid var(--border-color); }
.ck-pane-head.is-split { display: flex; align-items: center; justify-content: space-between; gap: 0.75rem; }
.ck-pane-title {
    display: inline-flex;
    align-items: center;
    gap: 0.4375rem;
    font-size: 0.8125rem;
    font-weight: 600;
    letter-spacing: -0.01em;
}
.ck-pane-title svg { width: 14px; height: 14px; color: var(--text-muted); }
.ck-pane-sub { font-size: 0.6875rem; color: var(--text-muted); margin-top: 0.0625rem; }
/* --- transcript --- */

.ck-transcript {
    flex: 1;
    min-height: 232px;
    max-height: 340px;
    overflow-y: auto;
    overscroll-behavior: contain;   /* never chain to the Shopmonkey page */
    padding: 0.625rem 0.875rem 0.875rem;
    display: flex;
    flex-direction: column;
    gap: 0.375rem;
}
.ck-transcript:focus-visible { outline: 2px solid var(--accent-blue); outline-offset: -2px; }
/* Advisor and caller are told apart by alignment and weight, not by two loud
   colours — a transcript striped red and blue is unreadable at speed. */
.ck-line { max-width: 92%; padding: 0.4375rem 0.625rem; border-radius: 8px; }
.ck-line.advisor { align-self: flex-start; background: var(--bg-card); border: 1px solid var(--border-color); }
.ck-line.caller  { align-self: flex-end; background: var(--tone-info-bg); }
.ck-line-meta { display: flex; align-items: baseline; gap: 0.5rem; margin-bottom: 0.125rem; }
.ck-line-who { font-size: 0.625rem; font-weight: 600; letter-spacing: 0.04em; color: var(--text-muted); }
.ck-line-at { font-size: 0.625rem; color: var(--text-muted); font-variant-numeric: tabular-nums; margin-left: auto; }
.ck-line-text { font-size: 0.8125rem; line-height: 1.55; color: var(--text-secondary); }
.ck-line.caller .ck-line-text { color: var(--text-primary); font-weight: 500; }
.ck-line.is-fresh { animation: ck-pop 220ms ease-out; }
/* --- the RO note ---
   Monospaced and left alone: this is meant to look like the box it is going to
   be pasted into, not like more app chrome. The blank line between facts is the
   gap, so a paste keeps the shop's paragraph-per-fact habit. */
.ck-ro {
    padding: 0.75rem 0.875rem;
    display: flex;
    flex-direction: column;
    gap: 0.6875rem;
    max-height: 244px;
    overflow-y: auto;
    overscroll-behavior: contain;
}
.ck-ro-line {
    margin: 0;
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: 0.75rem;
    line-height: 1.55;
    color: var(--text-primary);
}
.ck-ro-line.is-fresh { animation: ck-pop 220ms ease-out; }
.ck-ro-empty { margin: 0; font-size: 0.75rem; color: var(--text-muted); }
/* The live panel's note is a box the advisor can type in (Dave, 2026-09-10).
   It is as tall as its text — live.js sets the height from scrollHeight on
   every change — and never scrolls; the pane grows with it, and so does the
   520 px extension frame, which scrolls as a whole. Same monospace as the
   read-only lines, so it still looks like the box it is pasted into. */
.lv-call .ck-ro, .lv-scard-detail .ck-ro { max-height: none; overflow: visible; gap: 0.5rem; }
.ck-ro-edit {
    display: block;
    width: 100%;
    box-sizing: border-box;
    margin: 0;
    padding: 0.5rem 0.625rem;
    border: 1px solid var(--border-color);
    border-radius: 7px;
    background: var(--bg-card);
    color: var(--text-primary);
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: 0.75rem;
    line-height: 1.55;
    resize: none;
    overflow: hidden;
    min-height: 3.2em;
    white-space: pre-wrap;
    overflow-wrap: anywhere;
}
.ck-ro-edit::placeholder { color: var(--text-muted); font-family: inherit; }
.ck-ro-edit:focus-visible { outline: 2px solid var(--accent-blue); outline-offset: -1px; }
.ck-ro-edit.is-fresh { animation: ck-pop 220ms ease-out; }
.ck-ro.is-edited .ck-ro-edit { border-color: var(--accent-blue); }
/* "Updated note available — use it": only while a newer server note waits
   behind an edit. Wraps, so it fits the narrow frame. */
.ck-ro-update {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.375rem 0.625rem;
    margin: 0;
    padding: 0.375rem 0.5rem;
    border-radius: 6px;
    background: var(--tone-warn-bg);
    color: var(--tone-warn);
    font-size: 0.6875rem;
    line-height: 1.45;
}
.ck-ro-update[hidden] { display: none; }
.ck-ro-update-text { flex: 1 1 auto; font-weight: 600; }
.container .ck-ro-update svg { width: 11px; height: 11px; flex: none; }
.ck-ro-update .lv-ro-textbtn { color: inherit; font-weight: 600; }
.ck-ro-update .lv-ro-textbtn.is-quiet { font-weight: 400; opacity: 0.8; }
.ck-copy {
    display: inline-flex;
    align-items: center;
    gap: 0.375rem;
    flex: none;
    padding: 0.3125rem 0.5625rem;
    border: 1px solid var(--border-color);
    border-radius: 7px;
    background: var(--bg-card);
    color: var(--text-secondary);
    font-family: inherit;
    font-size: 0.6875rem;
    cursor: pointer;
}
.ck-copy:hover { color: var(--text-primary); border-color: var(--text-muted); }
.ck-copy svg { width: 12px; height: 12px; }
/* --- the checklist --- */

.ck-coverage {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    padding: 0.75rem 0.875rem;
    border-bottom: 1px solid var(--border-color);
}
.ck-coverage-figure { font-size: 1.0625rem; font-weight: 600; letter-spacing: -0.02em; }
.ck-coverage-label { font-size: 0.6875rem; color: var(--text-muted); }
/* The ring has to opt out of the app-wide 14px icon baseline, so its size and
   stroke ride on custom properties set by ckRing(). */
.home .ck-ring { width: var(--ring-size); height: var(--ring-size); flex: none; display: block; }
.home .ck-ring circle { fill: none; stroke-width: var(--ring-thick); }
.home .ck-ring .ck-ring-track { stroke: var(--bg-tertiary); }
.home .ck-ring .ck-ring-arc {
    stroke: var(--status-green);
    stroke-linecap: round;
    transition: stroke-dasharray 420ms ease-out;
}
/* The checklist never scrolls. It is the one thing on this screen an advisor
   reads mid-call, and a row hidden below a fold is a row that does not get
   asked — so the list renders at full height and the grid row grows to fit it.
   The transcript and the RO note keep their own caps and scroll instead. */
.ck-rows { list-style: none; margin: 0; padding: 0; flex: 0 0 auto; overflow: visible; }
/* Only the frozen copies in the idle and detail views may scroll. */
.ck-rows.is-static { max-height: 340px; overflow-y: auto; overscroll-behavior: contain; }
.ck-row {
    display: flex;
    align-items: flex-start;
    gap: 0.5rem;
    padding: 0.4375rem 0.875rem;
    border-bottom: 1px solid var(--border-color);
}
.ck-row:last-child { border-bottom: none; }
.ck-row-main { min-width: 0; flex: 1; }
.ck-row-label {
    display: flex;
    align-items: center;
    gap: 0.375rem;
    font-size: 0.75rem;
    font-weight: 500;
    color: var(--text-secondary);
}
.ck-row-label svg { width: 12px; height: 12px; color: var(--text-muted); }
.ck-row-value { display: block; font-size: 0.75rem; color: var(--text-muted); line-height: 1.45; }
.ck-row.is-done .ck-row-label { color: var(--text-primary); }
.ck-row.is-done .ck-row-value { color: var(--status-green); font-weight: 500; }
.ck-row.is-fresh { animation: ck-pop 220ms ease-out; }
.ck-row.is-just-done { animation: ck-flip 620ms ease-out; }
/* A row the call no longer asks for. It fades rather than vanishes — a green
   one especially, so the eye sees "kept" rather than "lost" — and the height
   collapses with it so the rows below slide up instead of jumping. */
.ck-row.is-leaving { animation: ck-leave 420ms ease-in forwards; overflow: hidden; pointer-events: none; }
/* The customer asked first: amber, still open, with the coaching in the hint. */
.ck-row.is-blocked .ck-dot { background: var(--status-amber); }
.ck-row.is-blocked .ck-row-value { color: var(--tone-warn); }
/* Suggested from the Shopmonkey record: the dot stays open (a ring, not a
   fill), the value is italic and muted-blue, so it reads as "the CRM says"
   and not as captured. It goes green when the advisor ticks it or the
   transcript earns it. The value is the edit control: hover and focus show
   the outline, and the input that replaces it takes the same slot. */
.ck-row.is-suggested .ck-dot { background: transparent; box-shadow: inset 0 0 0 2px var(--accent-blue-text); }
.ck-row.is-suggested .ck-row-value {
    color: var(--accent-blue-text);
    font-style: italic;
    font-weight: 500;
    opacity: 0.85;
    cursor: text;
    border-radius: 4px;
    margin-left: -0.1875rem;
    padding: 0 0.1875rem;
}
.ck-row.is-suggested .ck-row-value:hover,
.ck-row.is-suggested .ck-row-value:focus-visible { outline: 1px dashed var(--accent-blue-text); outline-offset: 1px; opacity: 1; }
.ck-row-value[hidden] { display: none; }
.ck-row-edit {
    display: block;
    width: 100%;
    max-width: 22rem;
    margin-top: 0.125rem;
    padding: 0.125rem 0.375rem;
    border: 1px solid var(--accent-blue-text);
    border-radius: 5px;
    background: var(--bg-card);
    color: var(--text-primary);
    font: inherit;
    font-size: 0.75rem;
    line-height: 1.45;
}
.ck-row-edit:focus-visible { outline: 2px solid var(--accent-blue); outline-offset: -1px; }
/* A click that is on its way to the server: the row keeps its new state,
   just quieter, and the buttons wait. */
.ck-row.is-pending { opacity: 0.7; }
.ck-row.is-pending .ck-row-value { cursor: default; }
/* Under the value: the reason a click did not land, or the record
   disagreeing with the call ("Call said … · Shopmonkey has …"). Empty is
   gone, so a row without one is the same height it always was. */
.ck-row-note { display: block; font-size: 0.6875rem; line-height: 1.4; color: var(--text-muted); margin-top: 0.0625rem; overflow-wrap: anywhere; }
.ck-row-note:empty { display: none; }
.ck-row-note.is-mismatch { color: var(--tone-warn); }
.ck-row-note.is-error { color: var(--status-red); }
/* The chip and the two buttons, on the right of a suggested row. They wrap
   under the value in a narrow frame rather than squeezing it. */
.ck-row-tools { display: flex; align-items: center; gap: 0.25rem; flex: none; margin-top: 0.0625rem; }
.ck-row-tools:empty { display: none; }
.ck-src-chip {
    font-size: 0.625rem;
    font-weight: 600;
    letter-spacing: 0.02em;
    padding: 0.0625rem 0.375rem;
    border-radius: 999px;
    background: var(--tone-info-bg);
    color: var(--tone-info);
    white-space: nowrap;
}
.ck-row-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 24px;
    height: 24px;
    padding: 0;
    border: 1px solid var(--border-color);
    border-radius: 6px;
    background: var(--bg-card);
    color: var(--text-secondary);
    cursor: pointer;
}
.ck-row-btn:hover { border-color: var(--text-muted); color: var(--text-primary); }
.ck-row-btn.is-yes:hover { border-color: var(--status-green); color: var(--status-green); }
.ck-row-btn.is-no:hover { border-color: var(--status-red); color: var(--status-red); }
.ck-row-btn:focus-visible { outline: 2px solid var(--accent-blue); outline-offset: 1px; }
.ck-row-btn:disabled { opacity: 0.5; cursor: default; }
/* `.container svg` (0,1,1) would win over a bare .ck-row-btn svg — scoped. */
.container .ck-row-btn svg { width: 12px; height: 12px; stroke-width: 2.5; }
@media (max-width: 560px) {
    .ck-row { flex-wrap: wrap; }
    .ck-row-tools { flex-basis: 100%; justify-content: flex-end; margin-top: 0.25rem; }
}
/* THE dot. Red until it is asked, green once it is captured. */
.ck-dot {
    width: 9px;
    height: 9px;
    border-radius: 50%;
    flex: none;
    margin-top: 0.3125rem;
    background: var(--status-red);
}
.ck-row.is-done .ck-dot { background: var(--status-green); }
.ck-dot.is-info { background: var(--accent-blue); }
/* --- cliff notes + coaching --- */

.ck-side { display: grid; grid-template-rows: auto minmax(0, 1fr); gap: 0.875rem; min-height: 0; }
.ck-notes { padding: 0.75rem 0.875rem; }
.ck-flags { padding: 0.75rem 0.875rem; display: grid; gap: 0.5rem; align-content: start; overflow-y: auto; overscroll-behavior: contain; max-height: 268px; }
.ck-flags-empty { font-size: 0.75rem; color: var(--text-muted); }
/* An open flag carries the amber rail; a satisfied one turns green and settles
   rather than vanishing, so the advisor sees that they closed it. */
.ck-flag {
    border: 1px solid var(--border-color);
    border-left: 3px solid var(--status-amber);
    border-radius: 8px;
    background: var(--bg-card);
    padding: 0.5rem 0.625rem;
}
.ck-flag.is-fresh { animation: ck-pop 220ms ease-out; }
.ck-flag.is-done { border-left-color: var(--status-green); opacity: 0.82; }
.ck-flag-top { display: flex; align-items: baseline; gap: 0.5rem; flex-wrap: wrap; margin-bottom: 0.1875rem; }
.ck-flag-kind {
    display: inline-flex;
    align-items: center;
    gap: 0.3125rem;
    font-size: 0.625rem;
    font-weight: 600;
    letter-spacing: 0.03em;
    text-transform: uppercase;
    color: var(--tone-warn);
}
.ck-flag-kind svg { width: 11px; height: 11px; stroke-width: 2; }
.ck-flag.is-done .ck-flag-kind { color: var(--status-green); }
.ck-flag-rule { font-size: 0.6875rem; color: var(--text-muted); }
.ck-flag-prompt { font-size: 0.8125rem; line-height: 1.5; color: var(--text-primary); }
.ck-flag-state {
    display: inline-flex;
    align-items: center;
    gap: 0.3125rem;
    margin-top: 0.3125rem;
    font-size: 0.6875rem;
    font-weight: 500;
    color: var(--text-muted);
}
.ck-flag-state svg { width: 11px; height: 11px; stroke-width: 2; }
.ck-flag.is-done .ck-flag-state { color: var(--status-green); }
/* --- wrap-up banner --- */

.ck-banner {
    display: flex;
    align-items: flex-start;
    gap: 0.625rem;
    padding: 0.75rem 0.875rem;
    margin-bottom: 0.875rem;
    border: 1px solid var(--border-color);
    border-radius: 10px;
    animation: ck-pop 260ms ease-out;
}
.ck-banner.is-good { background: var(--tone-pos-bg); border-color: var(--tone-pos-bg); }
.ck-banner.is-miss { background: var(--tone-neg-bg); border-color: var(--tone-neg-bg); }
.ck-banner-icon { flex: none; margin-top: 2px; }
.ck-banner.is-good .ck-banner-icon { color: var(--status-green); }
.ck-banner.is-miss .ck-banner-icon { color: var(--status-red); }
.ck-banner-icon svg { width: 17px; height: 17px; stroke-width: 2.25; }
.ck-banner-title { font-size: 0.875rem; font-weight: 600; letter-spacing: -0.01em; }
.ck-banner.is-good .ck-banner-title { color: var(--tone-pos); }
.ck-banner.is-miss .ck-banner-title { color: var(--tone-neg); }
.ck-banner-sub { font-size: 0.75rem; color: var(--text-secondary); margin-top: 0.125rem; }
.ck-miss { list-style: none; margin: 0.5rem 0 0; padding: 0; display: grid; gap: 0.3125rem; }
.ck-miss li { display: flex; align-items: flex-start; gap: 0.5rem; font-size: 0.75rem; color: var(--text-secondary); line-height: 1.5; }
.ck-miss b { color: var(--text-primary); font-weight: 600; }
/* =============================================================================
 * THE CALL STRIP (#/) — region 2
 * ========================================================================== */

.ck-strip-actions { display: inline-flex; align-items: center; gap: 0.5rem; flex-wrap: wrap; }
/* Dave, 2026-08-10: the calls stack vertically and each one spans the full
   width of the panel. Nothing scrolls sideways, nothing is hidden off the
   right edge — the whole list is on screen and a click opens one in place. */
.strip {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    padding: 1rem 1.125rem 0.25rem;
}
.scard {
    display: flex;
    flex-direction: column;         /* face on top, detail drops beneath it */
    border: 1px solid var(--border-color);
    border-radius: 10px;
    background: var(--bg-secondary);
    overflow: hidden;
}
.scard.is-open { border-color: var(--accent-blue); }
.scard-face {
    width: 100%;
    flex: 0 0 auto;
    display: flex;
    align-items: center;            /* one row: who, then how it went, then the number */
    flex-wrap: wrap;
    gap: 0.75rem 1rem;
    text-align: left;
    padding: 0.75rem 0.875rem;
    background: transparent;
    border: 0;
    font-family: inherit;
    color: inherit;
    cursor: pointer;
}
.scard-face:hover { background: var(--ctl-hover); }
.scard-face:focus-visible { outline: 2px solid var(--accent-blue); outline-offset: -2px; }
.scard-top { display: flex; align-items: center; gap: 0.5rem; flex: 1 1 200px; min-width: 0; }
.scard-ring { flex: none; }
.scard-id { min-width: 0; }
.scard-name { font-size: 0.8125rem; font-weight: 600; letter-spacing: -0.01em; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.scard-time { font-size: 0.6875rem; color: var(--text-muted); white-space: nowrap; }
.scard-meta { display: flex; align-items: center; gap: 0.5rem; flex: 2 1 220px; min-width: 0; }
.scard-dot { width: 10px; height: 10px; border-radius: 50%; flex: none; background: var(--disabled); }
.scard-dot.tone-good { background: var(--status-green); }
.scard-dot.tone-warn { background: var(--status-amber); }
.scard-dot.tone-bad  { background: var(--status-red); }
.scard-durwrap { flex: 1; max-width: 420px; height: 6px; background: var(--bg-tertiary); border-radius: 3px; overflow: hidden; }
.scard-dur { display: block; height: 100%; border-radius: 3px; background: var(--accent-blue); }
.scard-src { display: inline-flex; color: var(--text-muted); flex: none; }
/* Last thing on the row, pushed to the right edge so the numbers line up down
   the list rather than floating wherever the name above them ended. */
.scard-phone { margin-left: auto; font-size: 0.6875rem; color: var(--text-muted); letter-spacing: 0.06em; }
/* The expansion. The detail panel unrolls below the row and the rows beneath it
   move down — nothing shifts sideways and nothing is covered up.
   Animated as a grid row from 0fr to 1fr rather than as a max-height, because
   Dave, 2026-09: a max-height cap is a ceiling, and a ceiling on a long call is
   a scrollbar. 1fr is literally "as tall as the content", so the panel opens to
   exactly the size of the call inside it and nothing here ever scrolls. */
.scard-detail {
    display: grid;
    grid-template-rows: 0fr;
    visibility: hidden;
    border-top: 1px solid transparent;
    transition: grid-template-rows 320ms ease, visibility 0s linear 320ms;
}
.scard.is-open .scard-detail {
    grid-template-rows: 1fr;
    visibility: visible;
    border-top-color: var(--border-color);
    transition: grid-template-rows 320ms ease, visibility 0s;
}
/* Full width now, so the three blocks sit beside each other instead of stacking
   into a column the length of an arm. They fall back to one column on a phone
   on their own, which is what the auto-fit is for. */
.scard-detail-inner {
    width: 100%;
    min-height: 0;
    /* overflow:hidden is what makes the 0fr collapse clip; it is not a scroll
       box, and there is no height cap above it to scroll against. */
    overflow: hidden;
    padding: 0.875rem 1.125rem 1.125rem;
    background: var(--bg-card);
    display: grid;
    /* The transcript is the wordy one, so it gets the wider column; the
       checklist and the RO note are short lines and read fine narrower. Real
       proportions rather than auto-fit, which was packing three columns into
       the left two-thirds of the card and leaving the rest of the row empty. */
    grid-template-columns: minmax(0, 1.25fr) minmax(0, 1fr) minmax(0, 1fr);
    gap: 0.875rem 1.5rem;
    align-content: start;
    align-items: start;
}
.scard-detail-head { display: flex; align-items: center; gap: 0.5rem; flex-wrap: wrap; grid-column: 1 / -1; }
.scard-open { grid-column: 1 / -1; justify-self: start; }
.scard-detail-sub { font-size: 0.6875rem; color: var(--text-muted); }
/* The signals strip is a row of chips, not a column of anything — it reads
   across the whole card above the three blocks. */
.scard-block-full { grid-column: 1 / -1; }
.scard-block-label { display: flex; align-items: baseline; gap: 0.5rem; font-size: 0.6875rem; font-weight: 600; color: var(--text-muted); margin-bottom: 0.3125rem; }
.scard-block-count { margin-left: auto; font-weight: 500; }
.scard-summary { font-size: 0.75rem; color: var(--text-secondary); line-height: 1.5; }
.scard-actions { list-style: none; margin: 0.375rem 0 0; padding: 0; display: grid; gap: 0.25rem; }
.scard-actions li { display: flex; align-items: flex-start; gap: 0.4375rem; font-size: 0.6875rem; color: var(--text-secondary); line-height: 1.45; }
.scard-actions .ck-dot { width: 6px; height: 6px; margin-top: 0.3125rem; }
.ck-rows.is-static { border: 1px solid var(--border-color); border-radius: 8px; background: var(--bg-secondary); max-height: none; }
.ck-rows.is-static .ck-row { padding: 0.3125rem 0.5rem; }
.ck-rows.is-static .ck-row-label { font-size: 0.6875rem; }
.ck-rows.is-static .ck-row-value { font-size: 0.6875rem; }
.ck-rows.is-static .ck-dot { width: 8px; height: 8px; }
/* ── cockpit animations ───────────────────────────────────────────────────
   All of them are short and none of them are load-bearing: with reduced motion
   every state change below is drawn instantly and the script keeps advancing
   on exactly the same clock. */

@keyframes ck-pop {
    from { opacity: 0; transform: scale(0.94); }
to   { opacity: 1; transform: scale(1); }
}
/* red → green, with a brief lift so the eye catches which row flipped */
@keyframes ck-flip {
    0%   { background: var(--tone-pos-bg); }
70%  { background: var(--tone-pos-bg); }
100% { background: transparent; }
}
/* a row leaving: fade, then fold */
@keyframes ck-leave {
    0%   { opacity: 1; max-height: 5rem; }
    45%  { opacity: 0; max-height: 5rem; }
    100% { opacity: 0; max-height: 0; padding-top: 0; padding-bottom: 0; border-bottom-width: 0; }
}
@keyframes ck-fade {
    from { opacity: 1; }
    to   { opacity: 0; }
}
@keyframes ck-ring-pulse {
    from { transform: scale(1);    opacity: 0.5; }
to   { transform: scale(1.75); opacity: 0; }
}
@keyframes ck-blink { 50% { opacity: 0.25; }
}
/* ── responsive ───────────────────────────────────────────────────────────── */

@media (max-width: 1180px) {
    /* Transcript across the top, checklist and coaching side by side under it.
       The checklist keeps its own column at every width above phone size. */
    .ck-grid { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
.ck-col { grid-column: 1 / -1; grid-template-rows: auto; grid-template-columns: minmax(0, 1.15fr) minmax(0, 0.85fr); }
}
@media (max-width: 960px) {
    /* Three columns of a call detail stop being readable well before phone
       width: the transcript goes full width and the two short blocks pair up
       beneath it. Still no scrolling — just a different shape. */
    .scard-detail-inner { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
    .scard-block-wide { grid-column: 1 / -1; }
    .detail-grid { grid-template-columns: minmax(0, 1fr); }
/* Extraction above transcript on narrow — see the note on .detail-grid. */
    .detail-grid > .detail-extract { order: -1; }
.split { grid-template-columns: minmax(0, 1fr); }
.ck-incoming { grid-template-columns: minmax(0, 1fr); }
}
@media (max-width: 780px) {
    /* Single column. The checklist goes first: on a small screen it is the
       screen, and the transcript is the appendix — same call as .detail-grid. */
    .ck-grid { grid-template-columns: minmax(0, 1fr); }
.ck-pane-check { order: -2; }
.ck-side { order: -1; }
.ck-col { grid-column: auto; grid-template-columns: minmax(0, 1fr); grid-template-rows: auto auto; }
.ck-transcript { max-height: 260px; }
}
@media (max-width: 620px) {
    .scard-detail-inner { grid-template-columns: minmax(0, 1fr); }
    .container { padding: 0.875rem; }
/* .header-text is flex:1 with min-width:0, so on a phone it collapses to a
       word per line rather than pushing the illustrative chip onto its own row.
       Give it the full line and let the chip drop below it. */
    .header-text { flex-basis: 100%; }
.cell-tags { max-width: 180px; }
.bar-row { grid-template-columns: minmax(72px, 110px) minmax(0, 1fr) 46px; }
.ck-head { gap: 0.5rem 0.625rem; }
.ck-ringing .btn { margin-left: 0; }
.scard-top { flex-basis: 100%; }   /* name on its own line, meta + number under it */
}
@media (prefers-reduced-motion: reduce) {
    .tline.is-flash { animation: none; }
* { scroll-behavior: auto !important; }
/* Every cockpit state change still happens — it just happens instantly.
       The script advances on the same clock either way, so the demo stays
       followable rather than being switched off. */
    .ck-line.is-fresh,
    .ck-chip.is-fresh,
    .ck-chip.is-signal.is-fresh,
    .ck-chip.is-leaving,
    .ck-row.is-fresh,
    .ck-row.is-just-done,
    .ck-row.is-leaving,
    .ck-ro-line.is-fresh,
    .ck-ro-edit.is-fresh,
    .ck-flag.is-fresh,
    .ck-banner,
    .ck-connected,
    .ck-cust.is-fresh,
    .ck-pill.tone-warn .ck-pill-dot { animation: none; }
/* The pulse is the one element that exists only to move — with reduced
       motion it is not slowed down, it is not there. */
    .ck-ringing-icon::after { animation: none; display: none; }
.home .ck-ring .ck-ring-arc,
    .scard,
    .scard-detail,
    .scard.is-open .scard-detail { transition: none; }
    /* Metric explorer: the chart swaps in place, no fade. */
    .mx-chart { transition: none; }
    .mx-btn { transition: none; }
}

/* =============================================================================
 * live.js — the real-time panel (#/realtime)
 * =============================================================================
 * Reuses the cockpit's vocabulary (.ck-*) so the live call reads exactly like
 * the simulated one. Only what differs lives here. */

.ck-pill.tone-neg  { background: var(--tone-neg-bg);  color: var(--tone-neg); }
.ck-pill.tone-info { background: var(--tone-info-bg); color: var(--tone-info); }
.ck-pill.tone-neg .ck-pill-dot { animation: none; }

.lv-endpoint {
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: 0.6875rem;
    color: var(--text-muted);
    max-width: 320px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.lv-retry { color: var(--text-muted); }
.lv-error { color: var(--tone-neg); }

.lv-facts { display: grid; gap: 0.25rem; max-width: 420px; margin: 0; }
.lv-facts .ck-kv dd { margin: 0; }

.lv-call + .lv-call { border-top: 1px solid var(--border-color); }
.lv-call .ck-connected { flex-wrap: wrap; }
.lv-call .ck-connected svg { width: 14px; height: 14px; flex: none; }
.lv-call .ck-connected strong { font-variant-numeric: tabular-nums; }
.lv-spacer { flex: 1; }
.lv-call .ck-timer { margin-left: 0; }
/* The customer card sits between the answered banner and the grid. At a
   panel width with room, the head and the three rows share one line so the
   compact card costs about 60 px; below it they stack, which is still short
   enough for the checklist (ordered first on a narrow screen) to clear the
   fold in a 520 px frame. */
.lv-call .ck-cust { margin-bottom: 0.875rem; }
.lv-call .ck-cust.is-known:not(.is-open) { display: flex; flex-wrap: wrap; align-items: center; gap: 0.375rem 1.25rem; }
.lv-call .ck-cust.is-known:not(.is-open) .ck-cust-head { margin: 0; flex: 1 1 260px; min-width: 0; }
.lv-call .ck-cust.is-known:not(.is-open) .ck-cust-rows { flex: 1 1 280px; min-width: 0; display: flex; flex-wrap: wrap; gap: 0.25rem 1rem; }
.lv-call .ck-cust.is-known:not(.is-open) .ck-cust-rows .ck-kv { justify-content: flex-start; gap: 0.375rem; }
.lv-call .ck-cust.is-known:not(.is-open) .ck-cust-cue,
.lv-call .ck-cust.is-known:not(.is-open) .ck-cust-suggest,
.lv-call .ck-cust.is-known:not(.is-open) .ck-cust-note { flex-basis: 100%; margin-top: 0.25rem; }
.lv-call .ck-cust.is-known:not(.is-open) .ck-cust-toggle { margin-top: 0; }
.lv-scard-customer .ck-cust { padding: 0.625rem 0.75rem; }

.lv-grid {
    display: grid;
    grid-template-columns: minmax(0, 1.3fr) minmax(0, 1fr);
    gap: 0.875rem;
    align-items: stretch;
}
.lv-call .ck-transcript { max-height: 420px; }
.lv-call .ck-rows { max-height: 420px; }
/* The signal strip sits between the ring and the rows, and is simply not
   there when nothing is up — no empty band. */
.lv-signals { padding: 0.5rem 0.875rem; border-bottom: 1px solid var(--border-color); }
.lv-signals:empty { display: none; }
.lv-signals.is-static { padding: 0; border-bottom: none; }
.lv-idle-more { margin: 0.5rem 0 0; font-size: 0.75rem; color: var(--text-muted); max-width: 520px; }

/* --- Send to RO ---
   Under the note. A picker of the caller's orders (or the typed number when
   there is no caller on file), a read-back of the SERVER's order over the
   exact text that will go, one Send, then what was written with a link — or
   the dry-run payload, labelled as one. Every block here grows to what it
   holds: the note preview is the whole note, the list is every order the
   server sent (it caps at ten), nothing scrolls inside the pane. Everything
   wraps, so the 520 px frame gets the same controls stacked. */
.lv-ro-send {
    display: grid;
    gap: 0.5rem;
    padding: 0.5rem 0.875rem 0.625rem;
    border-top: 1px solid var(--border-color);
}
.lv-ro-head { display: flex; align-items: baseline; gap: 0.5rem; flex-wrap: wrap; }
.lv-ro-title { display: inline-flex; align-items: center; gap: 0.375rem; font-size: 0.75rem; font-weight: 600; color: var(--text-primary); }
.container .lv-ro-title svg { width: 12px; height: 12px; }
.lv-ro-sub { font-size: 0.6875rem; color: var(--text-muted); }
.lv-ro-actions {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    flex-wrap: wrap;
}
.lv-ro-num {
    width: auto;
    flex: 1 1 10rem;
    min-width: 0;
    padding: 0.3125rem 0.5rem;
    border: 1px solid var(--border-color);
    border-radius: 7px;
    background: var(--bg-card);
    color: var(--text-primary);
    font-family: inherit;
    font-size: 0.75rem;
    font-variant-numeric: tabular-nums;
}
.lv-ro-num:focus-visible { outline: 2px solid var(--accent-blue); outline-offset: -1px; }
.lv-ro-num.is-invalid { border-color: var(--status-red); }
.lv-ro-state { flex-basis: 100%; margin: 0; font-size: 0.6875rem; line-height: 1.45; color: var(--text-muted); overflow-wrap: anywhere; }
.lv-ro-state.is-warn { color: var(--status-amber); }
.lv-ro-state.is-notice { color: var(--tone-info); }
.lv-ro-state:empty { display: none; }
.container .lv-ro-state svg { width: 11px; height: 11px; vertical-align: -1px; }
/* A plain-text button: "Try again", "A different RO number…". */
.lv-ro-textbtn { padding: 0; border: 0; background: none; color: var(--accent-blue-text); font: inherit; font-size: 0.6875rem; cursor: pointer; text-decoration: underline; }
.lv-ro-textbtn:focus-visible { outline: 2px solid var(--accent-blue); outline-offset: 2px; border-radius: 3px; }
.lv-ro-other { justify-self: start; }
/* The list: one row per order, the whole row is the button. */
.lv-ro-pick { display: grid; gap: 0.25rem; }
.lv-ro-opt {
    display: flex;
    align-items: baseline;
    gap: 0.5rem;
    flex-wrap: wrap;
    width: 100%;
    box-sizing: border-box;
    padding: 0.375rem 0.5625rem;
    border: 1px solid var(--border-color);
    border-radius: 7px;
    background: var(--bg-card);
    color: var(--text-primary);
    font-family: inherit;
    font-size: 0.75rem;
    text-align: left;
    text-decoration: none;
    cursor: pointer;
}
.lv-ro-opt:hover { border-color: var(--text-muted); }
.lv-ro-opt:focus-visible { outline: 2px solid var(--accent-blue); outline-offset: -1px; }
.lv-ro-opt.is-open { border-color: var(--tone-pos); }
.lv-ro-opt.is-off { cursor: default; color: var(--text-muted); border-style: dashed; }
.lv-ro-opt.is-off:hover { border-color: var(--border-color); }
.lv-ro-opt-num { font-weight: 600; font-variant-numeric: tabular-nums; white-space: nowrap; }
.lv-ro-opt-car { flex: 1 1 8rem; min-width: 0; overflow-wrap: anywhere; }
.lv-ro-opt-status { font-size: 0.6875rem; color: var(--text-muted); white-space: nowrap; }
.lv-ro-opt-status.is-open { color: var(--tone-pos); font-weight: 600; }
.lv-ro-new { border-style: dashed; color: var(--text-secondary); }
.lv-ro-new .lv-ro-opt-car { font-size: 0.6875rem; color: var(--text-muted); }
/* The read-back. Facts as a definition list like the rest of the panel, the
   note in the same monospace as the pane above — it IS that text. */
.lv-ro-confirm { display: grid; gap: 0.5rem; padding: 0.5rem 0.625rem; border: 1px solid var(--accent-blue); border-radius: 8px; background: var(--bg-card); }
.lv-ro-facts { display: grid; gap: 0.25rem; margin: 0; }
.lv-ro-facts .ck-kv dd { margin: 0; overflow-wrap: anywhere; }
.lv-ro-note-label { font-size: 0.6875rem; color: var(--text-muted); }
.lv-ro-note-preview {
    margin: 0;
    padding: 0.5rem 0.625rem;
    border: 1px solid var(--border-color);
    border-radius: 7px;
    background: var(--bg-card);
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: 0.75rem;
    line-height: 1.55;
    color: var(--text-primary);
    white-space: pre-wrap;
    overflow-wrap: anywhere;
    user-select: text;
}
/* What the Customer Notes box already holds, above the text that will be
   added: same box, dimmer, so the new part reads as the new part. Grows with
   its content like the note — no scrollbar anywhere in this pane. */
.lv-ro-note-preview.is-existing { color: var(--text-secondary); background: var(--bg-tertiary); border-style: dashed; }
.lv-ro-dry-note { margin: 0; padding: 0.375rem 0.5rem; border-radius: 6px; background: var(--tone-warn-bg); color: var(--tone-warn); font-size: 0.6875rem; line-height: 1.45; }
.container .lv-ro-dry-note svg { width: 11px; height: 11px; vertical-align: -1px; }
.lv-ro-go { border-color: var(--accent-blue); color: var(--accent-blue-text); font-weight: 600; }
.lv-ro-go:disabled { opacity: 0.55; cursor: default; }
.lv-ro-go:disabled:hover { border-color: var(--accent-blue); color: var(--accent-blue-text); }
/* What happened. Green edge for a write, amber and marked for a dry run. */
.lv-ro-result { display: grid; gap: 0.5rem; padding: 0.5rem 0.625rem; border: 1px solid var(--tone-pos); border-radius: 8px; background: var(--tone-pos-bg); }
.lv-ro-result.lv-ro-dry { border-color: var(--status-amber); background: var(--tone-warn-bg); }
/* Written, but the read-back did not find it: amber too, and it says so. */
.lv-ro-result.lv-ro-unverified { border-color: var(--status-amber); background: var(--tone-warn-bg); }
.lv-ro-result-line { margin: 0; font-size: 0.75rem; line-height: 1.5; color: var(--text-primary); overflow-wrap: anywhere; }
.container .lv-ro-result-line svg { width: 12px; height: 12px; vertical-align: -2px; }
.lv-ro-link { white-space: nowrap; }
.lv-ro-sent-list { margin: 0; padding: 0; list-style: none; display: grid; gap: 0.25rem; font-size: 0.75rem; line-height: 1.5; color: var(--text-primary); }
.lv-ro-sent-list li { overflow-wrap: anywhere; }
.container .lv-ro-sent-list svg { width: 12px; height: 12px; vertical-align: -2px; color: var(--tone-pos); }
.lv-scard-sends .lv-ro-sent-list { font-size: 0.8125rem; }

/* A finished call opened from the strip. The live transcript is capped because
   it is streaming and you read its tail; this one is finished, so it is the
   whole call and it sizes to itself. Same for the RO note — you copy it whole,
   and a note you have to scroll to read is a note that gets pasted short. */
.lv-scard-transcript {
    max-height: none;
    min-height: 0;
    overflow: visible;
    border: 1px solid var(--border-color);
    border-radius: 8px;
}
.lv-scard-detail .ck-ro { padding: 0; }
.lv-scard-detail .ck-rows.is-static { max-height: none; overflow: visible; }
.lv-scard-detail .ck-copy { margin-top: 0.5rem; }
.lv-strip-note { margin: 0; padding: 0.75rem 1.125rem 1rem; font-size: 0.75rem; color: var(--text-muted); }
.lv-strip-empty { margin: 0; padding: 0.5rem 1.125rem 1rem; font-size: 0.75rem; color: var(--text-muted); }
.lv-strip-note.is-warn { color: var(--status-amber); }

/* The Recent row: the face, and beside it where the note went. The face
   was the whole row; now it shares the line with a link and keeps the rest. */
.lv-scard-row { display: flex; align-items: stretch; }
.lv-scard-row .scard-face { width: auto; flex: 1 1 auto; min-width: 0; }
.scard-ro-link {
    display: inline-flex;
    align-items: center;
    gap: 0.3125rem;
    flex: none;
    align-self: center;
    margin-right: 0.875rem;
    padding: 0.25rem 0.5rem;
    border: 1px solid var(--tone-pos);
    border-radius: 999px;
    background: var(--tone-pos-bg);
    color: var(--tone-pos);
    font-size: 0.6875rem;
    font-weight: 600;
    white-space: nowrap;
    text-decoration: none;
}
a.scard-ro-link:hover { text-decoration: underline; }
a.scard-ro-link:focus-visible { outline: 2px solid var(--accent-blue); outline-offset: 2px; }
.container .scard-ro-link svg { width: 11px; height: 11px; }
/* Send to RO inside an opened Recent card: the live panel's pane, in the
   card's full-width block. Nothing in it scrolls (see .ck-ro above). */
.lv-scard-ro .ck-pane-ro { margin: 0; }
.lv-scard-ro .ck-pane-ro .ck-ro { padding: 0.5rem 0.875rem 0.625rem; }
.lv-scard-detail .lv-scard-ro .ck-copy { margin-top: 0; }

/* --- An ended call, still on the panel ---
   Dave, 2026-09: keep it up until Done. The banner drops the green and the
   pop (nothing is happening on the line), the clock is frozen, and the two
   buttons sit on the right. The transcript and the note lose their caps:
   they were capped because they were streaming and you read the tail; an
   ended call is the whole call, and it sizes to itself. */
.lv-call.is-ended .ck-connected {
    background: var(--bg-tertiary);
    color: var(--text-secondary);
    animation: none;
}
.lv-ended-state { display: inline-flex; align-items: baseline; gap: 0.25rem; font-size: 0.75rem; font-weight: 600; color: var(--text-secondary); }
.lv-ended-state .ck-timer { font-size: 0.875rem; }
.lv-call-actions { display: inline-flex; align-items: center; gap: 0.375rem; flex: none; }
.container .lv-call-actions .ck-copy svg { width: 12px; height: 12px; }
.lv-done { border-color: var(--accent-blue); color: var(--accent-blue-text); font-weight: 600; }
.lv-call.is-ended .ck-transcript { max-height: none; min-height: 0; overflow: visible; }
.lv-call.is-ended .ck-rows { max-height: none; }
.lv-call.is-ended .ck-pane-transcript .ck-pane-sub { display: none; }

/* --- Minimized: one line ---
   .is-min shows the bar and hides everything else on that call's stage,
   including the banner. The bar is a button (Enter and Space open the call
   again) with the Done button beside it, so nothing is lost by folding. */
.lv-min { display: none; }
.lv-call.is-min { padding-top: 0.625rem; padding-bottom: 0.625rem; }
.lv-call.is-min > :not(.lv-min) { display: none; }
.lv-call.is-min .lv-min { display: flex; align-items: center; gap: 0.5rem; }
.lv-min-face {
    flex: 1 1 auto;
    min-width: 0;
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.25rem 0.875rem;
    padding: 0.4375rem 0.625rem;
    border: 1px solid var(--border-color);
    border-radius: 8px;
    background: var(--bg-secondary);
    color: var(--text-primary);
    font-family: inherit;
    font-size: 0.75rem;
    text-align: left;
    cursor: pointer;
}
.lv-min-face:hover { background: var(--ctl-hover); }
.lv-min-face:focus-visible { outline: 2px solid var(--accent-blue); outline-offset: -2px; }
.lv-min-ring { flex: none; display: inline-flex; }
.lv-min-who { display: inline-flex; align-items: baseline; gap: 0.375rem; min-width: 0; }
.lv-min-who strong { font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.lv-min-sub { color: var(--text-muted); font-variant-numeric: tabular-nums; white-space: nowrap; }
.lv-min-fact { color: var(--text-muted); white-space: nowrap; font-variant-numeric: tabular-nums; }
.lv-min-ro { display: inline-flex; align-items: center; gap: 0.25rem; }
.lv-min-ro.is-sent { color: var(--tone-pos); font-weight: 600; }
.container .lv-min-ro svg { width: 11px; height: 11px; }
.lv-pill-open { margin-left: 0.375rem; }

/* Finals are inserted ahead of this box, so a partial always reads last.
   It lays out like the transcript around it, or the caller/shop sides are lost. */
.lv-partials { display: flex; flex-direction: column; gap: 0.375rem; }
.lv-partials:empty { display: none; }

/* A partial is a line still being heard: present, but not to be trusted yet. */
.ck-line.lv-partial { opacity: 0.62; }
.ck-line.lv-partial .ck-line-text { font-style: italic; }

@media (max-width: 780px) {
    .lv-grid { grid-template-columns: minmax(0, 1fr); }
    .lv-grid .ck-pane-check { order: -1; }
    .lv-call .ck-transcript { max-height: 260px; }
    .lv-call.is-ended .ck-transcript { max-height: none; }
}
/* =============================================================================
 * THE AI VOICE AGENT TAB (#/voice)
 * =============================================================================
 *
 * The Retell agent's triage list, in this app's parts: .card, the .stat
 * tiles, the .badge tints. No new colour — the three statuses are the
 * semantic tokens (red = needs us, amber = waiting on them, green = done),
 * exactly as the tiles and the checklist dots already use them. Everything
 * wraps; nothing scrolls sideways or in a nested box, because this sits in
 * a 520 px frame. */

.va-head { align-items: flex-start; }
.va-head-text { flex: 1 1 12rem; min-width: 0; }
.va-tools { display: flex; align-items: center; gap: 0.5rem; flex-wrap: wrap; min-width: 0; }
.va-tools .select { min-width: 0; }
.va-updated { overflow-wrap: anywhere; }
.va-updated.is-warn { color: var(--status-amber); }
/* Four across on a wide page; two by two in the frame. */
.va-stats { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.va-stat { min-width: 0; }
.va-stat-red .stat-value { color: var(--status-red); }
.va-stat-amber .stat-value { color: var(--status-amber); }
.va-stat-green .stat-value { color: var(--status-green); }
/* --- the list --- */

.va-list { display: flex; flex-direction: column; min-width: 0; }
.va-state { padding: 1.5rem 1.125rem; text-align: center; font-size: 0.8125rem; color: var(--text-muted); }
.va-state-text { display: flex; justify-content: center; align-items: center; gap: 0.375rem; margin: 0; overflow-wrap: anywhere; }
.va-state-text svg { flex: 0 0 auto; }
.va-state.is-error .va-state-text { color: var(--status-red); }
.va-state .btn { display: inline-flex; margin: 0.75rem auto 0; }
/* The rail on the left is the status, so the list reads at a glance even
   before the badge text is read. */
.va-call {
    border-top: 1px solid var(--border-color);
    border-left: 3px solid var(--status-red);
    padding: 0.75rem 1rem 0.875rem;
    min-width: 0;
}
.va-call:first-child { border-top: 0; }
.va-call[data-status="awaiting_reply"] { border-left-color: var(--status-amber); }
.va-call[data-status="made_contact"] { border-left-color: var(--status-green); }
/* The whole header is the expand button: a big tap target that is a real
   <button>, so aria-expanded means what it says. The tel: links live
   outside it. */
.va-call-toggle {
    display: block;
    width: 100%;
    min-height: 36px;
    padding: 0.125rem 0;
    margin: 0;
    background: none;
    border: 0;
    border-radius: 6px;
    text-align: left;
    font: inherit;
    color: inherit;
    cursor: pointer;
}
.va-call-toggle:focus-visible { outline: 2px solid var(--accent-blue); outline-offset: 2px; }
.va-call-top {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.375rem 0.5rem;
    font-size: 0.75rem;
    color: var(--text-muted);
    font-variant-numeric: tabular-nums;
}
.va-call-dur::before { content: '·'; margin-right: 0.5rem; }
.va-chev { margin-left: auto; display: inline-flex; color: var(--text-muted); transition: transform 150ms ease; }
.va-call-toggle[aria-expanded="true"] .va-chev { transform: rotate(90deg); }
.va-call-name { font-size: 0.875rem; font-weight: 600; margin-top: 0.25rem; overflow-wrap: anywhere; }
.va-call-nums { display: flex; flex-wrap: wrap; gap: 0.25rem 1rem; margin-top: 0.125rem; font-size: 0.75rem; color: var(--text-secondary); }
.va-num { display: inline-flex; align-items: baseline; gap: 0.125rem; min-width: 0; }
.va-num-label { color: var(--text-muted); }
/* A 32 px tap target on a 19 px line: the link grows into the space around
   it rather than pushing the line apart. */
.va-num .ck-cust-phone { display: inline-flex; align-items: center; min-height: 32px; margin: -0.4375rem 0; padding: 0 0.125rem; letter-spacing: 0.02em; }
.va-call-sum { margin: 0.375rem 0 0; font-size: 0.8125rem; line-height: 1.5; color: var(--text-secondary); overflow-wrap: anywhere; }
/* --- the open row --- */

.va-call-body { display: grid; gap: 0.75rem; margin-top: 0.75rem; padding-top: 0.75rem; border-top: 1px dashed var(--border-color); }
.va-call-body[hidden] { display: none; }
.va-sub { font-size: 0.6875rem; font-weight: 600; text-transform: uppercase; letter-spacing: 0.04em; color: var(--text-muted); margin-bottom: 0.375rem; }
.va-status { display: flex; flex-wrap: wrap; gap: 0.375rem; }
/* Three buttons, one pressed. The pressed one is filled in its status
   colour — SM fills exactly one thing per group. */
.va-st {
    flex: 1 1 auto;
    min-height: 34px;
    padding: 0.25rem 0.625rem;
    border: 1px solid var(--border-color);
    border-radius: 8px;
    background: var(--bg-card);
    color: var(--text-secondary);
    font-family: inherit;
    font-size: 0.75rem;
    font-weight: 500;
    cursor: pointer;
}
.va-st:hover { background: var(--ctl-hover); }
.va-st:focus-visible { outline: 2px solid var(--accent-blue); outline-offset: 1px; }
.va-st:disabled { opacity: 0.55; cursor: default; }
.va-st[aria-pressed="true"] { font-weight: 600; color: var(--on-accent); }
.va-st[data-status="response_needed"][aria-pressed="true"] { background: var(--status-red); border-color: var(--status-red); }
.va-st[data-status="awaiting_reply"][aria-pressed="true"] { background: var(--status-amber); border-color: var(--status-amber); }
.va-st[data-status="made_contact"][aria-pressed="true"] { background: var(--status-green); border-color: var(--status-green); }
.va-notes { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.375rem; font-size: 0.75rem; line-height: 1.5; }
.va-note { padding: 0.5rem 0.625rem; background: var(--bg-secondary); border: 1px solid var(--border-color); border-radius: 8px; overflow-wrap: anywhere; }
.va-note-when { color: var(--text-muted); font-variant-numeric: tabular-nums; margin-right: 0.375rem; }
.va-note-form { display: flex; align-items: flex-start; gap: 0.5rem; }
.va-note-in {
    flex: 1 1 auto;
    min-width: 0;
    min-height: 36px;
    padding: 0.4375rem 0.625rem;
    border: 1px solid var(--border-color);
    border-radius: 8px;
    background: var(--bg-card);
    color: var(--text-primary);
    font-family: inherit;
    font-size: 0.8125rem;
    line-height: 1.4;
    resize: vertical;
}
.va-note-in:focus-visible { outline: 2px solid var(--accent-blue); outline-offset: -1px; }
.va-note-in::placeholder { color: var(--text-muted); }
.va-note-in:disabled { opacity: 0.6; }
.va-call-err { margin: 0; font-size: 0.75rem; color: var(--status-red); overflow-wrap: anywhere; }
.va-call-err:empty { display: none; }
/* Delete is the only red button on the page, and it is outlined, not filled:
   SM fills one thing per group and this is never the thing. The red is the
   same semantic token as the "response needed" rail. */
.va-btn-danger { color: var(--status-red); border-color: var(--status-red); }
.va-btn-danger:hover { background: var(--tone-neg-bg); }
.va .btn:disabled { opacity: 0.55; cursor: default; }
.va .btn:disabled:hover { background: var(--bg-card); }
.va-call-foot { display: flex; justify-content: flex-end; }
/* --- the sentiment row --- */

/* The full dashboard's three faces, sitting with the timeframe. Count then
   share; the count is the figure, the share is the context. */
.va-sent { display: inline-flex; align-items: center; gap: 0.75rem; font-size: 0.75rem; font-variant-numeric: tabular-nums; }
.va-sent[hidden] { display: none; }
.va-sent-item { display: inline-flex; align-items: center; gap: 0.25rem; }
.va-sent-item svg { width: 15px; height: 15px; flex: none; fill: none; stroke: currentColor; stroke-width: 1.75; stroke-linecap: round; stroke-linejoin: round; }
.va-sent-item.is-pos { color: var(--tone-pos); }
.va-sent-item.is-neu { color: var(--text-secondary); }
.va-sent-item.is-neg { color: var(--tone-neg); }
.va-sent-n { font-weight: 600; }
.va-sent-pct { color: var(--text-muted); }
/* --- selection and the bulk bar --- */

/* A native checkbox in the accent colour: the browser draws the focus ring
   and the indeterminate state, and both themes get them for free. The 36 px
   box around it is the tap target. */
.va-check { width: 16px; height: 16px; margin: 0; accent-color: var(--accent-blue); cursor: pointer; }
.va-check:disabled { cursor: default; opacity: 0.55; }
.va-check:focus-visible { outline: 2px solid var(--accent-blue); outline-offset: 2px; }
.va-bulk {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem 0.75rem;
    padding: 0.625rem 1.125rem;
    border-bottom: 1px solid var(--border-color);
    background: var(--bg-secondary);
}
.va-bulk[hidden] { display: none; }
.va-bulk-all { display: inline-flex; align-items: center; gap: 0.5rem; min-height: 36px; font-size: 0.8125rem; font-weight: 500; color: var(--text-secondary); cursor: pointer; }
.va-bulk-count { font-size: 0.75rem; color: var(--text-muted); font-variant-numeric: tabular-nums; }
.va-bulk-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem; margin-left: auto; min-width: 0; }
.va-bulk-actions .select { min-width: 0; }
.va-bulk-msg { flex-basis: 100%; margin: 0; font-size: 0.75rem; color: var(--text-secondary); overflow-wrap: anywhere; }
.va-bulk-msg:empty { display: none; }
.va-bulk-msg.is-error { color: var(--status-red); }
/* --- the row: checkbox, then everything else --- */

.va-call-row { display: flex; align-items: flex-start; gap: 0.375rem; }
.va-pick { display: flex; align-items: center; justify-content: center; flex: none; width: 36px; min-height: 36px; margin-left: -0.625rem; }
.va-call-main { flex: 1 1 auto; min-width: 0; }
/* Shopmonkey, under the numbers: the customer's name in the neutral tint,
   the work order in the info tint because it is the one that is a link,
   and "New customer" in the warn tint — the same yellow the checklist uses
   for a cue, and the same token in both themes. */
.va-sm { display: flex; flex-wrap: wrap; gap: 0.375rem; margin-top: 0.375rem; }
.va-sm-order { text-decoration: none; }
.va-sm-order:hover, .va-sm-order:focus-visible { text-decoration: underline; filter: brightness(0.92); }
:root[data-theme="dark"] .va-sm-order:hover, :root[data-theme="dark"] .va-sm-order:focus-visible { filter: brightness(1.15); }

@media (max-width: 620px) {
    .va-stats { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .va-head-text { flex-basis: 100%; }
    .va-sent { flex-basis: 100%; }
    .va-bulk-actions { margin-left: 0; flex-basis: 100%; }
}
