/* ===========================================================================
   PACE Consulting portal - shared styling for login / sophie / call_history.
   2026-08-09: rebranded onto SentraVoice's design system.

   Loaded AFTER index.css so it can override the marketing-site cascade. The
   pages pull in the real site header via render_page's <header id="main-header">
   injection, so the nav never drifts from the main site - which is also why
   this file hides the public auth CTAs (Internal / Login / Sign Up): the
   portal has its own session and its own Log out button.

   Brand tokens come from index.css:
       --primary-blue #305CDE   --primary-hover #1e3a8a
       --font-sans    Inter
   =========================================================================== */

:root {
    --portal-bg: #f4f6fb;
    --portal-panel: #ffffff;
    --portal-border: #e3e8f0;
    --portal-ink: #0f172a;
    --portal-muted: #64748b;
    --portal-radius: 12px;
    --portal-shadow: 0 1px 2px rgba(15, 23, 42, .04), 0 4px 16px rgba(15, 23, 42, .05);
    /* One step up from the panel: group headers and stepper hovers. */
    --portal-panel-alt: #f1f5f9;
}

body {
    background: var(--portal-bg);
    color: var(--portal-ink);
    font-family: var(--font-sans);
    margin: 0;
    min-height: 100vh;
    display: flex;
    flex-direction: column;
}

/* --- site header adjustments ------------------------------------------- */
/* The portal is an internal tool: the public Login / Sign Up / Internal CTAs
   would be confusing next to the portal's own session controls. */
header .auth-links,
header .mobile-nav-auth {
    display: none !important;
}

/* --- portal sub-header (page title + page actions) ---------------------- */
.portal-bar {
    background: var(--portal-panel);
    border-bottom: 1px solid var(--portal-border);
}

.portal-bar-inner {
    max-width: 1180px;
    margin: 0 auto;
    padding: 16px 20px;
    display: flex;
    align-items: center;
    gap: 16px;
    flex-wrap: wrap;
}

.portal-title {
    display: flex;
    align-items: baseline;
    gap: 11px;
    min-width: 0;
}

.portal-title h1 {
    margin: 0;
    font-size: 20px;
    font-weight: 700;
    letter-spacing: -.015em;
    color: var(--portal-ink);
}

.portal-title span {
    font-size: 13px;
    color: var(--portal-muted);
    white-space: nowrap;
}

.portal-bar-actions {
    margin-left: auto;
    display: flex;
    align-items: center;
    gap: 10px;
}

/* --- environment badge ---------------------------------------------------
   Which Pipedrive the portal drives. Production is red on purpose: the same
   login now works against both stacks, so this is the only thing on screen
   distinguishing a sandbox click from one that makes Sophie call a real lead.
   ----------------------------------------------------------------------- */
.env-badge {
    display: inline-flex;
    align-items: center;
    padding: 4px 11px;
    border: 1px solid transparent;
    border-radius: 999px;
    font-size: 11px;
    font-weight: 800;
    letter-spacing: .07em;
    text-transform: uppercase;
    white-space: nowrap;
}

.env-badge-prod {
    background: rgba(220, 38, 38, .09);
    border-color: rgba(220, 38, 38, .32);
    color: #b91c1c;
}

.env-badge-local {
    background: var(--portal-panel-alt);
    border-color: var(--portal-border);
    color: var(--portal-muted);
}

/* On the login card it is a block of its own above the form, not a chip
   sitting beside a title - so it centres under the heading rather than
   hanging off the left edge. */
.login-card .env-badge {
    display: flex;
    width: fit-content;
    margin: 0 auto 20px;
}

.wrap {
    width: 100%;
    max-width: 1180px;
    margin: 26px auto 64px;
    padding: 0 20px;
    flex: 1;
}

.panel {
    background: var(--portal-panel);
    border: 1px solid var(--portal-border);
    border-radius: var(--portal-radius);
    box-shadow: var(--portal-shadow);
    margin-bottom: 20px;
    overflow: hidden;
}

.panel-pad {
    padding: 22px;
}

/* --- buttons ------------------------------------------------------------
   Colours are load-bearing here: they are the operator's at-a-glance signal
   for what a button DOES (blue = run, red = stop, orange = restart). The
   rebrand changes shape, weight and feedback only - never the hue.
   ----------------------------------------------------------------------- */
