/* Premier ops dashboard — app shell and dashboard-only components.
 *
 * Loads after static/tokens.css, which owns the token layer and every
 * primitive (button, field, panel, table, badge, alert). Nothing here should
 * introduce a colour: if a rule needs one that isn't a token, the token layer
 * is missing it.
 *
 * Layout model: a two-column CSS grid at desktop (rail + content) that
 * collapses to a single column with an off-canvas rail below --bp-rail. There
 * is no JS involved in the responsive behaviour — only in opening the drawer.
 */

:root {
  --rail-w: 15.5rem;
  --topbar-h: 3.75rem;
  /* Dense controls read better square-ish than as pills; the pill shape stays
     on the public billing site where it is part of the brand voice. */
  --btn-radius: 8px;
}

/* ── app shell ───────────────────────────────────────────────────────────── */

.app {
  min-height: 100vh;
  min-height: 100dvh;
  display: grid;
  grid-template-columns: 1fr;
}

@media (min-width: 62rem) {
  .app { grid-template-columns: var(--rail-w) minmax(0, 1fr); }
}

/* ── rail (sidebar) ──────────────────────────────────────────────────────── */

.rail {
  position: fixed;
  inset: 0 auto 0 0;
  z-index: 60;
  width: min(var(--rail-w), 85vw);
  display: flex;
  flex-direction: column;
  background: var(--bg-sunken);
  border-right: 1px solid var(--line);
  transform: translateX(-100%);
  transition: transform 0.22s ease;
  overscroll-behavior: contain;
}
.rail[data-open="true"] { transform: none; }

@media (min-width: 62rem) {
  .rail { position: sticky; top: 0; height: 100vh; height: 100dvh; width: auto; transform: none; }
}

.rail-scrim {
  position: fixed;
  inset: 0;
  z-index: 55;
  background: rgb(0 0 0 / 0.55);
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.22s ease, visibility 0.22s ease;
}
.rail-scrim[data-open="true"] { opacity: 1; visibility: visible; }
@media (min-width: 62rem) { .rail-scrim { display: none; } }

.rail-brand {
  display: flex;
  align-items: center;
  gap: 0.65rem;
  padding: 0 var(--space-4);
  height: var(--topbar-h);
  flex: none;
  border-bottom: 1px solid var(--line);
  color: var(--text);
  text-decoration: none;
  font-weight: 700;
  letter-spacing: -0.015em;
}
.rail-mark {
  display: grid;
  place-items: center;
  width: 1.9rem;
  height: 1.9rem;
  flex: none;
  border-radius: 8px;
  overflow: hidden;
  background: var(--accent);
  color: var(--accent-ink);
}
.rail-mark .icon { width: 1.05rem; height: 1.05rem; stroke-width: 2.2; }
.rail-mark img { width: 100%; height: 100%; object-fit: cover; }

.rail-nav {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  padding: var(--space-3) var(--space-2) var(--space-4);
}

.rail-group {
  padding: var(--space-4) var(--space-3) var(--space-2);
  font-size: var(--step--2);
  font-weight: 700;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  /* --text-muted, not --text-faint: the old #475569 on #0f172a measured
     2.36:1, which fails WCAG AA for text this small by a wide margin. */
  color: var(--text-muted);
}
.rail-group:first-child { padding-top: var(--space-2); }

.rail-link {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  padding: 0.55rem 0.75rem;
  margin-bottom: 0.1rem;
  border-radius: 8px;
  color: var(--text-muted);
  text-decoration: none;
  font-size: var(--step--1);
  font-weight: 550;
  min-height: 40px;
  transition: background-color 0.14s ease, color 0.14s ease;
}
.rail-link .icon { color: var(--text-faint); transition: color 0.14s ease; }
.rail-link:hover { background: var(--bg-elevated); color: var(--text); }
.rail-link:hover .icon { color: var(--text-muted); }

/* The current page is marked with aria-current in the markup and styled from
   it, so the visual state and the assistive-tech state cannot drift apart. */
.rail-link[aria-current="page"] {
  background: var(--accent-soft);
  color: var(--text);
  font-weight: 650;
  box-shadow: inset 2px 0 0 var(--accent);
}
.rail-link[aria-current="page"] .icon { color: var(--accent); }

