@import url("https://fonts.googleapis.com/css2?family=DM+Sans:wght@400;500;700&family=DM+Serif+Display&family=JetBrains+Mono:wght@400;600&display=swap");

:root {
  --admin-bg: #0a0a0b;
  --admin-surface: #141416;
  --admin-surface-hover: #1a1a1e;
  --admin-border: #1e1e22;
  --admin-text: #e4e4e7;
  --admin-text-secondary: #a1a1aa;
  --admin-text-muted: #52525b;
  /* Ch13 — FALLBACK ONLY. Every admin page is served through
     _serve_branded_html now, which emits a <style data-tenant-branding> block
     after this file and wins the cascade, so these two are what an admin page
     would look like with no injection at all. Retargeted from the AloeVoice
     green/coral to the platform identity (RoyalVoice), because the admin
     surface belongs to the platform — this file is loaded by the 14 admin
     pages and nothing else. */
  --color-primary: #2271b1;
  --color-accent: #72aee6;
  --radius-sm: 6px;
  --radius-md: 10px;
  --shadow-md: 0 4px 12px rgba(0, 0, 0, 0.3);
  /* admin.css does not load variables.css, so --shadow-lg did not exist here
     and `box-shadow: var(--shadow-lg)` computed to none. Derived from the md
     value above on the same ratio variables.css uses for its own md -> lg step
     (offset and blur doubled, alpha x1.5), not eyeballed. Used by the shared
     box hover state at the end of this file. */
  --shadow-lg: 0 8px 24px rgba(0, 0, 0, 0.45);
  /* Approval gate (2026-09-11) — the Onboarding badge/filter/block colour.
     A fixed platform blue (the --color-primary fallback value) and NOT
     var(--color-primary) itself: that one is overridden per tenant by the
     branding injection, and a status colour must mean the same thing on every
     tenant's admin. */
  --admin-status-onboarding: #2271b1;
  --font-display: "DM Serif Display", Georgia, serif;
  --font-body: "DM Sans", -apple-system, sans-serif;
  --font-mono: "JetBrains Mono", monospace;
}

* { box-sizing: border-box; }

body.admin-page {
  margin: 0;
  min-height: 100vh;
  font-family: var(--font-body);
  background: var(--admin-bg);
  color: var(--admin-text);
}

.admin-login-wrap {
  min-height: 100vh;
  display: grid;
  place-items: center;
  padding: 24px;
}

.admin-login-card {
  width: min(430px, 100%);
  background: var(--admin-surface);
  border: 1px solid var(--admin-border);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-md);
  padding: 24px;
}

/* Ch13 — the tenant logo sits on a light plate inside this near-black card.
   Every logo we hold is a dark-ink wordmark drawn for a white background, so
   dropped straight onto --admin-surface it is invisible. Plate, not recolour:
   we never alter a tenant's artwork. `hidden` until the image actually loads,
   so a 404 or a slow fetch leaves no empty box. */
.admin-login-logo-plate {
  display: grid;
  place-items: center;
  width: fit-content;
  margin: 0 auto 14px;
  padding: 10px 14px;
  background: #fff;
  border-radius: var(--radius-sm);
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.35), 0 6px 18px rgba(0, 0, 0, 0.28);
}
.admin-login-logo-plate[hidden] { display: none; }
.admin-login-logo-plate img {
  display: block;
  max-height: 46px;
  max-width: 210px;
}

.admin-logo {
  margin: 0 0 6px;
  font-family: var(--font-display);
  color: var(--color-primary);
}

.admin-subtitle {
  margin: 0 0 18px;
  color: var(--admin-text-secondary);
}

.admin-field {
  display: grid;
  gap: 6px;
  margin-bottom: 12px;
}

.admin-field span {
  font-size: 13px;
  color: var(--admin-text-secondary);
}

.admin-input {
  width: 100%;
  border: 1px solid var(--admin-border);
  border-radius: var(--radius-sm);
  background: #0f0f11;
  color: var(--admin-text);
  padding: 10px 11px;
  font: inherit;
}

.admin-input[type="date"],
.admin-input[type="time"],
.admin-input[type="datetime-local"],
.admin-input[type="month"],
.admin-input[type="week"] {
  color-scheme: dark;
}

.admin-btn {
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  background: var(--color-primary);
  color: #08110c;
  font-weight: 700;
  padding: 10px 13px;
  cursor: pointer;
}

.admin-btn:disabled {
  opacity: 0.6;
  cursor: not-allowed;
}

.admin-error {
  min-height: 18px;
  margin-top: 10px;
  color: var(--color-accent);
  font-size: 13px;
}

.admin-shell {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}

.admin-topbar {
  position: sticky;
  top: 0;
  z-index: 20;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  padding: 12px 18px;
  background: #0f0f11;
  border-bottom: 1px solid var(--admin-border);
}

.admin-wordmark {
  color: var(--color-primary);
  font-family: var(--font-display);
  text-decoration: none;
  font-size: 24px;
}

.admin-nav {
  display: flex;
  gap: 8px;
  align-items: center;
}

.admin-nav a {
  color: var(--admin-text-secondary);
  text-decoration: none;
  padding: 6px 10px;
  border-radius: var(--radius-sm);
  border: 1px solid transparent;
}

.admin-nav a.active,
.admin-nav a:hover {
  color: var(--admin-text);
  border-color: var(--admin-border);
  background: var(--admin-surface-hover);
}

.admin-right {
  display: flex;
  align-items: center;
  gap: 10px;
}

.admin-text-secondary {
  color: var(--admin-text-secondary);
}

.admin-user {
  color: var(--admin-text-secondary);
  font-size: 13px;
}

.admin-main {
  padding: 22px;
}

.admin-panel {
  background: var(--admin-surface);
  border: 1px solid var(--admin-border);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-md);
}

.admin-panel h1,
.admin-panel h2 {
  margin: 0;
  padding: 16px;
  border-bottom: 1px solid var(--admin-border);
  font-size: 18px;
}

.admin-panel-body {
  padding: 16px;
  color: var(--admin-text-secondary);
}

.admin-kpis {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 12px;
  margin-bottom: 18px;
}

.admin-kpi-card {
  background: var(--admin-surface);
  border: 1px solid var(--admin-border);
  border-radius: var(--radius-md);
  padding: 14px;
  box-shadow: var(--shadow-md);
  display: grid;
  gap: 8px;
}

.admin-kpi-card span {
  font-size: 13px;
  color: var(--admin-text-secondary);
}

.admin-kpi-card strong {
  font-size: 28px;
  color: var(--admin-text);
}

.admin-grid-2 {
  display: grid;
  grid-template-columns: 1.35fr 1fr;
  gap: 12px;
}

/* Full-width stacked panels. Used where a two-column pairing produced a
   ragged row because the panels have unrelated heights (dashboard's
   Recent Calls / Open Tickets). Single-column at every width, so it needs
   no mobile override. */
.admin-stack {
  display: grid;
  grid-template-columns: 1fr;
  gap: 12px;
}

.admin-table-wrap {
  overflow: auto;
}

.admin-table {
  width: 100%;
  border-collapse: collapse;
  min-width: 640px;
}

.admin-table th,
.admin-table td {
  text-align: left;
  padding: 8px 10px;
  border-bottom: 1px solid var(--admin-border);
  font-size: 13px;
  white-space: nowrap;
}

.admin-table th {
  color: var(--admin-text-secondary);
  background: #101013;
  position: sticky;
  top: 0;
  z-index: 1;
}

.admin-table tbody tr:hover {
  background: #18181d;
}

.admin-toolbar {
  margin-bottom: 10px;
}

.admin-status-filters {
  display: inline-flex;
  gap: 8px;
  flex-wrap: wrap;
  margin-left: 10px;
}

.admin-status-filter {
  border: 1px solid var(--admin-border);
  border-radius: 999px;
  background: transparent;
  color: var(--admin-text-secondary);
  padding: 6px 12px;
  font-size: 12px;
  cursor: pointer;
}

.admin-status-filter.is-active {
  color: #fff;
}

.admin-status-filter.is-active.active {
  background: #3ea76f;
  border-color: #3ea76f;
}

.admin-status-filter.is-active.maintenance {
  background: #eab308;
  border-color: #eab308;
  color: #1b1b1b;
}

.admin-status-filter.is-active.suspended {
  background: #ef4444;
  border-color: #ef4444;
}

.admin-status-filter.is-active.deleted {
  background: #6b7280;
  border-color: #6b7280;
}

.admin-status-filter.is-active.all {
  background: #4b5563;
  border-color: #4b5563;
}

.admin-toolbar .admin-input {
  max-width: 420px;
}

.admin-detail-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
}

.admin-actions {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}

.admin-info-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 10px;
}

.admin-info-item {
  border: 1px solid var(--admin-border);
  border-radius: var(--radius-sm);
  padding: 8px;
  background: #101013;
}

/* Client-detail header money box. FOUR cells, so Balance and Effective limit
   land side by side: a negative balance is normal until it passes its floor,
   and read on its own it looks like a fault. Reuses .admin-info-item for the
   cell treatment; only the column count differs, and it steps down on the same
   two breakpoints as .admin-info-grid so the two never disagree. */
.admin-money-grid {
  grid-template-columns: repeat(4, minmax(0, 1fr));
}

.admin-money-note {
  font-size: 12px;
  color: var(--admin-text-secondary);
  margin-top: 3px;
}