.actions button,
.btn {
    font-family: inherit;
    font-size: 14px;
    font-weight: 600;
    padding: 10px 18px;
    border-radius: 9px;
    border: 1px solid transparent;
    cursor: pointer;
    transition: transform .14s ease, box-shadow .14s ease, background .14s ease,
                border-color .14s ease, color .14s ease;
    display: inline-flex;
    align-items: center;
    gap: 8px;
    white-space: nowrap;
    line-height: 1.2;
}

.actions button {
    margin-right: 10px;
    margin-bottom: 10px;
}

.actions button:hover:not(:disabled),
.btn:hover:not(:disabled) {
    transform: translateY(-1px);
}

.actions button:active:not(:disabled),
.btn:active:not(:disabled) {
    transform: translateY(0);
}

.actions button:focus-visible,
.btn:focus-visible,
input:focus-visible {
    outline: 2px solid var(--primary-blue);
    outline-offset: 2px;
}

button:disabled {
    opacity: .45;
    cursor: not-allowed;
    transform: none !important;
    box-shadow: none !important;
}

/* Primary action - SentraVoice royal blue, matching .cta-button on the site */
#run-btn,
#push-btn {
    background: linear-gradient(135deg, var(--primary-blue) 0%, var(--primary-hover) 100%);
    color: #fff;
    box-shadow: 0 4px 12px rgba(48, 92, 222, .22);
}

#run-btn:hover:not(:disabled),
#push-btn:hover:not(:disabled) {
    box-shadow: 0 7px 18px rgba(48, 92, 222, .32);
}

#dry-run-btn {
    background: #eef2f9;
    color: #24324a;
    border-color: #dbe3ef;
}

#dry-run-btn:hover:not(:disabled) {
    background: #e4eaf4;
}

#stop-btn {
    background: #c0392b;
    color: #fff;
    box-shadow: 0 4px 12px rgba(192, 57, 43, .22);
}

#stop-btn:hover:not(:disabled) {
    box-shadow: 0 7px 18px rgba(192, 57, 43, .3);
}

#restart-btn {
    background: #e67e22;
    color: #fff;
    box-shadow: 0 4px 12px rgba(230, 126, 34, .22);
}

#restart-btn:hover:not(:disabled) {
    box-shadow: 0 7px 18px rgba(230, 126, 34, .3);
}

#clear-btn,
#history-btn,
#dm-btn,
#import-btn,
.btn {
    background: #fff;
    color: #33415c;
    border-color: #d3dbe7;
}

#clear-btn:hover:not(:disabled),
#history-btn:hover:not(:disabled),
#dm-btn:hover:not(:disabled),
#import-btn:hover:not(:disabled),
.btn:hover:not(:disabled) {
    background: #f5f7fb;
    border-color: #bcc7d8;
    color: var(--portal-ink);
}

#history-btn,
#dm-btn,
#import-btn {
    color: var(--primary-blue);
    border-color: rgba(48, 92, 222, .32);
}

#history-btn:hover:not(:disabled),
#dm-btn:hover:not(:disabled),
#import-btn:hover:not(:disabled) {
    background: rgba(48, 92, 222, .07);
    border-color: var(--primary-blue);
}

.btn-ghost {
    background: transparent;
    border: 1px solid #d3dbe7;
    color: #475569;
    font-size: 13px;
    padding: 8px 14px;
    border-radius: 8px;
    font-weight: 600;
    cursor: pointer;
    font-family: inherit;
    display: inline-flex;
    align-items: center;
    gap: 7px;
    transition: background .14s, border-color .14s, color .14s;
}

.btn-ghost:hover {
    background: #f1f4f9;
    border-color: #b9c4d4;
    color: var(--portal-ink);
}

/* --- file picker --------------------------------------------------------
   The native control is browser chrome plus an unstyleable "No file chosen",
   and nothing here ever styled it - see the attribute-selector note further
   down for why it inherited none of the form rules either. It is now a label
   bound to a visually hidden input, wrapped so the button and the chosen
   filename read as one control.
   ----------------------------------------------------------------------- */
.file-row {
    margin-top: 14px;
    display: flex;
    align-items: center;
    gap: 12px;
    flex-wrap: wrap;
}

.file-field {
    display: inline-flex;
    align-items: center;
    gap: 12px;
    min-width: 0;
    max-width: 100%;
    padding: 5px 14px 5px 5px;
    background: var(--portal-panel-alt);
    border: 1px solid var(--portal-border);
    border-radius: 10px;
}

