/* Self-hosted (see server.js's CSP comment: no third-party fonts/CDNs) --
   Inter ships as one variable-font file, so all four weights below point
   at the same file; the browser snaps to the named instance per weight. */
@font-face {
  font-family: "Cormorant Garamond";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("fonts/cormorant-garamond-600.woff2") format("woff2");
}
@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url("fonts/inter-variable.woff2") format("woff2");
}

:root {
  color-scheme: light dark;
  --ink: #141312;
  --page-bg: #f7f4ec;
  --surface: #ffffff;
  --head-bg: rgba(20, 19, 18, 0.04);
  --border: #e6ddc9;
  --border-soft: rgba(20, 19, 18, 0.06);
  --muted: #726b5d;
  --accent: #b1502f;
  --accent-text: #b1502f;
  --accent-soft: rgba(177, 80, 47, 0.1);
  --good: #1f7a34;
  --good-soft: rgba(31, 122, 52, 0.1);
  --critical: #ae3131;
  --critical-soft: rgba(174, 49, 49, 0.1);
}
/* Three states: system dark (unless explicitly overridden to light),
   and an explicit dark override that wins even on a light system --
   [data-theme] is set by theme.js from the toggle in the sidebar/header. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --ink: #f7f4ec;
    --page-bg: #141312;
    --surface: #1d1b17;
    --head-bg: #242119;
    --border: #35322b;
    --border-soft: rgba(247, 244, 236, 0.08);
    --muted: #bcb2a0;
    --accent: #d97a54;
    --accent-text: #d97a54;
    --accent-soft: rgba(217, 122, 84, 0.16);
    --good: #7fd39a;
    --good-soft: rgba(76, 175, 106, 0.18);
    --critical: #e07a7a;
    --critical-soft: rgba(224, 122, 122, 0.15);
  }
}
:root[data-theme="dark"] {
  --ink: #f7f4ec;
  --page-bg: #141312;
  --surface: #1d1b17;
  --head-bg: #242119;
  --border: #35322b;
  --border-soft: rgba(247, 244, 236, 0.08);
  --muted: #bcb2a0;
  --accent: #d97a54;
  --accent-text: #d97a54;
  --accent-soft: rgba(217, 122, 84, 0.16);
  --good: #7fd39a;
  --good-soft: rgba(76, 175, 106, 0.18);
  --critical: #e07a7a;
  --critical-soft: rgba(224, 122, 122, 0.15);
}

/* Aliases onto the main brand tokens (:root, above) rather than its own
   fixed values -- these already flip for dark mode via that block's own
   media query, so .viz-root automatically follows without a duplicate
   light/dark split here. */
.viz-root {
  color-scheme: light dark;
  --chart-surface: var(--surface);
  --chart-text-primary: var(--ink);
  --chart-text-secondary: var(--muted);
  --chart-text-muted: var(--muted);
  --chart-gridline: var(--border);
  --chart-axis: var(--border);
  --status-good: var(--good);
  --status-critical: var(--critical);
}

* { box-sizing: border-box; }

body {
  margin: 0;
  font-family: "Inter", system-ui, -apple-system, "Segoe UI", sans-serif;
  background: var(--page-bg);
  color: var(--ink);
}

a {
  color: var(--accent);
}

a:hover {
  color: var(--accent-text);
  opacity: 0.8;
}

.layout {
  display: flex;
  min-height: 100vh;
}

.sidebar {
  width: 240px;
  flex-shrink: 0;
  background: var(--surface);
  border-right: 1px solid var(--border);
  padding: 16px 14px;
  display: flex;
  flex-direction: column;
}

.sidebar h1 {
  font-size: 1.1rem;
  margin: 0 0 12px;
}

.sidebar-brand {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 16px;
  padding: 0 4px;
}

/* Hidden on desktop (see the @media block near the end of this file) --
   there's no sidebar to collapse when it's already fully visible. */
.mobile-nav-toggle {
  display: none;
  margin-left: auto;
  width: 32px;
  height: 32px;
  align-items: center;
  justify-content: center;
  background: none;
  border: 1px solid var(--border);
  border-radius: 6px;
  font-size: 1rem;
  color: inherit;
  cursor: pointer;
  flex-shrink: 0;
}

.brand-mark {
  width: 18px;
  height: 35px;
  flex-shrink: 0;
  display: flex;
}

.brand-mark svg {
  display: block;
}

