/* AE dashboard — additions on top of the vendored Æthelstan build.
 *
 * app.css is COPIED from ae/vendor/royalist/dashboard/static/css/app.css: a
 * committed, minified Tailwind build (standalone CLI v3.4.17, `make css` in the
 * vendored dashboard — the Docker image has no node). It carries the design
 * tokens, the component layer (.card, .pill, .t-x, .num, .data-table, .btn,
 * .tab-btn) and exactly those Tailwind utilities the vendored templates used —
 * its JIT pass never saw these templates, so `grid-cols-3` and friends are NOT
 * in it. (Never let a star sit directly before a slash anywhere in this comment
 * — that closes it early, and CSS error recovery then eats the file's first
 * rule as part of the garbage selector. It silently ate .ae-shell for months.)
 *
 * Rather than stand up a second Tailwind build, everything new is plain CSS
 * here, written against the same custom properties (see the vendored DESIGN.md:
 * near-black, one accent, JetBrains Mono for numerals only).
 *
 * To rebuild app.css after changing the vendored design system:
 *   cd ae/vendor/royalist/dashboard && make css   # → static/css/app.css
 * then re-copy it to ae/control_plane/dashboard/static/css/app.css.
 */

/* ── brand tokens ──────────────────────────────────────────────────────────────
 * app.css is Royalist's build and ships a GOLD accent (#c9a961). Æthelstan's own
 * chrome is silver — the marketing site (aethelstan-site/src/styles/tokens.css)
 * is the source of truth. Re-point the accent here rather than re-minify the
 * vendored build; ae.css loads second, so these win.
 */
:root {
  --chrome-hi: #f5f6f8;
  --chrome-mid: #b9bec7;
  --chrome-lo: #5e636d;
  --chrome-gradient: linear-gradient(105deg, var(--chrome-lo), var(--chrome-hi) 40%, var(--chrome-mid) 55%, var(--chrome-hi) 70%, var(--chrome-lo));

  --accent: var(--chrome-mid);
  --accent-rgb: 185 190 199;
}

/* The vendored .btn-primary pairs its label with gold (a warm near-black). On
   silver that reads muddy — use the page's own near-black instead. */
.btn-primary { color: var(--bg-base); }

/* app.css hardcodes a gold wash behind every page. */
.backdrop-glow {
  background: radial-gradient(900px 500px at 28% -12%, rgb(var(--accent-rgb) / 0.05), transparent 70%);
}

/* ── layout ───────────────────────────────────────────────────────────────── */
.ae-shell { max-width: 1180px; margin: 0 auto; padding: 24px 20px 80px; }
.ae-main { position: relative; z-index: 10; padding-top: 56px; }
/* The gutter belongs to whichever rail the page actually renders, not to every
   page that extends base.html. It used to be unconditional, which indented the
   whole operator console 220px against an empty column. `.ae-main-railed` is
   the legacy customer rail (tenant.html); `.ae-main-ops` is the collapsed
   operator sidebar below, which is 56px until it is hovered. */
@media (min-width: 768px) {
  .ae-main-railed { padding-left: 220px; }
  .ae-main-ops { padding-left: 56px; }
}