.admin-info-label {
  font-size: 12px;
  color: var(--admin-text-secondary);
  margin-bottom: 4px;
}

.admin-info-value {
  color: var(--admin-text);
  font-size: 13px;
}

.admin-subhead {
  margin: 0 0 8px;
  color: var(--admin-text);
  font-size: 14px;
}

.admin-list {
  margin: 0;
  padding-left: 18px;
  color: var(--admin-text-secondary);
}

.admin-list li { margin: 4px 0; }

.admin-pre {
  margin: 0 0 12px;
  white-space: pre-wrap;
  font-family: var(--font-mono);
  font-size: 12px;
  border: 1px solid var(--admin-border);
  border-radius: var(--radius-sm);
  padding: 8px;
  background: #101013;
  color: var(--admin-text);
}

.admin-inline-link-wrap {
  margin-top: 12px;
}

.admin-inline-link {
  color: var(--color-primary);
  text-decoration: none;
}

.admin-inline-link:hover {
  text-decoration: underline;
}

.admin-health-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 10px;
}

.admin-health-label {
  display: block;
  font-size: 12px;
  color: var(--admin-text-secondary);
  margin-bottom: 4px;
}

.admin-health-value {
  color: var(--admin-text);
  font-weight: 600;
}

.admin-error {
  margin-top: 12px;
}

.admin-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 999px;
  padding: 2px 8px;
  font-size: 12px;
  font-weight: 700;
  background: rgba(62, 167, 111, 0.16);
  color: #9ce4bb;
}

.admin-action-btn {
  border: 1px solid var(--admin-border);
  border-radius: var(--radius-sm);
  background: #111114;
  color: var(--admin-text);
  padding: 5px 8px;
  font-size: 12px;
  text-decoration: none;
}

.admin-action-btn:hover {
  border-color: var(--color-primary);
}

@media (max-width: 1200px) {
  .admin-kpis,
  .admin-health-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .admin-grid-2 {
    grid-template-columns: 1fr;
  }

  .admin-info-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .admin-money-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .admin-topbar {
    flex-wrap: wrap;
  }

  .admin-nav {
    order: 3;
    flex-basis: 100%;
    flex-wrap: wrap;
    border-top: 1px solid var(--admin-border);
    padding-top: 8px;
    margin-top: 4px;
  }
}

@media (max-width: 760px) {
  .admin-kpis,
  .admin-health-grid {
    grid-template-columns: 1fr;
  }

  .admin-info-grid {
    grid-template-columns: 1fr;
  }

  .admin-money-grid {
    grid-template-columns: 1fr;
  }

  .admin-topbar {
    padding: 10px 14px;
    gap: 10px;
  }

  .admin-wordmark {
    font-size: 20px;
  }

  .admin-user {
    display: none;
  }

  .admin-main {
    padding: 14px;
  }

  .admin-detail-head {
    flex-direction: column;
    align-items: stretch;
  }

  .admin-actions {
    width: 100%;
  }

  .admin-actions .admin-btn,
  .admin-actions .admin-action-btn {
    flex: 1 1 auto;
  }
}

.mono {
  font-family: var(--font-mono);
}

/* ─────────── Phase 5 — Tickets management ─────────── */

.admin-tickets-toolbar {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  align-items: flex-end;
  margin-bottom: 12px;
}

.admin-filter-group {
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 160px;
}

.admin-filter-grow {
  flex: 1 1 280px;
}

.admin-filter-label {
  font-size: 12px;
  color: var(--admin-text-secondary);
}

.admin-select {
  appearance: none;
  background-image: linear-gradient(45deg, transparent 50%, var(--admin-text-secondary) 50%),
    linear-gradient(135deg, var(--admin-text-secondary) 50%, transparent 50%);
  background-position: calc(100% - 16px) calc(50% - 2px), calc(100% - 11px) calc(50% - 2px);
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
  padding-right: 28px;
  cursor: pointer;
}

.admin-tickets-meta {
  margin: 0 0 8px;
  font-size: 13px;
}

.admin-tickets-table tbody tr.admin-ticket-row {
  cursor: pointer;
}

.admin-tickets-table tbody tr.admin-ticket-row:hover {
  background: var(--admin-surface-hover);
}

.admin-ticket-client-id {
  font-size: 11px;
}

.admin-text-muted {
  color: var(--admin-text-muted);
}

.admin-empty-cell {
  text-align: center;
  color: var(--admin-text-secondary);
  padding: 18px 8px !important;
}

.admin-badge-soft {
  background: rgba(91, 142, 201, 0.16);
  color: #b3d2f7;
}

.admin-badge-status {
  display: inline-flex;
  align-items: center;
  border-radius: 999px;
  padding: 2px 10px;
  font-size: 12px;
  font-weight: 700;
  border: 1px solid var(--admin-border);
  background: #101013;
  color: var(--admin-text-secondary);
}

.admin-badge-status.open {
  background: rgba(234, 179, 8, 0.16);
  color: #f3d36b;
  border-color: rgba(234, 179, 8, 0.4);
}

.admin-badge-status.in-progress {
  background: rgba(91, 142, 201, 0.16);
  color: #8fb6e3;
  border-color: rgba(91, 142, 201, 0.4);
}

.admin-badge-status.resolved {
  background: rgba(62, 167, 111, 0.16);
  color: #9ce4bb;
  border-color: rgba(62, 167, 111, 0.4);
}

.admin-badge-status.closed {
  background: rgba(82, 82, 91, 0.32);
  color: var(--admin-text-secondary);
}

/* Chapter 10 — purple "Suggestion" event-type badge. Distinct from the
   green/yellow/red status pills so admins can spot suggestions in a
   mixed event list at a glance. */
.admin-badge-status.suggestion {
  background: rgba(112, 72, 179, 0.22);
  color: #c4a8f0;
  border-color: rgba(112, 72, 179, 0.5);
}

.admin-client-status {
  display: inline-flex;
  align-items: center;
  border-radius: 999px;
  padding: 2px 10px;
  font-size: 12px;
  font-weight: 700;
  border: 1px solid transparent;
}

.admin-client-status.active {
  background: rgba(62, 167, 111, 0.1);
  color: #3ea76f;
  border-color: #3ea76f;
}

.admin-client-status.maintenance {
  background: rgba(234, 179, 8, 0.1);
  color: #eab308;
  border-color: #eab308;
}

.admin-client-status.suspended {
  background: rgba(239, 68, 68, 0.1);
  color: #ef4444;
  border-color: #ef4444;
}

.admin-client-status.deleted {
  background: rgba(107, 114, 128, 0.1);
  color: #6b7280;
  border-color: #6b7280;
}

/* Approval gate (2026-09-11) — provisioned, welcome email not yet sent. Blue:
   not a problem state (red/amber) and not live (green). */
.admin-client-status.onboarding {
  background: rgba(34, 113, 177, 0.1);
  color: var(--admin-status-onboarding);
  border-color: var(--admin-status-onboarding);
}

.admin-status-filter.is-active.onboarding {
  background: var(--admin-status-onboarding);
  border-color: var(--admin-status-onboarding);
}

/* The onboarding block on the client page. Shown for every client: with the
   Approve button while unapproved, and as the approval record afterwards. */
.admin-onboarding-block {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
  margin: 8px 0 0;
  padding: 10px 14px;
  border: 1px solid var(--admin-border);
  border-left: 4px solid var(--admin-status-onboarding);
  border-radius: 4px;
  font-size: 13px;
}

.admin-onboarding-block.is-approved {
  border-left-color: #3ea76f;
}

.admin-client-row-deleted {
  background: rgba(239, 68, 68, 0.05);
}

.admin-ticket-expansion > td {
  background: #0c0c0e;
  padding: 16px !important;
  white-space: normal;
}

.admin-ticket-detail-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 260px;
  gap: 18px;
}

.admin-ticket-detail-heading {
  margin: 0 0 4px;
  font-family: var(--font-display);
  color: var(--admin-text);
  font-size: 18px;
}

.admin-ticket-detail-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-bottom: 14px;
  font-size: 12px;
}

.admin-ticket-section-title {
  margin-top: 14px;
  margin-bottom: 6px;
}

.admin-ticket-pre {
  margin-bottom: 14px;
  background: #0a0a0c;
}

.admin-ticket-notes {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-bottom: 12px;
}

.admin-ticket-note {
  border: 1px solid var(--admin-border);
  border-radius: var(--radius-sm);
  padding: 8px 10px;
  background: #0a0a0c;
}

.admin-ticket-note-meta {
  display: flex;
  justify-content: space-between;
  font-size: 11px;
  color: var(--admin-text-secondary);
  margin-bottom: 4px;
}

.admin-ticket-note-author {
  font-weight: 700;
  color: var(--color-primary);
}

.admin-ticket-note-time {
  font-family: var(--font-mono);
}

.admin-ticket-note-body {
  white-space: pre-wrap;
  font-size: 13px;
  color: var(--admin-text);
}

.admin-tickets-empty-notes {
  margin: 0 0 8px;
  color: var(--admin-text-muted);
  font-size: 13px;
  font-style: italic;
}