/* Clipped, not display:none - a display-hidden input cannot take focus, which
   would leave the label unreachable from the keyboard. */
.file-input {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
}

.file-field label {
    flex-shrink: 0;
    background: #fff;
}

.file-field label:hover {
    background: #f1f4f9;
    border-color: #b9c4d4;
    color: var(--portal-ink);
}

/* The input is off-screen, so the focus ring has to be drawn on the wrapper
   or keyboard users get no indication at all. */
.file-field:focus-within {
    border-color: var(--primary-blue);
    box-shadow: 0 0 0 3px rgba(48, 92, 222, .13);
}

.file-name {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.file-name.has-file {
    color: var(--portal-ink);
    font-weight: 600;
}

/* --- inline controls ---------------------------------------------------- */
.toggle-row {
    margin-top: 6px;
    display: flex;
    align-items: center;
    gap: 11px;
    flex-wrap: wrap;
}

#hours-btn {
    padding: 8px 15px;
    border-radius: 20px;
    border: 1px solid #d3dbe7;
    background: #fff;
    font-size: 13px;
    font-weight: 600;
    font-family: inherit;
    cursor: pointer;
}

#hours-btn.on {
    background: #e6f4ea;
    color: #1e7e34;
    border-color: #9fd3b0;
}

#hours-btn.off {
    background: #fdecea;
    color: #c0392b;
    border-color: #f0b3ac;
}

/* NOTE: these are ATTRIBUTE selectors, so they match on the type written in the
   markup, not on the type an input defaults to. Call History's company box
   (call_history.html) has no type= attribute at all and therefore picks up none
   of this - it is styled only by .search input plus the :focus rules below.
   Add a selector here for any new control rather than assuming it inherits. */
input[type="text"],
input[type="number"],
input[type="password"],
input[type="date"],
select {
    padding: 10px 12px;
    border: 1px solid #d3dbe7;
    border-radius: 8px;
    font-size: 14px;
    font-family: inherit;
    color: var(--portal-ink);
    background: #fff;
    transition: border-color .14s, box-shadow .14s;
}

/* Native date and select chrome is a good bit taller than a text input at the
   same padding, which leaves the toolbar row visibly ragged. */
input[type="date"],
select {
    line-height: 1.2;
    height: 40px;
    cursor: pointer;
}

input:focus,
select:focus {
    outline: none;
    border-color: var(--primary-blue);
    box-shadow: 0 0 0 3px rgba(48, 92, 222, .13);
}

#max-leads-input {
    width: 92px;
}

#max-leads-save {
    padding: 8px 15px;
    border: 1px solid rgba(48, 92, 222, .35);
    border-radius: 8px;
    background: #fff;
    color: var(--primary-blue);
    font-size: 13px;
    font-weight: 600;
    font-family: inherit;
    cursor: pointer;
}

#max-leads-save:hover {
    background: rgba(48, 92, 222, .07);
    border-color: var(--primary-blue);
}

/* --- banners ------------------------------------------------------------ */
.banner {
    margin-top: 14px;
    padding: 12px 16px;
    border-radius: 9px;
    font-size: 14px;
    display: none;
}

.banner.error {
    background: #fdecea;
    color: #a5281b;
    border: 1px solid #f5c6c0;
    display: block;
}

.banner.info {
    background: #eaf1fe;
    color: #1e3a8a;
    border: 1px solid #c5d8fb;
    display: block;
}

/* Amber, not red: the run itself is fine, but the lead list it is working
   from may be incomplete (batch_runner sets run.warning - see D5). */
.banner.warn {
    background: #fef6e7;
    color: #8a5a06;
    border: 1px solid #f6dfae;
    display: block;
}

/* --- tables ------------------------------------------------------------- */
table {
    width: 100%;
    border-collapse: collapse;
    font-size: 14px;
}

thead th {
    background: #f7f9fc;
    text-align: left;
    padding: 11px 15px;
    font-size: 11.5px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .05em;
    color: #64748b;
    border-bottom: 1px solid var(--portal-border);
    white-space: nowrap;
}

tbody td {
    padding: 12px 15px;
    border-bottom: 1px solid #f0f3f8;
    vertical-align: top;
    color: #334155;
}

tbody tr:last-child td {
    border-bottom: none;
}