.rail-foot {
  flex: none;
  padding: var(--space-3);
  border-top: 1px solid var(--line);
}
.rail-user {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.35rem 0.25rem;
}
.rail-avatar {
  display: grid;
  place-items: center;
  width: 2rem;
  height: 2rem;
  flex: none;
  border-radius: 8px;
  background: var(--accent-soft);
  border: 1px solid var(--accent-line);
  color: color-mix(in oklab, var(--accent) 65%, var(--text));
  font-size: var(--step--1);
  font-weight: 700;
}
.rail-user-name { font-size: var(--step--1); font-weight: 600; }
.rail-user-role { font-size: var(--step--2); color: var(--text-muted); }

/* ── topbar ──────────────────────────────────────────────────────────────── */

.shell { display: flex; flex-direction: column; min-width: 0; }

.topbar {
  position: sticky;
  top: 0;
  z-index: 40;
  display: flex;
  align-items: center;
  gap: var(--space-3);
  height: var(--topbar-h);
  padding: 0 var(--gutter);
  background: color-mix(in oklab, var(--bg) 88%, transparent);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--line);
}
.topbar-title {
  margin: 0;
  font-size: var(--step-1);
  font-weight: 650;
  letter-spacing: -0.015em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.icon-btn {
  display: grid;
  place-items: center;
  width: 40px;
  height: 40px;
  flex: none;
  padding: 0;
  border: 1px solid transparent;
  border-radius: 8px;
  background: transparent;
  color: var(--text-muted);
  cursor: pointer;
}
.icon-btn:hover { background: var(--bg-elevated); color: var(--text); }
.rail-toggle { display: grid; }
@media (min-width: 62rem) { .rail-toggle { display: none; } }

.crumbs {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  font-size: var(--step--1);
  color: var(--text-muted);
}
.crumbs a { text-decoration: none; }
.crumbs a:hover { color: var(--text); text-decoration: underline; }
.crumbs [aria-current="page"] { color: var(--text); font-weight: 600; }
.crumbs .sep { color: var(--text-faint); }
@media (max-width: 47.99rem) { .crumbs { display: none; } }

/* ── content ─────────────────────────────────────────────────────────────── */

.content {
  flex: 1;
  padding: var(--space-5) var(--gutter) var(--space-7);
  min-width: 0;
}

.page-head { margin-bottom: var(--space-5); }
.page-head h1 { margin-bottom: 0.15rem; font-size: var(--step-2); }
.page-head p { color: var(--text-muted); font-size: var(--step--1); margin: 0; }

/* ── stat tiles ──────────────────────────────────────────────────────────── */

.stat {
  display: flex;
  flex-direction: column;
  gap: 0.1rem;
  padding: var(--space-4);
  background: var(--bg-elevated);
  border: 1px solid var(--line);
  border-radius: var(--radius);
}
.stat-top { display: flex; align-items: center; justify-content: space-between; gap: var(--space-2); }
.stat-label {
  font-size: var(--step--2);
  font-weight: 650;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--text-muted);
}
.stat-value {
  font-size: var(--step-3);
  font-weight: 700;
  letter-spacing: -0.03em;
  line-height: 1.1;
  font-variant-numeric: tabular-nums;
  /* Reserve the line box before JS fills the number in, so the tile does not
     resize under the reader's eye when the fetch lands. */
  min-height: 1.1em;
}
.stat-sub { font-size: var(--step--2); color: var(--text-muted); }
.stat-mark {
  display: grid;
  place-items: center;
  width: 2rem;
  height: 2rem;
  flex: none;
  border-radius: 8px;
  background: var(--bg-sunken);
  border: 1px solid var(--line);
  color: var(--text-muted);
}
.stat-mark.accent { background: var(--accent-soft); border-color: var(--accent-line); color: color-mix(in oklab, var(--accent) 72%, var(--text)); }
.stat-mark.ok { background: var(--ok-soft); border-color: color-mix(in oklab, var(--ok) 35%, transparent); color: var(--ok); }
.stat-mark.warn { background: var(--warn-soft); border-color: color-mix(in oklab, var(--warn) 35%, transparent); color: var(--warn); }
.stat-mark.info { background: var(--info-soft); border-color: color-mix(in oklab, var(--info) 35%, transparent); color: var(--info); }
.stat-mark.danger { background: var(--danger-soft); border-color: color-mix(in oklab, var(--danger) 35%, transparent); color: var(--danger); }