.brand-mark .mark-lock-stroke { fill: none; stroke: var(--accent); stroke-width: 6.5; }
.brand-mark .mark-lock-body { fill: var(--accent); }
.brand-mark .mark-keyhole { fill: var(--page-bg); }
.brand-mark .mark-handset { fill: var(--ink); }

.brand-name {
  font-family: "Cormorant Garamond", serif;
  font-weight: 600;
  font-size: 1.2rem;
  letter-spacing: 0.01em;
  color: var(--ink);
}

.brand-name .brand-name-accent {
  color: var(--accent);
}

#search,
.view-as {
  width: 100%;
  padding: 8px 10px;
  border: 1px solid var(--border);
  border-radius: 6px;
  font-size: 0.9rem;
}

.view-as {
  margin-bottom: 8px;
}

.content-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px 12px;
  margin-bottom: 14px;
}

.page-title {
  font-size: 1.1rem;
  font-weight: 700;
}

.content-header-right {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  row-gap: 6px;
  gap: 12px;
}

.content-header .session-bar {
  margin-bottom: 0;
}

.theme-toggle {
  padding: 5px 12px;
  border: 1px solid var(--border);
  border-radius: 100px;
  background: var(--surface);
  color: inherit;
  font-size: 0.8rem;
  white-space: nowrap;
  cursor: pointer;
}

.theme-toggle:hover {
  background: var(--head-bg);
}

/* Login/account-canceled have no header bar to dock the toggle in --
   a fixed corner placement instead. */
.theme-toggle-corner {
  position: fixed;
  top: 16px;
  right: 16px;
}

.contact-list {
  list-style: none;
  margin: 12px 0 0;
  padding: 0;
}

.contact-list li {
  padding: 8px 10px;
  border-radius: 6px;
  cursor: pointer;
}

.contact-list li:hover,
.contact-list li.active {
  background: rgba(127, 127, 127, 0.15);
}

/* Unscoped so every contact-name-plus-phone pairing stacks the same way,
   including the dashboard table's contact cell, which used to have no
   matching rule at all (bare class, only scoped selectors existed) and so
   ran the name and phone together with no separation. */
.contact-phone {
  display: block;
  font-size: 0.8rem;
  color: var(--muted);
}

.search-wrap {
  position: relative;
}

.search-results {
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  z-index: 10;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 6px;
  margin-top: 4px;
  max-height: 260px;
  overflow-y: auto;
  box-shadow: 0 4px 10px rgba(0, 0, 0, 0.08);
  list-style: none;
  padding: 4px;
}

.search-result-item {
  padding: 7px 8px;
  border-radius: 5px;
  cursor: pointer;
  font-size: 0.85rem;
}

.search-result-item:hover {
  background: rgba(127, 127, 127, 0.15);
}

.search-result-item .contact-phone {
  display: block;
  font-size: 0.78rem;
  color: var(--muted);
}

.search-empty {
  padding: 7px 8px;
  font-size: 0.85rem;
  color: var(--muted);
}

.account-switcher-wrap {
  margin-top: 14px;
  padding-top: 12px;
  border-top: 1px solid var(--border);
}

.account-switcher-label {
  display: block;
  font-size: 0.78rem;
  color: var(--muted);
  margin-bottom: 4px;
}

.account-switcher {
  width: 100%;
  padding: 8px 10px;
  border: 1px solid var(--border);
  border-radius: 6px;
  font-size: 0.9rem;
  font-weight: 600;
  background: var(--surface);
}

.sidebar-nav {
  display: flex;
  flex-direction: column;
  gap: 2px;
  margin-top: 14px;
}

.nav-link {
  display: block;
  padding: 8px 10px;
  border-radius: 6px;
  color: inherit;
  text-decoration: none;
  font-size: 0.9rem;
}

.nav-link:hover {
  background: rgba(127, 127, 127, 0.12);
}

.nav-link.active {
  background: var(--accent-soft);
  color: var(--accent-text);
  font-weight: 600;
}

/* Deliberately not the client brand palette -- this is the operator's
   own cross-tenant view (see public/operator.html), not another client
   page, and it needs to be unmistakable at a glance that switching accent
   colors alone wouldn't achieve as clearly. A distinct dark sidebar
   regardless of light/dark theme, a different accent hue than the
   terracotta client brand uses anywhere, and an explicit badge -- not
   just a color a colorblind viewer might not register as "different." */
