/* ============================================================
   DASHBOARD — team status widget (top-right of the header)
   ============================================================ */
.oncall-box { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; justify-content: flex-end; }
.oncall-idle { display: flex; align-items: center; gap: var(--sp-3); }

/* A staff member currently on a call: solid pill in their avatar colour, "→
   company", a running timer, and the shared pulse (via --pulse). */
.oncall-pill {
  display: flex; align-items: center; gap: var(--sp-4);
  border-radius: 999px; padding: var(--sp-3) var(--sp-5); color: var(--white);
  font-size: var(--fs-4); white-space: nowrap;
  animation: dashpulse 1.8s infinite;
}
.oncall-pill b { font-weight: 700; letter-spacing: -.01em; }
.oncall-pill .ocp-arrow { opacity: .72; font-weight: 500; }
.oncall-pill .ocp-co { font-weight: 600; }
.oncall-pill .ocp-time {
  font-variant-numeric: tabular-nums; font-weight: 700; font-size: var(--fs-3);
  background: rgba(255, 255, 255, .24); border-radius: 999px; padding: var(--sp-1) 7px;
}

/* Everyone else: a small avatar disc with a status dot. */
.presence-chip { display: flex; align-items: center; }
.presence-chip .pc-av {
  position: relative; width: 30px; height: 30px; border-radius: 50%;
  display: grid; place-items: center; color: var(--white); font-weight: 700; font-size: var(--fs-3); flex: none;
}
.presence-chip .pc-dot {
  position: absolute; right: -1px; bottom: -1px; width: 9px; height: 9px;
  border-radius: 50%; border: 2px solid var(--paper);
}
/* "On the support queue" badge — a headset pinned opposite the status dot, so
   channel membership (who takes queue calls) reads separately from presence. */
.presence-chip .pc-queue {
  position: absolute; right: -4px; top: -4px; width: 15px; height: 15px;
  border-radius: 50%; display: grid; place-items: center;
  background: var(--teal); color: var(--white); border: 2px solid var(--paper);
}
.oncall-pill .ocp-queue { display: inline-flex; align-items: center; margin-right: var(--sp-1); opacity: .9; }

@keyframes dashpulse {
  0% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--pulse, var(--red)) 55%, transparent); }
  70% { box-shadow: 0 0 0 7px transparent; }
  100% { box-shadow: 0 0 0 0 transparent; }
}
@media (prefers-reduced-motion: reduce) {
  .oncall-pill, .kb-call__dir-icon--live { animation: none; }
}

/* Dashboard split: calls on the left, the viewer's tasks on the right. */
.dash-split { display: grid; grid-template-columns: 2fr 1fr; gap: 40px; align-items: start; }
.dash-split__col { min-width: 0; }
@media (max-width: 980px) { .dash-split { grid-template-columns: 1fr; gap: 0; } }

/* Each dashboard call list keeps both its empty note and its (always-rendered)
   table in the DOM; the note is shown only while the table holds no call, so a
   live insert/removal flips the empty state with no extra broadcast. */
.dash-calls:has(.kb-call) .cl-empty { display: none; }

/* Under the "Recent open calls" section header, each older day gets its own
   sub-header ("Yesterday", …). Those are secondary to the section header, so
   render them a step smaller and quieter. */
.dash-calls--today .kb-calls__date-row .cl-divider .lab { font-size: var(--fs-6); }

/* Compact "Needs follow-up" mirror in the right column: avatar + name/company +
   headline only. Hides the whole section (header included) while it holds no
   call, so a live rebuild flips it in/out with no extra broadcast. */
#followup_compact:not(:has(.dash-fu)) { display: none; }
/* Its "Needs follow-up" divider is the wrapper's first child, so it loses the
   usual section top-padding — add it back so it clears "My tasks" above it. */
.dash-split__col #followup_compact { margin-top: var(--sp-5); }

/* Hide the left-column "New comments" section while it holds no call — the
   wrapper always renders as a live-update target. */
#new_comments_section:not(:has(.dash-fu)) { display: none; }
/* When it's empty (hidden), it still sits in the DOM before the "Recent open
   calls" divider, stopping that divider being :first-child. Pull the divider's
   top padding back to the top-of-column value so it lines up with the search
   field and the right column's "My tasks" title. */
#new_comments_section:not(:has(.dash-fu)) + .cl-divider { padding-top: var(--sp-5); }

/* Assignee groups inside the compact follow-up list. The header is a section
   divider (avatar · name · rule): the 20px avatar sits centred in a 34px slot so
   it lines up with the caller-avatar column, the name lines up with the row body,
   and the rule fills the rest behind it. The floated "New activity" group leads
   with less top spacing (it sits right under the section header). */
.dash-fu-group { margin-top: var(--sp-7); }
.dash-fu-group--new { margin-top: var(--sp-6); }
/* The first group sits right under the "Needs follow-up" header, so it doesn't
   need the larger inter-group spacing (this shows when there's no New activity
   group leading). */
.cl-divider + .dash-fu-group { margin-top: var(--sp-6); }
/* New activity leads the list as part of the header, so it hugs it more tightly
   than a stand-alone assignee group would. */