/* A scrolling table box. PACE runs Sophie against ~400 leads at a time, and a
   400-row run table pushed the log panel and everything under it kilometres
   down the page (Adam, 2026-08-14). Cap the height and scroll the rows inside
   the box instead of scrolling the page. Short runs still size to content -
   max-height, not height. */
.table-scroll {
    overflow: auto;
    max-height: 60vh;
}

/* Direct child only. Scheduled Calls renders one table per day, each already
   wrapped in its own overflow-x div - that div is the nearest scrollport, so a
   sticky header inside it would pin to a box that never scrolls vertically and
   do nothing. Those tables get a sticky day heading instead (see below). */
.table-scroll > table thead th {
    position: sticky;
    top: 0;
    z-index: 2;
    /* border-collapse: collapse detaches cell borders from the cell, so the
       header's border-bottom scrolls away with the rows. An inset shadow is
       painted by the cell itself and stays put. */
    border-bottom: none;
    box-shadow: inset 0 -1px 0 var(--portal-border);
}

/* The day a call falls on is the one thing you cannot recover from a row once
   it has scrolled past - "12:21, TEST_CALL_3_TOREX" means nothing without it.
   Sticky within its own day block, so each heading rides down and is pushed off
   by the next day rather than all of them stacking up. */
.sched-day {
    position: sticky;
    top: 0;
    z-index: 1;
    background: var(--portal-panel);
    padding: 2px 0 6px;
}