.sidebar--operator {
  background: #1b2430;
  border-right: 1px solid #2a3542;
  color: #e8ecf1;
}
.sidebar--operator .brand-name,
.sidebar--operator .mobile-nav-toggle,
.sidebar--operator .nav-link {
  color: #e8ecf1;
}
.sidebar--operator .brand-name .brand-name-accent {
  color: #7dd3fc;
}
.sidebar--operator .brand-mark .mark-lock-stroke { stroke: #7dd3fc; }
.sidebar--operator .brand-mark .mark-lock-body { fill: #7dd3fc; }
.sidebar--operator .brand-mark .mark-keyhole { fill: #1b2430; }
.sidebar--operator .brand-mark .mark-handset { fill: #e8ecf1; }
.sidebar--operator .nav-link:hover {
  background: rgba(255, 255, 255, 0.08);
}
.sidebar--operator .nav-link.active {
  background: rgba(125, 211, 252, 0.16);
  color: #7dd3fc;
}
.operator-badge {
  display: inline-block;
  margin-left: 6px;
  padding: 1px 7px;
  border-radius: 100px;
  background: rgba(125, 211, 252, 0.16);
  color: #7dd3fc;
  font-size: 0.65rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.admin-nav {
  margin-top: 14px;
  padding-top: 12px;
  border-top: 1px solid var(--border);
}

.view-as-label {
  display: block;
  font-size: 0.78rem;
  color: var(--muted);
  margin-bottom: 4px;
}

.content {
  flex: 1;
  padding: 18px 28px;
}

.empty-state {
  color: var(--muted);
}

.filter-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px;
  margin-bottom: 14px;
  padding: 10px 16px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 10px;
}

.filter-bar-left {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  flex-shrink: 0;
}

/* Shown only when viewing one contact's calls (or a Coverage-report
   recording-status deep link) -- its own row with real spacing, instead of
   being crammed into the filter bar next to unrelated controls. */
.contact-context {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 14px;
  padding: 10px 14px;
  background: var(--accent-soft);
  border: 1px solid var(--border);
  border-radius: 8px;
}

.back-btn {
  border: none;
  background: none;
  color: var(--accent);
  font-weight: 600;
  font-size: 0.9rem;
  cursor: pointer;
  padding: 0;
}

.back-btn:hover {
  text-decoration: underline;
}

.contact-context-name {
  font-size: 0.85rem;
  color: var(--muted);
}

.filter-dates {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
}

.filter-dates label {
  display: flex;
  align-items: center;
  gap: 4px;
  font-size: 0.85rem;
  color: var(--muted);
}

.filter-dates input[type="date"] {
  padding: 5px 6px;
  border: 1px solid var(--border);
  border-radius: 6px;
  font-size: 0.85rem;
}

.preset-group {
  display: flex;
  gap: 2px;
  padding: 3px;
  background: rgba(127, 127, 127, 0.1);
  border-radius: 8px;
}

.preset-btn {
  padding: 6px 9px;
  border: 1px solid transparent;
  border-radius: 6px;
  background: none;
  color: var(--muted);
  font-size: 0.85rem;
  cursor: pointer;
}

.preset-btn.active {
  background: var(--surface);
  color: inherit;
  font-weight: 600;
}

.outcome-badge {
  display: inline-flex;
  padding: 3px 9px;
  border-radius: 100px;
  font-size: 0.78rem;
  font-weight: 600;
  white-space: nowrap;
}

/* Per-outcome colors as fixed classes rather than inline styles: the CSP
   here has no 'unsafe-inline' for style-src, so a dynamically computed
   style="" attribute is silently dropped by the browser. */
.outcome-completed { background: var(--good-soft); color: var(--good); }
.outcome-no-answer { background: var(--border-soft); color: var(--muted); }
.outcome-voicemail { background: var(--accent-soft); color: var(--accent-text); }
.outcome-busy { background: rgba(250, 178, 25, 0.2); color: #8a5a00; }
.outcome-canceled { background: var(--critical-soft); color: var(--critical); }
.outcome-default { background: var(--border-soft); color: var(--muted); }

/* Discrete width/height buckets for bars whose fill is computed from data
   (rep leaderboard bars, trend chart, inbound/outbound mix). Same CSP
   constraint as above rules out inline style="width:…" / "height:…", so
   JS rounds each value to the nearest of these fixed steps instead. */
.w-0 { width: 0%; }
.w-10 { width: 10%; }
.w-20 { width: 20%; }
.w-30 { width: 30%; }
.w-40 { width: 40%; }
.w-50 { width: 50%; }
.w-60 { width: 60%; }
.w-70 { width: 70%; }
.w-80 { width: 80%; }
.w-90 { width: 90%; }
.w-100 { width: 100%; }

.empty-state-pad {
  padding: 18px;
}

.page-size-label {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 0.85rem;
  color: var(--muted);
}

/* Direction/Outcome selects: same look as .page-size-label but WITHOUT its
   margin-left: auto -- two auto-margin siblings in one flex row split the
   row's leftover space between them, which is what pushed these two apart
   with a huge gap instead of sitting together. */
.filter-select-label {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 0.85rem;
  color: var(--muted);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 5px 8px;
}

.filter-select-label select {
  border: none;
  background: none;
  padding: 0;
  font-size: 0.85rem;
  font-weight: 500;
  color: inherit;
}

.filter-divider {
  width: 1px;
  height: 20px;
  background: var(--border);
}

.page-size-label select {
  padding: 5px 6px;
  border: 1px solid var(--border);
  border-radius: 6px;
  font-size: 0.85rem;
}

.results-summary {
  margin-left: auto;
  font-size: 0.85rem;
  color: var(--muted);
  white-space: nowrap;
}

.pagination {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 10px;
  margin-top: 12px;
  font-size: 0.85rem;
}

.pagination-divider {
  color: var(--border);
}

.pagination button {
  padding: 6px 12px;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: none;
  color: inherit;
  cursor: pointer;
}

.pagination button:disabled {
  opacity: 0.5;
  cursor: default;
}

.calls-table {
  table-layout: fixed;
}

table {
  width: 100%;
  border-collapse: separate;
  border-spacing: 0;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 10px;
  overflow: hidden;
}

th, td {
  text-align: left;
  padding: 10px 18px;
  border-bottom: 1px solid var(--border);
  font-size: 0.9rem;
}

thead {
  background: rgba(127, 127, 127, 0.06);
}

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

.recording-audio {
  display: none;
}

.recording-cell {
  display: flex;
  align-items: center;
  gap: 9px;
}

.play-btn {
  display: flex;
  align-items: center;
  gap: 9px;
  border: 1px solid var(--border);
  border-radius: 100px;
  padding: 5px 10px;
  background: var(--surface);
  color: var(--muted);
  font-size: 0.75rem;
  font-variant-numeric: tabular-nums;
  cursor: pointer;
}

.play-btn:hover {
  border-color: var(--muted);
}

.play-icon,
.pause-icon {
  fill: var(--accent);
  flex-shrink: 0;
}

/* The `hidden` attribute doesn't reliably suppress rendering on inline
   <svg> in every browser (its default UA stylesheet doesn't always carry
   the [hidden] { display: none } rule HTML elements get), so force it. */
.play-icon[hidden],
.pause-icon[hidden] {
  display: none;
}

.download-link {
  font-size: 0.85rem;
  white-space: nowrap;
}

.transcript-details summary {
  cursor: pointer;
  font-size: 0.85rem;
}

.transcribe-btn {
  padding: 4px 8px;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: none;
  color: inherit;
  font-size: 0.85rem;
  cursor: pointer;
}

.transcribe-btn:disabled {
  opacity: 0.6;
  cursor: default;
}

/* Team members table row actions (link-ghl-btn = "Save", reset-btn =
   "Reset password", delete-btn = "Delete") had no matching rules at all,
   so they fell back to raw browser default button chrome -- the one spot
   left looking unstyled next to everything else on the page. */
.ghl-link-select {
  padding: 5px 6px;
  border: 1px solid var(--border);
  border-radius: 6px;
  font-size: 0.82rem;
  max-width: 220px;
}

.link-ghl-btn,
.reset-btn {
  padding: 5px 10px;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: var(--surface);
  color: inherit;
  font-size: 0.82rem;
  cursor: pointer;
}

.link-ghl-btn:hover,
.reset-btn:hover {
  border-color: var(--muted);
  background: rgba(0, 0, 0, 0.03);
}

.delete-btn {
  padding: 5px 10px;
  border: 1px solid rgba(208, 59, 59, 0.3);
  border-radius: 6px;
  background: rgba(208, 59, 59, 0.06);
  color: #a52e2e;
  font-size: 0.82rem;
  cursor: pointer;
}

.delete-btn:hover {
  background: rgba(208, 59, 59, 0.12);
}

.transcript-text {
  margin: 6px 0 0;
  font-size: 0.85rem;
  color: var(--muted);
  max-width: 320px;
  white-space: pre-wrap;
}

.transcript-pending,
.transcript-failed {
  font-size: 0.85rem;
  color: var(--muted);
}

.login-page {
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
}

.login-card {
  width: 280px;
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 24px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 8px;
}

.login-brand {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  margin: 0 0 4px;
}

.login-brand .brand-mark {
  width: 23px;
  height: 44px;
}

.login-brand .brand-name {
  font-size: 1.5rem;
}

.login-card label {
  display: flex;
  flex-direction: column;
  gap: 4px;
  font-size: 0.85rem;
}

.login-card input {
  padding: 8px 10px;
  border: 1px solid var(--border);
  border-radius: 6px;
  font-size: 0.9rem;
}

.login-card button {
  padding: 9px;
  border: none;
  border-radius: 6px;
  background: var(--accent);
  color: #fff;
  font-size: 0.9rem;
  cursor: pointer;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .login-card button { color: var(--ink); }
}
:root[data-theme="dark"] .login-card button { color: var(--ink); }

.login-error {
  color: #c00;
  font-size: 0.85rem;
}

.cancel-card {
  width: 340px;
}

.cancel-card #restore-btn {
  padding: 9px;
  border: none;
  border-radius: 6px;
  background: var(--accent);
  color: #fff;
  font-size: 0.9rem;
  cursor: pointer;
}

.cancel-card #logout-form {
  margin-top: 4px;
  text-align: center;
}

.cancellation-banner {
  margin-bottom: 14px;
  padding: 10px 14px;
  border: 1px solid rgba(208, 59, 59, 0.3);
  border-radius: 8px;
  background: rgba(208, 59, 59, 0.06);
  color: #a02a2a;
  font-size: 0.88rem;
}

.danger-zone {
  margin-top: 28px;
  padding: 16px 18px;
  border: 1px solid rgba(208, 59, 59, 0.3);
  border-radius: 10px;
  background: rgba(208, 59, 59, 0.03);
}

.danger-zone h2 {
  margin-top: 0;
  color: #d03b3b;
}

.recovery-codes {
  font-family: ui-monospace, "SF Mono", "Cascadia Code", Consolas, monospace;
  font-size: 0.95rem;
  line-height: 1.8;
  padding: 14px 18px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--surface);
  white-space: pre-wrap;
}

#mfa-qr {
  display: block;
  margin: 10px 0;
  border-radius: 8px;
  background: #fff;
  padding: 8px;
}

#cancel-confirm {
  margin-top: 12px;
  padding-top: 12px;
  border-top: 1px solid rgba(208, 59, 59, 0.2);
}