/* Placeholder shimmer while a value is still loading. Reduced-motion viewers
   get the flat block, which still reads as "not a number yet". */
.is-loading {
  display: inline-block;
  min-width: 2.5ch;
  border-radius: 5px;
  color: transparent;
  background: linear-gradient(90deg, var(--bg-sunken) 25%, var(--line) 50%, var(--bg-sunken) 75%) 0 0 / 200% 100%;
  animation: shimmer 1.3s linear infinite;
}
@keyframes shimmer { to { background-position: -200% 0; } }

/* ── data tables ─────────────────────────────────────────────────────────── */

.panel > .table-scroll > .table { margin: 0; }
.panel > .table-scroll thead th { background: var(--bg-sunken); }

/* Below the rail breakpoint a wide table stops being a table: each row becomes
   a labelled card, driven entirely by the data-label the row renderer writes.
   This is the difference between "the dashboard works on a phone" and "the
   dashboard has a horizontal scrollbar on a phone". */
@media (max-width: 47.99rem) {
  .table-cards thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }
  .table-cards, .table-cards tbody, .table-cards tr, .table-cards td { display: block; width: 100%; }
  .table-cards tr {
    border: 1px solid var(--line);
    border-radius: var(--radius-sm);
    margin-bottom: var(--space-3);
    padding: var(--space-2) var(--space-3);
    background: var(--bg-elevated);
  }
  .table-cards tr:last-child { margin-bottom: 0; }
  .table-cards td {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--space-4);
    border: 0;
    padding: 0.3rem 0;
    text-align: right;
  }
  .table-cards td::before {
    content: attr(data-label);
    flex: none;
    font-size: var(--step--2);
    font-weight: 650;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--text-muted);
    text-align: left;
  }
  .table-cards td:empty { display: none; }
  .table-cards tbody tr:hover td { background: none; }
  .table-cards .empty-row td { display: block; text-align: center; }
  .table-cards .empty-row td::before { content: none; }
}

/* A polled region announces itself politely; without aria-live a screen reader
   never learns the table changed under it. */
.live-region { position: relative; }
.live-region[data-stale="true"] { opacity: 0.55; transition: opacity 0.2s ease; }

.refresh-note {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  font-size: var(--step--2);
  color: var(--text-faint);
}

/* ── disclosure (replaces the Bootstrap accordion + its JS) ──────────────── */

.disclosure { border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--bg-elevated); }
.disclosure + .disclosure { margin-top: var(--space-2); }
.disclosure > summary {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.7rem var(--space-4);
  min-height: 44px;
  cursor: pointer;
  font-weight: 600;
  font-size: var(--step--1);
  list-style: none;
  border-radius: inherit;
}
.disclosure > summary::-webkit-details-marker { display: none; }
.disclosure > summary::after {
  content: "";
  margin-left: auto;
  width: 0.55rem; height: 0.55rem;
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  transform: rotate(45deg) translate(-2px, -2px);
  color: var(--text-faint);
  transition: transform 0.18s ease;
}
.disclosure[open] > summary::after { transform: rotate(-135deg) translate(-2px, -2px); }
.disclosure[open] > summary { border-bottom: 1px solid var(--line); border-radius: var(--radius-sm) var(--radius-sm) 0 0; }
.disclosure > summary:hover { background: var(--bg-sunken); }
.disclosure-body { padding: var(--space-4); }
.disclosure-body > :last-child { margin-bottom: 0; }

/* ── tabs ────────────────────────────────────────────────────────────────── */

/* Progressive enhancement: app.js hides every panel but the active one and
   drives selection off the URL hash so a section stays linkable/bookmarkable.
   With JS disabled no panel ever gets [hidden], so the page falls back to
   today's plain stacked layout — this must never be the only way to reach
   the content. */
