/* QuoteDash — Bootstrap 3 theme layer.
 * Bootstrap 3.4.1 (cdnjs) does the heavy lifting; this file only themes
 * it and styles the handful of custom components BS3 doesn't have:
 * stat blocks, the schedule matrix, fit bars, best-fit rows, avatars. */
:root {
    --bg: #f4f7fa;
    --card: #ffffff;
    --ink: #1c2b3a;
    --muted: #7b8fa3;
    --line: #e3ebf3;
    --accent: #0e7490;
    --accent-soft: #e0f2f7;
    --good: #15803d;
    --warn: #b45309;
    --bad: #b91c1c;
}
body { background: var(--bg); color: var(--ink); }
a { color: var(--accent); }

/* full-width shell — the 1180px cap is gone; just keep content off the
 * window edge and stop it going silly on ultrawide monitors. */
.qf-wrap { padding-left: 18px; padding-right: 18px; max-width: 2200px; }

/* navbar tint + build info */
.navbar-inverse { background: #10222f; border: 0; border-radius: 0; }
.navbar-inverse .navbar-brand { color: #9fd6e4; font-weight: 400; }
.navbar-inverse .navbar-brand b { color: #fff; }
.navbar-inverse .navbar-nav > li > a { color: #b9cdda; font-weight: 600; }
.navbar-inverse .navbar-nav > .active > a,
.navbar-inverse .navbar-nav > .active > a:hover,
.navbar-inverse .navbar-nav > li > a:hover { background: #1d3a4d; color: #fff; }
.qf-buildinfo { color: #7d95a6; font-size: 11px; line-height: 50px; margin: 0; }
.qf-buildinfo a { color: #7d95a6; }
.qf-title { font-size: 21px; margin: 20px 0 14px; font-weight: 700; }
.nav-tabs + .panel-body h2:first-child { margin-top: 0; }
.qf-foot { text-align: center; color: var(--muted); font-size: 11px; padding: 26px 0 30px; }

/* panels: keep the soft rounded look */
.panel { border-radius: 10px; border-color: var(--line); box-shadow: none; margin-bottom: 16px; }
.panel-default > .panel-heading { background: #fff; border-color: var(--line); border-radius: 10px 10px 0 0;
    font-size: 13px; text-transform: uppercase; letter-spacing: .6px; color: #44607a; font-weight: 700; }
.panel-heading small { text-transform: none; letter-spacing: 0; font-weight: 400; color: var(--muted); }
.panel-body { padding: 14px 16px; }

/* tables inside panels: tighter, small-caps headers */
.table > thead > tr > th { font-size: 11px; color: var(--muted); text-transform: uppercase;
    letter-spacing: .5px; border-bottom-width: 2px; }
.table td.r, .table th.r { text-align: right; }

/* stat blocks (no BS3 equivalent) */
.qf-stats { display: flex; flex-wrap: wrap; gap: 12px; margin-bottom: 16px; }
.qf-stat { flex: 1 1 150px; background: var(--card); border: 1px solid var(--line); border-radius: 10px; padding: 12px 14px; }
.qf-stat .n { font-size: 24px; font-weight: 800; }
.qf-stat .l { font-size: 11px; color: var(--muted); text-transform: uppercase; letter-spacing: .5px; }
.qf-stat .s { font-size: 11px; color: var(--muted); }

/* inline fit/revenue bar */
.qf-bar { display: inline-block; width: 90px; height: 8px; background: var(--line);
    border-radius: 4px; overflow: hidden; vertical-align: middle; }
.qf-bar span { display: block; height: 100%; border-radius: 4px; }

/* filter bar — the controls are Bootstrap (.form-control .input-sm /
 * .btn), so this only handles the layout and the small-caps labels BS3
 * doesn't have. Each control sits in its own flex cell. */
.qf-filters { display: flex; flex-wrap: wrap; gap: 10px; align-items: flex-end;
    background: var(--card); border: 1px solid var(--line); border-radius: 10px; padding: 12px 14px; margin-bottom: 16px; }
.qf-filters label { display: block; font-size: 10px; color: var(--muted); text-transform: uppercase; letter-spacing: .5px; margin-bottom: 3px; }
.qf-filters > div { flex: 0 1 auto; min-width: 130px; }
.qf-filters .form-control { width: 100%; }
/* long option lists (cruise line, agent) need the room */
.qf-filters > div.qf-f-wide { min-width: 240px; flex: 1 1 240px; max-width: 340px; }
/* the Apply / Reset cell shouldn't stretch */
.qf-filters > div.qf-f-act { min-width: 0; }
.qf-filters .btn-link { padding-left: 6px; padding-right: 6px; }
.qf-presets { font-size: 12px; margin: -6px 0 14px; color: var(--muted); }
.qf-presets a { margin-right: 10px; }
.qf-presets a.on { font-weight: 800; text-decoration: underline; }

/* avatars */
.qf-av { width: 34px; height: 34px; border-radius: 50%; object-fit: cover; vertical-align: middle; }
.qf-av-i { display: inline-flex; width: 34px; height: 34px; border-radius: 50%; background: #d3e4ef;
    color: #2e5470; font-weight: 800; font-size: 13px; align-items: center; justify-content: center; vertical-align: middle; }

.qf-note { font-size: 12px; color: var(--muted); margin: 6px 0 0; }
.qf-dt { width: 90px; font-size: 10px; color: var(--muted); text-transform: uppercase; letter-spacing: .5px; }
.qf-mh { font-size: 11px; font-weight: 800; color: #44607a; text-transform: uppercase; letter-spacing: .5px; margin-bottom: 6px; }

/* line chips */
.qf-chips { display: flex; flex-wrap: wrap; gap: 4px; }
.qf-chip { font-size: 11px; background: #eef2f6; border-radius: 4px; padding: 1px 6px; color: #44607a; white-space: nowrap; }
.qf-chip b { color: var(--ink); }

/* clickable quote names (open the modal) */
.qf-quote-link { cursor: pointer; color: var(--accent); font-weight: 700; background: none; border: 0; padding: 0; font-size: inherit; text-align: left; }
.qf-quote-link:hover { text-decoration: underline; }

/* best-fit agent rows */
.qf-bf-row { display: flex; align-items: center; gap: 10px; padding: 7px 10px; border-bottom: 1px solid var(--line); margin: 0; }
.qf-bf-row.past { background: #fefce8; }

/* the line between agents who can take the quote and those who can't */
.qf-bf-divider { background: #f1f5f9; border-top: 2px solid #cbd5e1; border-bottom: 1px solid var(--line);
    padding: 4px 10px; font-size: 10px; font-weight: 800; text-transform: uppercase;
    letter-spacing: .6px; color: #64748b; }

/* myquotes.php — agent identity strip + stat cells */
.qf-me { display: flex; align-items: center; gap: 16px; flex-wrap: wrap; }
.qf-me-n { text-align: right; min-width: 92px; }
.qf-me-n .n { font-size: 22px; font-weight: 800; line-height: 1.1; }
.qf-me-n .n small { font-size: 13px; color: var(--muted); font-weight: 600; }
.qf-me-n .l { font-size: 10px; color: var(--muted); text-transform: uppercase; letter-spacing: .5px; }

/* myquotes.php — the "who are you?" stand-in picker */
.qf-pick { display: grid; grid-template-columns: repeat(auto-fill, minmax(210px, 1fr)); gap: 8px; }
.qf-pick-a { display: flex; align-items: center; gap: 9px; padding: 8px 10px; border: 1px solid var(--line);
    border-radius: 8px; color: var(--ink); text-decoration: none; }
.qf-pick-a:hover { background: var(--accent-soft); border-color: var(--accent); text-decoration: none; color: var(--ink); }
.qf-pick-a .qf-note { margin: 0; }

/* presence dots — Teams-style. Driven by last_active + the 30s heartbeat
 * in qf_foot; qf_dot() renders them and ping.php keeps them current. */
.qf-dot { display: inline-block; width: 9px; height: 9px; border-radius: 50%;
    background: #cbd5e1; margin-right: 5px; vertical-align: middle;
    border: 1px solid rgba(0,0,0,.08); flex-shrink: 0; }
.qf-dot.is-online { background: #22c55e; box-shadow: 0 0 0 2px rgba(34,197,94,.18); }
.qf-dot.is-idle   { background: #f59e0b; box-shadow: 0 0 0 2px rgba(245,158,11,.15); }
.qf-dot.is-offline{ background: #cbd5e1; }

/* duplicate groups — same person, more than once */
.qf-dupe { border: 1px solid var(--line); border-left: 3px solid #cbd5e1;
    border-radius: 0 8px 8px 0; padding: 10px 12px; margin-bottom: 10px; background: #fbfdff; }
.qf-dupe.is-strong { border-left-color: var(--bad); background: #fff7f7; }
.qf-dupe-h { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.badge.qf-badge-warn { background: var(--bad); }

/* how far back the queue is showing */
.qf-window { background: var(--card); border: 1px solid var(--line); border-radius: 8px;
    padding: 8px 10px; margin-bottom: 16px; }
.qf-win { display: block; font-size: 12px; color: #44607a; padding: 3px 0; text-decoration: none; }
.qf-win:hover { color: var(--accent); text-decoration: none; }
.qf-win.on { font-weight: 800; color: var(--accent); }
.qf-win.on:before { content: '▸ '; }

/* "who's on" panel under the queue sidebar */
.qf-sidecol { width: 190px; flex-shrink: 0; }
.qf-sidecol .qf-side { width: 100%; }
.qf-whos-on-box { background: var(--card); border: 1px solid var(--line); border-radius: 8px; padding: 8px 10px; }
.qf-who-h { font-size: 10px; font-weight: 800; color: var(--muted); text-transform: uppercase;
    letter-spacing: .5px; margin-bottom: 6px; }
.qf-who { display: flex; align-items: center; gap: 2px; font-size: 12px; color: #44607a; padding: 2px 0; }
.qf-who.is-me .qf-who-n { font-weight: 700; color: var(--ink); }
.qf-who-n { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.qf-who-r { font-size: 9px; text-transform: uppercase; letter-spacing: .4px; color: var(--accent);
    background: var(--accent-soft); border-radius: 3px; padding: 1px 4px; }
.qf-who-empty { font-size: 11px; color: var(--muted); }
@media (max-width: 860px) { .qf-sidecol { width: 100%; } }

/* our own notes on a queue card, under the customer's text */
.qf-ournote { background: #fffdf2; border-left: 3px solid #eab308; border-radius: 0 6px 6px 0;
    padding: 6px 10px; margin-top: 6px; font-size: 12px; color: #44607a; }
.qf-ournote b { color: var(--ink); font-size: 11px; }
.qf-ournote .qf-note { display: inline; margin-left: 6px; font-size: 10px; }
.qf-quicknote { display: flex; gap: 6px; margin-top: 6px; }
.qf-quicknote .form-control { flex: 1; }

/* source chip on queue cards — "Website Quote" plus the ad that paid for it */
.qf-src-base { color: var(--muted); }
.qf-src { display: inline-block; color: #fff; font-size: 9px; font-weight: 800;
    letter-spacing: .5px; padding: 1px 5px; border-radius: 3px; vertical-align: middle; }

/* product blocks on a queue card — one per thing they're asking for.
 * Name/time/phone/email stay in the header; WHAT they want lives here. */
.qf-blocks { display: flex; flex-direction: column; gap: 6px; margin-bottom: 8px; }
.qf-blk { border: 1px solid var(--line); border-left: 3px solid #cbd5e1;
    border-radius: 0 8px 8px 0; padding: 8px 11px; background: #fbfdff; }
.qf-blk-tag { font-size: 9px; font-weight: 800; color: var(--muted);
    text-transform: uppercase; letter-spacing: .6px; margin-bottom: 2px; }
.qf-blk-head { font-size: 14px; font-weight: 700; color: var(--ink); line-height: 1.3; }
.qf-blk-bits { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 5px; }
.qf-blk-air { margin-top: 6px; font-size: 11px; font-weight: 700; color: #1d4ed8; }

/* the cruise — the main event, so it gets the house colour */
.qf-blk-ocean { border-left-color: var(--accent); background: #f7fcfd; }
/* river cruise — same depth as ocean, its own colour */
.qf-blk-river { border-left-color: #0891b2; background: #f5fdff; }
.qf-blk-river .qf-blk-tag { color: #0891b2; }

/* the past-passenger loyalty number, revealed on demand */
.qi-ppid { animation: none; }

/* the blank home page */
.qf-home { max-width: 720px; }
.qf-home-hi { font-size: 24px; font-weight: 400; color: var(--ink); margin-bottom: 2px; }
.qf-home-soon { margin-top: 22px; padding: 16px 18px; border: 1px dashed var(--line);
    border-radius: 10px; color: var(--muted); font-size: 13px; background: var(--card); }
.qf-home-soon b { color: var(--ink); }

/* hotel stays — pre and post are separate bookings */
.qf-blk-hotel { border-left-color: #7c3aed; background: #faf8ff; }
.qf-blk-hotel .qf-blk-tag { color: #7c3aed; }
/* hotel stays on intake — the first form is always there; the second
   only appears when they want both ends of the trip */
.qi-stay-picks { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-bottom: 8px; }
.qi-stay-pick { font-size: 12px; font-weight: 700; color: #7c3aed; background: #faf8ff;
    border: 1px solid #ddd6fe; border-radius: 6px; padding: 5px 12px; margin: 0; cursor: pointer;
    letter-spacing: .5px; }
.qi-stay-pick input { margin-right: 5px; vertical-align: middle; }
.qi-stay { border: 1px solid var(--line); border-radius: 8px;
    padding: 10px 12px; margin-bottom: 8px; background: #fff; }
.qi-stay-head { font-size: 10px; font-weight: 800; color: var(--muted);
    text-transform: uppercase; letter-spacing: .6px; margin-bottom: 6px; }
.qi-stay-head.is-set { color: #7c3aed; }
/* air through the operator — same booking */
.qf-blk-airvia { border-left-color: #1d4ed8; background: #eff6ff; }
.qf-blk-airvia .qf-blk-head { font-size: 13px; color: #1d4ed8; }
/* a standalone flight — someone else's job */
.qf-blk-air { border-left-color: #b45309; background: #fffbeb; }
.qf-blk-air .qf-blk-tag { color: #b45309; }
.qf-blk-air-warn { color: #b45309; }

/* the other products on a quote — flights, hotel, car.
   One row each, and only for products that actually have data. */
.qf-extras { margin-bottom: 10px; }
.qf-ex { display: flex; align-items: center; gap: 7px; flex-wrap: wrap;
    background: #f8fafc; border: 1px solid var(--line); border-left: 3px solid #cbd5e1;
    border-radius: 0 8px 8px 0; padding: 6px 10px; margin-bottom: 4px; font-size: 12px; }
.qf-ex-tag { font-size: 10px; font-weight: 800; color: var(--muted);
    text-transform: uppercase; letter-spacing: .5px; min-width: 104px; }
.qf-ex-plain { border-left-color: var(--line); background: #fbfdff; }

/* air through the operator — same booking, same agent */
.qf-ex-air-via { background: #eff6ff; border-color: #bfdbfe; border-left-color: #1d4ed8; }
.qf-ex-air-via .qf-ex-tag { color: #1d4ed8; }

/* a standalone flight — someone else's job, so it stands out */
.qf-ex-air { background: #fffbeb; border-color: #fcd34d; border-left-color: #b45309; }
.qf-ex-air .qf-ex-tag { color: #b45309; }
.qf-route { font-size: 14px; letter-spacing: 1px; color: var(--ink); }
.qf-needs-air { font-size: 11px; font-weight: 700; color: #b45309;
    background: #fde68a; border-radius: 4px; padding: 2px 7px; }
.qf-warn-flip { font-size: 11px; font-weight: 700; color: #fff;
    background: var(--bad); border-radius: 4px; padding: 2px 7px; }

/* where the click came from — ad source on the quote modal */
.qf-mkt { display: flex; align-items: center; gap: 6px; flex-wrap: wrap;
    background: #eff6ff; border: 1px solid #bfdbfe; border-radius: 8px;
    padding: 6px 10px; margin-bottom: 10px; font-size: 12px; }
.qf-mkt-h { font-size: 10px; font-weight: 800; color: #1d4ed8; text-transform: uppercase; letter-spacing: .5px; }

/* the full website submission, collapsed */
.qf-fulldata { border: 1px solid var(--line); border-radius: 8px; padding: 8px 10px; margin-bottom: 10px; background: #fbfdff; }
.qf-fulldata > summary { cursor: pointer; font-size: 11px; font-weight: 800; color: #44607a;
    text-transform: uppercase; letter-spacing: .5px; }
.qf-fulldata table { margin: 8px 0 0; font-size: 12px; }

/* intake product tabs — the tick shows which products have data */
.qf-ptabs > li > a { font-size: 12px; padding: 6px 10px; color: #44607a; }
.qf-ptabs > li.has-data > a { font-weight: 700; }
.qf-ptabs > li.has-data > a, .qf-ptabs > li.has-data > a:hover { color: var(--good); }
.qi-tick { color: var(--good); font-weight: 700; }
.qi-pane { border: 1px solid var(--line); border-top: 0; border-radius: 0 0 8px 8px;
    padding: 12px 14px; background: #fbfdff; }

/* "include air through the operator" — a decision, not a text field, so
   it gets its own band rather than sitting in the grid */
.qi-air-opt { display: block; margin: 10px 0 0; padding: 7px 10px; font-weight: 600; font-size: 12px;
    color: #1d4ed8; background: #eff6ff; border: 1px solid #bfdbfe; border-radius: 6px; cursor: pointer; }
.qi-air-opt input { margin-right: 6px; vertical-align: middle; }
.qi-iata { text-transform: uppercase; letter-spacing: 2px; font-weight: 700; }

/* how much a score would move if you saved it */
.qf-delta { font-size: 10px; font-weight: 700; padding: 0 3px; border-radius: 3px; margin-left: 3px; }
.qf-delta.up   { color: var(--good); background: #dcfce7; }
.qf-delta.down { color: var(--bad);  background: #fee2e2; }

/* calibrate table — the two working-out columns sit back from the rest */
.qf-cal .qf-sub { color: var(--muted); font-size: 11px; background: #fbfdff; }
.qf-cal thead th { white-space: nowrap; }
.qf-cal tbody td:last-child { font-weight: 700; }

/* per-line capability chips on the performance table */
.qf-caps { display: flex; flex-wrap: wrap; gap: 4px; }
.qf-cap { font-size: 11px; background: #eef2f6; border-radius: 4px; padding: 1px 4px 1px 6px;
    color: #44607a; white-space: nowrap; display: inline-flex; align-items: center; gap: 4px; }
.qf-cap b { color: #fff; border-radius: 3px; padding: 0 4px; font-size: 10px; }
.qf-cap b.label-success  { background: var(--good); }
.qf-cap b.label-fit-mid  { background: #ca8a04; }
.qf-cap b.label-fit-low  { background: #ea580c; }
.qf-cap b.label-danger   { background: var(--bad); }

/* vacation editor */
.qf-vac-add { display: flex; gap: 8px; align-items: flex-end; flex-wrap: wrap; }
.qf-vac-add > div { flex: 1 1 140px; }
.qf-vac-add > div:last-child { flex: 0 0 auto; }
.qf-vac-list { max-height: 280px; overflow-y: auto; }
.qf-vac-run { border: 1px solid var(--line); border-radius: 8px; padding: 8px 10px; margin-bottom: 6px; background: #fffdf2; }
.qf-vac-chip { font-size: 10px; border: 1px solid #e3d9a8; background: #fff; border-radius: 4px;
    padding: 1px 5px; margin: 3px 3px 0 0; color: #8a6d1f; cursor: pointer; }
.qf-vac-chip:hover { background: #fee2e2; border-color: #fca5a5; color: var(--bad); }

/* quote timeline (modal + anywhere qf_render_timeline is called) */
.qf-timeline { max-height: 260px; overflow-y: auto; border: 1px solid var(--line);
    border-radius: 8px; padding: 4px 0; background: #fbfdff; }
.qf-tl-row { display: flex; gap: 10px; padding: 6px 11px; border-bottom: 1px solid #eef3f8; }
.qf-tl-row:last-child { border-bottom: 0; }
.qf-tl-row.is-comment { background: #fffdf2; }
.qf-tl-when { flex: 0 0 84px; font-size: 10px; color: var(--muted); line-height: 1.7; white-space: nowrap; }
.qf-tl-body { flex: 1; min-width: 0; font-size: 12px; }
/* event tag: fixed width so every row's text starts on the same line */
.qf-tl-tag { display: inline-block; min-width: 88px; text-align: center;
    font-size: 10px; font-weight: 700; letter-spacing: .5px; padding: 3px 6px; }
.qf-tl-text { color: var(--ink); margin-left: 4px; word-wrap: break-word; }
.qf-tl-by { font-size: 10px; color: var(--muted); margin-top: 1px; }

/* "assign anyway" checkbox on at-capacity agents */
.qf-force { font-size: 10px; color: var(--bad); font-weight: 700; margin: 0;
    white-space: nowrap; cursor: pointer; }
.qf-force input { margin: 0 2px 0 0; vertical-align: middle; }

/* schedule matrix */
.qf-slot { width: 13px; height: 16px; border: 1px solid #e3ebf3; background: #fff; cursor: pointer; }
.qf-slot.on { background: var(--accent); border-color: var(--accent); }
#qf-sched { user-select: none; border-collapse: collapse; }

/* label (badge) accent variant used for "verified"/past-client */
.label-info { background: var(--accent); }

/* fit-score bands — BS3 only ships one amber (label-warning), and we need
 * yellow and orange to read as different tiers, so both are defined here.
 * label-success / label-danger come from Bootstrap. See qf_fit_class(). */
.label-fit-mid { background: #ca8a04; }   /* 65-89  yellow */
.label-fit-low { background: #ea580c; }   /* 45-64  orange */
.qf-fit { font-size: 11px; font-weight: 700; letter-spacing: .2px; }

/* login */
.qf-login { display: flex; align-items: center; justify-content: center; min-height: 100vh; background: #10222f; }
.qf-login-card { background: #fff; border-radius: 12px; padding: 30px 34px; width: 320px; }
.qf-login-card h1 { margin: 0 0 16px; font-size: 20px; }

/* layout helpers still used alongside the BS3 grid */
.qf-layout { display: flex; gap: 16px; align-items: flex-start; }
.qf-side { width: 190px; flex-shrink: 0; margin-bottom: 16px; }
.qf-side .list-group-item { font-weight: 600; color: #44607a; }
.qf-side .list-group-item.active,
.qf-side .list-group-item.active:hover { background: #10222f; border-color: #10222f; color: #fff; }
.qf-main { flex: 1; min-width: 0; }
.qf-grid { display: grid; gap: 16px; }
.qf-grid.c2 { grid-template-columns: 1fr 1fr; }
.qf-grid.c3 { grid-template-columns: 1fr 1fr 1fr; }
@media (max-width: 860px) { .qf-layout { flex-direction: column; } .qf-side { width: 100%; } .qf-grid.c2, .qf-grid.c3 { grid-template-columns: 1fr; } }
.qf-lb { display: block; font-size: 10px; color: var(--muted); text-transform: uppercase; letter-spacing: .5px; margin: 0 0 3px; }
/* panels used as single-div cards keep their inner h2 style */
.panel h2 { font-size: 13px; margin: 0 0 10px; text-transform: uppercase; letter-spacing: .6px; color: #44607a; font-weight: 700; }
.panel h2 small { text-transform: none; letter-spacing: 0; font-weight: 400; color: var(--muted); font-size: 85%; }

/* check-in — who's taking quotes this week */
.qf-checkin-bar { display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
    background: var(--card); border: 1px solid var(--line); border-radius: 8px;
    padding: 8px 12px; margin-bottom: 10px; font-size: 13px; }
.qf-checkin { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 4px; }
.qf-ci { display: flex; align-items: center; gap: 8px; margin: 0; padding: 7px 10px;
    border: 1px solid var(--line); border-radius: 8px; background: var(--card);
    font-weight: 400; cursor: pointer; }
.qf-ci:hover { border-color: var(--accent); }
.qf-ci input[type=checkbox] { margin: 0; width: 16px; height: 16px; cursor: pointer; }
.qf-ci-name { font-weight: 700; font-size: 13px; color: var(--ink); }
.qf-ci-meta { margin-left: auto; display: flex; align-items: center; gap: 4px; }
/* unticked rows fade back so the list reads at a glance */
.qf-ci.is-off { background: #f8fafc; border-style: dashed; }
.qf-ci.is-off .qf-ci-name { color: var(--muted); text-decoration: line-through; }

/* ---- viewing as someone else -------------------------------------
 * Loud on purpose. An admin who forgets which of two people they are
 * is the whole failure mode this feature has, so the bar is amber,
 * full width, and pinned above the page rather than tucked into a
 * corner of the nav.
 */
.qf-maskbar {
    display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
    padding: 8px 16px;
    background: #fef3c7; border-bottom: 2px solid #f59e0b; color: #7c4a03;
    font-size: 13px;
}
.qf-maskbar-eye { font-size: 15px; line-height: 1; }
.qf-maskbar b { color: #7c2d12; }
.qf-maskbar-sub { color: #92700a; }
.qf-maskbar .btn { margin-left: auto; }

/* Everything on a masked page reads as inert: slightly faded, and any
   control that's been disabled shows the not-allowed cursor. */
body.qf-masked .qf-wrap { opacity: .93; }
body.qf-masked .qf-wrap button[disabled],
body.qf-masked .qf-wrap input[disabled],
body.qf-masked .qf-wrap select[disabled],
body.qf-masked .qf-wrap textarea[disabled] { cursor: not-allowed; }

/* ---- demo-mode notice — sits above everything, every page, until this
 *      is a real deployment and Brian pulls it ---- */
.qf-demobar {
    padding: 6px 16px;
    background: #fef3c7; border-bottom: 2px solid #f59e0b; color: #7c4a03;
    font-size: 12px; font-weight: 700; letter-spacing: .04em; text-align: center;
    text-transform: uppercase;
}

/* ---- still on the shared starter password ---- */
.qf-passbar {
    padding: 8px 16px;
    background: #eff6ff; border-bottom: 1px solid #bfdbfe; color: #1e40af;
    font-size: 13px;
}
.qf-passbar a { font-weight: 600; text-decoration: underline; }

/* ---- bulk login creation, on Admin ---- */
.qf-bulklogin {
    padding: 12px 14px; margin-bottom: 14px;
    background: #f8fafc; border: 1px solid #e2e8f0; border-radius: 4px;
}
.qf-bulklogin code { font-size: 12px; }

/* Quiet until you look for it — the roster is for reading, not for
   impersonating, so this shouldn't compete with the agent's name. */
.qf-viewas-link {
    margin-left: 6px; font-size: 11px; color: var(--muted);
    opacity: 0; transition: opacity .12s;
}
tr:hover .qf-viewas-link { opacity: 1; }
.qf-viewas-link:hover { color: var(--accent); }

/* The verification code box — big and spaced out, because six digits
   typed from a phone screen shouldn't need squinting. */
.qf-code {
    font: 700 24px/1.2 'Courier New', Courier, monospace;
    letter-spacing: 8px; text-align: center; padding: 10px;
}
.qf-code::placeholder { color: #cbd5e1; letter-spacing: 8px; }

/* ---- "Assigning to X…" — what replaces the Best-Fit list ---- */
.qf-assigning {
    display: flex; align-items: center; gap: 12px;
    padding: 18px 16px; min-height: 96px;
    border: 1px solid var(--line); border-radius: 8px;
    background: #f8fafc; color: #1c2b3a; font-size: 13px;
}
.qf-assigning-spin {
    width: 18px; height: 18px; flex: none;
    border: 2px solid #cbd5e1; border-top-color: var(--accent);
    border-radius: 50%; animation: qf-spin .7s linear infinite;
}
@keyframes qf-spin { to { transform: rotate(360deg); } }

/* ---- "Assigning to X…" — what replaces the Best-Fit list ---- */
.qf-assigning {
    display: flex; align-items: center; gap: 12px;
    padding: 18px 16px; min-height: 96px;
    border: 1px solid var(--line); border-radius: 8px;
    background: #f8fafc; color: #1c2b3a; font-size: 13px;
}
.qf-assigning-spin {
    width: 18px; height: 18px; flex: none;
    border: 2px solid #cbd5e1; border-top-color: var(--accent);
    border-radius: 50%; animation: qf-spin .7s linear infinite;
}
@keyframes qf-spin { to { transform: rotate(360deg); } }

/* ---- the conveyor belt --------------------------------------------
 * A card that's been assigned collapses to nothing over a quarter of a
 * second. Short enough not to be a wait, long enough that the eye
 * follows the list moving up rather than seeing it jump.
 */
.qf-qcard { transition: opacity .16s ease; }
.qf-card-going { opacity: .45; pointer-events: none; }
.qf-card-lift {
    overflow: hidden;
    transition: height .26s cubic-bezier(.3,0,.2,1),
                opacity .2s ease,
                margin .26s cubic-bezier(.3,0,.2,1),
                padding .26s cubic-bezier(.3,0,.2,1);
    opacity: 0; margin-top: 0 !important; margin-bottom: 0 !important;
    padding-top: 0 !important; padding-bottom: 0 !important;
}

/* ---- the floating ASSIGNED note ---- */
#qf-toasts {
    position: fixed; left: 50%; bottom: 22px; transform: translateX(-50%);
    z-index: 2000; display: flex; flex-direction: column; gap: 6px;
    align-items: center; pointer-events: none;
}
.qf-toast {
    display: flex; align-items: baseline; gap: 10px;
    padding: 9px 16px; border-radius: 999px;
    background: #0f2b1c; color: #d7f5e4;
    box-shadow: 0 6px 20px rgba(0,0,0,.28);
    font-size: 13px; white-space: nowrap;
    animation: qf-toast-in .18s cubic-bezier(.2,1.3,.5,1);
    transition: opacity .3s ease, transform .3s ease;
}
.qf-toast b {
    font-size: 11px; font-weight: 800; letter-spacing: 1.2px;
    text-transform: uppercase; color: #4ade80;
}
.qf-toast.is-bad { background: #3b0f13; color: #fecdd3; }
.qf-toast.is-bad b { color: #fb7185; }
.qf-toast.is-going { opacity: 0; transform: translateY(8px); }
@keyframes qf-toast-in {
    from { opacity: 0; transform: translateY(12px); }
    to   { opacity: 1; transform: translateY(0); }
}

/* Green marks the current top pick. It's a class rather than an inline
   colour because the list re-ranks itself as agents pick up work. */
.qf-bf-go { padding: 4px 12px; background: var(--accent); }
.qf-bf-go.is-top { background: var(--good); }

/* ---- who can open what, on Admin ---- */
.qf-pagegrid { display: grid; grid-template-columns: 1fr 1fr; gap: 1px 10px; }
.qf-pagegrid label {
    font-weight: 400; font-size: 11px; margin: 0;
    display: flex; align-items: center; gap: 4px; white-space: nowrap;
}
.qf-pagegrid.is-locked { opacity: .55; }

/* ---- Customer Service hand-off ---- */
.qf-cs-form {
    background: #fef2f2; border: 1px solid #fecaca; border-radius: 8px;
    padding: 9px 10px; margin-bottom: 6px;
}
.qf-cs-note { font-size: 11px; color: #991b1b; margin-bottom: 6px; line-height: 1.45; }

/* A special agent's row, once searched up — visibly not one of the pool. */
.qf-bf-row[data-special] { background: #f5f3ff; }

/* ---- "already in the works" — who has it, on the intake screen ---- */
.qi-owner {
    display: flex; align-items: center; gap: 10px;
    background: #fff; border: 1px solid #fecaca; border-radius: 6px;
    padding: 7px 10px; margin-bottom: 5px;
}
.qi-owner img,
.qi-owner .qi-owner-blank {
    width: 34px; height: 34px; border-radius: 50%; flex: none;
    object-fit: cover; background: #e2e8f0;
}
/* Whether you can put the caller through right now, at a glance. */
.qi-w {
    font-size: 10px; font-weight: 700; text-transform: uppercase;
    letter-spacing: .4px; padding: 1px 6px; border-radius: 999px;
}
.qi-w-yes { background: #dcfce7; color: #15803d; }
.qi-w-mid { background: #fef9c3; color: #a16207; }
.qi-w-no  { background: #e2e8f0; color: #64748b; }

/* A queue card whose agents haven't been ranked yet. */
.qf-lazy-box {
    display: flex; flex-direction: column; align-items: center; justify-content: center;
    min-height: 120px; padding: 18px;
    border: 1px dashed var(--line); border-radius: 8px; background: #fbfdff;
    text-align: center;
}

/* ---- "who is this person, then?" ----
 * The PAST CLIENT badge is what makes anyone ask, so the badge is the
 * way through to the answer rather than a dead label with the real link
 * in grey text somewhere below it.
 */
.qf-badge-link { text-decoration: none; cursor: pointer; }
.qf-badge-link:hover, .qf-badge-link:focus {
    text-decoration: none; color: #fff; filter: brightness(1.12);
}

.qf-pastbox {
    display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
    margin-top: 8px; padding: 8px 11px;
    background: #f0f9ff; border: 1px solid #bae6fd; border-radius: 6px;
    font-size: 12px;
}
.qf-pastbox .qf-note { margin: 0; }

/* ================================================== shopping a quote ==
 * The quote stays pinned at the top while the agent shops underneath, so
 * they never lose the thread of what the customer actually asked for.
 */
.qf-shop-head { border-left: 4px solid var(--accent); }
.qf-shop-asked { display: flex; flex-wrap: wrap; gap: 5px; }
.qf-shop-filters { align-items: flex-start; }
.qf-shop-filters select[multiple] { min-width: 190px; }

/* One card per itinerary, its dates listed underneath. */
.qf-sail { padding: 0 !important; overflow: hidden; }
.qf-sail-head {
    display: flex; gap: 14px; flex-wrap: wrap; align-items: flex-start;
    padding: 12px 14px; border-bottom: 1px solid var(--line);
}
.qf-sail-price {
    text-align: right; padding: 8px 14px; border-radius: 8px;
    background: #10222f; color: #fff; min-width: 130px;
}
.qf-sail-price .n { font-size: 26px; font-weight: 800; line-height: 1.1; }
.qf-sail-price .l { font-size: 10px; text-transform: uppercase; letter-spacing: .6px; color: #b9cdda; }

.qf-sail-dates { margin: 0 !important; }
.qf-sail-dates th { font-size: 11px; text-transform: uppercase; letter-spacing: .4px; }
.qf-sail-dates td, .qf-sail-dates th { padding: 6px 10px !important; }
.qf-sail-on { background: #ecfdf5 !important; }
.qf-sail-tick { cursor: pointer; }

/* The running shortlist. Sticky, because ticking a few while the customer
   talks is the entire interaction and the count is what's said out loud. */
.qf-shop-bar {
    position: sticky; bottom: 0; z-index: 400;
    display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
    padding: 10px 16px; margin-top: 10px;
    background: #fff; border: 1px solid var(--line); border-radius: 8px;
    box-shadow: 0 -4px 16px rgba(0,0,0,.10); font-size: 13px;
}
.qf-shop-bar.is-live { border-color: var(--good); background: #f0fdf4; }

.qf-shortlist {
    border: 1px solid #bae6fd; background: #f0f9ff;
    border-radius: 8px; padding: 8px 10px; margin-bottom: 12px;
}
.qf-shortlist table { background: transparent; }

/* ==================================================== the multi picker ==
 * Type to search, click to add a chip. Used by intake and by shop, so a
 * customer saying "Royal Caribbean or Carnival" comes out the same on
 * both.
 */
.qf-pick { position: relative; }
.qf-pick-box {
    border: 1px solid #ccc; border-radius: 4px; background: #fff;
    padding: 3px 4px; min-height: 32px;
}
.qf-pick-box:focus-within { border-color: var(--accent); box-shadow: 0 0 0 2px rgba(28,61,90,.10); }
.qf-pick-chips { display: flex; flex-wrap: wrap; gap: 3px; }
.qf-pick-chip {
    display: inline-flex; align-items: center; gap: 5px;
    background: #e8f0f7; color: #1c3d5a; border: 1px solid #c7dcec;
    border-radius: 12px; padding: 1px 4px 1px 9px; font-size: 12px; white-space: nowrap;
}
.qf-pick-x { cursor: pointer; color: #6b8fae; font-weight: 700; padding: 0 4px; }
.qf-pick-x:hover { color: var(--bad); }
.qf-pick-in {
    border: 0 !important; box-shadow: none !important; padding: 2px 4px !important;
    height: 24px !important; font-size: 12px;
}
.qf-pick-menu {
    display: none; position: absolute; z-index: 900; left: 0; right: 0; top: 100%;
    background: #fff; border: 1px solid var(--line); border-radius: 6px;
    box-shadow: 0 6px 18px rgba(0,0,0,.14); max-height: 230px; overflow-y: auto;
}
.qf-pick-menu.is-open { display: block; }
.qf-pick-opt { padding: 5px 10px; font-size: 12px; cursor: pointer; }
.qf-pick-opt:hover, .qf-pick-opt:first-child { background: #f1f6fa; }
.qf-pick-opt:hover { background: #e2edf5; }
.qf-pick-none { padding: 7px 10px; font-size: 12px; color: var(--muted); }

/* A chip for something we don't stock — kept because the customer said
   it, marked because we can't shop it. */
.qf-pick-chip.is-free { background: #fef3c7; border-color: #fcd34d; color: #92400e; }
.qf-pick-chip.is-free .qf-pick-x { color: #b45309; }
.qf-pick-opt.is-free { border-top: 1px solid var(--line); color: #92400e; }

/* ---- what they actually asked for ----
 * The header rows hold one value each because the rest of the app reads
 * them that way. This is where the rest of the answer lives, and it only
 * appears when there IS more than one.
 */
.qf-wish {
    margin-top: 8px; padding: 8px 10px;
    background: #fbfdff; border: 1px solid var(--line); border-radius: 8px;
}
.qf-wish-h {
    font-size: 10px; font-weight: 800; text-transform: uppercase;
    letter-spacing: .6px; color: var(--muted); margin-bottom: 5px;
}
.qf-wish-row { display: flex; flex-wrap: wrap; gap: 4px; align-items: baseline; margin-bottom: 3px; }
.qf-wish-lab { font-size: 11px; color: var(--muted); min-width: 92px; }
.qf-chip.is-free { background: #fef3c7; border-color: #fcd34d; color: #92400e; }

/* The half of the quote editor that destroys things. Coloured so it
   can't be mistaken for the half that just corrects them. */
.qf-danger { border-color: #fecaca !important; background: #fffbfb; }
.qf-danger h2 { color: #991b1b; }

/* A shopped quote's block. Green rather than the ocean blue, because
   this is what an agent FOUND, not what the customer asked for. */
.qf-blk-shop { border-left-color: var(--good); background: #f4fdf8; }
.qf-blk-shop .qf-blk-tag { color: #15803d; }
.qf-chip-price { background: #10222f; color: #fff; border-color: #10222f; font-weight: 700; }
.qf-chip-price .qf-note { color: #b9cdda; }

/* Straight through to the sailing on vacation.com. Small, because these
   are for checking something — not the point of the card. */
.qf-slink {
    display: inline-block; font-size: 11px; font-weight: 600;
    padding: 1px 7px; margin-right: 4px;
    border: 1px solid #cbd5e1; border-radius: 999px;
    color: #1c3d5a; background: #fff; text-decoration: none;
}
.qf-slink:hover { border-color: var(--accent); color: var(--accent); text-decoration: none; }

/* The app's own bookkeeping. Kept on the record, shown to admins, and
   quietened right down so the entries people actually wrote still read
   as the main thing. */
.qf-tl-row.is-system { opacity: .62; }
.qf-tl-row.is-system .qf-tl-text { color: var(--muted); font-size: 12px; }
.qf-timeline-wrap.hide-system .qf-tl-row.is-system { display: none; }

/* ============================================ who's holding what =====
 * One line per agent, collapsed. A manager scanning for trouble reads
 * the right-hand badges; clicking a name opens that person's plate.
 * Nothing is fetched on expand — the rows are already on the page.
 * The actual table markup + styling lives inline in queue.php now (see
 * qf-agtable there) — this old flex-row version is gone. Left deleted on
 * purpose: its .qf-agrow-head/.qf-agrow-body class names collided with
 * the new table's row classes and were silently forcing display:flex /
 * display:none onto it (2026-09 — that's what was making the Agents tab
 * look broken/misaligned and its click-to-expand not open).
 */

/* Explanatory text. Administrators see it; for everyone else the screen
   is the screen. Anything a non-admin NEEDS must never be a hint. */
body.qf-nohints .qf-hint { display: none !important; }
.qf-hint { font-style: italic; }

/* The quote being kept in a duplicate group — the others are parked
   against it, so it should read as the anchor rather than one of a set. */
.qf-dupe-keep { background: #f0fdf4 !important; }

/* ---------------------------------------------------------- call log --
 * Thirteen columns is a lot for one screen, so the table scrolls
 * sideways rather than wrapping every cell into three lines. The point
 * of this page is that it reads like the spreadsheet it replaces. */
.qf-calllog { font-size: 12px; white-space: nowrap; }
.qf-calllog td, .qf-calllog th { vertical-align: middle !important; }
.qf-calllog .nw { white-space: nowrap; }
/* Notes are free text and occasionally a paragraph. Cap the column and
 * let the full text arrive on hover rather than letting one long note
 * set the width of the whole table. */
.qf-calllog .qf-cl-notes { max-width: 260px; overflow: hidden; text-overflow: ellipsis; }
/* "Dupe" in the agent column is the team's own marker for a repeat row.
 * Kept visible — it's part of how they read the sheet — but muted, so
 * it doesn't compete with real entries. */
.qf-calllog tr.qf-cl-dupe td { opacity: .55; }

/* simple_call_log.php — the same twelve-column shape as the team's own
 * call-log spreadsheet (green header band and all), but reading straight
 * off QuoteDash's quotes for one day rather than the imported call
 * export. Reuses .qf-calllog's row styling; this just adds the header
 * band and a couple of always-blank columns so it visually matches the
 * sheet it's standing in for. */
.qf-simplecl.qf-calllog > thead > tr > th, .qf-simplecl > thead > tr > th {
    background: var(--good);
    color: #fff;
    border-color: var(--good);
}

/* ------------------------------------------- whiteboard / quote log --
 * Both rebuild a spreadsheet, so they borrow its habits: tight rows,
 * numbers hard right, colour used to group columns rather than to
 * decorate. The colours match the shading on the sheets they replace so
 * a manager's eye lands in the same place.
 */
.qf-board { font-size: 13px; }
.qf-board td, .qf-board th { padding: 4px 8px !important; vertical-align: middle !important; }
.qf-board .r, .qf-qlog .r { text-align: right; }
.qf-board .qf-b-agent { font-weight: 700; }
.qf-board .qf-b-status { width: 78px; font-size: 11px; }
/* Older periods sit behind this one, so they're greyed back. */
.qf-board .qf-b-old    { background: #f4f6f8; color: var(--muted); }
.qf-board .qf-b-live   { background: #e8f1fb; }   /* blue on the sheet */
.qf-board .qf-b-new    { background: #eeeeee; }   /* grey on the sheet */
.qf-board .qf-b-ref,
.qf-board .qf-b-compete{ background: #fffbe6; }   /* yellow on the sheet */
.qf-board .qf-b-total  { background: #eef7ee; font-size: 14px; }
/* A quiet week is still a row — just not one that should shout. */
.qf-board tr.qf-b-quiet td { color: #9aa5b1; }
.qf-board tr.qf-b-quiet td.qf-b-agent { font-weight: 400; }
/* A name the call log has and the roster doesn't. */
.qf-b-unknown { display: inline-block; width: 14px; height: 14px; line-height: 14px;
    text-align: center; border-radius: 50%; background: #f0ad4e; color: #fff;
    font-size: 10px; font-weight: 700; cursor: help; }

.qf-qlog { font-size: 11px; }
.qf-qlog td, .qf-qlog th { padding: 2px 5px !important; vertical-align: middle !important; }
.qf-qlog .qf-q-agent { font-weight: 700; white-space: nowrap; position: sticky; left: 0;
    background: var(--card); z-index: 2; box-shadow: 1px 0 0 var(--line); }
.qf-qlog .qf-q-daytop { text-align: center; border-left: 2px solid var(--line);
    font-size: 11px; white-space: nowrap; }
.qf-qlog .qf-q-tottop { text-align: center; border-left: 3px solid #6b8f6b; background: #eef7ee; }
.qf-qlog .qf-q-leads   { background: #eef4ee; }
.qf-qlog .qf-q-singles { background: #f7f7f7; }
.qf-qlog .qf-q-live    { background: #fffbe6; }   /* yellow on the sheet */
.qf-qlog .qf-q-direct  { background: #fdf0dd; }   /* orange on the sheet */
.qf-qlog .qf-q-tot     { background: #eef7ee; font-size: 12px; }
/* Saturday and Sunday are still counted — the desk works them — but
 * they shouldn't read like a weekday at a glance. */
.qf-qlog .qf-q-wknd { opacity: .75; }
/* An empty cell is the common case; zeros everywhere would be noise, so
 * blanks are used and only the numbers draw the eye. */
.qf-qlog td.r:empty { background-image: none; }

/* ------------------------------------------------------- send-backs --
 * The fold-away on an agent's own quote. Sending work back should be
 * available without sitting next to "Mark complete" competing for the
 * same click, so it's a summary you have to open on purpose.
 */
.qf-sendback { margin-top: 14px; border-top: 1px solid var(--line); padding-top: 10px; }
.qf-sendback > summary { cursor: pointer; font-size: 12px; color: var(--muted); outline: none; }
.qf-sendback > summary:hover { color: var(--fg); }
.qf-sendback[open] > summary { font-weight: 700; color: var(--fg); margin-bottom: 4px; }
/* On the report, a high refusal rate on enough quotes to mean something. */
.qf-bo-hi  td { background: #fdecec; }
.qf-bo-mid td { background: #fff8e6; }

/* ------------------------------------------------------ data audit --
 * A booking, and underneath it the calls that came before it. The point
 * of the page is scanning down a long list and seeing which bookings
 * have nothing under them, so the state is carried by a colour bar down
 * the left rather than something you have to read.
 */
.qf-au-day { font-size: 12px; font-weight: 800; text-transform: uppercase; letter-spacing: .5px;
    color: var(--muted); margin: 18px 0 6px; padding-bottom: 3px; border-bottom: 1px solid var(--line); }
.qf-au { border: 1px solid var(--line); border-left: 4px solid var(--line); border-radius: 6px;
    padding: 8px 12px; margin-bottom: 6px; background: var(--card); }
/* The class name IS the verdict from data_audit.php. If one is renamed
 * there and not here the row silently loses its colour, which is how the
 * "call logged" rows went grey. */
.qf-au.call      { border-left-color: #5cb85c; }
/* Nothing to match on. A different thing from "no call was logged", and
 * it must not read like a failure — muted, not red. */
.qf-au.nocontact { border-left-color: #ccc; opacity: .72; }
/* Several cabins on one sailing by one agent. Blue, not red — it is one
 * conversation that produced several bookings, and red would say
 * something untrue about the person who sold it. */
.qf-au.group     { border-left-color: #2e6da4; background: #f4f8fc; }
/* A customer who has booked with this agent many times. They email; they
 * don't ring. Not a documentation failure. */
.qf-au.repeat    { border-left-color: #6f42c1; background: #f9f7fd; }
/* Known to us, but not to this agent, and no call. Odd, not damning. */
.qf-au.known     { border-left-color: #e0a800; background: #fffdf5; }
/* Nobody has ever booked this person and there is no call. THE gap. */
.qf-au.new       { border-left-color: #d9534f; background: #fffafa; }
/* Sits on the contact line, so it has to read as part of that sentence
 * rather than as another badge competing with the verdict. */
.qf-au-repeat { color: #6f42c1; font-weight: 700; cursor: help; }
.qf-au-repeat.strong { background: #efe9fb; border-radius: 3px; padding: 0 5px; }
.qf-lb-repeat { background: #6f42c1; }
.qf-lb-known  { background: #e0a800; }
.qf-au-tag a.label { text-decoration: none; }
.qf-au-tag a.label:hover { filter: brightness(1.15); }
.qf-au-head { display: flex; justify-content: space-between; align-items: baseline; gap: 10px; }
.qf-au-who b { font-size: 14px; }
.qf-au-agent { font-size: 12px; color: var(--muted); margin-left: 8px; }
/* Said on every booking with no call behind it, whatever the reason the
 * left-hand colour gives. The reasons explain the gap; they don't mean
 * the intake got done. */
.qf-au-nolead { font-size: 11px; font-weight: 800; color: #d9534f;
    letter-spacing: .3px; margin-left: 6px; cursor: help; }
.qf-au-meta { font-size: 12px; color: var(--muted); margin-top: 2px; }
.qf-au-meta span:not(:last-child)::after { content: " · "; }
.qf-au-res { font-family: ui-monospace, Menlo, Consolas, monospace; font-size: 11px; }
.qf-au-contact { font-size: 11px; color: var(--muted); margin-top: 2px; }
.qf-au-calls { margin-top: 6px; padding-left: 10px; border-left: 2px dotted var(--line); }
.qf-au-call { font-size: 12px; padding: 2px 0; display: flex; gap: 8px; flex-wrap: wrap; align-items: baseline; }
.qf-au-gap { font-weight: 700; min-width: 72px; color: #2e5470; }
.qf-au-cdate { color: var(--muted); min-width: 46px; }
.qf-au-cagent { font-weight: 700; min-width: 90px; }
/* The call was taken by somebody other than the agent on the booking.
 * That's not an error — it's exactly what an audit is looking for. */
.qf-au-diff { color: #b8860b; font-weight: 800; }
.qf-au-cbits { color: var(--muted); }
.qf-au-cnote { color: var(--muted); font-style: italic; flex-basis: 100%; padding-left: 80px; }

/* The quote search sits above the buckets, because "where is that quote"
 * is a question you arrive with, not one you drill down into. */
.qf-qsearch { margin-bottom: 10px; }
.qf-qsearch label { display: block; margin-bottom: 4px; }

/* ---------------------------------------------------- agent home ----
 * The wide "you have N/M quotes" bar and the last-28-days cards. The bar
 * is the thing an agent glances at; the cards are the month behind it. */
.qf-hplate { display: block; background: var(--card); border: 1px solid var(--line);
    border-radius: 12px; padding: 16px 20px; margin: 6px 0 14px; color: inherit; }
.qf-hplate:hover { border-color: #b8c6d4; }
.qf-hplate-top { display: flex; align-items: baseline; gap: 14px; flex-wrap: wrap; }
.qf-hplate-big { font-size: 40px; font-weight: 800; line-height: 1; color: var(--fg); }
.qf-hplate-of { font-size: 26px; color: var(--muted); font-weight: 700; }
.qf-hplate-label { font-size: 15px; color: var(--muted); }
.qf-hbar { height: 10px; border-radius: 6px; background: #e7edf2; margin-top: 12px; overflow: hidden; }
.qf-hbar-fill { height: 100%; border-radius: 6px; transition: width .3s; }
.qf-hcards { display: flex; gap: 12px; flex-wrap: wrap; }
.qf-hcard { flex: 1 1 150px; background: var(--card); border: 1px solid var(--line);
    border-radius: 10px; padding: 14px 16px; }
.qf-hcard-n { font-size: 30px; font-weight: 800; line-height: 1; color: var(--fg); }
.qf-hcard-l { font-size: 12px; color: var(--muted); margin-top: 6px; line-height: 1.35; }
.qf-hcard-l span { font-size: 11px; opacity: .8; }