.admin-ticket-note-compose {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.admin-ticket-note-input {
  width: 100%;
  resize: vertical;
  min-height: 64px;
  font: inherit;
}

.admin-ticket-compose-actions {
  display: flex;
  align-items: center;
  gap: 10px;
}

.admin-btn-compact {
  padding: 6px 12px;
  font-size: 13px;
}

.admin-ticket-note-status {
  font-size: 12px;
}

.admin-ticket-sidebar {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.admin-ticket-sidebar-block {
  border: 1px solid var(--admin-border);
  border-radius: var(--radius-sm);
  padding: 10px;
  background: #0a0a0c;
}

.admin-ticket-status-select {
  width: 100%;
  margin-top: 4px;
}

.admin-ticket-status-msg {
  display: block;
  font-size: 11px;
  margin-top: 6px;
  min-height: 14px;
}

.admin-ticket-client-link {
  display: inline-block;
  margin-top: 6px;
  font-size: 12px;
}

@media (max-width: 900px) {
  .admin-ticket-detail-grid {
    grid-template-columns: minmax(0, 1fr);
  }
  .admin-tickets-toolbar {
    flex-direction: column;
    align-items: stretch;
  }
  .admin-filter-group {
    min-width: 0;
  }
}

/* ─────────── Phase 6 — Loading / empty / error states ─────────── */

.admin-loading-cell,
.admin-loading-block {
  text-align: center;
  color: var(--admin-text-secondary);
  padding: 18px 8px !important;
  font-size: 13px;
  font-style: italic;
}

.admin-loading-block::before,
.admin-loading-cell::before {
  content: "";
  display: inline-block;
  width: 10px;
  height: 10px;
  margin-right: 8px;
  border: 2px solid var(--admin-text-muted);
  border-top-color: var(--color-primary);
  border-radius: 50%;
  vertical-align: -1px;
  animation: admin-spin 0.8s linear infinite;
}

@keyframes admin-spin {
  to { transform: rotate(360deg); }
}

.admin-kpi-loading {
  color: var(--admin-text-muted) !important;
  font-size: 18px !important;
  font-weight: 500;
}

.admin-error-banner {
  display: block;
  padding: 12px 14px;
  margin: 0 0 14px;
  border: 1px solid rgba(239, 68, 68, 0.4);
  background: rgba(239, 68, 68, 0.1);
  color: #fca5a5;
  border-radius: var(--radius-sm);
  font-size: 13px;
}

.admin-error-banner.hidden {
  display: none;
}

.admin-danger-zone {
  border: 2px solid #ef4444;
  background: rgba(239, 68, 68, 0.08);
  margin-top: 20px;
}

.admin-btn-danger {
  background: #b42318;
  border-color: #ef4444;
  color: #fff;
}

.admin-btn-danger:hover {
  background: #912018;
}

.admin-modal-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.65);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 1200;
  padding: 16px;
}

.admin-modal-overlay.hidden {
  display: none;
}

.admin-modal-card {
  width: min(680px, 100%);
  border: 1px solid var(--admin-border);
  border-radius: var(--radius-md);
  background: #0f0f11;
  padding: 18px;
}

.admin-modal-actions {
  margin-top: 14px;
  display: flex;
  justify-content: flex-end;
  gap: 8px;
}

.input-error {
  border-color: #ef4444 !important;
  box-shadow: 0 0 0 2px rgba(239, 68, 68, 0.2);
}

.modal-error-banner {
  background: rgba(239, 68, 68, 0.1);
  border: 1px solid #ef4444;
  color: #ef4444;
  padding: 8px 12px;
  border-radius: 6px;
  margin-bottom: 12px;
  font-size: 13px;
  white-space: pre-line;
}

.modal-error-banner.hidden {
  display: none;
}

.admin-error-banner-actions {
  margin-left: 8px;
  font-size: 12px;
  text-decoration: underline;
  cursor: pointer;
  color: inherit;
  background: transparent;
  border: 0;
  padding: 0;
}

.admin-error-banner-actions:hover {
  color: #fff;
}


/* ─────────── UX Refresh Ch 7 — Analytics page on dark admin theme ─────────── */

.admin-analytics-toolbar {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  align-items: flex-end;
}

.admin-kpis-wide {
  grid-template-columns: repeat(5, minmax(0, 1fr));
}

@media (max-width: 1200px) {
  .admin-kpis-wide {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (max-width: 760px) {
  .admin-kpis-wide {
    grid-template-columns: 1fr;
  }
}

.admin-chart-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 14px;
}

@media (max-width: 900px) {
  .admin-chart-grid {
    grid-template-columns: 1fr;
  }
}

.admin-chart-card {
  background: var(--admin-surface);
  border: 1px solid var(--admin-border);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-md);
  padding: 14px;
}

.admin-chart-card-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  margin: 0 0 10px;
}

.admin-chart-card-head h3 {
  margin: 0;
  font-size: 14px;
  color: var(--admin-text);
  font-weight: 600;
}

.admin-chart-canvas-wrap {
  position: relative;
  height: 280px;
}

.admin-chart-canvas-wrap canvas {
  max-height: 280px;
}


/* ─────────── UX Refresh Ch 7.5 — 5-chart analytics layout + Tabler-icon button ─────────── */

.admin-charts-row-1 {
  display: grid;
  grid-template-columns: 2fr 1fr;
  gap: 14px;
}

.admin-charts-row-2 {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 14px;
}

.admin-charts-row-3 {
  display: grid;
  grid-template-columns: 1fr;
  gap: 14px;
}

@media (max-width: 1100px) {
  .admin-charts-row-1,
  .admin-charts-row-2 {
    grid-template-columns: 1fr;
  }
}

.admin-chart-canvas-tall {
  height: 320px;
}

.admin-chart-canvas-tall canvas {
  max-height: 320px;
}

.admin-chart-canvas-wide {
  height: 360px;
}

.admin-chart-canvas-wide canvas {
  max-height: 360px;
}

/* Call Heatmap only. Its Y axis lists all 24 hours; at the shared wide height
   of 360px each row is ~15px, too small for the per-cell call count to be
   legible. 640px gives every hour row ~26px. Declared after the .wide rules so
   it wins on order (same specificity). Added 2026-07-24. */
.admin-chart-canvas-heatmap {
  height: 640px;
}

.admin-chart-canvas-heatmap canvas {
  max-height: 640px;
}

.admin-btn-icon {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 8px 16px;
}

.admin-btn-icon .ti {
  font-size: 16px;
  line-height: 1;
}

.admin-btn-icon:hover {
  background: #2f8a5a;
}

/* ─────────── Critical Fixes Ch C — Client health pill bar ─────────── */

.admin-pill-bar {
  display: inline-flex;
  align-items: stretch;
  border: 1px solid var(--admin-border);
  border-radius: 999px;
  background: var(--admin-surface);
  overflow: hidden;
}

.admin-pill {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 7px 14px;
  background: transparent;
  color: var(--admin-text-secondary);
  border: 0;
  border-right: 1px solid var(--admin-border);
  font-size: 13px;
  font-weight: 500;
  cursor: pointer;
  transition: background 0.12s ease, color 0.12s ease;
  white-space: nowrap;
}

.admin-pill:last-child {
  border-right: 0;
}

.admin-pill:hover {
  background: var(--admin-surface-hover);
  color: var(--admin-text);
}

.admin-pill-dot {
  display: inline-block;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: currentColor;
}

.admin-pill-count {
  display: inline-block;
  min-width: 18px;
  padding: 0 6px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.06);
  color: var(--admin-text-secondary);
  font-size: 11px;
  font-weight: 600;
  text-align: center;
  line-height: 18px;
}