#cancel-confirm-input {
  display: block;
  margin: 6px 0 10px;
  padding: 7px 8px;
  border: 1px solid var(--border);
  border-radius: 6px;
  font-size: 0.9rem;
  width: 220px;
}

.account-success {
  color: #16794f;
}

.forgot-password {
  margin: 0;
  text-align: center;
  font-size: 0.8rem;
  color: var(--muted);
}

.session-bar {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 14px;
  margin-bottom: 12px;
  font-size: 0.85rem;
  color: var(--muted);
}

.session-bar a {
  color: inherit;
  white-space: nowrap;
}

.session-bar form {
  margin: 0;
}

.session-bar button {
  border: none;
  background: none;
  color: inherit;
  text-decoration: underline;
  font-size: inherit;
  white-space: nowrap;
  cursor: pointer;
  padding: 0;
}

.admin-page {
  max-width: 720px;
  margin: 0 auto;
  padding: 24px;
}

.coverage-page {
  max-width: 960px;
}

.chart-card {
  margin: 20px 0 28px;
  padding: 16px 18px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--chart-surface);
  color: var(--chart-text-primary);
}

.chart-card h2 {
  margin: 0 0 6px;
  font-size: 1rem;
}

.chart-card .settings-note {
  color: var(--chart-text-secondary);
}