/* --- status + type indicators (unchanged semantics, refined weight) ------ */
.status-OK      { color: #1e7e34; font-weight: 700; }
.status-RUNNING { color: var(--primary-blue); font-weight: 700; }
.status-BLOCKED { color: #b06000; font-weight: 700; }
.status-ERROR   { color: #c0392b; font-weight: 700; }
.status-SKIPPED { color: #94a3b8; }
.status-PENDING { color: #b0b8c4; }
.status-DRY_RUN { color: #6a1b9a; font-weight: 600; }
/* Promised for a later day: visible in Upcoming, never dialed today. */
.status-SCHEDULED { color: #7b8794; font-style: italic; }

/* --- Upcoming Calls priority groups (2026-08-26) ------------------------- */
/* A header row inside the table body, so the groups scroll with their rows
   rather than needing five separate tables. */
tr.tier-head > td {
    background: var(--portal-panel-alt, #f1f5f9);
    font-weight: 700;
    font-size: 12px;
    letter-spacing: .04em;
    text-transform: uppercase;
    color: #475569;
    padding: 9px 10px 8px;
    border-top: 2px solid #cbd5e1;
}
tr.tier-head .tier-count { font-weight: 500; text-transform: none; letter-spacing: 0; color: #64748b; }
tr.tier-1 > td:first-child { box-shadow: inset 3px 0 0 #c0392b; }
tr.tier-2 > td:first-child { box-shadow: inset 3px 0 0 #b06000; }
tr.tier-3 > td:first-child { box-shadow: inset 3px 0 0 var(--primary-blue, #2563eb); }
tr.tier-4 > td:first-child { box-shadow: inset 3px 0 0 #94a3b8; }
tr.tier-5 > td:first-child { box-shadow: inset 3px 0 0 #cbd5e1; }

.type-badge,
.badge {
    display: inline-block;
    padding: 3px 11px;
    border-radius: 20px;
    font-size: 12px;
    font-weight: 600;
    white-space: nowrap;
    background: #eef2f7;
    color: #475569;
}

.type-LEAD        { background: #eaf1fe; color: #1e3a8a; }
.type-ORG_CONTACT { background: #eef2f7; color: #475569; }
.type-ORG_LINE    { background: #f3e8fd; color: #6a1b9a; }

.type-link { text-decoration: none; }
.type-link:hover .type-badge { filter: brightness(0.94); text-decoration: underline; }

.badge.booked   { background: #e6f4ea; color: #1e7e34; }
.badge.callback { background: #eaf1fe; color: #1e3a8a; }
.badge.warn     { background: #fff4e5; color: #b06000; }
.badge.bad      { background: #fdecea; color: #c0392b; }
.badge.review   { background: #f3e8fd; color: #6a1b9a; }

.loglink {
    color: var(--primary-blue);
    cursor: pointer;
    font-weight: 600;
    white-space: nowrap;
}

.loglink:hover {
    text-decoration: underline;
}

pre {
    background: #0f172a;
    color: #dbe4f0;
    padding: 18px;
    border-radius: 10px;
    overflow-x: auto;
    max-height: 480px;
    overflow-y: auto;
    font-size: 12.5px;
    line-height: 1.55;
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
}

.muted {
    color: var(--portal-muted);
    font-size: 13px;
}

/* --- login -------------------------------------------------------------- */
.login-shell {
    flex: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 56px 20px 80px;
}

.login-card {
    width: 100%;
    max-width: 412px;
    background: var(--portal-panel);
    border: 1px solid var(--portal-border);
    border-radius: 16px;
    box-shadow: 0 2px 4px rgba(15, 23, 42, .04), 0 12px 36px rgba(15, 23, 42, .08);
    padding: 38px 34px 32px;
}

.login-card h1 {
    margin: 0 0 6px;
    font-size: 23px;
    font-weight: 700;
    letter-spacing: -.02em;
    text-align: center;
}

.login-card .subtitle {
    margin: 0 0 26px;
    text-align: center;
    color: var(--portal-muted);
    font-size: 14px;
}

.form-group {
    margin-bottom: 17px;
}

.form-group label {
    display: block;
    margin-bottom: 7px;
    font-weight: 600;
    font-size: 13px;
    color: #334155;
}

.form-group input {
    width: 100%;
}

.login-btn {
    width: 100%;
    padding: 12px;
    margin-top: 6px;
    background: linear-gradient(135deg, var(--primary-blue) 0%, var(--primary-hover) 100%);
    color: #fff;
    border: none;
    border-radius: 9px;
    font-size: 15px;
    font-weight: 600;
    font-family: inherit;
    cursor: pointer;
    box-shadow: 0 4px 12px rgba(48, 92, 222, .22);
    transition: transform .14s, box-shadow .14s;
}

.login-btn:hover {
    transform: translateY(-1px);
    box-shadow: 0 7px 18px rgba(48, 92, 222, .32);
}

.error-message {
    color: #c0392b;
    margin-top: 15px;
    text-align: center;
    font-size: 13.5px;
    display: none;
}

@media (max-width: 640px) {
    .portal-bar-inner { padding: 14px 16px; }
    .portal-title h1 { font-size: 18px; }
    .wrap { padding: 0 14px; margin-top: 18px; }
    .panel-pad { padding: 17px; }
    .login-card { padding: 30px 22px 26px; }
}

/* ===========================================================================
   Call History page (deliverable 6b)
   =========================================================================== */

.toolbar {
    padding: 16px 18px;
    display: flex;
    align-items: center;
    gap: 12px;
    flex-wrap: wrap;
    border-bottom: 1px solid var(--portal-border);
    background: #fcfdff;
}

.search {
    position: relative;
    flex: 1 1 260px;
    min-width: 200px;
}

.search input {
    width: 100%;
    padding-left: 36px;
}

.search svg {
    position: absolute;
    left: 12px;
    top: 50%;
    transform: translateY(-50%);
    opacity: .42;
    pointer-events: none;
}

.count {
    color: var(--portal-muted);
    font-size: 13px;
    margin-left: auto;
    white-space: nowrap;
}

/* Second toolbar row: date range + call length (Call History).
   Kept separate from .toolbar rather than piled into it, because .count uses
   margin-left:auto and once a single wrapping row breaks, "auto" resolves
   against whichever line the count lands on - so the row count drifts around
   the toolbar as the window narrows. */
.filter-bar {
    padding: 12px 18px;
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
    border-bottom: 1px solid var(--portal-border);
    background: #fcfdff;
}

.filter-bar .filter-group {
    display: flex;
    align-items: center;
    gap: 8px;
}

/* Visually separates "date range" from "length" without a hard divider that
   would look broken the moment the row wraps. */
.filter-bar .filter-sep {
    width: 1px;
    align-self: stretch;
    background: var(--portal-border);
    margin: 0 4px;
}

.filter-bar .btn-preset {
    padding: 7px 13px;
    font-size: 13px;
    border-radius: 20px;
}

/* Pushed to the far end of the FIRST line only, so it keeps its place beside
   the controls rather than being stranded under them. */
.filter-bar .filter-clear {
    margin-left: auto;
}

.filter-note {
    padding: 9px 18px;
    font-size: 12.5px;
    color: var(--portal-muted);
    background: #fffbeb;
    border-bottom: 1px solid var(--portal-border);
}

tbody tr.call-row {
    cursor: pointer;
    transition: background .12s;
}

tbody tr.call-row td {
    vertical-align: middle;
}

tbody tr.call-row:hover {
    background: #f7f9fe;
}

tbody tr.call-row.open {
    background: #f2f6fe;
}

.company {
    font-weight: 600;
    color: var(--portal-ink);
}

.contact {
    color: var(--portal-muted);
    font-size: 13px;
}

.when {
    white-space: nowrap;
    color: #334155;
}

.when small {
    display: block;
    color: #94a3b8;
    font-size: 11.5px;
}

.rec-link {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    color: var(--primary-blue);
    text-decoration: none;
    font-size: 13px;
    font-weight: 600;
    white-space: nowrap;
}

.rec-link:hover {
    text-decoration: underline;
}

.rec-audio {
    height: 32px;
    max-width: 210px;
    vertical-align: middle;
}

.rec-none {
    color: #b0b8c4;
    font-size: 13px;
}

.chev {
    transition: transform .16s ease;
    opacity: .45;
}

tr.open .chev {
    transform: rotate(90deg);
    opacity: .85;
}

.transcript-cell {
    padding: 0 !important;
}

.transcript-inner {
    padding: 18px 22px 22px 46px;
    background: #f8fafd;
    border-bottom: 1px solid #f0f3f8;
}

.t-line {
    display: flex;
    gap: 12px;
    margin-bottom: 9px;
    font-size: 13.5px;
    line-height: 1.55;
}

.t-who {
    flex: 0 0 62px;
    font-weight: 700;
    font-size: 11px;
    text-transform: uppercase;
    letter-spacing: .05em;
    padding-top: 3px;
}

.t-line.ai .t-who { color: var(--primary-blue); }
.t-line.human .t-who { color: #b06000; }

.t-text {
    flex: 1;
    color: #334155;
}

.t-empty {
    color: #94a3b8;
    font-style: italic;
    font-size: 13.5px;
}

.pager {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 15px;
    padding: 18px;
    border-top: 1px solid var(--portal-border);
}

.pager span {
    color: var(--portal-muted);
    font-size: 13px;
}

/* --- page and day steppers (2026-08-26) ---------------------------------
   Previous / Next / Today. These live inside .toggle-row rather than
   .actions, so they were falling through to raw browser buttons sitting
   next to styled ones - the one visibly unfinished control on the page.
   Same pill as #hours-btn, which is already the shape this portal uses for
   a secondary control, so nothing new is being invented here.
   ----------------------------------------------------------------------- */
.nav-btn {
    font-family: inherit;
    font-size: 13px;
    font-weight: 600;
    padding: 7px 14px;
    border-radius: 20px;
    border: 1px solid #d3dbe7;
    background: var(--portal-panel);
    color: #475569;
    cursor: pointer;
    white-space: nowrap;
    line-height: 1.2;
    transition: background .14s ease, border-color .14s ease,
                color .14s ease, transform .14s ease;
}

.nav-btn:hover:not(:disabled) {
    background: var(--portal-panel-alt);
    border-color: var(--primary-blue);
    color: var(--primary-blue);
    transform: translateY(-1px);
}

.nav-btn:active:not(:disabled) { transform: translateY(0); }

.nav-btn:focus-visible {
    outline: 2px solid var(--primary-blue);
    outline-offset: 2px;
}

/* "Today" returns you to the default view, so it reads as the way back
   rather than as another step. */
.nav-btn-now {
    border-color: var(--primary-blue);
    color: var(--primary-blue);
}

/* Holds a stepper pair and its label together so the three read as one
   control instead of three loose buttons. */
.nav-group {
    display: inline-flex;
    align-items: center;
    gap: 8px;
}

/* Fixed width: without it the row jostles sideways every 5s as "Page 1 of
   2" becomes "Page 10 of 12" under the poll. */
.nav-label {
    font-size: 13px;
    color: var(--portal-muted);
    min-width: 9.5em;
    text-align: center;
}

.state {
    padding: 58px 20px;
    text-align: center;
    color: #94a3b8;
}

.state h3 {
    margin: 0 0 7px;
    color: #475569;
    font-size: 16.5px;
    font-weight: 700;
}

.state p {
    margin: 0;
    font-size: 14px;
}

.banner.page-banner {
    margin: 0;
    border-radius: 0;
    border-left: none;
    border-right: none;
    border-top: none;
}

.skel {
    height: 14px;
    border-radius: 5px;
    background: linear-gradient(90deg, #eef1f6 25%, #f7f9fc 50%, #eef1f6 75%);
    background-size: 200% 100%;
    animation: sh 1.2s infinite;
}

@keyframes sh {
    0%   { background-position: 200% 0; }
    100% { background-position: -200% 0; }
}

@media (max-width: 720px) {
    .hide-sm { display: none; }
    .transcript-inner { padding-left: 20px; }
}

/* Call History raises errors with classList.add('show') rather than the
   error/info split the Sophie page uses. */
.banner.show {
    background: #fdecea;
    color: #a5281b;
    border: 1px solid #f5c6c0;
    display: block;
}

/* --- Upcoming Calls: the in-flight lead, pinned ---------------------------
   Sophie's current call is drawn as the first row of Upcoming Calls and held
   there. Before this it was an ordinary row: always row 1 of the list, but
   upcomingOffset persists across the 5s refresh and fillTable restores
   scrollTop, so paging forward once or scrolling down once carried it out of
   view permanently and the only way left to see what she was on was to hunt
   for a RUNNING row in Assigned Leads.

   top is set in JS from the measured thead height, not here - the header is
   itself sticky at top:0 and wraps at narrow widths, so the offset is not a
   constant. z-index stays BELOW the header's 2 so the pin tucks under it. */
tbody tr.running-pin > td {
    position: sticky;
    z-index: 1;
    /* Opaque on purpose: sticky cells are transparent by default, and the rows
       scrolling underneath would otherwise read straight through the pin. */
    background: var(--portal-panel-alt);
    box-shadow: inset 0 -1px 0 var(--portal-border);
}

tbody tr.running-pin > td:first-child {
    box-shadow: inset 3px 0 0 var(--primary-blue), inset 0 -1px 0 var(--portal-border);
}


/* -- Decision Makers (2026-08-29) ------------------------------------------
   The page reuses the Call History table wholesale - .call-row, .chev,
   .transcript-cell and the .t-* transcript lines are all shared. These are the
   four things it has that Call History does not. */

/* One line saying what the rows are. Without it they read as leads PACE
   already had, rather than numbers Sophie was handed on the phone. */
.dm-intro {
    margin: 0 0 16px;
    color: var(--portal-muted);
    font-size: 13.5px;
    line-height: 1.55;
    max-width: 74ch;
}

/* The decision maker's role, under their name. Sits in the same cell, so it
   borrows .company's weight above it and stays clearly secondary. */
.dm-role {
    color: var(--portal-muted);
    font-size: 12.5px;
    margin-top: 2px;
}

/* tel: link. The whole point of this page is that these numbers get called, so
   the number is the action - monospaced digits, because a phone number read off
   a screen and keyed into a handset is worse in a proportional face. */
.dm-phone {
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: 13.5px;
    font-weight: 600;
    color: var(--primary-blue);
    text-decoration: none;
    white-space: nowrap;
}

.dm-phone:hover {
    text-decoration: underline;
}

/* A number Sophie was given that would not parse into something dialable -
   usually a dropped digit in the transcription. The row is kept because the
   PERSON is the find (PACE dials ~122 to reach 3 decision makers), so this
   shows what was actually said, in the same monospace as a real number but
   deliberately NOT a link and not blue: nothing here should read as callable. */
.dm-phone-bad {
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: 13.5px;
    color: var(--portal-muted);
    white-space: nowrap;
}

.dm-flag {
    display: inline-block;
    margin-top: 4px;
    padding: 2px 7px;
    border-radius: 4px;
    background: #fff4e5;
    color: #b06000;
    font-size: 10.5px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .04em;
    white-space: nowrap;
}

/* The model's verbatim quote of the moment the number was given, above the
   transcript in an expanded row. It is what makes a row checkable at a glance,
   so it is set apart from the transcript rather than being its first line. */
.dm-evidence {
    margin-bottom: 16px;
    padding: 11px 14px;
    background: #fff;
    border: 1px solid #e6ecf5;
    border-left: 3px solid var(--primary-blue);
    border-radius: 6px;
    color: #334155;
    font-size: 13.5px;
    line-height: 1.55;
    font-style: italic;
}

.dm-evidence-label {
    display: block;
    font-style: normal;
    font-weight: 700;
    font-size: 10.5px;
    text-transform: uppercase;
    letter-spacing: .06em;
    color: var(--portal-muted);
    margin-bottom: 5px;
}