.tabs {
  display: flex;
  flex-wrap: wrap;
  gap: 0.25rem;
  border-bottom: 1px solid var(--line);
  margin-bottom: var(--space-4);
  overflow-x: auto;
}
.tab-btn {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.65rem var(--space-3);
  border: none;
  background: none;
  color: var(--text-muted);
  font: inherit;
  font-weight: 600;
  font-size: var(--step--1);
  white-space: nowrap;
  cursor: pointer;
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
}
.tab-btn:hover { color: var(--text); }
.tab-btn[aria-selected="true"] { color: var(--text); border-bottom-color: var(--accent); }
.tab-btn .icon { color: var(--text-faint); }
.tab-btn[aria-selected="true"] .icon { color: var(--accent); }
.tab-btn .badge { margin-left: 0.15rem; }

.tab-panel { display: flex; flex-direction: column; gap: var(--space-4); }
.tab-panel[hidden] { display: none; }

/* ── calls (live-ops two-column layout) ─────────────────────────────────────
   The page's actual loop is watch-what's-live + act-on-it + note-it, so
   those three panels share a main column that never scrolls out of view
   together; call-initiation (browser softphone, place a call) is occasional
   by comparison and lives in a side column instead of pushing the live
   table down the page. Below --bp-rail it collapses to one column with the
   side column *after* the main one, so an outbound-call form never bumps
   live monitoring off a phone screen. */
.call-layout {
  display: grid;
  gap: var(--space-4);
  grid-template-columns: 1fr;
}
@media (min-width: 62rem) {
  .call-layout { grid-template-columns: minmax(0, 1.6fr) minmax(18rem, 1fr); align-items: start; }
}
.call-main, .call-side { display: flex; flex-direction: column; gap: var(--space-4); min-width: 0; }

/* ── discord browser (mini-Discord: servers → channels → messages) ─────────
   Stacks on a phone (each pane is meaningless before you've picked from the
   one before it, so a stacked "pick a server, then a channel" flow reads
   fine there); a fixed-height three-column grid with independently
   scrolling panes on desktop, like a real chat client, so the message pane
   doesn't grow the whole page. */
.discord-browser {
  display: grid;
  grid-template-columns: 1fr;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
  background: var(--bg-elevated);
}
@media (min-width: 62rem) {
  .discord-browser {
    grid-template-columns: 14rem 16rem minmax(0, 1fr);
    height: min(48rem, calc(100vh - 14rem));
  }
}

.discord-pane { display: flex; flex-direction: column; min-height: 0; }
.discord-guilds, .discord-channels { border-bottom: 1px solid var(--line); }
@media (min-width: 62rem) {
  .discord-guilds, .discord-channels { border-bottom: none; border-right: 1px solid var(--line); overflow-y: auto; }
}

.discord-guild-list, .discord-channel-list { list-style: none; margin: 0; padding: 0.4rem; }
.discord-guild-btn, .discord-channel-btn {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.15rem;
  width: 100%;
  text-align: left;
  padding: 0.5rem 0.6rem;
  border: none;
  background: none;
  border-radius: var(--radius-sm);
  color: var(--text);
  font: inherit;
  cursor: pointer;
}
.discord-channel-btn { font-size: var(--step--1); }
.discord-guild-btn:hover, .discord-channel-btn:hover { background: var(--bg-sunken); }
.discord-guild-btn[aria-current="true"], .discord-channel-btn[aria-current="true"] {
  background: var(--bg-sunken);
  color: var(--accent-text);
  font-weight: 600;
}
.discord-guild-name { font-weight: 600; }

.discord-messages { min-height: 20rem; }
.discord-messages-head {
  padding: 0.75rem var(--space-4);
  border-bottom: 1px solid var(--line);
  flex: none;
}
.discord-message-pane {
  flex: 1;
  overflow-y: auto;
  padding: var(--space-3) var(--space-4);
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}
.discord-msg-meta { display: flex; align-items: baseline; gap: 0.5rem; }
.discord-msg-author { font-weight: 600; font-size: var(--step--1); }
.discord-msg-author-bot { color: var(--accent-text); }
.discord-msg-content { margin: 0.15rem 0 0; white-space: pre-wrap; overflow-wrap: anywhere; }
.note-text { white-space: pre-wrap; overflow-wrap: anywhere; }

.discord-composer {
  display: flex;
  gap: 0.5rem;
  align-items: flex-end;
  padding: var(--space-3) var(--space-4);
  border-top: 1px solid var(--line);
  flex: none;
}
.discord-composer .textarea { flex: 1; resize: vertical; }