.ae-stack > * + * { margin-top: 16px; }
.ae-row { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.ae-row-between { display: flex; align-items: center; justify-content: space-between; gap: 16px; flex-wrap: wrap; }
.ae-spacer { margin-left: auto; }

.ae-grid { display: grid; gap: 16px; grid-template-columns: 1fr; }
@media (min-width: 640px) { .ae-grid-2, .ae-grid-4 { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 1100px) { .ae-grid-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
@media (min-width: 900px) { .ae-grid-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); } }

.ae-scroll { overflow-x: auto; }
.ae-mb { margin-bottom: 16px; }
.ae-mb-sm { margin-bottom: 8px; }
.ae-mt { margin-top: 16px; }
.ae-mt-sm { margin-top: 8px; }
.ae-muted { color: var(--text-secondary); }

/* file picker + raw-markdown viewers for the operator's knowledge surface */
.ae-file { font-size: 12px; color: var(--text-secondary); }
.ae-disclosure { border: 1px solid var(--border); border-radius: 8px; padding: 10px 12px; }
.ae-disclosure summary { list-style: none; }
.ae-disclosure summary::-webkit-details-marker { display: none; }
.ae-pre {
  white-space: pre-wrap; word-break: break-word; font-size: 12px; line-height: 1.5;
  max-height: 340px; overflow-y: auto; margin: 0;
  color: var(--text-secondary); font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
}
.ae-body { font-size: 13px; color: var(--text-primary); }
.ae-max { max-width: 640px; }
.ae-nowrap { white-space: nowrap; }

/* ── the banner that must never be missed ─────────────────────────────────────
 * Parallel-build / paused: someone will otherwise believe posts are going out.
 * Amber, top of every page, above the fold, never dismissible.
 */
.banner-dry {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  padding: 16px 20px;
  margin-bottom: 20px;
  border-radius: 12px;
  background: rgb(251 191 36 / 0.08);
  border: 1px solid rgb(251 191 36 / 0.35);
  border-top-color: rgb(251 191 36 / 0.55);
}
.banner-dry-title { font-size: 14px; font-weight: 600; color: #fcd34d; }
.banner-dry-body { font-size: 13px; color: var(--text-secondary); margin-top: 3px; }
.banner-dry-tag {
  flex-shrink: 0;
  font-family: "JetBrains Mono", ui-monospace, monospace;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.1em;
  padding: 3px 8px;
  border-radius: 5px;
  color: #171307;
  background: var(--warn);
}

/* The red sibling of the dry-run banner: the dispatcher has gone quiet, so the
 * whole page may be describing a system that is no longer running. */
.banner-down {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  padding: 16px 20px;
  margin-bottom: 20px;
  border-radius: 12px;
  background: rgb(248 113 113 / 0.08);
  border: 1px solid rgb(248 113 113 / 0.4);
  border-top-color: rgb(248 113 113 / 0.6);
}
.banner-down-title { font-size: 14px; font-weight: 600; color: #fca5a5; }
.banner-down-body { font-size: 13px; color: var(--text-secondary); margin-top: 3px; }
.banner-down-tag {
  flex-shrink: 0;
  font-family: "JetBrains Mono", ui-monospace, monospace;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.1em;
  padding: 3px 8px;
  border-radius: 5px;
  color: #1a0808;
  background: var(--bad);
}

/* Pinned broken lanes on a tenant card: red, above the feed, immune to scroll-off. */
.lane-fails {
  margin-top: 14px;
  border: 1px solid rgb(248 113 113 / 0.4);
  background: rgb(248 113 113 / 0.06);
  border-radius: 8px;
  padding: 10px 12px;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.lane-fails-page { margin-top: 0; padding: 14px 16px; }
.lane-fail { font-size: 12.5px; line-height: 1.5; overflow-wrap: anywhere; }
.lane-fail-name { font-weight: 600; color: var(--bad); margin-right: 6px; }
.lane-fail-body { color: var(--text-secondary); }

/* The mute controls under a failing lane. Deliberately quiet: muting is a real
 * decision, not a dismiss button, and it must not out-shout the failure it sits
 * under. Wraps, because the reason field is a sentence on a narrow screen. */
.lane-mute {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  margin-top: 8px;
  color: var(--text-secondary);
  font-size: 12px;
}
.lane-mute .input-sm {
  font-size: 12px;
  padding: 3px 6px;
  height: auto;
  width: auto;
}
.lane-mute .input-sm[name="reason"] { flex: 1 1 260px; min-width: 0; }
.btn-sm { font-size: 12px; padding: 3px 9px; }

/* A filed incident carries a paragraph of detail, the remediation and a button,
 * so it is a bordered block rather than the one-line lane row above. */
.lane-fail-block {
  border: 1px solid rgb(248 113 113 / 0.4);
  background: rgb(248 113 113 / 0.06);
  border-radius: 8px;
  padding: 12px 14px;
}
.lane-fail-block .lane-fail-name { margin-right: 0; }

/* The per-run badge. Same amber vocabulary as the banner, so a DRY RUN row and
 * the page banner read as one fact, not two. */
.badge-dry {
  display: inline-flex;
  align-items: center;
  font-family: "JetBrains Mono", ui-monospace, monospace;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.08em;
  padding: 2px 7px;
  border-radius: 5px;
  color: var(--warn);
  background: rgb(251 191 36 / 0.14);
  border: 1px solid rgb(251 191 36 / 0.3);
  white-space: nowrap;
}

/* No password set: the operator should know the page is open to anyone. */
.banner-open {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 12px 16px;
  margin-bottom: 16px;
  border-radius: 10px;
  font-size: 13px;
  color: var(--text-secondary);
  background: var(--bg-overlay);
  border: 1px solid var(--border-subtle);
}

/* ── status pills not in the vendored set ────────────────────────────────── */
.pill-succeeded { color: var(--ok); background: rgb(74 222 128 / 0.12); }
.pill-running   { color: var(--accent); background: rgb(var(--accent-rgb) / 0.12); }
.pill-queued2   { color: var(--text-secondary); background: rgb(138 138 147 / 0.12); }
.pill-timed_out { color: var(--bad); background: rgb(248 113 113 / 0.12); }
.pill-skipped   { color: var(--text-secondary); background: rgb(138 138 147 / 0.12); }
.pill-off       { color: var(--text-secondary); background: rgb(138 138 147 / 0.12); }
.pill-on        { color: var(--ok); background: rgb(74 222 128 / 0.12); }
.pill-active    { color: var(--ok); background: rgb(74 222 128 / 0.12); }
.pill-demo      { color: var(--accent); background: rgb(var(--accent-rgb) / 0.12); }
.pill-churned   { color: var(--text-secondary); background: rgb(138 138 147 / 0.12); }

/* ── operator overview: one card per account ─────────────────────────────── */
.tenant-card {
  display: block;
  color: inherit;
  text-decoration: none;
  background: var(--bg-raised);
  border: 1px solid var(--border-subtle);
  border-top-color: var(--border-highlight);
  border-radius: 12px;
  padding: 20px;
  transition: transform 100ms ease, border-color 100ms ease;
}
.tenant-card:hover { transform: translateY(-1px); border-color: var(--border-highlight); }

/* The bigger overview card: the account summary is a link (head), the agent's
 * narrated diary sits below it. The card itself is no longer an <a> — the feed
 * carries its own links — so the head keeps the click affordance instead. */
.tenant-card-lg { padding: 22px 22px 18px; }
.tenant-card-head { display: block; color: inherit; text-decoration: none; }
.tenant-card-head:hover .tenant-name { color: var(--accent); }

.tenant-activity {
  margin-top: 16px;
  padding-top: 14px;
  border-top: 1px solid var(--border-subtle);
}
.tenant-activity-more {
  font-size: 12px;
  color: var(--text-secondary);
  text-decoration: none;
  white-space: nowrap;
}
.tenant-activity-more:hover { color: var(--text-primary); }

.activity-feed { list-style: none; margin: 10px 0 0; padding: 0; }
.activity-row {
  display: flex;
  gap: 10px;
  padding: 7px 0;
}
.activity-row + .activity-row { border-top: 1px solid rgb(38 38 44 / 0.35); }
.activity-dot {
  flex-shrink: 0;
  width: 7px; height: 7px;
  border-radius: 50%;
  margin-top: 5px;
  background: var(--ok);
}
.activity-failed .activity-dot { background: var(--bad); }
.activity-running .activity-dot { background: var(--warn); }
.activity-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
}
.activity-title { font-size: 12.5px; font-weight: 600; color: var(--text-primary); }
.activity-failed .activity-title { color: var(--bad); }
.activity-when {
  font-family: "JetBrains Mono", ui-monospace, monospace;
  font-size: 10.5px;
  color: var(--text-tertiary);
  white-space: nowrap;
}
.activity-detail {
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--text-secondary);
  margin-top: 1px;
  overflow-wrap: anywhere;
}

/* The full-page log reuses the card feed, roomier. */
.activity-feed-page .activity-row { padding: 11px 0; }
.activity-expand { margin-top: 6px; }
.activity-expand summary {
  cursor: pointer;
  font-size: 11.5px;
  color: var(--text-tertiary);
  list-style: none;
}
.activity-expand summary::-webkit-details-marker { display: none; }
.activity-expand summary::before { content: "▸ "; }
.activity-expand[open] summary::before { content: "▾ "; }
.activity-expand summary:hover { color: var(--text-primary); }
.activity-expand .ae-pre { margin-top: 6px; }

/* Archived accounts stay in the operator list, dimmed — present but out of the way. */
.ops-archived { opacity: 0.6; }
.ops-archived:hover { opacity: 0.85; }
.tenant-name { font-size: 15px; font-weight: 600; color: var(--text-primary); }
.tenant-meta { font-size: 12px; color: var(--text-secondary); margin-top: 2px; }
.tenant-pills { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 14px; }
.tenant-foot {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  margin-top: 14px;
  padding-top: 12px;
  border-top: 1px solid var(--border-subtle);
  font-size: 12px;
  color: var(--text-secondary);
}

/* ── native form controls, de-natived ─────────────────────────────────────────
 * The vendored .input styles text boxes but leaves <select> to the OS, which on
 * macOS renders the beveled legacy dropdown — the one control on the console
 * that ignores the design system. appearance:none takes the chrome back; the
 * chevron is inline SVG in the token silver so it follows the theme. Applied to
 * every select.input console-wide (operator + customer forms share the class).
 */
select.input {
  -webkit-appearance: none;
  -moz-appearance: none;
  appearance: none;
  color: var(--text-primary);
  background-color: var(--bg-overlay);
  background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%238a8a93' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 10px center;
  padding-right: 34px;
  cursor: pointer;
}
select.input:hover { border-color: var(--border-highlight); }
select.input:focus { border-color: var(--border-highlight); outline: none; }
/* The popup list itself is OS-drawn; these are the two knobs it does honor. */
select.input option { background: var(--bg-overlay); color: var(--text-primary); }

/* Date inputs: keep the dark scheme and swap the white calendar glyph for one
 * in the console's silver. */
input.input[type="date"] { color-scheme: dark; cursor: pointer; }
input.input[type="date"]::-webkit-calendar-picker-indicator {
  opacity: 0.55;
  cursor: pointer;
}
input.input[type="date"]::-webkit-calendar-picker-indicator:hover { opacity: 1; }

/* Checkboxes and radios pick up the accent instead of OS blue. */
.ae-check input[type="checkbox"],
.ae-radio input[type="radio"] {
  accent-color: var(--accent);
  width: 15px;
  height: 15px;
}

/* Buttons: the vendored .btn has no pressed state and inherits the UA's focus
 * ring; give it the same motion vocabulary as the cards. */
.btn { display: inline-flex; align-items: center; }
.btn:active { transform: translateY(1px); }
.btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.btn svg { flex-shrink: 0; }

/* An inline select (filters, toolbars) — the block-level 100% width is for forms. */
.input-select { width: auto; }

/* ── the reports tab ──────────────────────────────────────────────────────── */
.report-form { padding: 20px 22px; }
.report-checks { display: flex; flex-direction: column; gap: 8px; }
.report-checks .ae-check { font-size: 13px; }

/* ── empty states: an invitation, never an error ──────────────────────────── */
.ae-empty {
  padding: 28px 24px;
  text-align: center;
  border-radius: 12px;
  border: 1px dashed var(--border-subtle);
  background: rgb(23 23 27 / 0.4);
}
.ae-empty-title { font-size: 14px; font-weight: 600; color: var(--text-primary); }
.ae-empty-body {
  font-size: 13px;
  color: var(--text-secondary);
  margin: 6px auto 0;
  max-width: 460px;
  line-height: 1.6;
}

/* ── audience knowledge ───────────────────────────────────────────────────── */
.ae-know { max-height: 320px; overflow-y: auto; padding-right: 8px; }

/* ── header ───────────────────────────────────────────────────────────────── */
.ae-header {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 30;
  height: 56px;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 0 20px;
  background: rgb(10 10 12 / 0.92);
  backdrop-filter: blur(8px);
  border-bottom: 1px solid var(--border-subtle);
}
.ae-mark {
  display: grid;
  place-items: center;
  height: 32px;
  width: 32px;
  flex-shrink: 0;
  border-radius: 8px;
  border: 1px solid rgb(var(--accent-rgb) / 0.4);
  background: var(--bg-raised);
  font-family: Georgia, "Times New Roman", serif;
  font-size: 17px;
  font-weight: 700;
  /* Bright chrome, not the mid tone — the Æ is small and needs the extra lift.
     (Not the gradient: background-clip:text would eat the medallion plate.) */
  color: var(--chrome-hi);
  text-decoration: none;
}
.ae-wordmark { font-size: 13px; font-weight: 600; letter-spacing: 0.14em; color: var(--text-primary); }
.ae-subword { font-size: 10px; text-transform: uppercase; letter-spacing: 0.18em; color: var(--text-secondary); }

/* ── tab rail (desktop left, mobile bottom) ───────────────────────────────── */
.ae-rail {
  position: fixed;
  z-index: 30;
  bottom: 0;
  left: 0;
  right: 0;
  display: flex;
  justify-content: space-around;
  gap: 4px;
  padding: 6px 4px;
  background: rgb(10 10 12 / 0.95);
  backdrop-filter: blur(8px);
  border-top: 1px solid var(--border-subtle);
}
@media (min-width: 768px) {
  .ae-rail {
    top: 56px;
    right: auto;
    width: 220px;
    flex-direction: column;
    justify-content: flex-start;
    gap: 4px;
    padding: 12px;
    border-top: 0;
    border-right: 1px solid var(--border-subtle);
  }
}
.ae-rail-foot {
  display: none;
  margin-top: auto;
  padding: 0 12px 4px;
  font-size: 10px;
  line-height: 1.5;
  color: var(--text-tertiary);
}
@media (min-width: 768px) { .ae-rail-foot { display: block; } }

/* ── misc ─────────────────────────────────────────────────────────────────── */
.ae-link { color: var(--text-primary); text-decoration: underline; text-decoration-color: var(--text-tertiary); text-underline-offset: 2px; }
.ae-link:hover { text-decoration-color: var(--text-primary); }
.ae-back { font-size: 12px; color: var(--text-secondary); text-decoration: none; }
.ae-back:hover { color: var(--text-primary); }
.ae-title { font-size: 20px; font-weight: 600; letter-spacing: -0.01em; color: var(--text-primary); }
/* A form that must sit inline in the header (the sign-out button): a bare <form>
   is display:block and would drop onto its own line. */
.ae-inline { display: inline-flex; }

/* ── a table row that opens one thing ──────────────────────────────────────────
   The anchor stays the real, keyboard-reachable target; ae.js (initRowLinks)
   only extends its hit area over the row, so the whole row is clickable without
   nesting a link in every cell.

   This USED to be pure CSS — `position: relative` on the row, and an
   `inset: 0` pseudo-element on the anchor to cover it. Never do that on a <tr>:
   WebKit does not make a relatively-positioned table row a containing block, so
   in Safari every one of those overlays escaped its row and sized itself to
   .ae-main instead. The last row in the DOM won the stacking order, and a click
   ANYWHERE on the account page — a button, a form field, blank space — opened
   whichever post happened to be scheduled furthest into the future.

   `is-clickable` is set by the same JS that installs the handler, so the row
   only advertises itself as clickable when something is actually listening. */
.ae-rowlink:hover { background: var(--bg-overlay); }
.ae-rowlink.is-clickable { cursor: pointer; }

/* ── one post, worked by hand (ops content detail) ─────────────────────────── */
/* The caption field is the point of the page: monospace so trailing spaces,
   line breaks and emoji read exactly as they'll be pasted. */
.ae-caption {
  min-height: 160px;
  font-family: "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 13px;
}
.ae-url { flex: 1 1 260px; min-width: 0; font-size: 12px; color: var(--text-secondary); }
.ae-media { display: flex; }
.ae-media-preview {
  max-width: 320px; max-height: 480px; width: 100%;
  border-radius: 10px; border: 1px solid var(--border-subtle); background: var(--bg-overlay);
}

/* ═══ customer dashboard (seven tabs) ═══════════════════════════════════════ */

/* content-item status pill missing from every other set. */
.pill-awaiting { color: var(--warn); background: rgb(251 191 36 / 0.14); }

/* small layout helpers new to the customer surface */
.ae-min0 { min-width: 0; }
.ae-right { text-align: right; }
.ae-note { color: var(--text-secondary); line-height: 1.55; }
.ae-note svg { vertical-align: -2px; }

/* the "N to approve" header chip + the rail count badge */
.ae-approvals {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 12px; color: #fcd34d; text-decoration: none;
  padding: 4px 10px; border-radius: 999px;
  background: rgb(251 191 36 / 0.12); border: 1px solid rgb(251 191 36 / 0.3);
}
.ae-approvals:hover { background: rgb(251 191 36 / 0.18); }
.rail-badge {
  margin-left: auto; min-width: 18px; height: 18px; padding: 0 5px;
  display: inline-grid; place-items: center; border-radius: 999px;
  font-family: "JetBrains Mono", ui-monospace, monospace; font-size: 10px; font-weight: 600;
  color: #171307; background: var(--warn);
}

/* forms: text areas, radio/checkbox rows */
.ae-textarea { width: 100%; min-height: 72px; resize: vertical; font: inherit; line-height: 1.5; }
.ae-radio-row, .ae-check-row { display: flex; flex-wrap: wrap; gap: 8px 16px; }
.ae-radio, .ae-check {
  display: inline-flex; align-items: center; gap: 7px;
  font-size: 13px; color: var(--text-primary);
  padding: 6px 12px; border-radius: 8px;
  border: 1px solid var(--border-subtle); background: var(--bg-overlay);
  cursor: pointer;
}
.ae-radio input, .ae-check input { accent-color: var(--accent); }

/* approvals queue row */
.ae-approval-row { display: flex; align-items: center; justify-content: space-between; gap: 16px; }

/* ── calendar grid ─────────────────────────────────────────────────────────── */
.cal-grid { display: flex; flex-direction: column; gap: 1px; }
.cal-head, .cal-week { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 6px; }
.cal-head { margin-bottom: 6px; }
.cal-week { margin-bottom: 6px; }
.cal-hcell { text-align: center; padding: 4px 0; color: var(--text-secondary); }
.cal-cell {
  min-height: 92px; padding: 6px; border-radius: 8px;
  background: var(--bg-raised); border: 1px solid var(--border-subtle);
  display: flex; flex-direction: column; gap: 4px;
}
.cal-out { opacity: 0.45; }
.cal-today { border-color: rgb(var(--accent-rgb) / 0.55); }
.cal-cell-top { display: flex; align-items: center; justify-content: space-between; }
.cal-day { font-size: 12px; color: var(--text-secondary); }
.cal-today .cal-day { color: var(--accent); font-weight: 600; }
.cal-add {
  width: 20px; height: 20px; display: grid; place-items: center;
  border-radius: 6px; border: 1px solid transparent; background: transparent;
  color: var(--text-tertiary); cursor: pointer; opacity: 0; transition: opacity 100ms ease;
}
.cal-cell:hover .cal-add { opacity: 1; }
.cal-add:hover { color: var(--accent); border-color: var(--border-subtle); background: var(--bg-overlay); }
.cal-items { display: flex; flex-direction: column; gap: 3px; overflow: hidden; }
.cal-chip {
  display: flex; align-items: center; gap: 5px;
  font-size: 11px; line-height: 1.3; color: var(--text-primary);
  padding: 3px 6px; border-radius: 5px;
  background: var(--bg-overlay); border-left: 2px solid var(--text-tertiary);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.cal-chip-plat {
  flex-shrink: 0; font-family: "JetBrains Mono", ui-monospace, monospace;
  font-size: 9px; color: var(--text-secondary); text-transform: uppercase;
}
.cal-chip-posted   { border-left-color: var(--ok); }
.cal-chip-awaiting { border-left-color: var(--warn); }
.cal-chip-queued   { border-left-color: var(--accent); }
.cal-chip-running  { border-left-color: var(--accent); }
.cal-chip-active   { border-left-color: var(--ok); }
.cal-chip-failed   { border-left-color: var(--bad); }
.cal-chip-draft    { border-left-color: var(--text-tertiary); }

/* ── campaigns ─────────────────────────────────────────────────────────────── */
.camp-meta { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }
.camp-meta dt { margin: 0; }
.camp-meta dd { margin: 2px 0 0; }

/* ── insights ──────────────────────────────────────────────────────────────── */
.topic-form { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.topic-form input[type=text] { flex: 1; min-width: 200px; }

/* ── media hub ─────────────────────────────────────────────────────────────── */
.media-grid { display: grid; grid-template-columns: 1fr; gap: 12px; }
@media (min-width: 640px) { .media-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 1000px) { .media-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
.media-card {
  display: flex; align-items: center; gap: 12px;
  padding: 12px; border-radius: 10px;
  background: var(--bg-raised); border: 1px solid var(--border-subtle);
}
.media-thumb {
  flex-shrink: 0; width: 44px; height: 44px; border-radius: 8px;
  display: grid; place-items: center; color: var(--accent);
  background: var(--bg-overlay); border: 1px solid var(--border-subtle);
}
.media-body { flex: 1; min-width: 0; }
.media-body .ae-body { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ── modal ─────────────────────────────────────────────────────────────────── */
.modal { position: fixed; inset: 0; z-index: 50; display: grid; place-items: center; padding: 20px; }
.modal[hidden] { display: none; }
.modal-overlay { position: absolute; inset: 0; background: rgb(5 5 7 / 0.72); backdrop-filter: blur(3px); }
.modal-card {
  position: relative; z-index: 1; width: 100%; max-width: 560px;
  max-height: 88vh; overflow-y: auto;
  background: var(--bg-raised); border: 1px solid var(--border-subtle);
  border-top-color: var(--border-highlight);
  border-radius: 14px; padding: 24px;
  box-shadow: 0 24px 60px rgb(0 0 0 / 0.5);
}
.modal-x {
  display: grid; place-items: center; width: 30px; height: 30px;
  border-radius: 8px; border: 1px solid var(--border-subtle);
  background: var(--bg-overlay); color: var(--text-secondary); cursor: pointer;
}
.modal-x:hover { color: var(--text-primary); }

/* seven tabs is tight on the mobile bottom rail — let it scroll rather than crush */
@media (max-width: 767px) {
  .ae-rail { overflow-x: auto; justify-content: flex-start; }
  .ae-rail .tab-btn { flex: 0 0 auto; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   CUSTOMER CONSOLE (redesign) — everything scoped under `.aec`.

   Deliberately isolated: the operator surface above shares the vendored
   Tailwind build's `.card`/`.pill`/`.ae-*`; this console defines its own token
   set (--bg/--panel/--gold, NOT the build's --bg-base/--accent) and its own
   components, so the two visual systems can never bleed into each other. Only
   app.html carries `.aec`. Gold is reserved for exactly three marks: the active
   nav item, the selected KPI tile, and the one primary action per page.
   ═══════════════════════════════════════════════════════════════════════════ */
:root {
  /* surfaces */
  --bg:#08090A; --panel:#101113; --panel-2:#16181B; --panel-3:#1C1F23;
  --line:#202327; --line-2:#2C3037;
  /* text */
  --text:#E8E9EC; --dim:#7C818A; --faint:#4A4F57;
  /* semantic */
  --gold:#C9A227; --up:#5FBF7F; --down:#D4685A;
  /* platforms */
  --ig:#E0669C; --tt:#4DD0D8; --fb:#6E9BF5;
  --yt:#F2705F; --sub:#E8944A; --li:#5AA9C9;
  /* geometry */
  --r-ctl:6px; --r-card:8px; --r-nav:5px; --r-badge:4px;
}

.aec {
  min-height: 100vh;
  background: var(--bg);
  color: var(--text);
  font-family: Inter, system-ui, -apple-system, sans-serif;
  font-size: 13px;
  line-height: 1.45;
  font-variant-numeric: tabular-nums;
  -webkit-font-smoothing: antialiased;
}
.aec *, .aec *::before, .aec *::after { box-sizing: border-box; }
.aec button { font-family: inherit; }
.aec a { color: inherit; }
/* [hidden] must always win: several console controls set an explicit display
   (.stepper/.filter are flex), which would otherwise outspecify the UA rule and
   leave a JS-hidden control visible on the tabs it doesn't belong to. */
.aec [hidden] { display: none !important; }

/* ── app shell: 214px rail + fluid main ─────────────────────────────────────── */
.aec .shell { display: grid; grid-template-columns: 214px 1fr; min-height: 100vh; }
.aec main { min-width: 0; display: flex; flex-direction: column; }
/* The mobile drawer scrim must NOT be a grid item on desktop — without this base
   it defaults to display:block, becomes the shell's first cell, and shoves the
   rail into column 2 and main onto row 2. It only appears in the <900px drawer. */
.aec .rail-scrim { display: none; }

/* ── left rail ──────────────────────────────────────────────────────────────── */
.aec .rail {
  border-right: 1px solid var(--line);
  background: var(--panel);
  display: flex; flex-direction: column;
  position: sticky; top: 0; height: 100vh;
}
.aec .rail-top { padding: 15px 14px; border-bottom: 1px solid var(--line); }
.aec .brand { display: flex; align-items: center; gap: 10px; text-decoration: none; }
.aec .brand .mark {
  width: 30px; height: 30px; flex-shrink: 0; border-radius: 6px;
  display: grid; place-items: center;
  background: var(--gold); color: #0D0B04;
  font-family: Georgia, "Times New Roman", serif; font-weight: 700; font-size: 17px;
}
.aec .brand .wm { font-size: 12px; font-weight: 700; letter-spacing: 0.14em; color: var(--text); }
.aec .brand .cn { font-size: 11px; color: var(--dim); margin-top: 1px;
  max-width: 138px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.aec .nav { flex: 1; padding: 6px 8px; overflow-y: auto; }
.aec .nav .grp { padding: 14px 9px 6px; }
.aec .nav .grp:first-child { padding-top: 6px; }
.aec .lbl {
  font-size: 10px; font-weight: 600; letter-spacing: 0.11em;
  text-transform: uppercase; color: var(--dim);
}
.aec .nav button {
  display: flex; align-items: center; gap: 10px; width: 100%;
  padding: 8px 9px; border: 0; border-radius: var(--r-nav);
  background: transparent; color: var(--dim); cursor: pointer;
  font-size: 13px; text-align: left; transition: background .14s, color .14s;
}
.aec .nav button:hover { background: var(--panel-2); color: var(--text); }
.aec .nav button[aria-selected="true"] {
  background: var(--panel-2); color: var(--text); font-weight: 500;
  box-shadow: inset 2px 0 0 var(--gold);
}
.aec .nav button svg { width: 15px; height: 15px; flex-shrink: 0; stroke: currentColor; fill: none; stroke-width: 1.6; }
.aec .nav .rb {
  margin-left: auto; min-width: 17px; height: 17px; padding: 0 5px;
  display: inline-grid; place-items: center; border-radius: 999px;
  font-size: 10px; font-weight: 700; color: #0D0B04; background: var(--gold);
}
.aec .rail-btm { padding: 12px 14px; border-top: 1px solid var(--line);
  font-size: 10.5px; line-height: 1.5; color: var(--faint); }

/* ── topbar ─────────────────────────────────────────────────────────────────── */
.aec .top {
  position: sticky; top: 0; z-index: 10;
  background: rgba(8,9,10,.9); backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--line);
  padding: 11px 22px; display: flex; align-items: center; gap: 9px; flex-wrap: wrap;
}
.aec .top .title { font-size: 15px; font-weight: 600; letter-spacing: -0.015em; margin: 0; }
.aec .grow { flex: 1; }
.aec .live { display: inline-flex; align-items: center; gap: 6px;
  color: var(--up); font-size: 11px; font-weight: 600; letter-spacing: 0.06em; }
.aec .live.paused { color: var(--dim); }
.aec .live.dry { color: var(--sub); }
.aec .pulse { width: 6px; height: 6px; border-radius: 50%; background: currentColor; }

/* month stepper + platform filter live in the topbar; hidden per-tab via [hidden] */
.aec .stepper { display: flex; border: 1px solid var(--line); border-radius: var(--r-ctl); overflow: hidden; }
.aec .stepper a, .aec .stepper span.nav-x {
  display: grid; place-items: center; padding: 0 9px; color: var(--dim);
  text-decoration: none; background: none; min-height: 30px;
}
.aec .stepper a:hover { background: var(--panel-2); color: var(--text); }
.aec .stepper .nav-x { color: var(--faint); cursor: not-allowed; } /* disabled forward arrow */
.aec .stepper .m { padding: 6px 12px; font-weight: 500; min-width: 104px; text-align: center;
  border-left: 1px solid var(--line); border-right: 1px solid var(--line); }

/* platform filter: a <details> whose <summary> is the pill and whose menu is a
   plain list of toggle links (multi-select works with JS off). */
.aec .filter { position: relative; }
.aec .filter > summary { list-style: none; cursor: pointer; }
.aec .filter > summary::-webkit-details-marker { display: none; }
.aec .filter > summary::marker { content: ""; }
.aec .filter-menu {
  position: absolute; top: calc(100% + 6px); left: 0; z-index: 20; min-width: 190px;
  background: var(--panel-2); border: 1px solid var(--line-2); border-radius: var(--r-ctl);
  padding: 5px; box-shadow: 0 14px 40px rgba(0,0,0,.5);
}
.aec .filter-opt {
  display: flex; align-items: center; gap: 8px; padding: 7px 9px;
  border-radius: var(--r-nav); color: var(--dim); text-decoration: none; font-size: 12.5px;
}
.aec .filter-opt:hover { background: var(--panel-3); color: var(--text); }
.aec .filter-opt.on { color: var(--text); }
.aec .filter-opt .tick {
  width: 12px; height: 12px; flex-shrink: 0; border-radius: 3px;
  border: 1px solid var(--line-2); background: var(--panel);
}
.aec .filter-opt.on .tick { background: currentColor; border-color: currentColor; }
.aec .filter-opt.plat-instagram { --pc: var(--ig); }
.aec .filter-opt.plat-tiktok { --pc: var(--tt); }
.aec .filter-opt.plat-facebook { --pc: var(--fb); }
.aec .filter-opt.plat-youtube { --pc: var(--yt); }
.aec .filter-opt.on.plat-instagram, .aec .filter-opt.on.plat-tiktok,
.aec .filter-opt.on.plat-facebook, .aec .filter-opt.on.plat-youtube { color: var(--pc); }

/* topbar inline action groups + sign-out form sit as one row */
.aec .top .ae-inline { display: inline-flex; align-items: center; gap: 8px; }
.aec #pageActions [data-actions] { display: inline-flex; align-items: center; gap: 8px; }
.aec #pageActions [hidden] { display: none; }

/* ── platform hue map: any element tagged .plat-<key> exposes --pc ──────────── */
.aec .plat-instagram { --pc: var(--ig); }
.aec .plat-tiktok    { --pc: var(--tt); }
.aec .plat-facebook  { --pc: var(--fb); }
.aec .plat-youtube   { --pc: var(--yt); }
.aec .plat-linkedin  { --pc: var(--li); }

/* ── settings ───────────────────────────────────────────────────────────────── */
.aec .srow { display: flex; align-items: center; gap: 12px; padding: 13px 15px; border-bottom: 1px solid var(--line); }
.aec .srow:last-child { border-bottom: 0; }
.aec .sicon {
  width: 28px; height: 28px; flex-shrink: 0; border-radius: 6px;
  display: grid; place-items: center; font-weight: 700; font-size: 12px;
  background: color-mix(in srgb, var(--pc, var(--dim)) 15%, transparent); color: var(--pc, var(--dim));
}
.aec .sn { flex: 1; min-width: 0; }
.aec .sn b { font-size: 12.5px; font-weight: 500; }
.aec .sn small { display: block; color: var(--dim); font-size: 11px; margin-top: 1px; line-height: 1.45; }
.aec .sn small.attn { color: var(--sub); }
.aec .setup-picker { padding: 2px 15px 14px; border-bottom: 1px solid var(--line); }
.aec .radio { display: flex; align-items: center; gap: 8px; padding: 7px 0; font-size: 12.5px; color: var(--text); cursor: pointer; }
.aec .radio input { accent-color: var(--gold); }

.aec .killrow { display: flex; align-items: center; gap: 14px; padding: 15px; }
.aec .killrow .kt { flex: 1; min-width: 0; }
.aec .killrow .kt b { font-size: 13px; font-weight: 500; }
.aec .killrow .kt small { display: block; color: var(--dim); font-size: 11.5px; margin-top: 2px; line-height: 1.5; }
.aec .killrow .pulse { width: 8px; height: 8px; flex-shrink: 0; }
.aec .killrow.live .pulse { background: var(--up); }
.aec .killrow.paused .pulse { background: var(--dim); }
.aec .killrow.dry .pulse { background: var(--sub); }

/* The console's first text input (the "Your login" card). Scoped and named for
   reuse rather than styling bare `input`, which would also catch the file input
   and radios above and undo their own rules. */
.aec .flabel { display: block; font-size: 10px; font-weight: 600; letter-spacing: 0.11em;
  text-transform: uppercase; color: var(--dim); margin-bottom: 6px; }
.aec .finput {
  width: 100%; max-width: 320px; font: inherit; font-size: 13px; color: var(--text);
  background: var(--bg); border: 1px solid var(--line-2); border-radius: var(--r-ctl);
  padding: 8px 11px;
}
.aec .finput:focus { outline: none; border-color: var(--dim); }

.aec .brand-dl { display: grid; gap: 15px; }
.aec .brand-dl .k { font-size: 10px; font-weight: 600; letter-spacing: 0.11em; text-transform: uppercase; color: var(--dim); }
.aec .brand-dl .v { margin-top: 4px; color: var(--text); line-height: 1.55; white-space: pre-wrap; }
.aec .field-note { color: var(--dim); font-size: 12px; line-height: 1.6; }
.aec details.disclose { margin-top: 14px; }
.aec details.disclose > summary { cursor: pointer; color: var(--dim); font-size: 12px; list-style: none; }
.aec details.disclose > summary::-webkit-details-marker { display: none; }
.aec .kb-body { margin-top: 8px; max-height: 320px; overflow-y: auto; color: var(--dim);
  font-size: 12.5px; line-height: 1.55; white-space: pre-wrap; }

/* ── campaigns ──────────────────────────────────────────────────────────────── */
.aec .camps { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.aec .camp-h { padding: 14px 16px; border-bottom: 1px solid var(--line); }
.aec .camp-t { display: flex; align-items: center; gap: 10px; }
.aec .camp-t b { flex: 1; min-width: 0; font-size: 13.5px; font-weight: 600; }
.aec .pills { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 10px; }
.aec .plat-pill {
  font-size: 10.5px; padding: 2px 8px; border-radius: 100px;
  border: 1px solid color-mix(in srgb, var(--pc, var(--line-2)) 45%, transparent);
  color: var(--pc, var(--dim));
}
.aec .camp-facts { display: grid; grid-template-columns: 1fr 1fr; gap: 14px;
  padding: 15px 16px; border-bottom: 1px solid var(--line); }
.aec .fact .v { font-size: 14px; font-weight: 500; margin-top: 4px; }
.aec .fact .v.dim { color: var(--dim); font-weight: 400; }
/* The plain-English account of the campaign — the headline of the card, set at
   reading size rather than as a caption under a row of enums. */
.aec .camp-plain { padding: 14px 16px 0; font-size: 13px; line-height: 1.6; color: var(--text); }
.aec .camp-lines { padding: 12px 16px 14px; display: grid; gap: 7px;
  border-bottom: 1px solid var(--line); }
.aec .camp-lines .cl { display: flex; align-items: center; gap: 8px;
  font-size: 11.5px; color: var(--dim); }
.aec .camp-lines .cl svg { width: 12px; height: 12px; flex-shrink: 0; color: var(--faint); }
.aec .camp-card.running { border-color: color-mix(in srgb, var(--up) 32%, var(--line)); }
.aec .progress { padding: 13px 16px; border-bottom: 1px solid var(--line); }
.aec .progress .prow { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; }
.aec .progress .prow .cnt { font-size: 12px; color: var(--dim); }
/* shipped-vs-planned. NOT gold — §3 reserves gold for nav/tile/primary action;
   green reads as 'delivered' without stealing that role. */
.aec .ptrack { height: 5px; background: var(--panel-3); border-radius: 3px; overflow: hidden; margin-top: 9px; }
.aec .ptrack i { display: block; height: 100%; background: var(--up); border-radius: 3px; }
.aec .camp-d { padding: 15px 16px; color: var(--dim); font-size: 12px; line-height: 1.6; }
.aec .camp-card { cursor: pointer; text-align: left; transition: border-color .12s; }
.aec .camp-card:hover { border-color: var(--line-2); }
/* campaign detail (in the slide-over) */
.aec #so-campmeta { border-bottom: 1px solid var(--line); padding-bottom: 14px; margin-bottom: 4px; }
.aec .so-campplain { margin: 2px 0 10px; font-size: 13px; line-height: 1.6; color: var(--text); }
.aec .so-campline { font-size: 11.5px; color: var(--dim); margin-bottom: 4px; }
.aec .so-campfacts { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; margin: 4px 0 12px; }
.aec .so-campfacts .lbl { display: block; }
.aec .so-campfacts .v { font-size: 13px; margin-top: 3px; }
.aec .so-campprog { margin: 4px 0 12px; }
.aec .so-campbrief { color: var(--dim); font-size: 12px; line-height: 1.6; }

/* ── media hub ──────────────────────────────────────────────────────────────── */
.aec .assets { display: grid; grid-template-columns: repeat(4, 1fr); gap: 10px; }
.aec .asset { border: 1px solid var(--line); border-radius: var(--r-card); overflow: hidden; background: var(--panel); }
.aec .athumb {
  aspect-ratio: 9 / 13; position: relative; display: grid; place-items: center;
  background: linear-gradient(150deg, #1A1B1F, #26282E);
}
.aec .athumb .glyph { width: 30px; height: 30px; color: var(--faint); }
.aec .athumb .glyph svg { width: 100%; height: 100%; stroke: currentColor; fill: none; stroke-width: 1.5; }
/* the real cover — a frame of the file — layered over the fallback glyph */
.aec .athumb .acover { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; z-index: 1; background: #16181B; }
.aec .athumb .pl, .aec .athumb .dl { z-index: 3; }
.aec .athumb .playbadge { position: absolute; inset: 0; z-index: 2; display: grid; place-items: center;
  color: rgba(255,255,255,.82); pointer-events: none; }
.aec .athumb .playbadge svg { width: 34px; height: 34px; filter: drop-shadow(0 1px 4px rgba(0,0,0,.6)); }
.aec .athumb .pl {
  position: absolute; top: 9px; left: 9px; font-size: 9.5px; font-weight: 700;
  padding: 2px 6px; border-radius: var(--r-badge); background: rgba(8,9,10,.78); color: var(--pc, var(--dim));
}
.aec .athumb .dl {
  position: absolute; bottom: 9px; right: 9px; width: 26px; height: 26px;
  border-radius: 5px; background: rgba(8,9,10,.82); border: 1px solid var(--line-2);
  display: grid; place-items: center; color: var(--dim); opacity: 0; transition: opacity .12s;
}
.aec .athumb .dl svg { width: 14px; height: 14px; stroke: currentColor; fill: none; stroke-width: 1.8; }
.aec .asset:hover .dl, .aec .athumb .dl:focus-visible { opacity: 1; }
.aec .athumb .dl:hover { border-color: var(--dim); color: var(--text); }
@media (hover: none) { .aec .athumb .dl { opacity: 1; } } /* touch has no hover — always show */
.aec .ameta { padding: 10px 11px; }
.aec .ameta b { display: block; font-size: 12px; font-weight: 450; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.aec .ameta small { color: var(--faint); font-size: 10.5px; }

/* reusable brand assets — the real marks AE applies, not an upload stub */
.aec .brand-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(268px, 1fr)); gap: 10px; }
.aec .basset { display: flex; align-items: center; gap: 12px; padding: 11px 12px;
  border: 1px solid var(--line); border-radius: var(--r-card); background: var(--panel-2); }
.aec .basset.off { opacity: .62; }
.aec .bathumb { width: 46px; height: 46px; border-radius: var(--r-ctl); flex-shrink: 0;
  background: var(--panel-3); display: flex; align-items: center; justify-content: center;
  overflow: hidden;
  /* a chequerboard, so a transparent PNG reads as transparent rather than as a
     mark that happens to match the panel colour */
  background-image: linear-gradient(45deg, #1A1D21 25%, transparent 25%),
                    linear-gradient(-45deg, #1A1D21 25%, transparent 25%),
                    linear-gradient(45deg, transparent 75%, #1A1D21 75%),
                    linear-gradient(-45deg, transparent 75%, #1A1D21 75%);
  background-size: 10px 10px;
  background-position: 0 0, 0 5px, 5px -5px, -5px 0; }
.aec .bathumb img { max-width: 100%; max-height: 100%; object-fit: contain; }
.aec .baico { color: var(--faint); display: flex; }
.aec .baico svg { width: 18px; height: 18px; }
.aec .bameta { min-width: 0; flex: 1; }
.aec .bameta .bal { display: block; font-size: 10px; text-transform: uppercase;
  letter-spacing: .05em; color: var(--faint); }
.aec .bameta b { display: block; font-size: 12.5px; font-weight: 500; margin-top: 2px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.aec .bameta small { display: block; color: var(--dim); font-size: 10.5px; margin-top: 1px; }
.aec .bapal { display: flex; align-items: center; gap: 7px; margin-top: 14px; }
.aec .bapal .bal { font-size: 10px; text-transform: uppercase; letter-spacing: .05em;
  color: var(--faint); margin-right: 3px; }
.aec .bapal .swatch { width: 20px; height: 20px; border-radius: 4px; border: 1px solid var(--line-2); }

/* knowledge intake — the one input on the customer surface (migration 0025).
   Styled as a quiet panel rather than a hero: it sits under the produced assets,
   and the invitation is the copy, not the chrome. */
.aec .intake { border: 1px solid var(--line); border-radius: var(--r-card);
  background: var(--panel-2); padding: 13px 14px; display: grid; gap: 11px; }
.aec .ifield { display: block; }
.aec .ifield > span { display: block; font-size: 10px; text-transform: uppercase;
  letter-spacing: .05em; color: var(--faint); margin-bottom: 5px; }
.aec .intake input[type=file] { font: inherit; font-size: 12px; color: var(--dim); max-width: 100%; }
.aec .intake input[type=file]::file-selector-button {
  font: inherit; font-size: 11.5px; margin-right: 10px; padding: 5px 10px; cursor: pointer;
  color: var(--dim); background: var(--panel-3); border: 1px solid var(--line-2);
  border-radius: var(--r-ctl); }
.aec .intake input[type=file]::file-selector-button:hover { color: var(--text); border-color: var(--dim); }
.aec .intake textarea {
  width: 100%; font: inherit; font-size: 12.5px; line-height: 1.5; resize: vertical;
  color: var(--text); background: var(--panel-3); border: 1px solid var(--line-2);
  border-radius: var(--r-ctl); padding: 8px 10px; }
.aec .intake textarea::placeholder { color: var(--faint); }
.aec .intake textarea:focus { outline: none; border-color: var(--dim); }
.aec .irow { display: flex; align-items: center; justify-content: space-between; gap: 14px; }
.aec .irow small { color: var(--faint); font-size: 11px; }

/* the record: one row per uploaded file, each showing what it actually changed */
.aec .ilist { list-style: none; margin: 16px 0 0; padding: 0; display: grid; gap: 9px; }
.aec .iitem { border: 1px solid var(--line); border-radius: var(--r-card);
  background: var(--panel-2); padding: 11px 13px; }
.aec .ihead { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.aec .ihead b { font-size: 12.5px; font-weight: 500; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.aec .inote { color: var(--dim); font-size: 12px; line-height: 1.55; margin: 6px 0 0; }
.aec .isum { color: var(--dim); font-size: 12px; line-height: 1.55; margin: 7px 0 0; }
/* what changed. Marked with the same green the rest of the console uses for a
   real, completed thing — an empty list is rendered as prose by the template
   instead, so this never appears without something in it. */
.aec .iapplied { list-style: none; margin: 8px 0 0; padding: 0; display: grid; gap: 4px; }
.aec .iapplied li { position: relative; padding-left: 15px; font-size: 12px; line-height: 1.5; }
.aec .iapplied li::before { content: ""; position: absolute; left: 3px; top: 7px;
  width: 5px; height: 5px; border-radius: 50%; background: var(--up); }
.aec .iitem > small { display: block; margin-top: 8px; color: var(--faint); font-size: 10.5px; }

/* ── calendar: one week, seven columns ──────────────────────────────────────────
   A month grid needed 42 cells, a "+N more" truncation and a fixed six rows to
   answer a question about a handful of days. Seven columns give every post in the
   week its own visible row. */
.aec .calweek { display: grid; grid-template-columns: repeat(7, 1fr);
  border-left: 1px solid var(--line); border-top: 1px solid var(--line); }
.aec .day { min-height: 156px; padding: 8px; display: flex; flex-direction: column; gap: 4px;
  border-right: 1px solid var(--line); border-bottom: 1px solid var(--line); cursor: pointer; overflow: hidden; }
.aec .day:hover { background: var(--panel-2); }
.aec .day.today:hover { background: #15150E; }
.aec .day.past { background: #0C0D0F; }
.aec .day.today { background: #12120C; box-shadow: inset 0 0 0 1px rgba(201,162,39,.5); }
/* justify-content is set explicitly: the operator console's own `.cal-cell-top`
   (unscoped, further up this file) says space-between, which would fling a day
   number to the far edge on any day with no post count beside it. */
.aec .cal-cell-top { display: flex; align-items: baseline; gap: 6px; margin-bottom: 2px;
  justify-content: flex-start; }
.aec .day .dow { font-size: 10px; letter-spacing: 0.09em; text-transform: uppercase;
  color: var(--dim); font-weight: 600; }
.aec .dnum { font-size: 13px; color: var(--text); font-weight: 600; }
.aec .day.past .dnum { color: var(--dim); }
.aec .day.today .dow, .aec .day.today .dnum { color: var(--gold); }
.aec .day .day-count { margin-left: auto; font-size: 10px; color: var(--dim); }
/* An empty day that has already happened is a fact, not a gap. */
.aec .day-none { font-size: 11px; color: var(--faint); margin-top: 2px; }
.aec .chip {
  display: flex; align-items: center; gap: 6px; width: 100%; text-align: left;
  padding: 4px 6px; border: 0; border-left: 2px solid var(--pc, var(--faint));
  border-radius: var(--r-badge); background: var(--panel-2); color: var(--text);
  font-size: 11px; cursor: pointer; overflow: hidden;
}
.aec .chip:hover { background: var(--panel-3); }
.aec .chip .dot { width: 5px; height: 5px; border-radius: 50%; flex-shrink: 0; background: var(--pc, var(--faint)); }
.aec .chip .ct { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* Chip states. The week has to answer "did it work?" without being opened, so
   published is the only chip that is filled and ticked, and a slot that never
   went out is struck through rather than quietly looking like the rest. */
.aec .chip .tick { display: inline-flex; flex-shrink: 0; color: var(--up); }
.aec .chip .tick svg { width: 11px; height: 11px; }
.aec .chip.st-posted {
  background: color-mix(in srgb, var(--pc, var(--faint)) 12%, var(--panel-2));
  border-left-color: var(--pc, var(--faint));
}
.aec .chip.st-posted:hover { background: color-mix(in srgb, var(--pc, var(--faint)) 20%, var(--panel-2)); }
.aec .chip.st-posted .ct { color: var(--text); }
.aec .chip.st-inbox .dot { background: var(--sub); }
.aec .chip.st-missed { border-left-style: dashed; }
.aec .chip.st-missed .ct { color: var(--dim); text-decoration: line-through; }
.aec .chip.st-missed .dot, .aec .chip.st-blocked .dot { background: var(--down); }
.aec .chip.st-blocked .ct { color: var(--dim); text-decoration: line-through; }
.aec .chip.st-planned .dot { background: transparent; box-shadow: inset 0 0 0 1px var(--pc, var(--faint)); }

/* The same vocabulary on a status pill (slide-over head, day list). */
.aec .st-posted.muted-pill { background: rgba(95,191,127,.12); color: var(--up); }
.aec .st-inbox.muted-pill { background: rgba(232,148,74,.14); color: var(--sub); }
.aec .st-missed.muted-pill, .aec .st-blocked.muted-pill {
  background: rgba(224,106,95,.13); color: var(--down); }

.aec .so-live { margin: 0 0 14px; }
.aec .so-live .open svg { width: 13px; height: 13px; }

.aec .calfoot { padding: 10px 15px; border-top: 1px solid var(--line);
  display: flex; gap: 20px; flex-wrap: wrap; justify-content: space-between; }
.aec .legend { display: flex; gap: 14px; flex-wrap: wrap; font-size: 11px; color: var(--dim); }
.aec .legend span { display: inline-flex; align-items: center; }
.aec .legend .sw { width: 7px; height: 7px; border-radius: 2px; margin-right: 5px; background: var(--pc, var(--faint)); }
.aec .statekey .sw { background: transparent; box-shadow: inset 0 0 0 1px var(--faint); border-radius: 50%; }
.aec .statekey .tickkey { box-shadow: none; color: var(--up); width: auto; height: auto; }
.aec .statekey .tickkey svg { width: 11px; height: 11px; }

/* Campaign strip — what is actually running, in words, above the week it runs
   in. Wider cards than the old enum row needed: the sentence is the content. */
.aec .camp-strip .strip { display: grid; grid-template-columns: repeat(auto-fit, minmax(290px, 1fr));
  gap: 1px; background: var(--line); }
/* `.running`, NOT `.live`: `.aec .live` is the topbar posting pill and carries
   `display: inline-flex`, which laid this card's lines out as columns. */
.aec .strip-item { padding: 13px 15px; background: var(--panel); cursor: pointer;
  transition: background .12s; }
.aec .strip-item:hover { background: var(--panel-2); }
.aec .strip-item.running { background: color-mix(in srgb, var(--up) 5%, var(--panel)); }
.aec .strip-item.running:hover { background: color-mix(in srgb, var(--up) 9%, var(--panel)); }
.aec .si-h { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.aec .si-h b { font-size: 12.5px; }
.aec .si-plain { margin: 7px 0 0; font-size: 12px; line-height: 1.55; color: var(--text); }
.aec .si-m { margin-top: 8px; display: grid; gap: 4px;
  font-size: 11px; color: var(--dim); }
.aec .si-next { color: var(--sub); }
.aec .livedot { width: 6px; height: 6px; border-radius: 50%; background: var(--up); flex-shrink: 0;
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--up) 22%, transparent); }

/* approvals queue (cross-cutting; sits above the grid) */
.aec .appr-row { display: flex; align-items: center; justify-content: space-between; gap: 14px;
  padding: 13px 15px; border-bottom: 1px solid var(--line); }
.aec .appr-row:last-child { border-bottom: 0; }
.aec .appr-row .an { min-width: 0; }
.aec .appr-row .an .t { font-size: 12.5px; margin-top: 4px; overflow: hidden; text-overflow: ellipsis;
  white-space: nowrap; max-width: 46ch; }
.aec .appr-acts { display: flex; gap: 8px; flex-shrink: 0; }
.aec .ghost.approve { color: var(--up); border-color: color-mix(in srgb, var(--up) 40%, transparent); }
.aec .ghost.approve:hover { color: var(--up); border-color: var(--up); background: rgba(95,191,127,.08); }

/* ── slide-over: the calendar post detail (§7.4) ────────────────────────────── */
.aec .slideover { position: fixed; inset: 0; z-index: 60; }
.aec .slideover[hidden] { display: none; }
.aec .so-scrim { position: absolute; inset: 0; background: rgba(5,5,7,.6); backdrop-filter: blur(2px); }
.aec .so-panel {
  position: absolute; top: 0; right: 0; height: 100%; width: 420px; max-width: 92vw;
  background: var(--panel); border-left: 1px solid var(--line-2);
  box-shadow: -20px 0 60px rgba(0,0,0,.5); display: flex; flex-direction: column;
  overflow-y: auto; animation: so-in .18s ease;
}
@keyframes so-in { from { transform: translateX(24px); opacity: .5; } to { transform: none; opacity: 1; } }
.aec .so-head { padding: 15px 18px; border-bottom: 1px solid var(--line); display: flex; align-items: center; gap: 9px; }
.aec .so-x { margin-left: auto; display: grid; place-items: center; width: 30px; height: 30px; flex-shrink: 0;
  border-radius: var(--r-ctl); border: 1px solid var(--line); background: var(--panel-2); color: var(--dim); cursor: pointer; }
.aec .so-x:hover { color: var(--text); border-color: var(--line-2); }
.aec .so-x svg { width: 15px; height: 15px; stroke: currentColor; fill: none; stroke-width: 2; }
.aec .so-body { padding: 16px 18px; display: flex; flex-direction: column; gap: 16px; }
.aec .so-when { font-size: 12px; color: var(--dim); }
.aec .so-media { aspect-ratio: 16 / 10; border-radius: var(--r-card); position: relative;
  display: grid; place-items: center; background: linear-gradient(150deg, #1A1B1F, #26282E); overflow: hidden; }
.aec .so-media .glyph { width: 30px; height: 30px; color: var(--faint); }
.aec .so-media .glyph svg { width: 100%; height: 100%; stroke: currentColor; fill: none; stroke-width: 1.5; }
.aec .so-media .open { position: absolute; bottom: 9px; right: 9px; }
.aec .so-block .k { font-size: 10px; font-weight: 600; letter-spacing: 0.11em; text-transform: uppercase; color: var(--dim); }
.aec .so-hook { border-left: 2px solid var(--line-2); padding: 2px 0 2px 11px; margin-top: 6px;
  font-size: 13px; line-height: 1.5; color: var(--text); }
.aec .so-cap { margin-top: 6px; font-size: 12.5px; line-height: 1.6; color: var(--text); white-space: pre-wrap;
  max-height: 200px; overflow-y: auto; }
.aec .so-caphead { display: flex; align-items: center; justify-content: space-between; }
.aec .so-metrics { display: flex; gap: 20px; flex-wrap: wrap; margin-top: 6px; }
.aec .so-metric .v { font-size: 18px; font-weight: 600; letter-spacing: -0.02em; }
.aec .so-metric .l { font-size: 10px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--dim); }
.aec .so-note { font-size: 12px; color: var(--dim); line-height: 1.55; margin-top: 6px; }
.aec .so-actions { display: flex; gap: 8px; padding: 15px 18px; border-top: 1px solid var(--line); margin-top: auto; }
.aec .so-campaign a { color: var(--text); text-decoration: underline; text-decoration-color: var(--line-2); text-underline-offset: 2px; }
.aec .so-campaign a:hover { text-decoration-color: var(--dim); }
.aec .so-daytitle { font-size: 13px; font-weight: 600; }
.aec .so-back { display: grid; place-items: center; width: 30px; height: 30px; flex-shrink: 0;
  border-radius: var(--r-ctl); border: 1px solid var(--line); background: var(--panel-2); color: var(--dim); cursor: pointer; }
.aec .so-back svg { width: 15px; height: 15px; stroke: currentColor; fill: none; stroke-width: 2; transform: rotate(0); }
.aec .so-back:hover { color: var(--text); }
.aec .so-daylist { display: flex; flex-direction: column; margin: -4px 0; }
.aec .so-dayrow { display: flex; align-items: flex-start; gap: 10px; width: 100%; text-align: left;
  padding: 12px 2px; border: 0; border-bottom: 1px solid var(--line); background: none; color: var(--text); cursor: pointer; }
.aec .so-daylist .so-dayrow:last-child { border-bottom: 0; }
.aec .so-dayrow:hover { background: var(--panel-2); }
/* The day panel exists to show what the calendar chip cut off, so its titles
   WRAP rather than ellipsize — a second truncation here made opening a day
   pointless. Capped at three lines so one long caption cannot push the rest
   of the day off screen. */
.aec .so-dayrow .drt { flex: 1; min-width: 0; font-size: 12.5px; line-height: 1.45;
  overflow-wrap: anywhere; display: -webkit-box; -webkit-line-clamp: 3;
  -webkit-box-orient: vertical; overflow: hidden; }
.aec .so-dayrow .drdot { width: 6px; height: 6px; border-radius: 50%; flex-shrink: 0; margin-top: 5px; background: var(--pc, var(--faint)); }
.aec .chip-more { font-size: 10px; color: var(--dim); padding: 1px 4px; }

/* ── performance: one chart, three controls ─────────────────────────────────── */
.aec .perf-bar { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin-bottom: 10px; }
.aec .perf-window { font-size: 11px; color: var(--faint); }

/* period selector — plain links styled as a segmented control */
.aec .segmented { display: inline-flex; background: var(--panel-2); border: 1px solid var(--line);
  border-radius: var(--r-ctl); padding: 2px; gap: 2px; }
.aec .segmented .seg { font-size: 11.5px; color: var(--dim); padding: 5px 11px; border-radius: 4px;
  text-decoration: none; white-space: nowrap; transition: background .14s, color .14s; }
.aec .segmented .seg:hover { color: var(--text); background: var(--panel-3); }
/* the selected period — one of the sanctioned gold marks (§3) */
.aec .segmented .seg.on { background: #14130C; color: var(--gold); box-shadow: inset 0 0 0 1px rgba(201,162,39,.4); }

.aec .perf-card { margin-bottom: 10px; }
.aec .perf-head { border-bottom: 1px solid var(--line); }

/* metric selector: each option carries its own total, so the row doubles as the
   at-a-glance summary the KPI tiles used to be — without a second surface. */
.aec .metricsel { display: flex; overflow-x: auto; scrollbar-width: none; }
.aec .metricsel::-webkit-scrollbar { display: none; }
.aec .msel { flex: 1 0 auto; min-width: 104px; text-align: left; padding: 11px 14px;
  background: none; border: 0; border-right: 1px solid var(--line); cursor: pointer;
  position: relative; transition: background .14s; }
.aec .msel:last-child { border-right: 0; }
.aec .msel:hover:not(:disabled) { background: var(--panel-2); }
.aec .msel:disabled { opacity: .38; cursor: default; }
.aec .msel .ml { display: block; font-size: 10.5px; color: var(--dim); text-transform: uppercase;
  letter-spacing: .05em; }
.aec .msel .mv { display: block; font-size: 19px; font-weight: 600; letter-spacing: -.02em;
  color: var(--text); margin-top: 3px; font-variant-numeric: tabular-nums; }
.aec .msel[aria-selected="true"] { background: #12120C; }
.aec .msel[aria-selected="true"] .mv { color: var(--gold); }
.aec .msel[aria-selected="true"]::after { content: ""; position: absolute; left: 0; right: 0;
  bottom: -1px; height: 2px; background: var(--gold); }

.aec .perf-body { padding: 14px 15px 4px; }
.aec .perf-note { font-size: 11.5px; color: var(--dim); margin: 0 0 10px; }
/* "no view count reported for Facebook (12 posts)" — a stated gap, not a missing line */
.aec .perf-unmeasured { font-style: normal; color: var(--faint); }

/* legend = the per-account on/off switch */
.aec .perf-legend { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 12px; }
.aec .lg { display: inline-flex; align-items: center; gap: 6px; font-size: 11.5px; color: var(--faint);
  background: var(--panel-2); border: 1px solid var(--line); border-radius: 20px;
  padding: 4px 11px 4px 8px; cursor: pointer; transition: color .14s, border-color .14s, opacity .14s; }
.aec .lg .sw { width: 8px; height: 8px; border-radius: 50%; background: var(--faint); transition: background .14s; }
.aec .lg.on { color: var(--text); border-color: var(--line-2); }
.aec .lg.on .sw { background: var(--lc); }
.aec .lg:hover { border-color: var(--lc); }
.aec .lg.past .sw { background: transparent; box-shadow: inset 0 0 0 1.5px var(--lc); }
.aec .lg-past { font-size: 9.5px; letter-spacing: .06em; text-transform: uppercase;
  color: var(--faint); border: 1px solid var(--line); border-radius: 3px; padding: 0 4px; }

.aec .perf-plot { position: relative; }
.aec .perf-svg { width: 100%; height: 260px; display: block; overflow: visible; }

/* hover tooltip — every visible account for one bucket, the comparison the old
   single-series tiles could not show */
.aec .perf-tip { position: absolute; top: 4px; transform: translateX(-50%); pointer-events: none;
  background: var(--panel-3); border: 1px solid var(--line-2); border-radius: 6px;
  padding: 7px 9px; font-size: 11px; min-width: 118px; z-index: 3;
  box-shadow: 0 6px 20px rgba(0,0,0,.45); }
.aec .perf-tip.flip { transform: translateX(-100%) translateX(-8px); }
.aec .perf-tip b { display: block; color: var(--text); font-size: 10.5px; margin-bottom: 5px; }
.aec .perf-tip span { display: flex; align-items: center; gap: 6px; color: var(--dim); line-height: 1.7; }
.aec .perf-tip i { width: 7px; height: 7px; border-radius: 50%; flex-shrink: 0; }
.aec .perf-tip em { margin-left: auto; font-style: normal; color: var(--text);
  font-variant-numeric: tabular-nums; }

/* per-account totals + average per post for the selected metric */
.aec .perf-foot { display: grid; grid-template-columns: repeat(auto-fit, minmax(158px, 1fr));
  border-top: 1px solid var(--line); }
.aec .prow { padding: 11px 15px; border-right: 1px solid var(--line); }
.aec .prow:last-child { border-right: 0; }
.aec .prow .pl { display: flex; align-items: center; gap: 6px; font-size: 11px; color: var(--dim); }
.aec .prow .pl i { width: 7px; height: 7px; border-radius: 50%; background: var(--pc); }
.aec .prow .pt { display: block; font-size: 17px; font-weight: 600; letter-spacing: -.02em;
  margin-top: 4px; font-variant-numeric: tabular-nums; }
.aec .prow .pa { display: block; font-size: 11px; color: var(--dim); margin-top: 1px;
  font-variant-numeric: tabular-nums; }
.aec .prow .pa small { color: var(--faint); }
/* period-over-period, next to the number it qualifies */
.aec .prow .chg { font-size: 10.5px; font-weight: 500; margin-left: 7px;
  vertical-align: middle; letter-spacing: 0; }
.aec .prow .chg.up { color: var(--up); }
.aec .prow .chg.down { color: var(--down); }
.aec .prow .chg.new { color: var(--faint); }

.aec .xax { display: flex; justify-content: space-between; color: var(--faint); font-size: 10px;
  margin-top: 4px; padding: 0 10px 0 46px; }
.aec .visually-hidden { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }

/* ── link hub: the donut ───────────────────────────────────────────────────── */
.aec .hub-wrap { display: grid; grid-template-columns: 210px 1fr; gap: 22px; padding: 16px 15px; align-items: center; }
.aec .donut-side { position: relative; width: 190px; height: 190px; margin: 0 auto; }
.aec .donut { width: 100%; height: 100%; transform: rotate(-90deg); }
.aec .donut-track { stroke: var(--panel-3); }
.aec .donut-arc { cursor: pointer; transition: opacity .16s, stroke-width .16s; transform-origin: 21px 21px; }
.aec .donut-arc:hover { stroke-width: 6; }
.aec .donut-arc.dim { opacity: .22; }
.aec .donut-mid { position: absolute; inset: 0; display: flex; flex-direction: column;
  align-items: center; justify-content: center; pointer-events: none; text-align: center; }
.aec .donut-mid b { font-size: 27px; font-weight: 600; letter-spacing: -.03em;
  font-variant-numeric: tabular-nums; }
.aec .donut-mid span { font-size: 10.5px; color: var(--dim); margin-top: 1px; }

.aec .hub-lead { margin: 0 0 14px; }
.aec .donut-legend { list-style: none; margin: 0; padding: 0; }
.aec .hub-seg { display: flex; align-items: center; gap: 9px; width: 100%; padding: 7px 8px;
  background: none; border: 0; border-radius: var(--r-ctl); cursor: pointer; font-size: 12px;
  color: var(--dim); text-align: left; transition: background .14s, opacity .16s; }
.aec .hub-seg:hover { background: var(--panel-2); color: var(--text); }
.aec .hub-seg.dim { opacity: .35; }
.aec .hub-seg .sw { width: 9px; height: 9px; border-radius: 2px; flex-shrink: 0; align-self: flex-start; margin-top: 4px; }
/* two lines per row: the ask as written, and the URL it opened (_link_where) */
.aec .hub-seg .hl { display: flex; flex-direction: column; gap: 2px; flex: 1 1 auto;
  min-width: 0; color: var(--text); }
.aec .hub-seg .hl, .aec .hub-dests .hd { overflow: hidden; }
.aec .hub-seg .hw { font-style: normal; font-size: 10.5px; color: var(--faint);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.aec .hub-seg .hp { color: var(--faint); font-variant-numeric: tabular-nums; align-self: flex-start; margin-top: 1px; }
.aec .hub-seg .hn { margin-left: auto; color: var(--text); font-variant-numeric: tabular-nums; align-self: flex-start; margin-top: 1px; }
.aec .hub-seg[aria-expanded="true"] { background: var(--panel-2); }
.aec .hub-dests { list-style: none; margin: 0 0 6px; padding: 2px 8px 6px 26px; }
.aec .hub-dests li { display: flex; gap: 10px; font-size: 11.5px; color: var(--dim); padding: 3px 0; }
.aec .hub-dests .hd { overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.aec .hub-dests a.hd { color: var(--dim); text-decoration: none; }
.aec .hub-dests a.hd:hover { color: var(--text); }
.aec .hub-dests a.hd:hover em { text-decoration: underline; }
.aec .hub-dests .hd em { font-style: normal; font-size: 10px; color: var(--faint);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.aec .hub-dests .hn { margin-left: auto; font-variant-numeric: tabular-nums; }
.aec .hub-dests .hmore { color: var(--faint); }

/* the full "where we sent" table: proportional in-cell bar, zero rows dimmed */
.aec td .bar { height: 4px; border-radius: 2px; margin-top: 5px; background: var(--li); opacity: .8; }
.aec th.sortable { cursor: pointer; }
.aec th.sortable:hover { color: var(--text); }
.aec th[aria-sort] { color: var(--gold); }
.aec tr.zero td { color: var(--faint); }
.aec tr.zero td .bar { background: var(--faint); }

/* trend brief */
.aec .brief { font-size: 12.5px; line-height: 1.6; color: var(--dim); }
.aec .brief :is(h1,h2,h3) { color: var(--text); font-size: 13px; margin: 12px 0 5px; }
.aec .brief ul { margin: 6px 0; padding-left: 18px; }
.aec .brief a { color: var(--text); }

@media (max-width: 1180px) {
  .aec .hub-wrap { grid-template-columns: 1fr; }
}
@media (max-width: 700px) {
  .aec .perf-svg { height: 220px; }
  .aec .msel { min-width: 92px; padding: 9px 11px; }
  .aec .msel .mv { font-size: 16px; }
}

/* ── calendar responsive ────────────────────────────────────────────────────────
   Seven narrow columns stop being readable well before a phone. A week is short
   enough to stack instead: each day becomes a full-width row that KEEPS its post
   captions, where the month grid had to hide them behind a bare count. */
@media (max-width: 900px) {
  .aec .calweek { grid-template-columns: 1fr; }
  .aec .day { min-height: 0; padding: 10px 12px; }
  .aec .day.past:not(.today) { background: transparent; }
  .aec .cal-cell-top { margin-bottom: 0; }
  .aec .camps { grid-template-columns: 1fr; }
}

/* ── buttons ────────────────────────────────────────────────────────────────── */
.aec .ghost {
  border: 1px solid var(--line); background: none; color: var(--dim);
  border-radius: var(--r-ctl); padding: 6px 11px; font-size: 12px; cursor: pointer;
  display: inline-flex; align-items: center; gap: 6px; text-decoration: none;
}
.aec .ghost:hover { color: var(--text); border-color: var(--line-2); }
.aec .ghost svg { width: 14px; height: 14px; }
/* A destructive action that must stay reachable without competing for attention:
   it sits beside a "Connected" pill and should read as the quieter of the two,
   turning warm only on intent. */
.aec .ghost.quiet { border-color: transparent; color: var(--faint); }
.aec .ghost.quiet:hover { color: var(--down); border-color: color-mix(in srgb, var(--down) 40%, transparent); }
/* the ONE primary action per page */
.aec .gold {
  background: var(--gold); border-color: var(--gold); color: #0D0B04; font-weight: 600;
}
.aec .gold:hover { background: #D9B23A; border-color: #D9B23A; color: #0D0B04; }

/* ── card ───────────────────────────────────────────────────────────────────── */
.aec .card { background: var(--panel); border: 1px solid var(--line); border-radius: var(--r-card); }
.aec .card + .card, .aec .stack > * + * { margin-top: 10px; }
.aec .card-h {
  padding: 13px 15px; border-bottom: 1px solid var(--line);
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
}
.aec .card-h b { font-size: 13px; font-weight: 600; }
.aec .card-b { padding: 15px; }
.aec .note { font-size: 11px; color: var(--dim); }
.aec .intro { color: var(--dim); font-size: 12.5px; line-height: 1.6; max-width: 80ch; margin: 0 0 12px; }

/* ── body / layout ──────────────────────────────────────────────────────────── */
.aec .body { padding: 18px 22px 64px; }
.aec .grid { display: grid; gap: 10px; }
.aec .panel-hide { display: none; }

/* ── badges / pills ─────────────────────────────────────────────────────────── */
.aec .badge {
  display: inline-block; font-size: 10px; font-weight: 600; padding: 2px 7px;
  border-radius: var(--r-badge); white-space: nowrap;
}
.aec .ok {
  background: rgba(95,191,127,.12); color: var(--up);
  font-size: 10.5px; font-weight: 600; padding: 4px 9px; border-radius: 100px;
}
.aec .warn { background: rgba(232,148,74,.14); color: var(--sub);
  font-size: 10.5px; font-weight: 600; padding: 4px 9px; border-radius: 100px; }
.aec .muted-pill { background: rgba(124,129,138,.14); color: var(--dim);
  font-size: 10.5px; font-weight: 600; padding: 4px 9px; border-radius: 100px; }

/* ── tables ─────────────────────────────────────────────────────────────────── */
.aec table { width: 100%; border-collapse: collapse; font-size: 12.5px; }
.aec th {
  text-align: left; padding: 9px 15px; color: var(--dim);
  font-size: 10px; letter-spacing: 0.09em; text-transform: uppercase; font-weight: 600;
  border-bottom: 1px solid var(--line); white-space: nowrap;
}
.aec td { padding: 10px 15px; border-bottom: 1px solid var(--line); vertical-align: middle; }
.aec tbody tr:last-child td { border-bottom: 0; }
.aec tbody tr:hover { background: var(--panel-2); }
.aec th.n, .aec td.n { text-align: right; }
.aec .dim { color: var(--dim); }
.aec .up { color: var(--up); }
.aec .down { color: var(--down); }
.aec .zero { color: var(--faint); }
.aec .trunc { max-width: 1px; width: 52%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ── state primitives: empty · loading · error (every data region needs all 3) ─ */
.aec .empty {
  padding: 34px 18px; text-align: center;
  border: 1px dashed var(--line-2); border-radius: var(--r-card); background: var(--panel);
}
.aec .empty.bare { border: 0; background: none; padding: 22px 4px; }
.aec .empty .ico {
  width: 30px; height: 30px; margin: 0 auto 10px; border-radius: 7px;
  background: var(--panel-3); display: grid; place-items: center; color: var(--faint);
}
.aec .empty .ico svg { width: 16px; height: 16px; stroke: currentColor; fill: none; stroke-width: 1.7; }
.aec .empty b { font-size: 13px; font-weight: 600; }
.aec .empty p { color: var(--dim); font-size: 12.5px; line-height: 1.55; max-width: 46ch; margin: 5px auto 0; }
.aec .empty .reset { margin-top: 12px; }

.aec .skel { background: var(--panel-2); border-radius: var(--r-badge);
  overflow: hidden; position: relative; }
.aec .skel::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(90deg, transparent, rgba(255,255,255,.03), transparent);
  transform: translateX(-100%); animation: aec-shimmer 1.4s infinite;
}
@keyframes aec-shimmer { to { transform: translateX(100%); } }

.aec .errcard {
  border-left: 2px solid var(--down); background: rgba(212,104,90,.05);
  border-radius: var(--r-card); padding: 15px;
}
.aec .errcard h4 { margin: 0 0 5px; font-size: 12.5px; font-weight: 600; color: var(--down); }
.aec .errcard p { margin: 0 0 10px; color: var(--dim); font-size: 12.5px; line-height: 1.6; }

/* ── accessibility / motion ─────────────────────────────────────────────────── */
.aec :focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; }
@media (prefers-reduced-motion: reduce) {
  .aec *, .aec *::before, .aec *::after { transition: none !important; animation: none !important; }
}

/* ── responsive: rail → top drawer below 900px ──────────────────────────────── */
.aec .rail-toggle { display: none; }
@media (max-width: 900px) {
  .aec .shell { grid-template-columns: 1fr; }
  .aec .rail {
    position: fixed; z-index: 40; top: 0; left: 0; width: 260px; height: 100vh;
    transform: translateX(-100%); transition: transform .18s ease;
  }
  .aec .shell.rail-open .rail { transform: translateX(0); }
  .aec .rail-scrim { display: none; position: fixed; inset: 0; z-index: 39; background: rgba(0,0,0,.5); }
  .aec .shell.rail-open .rail-scrim { display: block; }
  .aec .rail-toggle {
    display: inline-grid; place-items: center; width: 32px; height: 30px;
    border: 1px solid var(--line); border-radius: var(--r-ctl); background: none;
    color: var(--dim); cursor: pointer; order: -1;
  }
  .aec .rail-toggle svg { width: 16px; height: 16px; stroke: currentColor; fill: none; stroke-width: 1.8; }
  .aec .body { padding: 15px 15px 56px; }
}

/* ── TikTok Direct Post composer (modal-tiktok) ────────────────────────────── */
.tt-id { display: flex; align-items: center; gap: 10px; }
.tt-avatar {
  width: 36px; height: 36px; border-radius: 50%; object-fit: cover;
  border: 1px solid var(--border-subtle); flex-shrink: 0;
}
.tt-preview {
  width: 100%; max-height: 300px; border-radius: 10px;
  background: #000; border: 1px solid var(--border-subtle);
}
/* A greyed compliance control: the creator turned it off in the TikTok app (or a
   rule excludes it) — shown so the user sees it exists, unusable on purpose. */
.ae-check.is-disabled { opacity: 0.5; cursor: not-allowed; }
.ae-check.is-disabled input { cursor: not-allowed; }

/* ═══ operator console v2 ═══════════════════════════════════════════════════
   The /ops surface was five pages that each had to be navigated back to /ops
   and re-entered, with every account's detail hidden behind an expando on a
   two-column grid. What follows is the rebuild: one persistent sidebar, one
   scannable row per account, and in-page jump navigation so a long account
   page is reachable without scrolling it.
   ========================================================================= */

/* ── the sidebar: 56px of icons, 244px on hover ────────────────────────────
   Collapsed by default because it is navigation, not content — it should cost
   the page almost nothing until it is wanted. It expands on hover AND on
   focus-within, which is not decoration: without the focus rule the labels are
   unreachable by keyboard and the whole rail becomes a row of unlabelled
   icons for anyone tabbing through it. */
.ops-nav {
  position: fixed;
  top: 56px;
  bottom: 0;
  left: 0;
  z-index: 25;
  width: 56px;
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 10px 0 16px;
  overflow: hidden;
  background: rgb(10 10 12 / 0.97);
  backdrop-filter: blur(8px);
  border-right: 1px solid var(--border-subtle);
  transition: width 0.16s ease, box-shadow 0.16s ease;
}
.ops-nav:hover,
.ops-nav:focus-within {
  width: 244px;
  overflow-y: auto;
  box-shadow: 18px 0 40px rgb(0 0 0 / 0.45);
}

.ops-nav-link {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-shrink: 0;
  margin: 0 6px;
  padding: 0 13px;
  height: 36px;
  border-radius: 8px;
  color: var(--text-secondary);
  font-size: 13px;
  text-decoration: none;
  white-space: nowrap;
  position: relative;
}
.ops-nav-link:hover { background: var(--bg-overlay); color: var(--text-primary); }
.ops-nav-link svg { flex-shrink: 0; }
/* Current page: the accent bar reads at 56px wide, where the label does not. */
.ops-nav-link.on { color: var(--text-primary); background: var(--bg-overlay); }
.ops-nav-link.on::before {
  content: "";
  position: absolute;
  left: -6px; top: 7px; bottom: 7px;
  width: 2px; border-radius: 2px;
  background: var(--accent);
}

/* Labels and headings fade with the rail rather than display:none-ing, so the
   width transition doesn't jump text into place at the end of it. */
.ops-nav-label,
.ops-nav-head,
.ops-nav-foot { opacity: 0; transition: opacity 0.12s ease; }
.ops-nav:hover .ops-nav-label,
.ops-nav:hover .ops-nav-head,
.ops-nav:hover .ops-nav-foot,
.ops-nav:focus-within .ops-nav-label,
.ops-nav:focus-within .ops-nav-head,
.ops-nav:focus-within .ops-nav-foot { opacity: 1; }

.ops-nav-label { overflow: hidden; text-overflow: ellipsis; }
.ops-nav-head {
  flex-shrink: 0;
  margin: 14px 6px 4px;
  padding: 0 13px;
  font-size: 10px;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--text-tertiary);
  white-space: nowrap;
}
.ops-nav-rule { flex-shrink: 0; height: 1px; margin: 8px 12px; background: var(--border-subtle); }
.ops-nav-foot {
  margin-top: auto;
  padding: 10px 19px 0;
  font-size: 10px;
  line-height: 1.5;
  color: var(--text-tertiary);
  white-space: nowrap;
}

/* An account's rail entry leads with a status dot, not an icon: at 56px the dot
   IS the information — which accounts are live, which are held, which are
   broken — and it survives the collapse where a name cannot. */
.ops-nav-dot {
  width: 8px; height: 8px; flex-shrink: 0;
  border-radius: 50%;
  margin: 0 4px;
  background: var(--text-tertiary);
}
.ops-nav-dot.is-active   { background: var(--ok); }
.ops-nav-dot.is-paused   { background: var(--warn); }
.ops-nav-dot.is-archived { background: var(--text-tertiary); opacity: 0.5; }
.ops-nav-dot.is-failing  { background: var(--bad); box-shadow: 0 0 0 3px rgb(var(--bad-rgb) / 0.18); }

/* Under 768px there is no room for a rail of any width, and a fixed one would
   sit on top of the content. It becomes a horizontally-scrolling strip under
   the header, permanently expanded — same links, same order. */
@media (max-width: 767px) {
  .ops-nav {
    position: static;
    width: auto;
    flex-direction: row;
    align-items: center;
    gap: 6px;
    overflow-x: auto;
    padding: 8px 12px;
    border-right: 0;
    border-bottom: 1px solid var(--border-subtle);
  }
  .ops-nav-label, .ops-nav-head, .ops-nav-foot { opacity: 1; }
  .ops-nav-head, .ops-nav-rule, .ops-nav-foot { display: none; }
  .ops-nav-link { margin: 0; }
}

/* ── the accounts list: one rectangle per account, no expandos ─────────────
   The whole rectangle is the link. The four things the operator asked to see
   without opening anything — is it running, when did it last run, is anything
   failing, how much is on the calendar — are the four cells. */
.ops-list { display: flex; flex-direction: column; gap: 10px; }

.ops-row {
  display: flex;
  align-items: center;
  gap: 18px;
  flex-wrap: wrap;
  padding: 15px 18px;
  border: 1px solid var(--border-subtle);
  border-left: 3px solid var(--text-tertiary);
  border-radius: 10px;
  background: var(--bg-raised);
  color: inherit;
  text-decoration: none;
  transition: border-color 0.1s ease, background 0.1s ease, transform 0.1s ease;
}
.ops-row:hover {
  background: var(--bg-overlay);
  border-color: var(--border-highlight);
  transform: translateX(1px);
}
.ops-row:hover .ops-row-name { color: var(--accent); }
.ops-row-active   { border-left-color: var(--ok); }
.ops-row-paused   { border-left-color: var(--warn); }
.ops-row-archived { border-left-color: var(--text-tertiary); opacity: 0.55; }
/* A broken lane outranks a green status: the point of the left edge is to be
   the one thing you can read at a glance, and "active" on an account whose
   production has been failing for three days is the wrong headline. */
.ops-row-failing  { border-left-color: var(--bad); }

.ops-row-main { flex: 2 1 210px; min-width: 0; }
.ops-row-cell { flex: 1 1 155px; min-width: 0; }
.ops-row-end  { margin-left: auto; display: flex; align-items: center; gap: 8px; flex-shrink: 0; }
.ops-row-name { font-size: 14.5px; font-weight: 600; color: var(--text-primary); }
.ops-row-sub {
  font-size: 12px; color: var(--text-secondary); margin-top: 2px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.ops-row-k {
  font-size: 10px; font-weight: 500; letter-spacing: 0.08em;
  text-transform: uppercase; color: var(--text-tertiary);
}
.ops-row-v { font-size: 12.5px; color: var(--text-primary); margin-top: 3px; }
.ops-row-v.is-bad  { color: var(--bad); }
.ops-row-v.is-ok   { color: var(--text-secondary); }
.ops-row-v.is-warn { color: var(--warn); }

/* ── in-page jump nav ──────────────────────────────────────────────────────
   Sticks under the fixed header so every section of a long account page is one
   click away. Sections carry scroll-margin-top or the header lands on top of
   the heading you just jumped to. */
.ops-jump {
  position: sticky;
  top: 56px;
  z-index: 20;
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin: 0 -20px 18px;
  padding: 10px 20px;
  background: rgb(10 10 12 / 0.94);
  backdrop-filter: blur(8px);
  border-bottom: 1px solid var(--border-subtle);
}
.ops-jump a {
  flex-shrink: 0;
  padding: 5px 11px;
  border: 1px solid var(--border-subtle);
  border-radius: 999px;
  background: var(--bg-raised);
  color: var(--text-secondary);
  font-size: 12px;
  text-decoration: none;
  white-space: nowrap;
}
.ops-jump a:hover { color: var(--text-primary); border-color: var(--border-highlight); }
.ops-jump a.on {
  color: var(--text-primary);
  background: var(--bg-overlay);
  border-color: rgb(var(--accent-rgb) / 0.55);
}
.ops-jump-count {
  margin-left: 5px;
  font-size: 10px;
  color: var(--text-tertiary);
  font-variant-numeric: tabular-nums;
}
.ops-jump a.is-bad { border-color: rgb(var(--bad-rgb) / 0.45); color: var(--bad); }
/* Header (56px) plus a two-row pill bar. The bar wraps rather than scrolling —
   a section you cannot see is a section you will not jump to, which defeats the
   point of it — so this has to clear the tallest it gets. ae.js narrows it to
   the bar's measured height once it can read one. */
.ops-section { scroll-margin-top: 152px; }

/* ── the weekly learning ledger ────────────────────────────────────────────
   One rectangle per week, because the learn loop runs twice a week and "what
   changed this week" is the unit the operator thinks in. Collapsed it shows
   the three counts; open it shows the three columns behind them. */
.wk { border: 1px solid var(--border-subtle); border-left: 3px solid var(--border-highlight);
      border-radius: 10px; background: var(--bg-raised); }
.wk + .wk { margin-top: 10px; }
.wk[open] { border-left-color: var(--accent); }
.wk > summary { list-style: none; cursor: pointer; }
.wk > summary::-webkit-details-marker { display: none; }
.wk-head { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; padding: 13px 16px; }
.wk-head::before {
  content: "▸";
  color: var(--text-tertiary);
  font-size: 11px;
  transition: transform 0.12s ease;
}
.wk[open] .wk-head::before { transform: rotate(90deg); }
.wk-when { font-size: 13.5px; font-weight: 600; color: var(--text-primary); }
.wk-dates { font-size: 12px; color: var(--text-secondary); }
.wk-counts { margin-left: auto; display: flex; gap: 6px; flex-wrap: wrap; }
.wk-chip {
  font-size: 11.5px; padding: 2px 9px; border-radius: 999px;
  border: 1px solid var(--border-subtle); color: var(--text-secondary);
  font-variant-numeric: tabular-nums; white-space: nowrap;
}
.wk-chip-learned  { color: var(--text-primary); border-color: rgb(var(--accent-rgb) / 0.45); }
.wk-chip-upgraded { color: var(--ok); border-color: rgb(var(--ok-rgb) / 0.35); }
.wk-chip-dropped  { color: var(--bad); border-color: rgb(var(--bad-rgb) / 0.3); }
.wk-chip-quiet    { color: var(--text-tertiary); }
.wk-body { padding: 2px 16px 16px; display: grid; gap: 18px; }
@media (min-width: 960px) { .wk-body { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
.wk-col-head {
  font-size: 10px; font-weight: 500; letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--text-tertiary); padding-bottom: 7px; border-bottom: 1px solid var(--border-subtle);
  margin-bottom: 10px;
}
.wk-item { font-size: 12.5px; line-height: 1.5; color: var(--text-primary); }
.wk-item + .wk-item { margin-top: 11px; padding-top: 11px; border-top: 1px solid rgb(38 38 44 / 0.4); }
.wk-item-meta { font-size: 11.5px; color: var(--text-secondary); margin-top: 3px; }
.wk-item-was { font-size: 11.5px; color: var(--text-tertiary); margin-top: 3px; }
.wk-item-was s { text-decoration-color: var(--bad); }
.wk-none { font-size: 12px; color: var(--text-tertiary); }

/* ── playbook entries: confidence readable before opening ──────────────────
   The left edge is banded by confidence and the meter repeats it numerically,
   so "which of these does AE actually believe" is answerable by scanning the
   left margin rather than by opening forty expandos. */
.pb {
  position: relative;
  border: 1px solid var(--border-subtle);
  border-radius: 10px;
  background: var(--bg-raised);
  overflow: hidden;
}
.pb + .pb { margin-top: 10px; }
.pb::before {
  content: "";
  position: absolute;
  left: 0; top: 0; bottom: 0;
  width: 4px;
  background: var(--text-tertiary);
}
.pb-c-high::before { background: var(--ok); }
.pb-c-good::before { background: var(--accent); }
.pb-c-thin::before { background: var(--warn); }
.pb-c-weak::before { background: var(--bad); }
/* A retired or draft entry is not steering anything, so its edge must not read
   as a live 0.9 belief. */
.pb-off::before { background: var(--text-tertiary); opacity: 0.6; }
.pb-off { opacity: 0.72; }

.pb > summary { list-style: none; cursor: pointer; padding: 13px 16px 13px 18px; }
.pb > summary::-webkit-details-marker { display: none; }
.pb-head { display: flex; align-items: flex-start; gap: 14px; }
.pb-title { font-size: 13.5px; font-weight: 600; color: var(--text-primary); }
.pb-meta { font-size: 11.5px; color: var(--text-secondary); margin-top: 4px; }
.pb-conf { margin-left: auto; flex-shrink: 0; text-align: right; }
.pb-conf-n {
  font-family: "JetBrains Mono", ui-monospace, monospace;
  font-size: 13px; font-variant-numeric: tabular-nums; color: var(--text-primary);
}
.pb-meter {
  width: 76px; height: 4px; margin-top: 5px; margin-left: auto;
  border-radius: 2px; background: var(--bg-overlay); overflow: hidden;
}
.pb-meter i { display: block; height: 100%; border-radius: 2px; background: var(--text-tertiary); }
.pb-c-high .pb-meter i { background: var(--ok); }
.pb-c-good .pb-meter i { background: var(--accent); }
.pb-c-thin .pb-meter i { background: var(--warn); }
.pb-c-weak .pb-meter i { background: var(--bad); }
.pb-body { padding: 0 16px 16px 18px; }

/* ── the weekly confidence recap ───────────────────────────────────────────
   What moved, which way, and the numbers underneath. Two columns so a gain and
   a drop of the same size are visibly different things. */
.recap { display: grid; gap: 18px; }
@media (min-width: 860px) { .recap { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.recap-col-head {
  display: flex; align-items: baseline; gap: 8px;
  font-size: 11px; font-weight: 500; letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--text-secondary); padding-bottom: 8px;
  border-bottom: 1px solid var(--border-subtle); margin-bottom: 12px;
}
.recap-item { display: flex; gap: 12px; align-items: flex-start; }
.recap-item + .recap-item { margin-top: 12px; padding-top: 12px; border-top: 1px solid rgb(38 38 44 / 0.4); }
.recap-delta {
  flex-shrink: 0;
  min-width: 56px;
  text-align: center;
  padding: 3px 8px;
  border-radius: 6px;
  font-family: "JetBrains Mono", ui-monospace, monospace;
  font-size: 12.5px;
  font-variant-numeric: tabular-nums;
}
.recap-up   { color: var(--ok);  background: rgb(var(--ok-rgb) / 0.12); }
.recap-down { color: var(--bad); background: rgb(var(--bad-rgb) / 0.12); }
.recap-title { font-size: 13px; font-weight: 600; color: var(--text-primary); }
.recap-why { font-size: 12px; color: var(--text-secondary); margin-top: 3px; line-height: 1.5; }
.recap-data {
  font-family: "JetBrains Mono", ui-monospace, monospace;
  font-size: 11px; color: var(--text-tertiary); margin-top: 5px;
  overflow-wrap: anywhere;
}
.recap-kind {
  font-size: 10px; letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--text-tertiary); margin-left: 6px;
}

/* ── section switcher (Insights | Campaign tactics) ────────────────────────── */
.ops-seg { display: inline-flex; padding: 3px; gap: 3px; border: 1px solid var(--border-subtle);
           border-radius: 10px; background: var(--bg-raised); }
.ops-seg a {
  padding: 6px 14px; border-radius: 7px; font-size: 13px;
  color: var(--text-secondary); text-decoration: none; white-space: nowrap;
}
.ops-seg a:hover { color: var(--text-primary); }
.ops-seg a.on { background: var(--bg-overlay); color: var(--text-primary); }

/* ── campaign tactics ──────────────────────────────────────────────────────
   Same confidence banding as an insight, plus the win record — which is the
   whole claim a tactic makes and has to be visible without opening it. */
.tac-record {
  display: inline-flex; align-items: baseline; gap: 5px;
  font-family: "JetBrains Mono", ui-monospace, monospace;
  font-size: 11.5px; font-variant-numeric: tabular-nums;
  padding: 2px 8px; border-radius: 999px;
  border: 1px solid var(--border-subtle); color: var(--text-secondary);
}
.tac-record.is-proven { color: var(--ok); border-color: rgb(var(--ok-rgb) / 0.35); }
.tac-record.is-untried { color: var(--text-tertiary); }
.tac-record.is-losing { color: var(--bad); border-color: rgb(var(--bad-rgb) / 0.3); }
.tac-parts { display: flex; flex-direction: column; gap: 6px; margin-top: 10px; }
.tac-part {
  display: flex; gap: 10px; align-items: baseline;
  font-size: 12.5px; color: var(--text-secondary);
  padding: 7px 11px; border-radius: 8px; background: var(--bg-overlay);
}
.tac-part b { color: var(--text-primary); flex-shrink: 0; font-variant-numeric: tabular-nums; }
.tac-cta {
  margin-top: 10px; padding: 9px 12px;
  border-left: 2px solid rgb(var(--accent-rgb) / 0.5);
  background: var(--bg-overlay); border-radius: 0 8px 8px 0;
  font-size: 12.5px; color: var(--text-primary);
}
/* A researched draft has not been read by a human yet — it must not look like a
   curated entry sitting next to one. */
.tac-new { border-style: dashed; }

/* ── the embedded agent log ────────────────────────────────────────────────── */
.log-scroll { max-height: 560px; overflow-y: auto; padding-right: 8px; }

/* ── agent spend ──────────────────────────────────────────────────────────────
   The reconciliation copy under the portfolio total is the one caption on the
   console that has to be able to say "these numbers do not agree" in colour, and
   the unpriced-run note has to be able to say "this figure is a floor".

   Deliberately NOT named .is-bad / .is-warn: those are already modifiers on
   .ops-row-v and .ops-jump a, and a global rule of that name would reach into
   both from a distance. */
.t-bad  { color: var(--bad); }
.t-warn { color: var(--warn); }

/* Spend numbers are numerals first — tabular figures so a column of them can be
   compared down the page rather than read one at a time. */
.spend-figure {
  font-family: "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
  font-variant-numeric: tabular-nums;
  font-size: 15px;
  color: var(--text-primary);
  margin-top: 3px;
}