.chart-wrap {
  position: relative;
  margin-top: 12px;
}

.month-chart {
  width: 100%;
  height: 260px;
  display: block;
  overflow: visible;
}

.chart-legend {
  display: flex;
  gap: 18px;
  margin-top: 10px;
  font-size: 0.85rem;
  color: var(--chart-text-secondary);
}

.legend-item {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}

.legend-swatch {
  width: 10px;
  height: 10px;
  border-radius: 2px;
  display: inline-block;
}

/* Fixed swatch colors as classes instead of inline style="background:…":
   same CSP constraint as the other rules above (no 'unsafe-inline' for
   style-src). Also fixes the Inbound swatch, which was still the old
   pre-redesign blue (#2563eb) instead of --accent. */
.legend-swatch-inbound { background: var(--accent); }
.legend-swatch-outbound { background: var(--ink); }
.legend-swatch-good { background: var(--status-good); }
.legend-swatch-critical { background: var(--status-critical); }

/* One-off layout tweaks that were inline style="" attributes, blocked by
   the same CSP constraint. */
.content-header-end { justify-content: flex-end; }
#report-presets { width: fit-content; margin-bottom: 16px; }
.rep-bars-card-narrow { max-width: 620px; }
.chart-legend-mt { margin-top: 10px; }

.chart-tooltip {
  position: absolute;
  pointer-events: none;
  background: var(--chart-text-primary);
  color: var(--chart-surface);
  font-size: 0.8rem;
  padding: 6px 10px;
  border-radius: 6px;
  white-space: nowrap;
  transform: translate(-50%, -100%);
  z-index: 5;
}