/* ── misc ────────────────────────────────────────────────────────────────── */

.kv { display: grid; grid-template-columns: auto 1fr; gap: 0.35rem var(--space-4); font-size: var(--step--1); }
.kv dt { color: var(--text-muted); }
.kv dd { margin: 0; overflow-wrap: anywhere; }

.toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
  margin-bottom: var(--space-4);
}
.toolbar .input, .toolbar .select { width: auto; min-width: 8rem; }

.form-grid {
  display: grid;
  gap: var(--space-3) var(--space-4);
  grid-template-columns: repeat(auto-fit, minmax(min(13rem, 100%), 1fr));
  align-items: end;
}
.form-grid .field { margin-bottom: 0; }

/* Flash + inline results stack under the topbar rather than pushing content. */
.flash-stack { margin-bottom: var(--space-4); }
.flash-stack:empty { display: none; }

/* ── modal (native <dialog>) ─────────────────────────────────────────────── */

.modal {
  width: min(var(--modal-w, 34rem), calc(100vw - 2rem));
  max-height: min(85dvh, 48rem);
  padding: 0;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  background: var(--bg-elevated);
  color: var(--text);
  box-shadow: 0 24px 60px -20px rgb(0 0 0 / 0.55);
  overflow: hidden;
}
.modal::backdrop { background: rgb(0 0 0 / 0.55); backdrop-filter: blur(2px); }
.modal[open] { display: flex; flex-direction: column; animation: modal-in 0.16s ease-out; }
@keyframes modal-in { from { opacity: 0; transform: translateY(6px) scale(0.99); } }

.modal-head {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-4) var(--space-5);
  border-bottom: 1px solid var(--line);
  flex: none;
}
.modal-title {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  margin: 0;
  font-size: var(--step-0);
  font-weight: 650;
  flex: 1;
  min-width: 0;
}
.modal-title .icon { color: var(--accent); }
.modal-body { padding: var(--space-5); overflow-y: auto; }
.modal-body > :last-child { margin-bottom: 0; }

/* Below the rail breakpoint a dialog is a sheet: full width, anchored to the
   bottom, which is where a thumb is. */
@media (max-width: 47.99rem) {
  .modal {
    width: 100vw;
    max-width: 100vw;
    max-height: 88dvh;
    margin: auto auto 0;
    border-radius: var(--radius) var(--radius) 0 0;
    border-bottom: 0;
  }
  .modal[open] { animation: sheet-in 0.18s ease-out; }
  @keyframes sheet-in { from { transform: translateY(100%); } }
}

/* ── search ──────────────────────────────────────────────────────────────── */

.search-form { margin-bottom: 0; }
.search-field { position: relative; flex: 1 1 14rem; min-width: 0; }
.search-field .input { padding-left: 2.2rem; }
.search-field .search-icon {
  position: absolute;
  left: 0.65rem;
  top: 50%;
  transform: translateY(-50%);
  color: var(--text-faint);
  pointer-events: none;
}
/* Safari draws its own clear button on type=search; keep ours consistent. */
.search-field input[type="search"]::-webkit-search-decoration,
.search-field input[type="search"]::-webkit-search-cancel-button { -webkit-appearance: none; }

/* ── pagination ──────────────────────────────────────────────────────────── */

.pager {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-5);
  border-top: 1px solid var(--line);
  background: var(--bg-sunken);
}
.pager-count { margin: 0; font-size: var(--step--1); color: var(--text-muted); }
.pager-list { display: flex; flex-wrap: wrap; align-items: center; gap: 0.25rem; list-style: none; margin: 0; padding: 0; }
.pager-link {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 40px;
  min-height: 40px;              /* pointer target floor, same as .btn */
  padding: 0 0.6rem;
  border: 1px solid transparent;
  border-radius: 8px;
  font-size: var(--step--1);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: var(--text-muted);
  text-decoration: none;
}
.pager-link:hover { background: var(--bg-elevated); border-color: var(--line-strong); color: var(--text); }
.pager-link.is-current {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--accent-ink);
}
.pager-link.is-disabled { opacity: 0.35; pointer-events: none; }
.pager-gap { display: inline-flex; min-width: 1.5rem; justify-content: center; color: var(--text-faint); }
.icon.flip { transform: scaleX(-1); }