.cl-divider + .dash-fu-group--new { margin-top: var(--sp-2); }
.dash-fu-group__head { display: flex; align-items: center; gap: var(--sp-4); padding: var(--sp-2) 0 var(--sp-3); font-family: var(--read); font-size: var(--fs-3); font-weight: 600; color: var(--muted); }
.dash-fu-group__head--new { color: var(--amber); font-weight: 700; }
.dash-fu-group__av-slot { flex: none; width: 34px; display: flex; justify-content: center; }
.dash-fu-group__av { flex: none; }
.dash-fu-group__av--none { width: 20px; height: 20px; border-radius: 50%; display: grid; place-items: center; background: var(--rail); color: var(--muted); }
.dash-fu-group__av--spark { width: 20px; height: 20px; display: grid; place-items: center; color: var(--amber); }
.dash-fu-group__name { flex: none; min-width: 0; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
.dash-fu-group__head .ln { flex: 1; height: 1px; background: var(--line); }

.dash-fu-list { display: flex; flex-direction: column; }
.dash-fu { display: flex; align-items: center; gap: var(--sp-4); padding: var(--sp-3); margin: 0 calc(-1 * var(--sp-3)); border-radius: 10px; color: inherit; text-decoration: none; cursor: pointer; }
.dash-fu:hover { background: var(--rail); }
.dash-fu__avatar { flex: none; position: relative; }
/* The avatar doubles as the resolution / call-back trigger — a bare button so
   it keeps the avatar's look while opening the menu. */
.dash-fu__avatar-btn { display: block; padding: 0; margin: 0; border: 0; background: none; cursor: pointer; color: inherit; border-radius: 50%; }
/* Call-back assignee, tucked into the customer avatar's bottom-right corner. */
.dash-fu__callback-badge {
  position: absolute; right: -3px; bottom: -3px;
  box-shadow: 0 0 0 2px var(--paper);
}
/* The row body is the modal link; the avatar/flag sit outside it. */
.dash-fu__link { flex: 1; min-width: 0; display: flex; color: inherit; text-decoration: none; }
.dash-fu__body { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.dash-fu__ident { display: flex; align-items: baseline; gap: var(--sp-3); min-width: 0; }
.dash-fu__ident .kb-call__contact-company { overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
.dash-fu__headline { font-family: var(--read); font-size: var(--fs-3); color: var(--muted); overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }

/* Highlighted-comment flag: dark glyph on a lime disc, pinned to the row's
   right edge so it reads as an instant "open me" cue. */
.dash-fu__flag {
  flex: none;
  display: grid; place-items: center;
  width: 26px; height: 26px; border-radius: 50%;
  background: var(--lime); color: var(--ink);
}

/* ============================================================
   ACTIVITY STREAM — the dashboard feed under "My tasks".
   ============================================================ */
.activity-feed { display: flex; flex-direction: column; padding: var(--sp-1) 0; }

/* Timeline: the disc is opaque and sits above a vertical rule that runs from
   each icon's centre down to the next icon's centre, so the discs read as a
   connected thread. Radius 14px + 7px top padding puts the centre at y=21px. */
.activity { position: relative; display: flex; align-items: flex-start; gap: 11px; padding: 7px 0; }
.activity:not(:last-child)::before { content: ""; position: absolute; left: 13px; top: 21px; bottom: -21px; width: 2px; background: var(--line); }

.activity__disc { position: relative; z-index: 1; flex: none; width: 28px; height: 28px; border-radius: 50%; display: grid; place-items: center; }

.activity__body { flex: 1; min-width: 0; padding-top: 3px; }
.activity__line { margin: 0; font-family: var(--read); font-size: var(--fs-5); color: var(--ink); line-height: 1.35; }
.activity__line strong { font-weight: 700; }

.activity__time { flex: none; margin-left: 10px; padding-top: var(--sp-3); font-family: var(--read); font-size: var(--fs-2); color: var(--faint); white-space: nowrap; }

.activity__sub { display: block; margin-top: 1px; font-family: var(--read); font-size: var(--fs-4); color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
a.activity__sub:hover { color: var(--accent); }


/* Transcript approval queue — shown on reviewers' dashboards only. Compact rows
   with approve / deny actions; denying deletes the transcript. */
/* Only space it off when it actually holds content — the wrapper always renders
   (it's a live-update target) and its ERB leaves whitespace, so it's never truly
   :empty; :has(*) keys off real element children instead. */
.dash-transcripts:has(*) { margin-bottom: var(--sp-6); }
.tr-list { display: flex; flex-direction: column; }
.tr-item {
  display: flex; align-items: center; gap: var(--sp-4);
  padding: var(--sp-3) 0; border-bottom: 1px solid var(--line);
}
.tr-item__hit {
  flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px;
  text-decoration: none; color: inherit;
}
.tr-item__title {
  font-size: var(--fs-4); font-weight: 600; color: var(--ink);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.tr-item__hit:hover .tr-item__title { color: var(--accent); }
.tr-item__meta {
  font-family: var(--read); font-size: var(--fs-3); color: var(--muted);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.tr-item__actions { display: flex; align-items: center; gap: var(--sp-2); flex: none; }
.tr-act-form { margin: 0; }
.tr-act {
  display: grid; place-items: center; width: 30px; height: 30px;
  border: 1px solid var(--line-2); border-radius: 8px; background: var(--panel);
  color: var(--muted); cursor: pointer; transition: color .12s, background .12s, border-color .12s;
}
.tr-act--ok:hover { color: var(--white); background: var(--green); border-color: var(--green); }
.tr-act--no:hover { color: var(--white); background: var(--red); border-color: var(--red); }