.chart-tooltip .tooltip-value {
  font-weight: 700;
}

.chart-bar-hit {
  fill: transparent;
  cursor: pointer;
}

.month-chart g:hover .chart-bar-seg,
.month-chart g:focus-within .chart-bar-seg {
  opacity: 0.85;
}

.chart-gridline {
  stroke: var(--chart-gridline);
  stroke-width: 1;
}

.chart-axis-label {
  fill: var(--chart-text-muted);
  font-size: 10px;
}

.clickable-row {
  cursor: pointer;
}

.clickable-row:hover {
  background: var(--chart-gridline, rgba(0, 0, 0, 0.04));
}

.settings-section {
  margin: 20px 0;
  padding: 14px 16px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 8px;
}

/* --- Contacts (A-Z) page --- */

.contacts-page {
  display: flex;
  flex-direction: column;
  height: calc(100vh - 24px * 2);
}

.az-strip {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  margin-bottom: 14px;
  padding: 10px 12px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 10px;
}

.az-letter {
  width: 26px;
  height: 26px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 6px;
  font-size: 0.8rem;
  font-weight: 600;
  color: var(--muted);
  text-decoration: none;
}

.az-letter.has-contacts {
  color: var(--accent-text);
  background: var(--accent-soft);
}

.contact-groups {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 10px;
  overflow-y: auto;
  flex: 1;
}

.contact-group-header {
  padding: 7px 18px;
  background: rgba(127, 127, 127, 0.06);
  border-bottom: 1px solid var(--border);
  font-size: 0.72rem;
  font-weight: 700;
  color: var(--muted);
  position: sticky;
  top: 0;
}

.contact-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 10px 18px;
  border-bottom: 1px solid var(--border);
  cursor: pointer;
  text-decoration: none;
  color: inherit;
}

.contact-row:hover {
  background: rgba(127, 127, 127, 0.08);
}

.contact-row-name {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 0.9rem;
  font-weight: 500;
}

.contact-avatar {
  width: 28px;
  height: 28px;
  border-radius: 100px;
  background: var(--accent-soft);
  color: var(--accent-text);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 0.7rem;
  font-weight: 700;
  flex-shrink: 0;
}

.contact-row-meta {
  display: flex;
  align-items: center;
  gap: 18px;
  font-size: 0.8rem;
  color: var(--muted);
}

/* --- Settings: tabbed layout --- */

.settings-layout {
  display: flex;
  flex: 1;
}

.settings-tabs-col {
  width: 220px;
  flex-shrink: 0;
  background: var(--surface);
  border-right: 1px solid var(--border);
  padding: 20px 14px;
}

.settings-tabs-col h1 {
  font-size: 1.05rem;
  margin: 0 0 16px;
  padding: 0 6px;
}

.settings-content {
  flex: 1;
  padding: 24px 32px;
  max-width: 900px;
}

/* --- Call report tab --- */

.rep-bars-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 16px 18px;
  margin-bottom: 14px;
}

.rep-bars-card h3 {
  margin: 0 0 14px;
  font-size: 0.9rem;
}

.rep-bar-row {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 7px 4px;
  cursor: pointer;
  border-radius: 6px;
}

.rep-bar-row:hover {
  background: rgba(127, 127, 127, 0.08);
}

.rep-bar-name {
  width: 130px;
  flex-shrink: 0;
  font-size: 0.85rem;
}

.rep-bar-track {
  flex-grow: 1;
  background: rgba(127, 127, 127, 0.12);
  border-radius: 4px;
  height: 14px;
  overflow: hidden;
}