/* ── admin section nav ───────────────────────────────────────────────────── */

.rail-sub { display: block; }
.rail-sub > summary {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  padding: 0.55rem 0.75rem;
  min-height: 40px;
  border-radius: 8px;
  color: var(--text-muted);
  font-size: var(--step--1);
  font-weight: 550;
  cursor: pointer;
  list-style: none;
}
.rail-sub > summary::-webkit-details-marker { display: none; }
.rail-sub > summary:hover { background: var(--bg-elevated); color: var(--text); }
.rail-sub > summary .icon:first-child { color: var(--text-faint); }
.rail-sub > summary::after {
  content: "";
  margin-left: auto;
  width: 0.45rem; height: 0.45rem;
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  transform: rotate(45deg) translate(-1px, -1px);
  color: var(--text-faint);
  transition: transform 0.18s ease;
}
.rail-sub[open] > summary::after { transform: rotate(-135deg) translate(-1px, -1px); }
.rail-sub[open] > summary { color: var(--text); }
.rail-sub-items { padding: 0.15rem 0 0.35rem 0.75rem; border-left: 1px solid var(--line); margin-left: 1.05rem; }
.rail-sub-items .rail-link { padding-left: 0.6rem; font-size: var(--step--2); min-height: 34px; }

/* Rendered Outline Markdown (templates/docs_document.html) — the only place
   in the app that shows staff-authored long-form prose rather than a table
   or a form. */
.prose { max-width: 68ch; line-height: 1.65; }
.prose :first-child { margin-top: 0; }
.prose :last-child { margin-bottom: 0; }
.prose h1, .prose h2, .prose h3, .prose h4 { line-height: 1.3; margin: 1.6em 0 0.6em; color: var(--text); }
.prose h1 { font-size: var(--step-2); }
.prose h2 { font-size: var(--step-1); }
.prose h3, .prose h4 { font-size: var(--step-0); }
.prose p, .prose ul, .prose ol, .prose table, .prose blockquote { margin: 0 0 1em; }
.prose ul, .prose ol { padding-left: 1.4em; }
.prose a { color: var(--accent-text); }
.prose code { font-family: var(--font-mono); font-size: 0.9em; background: var(--bg-elevated); border-radius: 4px; padding: 0.15em 0.4em; }
.prose pre { background: var(--bg-elevated); border: 1px solid var(--line); border-radius: var(--radius-sm); padding: 0.9em 1em; overflow-x: auto; }
.prose pre code { background: none; padding: 0; }
.prose blockquote { border-left: 3px solid var(--line-strong); padding-left: 1em; color: var(--text-muted); }
.prose table { border-collapse: collapse; width: 100%; }
.prose th, .prose td { border: 1px solid var(--line); padding: 0.5em 0.75em; text-align: left; }
.prose img { max-width: 100%; border-radius: var(--radius-sm); }

/* Personal-call transcript (/admin/personal-calls) — a chat: the caller's
   bubbles on the left, the owner's own words on the right. */
.pcall-audio { width: 100%; }
.pcall-summary { margin: 0; white-space: pre-wrap; }
.pcall-bubbles {
  display: flex;
  flex-direction: column;
  gap: 0.45rem;
  max-height: 34rem;
  overflow-y: auto;
  padding: 0.2rem 0;
}
.pcall-row { display: flex; }
.pcall-owner { justify-content: flex-end; }
.pcall-bubble {
  max-width: min(46rem, 78%);
  border-radius: var(--radius-md, 12px);
  padding: 0.55rem 0.85rem;
  border: 1px solid var(--line);
  background: var(--bg-elevated);
}
.pcall-caller .pcall-bubble { border-bottom-left-radius: 4px; }
.pcall-owner .pcall-bubble {
  border-bottom-right-radius: 4px;
  background: var(--accent-soft);
  border-color: transparent;
  color: var(--accent-text);
}
.pcall-who {
  font-size: 0.72rem;
  font-weight: 600;
  opacity: 0.7;
  margin-bottom: 0.15rem;
}
.pcall-text { white-space: pre-wrap; overflow-wrap: anywhere; }
