/* ── Phase 1: consolidated multi-channel console layout ───────────────────────
   Extends base.css / components.css (light theme, same tokens). Reuses existing
   components (.btn, .badge-*, .summary-bar, .slot-pill, .modal, .toast). Only the
   new topbar/sidebar/main/channel-switcher pieces live here. */

#app { max-width: 1240px; }               /* widen from 760 for sidebar + main */

/* ── topbar ─────────────────────────────────────────────────────────────────── */
.topbar-left { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.brand { display: flex; align-items: center; gap: 8px; font-weight: 600; font-size: 15px; }
.brand .brand-badge { width: 22px; height: 22px; border-radius: 6px; background: var(--blue); display: grid; place-items: center; color: #fff; font-size: 13px; }
.dataio { display: flex; align-items: center; gap: 6px; }
.upload-btn { display: inline-flex; align-items: center; gap: 6px; padding: 6px 12px; border: 1px solid var(--blue); border-radius: var(--radius); background: var(--blue-bg); color: var(--blue); font-size: 13px; font-weight: 600; cursor: pointer; }
.upload-btn:hover { background: #e3edfb; }
.tbtn { border: 1px solid var(--border); background: var(--surface); color: var(--muted); border-radius: var(--radius); padding: 6px 10px; font-size: 13px; cursor: pointer; }
.tbtn:hover { background: var(--bg); }
.tbtn.active { color: var(--text); border-color: var(--text); }

/* ── shell: sidebar + main ──────────────────────────────────────────────────── */
.shell { display: grid; grid-template-columns: 280px 1fr; gap: 16px; align-items: start; padding: 14px 16px; }
@media (max-width: 820px) { .shell { grid-template-columns: 1fr; } }
.main { display: flex; flex-direction: column; gap: 12px; min-width: 0; }

/* ── sidebar ────────────────────────────────────────────────────────────────── */
/* Scrolling rule for the left column: the ONLY scroll container is `.side` itself
   (the vertical stack of panels). Nothing inside a panel may clip or scroll —
   every control is laid out to fit 280px, so there is never hidden content in a box.
   `scrollbar-gutter: stable` reserves the scrollbar track so panels don't reflow when
   it appears, and the thumb is styled explicitly because the OS overlay scrollbar was
   invisible until hover (which read as "there is no scrollbar"). Safe to scroll here
   because all slot/priority popovers are position:fixed (core.js placeFixedPopover) —
   they escape this overflow instead of being clipped by it. */
.side { display: flex; flex-direction: column; gap: 10px; position: sticky; top: 62px;
  max-height: calc(100vh - 74px); overflow-y: auto; scrollbar-gutter: stable; padding-right: 2px;
  scrollbar-width: thin; scrollbar-color: #c9c5bc transparent; }
.side::-webkit-scrollbar { width: 9px; }
.side::-webkit-scrollbar-track { background: transparent; }
.side::-webkit-scrollbar-thumb { background: #c9c5bc; border-radius: 100px; border: 2px solid var(--bg); }
.side::-webkit-scrollbar-thumb:hover { background: #b0aba1; }
@media (max-width: 820px) { .side { max-height: none; overflow: visible; position: static; } }
/* No `overflow: hidden` here — it silently clipped anything that didn't fit (with no
   scrollbar, so the content was simply unreachable). Panels now grow to fit instead. */
.panel { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); }
.panel > summary { list-style: none; cursor: pointer; padding: 11px 13px; display: flex; align-items: center; gap: 8px; font-weight: 600; font-size: 12.5px; }
.panel > summary::-webkit-details-marker { display: none; }
.panel > summary .chev { margin-left: auto; color: var(--muted); transition: transform .15s; font-size: 11px; }
.panel[open] > summary .chev { transform: rotate(90deg); }
.pbody { padding: 0 13px 13px; display: flex; flex-direction: column; gap: 11px; min-width: 0; }
/* Nothing in a panel may push the column wider than it is: everything shrinks, and long
   unbroken strings (a pasted message, a long client/project name) wrap instead. */
.pbody > * { min-width: 0; max-width: 100%; overflow-wrap: anywhere; }
.lbl { font-size: 10.5px; font-weight: 600; letter-spacing: .08em; text-transform: uppercase; color: var(--muted); font-family: monospace; }
.pbody textarea, .pbody input[type=text], .pbody input[type=time], .pbody input[type=number], .pbody select { width: 100%; }
/* A labelled block: label on its own line, control(s) below at full width. Replaces the
   old single-line `.side-row`s that packed 3-4 controls into ~226px and got clipped. */
.field { display: flex; flex-direction: column; gap: 5px; min-width: 0; }
.field > .side-row { gap: 6px; }
/* Buttons in the sidebar share a line evenly rather than overflowing it. */
.btn-split { display: flex; gap: 6px; }
.btn-split > .btn { flex: 1; justify-content: center; }
/* Active-days chips: fixed 4-per-row grid (4+3) — as a wrapping flex row the 7th chip
   used to land in whatever gap was left and the row height jumped. */
.day-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 5px; }
.day-grid .day-label { justify-content: center; padding: 5px 2px; font-size: 12px; gap: 3px; }
/* Auto-retry: two labelled number fields side by side instead of "1 time(s), every 30 min"
   crammed inline with the labels as loose text nodes. */
.mini-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.mini-grid > * { min-width: 0; }          /* grid items default to min-width:auto -> can overflow */
.mini-grid .field > .lbl { font-size: 9.5px; }
/* Native selects ellipsize a long option instead of widening the panel; `title` on each
   select (set in HTML) makes the full value readable on hover. */
.pbody select { text-overflow: ellipsis; }
.varrow { display: flex; align-items: center; gap: 5px; flex-wrap: wrap; }
.varlbl { font-size: 10px; font-weight: 600; letter-spacing: .06em; text-transform: uppercase; color: var(--muted); font-family: monospace; }
.chip { font: 600 11px monospace; padding: 4px 7px; border-radius: 6px; border: 1px solid var(--border); background: var(--bg); color: var(--blue); cursor: pointer; }
.chip:hover { background: var(--blue-bg); }
.side-note { font-size: 11.5px; color: var(--muted); }
/* Count badge on a panel summary (suppressed addresses). Empty when zero — :empty
   collapses it so the panel title doesn't carry a stray "0". */
.pill-count { display: inline-block; min-width: 17px; padding: 1px 5px; border-radius: 100px;
  background: var(--red-bg, #fee2e2); color: var(--red); font-size: 10.5px; font-weight: 700;
  text-align: center; vertical-align: middle; }
.pill-count:empty { display: none; }
.side-row { display: flex; gap: 7px; align-items: center; flex-wrap: wrap; }

/* ── channel switcher ───────────────────────────────────────────────────────── */
.switch { display: inline-flex; background: var(--bg); border: 1px solid var(--border); border-radius: 10px; padding: 3px; gap: 2px; align-self: flex-start; }
.seg { display: flex; align-items: center; gap: 7px; border: 0; background: transparent; color: var(--muted); font-size: 13px; font-weight: 600; padding: 7px 13px; border-radius: 7px; cursor: pointer; font-family: inherit; }
.seg[aria-selected="true"] { background: var(--surface); color: var(--text); box-shadow: 0 1px 2px rgba(0,0,0,.1); }
.seg[aria-selected="true"][data-ch="call"] { color: var(--blue); }
.seg[aria-selected="true"][data-ch="whatsapp"] { color: var(--green); }
.seg[aria-selected="true"][data-ch="email"] { color: var(--yellow); }
.seg .offdot { width: 6px; height: 6px; border-radius: 50%; background: var(--yellow); }

/* ── "not connected" banner ─────────────────────────────────────────────────── */
.banner { display: none; align-items: flex-start; gap: 10px; padding: 11px 13px; border-radius: var(--radius); background: var(--yellow-bg); border: 1px solid var(--yellow); }
.banner.show { display: flex; }
.banner b { color: var(--text); }
.banner .sub { color: var(--muted); font-size: 12px; margin-top: 2px; }

/* ── TTS audio readiness chip ────────────────────────────────────────────────── */
.tts-chip { display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 9px 12px; border-radius: var(--radius); font-size: 12.5px; line-height: 1.4; }
.tts-chip.ok    { background: var(--green-bg); border: 1px solid var(--green); color: var(--green); }
.tts-chip.warn  { background: var(--yellow-bg); border: 1px solid var(--yellow); color: var(--yellow); }
.tts-chip.working { background: var(--blue-bg); border: 1px solid var(--blue); color: var(--blue); }
.tts-chip span { flex: 1; min-width: 200px; }
.tts-chip b { font-weight: 700; }
/* per-row flag for someone whose clip isn't rendered yet */
.badge-noaudio { background: var(--yellow-bg); color: var(--yellow); }

/* ── list toolbar ───────────────────────────────────────────────────────────── */
.list-card { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); overflow: hidden; }
.ltools { display: flex; align-items: center; gap: 10px; padding: 10px 12px; border-bottom: 1px solid var(--border); flex-wrap: wrap; }
.ltools .lsearch { flex: 1; min-width: 150px; max-width: 340px; }
.ltools .spacer { flex: 1; }
.ltools .lcount { font-size: 12px; color: var(--muted); }
.ltools .lcount b { color: var(--text); font-family: monospace; }

/* ── active/inactive toggle (per row) ───────────────────────────────────────── */
.tog { width: 34px; height: 20px; border-radius: 20px; background: var(--border); border: 0; position: relative; cursor: pointer; padding: 0; flex-shrink: 0; }
.tog::after { content: ""; position: absolute; top: 2px; left: 2px; width: 16px; height: 16px; border-radius: 50%; background: #fff; transition: left .15s; }
.tog.on { background: var(--green); }
.tog.on::after { left: 16px; }

/* per-row schedule button + inline slots reuse .slot-pill from components.css */
.row-sched { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; margin-top: 8px; padding-top: 8px; border-top: 1px solid var(--border); }
.row-sched-lbl { font-size: 11px; color: var(--muted); }

/* ── channel gating: dim + empty-state ──────────────────────────────────────── */
.dim { opacity: .5; pointer-events: none; }
/* ...but the primary action must still RECEIVE the click so it can say why it's
   disabled. Silently eating the click reads as a broken button — which is exactly
   how "Email All doesn't work" was reported. See sendBlockReason() in channels.js. */
.action-bar.dim #btn-call-all { pointer-events: auto; cursor: not-allowed; }
.empty { padding: 40px 16px; text-align: center; color: var(--muted); }
.empty .big { font-size: 26px; }
.empty .ttl { font-weight: 600; color: var(--text); margin-top: 6px; }

/* ── report view (toggled from topbar) ──────────────────────────────────────── */
#report-view { display: none; padding: 14px 24px; }
#report-view.show { display: block; }
.console-hidden { display: none !important; }

/* ── polish: brand badge as a clean circle to match the rounded UI ──────────── */
.brand .brand-badge { border-radius: 50%; font-size: 12px; }

/* ── polish: compact time slots (the pill was too big/round for this density) ── */
.slot-pill { border-radius: var(--radius); padding: 3px 9px; font-size: 12px; font-weight: 500; }
#bulk-slots { flex-wrap: wrap; }
/* (The old `.side .slot-popover { left:auto; right:0 }` clamp is gone — popovers are
   position:fixed and placed by core.js placeFixedPopover, which sets left/right itself,
   so the rule was dead except for shrinking them to 168px.) */
.row-sched { gap: 5px; }
.row-sched .slot-pill { padding: 3px 8px; }
/* thin divider between the schedule slots and the one-off priority pill */
.row-sched-sep { width: 1px; align-self: stretch; background: var(--border); margin: 2px 3px; }

/* ── polish: calling-window time input — smaller, softer native icon ────────── */
.pbody input[type=time] { padding: 4px 7px; max-width: 118px; }
.pbody input[type=time]::-webkit-calendar-picker-indicator { opacity: .4; cursor: pointer; }

/* ── polish: client manager modal — wider so client rows don't need a scroller ─ */
#org-modal .org-mgr-box { max-width: 500px; }
#org-list input { min-width: 0; }

/* per-row email subject override (sits above the body box in the row editor) */
.row-subject { width: 100%; padding: 7px 9px; font-size: 13px; margin-bottom: 6px;
  border: 1px solid var(--border); border-radius: var(--radius); background: #fafafa;
  color: var(--text); outline: none; font-family: inherit; }
.row-subject:focus { border-color: var(--text); background: #fff; }

/* ── daily list pager ──────────────────────────────────────────────────────────
   The list is served one page at a time (see /api/daily). Sending every contact to
   paint 200 rows was ~4MB of JSON per switch. Hidden entirely when there's only one
   page, so short lists gain no chrome. */
.pager { display: flex; flex-wrap: wrap; align-items: center; justify-content: center;
  gap: 4px; padding: 12px 0 4px; }
.pager:empty { display: none; }
.pager .pager-btn { min-width: 30px; padding: 4px 8px; font-variant-numeric: tabular-nums; }
.pager .pager-btn[disabled] { opacity: .4; cursor: default; }
.pager .pager-active { background: var(--text); color: #fff; border-color: var(--text); }
.pager .pager-gap { padding: 0 2px; color: var(--muted); font-size: 12px; }


/* ── ASK view ─────────────────────────────────────────────────────────────────
   A conversation column, not a dashboard: the client types, the answer appears
   beneath. Answers are wide (they hold a chart and a table); questions are not. */
#chat-view { display: none; padding: 14px 24px 24px; }
#chat-view.show { display: block; }
.chat-wrap { max-width: 900px; margin: 0 auto; }
#chat-log { display: flex; flex-direction: column; gap: 14px; margin-bottom: 14px; }

.chat-q { align-self: flex-end; max-width: 78%; background: var(--blue); color: #fff;
  padding: 8px 13px; border-radius: 14px 14px 3px 14px; font-size: 14px; }
.chat-a { background: var(--surface); border: 1px solid var(--border);
  border-radius: 12px; padding: 14px 16px; }
.chat-a .a-title { font-weight: 600; font-size: 14px; margin-bottom: 4px; }
.chat-a .a-insight { font-size: 14px; line-height: 1.55; margin-bottom: 12px; }
.chat-a .a-chart { min-height: 40px; margin-bottom: 10px; }
.chat-a .a-meta { font-size: 11.5px; color: var(--muted); display: flex; gap: 8px;
  flex-wrap: wrap; align-items: center; margin-top: 10px;
  padding-top: 9px; border-top: 1px solid var(--border); }

/* Resolved slots, editable. Changing one re-runs the SAME report with new params —
   no model call, so it is instant and free. */
/* These are controls, not labels — they were being read as static text because nothing
   about them invited a click. */
.slot-chip { border: 1px solid var(--border); border-radius: 100px; padding: 3px 10px;
  background: var(--surface); cursor: pointer; font-size: 11.5px; color: var(--text);
  font-family: inherit; }
.slot-chip:hover { border-color: var(--blue); color: var(--blue); background: var(--blue-bg); }
.slot-chip::after { content: " \25BE"; color: var(--muted); font-size: 9px; }
.slot-chip.noarrow::after { content: ""; }

.a-table-wrap { max-height: 330px; overflow: auto; border: 1px solid var(--border);
  border-radius: 8px; }
.a-table { width: 100%; border-collapse: collapse; font-size: 12.5px; }
.a-table th { position: sticky; top: 0; background: var(--bg); text-align: left;
  padding: 7px 9px; border-bottom: 1px solid var(--border); font-weight: 600;
  white-space: nowrap; }
.a-table td { padding: 6px 9px; border-bottom: 1px solid var(--border);
  overflow-wrap: anywhere; }
.a-table tr:last-child td { border-bottom: none; }

.chat-input-row { display: flex; gap: 8px; position: sticky; bottom: 0;
  background: var(--bg); padding: 10px 0; }
.chat-input-row input { flex: 1; }

/* FAQ — what the bot can answer. The client should never have to guess. */
.faq-group { margin-bottom: 12px; }
.faq-title { font-size: 11px; font-weight: 700; letter-spacing: .07em;
  text-transform: uppercase; color: var(--muted); margin-bottom: 6px; }
.faq-chips { display: flex; gap: 6px; flex-wrap: wrap; }
.faq-chip { border: 1px solid var(--border); border-radius: 100px; padding: 5px 11px;
  font-size: 12.5px; background: var(--surface); cursor: pointer; }
.faq-chip:hover { border-color: var(--blue); color: var(--blue); }
.chat-thinking { font-size: 13px; color: var(--muted); }


/* Slot editor popover (Ask view). Sizing only — placement is done in JS by
   placeFixedPopover(), which sets position/left/top. */
.slot-editor { display: none; width: 260px; background: var(--surface);
  border: 1px solid var(--border); border-radius: 10px; padding: 11px;
  box-shadow: 0 6px 20px rgba(0,0,0,.13); z-index: 60; }
.slot-editor.open { display: block; }
.slot-sec { font-size: 10px; font-weight: 700; letter-spacing: .07em;
  text-transform: uppercase; color: var(--muted); margin: 2px 0 6px; }
.preset-row { display: flex; flex-wrap: wrap; gap: 5px; margin-bottom: 9px; }
.preset-btn { border: 1px solid var(--border); background: var(--bg); border-radius: 100px;
  padding: 4px 9px; font-size: 11.5px; cursor: pointer; font-family: inherit; }
.preset-btn:hover { border-color: var(--blue); color: var(--blue); }
.slot-dates { display: flex; align-items: center; gap: 5px; }
.slot-dates input { flex: 1; min-width: 0; font-size: 12px; }
.slot-dates span { color: var(--muted); font-size: 12px; }


/* The FAQ catalogue is a permanent control, not onboarding — it collapses to this bar,
   pinned with the input so it is reachable without scrolling back up a long conversation. */
#chat-faq { position: sticky; bottom: 52px; background: var(--bg); padding-top: 6px; z-index: 2; }
.faq-toggle { border: 1px dashed var(--border); background: var(--surface); border-radius: 100px;
  padding: 6px 13px; font-size: 12.5px; cursor: pointer; color: var(--muted);
  font-family: inherit; }
.faq-toggle:hover { border-color: var(--blue); color: var(--blue); }
.faq-panel { margin-top: 9px; max-height: 40vh; overflow-y: auto; padding: 10px;
  border: 1px solid var(--border); border-radius: 10px; background: var(--surface); }