.rep-bar-fill {
  height: 100%;
  background: var(--accent);
  border-radius: 4px;
}

.rep-bar-total {
  width: 40px;
  text-align: right;
  font-size: 0.85rem;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}

.rep-back-link {
  font-size: 0.85rem;
  cursor: pointer;
  margin-bottom: 8px;
  display: inline-block;
}

.rep-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-bottom: 16px;
}

.rep-chip {
  padding: 6px 12px;
  border-radius: 100px;
  font-size: 0.82rem;
  border: 1px solid var(--border);
  background: none;
  color: inherit;
  cursor: pointer;
}

.rep-chip.active {
  background: var(--accent-soft);
  color: var(--accent-text);
  border-color: var(--accent);
  font-weight: 600;
}

.mix-bar {
  display: flex;
  width: 100%;
  height: 16px;
  border-radius: 100px;
  overflow: hidden;
}

.mix-bar-inbound {
  background: var(--accent);
}

.mix-bar-outbound {
  background: var(--ink);
}

.stat-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 12px;
  margin: 16px 0 24px;
}

.stat-tile {
  padding: 14px 16px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 8px;
}

.stat-tile-link {
  display: block;
  color: inherit;
  text-decoration: none;
  cursor: pointer;
}

.stat-tile-link:hover {
  border-color: var(--muted);
  background: rgba(0, 0, 0, 0.03);
}

.stat-value {
  font-size: 1.5rem;
  font-weight: 600;
}

.stat-label {
  font-size: 0.85rem;
  color: var(--muted);
  margin-top: 4px;
}

.stat-compare {
  font-size: 0.75rem;
  color: var(--muted);
  margin-top: 6px;
}

.settings-section h2 {
  margin: 0 0 10px;
  font-size: 1rem;
}

.toggle-row {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 0.9rem;
  cursor: pointer;
}

.settings-note {
  margin: 8px 0 0;
  font-size: 0.8rem;
  color: var(--muted);
}

.account-access-details summary {
  cursor: pointer;
  font-size: 0.85rem;
  color: var(--accent-text);
}

.account-access-list {
  display: flex;
  flex-direction: column;
  gap: 4px;
  margin: 8px 0;
  padding: 8px;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: var(--surface);
}

.account-access-option {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 0.85rem;
}

.admin-form {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  align-items: flex-end;
  margin-top: 12px;
}

.admin-form label {
  display: flex;
  flex-direction: column;
  gap: 4px;
  font-size: 0.85rem;
}

.admin-form input,
.admin-form select {
  padding: 7px 8px;
  border: 1px solid var(--border);
  border-radius: 6px;
  font-size: 0.9rem;
}

.admin-form button {
  padding: 8px 14px;
  border: none;
  border-radius: 6px;
  background: var(--accent);
  color: #fff;
  cursor: pointer;
  height: 34px;
}

.button-link {
  display: inline-block;
  padding: 8px 14px;
  border: none;
  border-radius: 6px;
  background: var(--accent);
  color: #fff;
  text-decoration: none;
  font: inherit;
  font-size: 0.9rem;
  cursor: pointer;
}

.button-link:disabled {
  opacity: 0.6;
  cursor: default;
}

/* --- Mobile (phone-width) layout ---
   Nothing below this point exists on desktop -- there was previously no
   responsive handling at all, so a phone (~390px CSS width) rendered the
   fixed 240px sidebar + wide table/filter-bar exactly as sized for
   desktop. Since the table cells and filter controls don't have room to
   shrink that far without overflowing, the page's own layout viewport
   grew to fit them (well past the physical screen width), which is what
   actually causes the "zoomed out, everything tiny and overlapping"
   mess on a phone -- not just "things looked cramped." overflow-x:hidden
   on body plus overflow-x:auto on the two content containers below stop
   that from happening again even if some future addition doesn't fit. */
body {
  overflow-x: hidden;
}

