/* Shared styling. Function over form - visual design comes later. */
:root {
  --bg: #f6f7f9; --card: #fff; --ink: #1c2024; --muted: #6b7280;
  --line: #e3e6ea; --accent: #1f6feb; --accent-soft: #eaf1fe;
  --good: #087443; --good-bg: #e8f5ee;
  --warn: #7a4a06; --warn-bg: #fff4e5; --warn-line: #f0a13a;
  --bad: #b42318; --bad-bg: #fdeceb;
}
* { box-sizing: border-box; }
body {
  margin: 0; padding: 20px;
  font: 14px/1.5 -apple-system, "Segoe UI", Roboto, sans-serif;
  background: var(--bg); color: var(--ink);
}
a { color: var(--accent); }
.wrap { max-width: 1220px; margin: 0 auto; }
h1 { font-size: 20px; margin: 0 0 4px; }
h2 { font-size: 15px; margin: 0 0 10px; }
.sub { color: var(--muted); font-size: 13px; }
.card {
  background: var(--card); border: 1px solid var(--line);
  border-radius: 8px; padding: 16px; margin-bottom: 14px;
}
.row { display: flex; gap: 14px; flex-wrap: wrap; align-items: flex-end; }
label { display: block; font-size: 12px; color: var(--muted); margin-bottom: 4px; }
input, select, button, textarea {
  font: inherit; padding: 6px 10px; border: 1px solid var(--line);
  border-radius: 6px; background: #fff; color: inherit;
}
button { background: var(--accent); color: #fff; border-color: var(--accent); cursor: pointer; }
button.ghost { background: #fff; color: var(--ink); border-color: var(--line); }
button:hover { filter: brightness(1.06); }
table { border-collapse: collapse; width: 100%; font-variant-numeric: tabular-nums; }
th, td { text-align: left; padding: 7px 9px; border-bottom: 1px solid var(--line); }
th { font-size: 12px; color: var(--muted); font-weight: 600; }
td.num, th.num { text-align: right; }
tr.clickable:hover { background: var(--accent-soft); cursor: pointer; }
.scroll { overflow-x: auto; }
.pill {
  display: inline-block; padding: 1px 8px; border-radius: 999px;
  font-size: 12px; border: 1px solid var(--line); background: #fff;
}
.pill.good { background: var(--good-bg); color: var(--good); border-color: #b7dfc8; }
.pill.warn { background: var(--warn-bg); color: var(--warn); border-color: var(--warn-line); }
.pill.bad  { background: var(--bad-bg);  color: var(--bad);  border-color: #f3c0bc; }
.pill.mute { background: #f1f3f5; color: var(--muted); }
.grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 10px; }
.kv .k { font-size: 12px; color: var(--muted); }
.kv .v { font-weight: 600; }
.muted { color: var(--muted); }
.empty { color: var(--muted); padding: 20px; text-align: center; }
.warnbox {
  background: var(--warn-bg); border: 1px solid var(--warn-line);
  color: var(--warn); border-radius: 8px; padding: 10px 14px; margin-bottom: 14px;
  font-size: 13px;
}
.cols { display: grid; grid-template-columns: 1fr 300px; gap: 14px; align-items: start; }
@media (max-width: 900px) { .cols { grid-template-columns: 1fr; } }
.tl { list-style: none; margin: 0; padding: 0; }
.tl li { display: grid; grid-template-columns: 150px 110px 1fr; gap: 10px;
         padding: 9px 0; border-bottom: 1px solid var(--line); align-items: start; }
.tl li:last-child { border-bottom: 0; }
.tl .when { color: var(--muted); font-size: 12px; }
.tl .what { font-weight: 600; font-size: 13px; }
.tl .detail { font-size: 13px; }
.strike { color: var(--bad); font-weight: 600; }

/* Callback - the warmest signal the system produces. Impossible to miss. */
.callback { border-radius: 8px; padding: 12px 16px; margin-bottom: 14px; border: 2px solid; }
.callback.hot  { background: #fdeceb; border-color: var(--bad);  color: #7a1610; }
.callback.warm { background: var(--warn-bg); border-color: var(--warn-line); color: var(--warn); }
.callback.cool { background: #f1f3f5; border-color: var(--line); color: var(--muted); }
.callback .hd { font-weight: 700; font-size: 15px; }
.callback .bd { font-size: 13px; margin-top: 4px; opacity: .9; }

/* Upsell - built from what the dealer themselves asked for. */
.upsell {
  background: #eef6ff; border: 2px solid var(--accent);
  border-radius: 8px; padding: 14px 16px; margin-bottom: 14px;
}
.upsell .hd { font-size: 15px; margin-bottom: 10px; }
.upsell .grp { margin-top: 10px; }
.upsell .lbl {
  font-size: 11px; text-transform: uppercase; letter-spacing: .04em;
  color: var(--muted); margin-bottom: 6px;
}
.upsell .cat { font-size: 13px; padding: 3px 0; }
.upsell .cat .n {
  display: inline-block; min-width: 24px; font-weight: 700; color: var(--accent);
}
.upsell .note {
  font-size: 12px; color: var(--muted); margin-top: 10px;
  border-top: 1px solid #cfe0f7; padding-top: 8px;
}

/* Premier - a different pitch, on different criteria. Never category access. */
.premier {
  background: #f6f1ff; border: 2px solid #7a5af8;
  border-radius: 8px; padding: 14px 16px; margin-bottom: 14px;
}
.premier .hd { font-size: 15px; font-weight: 700; color: #4c2fb8; margin-bottom: 8px; }
.premier .why { margin: 0 0 10px 18px; padding: 0; font-size: 13px; }
.premier .lbl {
  font-size: 11px; text-transform: uppercase; letter-spacing: .04em;
  color: var(--muted); margin-bottom: 6px;
}
.premier .sell .pill { margin: 0 4px 4px 0; }
.premier .note {
  font-size: 12px; color: var(--muted); margin-top: 10px;
  border-top: 1px solid #ddd0f7; padding-top: 8px;
}

/* Kanban board */
.board { display: flex; gap: 12px; overflow-x: auto; padding-bottom: 8px; align-items: flex-start; }
.col {
  background: #eef0f3; border: 1px solid var(--line); border-radius: 8px;
  min-width: 250px; max-width: 250px; flex: 0 0 250px; padding: 8px;
}
.col > .hd {
  font-size: 12px; font-weight: 700; text-transform: uppercase;
  letter-spacing: .03em; color: var(--muted); padding: 2px 4px 8px;
  display: flex; justify-content: space-between;
}
.col.terminal { background: #f4f1f1; }
.pcard {
  background: #fff; border: 1px solid var(--line); border-radius: 6px;
  padding: 8px 10px; margin-bottom: 8px; cursor: pointer; font-size: 13px;
}
.pcard:hover { border-color: var(--accent); }
.pcard.hot { border-left: 4px solid var(--bad); }
.pcard.warm { border-left: 4px solid var(--warn-line); }
/* ⚠️ BREAK ANYWHERE, NOT JUST AT SPACES.
   Real dealer names include unbreakable tokens - "Sovereign
   SalesAndMarketing@myyaho.com" is 28 characters with nowhere to wrap, and
   at 250px it spilled 202px of text through a 190px box. Normal word-wrap
   does nothing about it because there is no word boundary to use. Applies
   to every card, not just callbacks: a long name in any column had the
   same problem and nobody had looked. */
.pcard .co { font-weight: 600; overflow-wrap: anywhere; }
.pcard .meta { color: var(--muted); font-size: 12px; margin-top: 3px;
  overflow-wrap: anywhere; }
.pcard .cb { color: var(--bad); font-weight: 600; font-size: 12px; margin-top: 3px; }

/* ---- call intelligence on the 360 timeline -------------------------- */
/* Generated from the audio, not typed by anyone. Set apart from the
   logged facts around it so nobody mistakes a model's reading of a call
   for something a human recorded. */
.intel { margin-top: 8px; padding: 10px 12px; border-left: 3px solid var(--line);
         background: #fafbfc; border-radius: 0 6px 6px 0; }
.intelhead { display: flex; flex-wrap: wrap; gap: 4px; margin-bottom: 6px; }
.intelsum { margin: 4px 0 8px; line-height: 1.45; }
.intelblock { margin-top: 8px; }
.intelfoot { margin-top: 10px; display: flex; flex-wrap: wrap; gap: 12px;
             align-items: center; font-size: 12px; }

/* A quote is the dealer's or the agent's actual words. Anything not in
   this style is a summary and may be wrong. */
.q { margin: 3px 0; padding-left: 10px; border-left: 2px solid #dfe3e8;
     font-style: italic; color: #333; line-height: 1.4; }
.q.ans { border-left-color: #b7dfc8; }
.qk { display: inline-block; min-width: 62px; font-style: normal;
      font-size: 11px; text-transform: uppercase; letter-spacing: .04em;
      color: var(--muted); }

.transcript { margin-top: 8px; padding: 10px; background: #fff;
              border: 1px solid var(--line); border-radius: 6px;
              max-height: 340px; overflow: auto; white-space: pre-wrap;
              font-size: 12px; line-height: 1.5; }

.linkbtn { background: none; border: 0; padding: 0; cursor: pointer;
           color: var(--link, #0b63ce); font: inherit; font-size: 12px; }
.linkbtn:hover { text-decoration: underline; }
.warntext { color: var(--warn); }
.warnbox { border-color: var(--warn-line); background: var(--warn-bg); }

/* ---- admin board ---------------------------------------------------- */
.tabs { display: flex; flex-wrap: wrap; gap: 4px; margin: 16px 0 4px;
        border-bottom: 1px solid var(--line); }
.tab { background: none; border: 0; border-bottom: 2px solid transparent;
       padding: 8px 12px; cursor: pointer; font: inherit; font-size: 14px;
       color: var(--muted); }
.tab:hover { color: inherit; }
.tab.on { color: inherit; font-weight: 600; border-bottom-color: #0b63ce; }

.tbl { width: 100%; border-collapse: collapse; font-size: 13px; }
.tbl th { text-align: left; font-size: 11px; text-transform: uppercase;
          letter-spacing: .04em; color: var(--muted); font-weight: 600;
          padding: 6px 8px; border-bottom: 1px solid var(--line); }
.tbl td { padding: 8px; border-bottom: 1px solid #f0f2f4; vertical-align: top; }
.tbl tr:last-child td { border-bottom: 0; }
/* A deactivated row is still readable - it is history, not clutter. */
.tbl tr.off td { opacity: .55; }

.formgrid { display: grid; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
            gap: 14px; }
.formgrid input, .formgrid select { width: 100%; padding: 6px 8px;
            border: 1px solid var(--line); border-radius: 5px; font: inherit;
            font-size: 13px; }
.fl { display: flex; align-items: center; gap: 7px; font-size: 13px;
      align-self: end; padding-bottom: 6px; }
.fl input { width: auto; }

.btn { display: inline-block; padding: 6px 12px; border: 1px solid var(--line);
       border-radius: 6px; background: #fff; cursor: pointer; font: inherit;
       font-size: 13px; text-decoration: none; color: inherit; }
.btn:hover { background: #f6f8fa; }
.btn.primary { background: #0b63ce; border-color: #0b63ce; color: #fff; }
.btn.primary:hover { background: #0a58b8; }

/* One rule per row: the value and the sentence explaining it stay together,
   because a threshold without its meaning is a number nobody can safely
   change. */
.rule { padding: 10px 0; border-bottom: 1px solid #f0f2f4; }
.rule:last-child { border-bottom: 0; }
.ruletop { display: grid; grid-template-columns: 240px minmax(120px, 320px) auto;
           gap: 10px; align-items: center; }
.ruletop input { padding: 6px 8px; border: 1px solid var(--line);
                 border-radius: 5px; font: inherit; font-size: 13px; }
.ruletop .k { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; }

.goodbox { border-color: #b7dfc8; background: var(--good-bg); }
.badbox  { border-color: #f3c0bc; background: var(--bad-bg); }

/* ---- session bar ---------------------------------------------------- */
/* Present on every page so "who am I signed in as" is never a question.
   This is visibility, not access control - the server refuses regardless
   of what is rendered here. */
.sessionbar { display: flex; justify-content: space-between; align-items: center;
              gap: 16px; padding: 8px 18px; background: #fff;
              border-bottom: 1px solid var(--line); font-size: 13px;
              flex-wrap: wrap; }
.sessionleft { display: flex; gap: 16px; align-items: center; }
.sessionleft a { text-decoration: none; color: var(--muted); }
.sessionleft a:first-child { font-weight: 600; color: inherit; }
.sessionleft a:hover { color: inherit; text-decoration: underline; }
.sessionright { display: flex; gap: 12px; align-items: center; }

/* ---- board metrics bar ---------------------------------------------- */
/* Pinned so PAST DUE stays visible while scrolling a long board. The
   standing instruction is that nothing is past due at end of day, so the
   number that measures it must not scroll away. */
.metrics { position: sticky; top: 0; z-index: 20; display: flex; gap: 10px;
           flex-wrap: wrap; padding: 10px 0; margin-top: 12px;
           background: var(--bg); }
.metric { flex: 1 1 150px; min-width: 140px; background: #fff;
          border: 1px solid var(--line); border-radius: 8px; padding: 10px 14px;
          text-align: left; font: inherit; }
.metric.bad  { border-color: var(--bad);  background: var(--bad-bg); }
.metric.good { border-color: #b7dfc8;     background: var(--good-bg); }
button.metric { cursor: pointer; }
button.metric:hover { filter: brightness(.97); }
.mlabel { font-size: 11px; font-weight: 700; letter-spacing: .05em;
          color: var(--muted); }
.mval   { font-size: 30px; font-weight: 700; line-height: 1.1; }
.metric.bad .mval { color: var(--bad); }
.mhint  { font-size: 11px; color: var(--muted); }

/* ---- reaching every column ------------------------------------------- */
.boardbar { display: flex; align-items: center; gap: 6px; flex-wrap: wrap;
            margin: 4px 0 8px; }
.chip { font: inherit; font-size: 12px; padding: 3px 9px; border-radius: 999px;
        border: 1px solid var(--line); background: #fff; cursor: pointer; }
.chip.off { opacity: .45; text-decoration: line-through; }
.chip:hover { border-color: var(--accent); }

.boardwrap { position: relative; }
/* The board's own scrollbar sits at the bottom of a tall page, so it cannot
   be reached without scrolling down. These sit on top of the board itself. */
.scrollbtn { position: absolute; top: 50%; transform: translateY(-50%);
             z-index: 15; width: 32px; height: 56px; border-radius: 6px;
             border: 1px solid var(--line); background: rgba(255,255,255,.94);
             cursor: pointer; font-size: 22px; line-height: 1; color: var(--muted);
             box-shadow: 0 1px 4px rgba(0,0,0,.12); }
.scrollbtn:hover { color: inherit; border-color: var(--accent); }
.scrollbtn.left  { left: -6px; }
.scrollbtn.right { right: -6px; }
.hidebtn { font-size: 14px; color: var(--muted); margin-left: 6px; }

/* NO scroll-behavior:smooth HERE. With it set in CSS, assigning scrollLeft
   from JavaScript is swallowed - the read returns 0 and the board never
   moves - which is what made the scroll buttons appear broken. Smoothness
   is applied per-call from JS instead, where it is honoured. */

/* ---- aging indicators ------------------------------------------------ */
.agerow { display: flex; align-items: center; gap: 6px; margin: 4px 0 2px;
          flex-wrap: wrap; }
.agebadge { font-size: 11px; font-weight: 600; padding: 1px 7px;
            border-radius: 999px; border: 1px solid; }
.agebadge.fresh { color: var(--good); border-color: #b7dfc8; background: var(--good-bg); }
.agebadge.amber { color: var(--warn); border-color: var(--warn-line); background: var(--warn-bg); }
.agebadge.red   { color: var(--bad);  border-color: #f3c0bc;        background: var(--bad-bg); }
/* The left edge escalates with the badge so a red card is findable at a
   glance in a column of forty. */
.pcard.age-amber { border-left: 4px solid var(--warn); }
.pcard.age-red   { border-left: 4px solid var(--bad); }

/* ---- THE FIX FOR "I CANNOT REACH THE RIGHTMOST COLUMNS" --------------
   The board was as tall as its longest column - 8,291px with 60 cards -
   so its horizontal scrollbar rendered 8,000px below the fold. The board
   was scrollable the whole time; the control was simply somewhere nobody
   could get to.

   Constraining the board to the viewport puts the horizontal scrollbar
   back on screen and gives each column its own vertical scroll, which is
   how a kanban is meant to behave: move sideways between stages, move
   down within one. */
.board {
  /* max-height is set from JS to the room actually available - see fit()
     in board.html. This is only the fallback before that runs. */
  max-height: calc(100vh - 230px);
  overflow-x: auto;
  overflow-y: hidden;
  align-items: stretch;
}
.col {
  display: flex;
  flex-direction: column;
  max-height: 100%;
}
.col > .hd { flex: 0 0 auto; }
/* Cards scroll inside the column, not the page. */
.col .cards { overflow-y: auto; flex: 1 1 auto; min-height: 0; }
.chip.on { background: #0b63ce; border-color: #0b63ce; color: #fff; }
.chip.on .muted { color: #cfe0f7; }
.chip.empty { opacity: .5; }

/* ---- click to call --------------------------------------------------- */
.callbar { display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
           padding-bottom: 10px; margin-bottom: 10px;
           border-bottom: 1px solid var(--line); }
.callbtn { font-size: 14px; padding: 8px 14px; }
.callbtn .muted { font-weight: 400; }
.callbtn.primary .muted { color: #cfe0f7; }
.callbtn.bad { border-color: var(--bad); color: var(--bad); background: var(--bad-bg); }
/* A small call button on a board card, so a dial does not need a page load. */
.cardcall { font-size: 11px; padding: 2px 7px; border-radius: 4px;
            border: 1px solid var(--line); background: #fff; cursor: pointer;
            color: var(--muted); margin-top: 4px; }
.cardcall:hover { border-color: var(--accent); color: inherit; }

/* --------------------------------------------------------------------
   RingCentral presence banner.

   Sits directly under the session bar, above everything else, because
   it changes whether the primary action on the page works at all. It is
   a warning, not an error: nothing is broken, an app is shut.
   -------------------------------------------------------------------- */
.rcbanner {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  padding: 10px 16px; background: #fff5e6; border-bottom: 1px solid #f0c98a;
  color: #6b4a12; font-size: 13px;
}
.rcbanner strong { font-weight: 600; }
.rcbannerhint { color: #8a6a30; font-size: 12px; }
.rcbanner .linkbtn { margin-left: auto; color: #6b4a12; }

/* Greyed rather than hidden. A missing button reads as a broken page;
   a disabled one with a tooltip reads as "not right now". */
.cardcall:disabled, .callbtn:disabled {
  opacity: .45; cursor: not-allowed; filter: grayscale(1);
}

/* -------------------------------------------------------------------
   Partner edit form. Built from partner_editable_fields, so this styles
   whatever the configuration produces rather than a fixed set of rows.
   ------------------------------------------------------------------- */
.editgroup { margin: 12px 0 4px; }
.editgrouphead {
  font-size: 12px; font-weight: 600; text-transform: uppercase;
  letter-spacing: .04em; color: var(--muted); margin-bottom: 6px;
  border-bottom: 1px solid var(--line); padding-bottom: 4px;
}
.editrow { margin-bottom: 10px; }
.editrow label { display: block; font-size: 12px; color: var(--muted); margin-bottom: 3px; }
.editrow input, .editrow select, .editrow textarea {
  width: 100%; box-sizing: border-box; padding: 6px 8px;
  border: 1px solid var(--line); border-radius: 4px; font: inherit; font-size: 13px;
}
.editrow textarea { resize: vertical; }
.edithelp { font-size: 11px; color: var(--muted); margin-top: 3px; }
.editactions { margin-top: 14px; display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }

/* -------------------------------------------------------------------
   Callback queue. Above the board, visually distinct from it, because
   it is not a stage - it is an override of the cadence.
   ------------------------------------------------------------------- */

.metric.callbackmetric { border-color: var(--warn-line); background: var(--warn-bg); }
.metric.callbackmetric .mval { color: var(--warn); }

/* ==========================================================================
   CALLED US BACK - a COLUMN now, first position, same size as the others.
   It used to be a full-width panel above the board and took most of the
   screen; the callouts are the highest-converting segment but not at that
   price. Same .col geometry so it reads as part of the board, with a warn
   border so it does not read as just another stage.
   ========================================================================== */
.col.cbcol { background: #fff8ec; border: 2px solid var(--warn-line); }
.col.cbcol > .hd { color: var(--warn); }
.pcard.cbcard { border-left: 4px solid var(--warn-line); }
.pcard.cbcard .cbline { display: flex; align-items: center; gap: 6px;
  flex-wrap: wrap; margin-top: 4px; font-size: 12px; }
.cbcount { font-weight: 700; color: var(--warn); }
.cbvm, .cbwait { font-size: 12px; color: var(--muted); }
.cbnever { font-size: 11px; background: var(--bad); color: #fff;
  border-radius: 3px; padding: 1px 5px; }
.cbdupe { font-size: 11px; color: var(--muted); border: 1px solid var(--line);
  border-radius: 3px; padding: 1px 5px; }

/* The column chip for this column is shown but inert: a callback outranks
   the cadence, so it must not be dismissable by a mis-click. */
.chip.locked { opacity: .75; cursor: default; }
.chip.locked::after { content: " F512"; font-size: 10px; }

/* ==========================================================================
   BOARD SEARCH
   ========================================================================== */
.searchcell { display: flex; flex-direction: column; }
.searchcell input { min-width: 230px; padding: 6px 8px; font-size: 13px;
  border: 1px solid var(--line); border-radius: 4px; }
.searchcell input:focus { outline: 2px solid var(--accent); outline-offset: -1px; }
.qnote { font-size: 11px; color: var(--muted); margin-top: 3px; min-height: 14px; }
.qnote.hit { color: var(--accent); font-weight: 600; }
.qnote.miss { color: var(--bad); font-weight: 600; }

/* "+3 phone" on a stage header: dealers at this stage who are in the
   callback column instead. The count beside it is what is SHOWN; this is
   what was moved, so a column can never silently be missing dealers. */
.cbaway { margin-left: 5px; color: var(--warn); font-weight: 700; cursor: help; }

/* Call buttons: one per number we hold, each labelled. Stacked rather than
   inline so a long number never pushes the second button off a 250px card. */
.pcard .calls { display: flex; flex-direction: column; gap: 4px; margin-top: 6px; }
.pcard .calls .cardcall { width: 100%; text-align: left; }
.cardcall .cnum { color: var(--muted); font-weight: 400; margin-left: 4px; }

/* Today's activity. Present only when something happened today, so it reads
   as an event rather than a field that is usually empty. */
.pcard .today { font-size: 12px; color: var(--accent); margin-top: 4px; }
.pcard .today strong { color: var(--ink); }
.pcard.cbcard .today { color: var(--warn); }

/* The failure bar. Fixed to the bottom so it cannot be missed and cannot
   push the board around, and loud enough that "nothing happened" and "that
   failed" can never look alike. */
#gh-error-bar { position: fixed; left: 0; right: 0; bottom: 0; z-index: 9999;
  display: none; padding: 12px 16px; background: var(--bad); color: #fff;
  font-size: 14px; box-shadow: 0 -2px 10px rgba(0,0,0,.25); }
#gh-error-bar.show { display: flex; gap: 10px; align-items: center; }
#gh-error-bar strong { font-weight: 700; }
#gh-error-bar button { margin-left: auto; background: rgba(255,255,255,.15);
  color: #fff; border: 1px solid rgba(255,255,255,.4); border-radius: 4px;
  padding: 3px 10px; cursor: pointer; font-size: 12px; }