/* Inactive dot colors (so the colored bullets show even when not active). */
.admin-pill-green .admin-pill-dot { color: #3ea76f; }
.admin-pill-yellow .admin-pill-dot { color: #eab308; }
.admin-pill-red .admin-pill-dot { color: #ef4444; }

/* Active states — brand color background, white text, count badge inverted. */
.admin-pill.is-active {
  color: #fff;
  font-weight: 700;
}
.admin-pill.is-active .admin-pill-count {
  background: rgba(0, 0, 0, 0.22);
  color: #fff;
}
.admin-pill.is-active .admin-pill-dot {
  color: #fff;
  box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.3);
}

.admin-pill-all.is-active   { background: #4b5563; }
.admin-pill-green.is-active { background: #3ea76f; }
.admin-pill-yellow.is-active { background: #eab308; color: #1b1b1b; }
.admin-pill-yellow.is-active .admin-pill-count { background: rgba(0,0,0,0.18); color: #1b1b1b; }
.admin-pill-yellow.is-active .admin-pill-dot { color: #1b1b1b; box-shadow: 0 0 0 2px rgba(0,0,0,0.25); }
.admin-pill-red.is-active   { background: #ef4444; }

/* ─────────── Announcement Overhaul ─────────── */
.ann-pill {
  display: inline-block;
  padding: 2px 10px;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 700;
  border: 1px solid transparent;
  white-space: nowrap;
}
.ann-pill-green {
  background: rgba(62, 167, 111, 0.18);
  color: #9ce4bb;
  border-color: rgba(62, 167, 111, 0.4);
}
.ann-pill-amber {
  background: rgba(234, 179, 8, 0.18);
  color: #f3d36b;
  border-color: rgba(234, 179, 8, 0.4);
}
.ann-pill-gray {
  background: rgba(107, 114, 128, 0.18);
  color: #d1d5db;
  border-color: rgba(107, 114, 128, 0.4);
}

.admin-btn-sm {
  padding: 5px 10px;
  font-size: 12px;
  font-weight: 600;
  border-radius: var(--radius-sm);
  border: 1px solid transparent;
  cursor: pointer;
}
.ann-actions {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
}
.ann-btn-edit,
.ann-btn-publish {
  background: var(--color-primary);
  color: #08110c;
  border-color: var(--color-primary);
}
.ann-btn-edit:hover,
.ann-btn-publish:hover {
  background: #2f8a5a;
  border-color: #2f8a5a;
}
.ann-btn-delete {
  background: #b42318;
  color: #fff;
  border-color: #ef4444;
}
.ann-btn-delete:hover {
  background: #912018;
}

/* ============================================================================
   WordPress-style admin shell — Stage 1 (Dashboard only)
   Left dark sidebar + light content canvas. All selectors below are NEW and
   scoped to .admin-layout / .adminnav-* so the legacy dark top-nav pages
   (.admin-shell / .admin-topbar / .admin-nav) are completely untouched.
   ========================================================================== */
:root {
  /* WordPress-admin "Fresh" palette */
  --admin-canvas: #f0f0f1;
  --admin-canvas-line: #c3c4c7;
  --admin-ink: #1d2327;
  --admin-ink-soft: #50575e;
  /* Ch13 — the admin accent is THE TENANT'S colour, not a fixed RoyalVoice
     blue. These four were hardcoded #2271b1 / #135e96 / #72aee6 / rgba(34,113,
     177,.16), which is why a tenant admin saw their own name rendered in
     RoyalVoice blue. They now derive from --color-primary / --color-accent,
     which _serve_branded_html overrides per request in a <style> block emitted
     AFTER this file loads — custom properties resolve at use time, so every
     var(--admin-blue) below picks the tenant colour up with no further edits.
     Darker/lighter steps use OKLCH relative colour, not eyeballed hex. For the
     platform (RoyalVoice, #2271b1) these reproduce the old values: the derived
     dark step lands on ~#14609a against the old #135e96, and --color-accent IS
     #72aee6 in the royalvoice row, so the hover ink is exact. */
  --admin-blue: var(--color-primary);
  --admin-blue-dark: oklch(from var(--color-primary) calc(l - 0.07) c h);
  --admin-card-bg: #ffffff;
  --admin-card-line: #c3c4c7;
  --admin-card-line-soft: #dcdcde;
  --admin-th-bg: #f6f7f7;
  --admin-input-line: #8c8f94;
  --admin-sb-bg: #1d2327;
  --admin-sb-bg-soft: #2c3338;
  --admin-sb-ink: #f0f0f1;
  --admin-sb-ink-dim: #a7aaad;
  --admin-sb-active: var(--color-primary);
  --admin-sb-hover-ink: var(--color-accent);
  --admin-sb-border: #2c3338;
  --admin-sb-active-tint: oklch(from var(--color-primary) l c h / 0.16);
  --admin-sidebar-w: 250px;
  --admin-sidebar-w-collapsed: 70px;
  --admin-pagebar-h: 62px;
}

.admin-layout {
  min-height: 100vh;
  display: grid;
  grid-template-columns: var(--admin-sidebar-w) 1fr;
  background: var(--admin-canvas);
}
.admin-layout.is-collapsed {
  grid-template-columns: var(--admin-sidebar-w-collapsed) 1fr;
}

/* ---- Sidebar ---- */
.admin-sidebar {
  position: sticky;
  top: 0;
  height: 100vh;
  display: flex;
  flex-direction: column;
  background: var(--admin-sb-bg);
  border-right: 1px solid var(--admin-sb-border);
  overflow: hidden;
}

.admin-brand {
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 17px 18px;
  text-decoration: none;
  border-bottom: 1px solid var(--admin-sb-border);
  min-height: var(--admin-pagebar-h);
}
.admin-brand-mark {
  flex: none;
  width: 26px;
  height: 26px;
  display: grid;
  place-items: center;
  color: var(--admin-sb-active);
}
.admin-brand-mark svg { width: 25px; height: 25px; }
.admin-brand-text {
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 18px;
  letter-spacing: 0.01em;
  line-height: 1;
  color: #fff;
}
.admin-brand-text small {
  display: block;
  margin-top: 3px;
  font-family: var(--font-body);
  font-size: 9.5px;
  font-weight: 600;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--admin-sb-ink-dim);
}

.admin-sidebar-nav {
  flex: 1 1 auto;
  overflow-y: auto;
  padding: 12px 10px;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.adminnav-link,
.adminnav-parent {
  display: flex;
  align-items: center;
  gap: 11px;
  width: 100%;
  padding: 9px 11px;
  border: 0;
  border-radius: 8px;
  background: transparent;
  color: var(--admin-sb-ink);
  font: inherit;
  font-size: 14px;
  font-weight: 500;
  text-align: left;
  text-decoration: none;
  cursor: pointer;
}
.adminnav-link:hover,
.adminnav-parent:hover {
  background: var(--admin-sb-bg-soft);
  color: var(--admin-sb-hover-ink);
}
.adminnav-ico {
  flex: none;
  width: 20px;
  height: 20px;
  display: grid;
  place-items: center;
  color: var(--admin-sb-ink-dim);
}
.adminnav-ico svg { width: 19px; height: 19px; }
.adminnav-link:hover .adminnav-ico,
.adminnav-parent:hover .adminnav-ico { color: var(--admin-sb-hover-ink); }
.adminnav-label {
  flex: 1 1 auto;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.adminnav-caret {
  flex: none;
  width: 16px;
  height: 16px;
  color: var(--admin-sb-ink-dim);
  transition: transform 0.2s ease;
}
.adminnav-caret svg { width: 16px; height: 16px; }
.adminnav-group.is-open > .adminnav-parent > .adminnav-caret { transform: rotate(180deg); }

.adminnav-link.is-active {
  background: var(--admin-sb-active);
  color: #fff;
  box-shadow: none;
}
.adminnav-link.is-active .adminnav-ico { color: #fff; }
.adminnav-link.is-active:hover { background: var(--admin-sb-active); color: #fff; }
.adminnav-link.is-active:hover .adminnav-ico { color: #fff; }
.adminnav-group.has-active > .adminnav-parent { color: #fff; }
.adminnav-group.has-active > .adminnav-parent .adminnav-ico { color: #fff; }

.adminnav-sub {
  display: none;
  flex-direction: column;
  gap: 1px;
  padding: 2px 0 4px;
}
.adminnav-group.is-open > .adminnav-sub {
  display: flex;
  background: var(--admin-sb-bg-soft);
  border-radius: 6px;
  margin: 2px 0 4px;
  padding: 5px 0;
}
.adminnav-fly-title { display: none; }
.adminnav-sublink {
  display: block;
  padding: 7px 11px 7px 42px;
  border-radius: 7px;
  color: var(--admin-sb-ink-dim);
  font-size: 13.5px;
  text-decoration: none;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.adminnav-sublink:hover { color: var(--admin-sb-hover-ink); background: transparent; }
.adminnav-sublink.is-active {
  color: #fff;
  font-weight: 600;
  background: transparent;
  box-shadow: none;
}

.admin-sidebar-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 11px 16px;
  border-top: 1px solid var(--admin-sb-border);
  position: relative; /* keep the collapse toggle above any sibling stacking */
  z-index: 2;
}
.admin-foot-user {
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
  color: var(--admin-sb-ink-dim);
  font-size: 12.5px;
}
.admin-foot-user span:last-child {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.admin-foot-dot {
  flex: none;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--admin-sb-active);
  box-shadow: 0 0 0 3px rgba(34, 113, 177, 0.22);
}
.admin-sb-toggle {
  flex: none;
  display: grid;
  place-items: center;
  padding: 5px;
  border: 0;
  border-radius: 7px;
  background: transparent;
  color: var(--admin-sb-ink-dim);
  cursor: pointer;
}
.admin-sb-toggle:hover { color: #fff; background: var(--admin-sb-bg-soft); }
.admin-sb-toggle svg { width: 18px; height: 18px; transition: transform 0.2s ease; }
.admin-layout.is-collapsed .admin-sb-toggle svg { transform: rotate(180deg); }

/* ---- Content side ---- */
.admin-content {
  display: flex;
  flex-direction: column;
  min-width: 0;
  min-height: 100vh;
  background: var(--admin-canvas);
}
.admin-pagebar {
  position: sticky;
  top: 0;
  z-index: 15;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  min-height: var(--admin-pagebar-h);
  padding: 0 28px;
  background: #fff;
  border-bottom: 1px solid var(--admin-canvas-line);
}
.admin-pagebar-title {
  margin: 0;
  font-family: var(--font-body);
  font-weight: 500;
  font-size: 22px;
  color: var(--admin-ink);
}
.admin-pagebar-right {
  display: flex;
  align-items: center;
  gap: 14px;
}
.admin-pagebar .admin-user { color: var(--admin-ink-soft); font-size: 13px; }
.admin-pagebar .admin-user .mono { color: var(--admin-ink); }
.admin-btn-ghost {
  background: transparent;
  color: var(--admin-ink-soft);
  border: 1px solid var(--admin-canvas-line);
  font-weight: 600;
}
.admin-btn-ghost:hover {
  color: var(--admin-ink);
  border-color: #c9d2ce;
  background: #f6f8f7;
}

/* Generous content width — charts and multi-step wizards must not be squeezed. */
.admin-content .admin-main {
  width: 100%;
  max-width: 1600px;
  margin: 0;
  padding: 28px;
}

/* ---- Collapsed icon rail ----
   Every icon is a tap target: leaf links use their own href; parent icons
   navigate to their first child (handled in admin-nav.js). Submenus are fully
   hidden in the rail (no flyout) and overflow-x is clipped so the 70px rail
   never shows a stray horizontal scrollbar. */
.admin-layout.is-collapsed .adminnav-label,
.admin-layout.is-collapsed .adminnav-caret,
.admin-layout.is-collapsed .admin-brand-text,
.admin-layout.is-collapsed .admin-foot-user { display: none; }
.admin-layout.is-collapsed .admin-brand { justify-content: center; padding: 17px 0; }
.admin-layout.is-collapsed .admin-sidebar-foot { justify-content: center; }
.admin-layout.is-collapsed .adminnav-link,
.admin-layout.is-collapsed .adminnav-parent { justify-content: center; padding: 11px 0; }
.admin-layout.is-collapsed .admin-sidebar-nav { overflow-x: hidden; }
.admin-layout.is-collapsed .adminnav-sub { display: none; }

/* ---- Subtle staggered nav reveal on load ---- */
@keyframes adminnav-in {
  from { opacity: 0; transform: translateX(-6px); }
  to { opacity: 1; transform: none; }
}
.admin-sidebar-nav > * { animation: adminnav-in 0.34s ease both; }
.admin-sidebar-nav > *:nth-child(1) { animation-delay: 0.03s; }
.admin-sidebar-nav > *:nth-child(2) { animation-delay: 0.06s; }
.admin-sidebar-nav > *:nth-child(3) { animation-delay: 0.09s; }
.admin-sidebar-nav > *:nth-child(4) { animation-delay: 0.12s; }
.admin-sidebar-nav > *:nth-child(5) { animation-delay: 0.15s; }
.admin-sidebar-nav > *:nth-child(6) { animation-delay: 0.18s; }
.admin-sidebar-nav > *:nth-child(7) { animation-delay: 0.21s; }
.admin-sidebar-nav > *:nth-child(8) { animation-delay: 0.24s; }
@media (prefers-reduced-motion: reduce) {
  .admin-sidebar-nav > * { animation: none; }
}

/* ============================================================================
   WordPress-style LIGHT content theme — Dashboard only.
   Every selector is scoped under .admin-content so it overrides the shared dark
   card/table classes ONLY inside the new shell. The other 11 legacy pages have
   no .admin-content wrapper and keep their original dark theme untouched.
   ========================================================================== */

/* Cards / panels — white, thin border, minimal shadow, dark headings */
.admin-content .admin-panel,
.admin-content .admin-kpi-card {
  background: var(--admin-card-bg);
  border: 1px solid var(--admin-card-line);
  border-radius: 4px;
  box-shadow: 0 1px 1px rgba(0, 0, 0, 0.04);
}
.admin-content .admin-panel h1,
.admin-content .admin-panel h2 {
  margin: 0;
  padding: 12px 16px;
  border-bottom: 1px solid var(--admin-card-line-soft);
  font-family: var(--font-body);
  font-size: 14px;
  font-weight: 600;
  color: var(--admin-ink);
}
.admin-content .admin-panel-body { color: var(--admin-ink); }

/* KPI cards */
.admin-content .admin-kpi-card { padding: 16px 18px; }
.admin-content .admin-kpi-card span { color: var(--admin-ink-soft); font-size: 13px; }
.admin-content .admin-kpi-card strong { color: var(--admin-ink); font-weight: 600; }

/* Tables — white rows, dark text, light grey header, hover tint */
.admin-content .admin-table th {
  background: var(--admin-th-bg);
  color: var(--admin-ink);
  font-weight: 600;
  border-bottom: 1px solid var(--admin-card-line);
}
.admin-content .admin-table td {
  color: var(--admin-ink);
  border-bottom: 1px solid var(--admin-card-line-soft);
}
.admin-content .admin-table tbody tr:hover { background: var(--admin-th-bg); }

/* Secondary / muted text readable on white */
.admin-content .admin-text-secondary { color: var(--admin-ink-soft); }
.admin-content .admin-text-muted { color: #787c82; }

/* Links — WordPress blue */
.admin-content .admin-inline-link,
.admin-content .admin-panel-body a { color: var(--admin-blue); text-decoration: none; }
.admin-content .admin-inline-link:hover,
.admin-content .admin-panel-body a:hover { color: var(--admin-blue-dark); text-decoration: underline; }

/* Form controls — white WP-style inputs */
.admin-content .admin-input,
.admin-content .admin-select {
  /* background-COLOR, not the shorthand: the shorthand resets
     background-image and erased the chevron .admin-select paints, while
     appearance:none still suppressed the native arrow - leaving selects
     as bare bordered boxes. */
  background-color: #fff;
  color: var(--admin-ink);
  border: 1px solid var(--admin-input-line);
  border-radius: 4px;
}
.admin-content .admin-input::placeholder { color: #8c8f94; }
.admin-content .admin-input[type="date"],
.admin-content .admin-input[type="time"],
.admin-content .admin-input[type="datetime-local"],
.admin-content .admin-input[type="month"],
.admin-content .admin-input[type="week"] { color-scheme: light; }
.admin-content .admin-input:focus,
.admin-content .admin-select:focus {
  border-color: var(--admin-blue);
  box-shadow: 0 0 0 1px var(--admin-blue);
  outline: 2px solid transparent;
}

/* Primary buttons — WP blue. Exclude ghost logout, secondary/danger variants,
   and the semantic ann-btn-* action buttons (which keep their own colors). */
.admin-content .admin-btn:not(.admin-btn-ghost):not(.admin-btn-secondary):not(.admin-btn-danger):not([class*="ann-btn"]) {
  background: var(--admin-blue);
  color: #fff;
  border-color: var(--admin-blue);
  font-weight: 600;
}
.admin-content .admin-btn:not(.admin-btn-ghost):not(.admin-btn-secondary):not(.admin-btn-danger):not([class*="ann-btn"]):hover {
  background: var(--admin-blue-dark);
  border-color: var(--admin-blue-dark);
}

/* System Health grid */
.admin-content .admin-health-label { color: var(--admin-ink-soft); }
.admin-content .admin-health-value { color: var(--admin-ink); }

/* Error banner / inline error stay legible on light canvas */
.admin-content .admin-error-banner {
  background: #fcf0f1;
  border: 1px solid #d63638;
  color: #8a1f23;
}

/* ---- Badges / status tags — solid, bordered, readable (WP style) ----
   Light tinted background + darker matching text + a real same-hue border.
   Severity badge (admin-badge-status): info -> in-progress, warning -> open,
   error -> closed (per the dashboard JS mapping). */
.admin-content .admin-badge-status,
.admin-content .ann-pill {
  background: #f0f0f1;
  color: var(--admin-ink-soft);
  border: 1px solid #c3c4c7;
  font-weight: 600;
}
.admin-content .admin-badge-status.in-progress { /* info */
  background: #e6f1fa; color: #0a4b78; border-color: #2271b1;
}
.admin-content .admin-badge-status.open { /* warning */
  background: #fcf3df; color: #8a6100; border-color: #dba617;
}
.admin-content .admin-badge-status.closed { /* error */
  background: #fcebec; color: #8a1f23; border-color: #d63638;
}
.admin-content .admin-badge-status.resolved { /* success (unused here, kept consistent) */
  background: #e6f5ec; color: #0f6b3f; border-color: #2a8a4f;
}
.admin-content .admin-badge-status.suggestion {
  background: #f1ebfb; color: #5b2a9e; border-color: #7048b3;
}
.admin-content .ann-pill-green { /* Published / success */
  background: #e6f5ec; color: #0f6b3f; border-color: #2a8a4f;
}
.admin-content .ann-pill-amber { /* Scheduled */
  background: #fcf3df; color: #8a6100; border-color: #dba617;
}
.admin-content .ann-pill-gray { /* Expired / Pending */
  background: #f0f0f1; color: var(--admin-ink-soft); border-color: #c3c4c7;
}

/* ---- Action buttons ----
   Non-destructive (Edit, Publish Now) -> solid WP blue, matching Post Announcement.
   Destructive (Delete) -> solid WP red. White text on both. */
.admin-content .ann-btn-edit,
.admin-content .ann-btn-publish {
  background: var(--admin-blue);
  color: #fff;
  border-color: var(--admin-blue);
}
.admin-content .ann-btn-edit:hover,
.admin-content .ann-btn-publish:hover {
  background: var(--admin-blue-dark);
  border-color: var(--admin-blue-dark);
}
.admin-content .ann-btn-delete {
  background: #d63638;
  color: #fff;
  border-color: #d63638;
}
.admin-content .ann-btn-delete:hover {
  background: #b32d2e;
  border-color: #b32d2e;
}

/* ---- Shared filter pills / status chips / loading cells on the light canvas ----
   Used across Clients, Tickets, etc. :not(.is-active) guards keep the semantic
   active-state colors (green=healthy, red=suspended, etc.) untouched. */
.admin-content .admin-pill-bar { background: #fff; border-color: var(--admin-card-line); }
.admin-content .admin-pill { border-right-color: var(--admin-card-line-soft); }
.admin-content .admin-pill:not(.is-active) { color: var(--admin-ink-soft); }
.admin-content .admin-pill:not(.is-active):hover { background: var(--admin-th-bg); color: var(--admin-ink); }
.admin-content .admin-pill:not(.is-active) .admin-pill-count {
  background: #eceef0; color: var(--admin-ink-soft);
}
.admin-content .admin-status-filter:not(.is-active) {
  color: var(--admin-ink-soft); border-color: var(--admin-card-line);
}
.admin-content .admin-status-filter:not(.is-active):hover {
  color: var(--admin-ink); border-color: var(--admin-input-line);
}
.admin-content .admin-loading-cell,
.admin-content .admin-loading-block { color: var(--admin-ink-soft); }
.admin-content .admin-loading-cell::before,
.admin-content .admin-loading-block::before {
  border-color: #c3c4c7; border-top-color: var(--admin-blue);
}

/* Generic secondary checkbox/inline labels that used the dark secondary text var */
.admin-content label { color: inherit; }

/* Secondary action buttons + filter labels + field labels on light canvas */
.admin-content .admin-action-btn {
  background: #fff; color: var(--admin-ink); border-color: var(--admin-input-line);
}
.admin-content .admin-action-btn:hover { border-color: var(--admin-blue); color: var(--admin-blue); }
.admin-content .admin-filter-label,
.admin-content .admin-field span { color: var(--admin-ink-soft); }

/* ============================================================================
   Converted admin pages (body.admin-has-sidebar): flip the legacy DARK design
   tokens to LIGHT so the many var-based inline styles in page markup render
   correctly on white, and cover components that live OUTSIDE .admin-content
   (modals appended after </main>). The sidebar + pagebar use separate
   --admin-sb-* / --admin-ink tokens, so they are completely unaffected.
   ========================================================================== */
body.admin-has-sidebar {
  --admin-bg: #f0f0f1;
  --admin-surface: #ffffff;
  --admin-surface-hover: #f6f7f7;
  --admin-border: #c3c4c7;
  --admin-text: #1d2327;
  --admin-text-secondary: #50575e;
  --admin-text-muted: #787c82;
  --color-accent: #d63638;
}
/* Inputs / selects everywhere (incl. modals outside .admin-content) */
body.admin-has-sidebar .admin-input,
body.admin-has-sidebar .admin-select {
  /* See the .admin-content note above - the shorthand erases the chevron. */
  background-color: #fff;
  color: var(--admin-ink);
  border: 1px solid var(--admin-input-line);
  border-radius: 4px;
}
body.admin-has-sidebar .admin-input[type="date"],
body.admin-has-sidebar .admin-input[type="time"],
body.admin-has-sidebar .admin-input[type="datetime-local"],
body.admin-has-sidebar .admin-input[type="month"],
body.admin-has-sidebar .admin-input[type="week"] { color-scheme: light; }
body.admin-has-sidebar .admin-input:focus,
body.admin-has-sidebar .admin-select:focus {
  border-color: var(--admin-blue);
  box-shadow: 0 0 0 1px var(--admin-blue);
  outline: 2px solid transparent;
}
/* Primary buttons everywhere (incl. modal Save/Create outside .admin-content) */
body.admin-has-sidebar .admin-btn:not(.admin-btn-ghost):not(.admin-btn-secondary):not(.admin-btn-danger):not([class*="ann-btn"]) {
  background: var(--admin-blue);
  color: #fff;
  border-color: var(--admin-blue);
  font-weight: 600;
}
body.admin-has-sidebar .admin-btn:not(.admin-btn-ghost):not(.admin-btn-secondary):not(.admin-btn-danger):not([class*="ann-btn"]):hover {
  background: var(--admin-blue-dark);
  border-color: var(--admin-blue-dark);
}
/* Secondary buttons (undefined in base; some pages define a dark variant locally) */
body.admin-has-sidebar .admin-btn-secondary {
  background: #fff;
  color: var(--admin-ink);
  border: 1px solid var(--admin-card-line);
  border-radius: 4px;
  font-weight: 600;
  cursor: pointer;
}
body.admin-has-sidebar .admin-btn-secondary:hover { border-color: var(--admin-blue); color: var(--admin-blue); }
/* Shared modal card (base background is dark) */
body.admin-has-sidebar .admin-modal-card { background: #fff; border-color: var(--admin-card-line); }

/* Client Detail — info field boxes + <pre> display boxes (base hardcoded dark) */
.admin-content .admin-info-item {
  background: #fff;
  border-color: var(--admin-card-line);
}
.admin-content .admin-info-value { color: var(--admin-ink); }
.admin-content .admin-pre {
  background: #f6f7f7;
  border-color: var(--admin-card-line);
  color: var(--admin-ink);
}

/* Tickets — expanded ticket detail panel (base uses hardcoded dark backgrounds) */
.admin-content .admin-ticket-expansion > td {
  background: #f6f7f7;
  border-top: 1px solid var(--admin-card-line);
}
.admin-content .admin-ticket-pre,
.admin-content .admin-ticket-note,
.admin-content .admin-ticket-sidebar-block {
  background: #fff;
  border: 1px solid var(--admin-card-line-soft);
}
.admin-content .admin-ticket-note-author { color: var(--admin-blue); }
.admin-content .admin-ticket-note-input {
  background: #fff;
  color: var(--admin-ink);
  border: 1px solid var(--admin-input-line);
  border-radius: 4px;
}
.admin-content .admin-ticket-note-input:focus {
  border-color: var(--admin-blue);
  box-shadow: 0 0 0 1px var(--admin-blue);
  outline: 2px solid transparent;
}

/* Reply-to-Client vs Add-Note — two visually distinct tools so they can't be
   confused. Reply = blue "client sees this" identity; Note = muted internal. */
.admin-content .admin-comm-box {
  border-radius: 4px;
  padding: 12px 14px;
  margin-top: 16px;
}
.admin-content .admin-reply-box {
  background: #f0f6fc;
  border: 1px solid var(--admin-card-line-soft);
  border-left: 4px solid var(--admin-blue);
}
.admin-content .admin-note-box {
  background: #fff;
  border: 1px solid var(--admin-card-line-soft);
  border-left: 4px solid var(--admin-card-line);
}
.admin-content .admin-comm-head {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  margin-bottom: 10px;
}
.admin-content .admin-comm-title { margin: 0; font-size: 14px; color: var(--admin-ink); }
.admin-content .admin-reply-box .admin-comm-title { color: var(--admin-blue-dark); }
.admin-content .admin-comm-tag {
  font-size: 11px;
  font-weight: 600;
  padding: 2px 9px;
  border-radius: 999px;
  white-space: nowrap;
}
.admin-content .admin-comm-tag-visible { color: #fff; background: var(--admin-blue); }
.admin-content .admin-comm-tag-internal {
  color: var(--admin-ink-soft);
  background: #eef0f1;
  border: 1px solid var(--admin-card-line);
}
.admin-content .admin-comm-hint {
  font-size: 12px;
  color: var(--admin-blue-dark);
  font-style: italic;
}

/* ── Permanent (hard) deletion box ────────────────────────────────────────
   Placed at the END of this file and prefixed with .admin-content so it beats
   the light-theme `.admin-content .admin-panel` card rule above, which
   otherwise repaints every panel white. Deliberately heavier than the
   reversible danger zone: thicker border, stronger wash, red ring.
   (Danger-zone split, 2026-07-24.) */
.admin-content .admin-permanent-delete {
  border: 3px solid #ef4444;
  background: rgba(239, 68, 68, 0.10);
  box-shadow: 0 0 0 4px rgba(239, 68, 68, 0.12);
}

.admin-content .admin-permanent-delete h2 {
  color: #b42318;
  background: rgba(239, 68, 68, 0.14);
  border-bottom: 1px solid rgba(239, 68, 68, 0.35);
  letter-spacing: 0.02em;
}

/* The acknowledgement gate reads as part of the warning, not page furniture. */
.admin-content .admin-permanent-delete #hard-delete-ack-label {
  border: 1px solid rgba(239, 68, 68, 0.45);
  border-radius: 6px;
  padding: 10px 12px;
  background: rgba(255, 255, 255, 0.65);
}

/* A disabled Hard Delete must LOOK unavailable — otherwise the checkbox gate
   is invisible and users click a dead button. */
.admin-content .admin-permanent-delete .admin-btn-danger[disabled] {
  opacity: 0.45;
  cursor: not-allowed;
}

/* Portal Announcements — Message field. The browser default resize:both let
   the textarea be dragged past the card edge, breaking the container and
   forcing page-level horizontal scroll. Vertical resize stays available. */
.admin-content #ann-message {
  resize: vertical;
  width: 100%;
  max-width: 100%;
  box-sizing: border-box;
}

/* ── Analytics filter bar: one clean row ───────────────────────────────────
   Scoped to .admin-analytics-toolbar so no other admin page or button is
   affected.

   The bar bottom-aligns its items (align-items: flex-end), and each filter is
   a column of label-over-control. So any difference in CONTROL height pushed
   that column's LABEL out of line: the select measured 43px against the date
   inputs' 45px, which put "Range" 2px below "From"/"To". Equal control heights
   therefore fix the label alignment as a consequence, not as a separate rule.

   45px is the height two of the three controls already used - the majority, not
   a new value. Buttons join it so the whole row is one height: Apply was 37px
   and Export CSV 34px, because .admin-btn pads 10px 13px while .admin-btn-icon
   pads 8px 16px. Both now use the standard .admin-btn padding.

   font: inherit stops the buttons rendering in the browser default Arial
   13.33px next to labels and inputs already in the admin font. */
.admin-analytics-toolbar :is(select, input, button) {
  /* Adopts the admin button standard (37.6px) rather than the 45px this bar
     used previously. The select and both date inputs come down with the
     buttons, which is what keeps the three labels on one baseline: the bar
     bottom-aligns its items, so equal control heights are what aligns the
     labels above them. Font matches .admin-btn's 13px for the same reason. */
  font-family: inherit;
  font-size: 13px;
  height: 37.6px;
  box-sizing: border-box;
}

.admin-analytics-toolbar .admin-btn,
.admin-analytics-toolbar .admin-btn.admin-btn-icon {
  padding: 10px 13px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  line-height: 1.2;
}

/* ── Panel content inset ───────────────────────────────────────────────────
   .admin-panel has no padding of its own; .admin-panel-body supplies the 16px
   that the tables sit on. Content placed as a DIRECT child of the panel (filter
   rows, helper text, the clients pill bar) therefore rendered flush against the
   panel border while the table below was inset 16px. These give that content
   the same 16px the body already uses - matching, not inventing. */
.admin-panel-inset {
  padding-inline: 16px;
}

/* A header strip at the top of a panel: the same 16px inset plus 16px of
   breathing room above, so it is not glued to the panel's top border. The 8px
   below is the spacing the strip already carried. */
.admin-panel-head {
  padding: 16px 16px 8px;
}

/* ── Admin button: one size ────────────────────────────────────────────────
   .admin-btn declared no font, so a <button> fell back to the browser default
   (13.33px Arial) while an <a class="admin-btn"> inherited the page font
   (16px DM Sans) - which is why "+ Add New Client" rendered 43px against
   "+ Add New Plan" at 37px, despite identical padding, radius and weight.
   Declaring the font makes every .admin-btn render the same regardless of the
   element it is on. 13px is the size admin already uses for table cells, KPI
   labels and the user chip; the family is the admin font rather than the
   accidental Arial default.

   The analytics filter bar keeps its own 45px height via the more specific
   .admin-analytics-toolbar rule, so the label alignment fixed there is
   preserved. */
.admin-btn {
  font-family: inherit;
  font-size: 13px;
  line-height: 1.2;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

/* A panel header strip that sits ABOVE .admin-panel-body: heading on the left,
   actions on the right. The heading keeps its own 16px padding, so only the
   action group needs insetting - without it the buttons sit flush against the
   panel's top and right borders. Matches the 16px the body already uses. */
.admin-panel-head-actions {
  padding: 16px 16px 0 0;
}

/* Field label above a filter control group. Same type as .admin-filter-label,
   which is what the analytics filter bar already uses for "Range"/"From"/"To". */
.admin-group-label {
  display: block;
  font-size: 12px;
  font-weight: 700;
  color: var(--admin-ink);
  margin-bottom: 6px;
}

/* ── Light-theme select affordance ─────────────────────────────────────────
   .admin-select paints its caret with --admin-text-secondary, which is tuned
   for the dark base theme and nearly invisible on the light theme's white
   field. These re-paint it in the ink colour, and add the hover/focus states
   the selects previously lacked so they read as interactive. */
.admin-content .admin-select,
body.admin-has-sidebar .admin-select {
  background-image: linear-gradient(45deg, transparent 50%, var(--admin-ink) 50%),
    linear-gradient(135deg, var(--admin-ink) 50%, transparent 50%);
}

.admin-content .admin-select:hover,
body.admin-has-sidebar .admin-select:hover {
  border-color: var(--admin-blue);
}

/* Groups a title with the control(s) it labels, so the title and the control
   share one left edge by construction. */
.admin-labelled-group {
  display: flex;
  flex-direction: column;
}

/* .admin-status-filters carries margin-left:10px from its old inline position
   in the toolbar row. Inside a labelled group that 10px pushed the buttons out
   of line with their own title. */
.admin-labelled-group .admin-status-filters {
  margin-left: 0;
}

/* ============================================================================
   ONE BOX TREATMENT — every admin card/panel, defined once.

   Before this block admin had 4 different radii (4/6/8/10px), only 5 of ~20
   boxes carried any shadow at all (in 2 different values), and nothing moved
   on hover. This section is the single source of truth; it sits last in the
   file so it outranks the page-local <style> blocks and the earlier
   .admin-content overrides without needing !important.

   Flat at rest, a light shadow fading in on hover. There is NO movement:
   no transform, no lift. (Supersedes the translateY(-2px) shipped in
   a3b85ea/1a3e74f — Val replaced it with the shadow-only treatment.)

   The hover shadow is crossfaded on an ::after pseudo-element rather than
   transitioned as box-shadow — animating box-shadow repaints the whole box
   every frame and janks on the long pages (Call Logs, client-detail).
   Only `opacity` animates here, which is compositor-only.

   No z-index on the pseudo: an outer box-shadow is never painted inside its
   own border-box, so a transparent inset:0 pseudo renders nothing but the
   shadow ring outside the card.

   The shadow value is the same literal the portal uses (variables.css
   --shadow-md), so both surfaces are provably identical. It cannot be written
   as var(--shadow-md) here: admin.css declares its own token block and
   redefines --shadow-md as 0 4px 12px rgba(0,0,0,0.3), far too heavy for a
   hover hint.
   ========================================================================== */

:root {
  --box-hover-shadow: 0 4px 12px rgba(35, 15, 16, 0.08);
}

/* --- Boxes that get the treatment: 5px radius, flat, shadow on hover --- */
.admin-content .admin-panel,
.admin-content .admin-kpi-card,
.admin-content .admin-chart-card,
.admin-content .td-section,
.admin-content .pt-section {
  position: relative;
  border-radius: 5px;
  box-shadow: none;
}

.admin-content .admin-panel::after,
.admin-content .admin-kpi-card::after,
.admin-content .admin-chart-card::after,
.admin-content .td-section::after,
.admin-content .pt-section::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  box-shadow: var(--box-hover-shadow);
  opacity: 0;
  transition: opacity 0.2s ease;
  pointer-events: none;
}

.admin-content .admin-panel:hover::after,
.admin-content .admin-kpi-card:hover::after,
.admin-content .admin-chart-card:hover::after,
.admin-content .td-section:hover::after,
.admin-content .pt-section:hover::after {
  opacity: 1;
}

/* --- Radius only. These deliberately get NO hover shadow ---
   Nested blocks sit inside a box that already shadows on hover; pointing at a
   child hovers the parent too, so both would shadow at once and the inner one
   reads wrong. Modals are centred dialogs and the login card is a page hero —
   neither is a browsable item, and both keep their own shadow. Reported to
   Val before shipping. */
.admin-content .admin-info-item,
.admin-content .admin-ticket-note,
.admin-content .admin-ticket-sidebar-block,
.admin-content .admin-comm-box,
.admin-content .admin-pre,
.admin-content .td-stat,
.admin-content .us-reveal,
.admin-content #nc-progress-wrap {
  border-radius: 5px;
}

/* Modals live outside .admin-content (siblings of .admin-layout), so they are
   scoped on the body class instead. body.admin-page beats the page-local
   <style> rules that would otherwise win on document order. */
body.admin-page .admin-modal-card,
body.admin-page .bp-modal-card,
body.admin-page .tn-modal-card,
body.admin-page .admin-login-card {
  border-radius: 5px;
}

/* --- Reduced motion: the shadow still appears, it just stops fading.
       With the lift gone this is all that is left to govern. --- */
@media (prefers-reduced-motion: reduce) {
  .admin-content .admin-panel::after,
  .admin-content .admin-kpi-card::after,
  .admin-content .admin-chart-card::after,
  .admin-content .td-section::after,
  .admin-content .pt-section::after {
    transition: none;
  }
}

/* ══════════════════════════════════════════════════════════════════════════
   Admin Call Logs — cell classes copied from portal.css (Chapter A, 2026-09-09)

   The admin call-logs page reuses the portal's cell renderer, which emits these
   ten classes. Admin pages load ONLY this file — never portal.css — so without
   these the badges would render as bare text and the audio player unsized.
   Copied verbatim from portal.css except where noted below.

   THREE TOKENS THE PORTAL RULES DEPEND ON DO NOT EXIST HERE. portal.css opens
   with `@import variables.css`; admin.css deliberately does not, and defines
   its own palette instead. Of the five variables these rules reference,
   --font-mono and --color-primary already exist above. The other three:

     --radius-full / --text-xs   copied verbatim from variables.css. Pure
                                 geometry and type scale, no colour, so they
                                 carry no portal identity into this file.
     --color-primary-dark        NOT copied — it is portal green, and this is
                                 the blue admin surface. .btn-link below uses
                                 --admin-blue, which is this file's OWN link
                                 colour: `.admin-content .admin-panel-body a`
                                 already uses it, and it derives from
                                 --color-primary, so a transcript link is
                                 tenant-branded exactly like every other link
                                 on the page. 5.17:1 on the panel, AA.

   NOTE ON THE BACKGROUND these rules actually sit on: the dark :root palette
   at the top of this file is the LEGACY shell. Every page using
   body.admin-has-sidebar — including Call Logs — is overridden to a light
   theme further down (--admin-surface: #fff, --admin-card-bg: #fff), so these
   cells render on WHITE, not on #141416. Do not reason about contrast here
   from the :root block alone; that mistake was made once already and picked
   --color-accent, which under admin-has-sidebar is the destructive RED
   (#d63638), not the blue it is at :root.

   The four badge tints are copied verbatim. They are filled pills carrying
   their own backgrounds, so their contrast is internal to the pill
   (4.59:1 – 6.60:1, all AA) regardless of the surface behind them. */
:root {
  --radius-full: 9999px;
  --text-xs: 0.75rem;
}

.mono-small {
  font-family: var(--font-mono);
  font-size: 0.8rem;
}

.datetime-compact {
  white-space: nowrap;
  font-size: 0.82rem;
}

.badge-pill {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--radius-full);
  padding: 0.18rem 0.5rem;
  font-size: var(--text-xs);
  font-weight: 700;
  white-space: nowrap;
}

.badge-green  { background: #e8f7ef; color: #2d7c53; }
.badge-yellow { background: #fef6dc; color: #9a6500; }
.badge-gray   { background: #eeeeef; color: #5a5a61; }
.badge-red    { background: #fdecec; color: #a32020; }

/* --admin-blue (this file's own link colour), not the portal's
   --color-primary-dark and not --color-accent — see the note above. */
.btn-link {
  border: none;
  background: transparent;
  color: var(--admin-blue);
  text-decoration: underline;
  cursor: pointer;
  padding: 0;
  font: inherit;
}
.btn-link:hover { color: var(--admin-blue-dark); }

.transcript-trigger {
  display: inline-block;
  min-width: 200px;
  max-width: 100%;
}

.audio-inline {
  width: 180px;
  height: 30px;
}

/* ── Admin Call Logs page layout (Chapter A, 2026-09-09) ──────────────────
   Page-local classes, all prefixed acl- so they cannot collide with the
   shared admin components above. Tokens are admin.css's own throughout —
   nothing here reaches for a portal variable. */
.acl-scopebar,
.acl-filterbar {
  display: flex;
  flex-wrap: wrap;
  gap: 10px 14px;
  align-items: flex-end;
}

.acl-filterbar {
  padding-bottom: 12px;
  margin-bottom: 12px;
  border-bottom: 1px solid var(--admin-border);
}

.acl-field {
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 130px;
}

.acl-field-grow { flex: 1 1 260px; }

/* `hidden` must win. .acl-field sets display:flex, which outranks the
   browser's own [hidden]{display:none} — the master's tenant picker starts
   hidden in the HTML and would otherwise show for everyone before the script
   decides. Same pattern as .admin-login-logo-plate[hidden]. */
.acl-field[hidden] { display: none; }

/* One control height for both bars (2026-09-10). Both bars bottom-align their
   items (align-items: flex-end) and each filter is a label-over-control
   column, so any difference in CONTROL height pushes that column's LABEL out
   of line. Measured before this rule: text/search/number inputs 43px against
   selects and date inputs 45px (labels 2px apart in every row), and the
   buttons 37.6px. Same fix and same values as .admin-analytics-toolbar
   above: the admin button standard, 37.6px at 13px. */
.acl-scopebar :is(select, input, button),
.acl-filterbar :is(select, input, button) {
  font-family: inherit;
  font-size: 13px;
  height: 37.6px;
  box-sizing: border-box;
}

.acl-field-actions {
  flex-direction: row;
  gap: 8px;
  align-items: center;
}

.acl-field-label {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--admin-text-muted);
}

.acl-scope-summary,
.acl-muted {
  color: var(--admin-text-secondary);
  font-size: 13px;
}

/* Centred on the controls beside it rather than nudged by padding: the old
   padding-bottom: 8px put its text 6px below the select's centre. */
.acl-scope-summary {
  display: flex;
  align-items: center;
  height: 37.6px;
}

/* The table can be far wider than the viewport — every tenant column plus the
   admin-only Client column. Scroll it inside its own wrapper rather than
   letting the page scroll sideways. */
#acl-table { min-width: max-content; }

#acl-table th {
  cursor: default;
  user-select: none;
}

#acl-table th[data-sortable="1"] { cursor: pointer; }
#acl-table th[data-sortable="1"]:hover { color: var(--admin-text); }

#acl-table th .acl-sort-arrow {
  margin-left: 4px;
  opacity: 0.75;
  font-size: 10px;
}

/* One line per cell, vertically centred — the SAME treatment the client
   portal's call-logs table uses (portal.css `#calls-table tbody td`: nowrap,
   overflow hidden, ellipsis). The renderer this page copies was built for
   that single-line table.

   Layout fix (2026-09-10). This rule previously set `white-space: normal` and
   `vertical-align: top`. Measured on the live page, that let Blazer's Summary
   cell (bz_summary renders call_summary: 219 and 292 chars) wrap inside its
   320px cap to 85px and 119px of text, driving those rows to 102px and 136px
   while the rest of the row's content sat top-aligned in dead space.
   AloeVoice never showed it only because its Summary column renders the much
   shorter short_sentence_summary. Nothing to do with column order, the
   audio element (30px on both pages) or the transcript link.

   Long text is now clipped with an ellipsis exactly as the portal clips it;
   the full text is unchanged in the DOM. max-width is kept: measured, it is
   what holds the widest columns at 320px, so column widths are unchanged.

   REUSED (2026-09-11) by the call-import preview table on the client page —
   same defect, same cure. Its value cells carried white-space: nowrap (from
   .admin-table td) and an inline max-width with overflow: visible, so a long
   Airtable link or summary painted up to 358px over the next column. The
   selector is scoped to the preview's own marked cells (td.ci-pv-cell inside
   #call-import-preview); the full-width "Source row" cell carries no class,
   so this rule's max-width never reaches it. The cells' inline max-width
   (260px) still wins over the 320px here. */
#acl-table td,
#call-import-preview td.ci-pv-cell {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  vertical-align: middle;
  max-width: 320px;
}

#acl-table td[data-col="call_id"],
#acl-table td[data-col="phone"],
#acl-table td[data-col="agent_phone"] { white-space: nowrap; }

.acl-pager {
  display: flex;
  align-items: center;
  gap: 12px;
  padding-top: 12px;
}

/* The Client cell must stay a real TABLE CELL.

   Layout fix (2026-09-10). This previously set `display: flex` on the
   .acl-client-cell class — and that class sits on the <td> itself
   (admin-call-logs.js renderTable). A flex <td> is no longer a table-cell, so
   it stopped stretching to the row's height: measured at a fixed 49px inside
   rows of 102px and 136px, its bottom divider stopped 52px and 86px short of
   the row's. Every other cell was table-cell and stretched correctly.

   The company name and client id are now stacked by making the two CHILDREN
   block-level, which leaves the <td> in table layout. The 2px gap the flex
   column provided is reproduced with margin-top on the second line. */
#acl-table td.acl-client-cell > span,
#acl-table td.acl-client-cell > small {
  display: block;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

#acl-table td.acl-client-cell > small {
  margin-top: 2px;
  color: var(--admin-text-muted);
  font-size: 11px;
}

/* Transcript overlay */
.acl-modal {
  position: fixed;
  inset: 0;
  display: none;
  z-index: 60;
}

.acl-modal.open { display: block; }

.acl-modal-backdrop {
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, 0.6);
}

.acl-modal-card {
  position: relative;
  width: min(820px, calc(100% - 32px));
  max-height: 78vh;
  margin: 8vh auto 0;
  display: flex;
  flex-direction: column;
  background: var(--admin-surface);
  border: 1px solid var(--admin-border);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-lg);
}

.acl-modal-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 14px 16px;
  border-bottom: 1px solid var(--admin-border);
}

.acl-modal-head h3 { margin: 0; font-size: 15px; }

.acl-modal-body {
  margin: 0;
  padding: 16px;
  overflow: auto;
  white-space: pre-wrap;
  font-family: var(--font-mono);
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--admin-text);
}

/* ── Admin call-logs DETAIL modal (2026-09-10) ─────────────────────────────
   admin.css had no label/value grid to reuse: the only candidate,
   .admin-ticket-detail-grid, is the tickets page's two-pane layout (content |
   260px sidebar), not a key/value list. These are new, prefixed acl- and
   scoped to this page's modal, built only from admin.css's own tokens — the
   admin page never loads portal.css. The modal shell itself (.acl-modal,
   .acl-modal-card, .acl-modal-head) is the transcript overlay's, reused. */
.acl-detail-card { width: min(980px, calc(100% - 32px)); }

.acl-detail-body {
  flex: 1 1 auto;
  min-height: 0;          /* lets the body scroll inside the card's max-height */
  overflow: auto;
  padding: 16px;
}

.acl-detail-grid {
  display: grid;
  grid-template-columns: minmax(140px, 200px) minmax(0, 1fr);
  gap: 8px 16px;
  margin: 0;
}

.acl-detail-grid dt {
  padding-top: 2px;
  color: var(--admin-text-muted);
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.acl-detail-grid dd {
  margin: 0;
  min-width: 0;
  color: var(--admin-text);
  font-size: 13px;
  overflow-wrap: anywhere;
}

/* Transcripts in FULL (the table shows a six-word snippet). */
.acl-detail-full {
  margin: 0;
  max-height: 280px;
  overflow: auto;
  padding: 8px 10px;
  white-space: pre-wrap;
  font-family: var(--font-mono);
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--admin-text);
  background: var(--admin-surface-hover);
  border: 1px solid var(--admin-border);
  border-radius: var(--radius-sm);
}

.acl-detail-section { margin-top: 16px; }

.acl-detail-section h4 {
  margin: 0 0 6px;
  color: var(--admin-text-muted);
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

/* Rows open the modal on click. */
#acl-body tr[data-call-id] { cursor: pointer; }
