/*
 * Audience Marketing styles.
 *
 * Visual conventions cribbed from the SMTP Email Campaign Tool
 * (app/views/smtp_campaigns/, .smtp-* classes in avo_custom.css):
 *   - Filled pastel pills (bg + same-hue darker text), not outlined
 *   - Single-line dense tables wrapped in a white card container
 *   - Hierarchical detail pages: hero -> key relationships -> meta
 *   - Chip-lists for one-to-many fields so they scale to N values
 */

/* ------------------------------------------------------------------ */
/* Page shell                                                         */
/* ------------------------------------------------------------------ */
.campaign-page {
  /* Outer page padding lives at the app frame's .viewport > .shell rule
     (24px / --s-6). Do not re-set it here.

     `width: 100%` is load-bearing. The parent (.viewport > .shell) is
     `display: flex; flex-direction: column`, and flex children default
     to `min-width: auto` — they don't shrink below their intrinsic
     content size. Without `width: 100%` here, .campaign-page sizes to
     its content (wider table cells → wider page), which makes the page
     visibly grow or shrink between AM modules (Sends content is wider
     than Campaigns content; the page felt "bigger" on Sends). Matches
     the same fix DGT applied to .dg-shell. */
  width: 100%;
  max-width: 1280px;
  margin: 0 auto;
  /* Belt-and-suspenders: cap the cross-axis stretch in the flex parent
     so wide table content can't push past the cap. */
  min-width: 0;
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
}

/* Header: top row holds title + primary action.
   Cross-links live in a secondary nav strip below (.campaign-subnav). */
.campaign-header {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 1rem;
  margin-bottom: 0.5rem;
}
.campaign-title {
  font-size: 1.375rem;
  font-weight: 600;
  margin: 0;
  display: flex;
  align-items: center;
  gap: 0.5rem;
}
.campaign-subtitle {
  color: var(--color-slate-500);
  font-size: 0.8125rem;
  margin-top: 0.25rem;
}
.campaign-header-actions {
  display: flex;
  gap: 0.375rem;
  flex-shrink: 0;
}