@media (max-width: 860px) {
  .layout {
    flex-direction: column;
    min-height: auto;
  }

  /* Sticky so the operator page's dark navy/badge cue (the whole point of
     .sidebar--operator) doesn't scroll out of view the moment you look at
     the actual account data -- which is every time, since that's the page's
     content. Sticks relative to the page's own scroll container; nothing
     else on the page uses position:fixed/sticky at a higher z-index. */
  .sidebar {
    width: 100%;
    border-right: none;
    border-bottom: 1px solid var(--border);
    padding: 12px 14px;
    position: sticky;
    top: 0;
    z-index: 20;
  }

  .sidebar-brand {
    margin-bottom: 0;
  }

  .mobile-nav-toggle {
    display: flex;
  }

  /* Collapsed by default -- expanded via .nav-open (toggled by
     #mobile-nav-toggle in app.js/contacts.js/settings.js). The
     :not([hidden]) guard on account-switcher-wrap/admin-nav matters: both
     are conditionally hidden by JS already (single-account deployments,
     non-admin logins) via the hidden ATTRIBUTE, and a plain class
     selector here would otherwise have higher specificity than the
     browser's default [hidden] rule and silently un-hide them regardless
     of that JS-driven state -- the same class of bug the play/pause icon
     fix in app.js ran into earlier with SVG elements. */
  .sidebar > .search-wrap,
  .sidebar > .sidebar-nav {
    display: none;
  }
  .sidebar > .account-switcher-wrap:not([hidden]),
  .sidebar > .admin-nav:not([hidden]) {
    display: none;
  }
  .sidebar.nav-open > .search-wrap {
    display: block;
    margin-top: 12px;
  }
  .sidebar.nav-open > .sidebar-nav {
    display: flex;
    margin-top: 12px;
  }
  .sidebar.nav-open > .account-switcher-wrap:not([hidden]),
  .sidebar.nav-open > .admin-nav:not([hidden]) {
    display: block;
    margin-top: 12px;
  }

  .content {
    width: 100%;
    padding: 14px 16px;
  }

  /* .filter-bar-left's flex-shrink:0 (needed on desktop so it never gets
     squeezed by .results-summary's margin-left:auto) fights its own
     flex-wrap:wrap on a narrow screen: flex-shrink:0 keeps it at its full
     max-content width instead of ever being narrowed down to the
     viewport, so its own children never actually get pushed onto new
     lines -- the box just grows past the screen edge instead. Letting it
     shrink (and take the full row's width) here is what makes the wrap
     actually happen. */
  .filter-bar-left {
    flex-shrink: 1;
    width: 100%;
  }

  /* Every table on the site (the calls table, and every table in
     Settings) becomes a stack of cards instead of forcing a horizontal
     scroll: each <tr> is its own bordered card, and each <td> shows its
     own column header as a label (via the data-label attribute set on
     the <td> itself where each table is rendered -- see renderCalls() in
     app.js and the various loadX() functions in settings.js) instead of
     depending on a <thead> row that no longer makes sense once there's
     no grid of columns left to label. This replaces the earlier
     "min-width + scroll sideways" approach: that kept text from
     overlapping, but the user still had to scroll right to read a
     recording status or an outcome, which isn't actually fixed -- this
     makes every value visible without scrolling in either direction. */
  table thead {
    display: none;
  }
  table, table tbody, table tr, table td {
    display: block;
    width: 100%;
  }
  table {
    border: none;
    background: none;
    border-spacing: 0;
  }
  table tr {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 10px;
    margin-bottom: 10px;
    padding: 4px 14px;
  }
  table td {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 4px;
    padding: 8px 0;
    border-bottom: 1px solid var(--border);
    font-size: 0.9rem;
    text-align: left;
  }
  table td:last-child {
    border-bottom: none;
  }
  /* A cell with no data-label (an empty-state row spanning every column,
     e.g. "No calls match this filter.") is already its own message and
     doesn't need a label in front of it -- only cells the JS explicitly
     tagged (see renderCalls() in app.js, the loadX() functions in
     settings.js) get one. */
  table td[data-label]::before {
    content: attr(data-label);
    font-weight: 600;
    color: var(--muted);
    font-size: 0.78rem;
  }

  .content-header {
    flex-wrap: wrap;
    row-gap: 6px;
  }

  .settings-layout {
    flex-direction: column;
  }

  .settings-tabs-col {
    width: 100%;
    border-right: none;
    border-bottom: 1px solid var(--border);
    padding: 12px 14px;
  }

  /* Redundant with the page's own content-header title once the tabs
     column is a slim horizontal strip instead of a full sidebar. */
  .settings-tabs-col > h1 {
    display: none;
  }

  #settings-tabs {
    flex-direction: row;
    flex-wrap: nowrap;
    overflow-x: auto;
    gap: 6px;
    margin-top: 0;
  }

  #settings-tabs .nav-link {
    white-space: nowrap;
  }

  .settings-content {
    width: 100%;
    max-width: 100%;
    padding: 14px 16px;
    overflow-x: auto;
  }
}