/* ------------------------------------------------------------------ */
/* Top strip: back-arrow to Campaign Tools, Home link to Avo home.    */
/* Mirrors the convention in smtp_campaigns + sponsor_proposals.      */
/* ------------------------------------------------------------------ */
.campaign-toplinks {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin: -0.5rem 0 0.875rem;
  font-size: 0.8125rem;
}
.campaign-toplink-back {
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
  color: var(--color-slate-600);
  text-decoration: none;
}
.campaign-toplink-back:hover { color: #2563eb; }
.campaign-toplink-back svg { stroke-width: 2; }

/* Breadcrumbs nav (left side of top strip). */
.campaign-breadcrumbs {
  display: flex;
  align-items: center;
  gap: 0.375rem;
  flex-wrap: wrap;
  font-size: 0.8125rem;
  min-height: 1.5rem;
}
.campaign-breadcrumb-link {
  color: #2563eb;
  text-decoration: none;
}
.campaign-breadcrumb-link:hover {
  text-decoration: underline;
}
.campaign-breadcrumb-current {
  color: var(--color-slate-900);
  font-weight: 600;
}
.campaign-breadcrumb-sep {
  color: var(--color-slate-400);
  user-select: none;
}

.campaign-toplinks-actions {
  display: flex;
  align-items: center;
  gap: 0.875rem;
}
.campaign-toplink-home {
  color: var(--color-slate-500);
  text-decoration: none;
}
.campaign-toplink-home:hover { color: #2563eb; }

/* "My" dropdown in the persistent top strip — operator-scoped queues.
   Single trigger that opens to a menu of "My …" pages. Today the menu
   has one item (My creatives); other operator-scoped surfaces (My
   campaigns, My sends, etc.) get added here as data when they emerge. */
.campaign-my-dropdown {
  position: relative;
}
.campaign-my-trigger {
  background: transparent;
  border: 1px solid var(--border-strong);
  border-radius: var(--r-pill);
  padding: 0.25rem 0.625rem;
  font-family: inherit;
  font-size: 0.8125rem;
  font-weight: 500;
  color: var(--color-slate-700);
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
  line-height: 1.25rem;
}
.campaign-my-trigger:hover { background: var(--color-slate-50); border-color: var(--color-slate-400); }
.campaign-my-trigger-arrow {
  flex-shrink: 0;
}
.campaign-my-menu {
  position: absolute;
  top: calc(100% + 4px);
  right: 0;
  background: #ffffff;
  border: 1px solid var(--color-slate-300);
  border-radius: 0.375rem;
  box-shadow: 0 10px 25px -8px rgba(15, 17, 21, 0.18);
  padding: 0.25rem;
  min-width: 11rem;
  z-index: 50;
}
.campaign-my-menu a {
  display: block;
  padding: 0.4375rem 0.625rem;
  font-size: 0.8125rem;
  color: var(--color-slate-800);
  text-decoration: none;
  border-radius: 0.25rem;
}
.campaign-my-menu a:hover { background: #eff6ff; color: #1d4ed8; }

/* ------------------------------------------------------------------ */
/* Section nav: 4 dropdown pills (Activity / Creative / Audience /    */
/* Sending). Each opens on click to reveal its child links. The pill  */
/* containing the current page shows the child name as a subtitle.    */
/* Single-row, opens-on-demand — replaces the always-visible card.    */
/* ------------------------------------------------------------------ */
.campaign-subnav {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-top: 0.5rem;
  margin-bottom: 1.25rem;
  padding-top: 0.875rem;
  border-top: 1px solid var(--color-slate-200);
}
.campaign-subnav-group {
  position: relative;
}
.campaign-subnav-pill {
  display: inline-flex;
  align-items: center;
  gap: 0.4375rem;
  padding: 0.4375rem 0.75rem;
  border: 1px solid var(--border-strong);
  border-radius: var(--r-pill);                    /* 4px square per design-system shared-page-shell (was 9999px pill) */
  background: var(--surface);
  color: var(--fg-muted);
  font-size: 0.8125rem;
  line-height: 1;
  cursor: pointer;
  transition: background 0.15s, border-color 0.15s, color 0.15s;
  font-family: inherit;
}
.campaign-subnav-pill:hover {
  background: var(--color-slate-100);
  border-color: var(--color-slate-400);
}
/* Active pill uses the domain tint per AUDIENCE_MARKETING_PAGE_SHELL.md §4.
   The .am-domain-* class on the page wrapper sets --tint-100/200/800. */
.campaign-subnav-group--active .campaign-subnav-pill {
  background: var(--surface-2);                     /* neutral active state (weight + bg, no color tint) per DS shared-page-shell */
  border-color: var(--border-strong);
  color: var(--fg);
}
.campaign-subnav-pill-label {
  font-weight: 600;
  letter-spacing: 0.01em;
}
.campaign-subnav-pill-current {
  color: var(--color-slate-500);
  font-weight: 400;
  padding-left: 0.4375rem;
  border-left: 1px solid var(--color-slate-200);
  margin-left: 0.125rem;
}
.campaign-subnav-group--active .campaign-subnav-pill-current {
  color: var(--fg-muted);
  opacity: 0.8;
  border-left-color: var(--border);
}
.campaign-subnav-pill-arrow {
  color: var(--color-slate-400);
  margin-left: 0.0625rem;
  transition: transform 0.15s;
}
/* Flip the chevron when the menu sibling is open. The existing
   dropdown_controller toggles the [hidden] attribute on the menu
   target; we read that as the open/closed signal. */
.campaign-subnav-group:has(.campaign-subnav-menu:not([hidden])) .campaign-subnav-pill-arrow {
  transform: rotate(180deg);
}

/* Dropdown menu — anchored to the pill, opens below. */
.campaign-subnav-menu {
  position: absolute;
  top: calc(100% + 0.375rem);
  left: 0;
  z-index: 30;
  min-width: 12rem;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-modal);
  box-shadow: var(--sh-menu);
  padding: 0.375rem;
  display: flex;
  flex-direction: column;
  gap: 0.0625rem;
  animation: campaign-subnav-menu-in 0.12s ease-out;
}
.campaign-subnav-menu[hidden] { display: none; }
.campaign-subnav-menu a {
  display: block;
  padding: 0.4375rem 0.625rem;
  border-radius: 0.3125rem;
  color: var(--color-slate-700);
  font-size: 0.8125rem;
  text-decoration: none;
  line-height: 1.3;
  white-space: nowrap;
}
.campaign-subnav-menu a:hover {
  background: var(--color-slate-100);
  color: var(--color-slate-800);
}
.campaign-subnav-menu a.campaign-subnav-menu-item-current {
  background: #eff6ff;
  color: #1d4ed8;
  font-weight: 600;
}
@keyframes campaign-subnav-menu-in {
  from { opacity: 0; transform: translateY(-2px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* ------------------------------------------------------------------ */
/* Buttons                                                            */
/* ------------------------------------------------------------------ */
.campaign-btn {
  /* Matches both <a> and <button> elements (button_to renders a form
     with a <button>, browsers default-style buttons differently from
     anchors — these declarations override that). */
  display: inline-flex;
  align-items: center;
  justify-content: center;
  box-sizing: border-box;
  padding: 0.4375rem 0.875rem;
  margin: 0;
  border-radius: 0.375rem;
  font-family: inherit;
  font-size: 0.8125rem;
  font-weight: 500;
  text-decoration: none;
  cursor: pointer;
  border: 1px solid var(--color-slate-300);
  background: #ffffff;
  color: var(--color-slate-800);
  line-height: 1.25rem;
  transition: background 0.15s, border-color 0.15s;
  -webkit-appearance: none;
  appearance: none;
}
.campaign-btn:hover { background: var(--color-slate-100); border-color: var(--color-slate-400); }
.campaign-btn-primary { background: #2563eb; color: #ffffff; border-color: #2563eb; }
.campaign-btn-primary:hover { background: #1d4ed8; border-color: #1d4ed8; }
.campaign-btn-danger { background: #dc2626; color: #ffffff; border-color: #dc2626; }
.campaign-btn-danger:hover { background: #b91c1c; border-color: #b91c1c; }
.campaign-btn-sm { padding: 0.25rem 0.5rem; font-size: 0.75rem; line-height: 1rem; }
.campaign-btn-disabled {
  background: var(--color-slate-100);
  color: var(--color-slate-400);
  border-color: var(--color-slate-200);
  cursor: not-allowed;
}
.campaign-btn-disabled:hover { background: var(--color-slate-100); border-color: var(--color-slate-200); }

/* ------------------------------------------------------------------ */
/* "Manage X ↗" jump-link next to dropdowns on forms.                 */
/* CONVENTIONS.md §13.                                                */
/* ------------------------------------------------------------------ */
.campaign-form-label-inline {
  display: inline-block;
  margin-right: 0.5rem;
}
.campaign-manage-link {
  display: inline-block;
  font-size: 0.75rem;
  font-weight: 500;
  color: #2563eb;
  text-decoration: none;
  padding: 0.0625rem 0.4rem;
  border: 1px solid #dbeafe;
  border-radius: 0.25rem;
  background: #eff6ff;
  vertical-align: baseline;
}
.campaign-manage-link:hover {
  background: #dbeafe;
  border-color: #93c5fd;
  text-decoration: none;
}

/* Inline state-edit form on detail pages. */
.campaign-inline-state {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
}
.campaign-inline-state-label {
  font-size: 0.75rem;
  font-weight: 600;
  color: var(--color-slate-600);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  margin: 0;
}
.campaign-inline-state select {
  padding: 0.25rem 0.5rem;
  font-size: 0.8125rem;
  border-radius: 0.375rem;
  border: 1px solid var(--color-slate-300);
  background: #ffffff;
}

/* ------------------------------------------------------------------ */
/* Anchor blocks — Creative + RecipientList side by side, prominent.  */
/* ------------------------------------------------------------------ */
.campaign-anchors {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1rem;
  margin: 0 0 1.25rem 0;
}
.campaign-anchor {
  background: #ffffff;
  border: 1px solid var(--color-slate-300);
  border-radius: 0.5rem;
  padding: 1rem 1.25rem;
}
.campaign-anchor-label {
  font-size: 0.6875rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--color-slate-500);
  margin-bottom: 0.5rem;
}
.campaign-anchor-title {
  font-size: 1rem;
  font-weight: 600;
  color: var(--color-slate-900);
  margin-bottom: 0.25rem;
}
.campaign-anchor-title.campaign-anchor-empty {
  color: var(--color-slate-400);
  font-style: italic;
  font-weight: 500;
}
.campaign-anchor-meta {
  font-size: 0.8125rem;
  color: var(--color-slate-600);
}
@media (max-width: 720px) {
  .campaign-anchors { grid-template-columns: 1fr; }
}

/* button_to wraps in <form>; neutralize inline-form layout. */
.campaign-actions-panel form,
.campaign-header-actions form { display: inline; margin: 0; padding: 0; }

/* ------------------------------------------------------------------ */
/* Flash                                                              */
/* ------------------------------------------------------------------ */
.campaign-flash {
  padding: 0.625rem 0.875rem;
  border-radius: 0.375rem;
  margin-bottom: 1rem;
  font-size: 0.8125rem;
  border: 1px solid;
}
.campaign-flash-success { background: #ecfdf5; color: #065f46; border-color: #a7f3d0; }
.campaign-flash-error   { background: #fef2f2; color: #991b1b; border-color: #fca5a5; }

/* m2m grouping — canonical-home + cross-references pattern.
   Bold count in band header = primaries only; small +N xref annotation
   sits to the right alongside the count. Cross-reference rows use the
   indented-line treatment: smaller font, muted color, less vertical
   padding; date + name in the regular column geometry, pointer in a
   trailing colspan. */
.cp-group-xref-count {
  margin-left: 0.375rem;
  font-size: 0.6875rem;
  color: var(--color-slate-400);
  font-weight: normal;
}
.cp-m2m-xref > td {
  padding: 0.125rem 0.5rem;
  font-size: 0.6875rem;
  color: var(--color-slate-400);
  background: transparent;
  border-top: 1px solid var(--color-slate-100);
  line-height: 1.5;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 0; /* lets cells respect column widths and the per-cell
                   overflow/ellipsis instead of expanding to content */
}
/* Indentation — the whole xref row visually starts farther right
   than the primary rows so it reads as "demoted under." Applied as
   left-padding on the first cell so column alignment with primaries
   is preserved end-to-end (just shifted in). */
.cp-m2m-xref > td.cp-m2m-xref-date {
  padding-left: 2rem;
  font-variant-numeric: tabular-nums;
}
.cp-m2m-xref-name a {
  color: var(--color-slate-500);
  text-decoration: none;
}
.cp-m2m-xref-name a:hover { text-decoration: underline; }
.cp-m2m-xref-marker {
  margin-right: 0.25rem;
  color: var(--color-slate-300);
  font-size: 0.75rem;
}
.cp-m2m-xref-pointer {
  color: var(--color-slate-400);
}

/* ------------------------------------------------------------------ */
/* Tabs                                                               */
/* ------------------------------------------------------------------ */
.campaign-tabs {
  display: flex;
  gap: 0.5rem;
  border-bottom: 1px solid var(--color-slate-200);
  margin-bottom: 1rem;
}
.campaign-tab {
  padding: 0.5rem 0.875rem;
  color: var(--color-slate-500);
  text-decoration: none;
  border-bottom: 2px solid transparent;
  font-size: 0.8125rem;
  margin-bottom: -1px;
}
.campaign-tab:hover { color: var(--color-slate-700); }
.campaign-tab--active { color: var(--color-slate-900); border-bottom-color: #2563eb; font-weight: 500; }

/* ------------------------------------------------------------------ */
/* Filters                                                            */
/* ------------------------------------------------------------------ */
.campaign-filters {
  display: flex;
  gap: 0.5rem;
  margin-bottom: 0.625rem;
  flex-wrap: wrap;
  align-items: center;
}
.campaign-filters input,
.campaign-filters select {
  padding: 0.3125rem 0.5rem;
  border: 1px solid var(--color-slate-300);
  border-radius: 0.375rem;
  font-size: 0.8125rem;
  background: #ffffff;
}
.campaign-filters input { min-width: 14rem; }
.campaign-list-count {
  margin-bottom: 0.5rem;
  color: var(--color-slate-500);
  font-size: 0.75rem;
}

/* ------------------------------------------------------------------ */
/* Tables                                                             */
/* ------------------------------------------------------------------ */
.campaign-table-container {
  background: #ffffff;
  /* No `overflow` here — sticky positioning on <thead th> needs the
     bounded viewport's scroll container to be the ancestor that
     pins. Setting overflow-x:auto auto-promotes overflow-y to auto
     (per CSS spec when one axis is non-visible), which would create
     a fake scroll ancestor and break sticky. */
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.04);
}
.campaign-table {
  width: 100%;
  /* `separate` is required for sticky on <th> / band <td> to work
     across browsers (Chrome / Safari notoriously buggy with sticky
     under border-collapse:collapse). */
  border-collapse: separate;
  border-spacing: 0;
  font-size: 0.8125rem;
  table-layout: auto;
}
.campaign-table th,
.campaign-table td {
  padding: 0.5rem 0.75rem;
  text-align: left;
  border-bottom: 1px solid var(--color-slate-100);
  vertical-align: middle;
  white-space: nowrap;
}
.campaign-table th {
  background: var(--color-slate-50);
  color: var(--color-slate-600);
  font-weight: 600;
  font-size: 0.6875rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}
.campaign-table tbody tr:hover { background: var(--color-slate-50); }
.campaign-table tbody tr.cp-row-link { cursor: pointer; }
.campaign-table tbody tr.cp-row-link:hover { background: var(--color-slate-100); }
.campaign-table tbody tr:last-child td { border-bottom: 0; }
.campaign-table td.campaign-cell-num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.campaign-table td.campaign-cell-actions { text-align: right; width: 1%; white-space: nowrap; }
.campaign-table td.campaign-cell-wrap { white-space: normal; }

/* Name cell — long-string columns. Cap so the table fits a normal
   viewport without horizontal scroll. With multiple name cells per
   row (Sends has four: campaign, creative, list, config) the cap
   has to be tight or the table overflows even on 1440-wide screens.
   Full text remains in the link href + title tooltip. */
.campaign-table td.campaign-cell-name,
.campaign-table th.campaign-cell-name {
  max-width: 11rem;
  overflow: hidden;
  text-overflow: ellipsis;
}
.campaign-table td.campaign-cell-name a { display: inline-block; max-width: 100%; overflow: hidden; text-overflow: ellipsis; vertical-align: middle; }

.campaign-table a { color: var(--color-slate-800); text-decoration: none; }
.campaign-table a:hover { color: #2563eb; text-decoration: underline; }

/* Sortable column headers */
.campaign-sort-link {
  color: inherit;
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
}
.campaign-sort-link:hover { color: #2563eb; text-decoration: none; }
.campaign-sort-link--active { color: #2563eb; }
.campaign-sort-arrow {
  display: inline-block;
  font-size: 0.625rem;
  color: var(--color-slate-400);
  font-weight: 400;
}
.campaign-sort-arrow--active { color: #2563eb; font-weight: 700; }

/* Page-level free-text search */
.campaign-search-box {
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
  margin: 0;
}
.campaign-search-box input[type="text"] {
  padding: 0.3125rem 0.5rem;
  border: 1px solid var(--color-slate-300);
  border-radius: 0.375rem;
  font-size: 0.8125rem;
  background: #ffffff;
  min-width: 18rem;
}

/* Global utility: muted secondary text. Used inside table cells, the
   .campaign-keys strip values, anywhere a small dim string belongs.
   Block by default so it sits on its own line under a primary value;
   inline when used as a span inside a single-line cell. */
.campaign-meta {
  color: var(--color-slate-500);
  font-size: 0.75rem;
  font-weight: 400;
  line-height: 1.25;
}
div.campaign-meta { display: block; }
span.campaign-meta { display: inline; }

/* Role columns on Creatives — distinct pastel tints so the operator
   can scan to a row's drafter / proofer / approver assignments by
   color, not just by reading every cell. Header and cells get the
   same tint. Subtle enough that text remains readable.
   The header selectors are scoped under `.campaign-table thead` so
   they win specificity against the sticky-header rule below that
   fills every <th> with the panel gray. */
.campaign-table thead th.campaign-cell-role,
.campaign-table td.campaign-cell-role { background-color: rgba(0, 0, 0, 0.015); }
.campaign-table thead th.campaign-cell-role--drafter,
.campaign-table td.campaign-cell-role--drafter        { background-color: rgba(59, 130, 246, 0.06); }  /* blue */
.campaign-table thead th.campaign-cell-role--first-proofer,
.campaign-table td.campaign-cell-role--first-proofer  { background-color: rgba(245, 158, 11, 0.07); }  /* amber */
.campaign-table thead th.campaign-cell-role--second-proofer,
.campaign-table td.campaign-cell-role--second-proofer { background-color: rgba(16, 185, 129, 0.07); }  /* emerald */
.campaign-table thead th.campaign-cell-role--approver,
.campaign-table td.campaign-cell-role--approver       { background-color: rgba(139, 92, 246, 0.07); }  /* violet */
.campaign-table thead th.campaign-cell-role--creator,
.campaign-table td.campaign-cell-role--creator        { background-color: rgba(107, 114, 128, 0.06); } /* gray */
/* A short colored accent bar at the top of the header carries the role
   hue even when the row is hovered (which can wash out the fill). */
th.campaign-cell-role { position: relative; }
th.campaign-cell-role::before {
  content: "";
  position: absolute;
  top: 0; left: 0; right: 0;
  height: 2px;
}
th.campaign-cell-role--drafter::before        { background: #3b82f6; }
th.campaign-cell-role--first-proofer::before  { background: #f59e0b; }
th.campaign-cell-role--second-proofer::before { background: #10b981; }
th.campaign-cell-role--approver::before       { background: #8b5cf6; }
th.campaign-cell-role--creator::before        { background: var(--color-slate-500); }

/* ------------------------------------------------------------------ */
/* Pills (status badges) — filled pastel style                        */
/* Bg: light hue. Text: darker hue same family. No border.            */
/* ------------------------------------------------------------------ */
.campaign-pill {
  display: inline-block;
  padding: 0.0625rem 0.5rem;
  border-radius: 9999px;
  font-size: 0.6875rem;
  font-weight: 500;
  line-height: 1.125rem;
  white-space: nowrap;
  background: var(--color-slate-200);
  color: var(--color-slate-700);
  vertical-align: middle;
}

/* Campaign planning_state */
.campaign-pill--draft     { background: var(--color-slate-200); color: var(--color-slate-700); }
.campaign-pill--in-review { background: #fef3c7; color: #92400e; }
.campaign-pill--approved  { background: #d1fae5; color: #065f46; }
.campaign-pill--revising  { background: #fee2e2; color: #b91c1c; }
.campaign-pill--archived  { background: var(--color-slate-200); color: var(--color-slate-500); }

/* CampaignSend sending_status */
.campaign-pill--idle      { background: var(--color-slate-200); color: var(--color-slate-600); }
.campaign-pill--scheduled { background: #ede9fe; color: #6d28d9; }
.campaign-pill--sending   { background: #dbeafe; color: #1d4ed8; }
.campaign-pill--sent      { background: #d1fae5; color: #065f46; }
.campaign-pill--failed    { background: #fee2e2; color: #b91c1c; }
.campaign-pill--cancelled { background: var(--color-slate-100); color: var(--color-slate-500); }

/* Creative workflow_state */
.campaign-pill--placeholder    { background: var(--color-slate-100); color: var(--color-slate-500); }
.campaign-pill--drafted        { background: #dbeafe; color: #1d4ed8; }
.campaign-pill--proofed        { background: #ede9fe; color: #6d28d9; }
.campaign-pill--second-proofed { background: #ddd6fe; color: #5b21b6; }
.campaign-pill--please-revise  { background: #fee2e2; color: #b91c1c; }

/* Domain lifecycle_stage */
.campaign-pill--new      { background: var(--color-slate-200); color: var(--color-slate-600); }
.campaign-pill--warming  { background: #fef3c7; color: #92400e; }
.campaign-pill--active   { background: #d1fae5; color: #065f46; }
.campaign-pill--cooling  { background: #fed7aa; color: #9a3412; }
.campaign-pill--retired  { background: var(--color-slate-200); color: var(--color-slate-500); }

/* Vertical badges */
.campaign-vert {
  display: inline-block;
  padding: 0 0.4375rem;
  font-size: 0.625rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  border-radius: 0.25rem;
  vertical-align: middle;
}
.campaign-vert--people { background: #fce7f3; color: #9d174d; }
.campaign-vert--marketing { background: #cffafe; color: #155e75; }

/* ------------------------------------------------------------------ */
/* Chip lists (events, topics, etc — one-to-many that scales)         */
/* ------------------------------------------------------------------ */
.campaign-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 0.25rem;
}
.campaign-chip {
  display: inline-block;
  padding: 0.0625rem 0.5rem;
  background: var(--color-slate-100);
  border: 1px solid var(--color-slate-200);
  border-radius: 0.25rem;
  font-size: 0.75rem;
  color: var(--color-slate-800);
  text-decoration: none;
  white-space: nowrap;
  max-width: 22rem;
  overflow: hidden;
  text-overflow: ellipsis;
}
.campaign-chip:hover { background: var(--color-slate-200); color: #2563eb; }
.campaign-chip-more {
  font-size: 0.75rem;
  color: var(--color-slate-500);
  padding: 0.0625rem 0.25rem;
}

/* ------------------------------------------------------------------ */
/* Detail-page hierarchy                                              */
/* ------------------------------------------------------------------ */

/* Hero band — title + primary status pills + primary actions.
   Already covered by .campaign-header. */

/* Key relationships strip — the most important info on a show page,
   laid out as label-above-value pairs in a horizontal row.
   Visually prominent: white card, NOT gray boxes. */
.campaign-keys {
  background: #ffffff;
  border: 1px solid var(--color-slate-200);
  border-radius: 0.5rem;
  padding: 0.875rem 1rem;
  margin-bottom: 1rem;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
  gap: 1rem 1.5rem;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.03);
}
.campaign-key {
  display: flex;
  flex-direction: column;
  gap: 0.1875rem;
  min-width: 0;
}
.campaign-key-label {
  font-size: 0.625rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--color-slate-500);
  font-weight: 600;
}
/* Stacks primary value over (optional) .campaign-meta secondary line.
   min-width:0 prevents long unbroken strings from blowing out the grid. */
.campaign-key-value {
  display: flex;
  flex-direction: column;
  gap: 0.125rem;
  font-size: 0.875rem;
  color: var(--color-slate-900);
  min-width: 0;
  word-break: break-word;
  line-height: 1.3;
}
.campaign-key-value > a,
.campaign-key-value > span:not(.campaign-pill):not(.campaign-meta) {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  min-width: 0;
}
.campaign-key-value--multi { word-break: normal; }

/* Section headings between hero and content. */
.campaign-section {
  margin-top: 1.5rem;
  margin-bottom: 0.625rem;
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
}
.campaign-section-title {
  font-size: 0.875rem;
  font-weight: 600;
  margin: 0;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--color-slate-600);
}
.campaign-section-meta { font-size: 0.75rem; color: var(--color-slate-500); }

/* Settings/metadata grid — denser, smaller, lower-prominence than the
   key relationships strip. Used for technical-detail fields. */
.campaign-detail-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
  gap: 0.5rem 0.875rem;
  background: var(--color-slate-50);
  border: 1px solid var(--color-slate-200);
  border-radius: 0.5rem;
  padding: 0.75rem 1rem;
  margin-bottom: 1rem;
}
.campaign-detail-block {
  display: flex;
  flex-direction: column;
  gap: 0.1875rem;
  min-width: 0;
  font-size: 0.8125rem;
  color: var(--color-slate-800);
  line-height: 1.4;
}
/* Fallback: bare child divs (in views that don't use .campaign-detail-value
   explicitly) still get the right size + ellipsis. */
.campaign-detail-block > div:not(.campaign-detail-label):not(.campaign-meta) {
  font-size: 0.8125rem;
  min-width: 0;
  word-break: break-word;
}
.campaign-detail-label {
  font-size: 0.625rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--color-slate-500);
  font-weight: 600;
}
.campaign-detail-value {
  font-size: 0.8125rem;
  color: var(--color-slate-800);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.campaign-detail-value--wrap { white-space: normal; }

/* ------------------------------------------------------------------ */
/* Performance stats grid (Observability)                             */
/* Big-number cards with small label + percent. Used on Send show and */
/* Campaign show (rolled-up totals across the Campaign's Sends).       */
/* ------------------------------------------------------------------ */
.campaign-stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(8rem, 1fr));
  gap: 0.5rem;
  margin-bottom: 1rem;
}
.campaign-stat {
  background: #ffffff;
  border: 1px solid var(--color-slate-200);
  border-radius: 0.375rem;
  padding: 0.625rem 0.75rem;
  display: flex;
  flex-direction: column;
  gap: 0.125rem;
  min-width: 0;
}
.campaign-stat-label {
  font-size: 0.625rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--color-slate-500);
  font-weight: 600;
}
.campaign-stat-value {
  font-size: 1.375rem;
  font-weight: 600;
  color: var(--color-slate-900);
  line-height: 1.1;
  font-variant-numeric: tabular-nums;
}
.campaign-stat-value--empty { color: var(--color-slate-400); font-weight: 400; }
.campaign-stat-rate {
  font-size: 0.75rem;
  color: var(--color-slate-500);
  font-variant-numeric: tabular-nums;
}
.campaign-stat-rate--good { color: #059669; }
.campaign-stat-rate--bad { color: #b91c1c; }

.campaign-stats-empty {
  background: var(--color-slate-50);
  border: 1px dashed var(--color-slate-300);
  border-radius: 0.5rem;
  padding: 1rem;
  text-align: center;
  color: var(--color-slate-500);
  font-size: 0.8125rem;
  margin-bottom: 1rem;
}
.campaign-stats-empty a { color: #2563eb; }

/* Workflow / state-transition action panel. Slightly more prominent. */
.campaign-actions-panel {
  background: #ffffff;
  border: 1px solid var(--color-slate-200);
  border-radius: 0.5rem;
  padding: 0.625rem 0.875rem;
  margin-bottom: 1rem;
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  align-items: center;
  font-size: 0.8125rem;
}
.campaign-actions-panel strong {
  color: var(--color-slate-600);
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  margin-right: 0.5rem;
}

/* ------------------------------------------------------------------ */
/* Long-text blocks (notes, descriptions)                             */
/* ------------------------------------------------------------------ */
.campaign-prose {
  background: var(--color-slate-50);
  border: 1px solid var(--color-slate-200);
  border-radius: 0.5rem;
  padding: 0.75rem 1rem;
  margin-bottom: 1rem;
  font-size: 0.8125rem;
  color: var(--color-slate-800);
  line-height: 1.4;
}
.campaign-prose pre {
  white-space: pre-wrap;
  margin: 0;
  font-family: inherit;
  font-size: inherit;
}

/* ------------------------------------------------------------------ */
/* Form                                                               */
/* ------------------------------------------------------------------ */
.campaign-form { max-width: 720px; }
.campaign-form .field { margin-bottom: 0.875rem; }
.campaign-form label {
  display: block;
  margin-bottom: 0.25rem;
  font-size: 0.8125rem;
  font-weight: 500;
  color: var(--color-slate-700);
}
.campaign-form input[type="text"],
.campaign-form input[type="email"],
.campaign-form input[type="url"],
.campaign-form input[type="number"],
.campaign-form input[type="datetime-local"],
.campaign-form textarea,
.campaign-form select {
  width: 100%;
  padding: 0.4375rem 0.625rem;
  border: 1px solid var(--color-slate-300);
  border-radius: 0.375rem;
  font-size: 0.8125rem;
  background: #ffffff;
}
.campaign-form textarea { min-height: 4rem; }
.campaign-form .errors {
  background: #fef2f2;
  color: #991b1b;
  padding: 0.5rem 0.75rem;
  border-radius: 0.375rem;
  margin-bottom: 1rem;
  font-size: 0.8125rem;
  border: 1px solid #fca5a5;
}
.campaign-form .actions {
  margin-top: 1.25rem;
  display: flex;
  gap: 0.5rem;
}

/* ------------------------------------------------------------------ */
/* Empty state                                                        */
/* ------------------------------------------------------------------ */
.campaign-empty {
  padding: 2rem;
  text-align: center;
  color: var(--color-slate-500);
  background: var(--color-slate-50);
  border-radius: 0.5rem;
  border: 1px dashed var(--color-slate-300);
  font-size: 0.8125rem;
}
/* Muted variant for the overflow-refusal case — the flash alert above
   carries the explanation, this is just a soft hint. */
.campaign-empty--muted {
  background: transparent;
  border-style: dotted;
  border-color: var(--color-slate-200);
  color: var(--color-slate-400);
}

/* ------------------------------------------------------------------ */
/* Weekly plan grid                                                   */
/* ------------------------------------------------------------------ */
.weekly-plan-grid {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 0.5rem;
  margin-top: 1rem;
}
.weekly-plan-day {
  background: var(--color-slate-50);
  padding: 0.5rem;
  border-radius: 0.375rem;
  min-height: 200px;
}
.weekly-plan-day-header {
  font-size: 0.6875rem;
  font-weight: 600;
  color: var(--color-slate-500);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  margin-bottom: 0.375rem;
}
.weekly-plan-send {
  background: #ffffff;
  border: 1px solid var(--color-slate-200);
  border-radius: 0.25rem;
  padding: 0.3125rem 0.5rem;
  font-size: 0.75rem;
  margin-bottom: 0.25rem;
}
/* Audience-segment chips on the weekly-plan card. Operators scan dozens
   of these per day and asked for visual differentiation between comp /
   paid and community / non-community. Pill-style fill so each axis is
   distinguishable at a glance. */
.weekly-plan-comp,
.weekly-plan-rtype {
  display: inline-block;
  padding: 0 0.3125rem;
  border-radius: 0.1875rem;
  font-size: 0.65rem;
  font-weight: 500;
  letter-spacing: 0.01em;
  line-height: 1.3;
  vertical-align: baseline;
}
.weekly-plan-comp--comp                  { background: #fef3c7; color: #92400e; }  /* amber — comp */
.weekly-plan-comp--paid                  { background: #dcfce7; color: #166534; }  /* green — paid */
.weekly-plan-comp--not-applicable        { background: var(--color-slate-100); color: var(--color-slate-500); }
.weekly-plan-rtype--community-member     { background: #dbeafe; color: #1e40af; }  /* blue — community */
.weekly-plan-rtype--non-community-member { background: #fce7f3; color: #9d174d; }  /* pink — non-community */
.weekly-plan-rtype--not-applicable       { background: var(--color-slate-100); color: var(--color-slate-500); }

/* ------------------------------------------------------------------ */
/* Grouped table sections (collapsible)                               */
/* Convention in docs/GROUP_BY_AND_SORT_CONVENTION.md                 */
/* ------------------------------------------------------------------ */
.grouped-section { margin-top: 1.25rem; }
.grouped-section:first-child { margin-top: 0.5rem; }

.grouped-section-header {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.625rem 0.875rem;
  margin: 0 0 0.5rem;
  width: 100%;
  border-radius: 0.5rem;
  border: 1px solid var(--color-slate-200);
  background: var(--color-slate-50);
  color: var(--color-slate-700);
  font-family: inherit;
  text-align: left;
  cursor: pointer;
  transition: filter 0.12s;
}
.grouped-section-header:hover { filter: brightness(0.97); }
.grouped-section-header-label {
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  font-size: 0.75rem;
}
.grouped-section-header-count {
  font-weight: 600;
  font-size: 0.875rem;
  margin-left: auto;
  font-variant-numeric: tabular-nums;
  color: inherit;
  opacity: 0.75;
}
.grouped-section-chevron {
  flex-shrink: 0;
  opacity: 0.6;
  transition: transform 0.15s;
}
.grouped-section--collapsed .grouped-section-chevron { transform: rotate(-90deg); }
.grouped-section--collapsed .grouped-section-header { margin-bottom: 0; }

/* State-tinted variants — used when grouping by an enum like
   workflow_state on My creatives or planning_state on My campaigns.
   Each variant tints the header band by the state's role, so
   operators can scan grouped tables by color. Convention: tint maps
   to the dasherized state name. */
.grouped-section-header--placeholder       { background: var(--color-slate-100); border-color: var(--color-slate-300); color: var(--color-slate-700); }
.grouped-section-header--drafted           { background: #dbeafe; border-color: #93c5fd; color: #1e40af; }
.grouped-section-header--proofed           { background: #d1fae5; border-color: #6ee7b7; color: #065f46; }
.grouped-section-header--second-proofed    { background: #ddd6fe; border-color: #a78bfa; color: #4c1d95; }
.grouped-section-header--approved          { background: #fef3c7; border-color: #fcd34d; color: #78350f; }
.grouped-section-header--please-revise     { background: #fee2e2; border-color: #fca5a5; color: #991b1b; }
.grouped-section-header--draft             { background: var(--color-slate-100); border-color: var(--color-slate-300); color: var(--color-slate-700); }
.grouped-section-header--in-review         { background: #ddd6fe; border-color: #a78bfa; color: #4c1d95; }
.grouped-section-header--revising          { background: #fee2e2; border-color: #fca5a5; color: #991b1b; }

/* Footer line on the My pages: surfaces the count of items outside
   the date window so operators don't think we're hiding things. */
.campaign-out-of-window {
  margin-top: 1rem;
  padding: 0.625rem 0.875rem;
  background: var(--color-slate-50);
  border: 1px dashed var(--color-slate-300);
  border-radius: 0.5rem;
  font-size: 0.8125rem;
  color: var(--color-slate-500);
}
.campaign-out-of-window a {
  color: #2563eb;
  text-decoration: none;
  margin-left: 0.25rem;
}
.campaign-out-of-window a:hover { text-decoration: underline; }

/* ================================================================== */
/* Control panel — declarative-summary header for the index pages.    */
/* See docs/GROUP_BY_AND_SORT_CONVENTION.md and the                    */
/* audience-marketing-control-panel-design briefing.                  */
/* ================================================================== */
.cp-panel {
  position: relative;
  margin: 0.5rem 0 0.75rem;
  padding: 0.75rem 0;
  border-top: 1px solid var(--color-slate-200);
  border-bottom: 1px solid var(--color-slate-200);
  font-size: 0.875rem;
  background: #fff;
}

.cp-sentence {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0 0.375rem;
  line-height: 1.7;
  color: var(--color-slate-700);
}
.cp-word { color: var(--color-slate-500); }
.cp-count {
  color: var(--color-slate-900);
  font-weight: 600;
}
/* m2m memberships annotation — secondary, parenthetical. Surfaces
   total rendered rows (primaries + xrefs) when m2m grouping makes
   one record appear in multiple sections. */
.cp-memberships {
  color: var(--color-slate-500);
  font-size: 0.8125rem;
  font-variant-numeric: tabular-nums;
}

/* The clickable token. Soft pastel; hover shifts to faint blue. */
.cp-chip-wrap {
  position: relative;
  display: inline-flex;
  align-items: baseline;
  gap: 0.25rem;
}
.cp-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  padding: 0.125rem 0.4375rem;
  border: 1px solid transparent;
  border-radius: 0.25rem;
  background: var(--color-slate-100);
  color: var(--color-slate-900);
  font-weight: 500;
  font-family: inherit;
  cursor: pointer;
  user-select: none;
  transition: background-color 120ms, border-color 120ms, color 120ms;
}
.cp-chip:hover {
  background: #eff6ff;
  border-color: rgba(37, 99, 235, 0.18);
  color: #1d4ed8;
}
.cp-chev {
  color: var(--color-slate-400);
  font-size: 0.6875rem;
}
.cp-chip:hover .cp-chev { color: #1d4ed8; }

/* Two visual treatments only across the sentence:
   1. FILLED VALUES (.cp-chip + .cp-chip--sort + .cp-chip--group-order
      + .cp-filter) — soft warm-gray background, ink text.
   2. EMPTY SLOTS (.cp-chip--empty for "not grouped", .cp-chip--add for
      "+ filter" and "+ order groups") — dashed accent border,
      transparent fill, accent text.
   No "privileged" treatment for the date — visually elevating it
   makes the line uneven and tells the reader nothing useful. */

/* Empty / unfilled slot — same shape and hover as .cp-chip--add. */
.cp-chip--empty,
.cp-chip--add {
  background: transparent;
  color: #1d4ed8;
  border: 1px dashed rgba(37, 99, 235, 0.35);
  font-weight: 500;
}
.cp-chip--empty:hover,
.cp-chip--add:hover {
  background: #dbeafe;
  border-style: dashed;
  color: #1d4ed8;
}

/* Sort + group-order chips: split label / arrow region so the arrow
   is independently clickable (Excel-style click-to-flip). */
.cp-chip--sort,
.cp-chip--group-order {
  padding: 0;
  background: var(--color-slate-100);
  border: 1px solid transparent;
  border-radius: 0.25rem;
  overflow: hidden;
}
.cp-chip--sort:hover,
.cp-chip--group-order:hover {
  background: #eff6ff;
  border-color: rgba(37, 99, 235, 0.18);
}
.cp-chip-label {
  display: inline-flex;
  align-items: center;
  padding: 0.125rem 0.5rem;
  background: transparent;
  border: none;
  color: inherit;
  font-weight: 500;
  font-family: inherit;
  cursor: pointer;
}
.cp-chip-arrow {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 1.25rem;
  padding: 0.125rem 0.3125rem;
  background: transparent;
  border-left: 1px solid rgba(0, 0, 0, 0.08);
  color: var(--color-slate-500);
  font-size: 0.8125rem;
  text-decoration: none;
  cursor: pointer;
}
.cp-chip-arrow:hover {
  background: rgba(37, 99, 235, 0.12);
  color: #1d4ed8;
  text-decoration: none;
}

/* The × inside a chip — used by the group-order chip to clear the
   override entirely. Lives next to the direction arrow, looks like
   a quiet sibling, hover signals destructive intent. */
.cp-chip-x {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 1.125rem;
  padding: 0.125rem 0.3125rem;
  background: transparent;
  border-left: 1px solid rgba(0, 0, 0, 0.08);
  color: var(--color-slate-400);
  font-size: 0.875rem;
  line-height: 1;
  text-decoration: none;
  cursor: pointer;
}
.cp-chip-x:hover {
  background: rgba(220, 38, 38, 0.08);
  color: #b91c1c;
  text-decoration: none;
}

/* WHERE row. Filter chips here use the same filled treatment as
   value chips in the sentence above — one shape, one background. */
.cp-where {
  margin-top: 0.5rem;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.375rem;
}
.cp-where-label {
  color: var(--color-slate-500);
  font-size: 0.6875rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  font-weight: 600;
  margin-right: 0.125rem;
}
/* WHERE-row chip — visual spec: STATE 12 in find-bar-states.html.
   Structure: [scope label] [italic muted op-word] [semibold value] × */
.cp-filter {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 3px 8px;
  background: #ffffff;
  color: var(--color-slate-900);
  border: 1px solid var(--color-slate-200);
  border-radius: 4px;
  font-size: 12px;
  transition: background-color 120ms, border-color 120ms;
}
.cp-filter:hover {
  background: var(--color-slate-50);
  border-color: var(--color-slate-300);
}
.cp-filter-field {
  color: var(--color-slate-500);
  font-size: 11px;
  font-weight: 400;
  flex-shrink: 0;
}
.cp-filter-op {
  color: var(--color-slate-400);
  font-size: 11px;
  font-style: italic;
  font-weight: 400;
  flex-shrink: 0;
}
.cp-filter-val {
  color: var(--color-slate-900);
  font-weight: 500;
  max-width: 18rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.cp-filter-edit {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  text-decoration: none;
  color: inherit;
  cursor: pointer;
}
.cp-filter-edit:hover .cp-filter-val { color: #1d4ed8; }
/* Display-only chip body (e.g., the Mine chip) — no edit hover. */
.cp-filter-edit--readonly { cursor: default; }
.cp-filter-edit--readonly:hover .cp-filter-val { color: inherit; }
.cp-filter-x {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 1.125rem;
  margin-left: 0.125rem;
  padding: 0 0.25rem;
  color: var(--color-slate-400);
  font-size: 0.875rem;
  line-height: 1;
  text-decoration: none;
  border-radius: 0.1875rem;
}
.cp-filter-x:hover {
  background: rgba(220, 38, 38, 0.08);
  color: #b91c1c;
  text-decoration: none;
}

/* Actions row. */
.cp-actions {
  margin-top: 0.5rem;
  display: flex;
  align-items: center;
  gap: 0.875rem;
  font-size: 0.6875rem;
  color: var(--color-slate-400);
}
.cp-action-link {
  color: var(--color-slate-500);
  font-size: 0.6875rem;
  text-decoration: none;
}
.cp-action-link:hover { color: var(--color-slate-900); text-decoration: underline; }
.cp-action-link--clear { margin-left: 0.5rem; }

/* Popover — positioned by CSS, anchored to its parent .cp-chip-wrap
   (which is position: relative). No JS positioning. Capped at 60vh
   so a tall enum list (or a long sortable field list) can never
   exceed the viewport — content scrolls inside instead. */
.cp-pop {
  position: absolute;
  top: calc(100% + 4px);
  left: 0;
  z-index: 60;
  min-width: 14rem;
  max-width: 22rem;
  max-height: 60vh;
  overflow-y: auto;
  background: #fff;
  border: 1px solid var(--color-slate-200);
  border-radius: 0.375rem;
  box-shadow: 0 16px 40px -10px rgba(15, 17, 21, 0.22), 0 0 0 1px rgba(15, 17, 21, 0.06);
  padding: 0.25rem 0;
  text-align: left;
  font-size: 0.8125rem;
}
.cp-pop[hidden] { display: none; }
.cp-pop-h {
  padding: 0.375rem 0.75rem 0.25rem;
  font-size: 0.625rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--color-slate-500);
  font-weight: 600;
  border-bottom: 1px solid var(--color-slate-100);
}
.cp-opt {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.3125rem 0.75rem;
  color: var(--color-slate-900);
  text-decoration: none;
  cursor: pointer;
  font-size: 0.75rem;
  font-family: inherit;
}
.cp-opt:hover { background: var(--color-slate-50); text-decoration: none; }
.cp-opt--current { font-weight: 500; }
.cp-opt .cp-check {
  display: inline-flex;
  width: 0.625rem;
  color: #16a34a;
  font-size: 0.6875rem;
  visibility: hidden;
}
.cp-opt--current .cp-check { visibility: visible; }
.cp-opt-meta {
  color: var(--color-slate-400);
  font-size: 0.6875rem;
  font-weight: 400;
}
.cp-pop-divider {
  height: 1px;
  background: var(--color-slate-100);
  margin: 0.25rem 0;
}
.cp-pop-section-title {
  padding: 0.375rem 0.75rem 0.125rem;
  font-size: 0.625rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--color-slate-400);
  font-weight: 600;
}

/* Date popover specifics. */
.cp-pop--date { min-width: 18rem; }
.cp-preset-row {
  display: flex;
  flex-wrap: wrap;
  gap: 0.25rem;
  padding: 0.5rem 0.75rem 0.25rem;
}
.cp-preset {
  padding: 0.25rem 0.625rem;
  border: 1px solid var(--color-slate-200);
  border-radius: 100px;
  background: #fff;
  color: var(--color-slate-700);
  font-size: 0.6875rem;
  text-decoration: none;
}
.cp-preset:hover {
  border-color: #1d4ed8;
  color: #1d4ed8;
  text-decoration: none;
}
.cp-preset--current {
  background: #dbeafe;
  border-color: #1d4ed8;
  color: #1d4ed8;
  font-weight: 500;
}
.cp-pop-custom {
  padding: 0.5rem 0.75rem 0.625rem;
  border-top: 1px solid var(--color-slate-100);
  margin-top: 0.375rem;
  display: flex;
  align-items: center;
  gap: 0.375rem;
  font-size: 0.6875rem;
  color: var(--color-slate-500);
}
.cp-pop-custom input[type="date"],
.cp-pop-custom input[type="text"] {
  border: 1px solid var(--color-slate-200);
  padding: 0.1875rem 0.375rem;
  border-radius: 0.25rem;
  font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  font-size: 0.6875rem;
}
.cp-pop-submit {
  padding: 0.1875rem 0.5rem;
  background: #2563eb;
  color: #fff;
  border: none;
  border-radius: 0.25rem;
  font-size: 0.6875rem;
  cursor: pointer;
}
.cp-pop-submit:hover { background: #1d4ed8; }

/* Inline value chips inside the + filter popover (one section per
   filterable field; clicking a chip applies that filter directly). */
.cp-pop--filter { min-width: 17rem; max-width: 24rem; }
.cp-pop-values {
  display: flex;
  flex-wrap: wrap;
  gap: 0.25rem;
  padding: 0.125rem 0.75rem 0.375rem;
}
.cp-pill-link {
  display: inline-flex;
  align-items: center;
  padding: 0.1875rem 0.5rem;
  background: var(--color-slate-100);
  color: var(--color-slate-900);
  font-size: 0.6875rem;
  font-weight: 500;
  border-radius: 100px;
  text-decoration: none;
  border: 1px solid transparent;
}
.cp-pill-link:hover {
  background: #dbeafe;
  border-color: rgba(37, 99, 235, 0.18);
  color: #1d4ed8;
  text-decoration: none;
}
.cp-pop-section-empty {
  padding: 0.25rem 0.75rem 0.5rem;
  color: var(--color-slate-400);
  font-size: 0.6875rem;
  font-style: italic;
}

/* Group section header rendered inside the campaigns table when
   grouped. The header IS the click target — clicking toggles
   collapse via the grouped-section Stimulus controller, which adds
   the `.grouped-section--collapsed` class on the wrapping <section>
   and hides the body. */
/* One-table grouped layout — see GROUPED_TABLE_STRUCTURE_DELTA.md.
   The <table> contains a single sticky <thead> and a single <tbody>
   that interleaves group bands (full-width <tr> via colspan) with
   data rows. Column geometry is shared across all groups. */

.campaign-table thead th {
  position: sticky;
  top: 0;
  z-index: 2;
  background: var(--color-slate-50);
}
.campaign-table--grouped .cp-group-band > td {
  /* Bands deliberately do NOT stick — pinning them obscures whether
     the row currently in view is the first entry in the section.
     Only the column header sticks. */
  padding: 0;
  background: var(--color-slate-100);
  border-top: 1px solid var(--color-slate-200);
  border-bottom: 1px solid var(--color-slate-200);
  /* The band button is absolutely positioned inside this cell so its
     intrinsic content width (which can be very long for combo m2m
     sections like "Event A + Event B + Event C") does NOT push the
     table's `table-layout: auto` columns wider. The cell defines a
     fixed-height box; the button paints across it. */
  position: relative;
  height: 1.875rem;
  overflow: hidden;
}

.cp-group-band-btn {
  position: absolute;
  inset: 0;
  width: 100%;
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.5rem 0.875rem;
  background: transparent;
  border: 0;
  font-size: 0.6875rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-weight: 600;
  color: var(--color-slate-700);
  cursor: pointer;
  text-align: left;
  font-family: inherit;
}
.cp-group-band-btn:hover { background: rgba(0,0,0,0.03); }

.cp-group-band-label {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.cp-group-count {
  flex-shrink: 0;
  margin-left: auto;
  font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  font-size: 0.6875rem;
  color: var(--color-slate-500);
  text-transform: none;
  letter-spacing: 0;
}
.cp-group-order-value {
  flex-shrink: 0;
  font-size: 0.6875rem;
  color: var(--color-slate-400);
  font-weight: normal;
  text-transform: none;
  letter-spacing: 0;
  font-variant-numeric: tabular-nums;
}
.cp-group-chevron {
  flex-shrink: 0;
  color: var(--color-slate-500);
  transition: transform 120ms ease;
}
.cp-group-band--collapsed .cp-group-chevron {
  transform: rotate(-90deg);
}

/* ================================================================== */
/* Relevance toggle — "Show archived" / "Show sent" / etc.            */
/* See docs/RELEVANCE_TOGGLE_PATTERN.md.                              */
/* Pill switch + label, lives in the page heading meta-cluster.       */
/* OFF (default): muted, archived/etc. records hidden.                */
/* ON: accent color, irrelevant records included in the view.         */
/* ================================================================== */
.rt-toggle {
  display: inline-flex;
  align-items: center;
  gap: 0.4375rem;
  padding: 0.25rem 0.5rem;
  background: transparent;
  border: 1px solid transparent;
  border-radius: 0.25rem;
  text-decoration: none;
  cursor: pointer;
  user-select: none;
  font-family: inherit;
  transition: background-color 120ms;
}
.rt-toggle:hover {
  background: var(--color-slate-100);
  text-decoration: none;
}
.rt-toggle-pill {
  position: relative;
  display: inline-block;
  width: 1.5rem;
  height: 0.875rem;
  background: var(--color-slate-300);
  border-radius: 100px;
  transition: background-color 120ms;
}
.rt-toggle-knob {
  position: absolute;
  top: 1px;
  left: 1px;
  width: 0.75rem;
  height: 0.75rem;
  background: #ffffff;
  border-radius: 100px;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.15);
  transition: transform 120ms;
}
.rt-toggle-label {
  font-size: 0.75rem;
  font-weight: 500;
  color: var(--color-slate-500);
  transition: color 120ms;
}
.rt-toggle--on .rt-toggle-pill {
  background: #2563eb;
}
.rt-toggle--on .rt-toggle-knob {
  transform: translateX(0.625rem);
}
.rt-toggle--on .rt-toggle-label {
  color: var(--color-slate-900);
}

/* =====================================================================
   Display popover (column visibility + reorder) + pagination footer.
   See docs/CONTROL_PANEL_DELTA_DISPLAY.md for the brief.
   ===================================================================== */

.cp-display-wrap {
  position: relative;
  display: inline-flex;
}

.cp-display-btn {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.375rem 0.625rem;
  background: transparent;
  border: 1px solid var(--color-slate-300);
  border-radius: 6px;
  color: var(--color-slate-700);
  font-size: 0.8125rem;
  font-weight: 500;
  cursor: pointer;
  transition: background 120ms, border-color 120ms;
}
.cp-display-btn:hover {
  background: var(--color-slate-50);
  border-color: var(--color-slate-400);
}
.cp-display-btn[aria-expanded="true"] {
  border-color: #2563eb;
  color: #1d4ed8;
}
.cp-display-count {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 1.25rem;
  height: 1.25rem;
  padding: 0 0.375rem;
  background: var(--color-slate-100);
  border-radius: 999px;
  font-size: 0.75rem;
  font-weight: 600;
  color: var(--color-slate-600);
}

.cp-display-popover {
  position: absolute;
  top: calc(100% + 0.375rem);
  right: 0;
  z-index: 30;
  width: 280px;
  max-height: 70vh;
  overflow-y: auto;
  background: #ffffff;
  border: 1px solid var(--color-slate-200);
  border-radius: 8px;
  box-shadow: 0 12px 24px -8px rgba(0, 0, 0, 0.18), 0 4px 8px -4px rgba(0, 0, 0, 0.08);
  padding: 0.5rem 0;
  font-size: 0.8125rem;
}
.cp-display-popover[hidden] { display: none; }

.cp-display-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0.5rem 0.875rem 0.375rem;
}
.cp-display-header-title {
  font-size: 0.6875rem;
  font-weight: 700;
  letter-spacing: 0.05em;
  color: var(--color-slate-500);
}
.cp-display-reset {
  font-size: 0.75rem;
  font-weight: 500;
  color: #2563eb;
  text-decoration: none;
}
.cp-display-reset:hover { text-decoration: underline; }

.cp-display-subhead {
  padding: 0.25rem 0.875rem 0.5rem;
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  color: var(--color-slate-500);
  border-bottom: 1px solid var(--color-slate-100);
}

.cp-display-list {
  list-style: none;
  margin: 0;
  padding: 0.25rem 0;
}

.cp-display-row {
  position: relative;
  display: flex;
  align-items: center;
  padding: 0;
  border-radius: 4px;
  cursor: grab;
}
.cp-display-row:hover { background: var(--color-slate-50); }
.cp-display-row--dragging { opacity: 0.5; }
.cp-display-row--drop-before::before,
.cp-display-row--drop-after::after {
  content: "";
  position: absolute;
  left: 0.5rem;
  right: 0.5rem;
  height: 2px;
  background: #2563eb;
  border-radius: 1px;
}
.cp-display-row--drop-before::before { top: -1px; }
.cp-display-row--drop-after::after  { bottom: -1px; }

.cp-display-grip {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 1.25rem;
  padding: 0.5rem 0 0.5rem 0.5rem;
  color: var(--color-slate-400);
}

.cp-display-link {
  flex: 1;
  display: flex;
  align-items: center;
  gap: 0.625rem;
  padding: 0.4375rem 0.875rem 0.4375rem 0.5rem;
  text-decoration: none;
  color: inherit;
  cursor: pointer;
}

.cp-display-checkbox {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 0.875rem;
  height: 0.875rem;
  border: 1.5px solid var(--color-slate-300);
  border-radius: 3px;
  background: #ffffff;
  flex-shrink: 0;
  transition: background 120ms, border-color 120ms;
}
.cp-display-checkbox--on {
  background: #2563eb;
  border-color: #2563eb;
}

.cp-display-label {
  flex: 1;
  font-size: 0.875rem;
  color: var(--color-slate-900);
}
.cp-display-row--hidden .cp-display-label {
  color: var(--color-slate-500);
}

.cp-display-type {
  font-size: 0.75rem;
  color: var(--color-slate-400);
  font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
}

/* =====================================================================
   Bounded viewport (working-list archetype) — see
   docs/PAGINATION_AND_SCROLL_STRATEGY.md.
   ===================================================================== */

.cp-viewport {
  display: flex;
  flex-direction: column;
  border: 1px solid var(--color-slate-200);
  border-radius: 6px;
  overflow: hidden;
  background: #ffffff;
  margin-top: 0.5rem;
}

.cp-viewport-content {
  overflow-y: auto;
  overflow-x: auto;
  /* height set inline by viewport_controller.js (loaded from
     localStorage; default ~65vh; clamped 240px–calc(100vh-200px)). */
}

.cp-viewport-loader {
  padding: 0.5rem 1rem;
  text-align: center;
  font-size: 0.8125rem;
  color: var(--color-slate-500);
  font-style: italic;
}

.cp-viewport-handle {
  position: relative;
  height: 8px;
  background: var(--color-slate-100);
  border-top: 1px solid var(--color-slate-200);
  border-bottom: 1px solid var(--color-slate-200);
  cursor: ns-resize;
  user-select: none;
  display: flex;
  align-items: center;
  justify-content: center;
}
.cp-viewport-handle:hover { background: var(--color-slate-200); }
.cp-viewport-grip {
  display: block;
  width: 32px;
  height: 3px;
  background: var(--color-slate-300);
  border-radius: 1.5px;
  position: relative;
}
.cp-viewport-grip::before,
.cp-viewport-grip::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  height: 1px;
  background: var(--color-slate-300);
}
.cp-viewport-grip::before { top: -3px; }
.cp-viewport-grip::after  { bottom: -3px; }

.cp-viewport-footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.5rem 1rem;
  background: var(--color-slate-50);
  font-size: 0.8125rem;
  color: var(--color-slate-600);
}

.cp-position-indicator strong {
  color: var(--color-slate-900);
  font-weight: 600;
}

.cp-viewport-landmarks {
  display: flex;
  align-items: center;
  gap: 0.375rem;
}

.cp-landmark-btn {
  padding: 0.25rem 0.625rem;
  background: transparent;
  border: 1px solid var(--color-slate-300);
  border-radius: 4px;
  color: var(--color-slate-700);
  font-size: 0.75rem;
  font-weight: 500;
  cursor: pointer;
  transition: background 120ms, border-color 120ms;
}
.cp-landmark-btn:hover {
  background: #ffffff;
  border-color: var(--color-slate-400);
}
.cp-landmark-btn[hidden] { display: none; }

/* Jump-to-row form: small number input + Jump button inline with the
   other footer landmarks (↑ Top, Collapse all). Renders only when the
   total record count crosses a threshold (see _index_page.html.erb). */
.cp-landmark-jumpto {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  margin-right: 0.25rem;
}
.cp-landmark-jumpto-input {
  width: 4.5rem;
  padding: 0.25rem 0.5rem;
  border: 1px solid var(--color-slate-300);
  border-radius: 4px;
  font-size: 0.75rem;
  font-family: inherit;
  background: #ffffff;
  color: var(--color-slate-900);
}
.cp-landmark-jumpto-input::-webkit-inner-spin-button,
.cp-landmark-jumpto-input::-webkit-outer-spin-button {
  opacity: 0.5;
}

/* =====================================================================
   Type-to-search FK filter picker (in the + filter popover).
   See entry d0b2547a (May 8, 2026) for the spec.
   ===================================================================== */

.cp-pop-search {
  position: relative;
  margin-bottom: 0.5rem;
}

.cp-pop-search-input {
  width: 100%;
  padding: 0.375rem 0.5rem;
  background: #ffffff;
  border: 1px solid var(--color-slate-300);
  border-radius: 4px;
  font-size: 0.8125rem;
  color: var(--color-slate-900);
  outline: none;
  transition: border-color 120ms;
}
.cp-pop-search-input:focus {
  border-color: #2563eb;
}

.cp-pop-search-results {
  list-style: none;
  margin: 0.25rem 0 0;
  padding: 0.25rem 0;
  background: #ffffff;
  border: 1px solid var(--color-slate-200);
  border-radius: 4px;
  box-shadow: 0 4px 12px -2px rgba(0, 0, 0, 0.08);
  max-height: 14rem;
  overflow-y: auto;
}
.cp-pop-search-results[hidden] { display: none; }

.cp-pop-search-results li { padding: 0; }
.cp-pop-search-results li a {
  display: block;
  padding: 0.375rem 0.625rem;
  color: var(--color-slate-900);
  font-size: 0.8125rem;
  text-decoration: none;
}
.cp-pop-search-results li a:hover,
.cp-pop-search-active a {
  background: #eff6ff;
  color: #1d4ed8;
}

.cp-pop-search-empty {
  padding: 0.375rem 0.625rem;
  color: var(--color-slate-400);
  font-size: 0.8125rem;
  font-style: italic;
}


/* =====================================================================
   Find bar — visual spec: find-bar-states.html (state gallery).
   ===================================================================== */

.cp-findbar {
  width: 380px;
  font-size: 13px;
  color: var(--color-slate-900);
  padding: 12px;
}

/* Row: holds either (icon + input) or (header text), plus modifier */
.cp-findbar-row {
  display: flex;
  align-items: stretch;
  border: 1px solid var(--color-slate-200);
  border-radius: 6px;
  background: #ffffff;
  overflow: hidden;
  height: 36px;
}
.cp-findbar-row:focus-within {
  border-color: #1d4ed8;
  box-shadow: 0 0 0 3px #e6edfb;
}

/* Magnifier icon (input mode only) */
.cp-findbar-icon {
  display: flex;
  align-items: center;
  padding: 0 0 0 10px;
  color: var(--color-slate-400);
  flex-shrink: 0;
}
.cp-findbar-icon[hidden] { display: none; }

/* Find input (input mode only) */
.cp-findbar-input {
  flex: 1;
  border: 0;
  padding: 0 8px;
  font-family: inherit;
  font-size: 14px;
  color: var(--color-slate-900);
  background: transparent;
  outline: none;
  min-width: 0;
}
.cp-findbar-input[hidden] { display: none; }
.cp-findbar-input::placeholder { color: var(--color-slate-400); }

/* Header text (header mode only). white-space: nowrap so longer verb
 * strings can't wrap the 36px row into multiple lines — the field
 * name lives in the modifier dropdown to the right, not here. */
.cp-findbar-header-text {
  flex: 1;
  display: flex;
  align-items: center;
  gap: 4px;
  padding: 0 12px;
  font-size: 13px;
  color: var(--color-slate-800);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.cp-findbar-header-text[hidden] { display: none; }

/* Modifier wrap — paper-2 background, vertical divider on the left */
.cp-findbar-modifier-wrap {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  gap: 4px;
  padding: 0 28px 0 10px;
  border-left: 1px solid var(--color-slate-200);
  background: var(--color-slate-50);
  position: relative;
  cursor: pointer;
}
.cp-findbar-modifier-wrap::after {
  content: "";
  position: absolute;
  right: 10px;
  top: 50%;
  width: 0;
  height: 0;
  border-left: 4px solid transparent;
  border-right: 4px solid transparent;
  border-top: 4px solid var(--color-slate-500);
  transform: translateY(-50%);
  pointer-events: none;
}
.cp-findbar-modifier-prefix {
  color: var(--color-slate-500);
  font-size: 11px;
}
.cp-findbar-modifier {
  appearance: none;
  -webkit-appearance: none;
  -moz-appearance: none;
  border: 0;
  background: transparent;
  font-family: inherit;
  font-size: 11px;
  color: #1d4ed8;
  font-weight: 500;
  cursor: pointer;
  padding: 0 4px 0 0;
  outline: none;
  /* Hide native arrow */
  background-image: none;
}
.cp-findbar-modifier::-ms-expand { display: none; }

/* Body container */
.cp-findbar-body { /* immediate children handle their own spacing */ }
.cp-findbar-slot[hidden] { display: none; }

/* Hint (free-text and All fields, after the operator types) */
.cp-findbar-hint {
  margin-top: 8px;
  font-size: 11px;
  color: var(--color-slate-500);
  font-style: italic;
}
.cp-findbar-hint strong {
  color: var(--color-slate-800);
  font-weight: 500;
  font-style: normal;
}

/* Long-fk: typeahead + fallback rows */
.cp-findbar-results {
  margin-top: 8px;
  border-top: 1px solid var(--color-slate-100);
  padding-top: 6px;
}
.cp-findbar-results[hidden] { display: none; }

.cp-findbar-typeahead {
  list-style: none;
  margin: 0;
  padding: 0;
  max-height: 220px;
  overflow-y: auto;
}
.cp-findbar-typeahead li { padding: 0; }
.cp-findbar-ta-row {
  display: flex;
  align-items: baseline;
  gap: 6px;
  padding: 6px;
  border-radius: 4px;
  font-size: 13px;
  color: var(--color-slate-900);
  text-decoration: none;
}
.cp-findbar-ta-row:hover { background: var(--color-slate-50); }

.cp-findbar-no-matches {
  padding: 8px 0;
  color: var(--color-slate-400);
  font-style: italic;
  font-size: 11px;
}

.cp-findbar-fallback-divider {
  margin: 6px 0 4px;
  border-top: 1px dashed var(--color-slate-200);
}
.cp-findbar-fallback {
  display: block;
  padding: 8px;
  background: var(--color-slate-50);
  border: 1px dashed var(--color-slate-200);
  border-radius: 4px;
  font-size: 12px;
  color: var(--color-slate-800);
  text-decoration: none;
  margin-top: 4px;
}
.cp-findbar-fallback:hover {
  background: #e6edfb;
  border-color: #1d4ed8;
  color: #1d4ed8;
}

/* Short-enum chip-cloud */
.cp-findbar-cloud {
  margin-top: 10px;
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}
.cp-findbar-pill {
  padding: 5px 12px;
  border: 1px solid var(--color-slate-200);
  border-radius: 100px;
  font-size: 12px;
  background: #ffffff;
  color: var(--color-slate-800);
  cursor: pointer;
  font-family: inherit;
  transition: background 100ms, border-color 100ms, color 100ms;
}
.cp-findbar-pill:hover { background: var(--color-slate-50); }
.cp-findbar-pill--on {
  background: #1d4ed8;
  border-color: #1d4ed8;
  color: #ffffff;
  font-weight: 500;
}

/* Boolean buttons */
.cp-findbar-bool-row {
  display: flex;
  gap: 8px;
  margin-top: 10px;
}
.cp-findbar-bool {
  flex: 1;
  text-align: center;
  padding: 10px;
  border: 1px solid var(--color-slate-200);
  border-radius: 5px;
  background: #ffffff;
  color: var(--color-slate-800);
  font-size: 13px;
  cursor: pointer;
  font-family: inherit;
}
.cp-findbar-bool:hover,
.cp-findbar-bool--on {
  background: #e6edfb;
  border-color: #1d4ed8;
  color: #1d4ed8;
  font-weight: 500;
}

/* Date presets */
.cp-findbar-preset-list {
  margin-top: 10px;
  display: flex;
  flex-direction: column;
  gap: 1px;
  /* The canonical date list is ~40 entries; let the popup scroll its
     preset list independently so it doesn't tower over the page. Matches
     the panel-top `.cp-pop` cap. */
  max-height: 50vh;
  overflow-y: auto;
}
.cp-findbar-preset {
  padding: 7px 10px;
  border-radius: 4px;
  font-size: 13px;
  color: var(--color-slate-900);
  text-decoration: none;
}
.cp-findbar-preset:hover { background: var(--color-slate-50); }
.cp-findbar-preset--on {
  background: #e6edfb;
  color: #1d4ed8;
  font-weight: 500;
}
.cp-findbar-preset--custom {
  color: #1d4ed8;
  border-top: 1px dashed var(--color-slate-200);
  margin-top: 4px;
  padding-top: 9px;
}

/* Range form (date custom + numeric) */
.cp-findbar-range-form {
  margin-top: 10px;
  display: flex;
  align-items: end;
  gap: 8px;
}
.cp-findbar-range-col { flex: 1; }
.cp-findbar-range-col label {
  display: block;
  font-size: 10px;
  color: var(--color-slate-500);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  font-weight: 600;
  margin-bottom: 4px;
}
.cp-findbar-range-col input {
  width: 100%;
  padding: 6px 8px;
  border: 1px solid var(--color-slate-200);
  border-radius: 4px;
  font-size: 13px;
  color: var(--color-slate-900);
  outline: none;
  font-family: inherit;
}
.cp-findbar-range-col input:focus {
  border-color: #1d4ed8;
  box-shadow: 0 0 0 2px #e6edfb;
}
.cp-findbar-range-arrow {
  padding-bottom: 8px;
  color: var(--color-slate-400);
}

/* Action row at the bottom of the popover */
.cp-findbar-actions {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  margin-top: 10px;
}
.cp-findbar-actions--with-back {
  justify-content: space-between;
}
.cp-findbar-back {
  background: none;
  border: none;
  color: var(--color-slate-500);
  font-size: 11px;
  padding: 0;
  font-family: inherit;
  cursor: pointer;
  text-decoration: none;
}
.cp-findbar-back:hover { color: #1d4ed8; }
.cp-findbar-apply {
  padding: 6px 14px;
  background: #1d4ed8;
  color: #ffffff;
  border: 0;
  border-radius: 4px;
  font-size: 12px;
  font-weight: 500;
  cursor: pointer;
  font-family: inherit;
  margin-left: auto;
}
.cp-findbar-apply:hover { background: #1e40af; }
.cp-findbar-apply:disabled {
  background: var(--color-slate-100);
  color: var(--color-slate-400);
  cursor: not-allowed;
}

/* ============================================================
   v2 Index archetype chrome — `cpv1-` namespace.
   Mapped from new-design-system/design-system/archetypes/
   index-page/reference.html. All AM indexes flow through one
   shared partial (`shared/_index_page.html.erb`) that emits the
   classes below. The legacy `.campaign-*` / `.cp-*` classes
   above are kept harmless during the rollout and will be culled
   in a cleanup pass once all 6 AM indexes have flipped over.
   ============================================================ */

/* === Page head (title row + saved-views tab row) ============ */
.cpv1-page-head {
  background: white;
  border: 1px solid var(--color-slate-200);
  border-radius: 4px;
  overflow: hidden;
}
.cpv1-page-title-row {
  display: flex; align-items: center; justify-content: space-between;
  padding: 14px 18px;
  border-bottom: 1px solid var(--color-slate-200);
  gap: 12px;
}
.cpv1-page-title { font-size: 18px; font-weight: 600; letter-spacing: -0.01em; margin: 0; color: var(--color-slate-900); }
.cpv1-page-title-actions { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.cpv1-btn-primary {
  padding: 6px 13px;
  background: var(--color-slate-900); color: #fff;
  border: 1px solid var(--color-slate-900); border-radius: 4px;
  font: inherit; font-size: 12.5px; font-weight: 500; cursor: pointer;
  text-decoration: none;
  display: inline-flex; align-items: center; gap: 5px;
}
.cpv1-btn-primary:hover { background: #1e293b; text-decoration: none; color: #fff; }
.cpv1-body a.cpv1-btn-primary, .cpv1-body a.cpv1-btn-primary:hover { color: #fff; text-decoration: none; }
/* disabled: the design system's button (components/button: opacity .5, no hover, not-allowed) */
.cpv1-btn-primary:disabled, .cpv1-btn-primary[aria-disabled="true"] { opacity: .5; cursor: not-allowed; }
.cpv1-btn-primary:disabled:hover, .cpv1-btn-primary[aria-disabled="true"]:hover { background: var(--color-slate-900); }

/* === Saved Views tab row (sits inside .cpv1-page-head) ====== */
.cpv1-views-row {
  display: flex; align-items: stretch;
  padding: 0 18px;
  background: white;
  overflow-x: auto;
  scrollbar-width: thin;
}
.cpv1-tab {
  padding: 10px 13px;
  font-size: 13px; font-weight: 500;
  color: var(--color-slate-500);
  cursor: pointer;
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
  display: inline-flex; align-items: center; gap: 6px;
  white-space: nowrap;
  text-decoration: none;
  background: transparent;
}
.cpv1-tab:hover { color: var(--color-slate-900); text-decoration: none; }
.cpv1-tab--active {
  color: var(--color-slate-900);
  border-bottom-color: var(--color-slate-900);
}
/* Drift indicator — URL state has diverged from the active view. */
.cpv1-tab--dirty::after {
  content: "";
  width: 5px; height: 5px;
  border-radius: 50%;
  background: #b45309;
  display: inline-block;
  margin-left: 2px;
}
.cpv1-tab-label { display: inline-block; }
.cpv1-tab-meta {
  font-family: 'IBM Plex Mono', ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 10.5px;
  font-weight: 400;
  color: var(--color-slate-400);
}
.cpv1-tab--active .cpv1-tab-meta { color: var(--color-slate-500); }

/* Per-tab wrap so the edit pencil can sit adjacent to the tab link
 * inside the same baseline strip. When the wrap is active, the
 * underline spans BOTH the link and the edit button so the two read
 * as one tab. The pencil only renders when the operator can edit the
 * view (server-side gate via SavedView#editable_by?). */
.cpv1-tab-wrap {
  display: inline-flex; align-items: stretch; position: relative;
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
}
.cpv1-tab-wrap--active { border-bottom-color: var(--color-slate-900); }
/* When the wrap carries the active underline, the inner .cpv1-tab
 * doesn't double-paint it. The Mine tab (which has no wrap) still
 * uses .cpv1-tab--active for its own underline. */
.cpv1-tab-wrap--active .cpv1-tab--active {
  border-bottom-color: transparent;
  margin-bottom: 0;
}
.cpv1-tab-edit {
  display: inline-flex; align-items: center; justify-content: center;
  padding: 10px 8px;
  color: var(--color-slate-400);
  background: transparent; border: 0; cursor: pointer;
  font-family: inherit;
}
.cpv1-tab-edit:hover { color: var(--color-slate-900); }
.cpv1-tab-edit svg { display: block; }
.cpv1-tab-wrap--active .cpv1-tab-edit { color: var(--color-slate-700); }

/* The ⋯ overflow menu. Sized to its content; positioned with
 * `position: fixed` and explicit top/left set in JS at open time so
 * it can escape ancestor `overflow: hidden` clipping on .cpv1-page-head
 * and the horizontal scroll on .cpv1-views-row. Open via
 * .cpv1-tab-menu--open. */
.cpv1-tab-menu {
  display: none;
  position: fixed;
  min-width: 200px;
  padding: 4px 0;
  background: white;
  border: 1px solid var(--color-slate-200);
  border-radius: 4px;
  box-shadow: 0 4px 16px rgba(15, 23, 42, 0.08), 0 1px 3px rgba(15, 23, 42, 0.04);
  z-index: 1000;
}
.cpv1-tab-menu--open { display: block; }
.cpv1-tab-menu-item {
  display: block; width: 100%;
  padding: 7px 14px;
  font: inherit; font-size: 12.5px; color: var(--color-slate-900);
  background: transparent; border: 0; text-align: left;
  cursor: pointer;
}
.cpv1-tab-menu-item:hover { background: var(--color-slate-50); }
.cpv1-tab-menu-item--danger { color: #991b1b; }
.cpv1-tab-menu-item--danger:hover { background: #fef2f2; }
.cpv1-tab-menu-divider {
  height: 1px; margin: 4px 0;
  background: var(--color-slate-200);
}

/* Thin vertical hairline between built-in (admin-locked) views and
 * user-owned views. Per DS reference.html `.tab-separator { width: 1px;
 * background: var(--border); margin: 8px 8px; align-self: stretch }`. */
.cpv1-tab-separator {
  width: 1px;
  margin: 8px 8px;
  background: var(--color-slate-200);
  align-self: stretch;
}

/* Trailing "+ view" save-current-as-new affordance. Mono + faint so it
 * reads as a meta-action rather than a tab; clicking POSTs to
 * /saved_views and navigates to the new view. */
.cpv1-tab-add {
  padding: 10px 12px;
  font-size: 13px; color: var(--color-slate-400);
  cursor: pointer;
  font-family: 'IBM Plex Mono', ui-monospace, SFMono-Regular, Menlo, monospace;
  background: transparent; border: 0;
  margin-bottom: -1px;
}
.cpv1-tab-add:hover { color: var(--color-slate-900); }

/* Inline rename input — swaps in for the tab label while editing; same
 * baseline, same font, no chrome that competes with the tab itself. */
.cpv1-tab-rename-input {
  font: inherit; font-size: 13px; font-weight: 500;
  color: var(--color-slate-900);
  background: white;
  border: 1px solid var(--color-blue-700, #1d4ed8);
  border-radius: 3px;
  padding: 1px 6px;
  outline: none;
  min-width: 80px;
  max-width: 220px;
}

/* === Control-panel strip (sentence + WHERE row) =============
 * Per DS canon (reference.html L271-277): the strip is a separate card
 * from the page-head with margin-top: 10px and full 4px radius. NOT
 * flush-stacked. */
.cpv1-strip {
  background: white;
  border: 1px solid var(--color-slate-200);
  border-radius: 4px;
  margin-top: 10px;
}
.cpv1-strip-sentence {
  padding: 12px 16px;
  display: flex; align-items: center; justify-content: space-between;
  gap: 16px;
}
.cpv1-strip-sentence .cpv1-sentence-text {
  font-size: 14px; color: var(--color-slate-700); line-height: 1.85; flex: 1;
}
.cpv1-strip-sentence .cpv1-sentence-text b { color: var(--color-slate-900); font-weight: 600; }
.cpv1-strip-where {
  padding: 10px 16px;
  border-top: 1px solid var(--color-slate-200);
  display: flex; align-items: center; gap: 6px; flex-wrap: wrap;
}
.cpv1-where-label {
  font-family: 'IBM Plex Mono', ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 10.5px; text-transform: uppercase; letter-spacing: 0.08em;
  color: var(--color-slate-400); font-weight: 600; margin-right: 4px;
}
.cpv1-where-and {
  font-family: 'IBM Plex Mono', ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 10px; color: var(--color-slate-400);
  text-transform: uppercase; letter-spacing: 0.06em; margin: 0 2px;
}

/* === Strip-scoped chips (date / sort / group inside .cpv1-strip) === */
.cpv1-strip .cpv1-chip {
  display: inline-flex; align-items: center;
  padding: 2px 8px;
  background: white;
  border: 1px solid var(--color-slate-300);
  border-radius: 3px;
  font-size: 12.5px; font-weight: 500;
  color: var(--color-slate-900);
  cursor: pointer;
  text-decoration: none;
  white-space: nowrap;
  font: inherit; font-size: 12.5px; font-weight: 500;
}
.cpv1-strip .cpv1-chip:hover { background: var(--color-slate-50); }
.cpv1-strip .cpv1-chip--add  { border-style: dashed; color: var(--color-slate-500); background: transparent; }
.cpv1-strip .cpv1-chip--empty { color: var(--color-slate-500); font-style: italic; font-weight: 400; }
.cpv1-strip .cpv1-chev {
  font-family: 'IBM Plex Mono', ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 9px; color: var(--color-slate-400); margin-left: 3px;
}
.cpv1-strip .cpv1-chip-pair { display: inline-flex; align-items: stretch; }
.cpv1-strip .cpv1-chip-pair .cpv1-chip-label {
  padding: 2px 8px 2px 7px;
  background: white;
  border: 1px solid var(--color-slate-300);
  border-right: 1px solid var(--color-slate-200);
  border-radius: 3px 0 0 3px;
  font: inherit; font-size: 12.5px; font-weight: 500; color: var(--color-slate-900);
  cursor: pointer;
}
.cpv1-strip .cpv1-chip-pair .cpv1-chip-label:hover { background: var(--color-slate-50); }
.cpv1-strip .cpv1-chip-pair .cpv1-chip-arrow {
  padding: 2px 7px;
  background: white;
  border: 1px solid var(--color-slate-300); border-left: none;
  border-radius: 0 3px 3px 0;
  font-family: 'IBM Plex Mono', ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 12.5px; font-weight: 600; color: var(--color-slate-900);
  cursor: pointer;
  text-decoration: none;
}
.cpv1-strip .cpv1-chip-pair .cpv1-chip-arrow:hover { background: var(--color-slate-50); }
/* The connecting words ("with", "grouped by", "sorted by", ".") in the sentence */
.cpv1-strip .cpv1-word { color: var(--color-slate-500); font-size: 14px; }
.cpv1-strip .cpv1-count { font-weight: 600; color: var(--color-slate-900); margin: 0 2px; }
.cpv1-strip .cpv1-count-noun { color: var(--color-slate-900); font-weight: 600; font-size: 14px; }
.cpv1-strip .cpv1-sentence-text b { color: var(--color-slate-900); font-weight: 600; }
.cpv1-strip .cpv1-memberships { color: var(--color-slate-400); font-size: 12px; margin-left: 2px; }
.cpv1-strip .cpv1-chip-wrap { position: relative; display: inline-block; }
.cpv1-strip-actions {
  display: flex; align-items: center; gap: 12px;
  padding: 8px 16px;
  border-top: 1px solid var(--color-slate-200);
  background: var(--color-slate-50);
}
.cpv1-strip-actions a {
  font-size: 12px; color: var(--color-blue-700, #1d4ed8); text-decoration: none;
}
.cpv1-strip-actions a:hover { text-decoration: underline; }
.cpv1-strip-action-link--clear { color: var(--color-slate-500); }

/* === Filter chip (three-part, per DS reference) ============= */
.cpv1-filter-chip {
  display: inline-flex; align-items: stretch;
  border: 1px solid var(--color-slate-300);
  border-radius: 3px;
  background: white;
  font-size: 12px;
  cursor: pointer;
}
/* Segment styling (scope | op | value), per the DS index-page
   reference (.filter-chip > span). Segments live INSIDE the clickable
   .cpv1-filter-chip-edit wrapper (button/anchor/span depending on the
   chip kind) so the whole triple is one edit target — the wrapper's
   children get the segment treatment and the wrapper itself stays a
   zero-padding flex shell. */
.cpv1-filter-chip > span:not(.cpv1-filter-chip-edit),
.cpv1-filter-chip > a,
.cpv1-filter-chip-edit > span {
  padding: 2px 8px;
  display: inline-flex; align-items: center;
  border-right: 1px solid var(--color-slate-200);
  color: var(--color-slate-900);
  text-decoration: none;
}
.cpv1-filter-chip > span:not(.cpv1-filter-chip-edit):last-child,
.cpv1-filter-chip > a:last-child { border-right: none; }
.cpv1-filter-chip-edit {
  display: inline-flex; align-items: stretch;
  cursor: pointer;
  color: inherit;
  background: transparent;
  border: none;
  padding: 0;
  font: inherit;
}
.cpv1-filter-chip-edit:hover { background: var(--color-slate-50); }
.cpv1-filter-chip-scope { font-weight: 500; }
.cpv1-filter-chip-op {
  font-family: 'IBM Plex Mono', ui-monospace, SFMono-Regular, Menlo, monospace;
  color: var(--color-slate-500);
}
.cpv1-filter-chip-value { font-weight: 500; }
.cpv1-filter-chip-x {
  padding: 0 7px;
  color: var(--color-slate-400);
  cursor: pointer;
  text-decoration: none;
  display: inline-flex; align-items: center;
  /* No border-left — the value segment's border-right is the divider
     before the ×, per the DS reference (both at once doubles it). */
}
.cpv1-filter-chip-x:hover { background: #fef2f2; color: #991b1b; }

/* === Utility button (Columns) =============================== */
.cpv1-util-btn {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 5px 10px;
  background: white;
  border: 1px solid var(--color-slate-300); border-radius: 4px;
  font: inherit; font-size: 12.5px; color: var(--color-slate-900); cursor: pointer;
}
.cpv1-util-btn:hover { background: var(--color-slate-50); }
.cpv1-util-btn svg { width: 13px; height: 13px; }
.cpv1-util-btn .cpv1-util-btn-count {
  font-family: 'IBM Plex Mono', ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 10.5px; color: var(--color-slate-400); margin-left: 2px;
}

/* === Index area — Stimulus controller scope host ============
 * The .cpv1-index-area div wraps .cpv1-tbl-wrap and .cpv1-landmark so
 * both sit inside the viewport-controller's scope (without it the
 * landmark's `indicator`, `collapseBtn`, and `topBtn` targets fall
 * outside and Stimulus actions silently no-op). `display: contents`
 * removes the wrapper from the box tree so its children participate
 * in the parent's layout as before. */
.cpv1-index-area { display: contents; }

/* === Multi-select (Index archetype opt-in) ==================
 * A 34px checkbox column and, while something is selected, the selection
 * strip over the table's header row. */
.cpv1-tbl .cpv1-col-check, .cpv1-tbl col.cpv1-col-check { width: 34px; min-width: 34px; max-width: 34px; padding: 0 8px; text-align: center; }
/* The checkbox, drawn by the app like its radio (Avo's base sheet would paint
   it in its own blue): 14px, slate-400 border, slate-900 with a white mark when
   checked, a white dash when half-checked. The mark is a background image so
   no other sheet's ::after rules can move it. */
.cpv1-check { appearance: none; -webkit-appearance: none; width: 14px; height: 14px; margin: 0; vertical-align: middle; border: 1px solid var(--color-slate-400); border-radius: var(--r-input); background: var(--surface, #fff); background-image: none; color: var(--color-slate-900); cursor: pointer; flex: none; }
.cpv1-check:hover:not(:disabled) { border-color: var(--color-slate-900); }
.cpv1-check:checked, .cpv1-check:checked:hover, .cpv1-check:checked:focus,
.cpv1-check:indeterminate, .cpv1-check:indeterminate:hover, .cpv1-check:indeterminate:focus { border-color: var(--color-slate-900); background-color: var(--color-slate-900); background-size: 10px 10px; background-position: center; background-repeat: no-repeat; }
.cpv1-check:checked, .cpv1-check:checked:hover, .cpv1-check:checked:focus { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='white' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3.5 8.5l3 3 6-7'/%3E%3C/svg%3E"); }
.cpv1-check:indeterminate, .cpv1-check:indeterminate:hover, .cpv1-check:indeterminate:focus { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='white' stroke-width='2.4' stroke-linecap='round'%3E%3Cpath d='M4 8h8'/%3E%3C/svg%3E"); }
.cpv1-check:focus-visible { outline: 2px solid var(--color-blue-700); outline-offset: 2px; }
.cpv1-check:disabled { border-color: var(--color-slate-200); background: var(--surface-2, var(--color-slate-100)); cursor: default; }
/* The radio, drawn by the app like its checkbox: 14px, slate-900 when chosen. */
.cpv1-radio { appearance: none; -webkit-appearance: none; width: 14px; height: 14px; margin: 0; border: 1px solid var(--color-slate-400); border-radius: 50%; background: var(--surface, #fff); color: var(--color-slate-900); flex: none; cursor: pointer; position: relative; }
.cpv1-radio:hover:not(:disabled) { border-color: var(--color-slate-900); }
/* Avo's base sheet paints a checked radio in its own blue while hovered or focused
   (input:where([type=radio]):checked:hover / :focus); these outrank it. */
.cpv1-radio:checked, .cpv1-radio:checked:hover, .cpv1-radio:checked:focus { border-color: var(--color-slate-900); background-color: var(--color-slate-900); background-image: none; }
/* The dot: centred by inset + auto margins, with transform pinned, so no
   other sheet's ::after transform can shift it. */
.cpv1-radio:checked::after { content: ""; position: absolute; inset: 0; margin: auto; width: 5px; height: 5px; border-radius: 50%; background: #fff; transform: none; }
.cpv1-radio:focus-visible { outline: 2px solid var(--color-blue-700); outline-offset: 2px; }
.cpv1-radio:disabled { border-color: var(--color-slate-200); background: var(--surface-2, var(--color-slate-100)); cursor: default; }
.cpv1-visually-hidden { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
/* Selection strip: while something is selected it lies over the table's
   own header row (to the right of the header checkbox), carrying the
   selection in words, the Actions menu (the record's own state menu,
   reused) and Clear. Nothing is reserved for it at rest. The controller
   sets its top, height and right edge from the header it covers. */
.cpv1-tbl-wrap { position: relative; }
.cpv1-select-controls {
  position: absolute; top: 0; left: 34px; right: 16px; z-index: 3;
  display: flex; align-items: center; gap: 14px;
  padding: 0 12px 0 8px;
  background: var(--color-slate-100); border-bottom: 1px solid var(--color-slate-200);
  font-size: 13px; color: var(--fg); white-space: nowrap; overflow: visible;
}
.cpv1-select-controls[hidden] { display: none; }
.cpv1-select-actions { position: relative; }
.cpv1-select-actions-btn {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 3px 9px; font: inherit; font-size: 12px; font-weight: 600;
  color: var(--fg); background: var(--surface, #fff);
  border: 1px solid var(--border, var(--color-slate-200)); border-radius: var(--r-pill);
  cursor: pointer;
}
.cpv1-select-actions-btn:hover { background: var(--color-slate-50); }
/* The wrap clips its overflow, so the dropdown floats fixed at the
   trigger (placed by the controller) and closes when the box scrolls. */
.cpv1-select-actions .cpv1-state-menu { position: fixed; right: auto; min-width: 180px; }
.cpv1-select-matching { color: var(--color-blue-700); text-decoration: none; }
.cpv1-select-matching:hover { text-decoration: underline; }
.cpv1-select-message { color: var(--fg); }
.cpv1-col-check { user-select: none; }

/* The row's date, where a campaign's dates are changed from the list. */
.cpv1-index-date { background: none; border: 0; padding: 2px 6px; margin: -2px -6px; font: inherit; color: inherit; border-radius: var(--r-pill); cursor: pointer; white-space: nowrap; }
.cpv1-index-date:hover { background: var(--color-slate-100); box-shadow: inset 0 0 0 1px var(--color-slate-300); }
/* The list's one popover for that form: fixed at the clicked cell. */
.cpv1-index-popover { position: fixed; z-index: 60; width: 340px; background: var(--surface, #fff); border: 1px solid var(--border, var(--color-slate-200)); border-radius: var(--r-card, 8px); box-shadow: 0 8px 24px rgba(0, 0, 0, .10); padding: 10px 14px 12px; display: block; }
.cpv1-index-popover[hidden] { display: none; }
/* The bulk-form modal: an Actions item that asks first. */
/* The change-dates forms: the row popover and, in the design system's modal
   (shared/_confirm_modal's .modal-backdrop / .modal / .btn), the bulk form. */
.cpv1-cdf { font-size: 13px; color: var(--fg); }
.cpv1-cdf-title { font-size: 14px; font-weight: 600; margin: 0 0 6px; }
.cpv1-cdf-label { font-size: 10.5px; letter-spacing: .06em; text-transform: uppercase; font-family: var(--font-mono); color: var(--fg-muted); margin: 12px 0 6px; font-weight: 600; }
.cpv1-cdf-opt { display: flex; align-items: flex-start; gap: 8px; font-size: 13px; padding: 4px 0; cursor: pointer; }
.cpv1-cdf-opt .cpv1-radio { margin-top: 2px; }
.cpv1-cdf-opt input:disabled + span { color: var(--fg-faint); }
.cpv1-cdf-opt:hover .cpv1-radio:not(:disabled) { border-color: var(--color-slate-900); }
.cpv1-cdf-inline { display: inline-flex; align-items: center; gap: 6px; }
.cpv1-cdf-num { width: 52px; padding: 3px 6px; font: inherit; font-size: 13px; border: 1px solid var(--color-slate-300); border-radius: var(--r-input); text-align: center; }
/* The readout of what the change leaves untouched: a count, then the reason. */
.cpv1-cdf-fact { font-size: 12.5px; color: var(--fg); line-height: 1.5; }
.cpv1-cdf-fact span { color: var(--fg-muted); }
.cpv1-cdf-error { font-size: 12.5px; color: var(--fg); margin: 8px 0 0; }
.cpv1-cdf-actions { display: flex; justify-content: flex-end; gap: 8px; margin-top: 14px; }
.cpv1-cdf .btn:disabled { opacity: .45; cursor: default; }
.is-all-matching .cpv1-check { cursor: default; }
.cpv1-select-count { font-size: 13px; color: var(--fg); }
.cpv1-select-clear { color: var(--color-blue-700); text-decoration: none; }
.cpv1-select-clear:hover { text-decoration: underline; }
/* Full screen (fullscreen_controller): the page body fills the screen on
 * its own; give it the page's ground and let it scroll. */
.cpv1-body:fullscreen, .cpv1-index-host:fullscreen { background: var(--color-slate-50, #f8fafc); overflow: auto; padding: 8px 24px 24px; }
/* The index body's own host (shared/_index_page_body): nothing at rest, a
   block when it is the fullscreen element. */
.cpv1-index-host { display: contents; }
.cpv1-index-host:fullscreen { display: block; }

/* === Table wrap + table chrome (per DS Table component) =====
 * Per DS canon (reference.html L365-371): tbl-wrap renders as an
 * open-topped continuation — `border-top: none; border-radius: 0;
 * margin-top: 10px`. The landmark caps the bottom (border-top: none,
 * rounded bottom). The table's slate-100 thead background visually
 * starts the card at top; the missing top border is intentional. */
.cpv1-tbl-wrap {
  background: white;
  border: 1px solid var(--color-slate-200);
  border-top: none;
  border-radius: 0;
  margin-top: 10px;
  overflow: hidden;
}
.cpv1-tbl-viewport {
  max-height: 480px;
  overflow-y: auto;
  /* Reserve scrollbar gutter even when no scrollbar is present, so the
   * inner table content width is identical whether or not the table is
   * scrollable. Without this, scrolled states are ~15px narrower than
   * non-scrolled and the columns reflow when filters change. */
  scrollbar-gutter: stable;
  border-bottom: 1px solid var(--color-slate-200);
}
.cpv1-tbl {
  width: 100%;
  border-collapse: collapse;
  font-size: 13px;
  margin: 0;
  /* Fixed layout so column widths follow .cpv1-col-* modifier classes
   * rather than browser content-driven auto layout. Density across pages
   * requires predictable column widths — see
   * docs/handoff/audience-marketing/_shared/INDEX-COLUMN-INVENTORY.md. */
  table-layout: fixed;
}
/* Base data-cell density — single-line data rows, ellipsis on
 * overflow. Headers (`th`) are NOT subject to this rule: a truncated
 * header means the operator can't tell what column they're reading.
 * Header labels wrap naturally so they stay fully visible at any
 * column width. The existing title="..." attribute on Name/Label
 * cells (set via cell_attrs:) keeps full data values discoverable on
 * hover. */
.cpv1-tbl td {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* === Per-type column widths (cpv1-col-*) ====================
 * Applied via control_panel_config[:columns][:css]. Each type has
 * one canonical width applied everywhere it appears so the same
 * data-class is the same size across all 5 AM indexes. */
.cpv1-tbl .cpv1-col-date         { width: 100px; }
.cpv1-tbl .cpv1-col-datetime     { width: 130px; }
.cpv1-tbl .cpv1-col-email        { width: 110px; }
.cpv1-tbl .cpv1-col-count        { width: 70px;  text-align: right; font-variant-numeric: tabular-nums; }
.cpv1-tbl .cpv1-col-count--wide  { width: 90px;  text-align: right; font-variant-numeric: tabular-nums; }
.cpv1-tbl .cpv1-col-badge-narrow { width: 95px; }
.cpv1-tbl .cpv1-col-badge-wide   { width: 130px; }
.cpv1-tbl .cpv1-col-enum-short   { width: 80px; }
.cpv1-tbl .cpv1-col-enum-med     { width: 100px; }
.cpv1-tbl .cpv1-col-yesno        { width: 60px; }
.cpv1-tbl .cpv1-col-fk-short     { width: 130px; }
.cpv1-tbl .cpv1-col-fk-med       { width: 180px; }
.cpv1-tbl .cpv1-col-fk-long      { width: 240px; }
.cpv1-tbl .cpv1-col-address      { width: 200px; }
.cpv1-tbl .cpv1-col-url          { width: 140px; }
.cpv1-tbl .cpv1-col-text         { width: 200px; }
/* Primary Name/Label column — flex; takes remaining space. No explicit
 * width so table-layout: fixed shares slack proportionally; min-width
 * keeps a floor so even at narrow viewports the name stays usable. */
.cpv1-tbl .cpv1-col-name         { width: auto; min-width: 200px; }
.cpv1-tbl .cpv1-col-name--narrow { width: auto; min-width: 100px; } /* for the "Send #N" leftmost on Sends */
.cpv1-tbl thead { position: sticky; top: 0; z-index: 2; }
.cpv1-tbl th {
  text-align: left; padding: 8px 12px;
  font-weight: 600; color: var(--color-slate-500);
  font-size: 10.5px; text-transform: uppercase; letter-spacing: 0.04em;
  font-family: 'IBM Plex Mono', ui-monospace, SFMono-Regular, Menlo, monospace;
  background: var(--color-slate-100);
  border-bottom: 1px solid var(--color-slate-200);
}
.cpv1-tbl td {
  padding: 8px 12px;
  border-bottom: 1px solid #eef2f6;
  color: var(--color-slate-900);
  vertical-align: top;
}
.cpv1-tbl tr.cpv1-data-row { cursor: default; }
.cpv1-tbl tr.cpv1-data-row:hover td { background: #f8fafc; }

.cpv1-tbl tr.cpv1-group-band td {
  background: var(--color-slate-100);
  padding: 7px 12px;
  font-family: 'IBM Plex Mono', ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 11px;
  text-transform: uppercase; letter-spacing: 0.04em;
  color: var(--color-slate-500); font-weight: 600;
  cursor: pointer; user-select: none;
  position: sticky; top: 31px; z-index: 1;
}
.cpv1-tbl tr.cpv1-group-band td:hover { background: var(--color-slate-200); }
.cpv1-tbl tr.cpv1-group-band .cpv1-group-band-chev {
  display: inline-block; width: 12px; text-align: center;
  margin-right: 6px; color: var(--color-slate-400);
  transition: transform 0.15s;
}
.cpv1-tbl tr.cpv1-group-band.is-collapsed .cpv1-group-band-chev { transform: rotate(-90deg); }
.cpv1-tbl tr.cpv1-group-band .cpv1-group-band-name { color: var(--color-slate-900); }
.cpv1-tbl tr.cpv1-group-band .cpv1-group-band-meta { color: var(--color-slate-400); font-weight: 400; margin-left: 8px; }

/* Subtle muted helper text for cells. Slate-400 alone carries the
 * de-emphasis — no italics; plain-text fields should look like every
 * other plain-text field. */
.cpv1-cell-muted { color: var(--color-slate-400); }
.cpv1-cell-num { text-align: right; font-variant-numeric: tabular-nums; }
.cpv1-cell-link { color: var(--color-slate-900); text-decoration: none; font-weight: 500; }
.cpv1-cell-link:hover { text-decoration: underline; color: var(--color-slate-900); }

/* Status badges — multi-axis encoding (color + label) per
 * components/badge-chip. Mapped to the planning_state + vertical
 * + workflow_state enums in the AM module. */
/* Badge atom (components/badge-chip): Title Case, sans, tinted pair.
 * The markup carries the cased label; no transform. */
.cpv1-badge {
  display: inline-flex; align-items: center; padding: 1px 7px;
  border-radius: 3px;
  font-size: 11px; font-weight: 600;
  background: var(--color-slate-100); color: var(--color-slate-500);
  border: 1px solid var(--color-slate-200);
}
/* rule-invalidated SendingConfiguration (inactive_at set by the
   deactivate sweeper). Warning amber — operator should re-pick a
   different config wherever this is attached. */
.cpv1-badge--rule-invalid { background: #fef3c7; color: #92400e; border-color: #fde68a; margin-left: 6px; }
/* planning_state */
.cpv1-badge--planning-draft     { background: #fef3c7; color: #92400e; border-color: #fde68a; }
.cpv1-badge--planning-in_review { background: #eff6ff; color: #1d4ed8; border-color: #bfdbfe; }
.cpv1-badge--planning-in-review { background: #eff6ff; color: #1d4ed8; border-color: #bfdbfe; }
.cpv1-badge--planning-approved  { background: #f0fdf4; color: #166534; border-color: #a7f3d0; }
.cpv1-badge--planning-revising  { background: #fef2f2; color: #991b1b; border-color: #fecaca; }
.cpv1-badge--planning-archived  { background: var(--color-slate-100); color: var(--color-slate-400); border-color: var(--color-slate-200); }
/* vertical — neutral chips, just labels */
.cpv1-badge--vertical-people    { background: white; color: var(--color-slate-700); border-color: var(--color-slate-300); }
.cpv1-badge--vertical-marketing { background: white; color: var(--color-slate-700); border-color: var(--color-slate-300); }
/* workflow_state (Creative) — same palette as the Creative show page's
 * head menu (creative_page.css). Copied here unscoped so it applies in
 * the Creatives index table cells too. */
.cpv1-badge--workflow-placeholder    { background: white;   color: #57534e; border-color: #d6d3d1; }
.cpv1-badge--workflow-drafting_in_progress { background: #eff6ff; color: #1e40af; border-color: #bfdbfe; }
.cpv1-badge--workflow-drafted        { background: #eff6ff; color: #1e40af; border-color: #bfdbfe; }
.cpv1-badge--workflow-proofed        { background: #eff6ff; color: #1e40af; border-color: #93c5fd; }
.cpv1-badge--workflow-approved       { background: #dbeafe; color: #1e3a8a; border-color: #60a5fa; }
.cpv1-badge--workflow-second_proofed { background: #f0fdf4; color: #166534; border-color: #bbf7d0; }
.cpv1-badge--workflow-please_revise  { background: #fef2f2; color: #991b1b; border-color: #fecaca; }
/* sending_status (Send) — neutral for draft; blue for in-flight; green
 * for done; red for failed; muted for cancelled. */
.cpv1-badge--sending-draft     { background: var(--color-slate-100); color: var(--color-slate-500); border-color: var(--color-slate-200); }
.cpv1-badge--sending-scheduled { background: #eff6ff; color: #1d4ed8; border-color: #bfdbfe; }
.cpv1-badge--sending-sending   { background: #fef3c7; color: #92400e; border-color: #fde68a; }
.cpv1-badge--sending-sent      { background: #f0fdf4; color: #166534; border-color: #a7f3d0; }
.cpv1-badge--sending-failed    { background: #fef2f2; color: #991b1b; border-color: #fecaca; }
.cpv1-badge--sending-cancelled { background: var(--color-slate-100); color: var(--color-slate-400); border-color: var(--color-slate-200); }

/* === Landmark row (bottom of the table wrap) ================ */
.cpv1-landmark {
  background: white;
  border: 1px solid var(--color-slate-200);
  border-top: none;
  border-radius: 0 0 4px 4px;
  padding: 9px 16px;
  display: flex; align-items: center; justify-content: space-between;
  font-size: 12px;
  gap: 14px;
}
.cpv1-landmark-left {
  font-family: 'IBM Plex Mono', ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 11px;
  color: var(--color-slate-400);
  text-transform: uppercase; letter-spacing: 0.04em;
}
.cpv1-landmark-right { display: flex; align-items: center; gap: 14px; }
.cpv1-landmark-link {
  background: transparent; border: none; padding: 0;
  font: inherit; font-size: 12px;
  color: var(--color-blue-700, #1d4ed8); cursor: pointer;
  text-decoration: none;
}
.cpv1-landmark-link:hover { text-decoration: underline; }
/* Jump-to-row — canon doesn't specify a visual so this matches the
 * landmark's mono/faint vocabulary: the label is the same mono
 * uppercase as .cpv1-landmark-left, and the input is a quiet
 * monospaced field that reads as part of the same row, not a form. */
.cpv1-landmark-jumpto {
  display: inline-flex; align-items: baseline; gap: 6px;
  margin: 0;
}
.cpv1-landmark-jumpto-label {
  font-family: 'IBM Plex Mono', ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 11px;
  color: var(--color-slate-400);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  cursor: pointer;
}
.cpv1-landmark-jumpto-input {
  width: 70px; padding: 2px 6px;
  font-family: 'IBM Plex Mono', ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 12px;
  color: var(--color-slate-900);
  background: var(--color-slate-50);
  border: 1px solid var(--color-slate-200);
  border-radius: 3px;
  text-align: right;
}
.cpv1-landmark-jumpto-input::placeholder {
  color: var(--color-slate-400);
  font-style: normal;
}
.cpv1-landmark-jumpto-input:focus {
  outline: none;
  background: white;
  border-color: var(--color-blue-700, #1d4ed8);
}
/* Hide the number input's spinner controls — they look out of place
 * in the landmark's quiet mono row. Enter submits via the form. */
.cpv1-landmark-jumpto-input::-webkit-outer-spin-button,
.cpv1-landmark-jumpto-input::-webkit-inner-spin-button {
  -webkit-appearance: none; margin: 0;
}
.cpv1-landmark-jumpto-input { -moz-appearance: textfield; }

/* === Viewport handle (drag-to-resize) — moved into landmark */
.cpv1-viewport-handle {
  height: 4px; background: var(--color-slate-100);
  cursor: ns-resize;
  border-top: 1px solid var(--color-slate-200);
  display: flex; align-items: center; justify-content: center;
}
.cpv1-viewport-handle:hover { background: var(--color-slate-200); }
.cpv1-viewport-grip {
  width: 24px; height: 2px;
  background: var(--color-slate-300); border-radius: 1px;
}

/* === m2m xref row (canonical-home cross-reference) ========== */
.cpv1-tbl tr.cpv1-m2m-xref > td {
  padding: 4px 12px;
  font-size: 12px;
  color: var(--color-slate-500);
  background: white;
  border-bottom: 1px solid #eef2f6;
}
.cpv1-tbl tr.cpv1-m2m-xref > td.cpv1-m2m-xref-date {
  font-family: 'IBM Plex Mono', ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 11px;
  color: var(--color-slate-400);
  white-space: nowrap;
}
.cpv1-m2m-xref-name a {
  color: var(--color-slate-700);
  text-decoration: none;
}
.cpv1-m2m-xref-name a:hover { text-decoration: underline; }
.cpv1-m2m-xref-marker {
  color: var(--color-slate-400);
  margin-right: 4px;
}
.cpv1-m2m-xref-pointer {
  color: var(--color-slate-400);
  font-style: italic;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* === Empty state ============================================ */
.cpv1-empty-block {
  background: white;
  border: 1px solid var(--color-slate-200);
  border-top: none;
  border-radius: 0 0 4px 4px;
  display: flex; flex-direction: column;
  align-items: center; justify-content: center;
  text-align: center; padding: 80px 20px;
}
.cpv1-empty-title { font-size: 16px; font-weight: 600; color: var(--color-slate-900); margin-bottom: 8px; }
.cpv1-empty-body {
  font-size: 13px; color: var(--color-slate-500); line-height: 1.6;
  max-width: 380px; margin: 0 0 18px;
}
.cpv1-empty-action {
  padding: 6px 14px; background: var(--color-slate-900); color: #fff;
  border: 1px solid var(--color-slate-900); border-radius: 4px;
  font: inherit; font-size: 13px; font-weight: 500; cursor: pointer;
  text-decoration: none;
}
.cpv1-empty-action:hover { background: #1e293b; color: white; text-decoration: none; }
/* Rendered as a link inside .cpv1-body the action must still read white on
   slate: the body's link color (campaign_page.css) would otherwise win. */
.cpv1-body a.cpv1-empty-action { color: #fff; }
.cpv1-body a.cpv1-empty-action:hover { color: white; text-decoration: none; }
.cpv1-body a.cpv1-empty-action--ghost, .cpv1-body a.cpv1-empty-action--ghost:hover { color: var(--color-blue-700, #1d4ed8); }
.cpv1-empty-action--ghost {
  background: transparent; color: var(--color-blue-700, #1d4ed8);
  border: 1px solid var(--color-slate-300);
}
.cpv1-empty-action--ghost:hover { background: var(--color-slate-50); color: var(--color-blue-700, #1d4ed8); }


/* ------------------------------------------------------------------ */
/* Find-bar, scope-list variant (cfg[:filter_menu]; Speaker Booking     */
/* Events, per the Team Assignments handoff's "+ filter option set"):   */
/* the page's filters as options first; the bar and body show once a    */
/* scope is picked, with ← Back to the list.                            */
/* ------------------------------------------------------------------ */
.cp-findbar-menu .cp-opt { width: 100%; background: none; border: 0; text-align: left; }
.cp-findbar-menu .cp-opt:hover { background: var(--color-slate-50); }
.cp-findbar-modifier-wrap[hidden] { display: none; }
.cp-findbar-back--menu { padding: 0 12px; white-space: nowrap; }
.cp-findbar-header-scope { font-weight: 600; }
.cp-findbar-header-sep { color: var(--color-slate-400); margin: 0 2px; }
.cp-findbar--menu-open { padding: 0; }
.cp-findbar-menu { padding: 2px 0 4px; }
