/* SEF Studio: per-surface rules.
 *
 * Ordered by surface family:
 *   1. Auth (login, logged_out)
 *   2. Tenant picker
 *   3. Tenant dashboard
 *   4. Onboarding wizard (overview + step pages)
 *   5. URL importer (form, preview, status)
 *   6. Approval queue (batch_review, draft cards)
 *   7. Posts: generate hub + sub-tabs
 *   8. Briefs: proposal list / new / detail
 */

/* ============================================================ AUTH === */

.auth-page {
  min-height: 60vh;
  display: grid;
  place-items: start center;
  padding-block: clamp(2rem, 6vh, 5rem);
}
.auth-canvas {
  width: 100%;
  max-width: 460px;
  padding-inline: var(--gutter);
}
.auth-display {
  font-family: var(--font-serif);
  font-weight: 500;
  font-size: var(--type-display);
  line-height: 1.05;
  letter-spacing: -0.02em;
  margin: 0.4rem 0 1rem;
}
.auth-form {
  display: flex;
  flex-direction: column;
  gap: 1.4rem;
  margin-top: 1.75rem;
}
.auth-form .form-actions {
  display: flex;
  gap: 0.75rem;
  align-items: center;
  margin-top: 0.5rem;
}
.auth-foot {
  margin-top: 2rem;
  padding-top: 1.1rem;
  border-top: 1px solid var(--color-rule);
}

/* ================================================ TENANT PICKER ===== */

.tenant-list {
  list-style: none;
  padding: 0;
  margin: 1.75rem 0;
  display: grid;
  gap: 0.75rem;
}
@media (max-width: 600px) {
  /* Tighter vertical rhythm on mobile so the picker doesn't waste a
   * whole screen on the H1 + 'N available' before the first card. */
  .tenant-list { margin: 1rem 0; gap: 0.5rem; }
}
.tenant-list > li {
  background: var(--color-bg);
  border: 1px solid var(--color-rule);
  border-radius: 2px;
  transition: border-color var(--transition-fast);
}
.tenant-list > li:hover { border-color: var(--color-rule-strong); }
.tenant-list > li.muted {
  border-color: transparent;
  background: transparent;
  padding: 0.5rem 0;
}
.tenant-list a {
  display: grid;
  grid-template-columns: 1fr auto auto;
  align-items: center;
  gap: 0.4rem 1rem;
  padding: 1rem 1.25rem;
  min-height: 44px;
  color: var(--color-text);
  text-decoration: none;
}
.tenant-list a:hover { color: var(--color-text); }

/* Mobile: stack the row so the role pill (which can be wide — 'PLATFORM
 * OWNER via SEF' is ~22 chars) sits below the name + slug instead of
 * getting pushed off the right edge. The 3-column grid collapses to two
 * rows: name + slug on the first row, role pill on the second.
 *
 * The picker is the first thing tenants see after login, so this matters
 * a lot for first-impression quality on phones. */
@media (max-width: 600px) {
  .tenant-list a {
    grid-template-columns: 1fr;
    grid-template-areas:
      "name"
      "slug"
      "role";
    gap: 0.25rem;
    padding: 0.85rem 1rem;
  }
  .tenant-name { grid-area: name; }
  .tenant-slug { grid-area: slug; }
  .tenant-role { grid-area: role; justify-self: start; margin-top: 0.4rem; }
}
.tenant-name {
  font-family: var(--font-serif);
  font-size: 1.2rem;
  font-weight: 500;
  letter-spacing: -0.01em;
}
.tenant-slug {
  font-family: var(--font-mono);
  font-size: var(--type-small);
  color: var(--color-muted);
}
.tenant-role {
  font-family: var(--font-mono);
  font-size: var(--type-eyebrow);
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--color-oxblood);
  background: var(--color-bg-tint);
  padding: 0.25rem 0.6rem;
  border-radius: 2px;
  display: inline-flex;
  align-items: center;
  gap: 0.5em;
  white-space: nowrap;
}
/* SEF-side row: same pill but a subtle outline shift + 'via SEF'
 * marker so a Studio Manager browsing 30 tenants can quickly tell
 * which are their own memberships vs platform-side access. */
.tenant-role.tenant-role-sef {
  background: transparent;
  border: 1px solid var(--color-oxblood);
  padding: calc(0.25rem - 1px) calc(0.6rem - 1px);
}
.tenant-role-marker {
  font-size: 0.78em;
  letter-spacing: 0.08em;
  font-weight: 400;
  color: var(--color-muted);
  text-transform: none;
}

/* ================================================== DASHBOARD ======= */

.dashboard-header {
  margin-bottom: clamp(1.5rem, 3vh, 2.25rem);
}
.dashboard-header h1 {
  font-family: var(--font-serif);
  font-size: clamp(1.75rem, 3.4vw, 2.4rem);
  font-weight: 500;
  letter-spacing: -0.02em;
  line-height: 1.1;
  margin: 0 0 0.4rem;
}

/* Stat row (in queue / approved / posted / total). */
.stat-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 0.85rem;
  margin: 0 0 2rem;
}
.stat-card {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  padding: 1.1rem 1.2rem;
  background: var(--color-bg);
  border: 1px solid var(--color-rule);
  border-radius: 2px;
  text-decoration: none;
  color: var(--color-text);
  transition: border-color var(--transition-fast), background var(--transition-fast);
}
a.stat-card:hover {
  border-color: var(--color-rule-strong);
  background: var(--color-bg-tint);
}
.stat-label {
  font-family: var(--font-mono);
  font-size: var(--type-eyebrow);
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--color-muted);
}
.stat-value {
  font-family: var(--font-serif);
  font-size: 2.2rem;
  font-weight: 500;
  line-height: 1;
  letter-spacing: -0.02em;
  color: var(--color-text);
  margin: 0.2rem 0;
}
.stat-foot {
  font-family: var(--font-mono);
  font-size: var(--type-eyebrow);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--color-muted);
}

/* =============================================== HOME DASHBOARD ====== */

.home-next-post {
  background: var(--color-bg);
  border: 1px solid var(--color-rule);
  border-left: 3px solid var(--color-oxblood);
  border-radius: 2px;
  padding: var(--app-card-pad);
  margin-bottom: 1.25rem;
}
.home-next-post--empty {
  border-left-color: var(--color-rule-strong);
}
.home-next-post-label {
  font-family: var(--font-mono);
  font-size: var(--type-eyebrow);
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--color-oxblood);
  display: block;
  margin-bottom: 0.5rem;
}
.home-next-post-meta {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  margin-bottom: 0.5rem;
}
.home-next-post-body {
  margin: 0 0 0.75rem;
  line-height: 1.5;
  color: var(--color-text);
}

.stat-card--attention {
  border-color: var(--color-oxblood);
}
.stat-card--warn {
  border-color: var(--color-warn, #b86800);
}

.home-alert {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.6rem var(--app-card-pad);
  border-radius: 2px;
  border: 1px solid;
  margin-bottom: 1.25rem;
  font-size: 0.9rem;
}
.home-alert--warn {
  background: #fffbf0;
  border-color: #e8c060;
  color: #7a5000;
}
.home-alert-icon { font-size: 1rem; }

.home-section-label {
  font-family: var(--font-mono);
  font-size: var(--type-eyebrow);
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--color-muted);
  margin: 0 0 0.75rem;
}

.home-week {
  margin-bottom: 1.75rem;
}
.home-week-dots {
  display: flex;
  gap: 0.5rem;
}
.home-week-dot {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.35rem;
  flex: 1;
  text-decoration: none;
  color: var(--color-muted);
  padding: 0.5rem 0;
}
.home-week-dot-day {
  font-family: var(--font-mono);
  font-size: 0.65rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}
.home-week-dot-marker {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  border: 1.5px solid var(--color-rule-strong);
  background: transparent;
  transition: background var(--transition-fast), border-color var(--transition-fast);
}
.home-week-dot--filled .home-week-dot-marker {
  background: var(--color-oxblood);
  border-color: var(--color-oxblood);
}
.home-week-dot--today .home-week-dot-day {
  color: var(--color-oxblood);
  font-weight: 600;
}
.home-week-dot:hover .home-week-dot-marker {
  border-color: var(--color-oxblood);
}

.home-actions {
  margin-bottom: 1.75rem;
}
.home-actions-row {
  display: flex;
  gap: 0.75rem;
  flex-wrap: wrap;
}

.home-activity {
  margin-bottom: 2rem;
}
.home-activity-list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: grid;
  gap: 0;
  border: 1px solid var(--color-rule);
  border-radius: 2px;
  overflow: hidden;
}
.home-activity-row {
  display: flex;
  align-items: baseline;
  gap: 0.6rem;
  padding: 0.55rem var(--app-card-pad);
  border-bottom: 1px solid var(--color-rule);
  background: var(--color-bg);
  font-size: 0.875rem;
}
.home-activity-row:last-child { border-bottom: none; }
.home-activity-time {
  font-family: var(--font-mono);
  font-size: 0.72rem;
  white-space: nowrap;
  flex-shrink: 0;
}
.home-activity-body {
  color: var(--color-text);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  min-width: 0;
}

/* ================================================= SETTINGS HUB ===== */

.settings-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  gap: 0.85rem;
  margin-bottom: 2rem;
}
.settings-card {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  padding: var(--app-card-pad);
  background: var(--color-bg);
  border: 1px solid var(--color-rule);
  border-radius: var(--app-card-radius);
  text-decoration: none;
  color: var(--color-text);
  transition: border-color var(--transition-fast), background var(--transition-fast);
}
.settings-card:hover {
  border-color: var(--color-oxblood);
  background: var(--color-bg-tint);
}
.settings-card-title {
  font-family: var(--font-mono);
  font-size: var(--type-eyebrow);
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--color-oxblood);
}
.settings-card-desc {
  font-size: 0.875rem;
  color: var(--color-muted);
  line-height: 1.4;
}

.settings-features {
  margin-top: 2rem;
  margin-bottom: 2rem;
}
.settings-feature-list {
  display: grid;
  gap: 0;
  border: 1px solid var(--color-rule);
  border-radius: var(--app-card-radius);
  overflow: hidden;
}
.settings-feature-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.85rem var(--app-card-pad);
  background: var(--color-bg);
  border-bottom: 1px solid var(--color-rule);
}
.settings-feature-row:last-child { border-bottom: none; }
.settings-feature-row strong { display: block; font-size: 0.9rem; margin-bottom: 0.15rem; }
.settings-toggle {
  flex-shrink: 0;
  font-family: var(--font-mono);
  font-size: var(--type-eyebrow);
  font-weight: 500;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  padding: 0.3rem 0.75rem;
  border: 1px solid var(--color-rule-strong);
  border-radius: 2px;
  background: var(--color-bg-tint);
  color: var(--color-muted);
  cursor: pointer;
  transition: background var(--transition-fast), border-color var(--transition-fast), color var(--transition-fast);
}
.settings-toggle--on {
  background: var(--color-status-ok-bg);
  color: var(--color-status-ok-fg);
  border-color: var(--color-status-ok-fg);
}

/* ================================================== DASHBOARD ======= */

.dashboard-actions { margin-bottom: 2rem; }
.dashboard-actions h2 {
  font-family: var(--font-mono);
  font-size: var(--type-eyebrow);
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--color-oxblood);
  margin: 0 0 0.85rem;
}
.dashboard-actions h2.muted { color: var(--color-muted); }

.action-list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: grid;
  gap: 0.4rem;
  max-width: 540px;
}
.action-list a {
  display: block;
  padding: 0.7rem 1rem;
  background: var(--color-bg);
  border: 1px solid var(--color-rule);
  border-radius: 2px;
  color: var(--color-text);
  text-decoration: none;
  transition: border-color var(--transition-fast), background var(--transition-fast), color var(--transition-fast);
}
.action-list a:hover {
  border-color: var(--color-oxblood);
  color: var(--color-oxblood);
}
.action-list a.cta {
  background: var(--color-oxblood);
  color: var(--color-bg);
  border-color: var(--color-oxblood);
  font-weight: 500;
}
.action-list a.cta:hover {
  background: var(--color-oxblood-hover);
  border-color: var(--color-oxblood-hover);
  color: var(--color-bg);
}

/* ==================================== ONBOARDING WIZARD ============= */

/* Overview checklist. Step number is a small mono badge in oxblood, not a
 * filled green circle. Done state stamps the number cream-on-oxblood.
 */
.wizard-checklist {
  list-style: none;
  padding: 0;
  margin: 1.5rem 0;
  display: grid;
  gap: 0.6rem;
}
.wizard-checklist > li {
  background: var(--color-bg);
  border: 1px solid var(--color-rule);
  border-radius: 2px;
  overflow: hidden;
  transition: border-color var(--transition-fast);
}
.wizard-checklist > li:has(> a:hover) { border-color: var(--color-rule-strong); }
.wizard-checklist > li.done {
  border-color: var(--color-oxblood);
  background: linear-gradient(180deg, rgba(92, 31, 31, 0.04), transparent), var(--color-bg);
}
.wizard-checklist > li > a,
.wizard-checklist > li > .step-row {
  display: grid;
  grid-template-columns: 36px 1fr auto;
  gap: 1rem;
  align-items: center;
  padding: 0.95rem 1.2rem;
  color: var(--color-text);
  text-decoration: none;
}
.wizard-checklist .step-num {
  width: 32px;
  height: 32px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-mono);
  font-size: 0.85rem;
  font-weight: 500;
  letter-spacing: 0.04em;
  color: var(--color-oxblood);
  background: transparent;
  border: 1px solid var(--color-oxblood);
  border-radius: 2px;
}
.wizard-checklist .done .step-num {
  background: var(--color-oxblood);
  color: var(--color-bg);
}
.wizard-checklist .step-body { display: flex; flex-direction: column; gap: 0.15rem; }
.wizard-checklist .step-title {
  font-family: var(--font-serif);
  font-weight: 500;
  font-size: 1.1rem;
  letter-spacing: -0.01em;
  color: var(--color-text);
}
.wizard-checklist .step-sub {
  font-size: var(--type-small);
  color: var(--color-muted);
  line-height: 1.4;
}
.wizard-checklist .step-status {
  font-family: var(--font-mono);
  font-size: var(--type-eyebrow);
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--color-muted);
  text-align: right;
}
.wizard-checklist .done .step-status { color: var(--color-oxblood); }

/* Step forms (shared with the brand kit, brief, sources, platforms pages). */
.wizard-form { max-width: 720px; }
.wizard-form .form-row { margin-bottom: 1.1rem; }
.wizard-form .form-row-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: 0.8rem;
}
.wizard-form label { display: block; }
.wizard-form h2 {
  font-family: var(--font-mono);
  font-size: var(--type-eyebrow);
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--color-oxblood);
  margin: 1.5rem 0 0.6rem;
}
.wizard-form .form-actions {
  display: flex;
  gap: 0.6rem;
  align-items: center;
  flex-wrap: wrap;
  margin-top: 1.5rem;
  padding-top: 1.1rem;
  border-top: 1px solid var(--color-rule);
}

/* Source list (existing-sources / existing-connections sections). */
.source-list { margin: 1.25rem 0 1.75rem; }
.source-list h2 {
  font-family: var(--font-mono);
  font-size: var(--type-eyebrow);
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--color-oxblood);
  margin: 0 0 0.65rem;
}
.source-list ul {
  list-style: none;
  padding: 0;
  margin: 0;
  display: grid;
  gap: 0.4rem;
}
.source-list li {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.65rem;
  padding: 0.7rem 0.95rem;
  background: var(--color-bg);
  border: 1px solid var(--color-rule);
  border-radius: 2px;
  font-size: var(--type-small);
}

/* ==================================== URL IMPORTER ================== */

.import-form {
  max-width: 760px;
  margin-top: 1rem;
}
.import-form > p { margin: 0.85rem 0; }
.import-form fieldset { margin-bottom: 1.25rem; }

.preview-block {
  margin: 1.5rem 0;
  padding: 1.25rem 1.4rem;
  border: 1px solid var(--color-rule);
  border-radius: 2px;
  background: var(--color-bg);
}
.preview-block h2 {
  font-family: var(--font-mono);
  font-size: var(--type-eyebrow);
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--color-oxblood);
  margin: 0 0 0.85rem;
}
.preview-block p { margin: 0 0 0.6rem; }
.preview-block p:last-child { margin: 0; }
.preview-block.warnings { border-left: 3px solid var(--color-status-warn-fg); }

.preview-confirm {
  display: contents;
}

.handle-table {
  width: 100%;
  border-collapse: collapse;
  margin: 0.5rem 0;
  font-size: var(--type-small);
}
.handle-table thead th {
  text-align: left;
  font-family: var(--font-mono);
  font-size: var(--type-eyebrow);
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--color-muted);
  border-bottom: 1px solid var(--color-rule-strong);
  padding: 0.5rem 0.7rem;
}
.handle-table tbody td {
  padding: 0.6rem 0.7rem;
  border-bottom: 1px solid var(--color-rule);
  vertical-align: middle;
}
.handle-table tbody tr:last-child td { border-bottom: 0; }
.handle-table tbody td label {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  margin-right: 0.6rem;
  font-family: var(--font-sans);
  font-size: var(--type-small);
  text-transform: none;
  letter-spacing: 0;
  color: var(--color-text);
}
.handle-table em {
  color: var(--color-muted);
  font-style: italic;
}

.import-status {
  border: 1px solid var(--color-rule);
  border-radius: 2px;
  padding: 1.25rem 1.4rem;
  background: var(--color-bg);
  margin: 1rem 0;
}
.import-status p { margin: 0 0 0.55rem; }
.import-status p:last-child { margin: 0; }
.import-status pre.error-detail,
.error-detail {
  font-size: var(--type-small);
  background: var(--color-status-fail-bg);
  color: var(--color-status-fail-fg);
  border: 1px solid var(--color-status-fail-fg);
  border-radius: 2px;
  padding: 0.7rem 1rem;
  margin: 0.5rem 0;
  white-space: pre-wrap;
  word-break: break-word;
}

/* ==================================== APPROVAL QUEUE ================ */

.queue-header {
  display: flex;
  align-items: baseline;
  gap: 1rem;
  flex-wrap: wrap;
  margin-bottom: 1.5rem;
}
.queue-header h1 {
  font-family: var(--font-serif);
  font-size: clamp(1.75rem, 3.4vw, 2.4rem);
  font-weight: 500;
  letter-spacing: -0.02em;
  line-height: 1.1;
  margin: 0;
}
.queue-header .muted {
  font-family: var(--font-mono);
  font-size: var(--type-eyebrow);
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
}
.queue-header .queue-actions {
  margin-left: auto;
  display: flex;
  gap: 0.6rem;
  flex-wrap: wrap;
  align-items: center;
}

/* In-flight batch banner. Surfaces after Generate-page dispatch so the
   operator gets visible progress instead of an empty queue + a stale
   success toast. JS in batch_review.html updates the text as drafts
   arrive. */
.generating-banner {
  flex-basis: 100%;
  display: flex;
  align-items: center;
  gap: 0.75rem;
  margin: 0.6rem 0 0;
  padding: 0.75rem 1rem;
  background: var(--color-cream, #f4ecd8);
  border: 1px solid var(--color-rule);
  border-left: 4px solid var(--color-oxblood);
  border-radius: 3px;
  font-size: 0.95rem;
  line-height: 1.4;
}
.generating-banner-text { flex: 1; }
/* Queue error banner — used by the htmx:responseError handler to
 * surface refused approves / capability-denied / length-overflow.
 * Coloured oxblood to signal stop, not the cream of the in-flight
 * banner above. */
.queue-error-banner {
  flex-basis: 100%;
  display: flex;
  align-items: flex-start;
  gap: 0.75rem;
  margin: 0.6rem 0 0;
  padding: 0.75rem 1rem;
  background: #fbe9e9;
  border: 1px solid #d9b3b3;
  border-left: 4px solid var(--color-oxblood);
  border-radius: 3px;
  font-size: 0.95rem;
  line-height: 1.4;
  color: #4a1414;
}
/* The `hidden` attribute on the banner element is supposed to keep
 * it out of the flow until the htmx:responseError handler fills it
 * in. Without this rule, the `display:flex` above wins over the user
 * agent stylesheet's `[hidden]{display:none}` (same specificity,
 * later in cascade) and the banner renders empty on every page load.
 * Caught by an empty oxblood banner on the queue 2026-05-24. */
.queue-error-banner[hidden] {
  display: none;
}
.queue-error-banner-text { flex: 1; white-space: pre-wrap; word-break: break-word; }
.queue-error-banner-close {
  background: none;
  border: 0;
  font-size: 1.4rem;
  line-height: 1;
  cursor: pointer;
  color: var(--color-oxblood);
  padding: 0 0.2rem;
}
.queue-error-banner-close:hover { color: #2a0808; }
.generating-spinner {
  width: 18px;
  height: 18px;
  border: 2px solid var(--color-rule);
  border-top-color: var(--color-oxblood);
  border-radius: 50%;
  animation: generatingSpin 0.9s linear infinite;
  flex: 0 0 auto;
}
@keyframes generatingSpin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
  .generating-spinner { animation: none; border-top-color: var(--color-oxblood); }
}

/* Bulk-actions dropdown in the queue header. Native <details>/<summary>
   with a small popover panel anchored to the summary. Keeping this lean
   so the queue header doesn't sprout three loose action buttons. */
.bulk-menu { position: relative; }
.bulk-menu > summary {
  list-style: none;
  cursor: pointer;
  user-select: none;
}
.bulk-menu > summary::-webkit-details-marker { display: none; }
.bulk-menu-caret {
  display: inline-block;
  font-size: 0.75em;
  margin-left: 0.15rem;
  transform: translateY(-1px);
}
.bulk-menu[open] .bulk-menu-caret { transform: translateY(-1px) rotate(180deg); }
.bulk-menu-list {
  position: absolute;
  top: calc(100% + 0.35rem);
  right: 0;
  z-index: 30;
  min-width: 220px;
  display: flex;
  flex-direction: column;
  background: var(--color-bg, #fff);
  border: 1px solid var(--color-border, rgba(0, 0, 0, 0.12));
  border-radius: 6px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);
  padding: 0.3rem;
}
.bulk-menu-item {
  appearance: none;
  background: transparent;
  border: 0;
  text-align: left;
  font-family: inherit;
  font-size: 15px;
  color: var(--color-text);
  padding: 0.55rem 0.75rem;
  border-radius: 4px;
  min-height: 40px;
  cursor: pointer;
}
.bulk-menu-item:hover,
.bulk-menu-item:focus-visible {
  background: var(--color-bg-tint, rgba(0, 0, 0, 0.05));
  outline: none;
}
.bulk-menu-item--danger { color: var(--color-oxblood, #5c1f1f); }

.grid {
  display: grid;
  gap: 0.85rem;
  /* Each row sizes to its tallest card so wide cards (LinkedIn / Instagram)
     don't force adjacent X/Bluesky cards to stretch. */
  grid-auto-rows: min-content;
  align-items: start;
}
@media (min-width: 960px) {
  .grid { grid-template-columns: 1fr 1fr; }
  /* Long-body cards take the full row so the full text shows without scroll. */
  .grid .card--wide { grid-column: 1 / -1; }
  /* Day-group divider spans the full row width so day boundaries
     read clearly when cards are laid out in a two-column grid. */
  .grid .queue-day-divider { grid-column: 1 / -1; }
}

/* Day-group divider in the queue grid. A thin rule with a date label
   on the left and the per-day draft count on the right; sits flush
   with the cards above and below. */
.queue-day-divider {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.25rem 0 0.15rem;
  margin-top: 0.4rem;
  border-top: 1px solid var(--color-rule);
}
.queue-day-divider:first-child {
  border-top: none;
  margin-top: 0;
  padding-top: 0;
}
.queue-day-label {
  font-family: var(--font-mono);
  font-size: var(--type-eyebrow);
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--color-muted);
}
.queue-day-count {
  font-family: var(--font-mono);
  font-size: var(--type-eyebrow);
  color: var(--color-muted);
  margin-left: auto;
}

/* Draft card body form (textarea inside card).
 * `field-sizing: content` (Chromium 123+, Edge, Opera) auto-grows the box to
 * fit. For Firefox/Safari we fall back to a small JS autosize hook in
 * batch_review.html. Either way, the textarea expands until the whole post is
 * visible — no inner scrollbar. */
.body-form { margin-top: 0.25rem; }
.body-form textarea {
  width: 100%;
  font-family: var(--font-mono);
  font-size: 0.9rem;
  line-height: 1.5;
  padding: 0.65rem 0.8rem;
  background: var(--color-bg);
  color: var(--color-text);
  border: 1px solid var(--color-rule);
  border-radius: 2px;
  field-sizing: content;
  min-height: 6.5rem;
  resize: vertical;
  overflow: hidden;
  transition: border-color var(--transition-fast);
}
.body-form textarea:focus {
  outline: none;
  border-color: var(--color-oxblood);
  box-shadow: 0 0 0 3px rgba(92, 31, 31, 0.12);
}
.body-form textarea[disabled] {
  background: var(--color-bg-tint);
  color: var(--color-muted);
}
.body-form button { margin-top: 0.5rem; }
/* Read-only body shown when a draft is no longer editable
 * (APPROVED / SCHEDULED / AWAITING_COSIGN / POSTED / etc).
 * Matches the textarea's visual frame so the card layout doesn't
 * jump between editable and locked states. */
.body-readonly {
  margin-top: 0.25rem;
  padding: 0.65rem 0.8rem;
  background: var(--color-bg-tint);
  border: 1px solid var(--color-rule);
  border-radius: 2px;
}
.body-readonly .post-body {
  font-family: var(--font-mono);
  font-size: 0.9rem;
  line-height: 1.5;
  margin: 0;
  white-space: pre-wrap;
  word-wrap: break-word;
}
.body-readonly-url {
  margin: 0.4rem 0 0;
  word-wrap: break-word;
}
.body-readonly .char-count { margin-bottom: 0; }
/* Per-platform reassurance under the Link URL field: a Bluesky single-post
   link publishes as a native embed card, not inline body text. Colour/size
   come from the `muted small` utility classes on the span. */
.bluesky-link-hint {
  display: block;
  margin: 0.3rem 0 0;
}
.char-count {
  font-family: var(--font-mono);
  font-size: var(--type-eyebrow);
  letter-spacing: 0.06em;
  color: var(--color-muted);
  margin: 0.4rem 0 0.2rem;
}

.flags {
  list-style: none;
  padding-left: 0;
  margin: 0.6rem 0;
  display: grid;
  gap: 0.25rem;
  font-size: var(--type-small);
  color: var(--color-status-warn-fg);
}
.flags li::before {
  content: "!";
  display: inline-block;
  width: 1.25em;
  margin-right: 0.4rem;
  color: var(--color-status-warn-fg);
  font-family: var(--font-mono);
  font-weight: 500;
}

.source {
  font-size: var(--type-small);
  color: var(--color-muted);
  margin: 0.6rem 0;
  border-top: 1px solid var(--color-rule);
  padding-top: 0.55rem;
}
.source a { color: var(--color-muted); text-decoration: underline; text-underline-offset: 3px; }
.source a:hover { color: var(--color-oxblood); }

.card-actions select {
  padding: 0.45rem 0.6rem;
  font-family: var(--font-sans);
  font-size: var(--type-small);
  background: var(--color-bg);
  color: var(--color-text);
  border: 1px solid var(--color-rule-strong);
  border-radius: 2px;
}

/* Calendar deep-link highlight (interlude PR #4).
   When /<slug>/queue/?focus=<pk> lands on the queue, the matching
   card briefly carries this class. Static outline + a 2s pulse so
   the operator's eye is drawn back to the chip they clicked on the
   calendar. The class is removed by JS after 2s. */
.card--focused {
  outline: 3px solid var(--color-oxblood);
  outline-offset: 4px;
  animation: card-focused-pulse 2s ease-out;
}
@keyframes card-focused-pulse {
  0%   { box-shadow: 0 0 0 6px rgba(92, 31, 31, 0.28); }
  100% { box-shadow: 0 0 0 0   rgba(92, 31, 31, 0);    }
}
@media (prefers-reduced-motion: reduce) {
  .card--focused { animation: none; }
}

/* ==================================== POSTS: GENERATE HUB =========== */

.generate-tabs {
  display: flex;
  flex-wrap: wrap;
  gap: 0;
  border-bottom: 1px solid var(--color-rule-strong);
  margin: 1.25rem 0 1.5rem;
}
.generate-tab {
  font-family: var(--font-mono);
  font-size: var(--type-eyebrow);
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--color-muted);
  text-decoration: none;
  padding: 0.7rem 1rem;
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
  transition: color var(--transition-fast), border-color var(--transition-fast);
}
.generate-tab:hover { color: var(--color-text); }
.generate-tab.active {
  color: var(--color-oxblood);
  border-bottom-color: var(--color-oxblood);
}

.generate-panel { padding: 0.5rem 0; }
.generate-form {
  max-width: 760px;
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

/* Week tab needs the full page width — it's a multi-column table that
   collapses ugly at 760px. The form drops the max-width cap, and the
   parent container drops its max-width when the Week panel is the
   visible tab. Together: table fills viewport minus the gutter padding,
   without affecting the other (form-shaped) tabs. */
#week-form { max-width: none; }
main.container:has(#panel-week:not([hidden])) {
  max-width: none;
}

/* W5: align the Review queue surface to the brand's left edge. The brand sits
   in .topnav-inner (max-width: canvas-max); the default .container is narrower
   (container-max), so on wide screens "Review" was inset from the brand and the
   left margin sat empty. Both wrappers are centered with the same --gutter, so
   widening ONLY the queue surface to canvas-max lines its left content edge up
   with the brand and keeps the existing right-hand gutter on the 2-col grid.
   Scoped via :has(.queue-header) so every other page keeps container-max. Below
   canvas-max the viewport already governs, so the sub-720px layout is unchanged. */
main.container:has(.queue-header) {
  max-width: var(--canvas-max);
}
.generate-form h2 {
  font-family: var(--font-serif);
  font-size: 1.4rem;
  font-weight: 500;
  letter-spacing: -0.01em;
  margin: 0 0 0.4rem;
}
.generate-form > p.muted { margin: 0 0 0.5rem; }
.generate-form button[type="submit"] {
  align-self: flex-start;
  margin-top: 0.5rem;
}

.plan-platform-filter {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex-wrap: wrap;
  margin: 0.5rem 0 0.25rem;
}
.plan-platform-filter-label {
  margin-right: 0.25rem;
}
.plan-platform-chip {
  cursor: pointer;
  border: none;
  opacity: 0.35;
  transition: opacity var(--transition-fast);
}
.plan-platform-chip--active {
  opacity: 1;
}
.plan-platform-chip:hover {
  opacity: 0.85;
}

.plan-table {
  width: 100%;
  border-collapse: collapse;
  margin: 0.5rem 0 1rem;
  font-size: var(--type-small);
}
.plan-table thead th {
  text-align: left;
  font-family: var(--font-mono);
  font-size: var(--type-eyebrow);
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--color-muted);
  border-bottom: 1px solid var(--color-rule-strong);
  padding: 0.55rem 0.7rem;
}
.plan-table tbody td {
  padding: 0.6rem 0.7rem;
  border-bottom: 1px solid var(--color-rule);
  vertical-align: top;
}
.plan-table tbody tr:hover { background: var(--color-bg-tint); }

/* ---- Week tab: status strip + per-row flags (Phase 1.1) ---- */
/* Generate-week date picker sits above the status strip and is always
   visible regardless of plan state. */
.week-start-picker {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  margin: 0.4rem 0 0.9rem;
}
.week-start-picker label {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
}
.week-start-picker input[type="date"] {
  font-family: inherit;
  font-size: 15px;
  min-height: 36px;
  padding: 0.25rem 0.5rem;
  border: 1px solid var(--color-border, rgba(0, 0, 0, 0.15));
  border-radius: 4px;
}

.week-status {
  display: grid;
  grid-template-columns: max-content 1fr;
  column-gap: 1.2rem;
  row-gap: 0.45rem;
  margin: 0.4rem 0 1.2rem;
  padding: 0.9rem 1rem;
  background: var(--color-bg-tint);
  border: 1px solid var(--color-rule);
  border-radius: 2px;
  font-size: var(--type-small);
}
.week-status-row {
  display: contents;
}
.week-status dt {
  font-family: var(--font-mono);
  font-size: var(--type-eyebrow);
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--color-muted);
  align-self: center;
}
.week-status dd {
  margin: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem 0.7rem;
  align-items: center;
}

.overlay-chip {
  display: inline-flex;
  gap: 0.35rem;
  padding: 0.15rem 0.55rem;
  background: var(--color-bg);
  border: 1px solid var(--color-rule);
  border-radius: 2px;
}
.cadence-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
}
.cadence-ok    { color: var(--color-status-ok-fg);   font-weight: 600; }
.cadence-short { color: var(--color-status-warn-fg); font-weight: 600; }

/* Column sizing for the Week-tab plan table.
   Use semantic class selectors (never nth-child — column count changes
   break those). table-layout: auto lets the browser compute cell widths
   from content; we give min-width / max-width hints to keep narrow
   columns narrow and prevent the flags column blowing out the layout.
   Columns: pick | day | platform | kind | source | flags | actions
   Time-of-day is intentionally absent — it is set on the calendar
   surface, not at generation. */
.plan-table { table-layout: auto; }

/* pick (checkbox) — wider on desktop to also fit the drag handle. The
 * handle is hidden below 720px (no native HTML5 drag-and-drop on touch),
 * so the column collapses back to checkbox-only on phones. */
.plan-col-pick  { width: 3.4rem; min-width: 3.4rem; text-align: center; white-space: nowrap; }
@media (max-width: 720px) {
  .plan-col-pick { width: 2rem; min-width: 2rem; }
}

/* Drag handle. Desktop-only — touch drag would clash with the page's
 * vertical scroll and there's no mobile HTML5-drag analogue worth
 * shipping in v1. Cursor flip on grab/grabbing matches the queue card
 * drag affordance. */
.plan-drag-handle {
  display: inline-block;
  margin-right: 0.3rem;
  padding: 0 0.15rem;
  color: var(--color-muted);
  cursor: grab;
  user-select: none;
  vertical-align: middle;
  font-size: 0.9rem;
  line-height: 1;
  letter-spacing: -0.15em;
}
.plan-drag-handle:active { cursor: grabbing; }
@media (max-width: 720px), (pointer: coarse) {
  .plan-drag-handle { display: none; }
}

/* Dragging-row + drop-target visual feedback, mirroring the queue
 * card pattern so the affordance reads consistently. */
.plan-row.plan-row--dragging { opacity: 0.45; }
.plan-row.plan-row--drop-above td { box-shadow: inset 0 2px 0 0 var(--color-oxblood); }
.plan-row.plan-row--drop-below td { box-shadow: inset 0 -2px 0 0 var(--color-oxblood); }
.plan-row.plan-row--saving { opacity: 0.7; pointer-events: none; }
/* day */
.plan-col-day   { width: 6rem;  min-width: 6rem;  white-space: nowrap; }
/* platform badge */
.plan-col-platform { width: 6rem; min-width: 6rem; }
/* source / topic — takes the remaining slack. Kind rides as an inline
   .kind-tag prefix here (no dedicated column) so longer kinds like
   'advocacy_tool' don't push the table wide. */
.plan-col-source { min-width: 12rem; }
/* flags — capped so one long badge doesn't eat the table */
.plan-col-flags { width: 13rem; max-width: 13rem; }
/* campaign tag — narrow select column */
.plan-col-campaign { width: 11rem; min-width: 9rem; }
/* action buttons — 5 × 1.9rem + gaps */
.plan-col-actions { width: 10.5rem; min-width: 10.5rem; text-align: right; white-space: nowrap; }

/* Aliases kept for back-compat with other templates using the old names. */
.plan-table-flags { width: 13rem; max-width: 13rem; }
.plan-row-actions { width: 10.5rem; min-width: 10.5rem; text-align: right; white-space: nowrap; }

/* The Flags column td carries both .plan-col-flags AND .plan-flags. The
 * earlier `display: flex` on the td produced inconsistent vertical
 * alignment because flex on a `<td>` is fragile in some browsers and
 * the user-agent's `display: table-cell` keeps interacting with it.
 * Treat the td as a normal table cell (vertical-align: top inherits
 * from .plan-table tbody td above) and let the inline-block chips
 * flow naturally with margin-based spacing. */
.plan-flags  { line-height: 1.4; }
.plan-flags .flag { vertical-align: top; margin: 0 0.25rem 0.25rem 0; }
.plan-source-cell { line-height: 1.35; word-break: break-word; }

/* Inline kind tag inside the source cell. Replaces the old Kind column.
   Tight, one-line, lower contrast than the title so it reads as a
   prefix label rather than as competing content. The colour variants
   pick out the three semantic buckets so an operator scanning the
   column can clock the mix at a glance:
     --typed     typed evergreen content (concept / episode / tool / ...)
     --evergreen brief topic-seed fallback
     --news      RSS news (no content_kind)                                */
.kind-tag {
  display: inline-block;
  margin-right: 0.4rem;
  padding: 0 0.4rem;
  font-size: 0.7rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  line-height: 1.5rem;
  white-space: nowrap;
  border-radius: 2px;
  vertical-align: 1px;
}
.kind-tag--typed     { background: var(--color-bg-tint); color: var(--color-text);  border: 1px solid var(--color-rule-strong); }
.kind-tag--evergreen { background: var(--color-bg-tint); color: var(--color-muted); border: 1px dashed var(--color-rule); }
.kind-tag--news      { background: var(--color-bg);      color: var(--color-muted); border: 1px solid var(--color-rule); }
.row-action-btn {
  display: inline-block;
  width: 1.9rem;
  height: 1.9rem;
  margin-left: 0.15rem;
  padding: 0;
  font-size: 1rem;
  line-height: 1.6rem;
  text-align: center;
  background: var(--color-bg);
  color: var(--color-text);
  border: 1px solid var(--color-rule);
  border-radius: 2px;
  cursor: pointer;
}
.row-action-btn:hover:not([disabled]) {
  background: var(--color-bg-tint);
  border-color: var(--color-rule-strong);
}
.row-action-btn[disabled] { opacity: 0.35; cursor: not-allowed; }
/* In-flight regenerate spins JUST its ↻ glyph (wrapped in
 * .row-action-glyph) so the operator sees active "working" feedback
 * during the ~2s LLM round-trip. Spinning the whole button looked
 * silly — the box moves with the glyph and the title attribute
 * jitters; pinning the box steady while the arrow turns reads as
 * a normal "loading" affordance. ↻ already points clockwise, so the
 * 0 → 360deg rotation in htmx-spin matches the arrow's direction. */
.row-action-glyph {
  display: inline-block;
  transform-origin: 50% 50%;
}
form.htmx-request .row-action-btn--regenerate .row-action-glyph {
  animation: htmx-spin 0.7s linear infinite;
}
@media (prefers-reduced-motion: reduce) {
  form.htmx-request .row-action-btn--regenerate .row-action-glyph { animation: none; }
}
.row-action-reject { transition: color 0.1s, border-color 0.1s; }
.row-action-reject:hover {
  color: var(--color-status-fail-fg);
  border-color: var(--color-status-fail-fg);
}

/* The thread kind-flip button on the Week-tab carries multi-character
 * copy ("→ single" / "→ thread"), so it can't share the fixed
 * 1.9rem square sizing the other row-action-btns use. Let it size to
 * its content and keep the text on one line. */
.plan-thread-flip-btn {
  width: auto;
  min-width: 1.9rem;
  padding: 0 0.5rem;
  white-space: nowrap;
}

/* Per-slot thread controls. Sits on a new line under the source title;
 * the small parts-stepper input + "→ single" button line up next to
 * each other on the same row. */
.plan-thread-toggle {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  margin-top: 0.25rem;
  flex-wrap: wrap;
}
.plan-thread-toggle form { display: inline-flex; align-items: center; gap: 0.25rem; }
.plan-thread-parts-input {
  width: 3.5rem;
  padding: 0 0.2rem;
  font-size: var(--type-small);
}

/* Kind tag for thread slots. Same tonal weight as the existing
 * kind-tag--typed but with a slight accent so the operator's eye
 * catches "this slot is a thread" without reading the parts stepper. */
.kind-tag--thread {
  background: var(--color-bg-tint);
  color: var(--color-oxblood);
  border: 1px solid var(--color-oxblood);
}

/* Per-row campaign tag select. Mobile floor: 44px height, 16px font on
 * the input so iOS doesn't auto-zoom on focus (CLAUDE.md rule 7). The
 * tagged variant gets a coloured ring so operators can scan which slots
 * are linked to a campaign at a glance. */
.plan-campaign-form { margin: 0; }
.plan-campaign-select {
  min-height: 44px;
  font-size: 16px;
  width: 100%;
  padding: 0.25rem 0.4rem;
  background: var(--color-bg);
  color: var(--color-text);
  border: 1px solid var(--color-rule);
  border-radius: 2px;
}
.plan-campaign-select--tagged {
  border-color: var(--color-rule-strong);
  background: var(--color-bg-tint);
  font-weight: 600;
}
.plan-campaign-select:focus-visible {
  outline: 2px solid var(--color-rule-strong);
  outline-offset: 2px;
}
@media (min-width: 721px) {
  /* Desktop: tighter target — touch floor only applies to phones. */
  .plan-campaign-select { min-height: 1.9rem; font-size: 0.875rem; }
}

/* Queue card: row-action toolbar above the approve/reject row.
   Mirrors the per-row controls on the Generate page Week tab so the
   operator can move / regenerate / swap / delete directly from the
   approval queue. */
.card-row-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.15rem;
  margin-top: 0.5rem;
  padding-top: 0.4rem;
  border-top: 1px dashed var(--color-rule);
}

/* Phase 1.2: swap modal. */
.modal-backdrop {
  position: fixed; inset: 0;
  background: rgba(0, 0, 0, 0.45);
  display: flex; align-items: center; justify-content: center;
  z-index: 100;
}
.modal-card {
  background: var(--color-bg);
  border: 1px solid var(--color-rule-strong);
  border-radius: 2px;
  width: min(640px, 92vw);
  max-height: 86vh;
  display: flex;
  flex-direction: column;
}
.modal-header {
  display: flex; justify-content: space-between; align-items: center;
  padding: 0.8rem 1rem;
  border-bottom: 1px solid var(--color-rule);
}
.modal-header h3 { margin: 0; font-size: var(--type-body); }
.modal-close {
  background: none; border: none;
  font-size: 1.4rem; line-height: 1;
  cursor: pointer;
  color: var(--color-muted);
}
.modal-body {
  padding: 1rem;
  overflow-y: auto;
  display: flex; flex-direction: column; gap: 1.2rem;
}
.modal-body section h4 {
  margin: 0 0 0.5rem;
  font-family: var(--font-mono);
  font-size: var(--type-eyebrow);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--color-muted);
}
.modal-list { list-style: none; padding: 0; margin: 0; max-height: 30vh; overflow-y: auto; }
.modal-list li { margin: 0; }
.modal-list li + li { border-top: 1px solid var(--color-rule); }
.modal-row-btn {
  width: 100%;
  text-align: left;
  padding: 0.5rem 0.6rem;
  background: none;
  border: none;
  cursor: pointer;
  display: flex; flex-direction: column; gap: 0.15rem;
  font: inherit;
  color: inherit;
}
.modal-row-btn:hover { background: var(--color-bg-tint); }
/* Queue "Source" editor (rebuild of the swap modal). Reuses the .modal-*
   shell above; these rules lay out the Currently card + the single
   source/format form. 44px controls / 16px inputs for the mobile floor (§7). */
.swap-currently-card {
  padding: 0.7rem 0.8rem;
  border: 1px solid var(--color-rule);
  border-radius: 2px;
  background: var(--color-bg-tint);
  display: flex; flex-direction: column; gap: 0.4rem;
}
.swap-eyebrow {
  font-family: var(--font-mono);
  font-size: var(--type-eyebrow);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--color-muted);
}
.swap-currently-chips { display: flex; flex-wrap: wrap; gap: 0.4rem; }
.swap-currently-subject { font-size: var(--type-body); }
.swap-locked-note { margin: 0.2rem 0 0; }
.swap-legend { margin: 0; }

.swap-form { display: flex; flex-direction: column; gap: 0.9rem; }
.swap-fields { display: flex; flex-direction: column; gap: 0.5rem; padding-left: 0.2rem; }
.swap-fields label { display: flex; flex-direction: column; gap: 0.2rem; }
.swap-fields label > span,
.swap-lbl {
  font-family: var(--font-mono);
  font-size: var(--type-eyebrow);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--color-muted);
}
.swap-source-types {
  border: 1px solid var(--color-rule);
  border-radius: 2px;
  padding: 0.4rem 0.7rem;
  margin: 0;
  display: flex; flex-direction: column; gap: 0.1rem;
}
.swap-source-types legend { padding: 0 0.3rem; }
.swap-form .swap-radio {
  display: flex; flex-direction: row; align-items: center; gap: 0.5rem;
  min-height: 44px; cursor: pointer;
}
.swap-form .swap-radio input { width: auto; }
.swap-format { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem; }
.swap-thread-parts { width: 5rem; }
.swap-form .swap-sync-toggle {
  display: flex; flex-direction: row; align-items: center; gap: 0.5rem;
  min-height: 44px;
}
.swap-form .swap-sync-toggle input { width: auto; }
.swap-form .btn { align-self: flex-start; }
.swap-form select,
.swap-form input[type="number"] { min-height: 44px; font-size: 16px; }

/* Generate/Week-tab swap modal (posts/generate/_week_swap_modal.html) — a
   separate surface from the queue "Source" editor above; keep its layout. */
.evergreen-swap-form {
  display: flex; flex-direction: column; gap: 0.5rem;
}
.evergreen-swap-form label { display: flex; flex-direction: column; gap: 0.2rem; }
.evergreen-swap-form label > span {
  font-family: var(--font-mono);
  font-size: var(--type-eyebrow);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--color-muted);
}
.evergreen-swap-form button { align-self: flex-start; }

/* Calendar edit modal — opened by clicking a chip on /<slug>/calendar/.
   Reuses .modal-backdrop / .modal-card / .modal-header / .modal-body
   from the swap-modal block above; the rules here just lay out the
   form fields specific to the calendar edit case. */
.cal-modal { width: min(680px, 94vw); }
.cal-modal-body { gap: 1rem; }
.cal-modal-meta {
  display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem;
}
.cal-modal-limit { margin-left: auto; }
.cal-modal-warn {
  margin: 0;
  padding: 0.55rem 0.7rem;
  border-left: 3px solid var(--color-status-warn-fg, #b88600);
  background: var(--color-status-warn-bg, #fff8e6);
  color: var(--color-status-warn-fg, #6b4d00);
  font-size: var(--type-small);
  border-radius: 2px;
}
.cal-modal-readonly .post-body {
  white-space: pre-wrap;
  margin: 0 0 0.5rem;
}
.cal-modal-form {
  display: flex; flex-direction: column; gap: 0.9rem;
}
.cal-modal-field {
  display: flex; flex-direction: column; gap: 0.3rem;
}
.cal-modal-label {
  font-family: var(--font-mono);
  font-size: var(--type-eyebrow);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--color-muted);
}
.cal-modal-form textarea,
.cal-modal-form input[type="url"],
.cal-modal-form input[type="datetime-local"] {
  width: 100%;
  font: inherit;
  font-size: 16px; /* iOS no-zoom on focus, per CLAUDE.md rule 7 */
  padding: 0.55rem 0.65rem;
  border: 1px solid var(--color-rule-strong);
  border-radius: 2px;
  background: var(--color-bg);
  color: inherit;
  min-height: 44px; /* mobile touch floor, per CLAUDE.md rule 7 */
}
.cal-modal-form textarea {
  min-height: 140px;
  resize: vertical;
  line-height: 1.45;
}
.cal-modal-form textarea:focus-visible,
.cal-modal-form input:focus-visible {
  outline: 2px solid var(--color-oxblood, #6b1e1e);
  outline-offset: 2px;
}
.cal-modal-hint {
  align-self: flex-end;
}
.cal-modal-error {
  padding: 0.5rem 0.7rem;
  border-left: 3px solid var(--color-error, #c0392b);
  background: var(--color-status-fail-bg, #fde7e7);
  color: var(--color-status-fail-fg, #7a1f1f);
  font-size: var(--type-small);
  border-radius: 2px;
}
.cal-modal-actions {
  display: flex; justify-content: flex-end; gap: 0.5rem;
  padding-top: 0.4rem;
  border-top: 1px solid var(--color-rule);
}
.cal-modal-actions .btn { min-height: 44px; }

@media (max-width: 720px) {
  .cal-modal { width: 100vw; max-height: 100vh; height: 100vh; border-radius: 0; }
  .modal-backdrop:has(> .cal-modal) { align-items: stretch; justify-content: stretch; }
  .cal-modal-actions { position: sticky; bottom: 0; background: var(--color-bg); }
}

@media (prefers-reduced-motion: reduce) {
  .modal-backdrop { transition: none; }
}

/* Hint that a chip is clickable for the modal. The chip already has
   cursor:pointer via the <a>; this keeps the hover signal subtle so
   it doesn't fight with the drag affordance. */
.cal-chip[hx-get]:hover { filter: brightness(1.05); }

.flag {
  display: inline-block;
  padding: 0.1rem 0.45rem;
  font-family: var(--font-mono);
  font-size: var(--type-eyebrow);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  border-radius: 2px;
  border: 1px solid transparent;
  white-space: nowrap;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
}
.flag-neutral { background: var(--color-bg-tint);        color: var(--color-muted);        border-color: var(--color-rule); }
.flag-info    { background: var(--color-status-info-bg); color: var(--color-status-info-fg); }
.flag-warn    { background: var(--color-status-warn-bg); color: var(--color-status-warn-fg); }
.flag-danger  { background: var(--color-status-fail-bg); color: var(--color-status-fail-fg); }

/* Slot whose pinned source would be hard-gated at draft time (archival
   news >= 90d, or event past the recap window). The picker filter
   excludes such items at pick time; this rule covers the residual case
   where a slot was pinned and then aged out, plus the migration window
   for plans built before the picker filter shipped. The status strip
   surfaces the count and an explicit "Refresh stale slots" button.
   Visual treatment is informational (muted + tinted left border), not
   strikethrough — the flag-danger badge does the loud signalling. */
.plan-row-skip td {
  color: var(--color-muted);
  background: var(--color-status-fail-bg);
}
.plan-row-skip td:first-child {
  border-left: 3px solid var(--color-status-fail-fg);
}
.plan-empty-state {
  padding: 1.5rem 1rem;
  border: 1px dashed var(--color-rule-strong);
  border-radius: 2px;
  margin: 1rem 0;
}
.plan-empty-state p { margin: 0 0 0.5rem; }
.plan-empty-state p:last-of-type { margin-bottom: 1rem; }

/* ==================================== CADENCE MATRIX (BRIEF) ======= */

.cadence-matrix-wrap {
  overflow-x: auto;
  margin: 0.4rem 0 0.6rem;
}
.cadence-matrix {
  border-collapse: collapse;
  font-family: var(--font-mono);
  font-size: var(--type-eyebrow);
}
.cadence-matrix th,
.cadence-matrix td {
  padding: 0.3rem 0.4rem;
  text-align: center;
  border: 1px solid var(--color-rule);
}
.cadence-matrix thead th {
  background: var(--color-bg-tint);
  color: var(--color-muted);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  font-weight: 500;
}
.cadence-matrix-platform {
  text-align: left;
  background: var(--color-bg-tint);
  font-weight: 500;
}
.cadence-matrix-total {
  background: var(--color-bg-tint);
  font-weight: 700;
  min-width: 2.4rem;
}
.cadence-matrix-cell {
  width: 3.4rem;
  min-height: 36px;
  text-align: center;
  padding: 0.25rem 1.1rem 0.25rem 0.4rem;
  font: inherit;
  border: 1px solid var(--color-rule);
  background: var(--color-bg);
  color: var(--color-text);
  box-sizing: border-box;
}
.cadence-matrix-cell:focus-visible {
  outline: 2px solid var(--color-oxblood);
  outline-offset: 1px;
}
@media (pointer: coarse), (max-width: 720px) {
  .cadence-matrix-cell { min-height: 44px; font-size: 16px; }
}

/* ==================================== BRIEFS: PROPOSALS ============= */

.proposal-meta {
  background: var(--color-bg);
  border: 1px solid var(--color-rule);
  border-radius: 2px;
  padding: 1rem 1.2rem;
  margin: 1rem 0 1.5rem;
}
.proposal-meta p { margin: 0 0 0.5rem; }
.proposal-meta p:last-child { margin: 0; }

.proposal-actions {
  background: var(--color-bg-tint);
  border: 1px solid var(--color-rule);
  border-radius: 2px;
  padding: 1rem 1.2rem;
  margin: 1.5rem 0;
}
.proposal-actions h2 {
  font-family: var(--font-mono);
  font-size: var(--type-eyebrow);
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--color-oxblood);
  margin: 0 0 0.75rem;
}
.proposal-actions form.inline { margin: 0 0 0.6rem; align-items: stretch; }
.proposal-actions form.inline:last-of-type { margin-bottom: 0.75rem; }

.diff-table { width: 100%; }
.diff-table tbody td:first-child {
  font-family: var(--font-mono);
  font-size: var(--type-small);
  color: var(--color-muted);
  width: 25%;
  white-space: nowrap;
}
.diff-table tbody td code {
  background: var(--color-bg-tint);
  padding: 0.1em 0.4em;
}
.diff-added,
.diff-removed {
  font-family: var(--font-mono);
  font-size: var(--type-small);
  padding: 0.35rem 0.55rem;
  margin: 0.15rem 0;
  border-radius: 2px;
  white-space: pre-wrap;
  word-break: break-word;
}
.diff-added {
  background: var(--color-status-ok-bg);
  color: var(--color-status-ok-fg);
}
.diff-removed {
  background: var(--color-status-fail-bg);
  color: var(--color-status-fail-fg);
}
pre.diff-added,
pre.diff-removed { line-height: 1.45; max-height: 240px; overflow: auto; }


/* ============================================================ PROMO == */
/* Public homepage at "/". Marketing-density (looser than app surfaces),
 * mirrors the apex sef-marketing visual language: eyebrow + serif display
 * + oxblood foot rule + subhead + CTA, three-pillar row with vertical
 * hairlines, numbered capabilities, tinted Phase 0 status band.
 */

.promo-canvas {
  width: 100%;
  max-width: var(--container-max);
  margin: 0 auto;
  padding-inline: var(--gutter);
}

.promo-hero {
  padding-block: clamp(3.5rem, 10vh, 6rem) clamp(2.5rem, 7vh, 4.5rem);
}
.promo-hero-canvas {
  width: 100%;
  max-width: var(--container-max);
  margin: 0 auto;
  padding-inline: var(--gutter);
}
.promo-eyebrow {
  margin-bottom: clamp(2rem, 5vh, 3rem);
}
.promo-headline {
  font-family: var(--font-serif);
  font-weight: 500;
  font-size: var(--type-display);
  line-height: 1.05;
  letter-spacing: -0.02em;
  margin: 0 0 clamp(2.5rem, 7vh, 4rem);
  max-width: 22ch;
}
.promo-foot {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: clamp(1.5rem, 4vw, 3rem);
  align-items: end;
  padding-top: 1.4rem;
  border-top: 2px solid var(--color-oxblood);
}
.promo-subhead {
  font-family: var(--font-serif);
  font-size: var(--type-lead);
  line-height: 1.5;
  color: var(--color-text);
  margin: 0;
  max-width: 48ch;
}
.promo-cta {
  margin: 0;
  justify-self: end;
}
@media (max-width: 720px) {
  .promo-foot {
    grid-template-columns: 1fr;
    align-items: start;
  }
  .promo-cta { justify-self: start; }
}

.promo-pillar {
  padding-block: clamp(3rem, 8vh, 5rem);
  border-block: 1px solid var(--color-rule);
}
.promo-pillar-eyebrow {
  text-align: center;
  display: block;
  margin-bottom: clamp(1.75rem, 4vh, 2.5rem);
}
.promo-pillar-row {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  align-items: center;
  text-align: center;
}
.promo-pillar-item {
  font-family: var(--font-serif);
  font-weight: 500;
  font-size: clamp(1.4rem, 2.6vw, 1.9rem);
  line-height: 1.15;
  padding: 0 clamp(0.5rem, 2vw, 1.5rem);
  position: relative;
}
.promo-pillar-item + .promo-pillar-item::before {
  content: "";
  position: absolute;
  left: 0;
  top: 12%;
  bottom: 12%;
  width: 1px;
  background: var(--color-rule-strong);
}
.promo-pillar-coda {
  font-family: var(--font-serif);
  font-style: italic;
  font-size: var(--type-lead);
  color: var(--color-muted);
  text-align: center;
  margin: clamp(1.75rem, 4vh, 2.5rem) auto 0;
}
@media (max-width: 720px) {
  .promo-pillar-row { grid-template-columns: 1fr; gap: 1.25rem; }
  .promo-pillar-item + .promo-pillar-item::before { display: none; }
}

.promo-section {
  padding-block: clamp(3.5rem, 9vh, 5.5rem);
}
.promo-section-head {
  max-width: 60ch;
  margin-bottom: clamp(2rem, 5vh, 3rem);
}
.promo-section-head h2 {
  font-family: var(--font-serif);
  font-weight: 500;
  font-size: var(--type-h2);
  line-height: 1.15;
  letter-spacing: -0.01em;
  margin: 0.6rem 0 0.9rem;
}
.promo-section-deck {
  color: var(--color-muted);
  margin: 0;
}

.promo-capabilities {
  list-style: none;
  padding: 0;
  margin: 0;
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: clamp(1.25rem, 3vw, 2rem) clamp(1.5rem, 4vw, 3rem);
}
@media (max-width: 720px) {
  .promo-capabilities { grid-template-columns: 1fr; }
}
.promo-capability {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 1rem;
  padding-top: 1.1rem;
  border-top: 1px solid var(--color-rule);
}
.promo-capability-num {
  font-family: var(--font-mono);
  font-size: var(--type-eyebrow);
  font-weight: 500;
  letter-spacing: 0.16em;
  color: var(--color-oxblood);
  padding-top: 0.4rem;
}
.promo-capability-body h3 {
  font-family: var(--font-serif);
  font-weight: 500;
  font-size: var(--type-h3);
  line-height: 1.25;
  margin: 0 0 0.4rem;
}
.promo-capability-body p {
  margin: 0;
  color: var(--color-muted);
  line-height: 1.55;
}

.promo-status {
  background: var(--color-bg-tint);
  padding-block: clamp(3rem, 7vh, 4.5rem);
  border-top: 1px solid var(--color-rule);
}
.promo-section-tight {
  max-width: var(--container-max);
}
.promo-status-grid {
  display: grid;
  grid-template-columns: minmax(180px, 1fr) 3fr;
  gap: clamp(1.5rem, 4vw, 3rem);
  align-items: start;
}
@media (max-width: 720px) {
  .promo-status-grid { grid-template-columns: 1fr; }
}
.promo-status-label {
  font-family: var(--font-mono);
  font-size: var(--type-eyebrow);
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--color-muted);
  margin: 0;
  padding-top: 0.3rem;
}
.promo-status-body p {
  margin: 0 0 0.9rem;
  color: var(--color-text);
  line-height: 1.6;
  max-width: 60ch;
}
.promo-status-body p:last-child { margin-bottom: 0; }
.promo-status-body a {
  color: var(--color-oxblood);
  text-decoration: underline;
  text-underline-offset: 3px;
  text-decoration-thickness: 1px;
}
.promo-status-body a:hover { color: var(--color-oxblood-hover); }


/* "What makes this different" section. 2x2 grid of differentiator tiles
 * (screenshot on top, functional benefit + movement benefit beneath).
 * Sits between `02 / What you get` and the `Where we are` status band on
 * the Studio / Outreach / Events public homepages. Mobile collapses to
 * a single column at the project breakpoint (720px). */
.promo-diff-grid {
  list-style: none;
  padding: 0;
  margin: 0;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(1.5rem, 3.5vw, 2.5rem);
  counter-reset: promo-diff-counter;
}
@media (max-width: 720px) {
  .promo-diff-grid { grid-template-columns: 1fr; }
}
.promo-diff-tile {
  display: flex;
  flex-direction: column;
  background: var(--color-bg);
  border: 1px solid var(--color-rule);
  border-radius: 2px;
  overflow: hidden;
  transition: border-color var(--transition-fast), transform var(--transition-fast);
}
.promo-diff-tile:hover { border-color: var(--color-rule-strong); }
.promo-diff-shot {
  margin: 0;
  aspect-ratio: 16 / 10;
  background: var(--color-bg-tint);
  border-bottom: 1px solid var(--color-rule);
  overflow: hidden;
}
.promo-diff-shot img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: top left;
  display: block;
}
.promo-diff-body {
  padding: clamp(1rem, 2.5vw, 1.5rem) clamp(1.1rem, 2.5vw, 1.6rem) clamp(1.2rem, 2.8vw, 1.6rem);
  display: flex;
  flex-direction: column;
  gap: 0.55rem;
}
.promo-diff-body h3 {
  font-family: var(--font-serif);
  font-weight: 500;
  font-size: var(--type-h3);
  line-height: 1.25;
  letter-spacing: -0.01em;
  margin: 0;
  color: var(--color-text);
}
.promo-diff-fn {
  margin: 0;
  color: var(--color-text);
  line-height: 1.55;
}
.promo-diff-mvt {
  margin: 0;
  color: var(--color-muted);
  line-height: 1.55;
  font-size: var(--type-small);
}
.promo-diff-mvt .kicker {
  font-family: var(--font-mono);
  font-size: var(--type-eyebrow);
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--color-oxblood);
  margin-right: 0.45rem;
}


/* ===================================================== TEAM (B.1) ==== */

.page-header {
  margin-bottom: clamp(1.5rem, 3vh, 2.25rem);
}
.page-header h1 {
  font-family: var(--font-serif);
  font-size: clamp(1.75rem, 3.4vw, 2.4rem);
  font-weight: 500;
  line-height: 1.05;
  letter-spacing: -0.02em;
  margin: 0 0 0.4rem;
}

.team-section { margin-block: 2rem; }
.team-section-heading {
  font-family: var(--font-mono);
  font-size: var(--type-eyebrow);
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--color-muted);
  margin: 0 0 0.75rem;
  display: flex;
  align-items: center;
  gap: 0.6rem;
}
.team-count {
  font-family: var(--font-mono);
  font-size: var(--type-eyebrow);
  background: var(--color-bg-tint);
  color: var(--color-text);
  padding: 0.1rem 0.5rem;
  border-radius: 999px;
  letter-spacing: 0.1em;
}

.team-list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: grid;
  gap: 0.5rem;
}
.team-row {
  display: grid;
  grid-template-columns: 1fr auto auto;
  align-items: center;
  gap: 1rem;
  padding: 0.85rem 1rem;
  background: var(--color-bg);
  border: 1px solid var(--color-rule);
  border-radius: 2px;
}
.team-row-inactive { opacity: 0.55; }
.team-row-invite { border-style: dashed; }
.team-row-identity {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  min-width: 0;
}
.team-row-name {
  font-weight: 500;
  font-size: 1rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.team-row-email {
  font-family: var(--font-mono);
  font-size: var(--type-small);
  color: var(--color-muted);
}
.team-row-meta { white-space: nowrap; }

.team-role-pill {
  font-family: var(--font-mono);
  font-size: var(--type-eyebrow);
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  padding: 0.25rem 0.6rem;
  border-radius: 2px;
  white-space: nowrap;
}
.team-role-owner       { background: var(--color-oxblood); color: var(--color-bg); }
.team-role-manager     { background: var(--color-bg-tint); color: var(--color-oxblood); border: 1px solid var(--color-oxblood); }
.team-role-editor      { background: var(--color-bg-tint); color: var(--color-text); }
.team-role-contributor { background: var(--color-bg-tint); color: var(--color-muted); }
.team-role-viewer      { background: transparent; color: var(--color-muted); border: 1px solid var(--color-rule); }

.empty-state {
  padding: 1.5rem;
  text-align: center;
  border: 1px dashed var(--color-rule);
  border-radius: 2px;
  color: var(--color-muted);
}

/* Mobile: rows stack so the role pill doesn't crush the email column. */
@media (max-width: 600px) {
  .team-row {
    grid-template-columns: 1fr auto;
    grid-template-areas:
      "identity role"
      "meta meta";
    gap: 0.5rem 0.85rem;
  }
  .team-row-identity { grid-area: identity; }
  .team-role-pill   { grid-area: role; }
  .team-row-meta    { grid-area: meta; }
}

/* Team invite form (B.2) */
.team-invite-section {
  background: var(--color-bg-tint);
  padding: 1.25rem;
  border-radius: 2px;
  border: 1px solid var(--color-rule);
}
.team-invite-form {
  display: grid;
  grid-template-columns: 1fr 200px auto;
  gap: 0.85rem;
  align-items: end;
}
.team-invite-field {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
}
.team-invite-field input,
.team-invite-field select {
  /* iOS Safari auto-zooms below 16px; keep explicit. */
  font-size: 16px;
  padding: 0.55rem 0.7rem;
  background: var(--color-bg);
  border: 1px solid var(--color-rule);
  border-radius: 2px;
  font-family: inherit;
}
.team-invite-actions { display: flex; }
.team-invite-section .muted.small { margin-top: 0.6rem; }

@media (max-width: 600px) {
  .team-invite-form {
    grid-template-columns: 1fr;
  }
}

/* Per-app role matrix (invite + create forms, and the per-member
 * "Edit access" panel). One row per SEF app: app name + role select.
 * The fieldset spans the full form width so the email field and the
 * submit button keep their own grid cells. */
.team-app-matrix {
  grid-column: 1 / -1;
  border: 1px solid var(--color-rule);
  border-radius: 2px;
  padding: 0.85rem;
  margin: 0;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 0.6rem 0.85rem;
}
.team-app-matrix legend {
  padding-inline: 0.25rem;
}
.team-app-row {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
}
.team-app-name {
  font-family: var(--font-mono);
  font-size: var(--type-eyebrow);
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--color-muted);
}
.team-app-row select {
  font-size: 16px; /* iOS Safari no-zoom floor */
  min-height: 44px;
  padding: 0.45rem 0.6rem;
  background: var(--color-bg);
  border: 1px solid var(--color-rule);
  border-radius: 2px;
  font-family: inherit;
}
.team-app-row select:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

/* Per-app badges on the member roster (read-only summary). */
.team-app-badges {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem;
  align-items: center;
}

/* Per-member "Edit access" disclosure. */
.team-app-editor {
  grid-column: 1 / -1;
  width: 100%;
}
.team-app-editor summary {
  list-style: none;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.team-app-editor summary::-webkit-details-marker { display: none; }
.team-app-editor summary::marker { content: ""; }
.team-app-editor[open] > form {
  margin-top: 0.6rem;
}

/* Team row inline actions (B.3) */
.team-row {
  /* Re-grid to accommodate optional role-picker + actions columns. */
  grid-template-columns: 1fr auto auto auto;
}
.team-row-rolepicker { margin: 0; }
.team-row-rolepicker select {
  font-family: var(--font-mono);
  font-size: var(--type-eyebrow);
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  background: var(--color-bg);
  color: var(--color-text);
  border: 1px solid var(--color-rule);
  padding: 0.25rem 0.5rem;
  border-radius: 2px;
}
.team-row-actions {
  display: inline-flex;
  gap: 0.85rem;
  white-space: nowrap;
}
.team-action-link {
  font-family: var(--font-mono);
  font-size: var(--type-eyebrow);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--color-muted);
  background: transparent;
  border: 0;
  padding: 0;
  cursor: pointer;
}
.team-action-link:hover { color: var(--color-oxblood); }
.team-action-danger:hover { color: var(--color-error); }

@media (max-width: 600px) {
  .team-row {
    grid-template-columns: 1fr auto;
    grid-template-areas:
      "identity role"
      "meta meta"
      "actions actions";
  }
  .team-row-identity   { grid-area: identity; }
  .team-row-rolepicker { grid-area: role; }
  .team-role-pill      { grid-area: role; }
  .team-row-meta       { grid-area: meta; }
  .team-row-actions    { grid-area: actions; justify-content: flex-end; }
}

/* ====================================================== PLATFORMS (B.4) === */

.platform-grid {
  display: grid;
  gap: 1rem;
  grid-template-columns: 1fr 1fr;
}
@media (max-width: 720px) {
  .platform-grid { grid-template-columns: 1fr; }
}
.platform-card {
  background: var(--color-bg);
  border: 1px solid var(--color-rule);
  border-radius: 2px;
  padding: 1.25rem;
  display: flex;
  flex-direction: column;
  gap: 0.85rem;
}
.platform-card--status-connected { border-left: 3px solid var(--color-status-ok-fg); }
.platform-card--status-disconnected,
.platform-card--status-disabled,
.platform-card--status-no-credential {
  border-left: 3px solid var(--color-status-warn-fg);
}
.platform-card--status-unconnected {
  border-left: 3px dashed var(--color-rule-strong);
  background: var(--color-bg-tint);
}

.platform-card-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  flex-wrap: wrap;
}
.platform-status {
  font-family: var(--font-mono);
  font-size: var(--type-eyebrow);
  letter-spacing: 0.14em;
  text-transform: uppercase;
}
.platform-status--connected     { color: var(--color-status-ok-fg); }
.platform-status--disconnected,
.platform-status--disabled,
.platform-status--no-credential { color: var(--color-status-warn-fg); }
.platform-status--unconnected   { color: var(--color-muted); }

.platform-card-body {
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: 0.4rem 1rem;
  margin: 0;
}
.platform-card-body dt {
  font-family: var(--font-mono);
  font-size: var(--type-eyebrow);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--color-muted);
}
.platform-card-body dd {
  margin: 0;
  font-size: 0.95rem;
}
.platform-card-foot {
  margin-top: 0.4rem;
  padding-top: 0.85rem;
  border-top: 1px dashed var(--color-rule);
}

@media (max-width: 600px) {
  .platform-card-body {
    grid-template-columns: 1fr;
    gap: 0.15rem;
  }
  .platform-card-body dd { margin-bottom: 0.5rem; }
}

/* Platform actions panel (B.5) */
.platform-card-actions {
  margin-top: 0.5rem;
  border-top: 1px solid var(--color-rule);
  padding-top: 0.85rem;
}
.platform-card-actions > summary {
  list-style: none;
  cursor: pointer;
  font-family: var(--font-mono);
  font-size: var(--type-eyebrow);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--color-muted);
  padding: 0.25rem 0;
}
.platform-card-actions > summary:hover { color: var(--color-oxblood); }
.platform-card-actions > summary::-webkit-details-marker { display: none; }
.platform-card-actions > summary::marker { content: ""; }

.platform-actions-panel {
  display: flex;
  flex-direction: column;
  gap: 0.85rem;
  padding-top: 0.85rem;
}
.platform-form {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.75rem;
  align-items: end;
}
.platform-form > .muted.small,
.platform-form > p {
  grid-column: 1 / -1;
  margin: 0;
}
.platform-field {
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
}
.platform-field input,
.platform-field select {
  font-size: 16px;
  padding: 0.5rem 0.65rem;
  background: var(--color-bg);
  border: 1px solid var(--color-rule);
  border-radius: 2px;
}
.platform-form-actions {
  grid-column: 1 / -1;
  display: flex;
  gap: 0.5rem;
}
.platform-rotate { margin: 0; }
.platform-rotate > summary {
  cursor: pointer;
  padding: 0.4rem 0;
  list-style: none;
}
.platform-rotate > summary::-webkit-details-marker { display: none; }
.platform-rotate > summary::marker { content: ""; }
.platform-rotate[open] > summary { color: var(--color-oxblood); }
.platform-rotate .platform-form { margin-top: 0.5rem; }

@media (max-width: 600px) {
  .platform-form { grid-template-columns: 1fr; }
}

/* Sources page (B.6) */
.source-form {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.75rem;
  align-items: end;
}
.source-form .source-field-url { grid-column: 1 / -1; }
.source-form .source-field-checkbox {
  grid-column: 1 / -1;
  display: flex;
  flex-direction: row;
  gap: 0.5rem;
  align-items: center;
  margin-top: 0.5rem;
}
.source-form input,
.source-form select {
  font-size: 16px;
  padding: 0.5rem 0.65rem;
  background: var(--color-bg);
  border: 1px solid var(--color-rule);
  border-radius: 2px;
}
.source-row .team-row-name a { color: inherit; text-decoration: none; }
.source-row .team-row-name a:hover { color: var(--color-oxblood); }
.source-test-sample {
  margin: 0.6rem 0 0;
  padding-left: 1.25rem;
  font-size: 0.9rem;
}
.source-aside { margin-top: 1.5rem; }

/* Source kind pills reuse the team role pill base styles */
.team-role-rss      { background: var(--color-bg-tint); color: var(--color-text); }
.team-role-json_api { background: var(--color-bg-tint); color: var(--color-oxblood); border: 1px solid var(--color-oxblood); }
.team-role-manual   { background: transparent; color: var(--color-muted); border: 1px solid var(--color-rule); }

@media (max-width: 600px) {
  .source-form { grid-template-columns: 1fr; }
}

/* ============================================================ BRIEF (C.1) === */

.brief-subnav {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 1.25rem;
  border-bottom: 1px solid var(--color-rule);
  margin: 0 0 1.75rem;
  padding-bottom: 0.6rem;
}
.brief-subnav-link {
  font-family: var(--font-mono);
  font-size: var(--type-eyebrow);
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--color-muted);
  text-decoration: none;
  padding-bottom: 0.4rem;
  border-bottom: 2px solid transparent;
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
}
.brief-subnav-link:hover { color: var(--color-oxblood); }
.brief-subnav-link--active {
  color: var(--color-oxblood);
  border-bottom-color: var(--color-oxblood);
}
.brief-subnav-count {
  background: var(--color-status-warn-bg);
  color: var(--color-status-warn-fg);
  padding: 0.1rem 0.45rem;
  border-radius: 999px;
  font-size: 0.78em;
  letter-spacing: 0.08em;
}

.brief-sections {
  display: grid;
  gap: 1.5rem;
}
.brief-section {
  background: var(--color-bg);
  border: 1px solid var(--color-rule);
  border-radius: 2px;
  overflow: hidden;
}
.brief-section-head {
  background: var(--color-bg-tint);
  border-bottom: 1px solid var(--color-rule);
  padding: 0.6rem 1rem 0.6rem 1.25rem;
}
.brief-section.is-collapsed .brief-section-head {
  border-bottom: none;
}
.brief-section.is-collapsed .brief-section-body {
  display: none;
}
.brief-section-head h2 {
  font-family: var(--font-serif);
  font-size: 1rem;
  font-weight: 600;
  margin: 0;
  letter-spacing: -0.01em;
}
.brief-section-blurb {
  font-size: var(--type-eyebrow);
  color: var(--color-muted);
  flex: 1;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  min-width: 0;
  margin-left: 0.75rem;
  align-self: center;
}
.brief-section-titlerow {
  display: flex;
  align-items: center;
  gap: 0;
}
.brief-section-actions {
  display: inline-flex;
  gap: 0.75rem;
  align-items: center;
  flex-shrink: 0;
}
.brief-section-link {
  font-family: var(--font-mono);
  font-size: var(--type-eyebrow);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--color-muted);
  text-decoration: none;
  padding: 0.15rem 0.5rem;
  border: 1px solid var(--color-rule);
  border-radius: 2px;
  background: white;
}
.brief-section-link:hover { color: var(--color-oxblood); }
.brief-section-link--owner { color: var(--color-oxblood); border-color: var(--color-oxblood); }
.brief-section-toggle {
  background: none;
  border: 1px solid var(--color-rule);
  border-radius: 2px;
  padding: 0.1rem 0.4rem;
  cursor: pointer;
  color: var(--color-muted);
  font-size: var(--type-eyebrow);
  line-height: 1.4;
}
.brief-section-toggle:hover { color: var(--color-oxblood); border-color: var(--color-oxblood); }
.brief-section-body {
  padding: 1rem 1.25rem 1.25rem;
  margin: 0;
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: 0.6rem 1.25rem;
}
.brief-section-body dt {
  font-family: var(--font-mono);
  font-size: var(--type-eyebrow);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--color-muted);
  padding-top: 0.15rem;
}
.brief-section-body dd { margin: 0; }
.brief-section-body p { margin: 0; }
.brief-list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 0.3rem;
  font-size: 0.95rem;
}
.brief-list li {
  background: var(--color-bg-tint);
  border: 1px solid var(--color-rule);
  border-radius: 2px;
  padding: 0.15rem 0.5rem;
  font-size: 0.875rem;
}
ol.brief-list {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  list-style: decimal inside;
}
ol.brief-list li {
  background: none;
  border: none;
  padding: 0;
  font-size: 0.875rem;
}
.brief-topic-category-title {
  font-size: 0.85rem;
  font-weight: 600;
  margin-bottom: 0.3rem;
}
.brief-kv {
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: 0.2rem 1rem;
  margin: 0;
  font-family: var(--font-mono);
  font-size: var(--type-small);
}
.brief-kv dt { color: var(--color-muted); text-transform: none; letter-spacing: 0; }
.brief-kv dd { color: var(--color-text); }
.brief-json {
  margin: 0;
  font-family: var(--font-mono);
  font-size: var(--type-small);
  background: var(--color-bg-tint);
  border: 1px solid var(--color-rule);
  border-radius: 2px;
  padding: 0.6rem 0.8rem;
  white-space: pre-wrap;
  word-break: break-word;
}
.brief-stance {
  font-family: var(--font-mono);
  font-size: var(--type-eyebrow);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  padding: 0.05rem 0.4rem;
  border-radius: 2px;
}
.brief-stance--advocate { background: var(--color-status-ok-bg); color: var(--color-status-ok-fg); }
.brief-stance--differ   { background: var(--color-status-warn-bg); color: var(--color-status-warn-fg); }
.brief-stance--neutral  { background: var(--color-bg-tint); color: var(--color-muted); }

@media (max-width: 720px) {
  .brief-section-body { grid-template-columns: 1fr; gap: 0.2rem; }
  .brief-section-body dt { padding-top: 0.5rem; }
}

/* Brief per-section propose/edit links, form, and accordion (C.2) */

.brief-section-form {
  display: grid;
  gap: 1.25rem;
  max-width: min(100%, 1080px);
}
.brief-form-field { display: grid; gap: 0.4rem; }
.brief-form-field-row { display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; }
.brief-form-label {
  font-family: var(--font-mono);
  font-size: var(--type-eyebrow);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--color-muted);
  display: block;
  margin-bottom: 0.3rem;
}
.brief-form-field input,
.brief-form-field select,
.brief-form-field textarea {
  font-size: 16px;
  padding: 0.55rem 0.7rem;
  background: var(--color-bg);
  border: 1px solid var(--color-rule);
  border-radius: 2px;
  font-family: inherit;
  width: 100%;
  box-sizing: border-box;
}
/* Checkboxes shouldn't stretch to full width — they're a fixed-size control. */
.brief-form-field input[type="checkbox"] { width: auto; }
.brief-form-field textarea { resize: vertical; min-height: 5.5rem; }
.brief-form-field--text textarea { min-height: 6.5rem; }
.brief-form-json { font-family: var(--font-mono); font-size: 0.9rem; min-height: 9rem; }

/* Subfield groupings (used inside hashtag_library, etc.). Visually
   separates the three sub-blocks so the section doesn't read as a wall
   of inputs. */
.brief-subfield {
  display: grid;
  gap: 0.4rem;
  padding: 0.75rem 0.9rem;
  background: var(--color-bg);
  border: 1px solid var(--color-rule);
  border-radius: 2px;
}
.brief-subfield + .brief-subfield { margin-top: 0.6rem; }
.brief-subfield-label {
  font-family: var(--font-mono);
  font-size: var(--type-eyebrow);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--color-muted);
}
.brief-platform-table { width: 100%; border-collapse: collapse; }
.brief-platform-table th,
.brief-platform-table td { padding: 0.25rem 0.4rem; vertical-align: middle; }
.brief-platform-table th:first-child { width: 110px; text-align: left; }
.brief-platform-table input,
.brief-platform-table select { width: 100%; box-sizing: border-box; }

/* Campaign overlay form: keep key controls full-width so long guidance
   lines are editable without horizontal clipping / cramped input boxes. */
.overlay-form .overlay-input--full {
  width: 100%;
  box-sizing: border-box;
}
.overlay-form .overlay-style-overrides {
  width: 100%;
}
.overlay-form .overlay-style-overrides .brief-row {
  display: grid;
  grid-template-columns: auto 1fr 170px;
  gap: 0.55rem;
  align-items: start;
}
.overlay-form .overlay-style-overrides .brief-row > p {
  grid-column: 1 / -1;
  margin: 0;
}
@media (max-width: 720px) {
  .overlay-form .overlay-style-overrides .brief-row {
    grid-template-columns: 1fr;
  }
}

.brief-rows {
  display: grid;
  gap: 0.5rem;
}
.brief-row {
  display: grid;
  gap: 0.5rem;
  align-items: center;
}
/* All row widgets reserve a fixed-width trailing column for the
   per-row Remove button (data-remove-row). The column shrinks away
   on narrow viewports via the media query at the foot of this block. */
.brief-rows-list .brief-row     { grid-template-columns: 1fr 36px; }
.brief-rows-topics .brief-row   { grid-template-columns: 1fr 90px 36px; }
.brief-rows-positions .brief-row { grid-template-columns: 1fr 130px 1fr 36px; }
.brief-rows-phrases .brief-row  { grid-template-columns: 1fr 90px 36px; }
.brief-rows-weighted .brief-row { grid-template-columns: 1fr 110px 36px; }
.brief-rows-hashtag-groups .brief-row { grid-template-columns: 200px 1fr 36px; }
/* Categorised topics widget: each category is a <fieldset> whose
   header carries the category metadata (name, fires-N-times weight,
   hashtags CSV) and whose body nests the topic rows. Visual hierarchy
   is the load-bearing UX choice here — the category name reads as a
   heading-style input, the header sits in a tinted band, and the
   topics nest below an eyebrow label so the parent / child
   relationship is obvious at a glance. */
.brief-categories { display: grid; gap: 1.25rem; }
.brief-category {
  border: 1px solid var(--color-rule);
  border-left: 3px solid var(--color-oxblood);
  border-radius: 2px;
  padding: 0;
  margin: 0;
  background: var(--color-bg);
}
.brief-category-header {
  display: grid;
  grid-template-columns: 1.4fr 110px 1fr 36px;
  gap: 0.75rem;
  align-items: end;
  background: var(--color-bg-tint);
  padding: 0.75rem 0.9rem;
  border-bottom: 1px solid var(--color-rule);
}
.brief-category-name-field,
.brief-category-hashtags-field,
.brief-weight-field {
  display: grid;
  gap: 0.25rem;
  margin: 0;
}
.brief-field-eyebrow {
  font-family: var(--font-mono);
  font-size: var(--type-eyebrow);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--color-muted);
}
.brief-category-name {
  font-family: var(--font-serif) !important;
  font-size: 1.2rem !important;
  font-weight: 500 !important;
  background: transparent !important;
  border: 0 !important;
  border-bottom: 1px dashed var(--color-rule-strong) !important;
  border-radius: 0 !important;
  padding: 0.35rem 0.2rem !important;
}
.brief-category-name:focus {
  border-bottom-color: var(--color-oxblood) !important;
  outline: none;
}
/* Weight input + suffix multiplier symbol packed into one visual
   chip so the "×" reads as part of the value. The input keeps its
   number-spinner; the suffix sits to its right. */
.brief-weight-input {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
}
.brief-weight-input input[type="number"] {
  text-align: right;
}
.brief-weight-field .brief-weight-input input[type="number"] {
  width: 100%;
}
.brief-weight-suffix {
  font-family: var(--font-mono);
  color: var(--color-muted);
  font-size: 1rem;
}
.brief-category-remove {
  align-self: end;
}
.brief-category-body {
  padding: 0.75rem 0.9rem 0.9rem;
}
.brief-category-topics-eyebrow {
  font-family: var(--font-mono);
  font-size: var(--type-eyebrow);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--color-muted);
  margin: 0 0 0.6rem;
}
.brief-category-topics-eyebrow .muted {
  text-transform: none;
  letter-spacing: 0;
  font-size: 0.78rem;
}
.brief-rows-cat-topics .brief-row {
  grid-template-columns: 1fr 80px 1fr 36px;
  align-items: center;
}
.brief-weight-input--topic {
  width: 80px;
}
.brief-weight-input--topic input[type="number"] {
  width: 100%;
}

.brief-topics-switch { margin-top: 0.6rem; }
.brief-topics-power {
  margin-top: 1rem;
  border: 1px dashed var(--color-rule);
  border-radius: 2px;
  padding: 0.6rem 0.8rem;
}
.brief-topics-power > summary {
  font-family: var(--font-mono);
  font-size: var(--type-eyebrow);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  cursor: pointer;
  color: var(--color-muted);
}
.brief-topics-power textarea {
  width: 100%;
  margin-top: 0.5rem;
}
.brief-topic-category {
  margin: 0.4rem 0 0.75rem;
  padding-left: 0.5rem;
  border-left: 2px solid var(--color-rule);
}
.brief-topic-category-title {
  font-family: var(--font-serif);
  font-size: 1rem;
  font-weight: 500;
  margin: 0 0 0.25rem;
}

/* Add-row button: subtle, full-width-ish, sits below the rows. */
.row-add {
  margin-top: 0.4rem;
  padding: 0.45rem 0.9rem;
  font-family: var(--font-mono);
  font-size: var(--type-eyebrow);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  background: transparent;
  border: 1px dashed var(--color-rule);
  color: var(--color-muted);
  cursor: pointer;
  border-radius: 2px;
  justify-self: start;
}
.row-add:hover,
.row-add:focus-visible {
  border-style: solid;
  border-color: var(--color-oxblood);
  color: var(--color-oxblood);
}

/* Per-row remove button. Square, low-emphasis, becomes oxblood on
   hover. The aria-label tells AT what the × means. */
.row-remove {
  width: 32px;
  height: 32px;
  padding: 0;
  background: transparent;
  border: 1px solid var(--color-rule);
  color: var(--color-muted);
  cursor: pointer;
  border-radius: 2px;
  font-size: 1.1rem;
  line-height: 1;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.row-remove:hover,
.row-remove:focus-visible {
  border-color: var(--color-oxblood);
  color: var(--color-oxblood);
}

@media (max-width: 600px) {
  /* On phone-width, collapse multi-column rows to single column and
     let the remove button sit on its own line. The Apple HIG 44px
     min-height is honoured by the .row-remove sizing. */
  .brief-rows-list .brief-row,
  .brief-rows-topics .brief-row,
  .brief-rows-positions .brief-row,
  .brief-rows-phrases .brief-row,
  .brief-rows-weighted .brief-row,
  .brief-rows-hashtag-groups .brief-row,
  .brief-row--category-meta,
  .brief-rows-cat-topics .brief-row,
  .brief-category-header {
    grid-template-columns: 1fr;
  }
  .row-remove { justify-self: end; }
}

/* Onboarding wizard topic + position rows. Without an explicit width
   the browser sizes columns to placeholder content, clipping topic
   strings like "EU fiscal rules and exception...". */
.rows-table {
  width: 100%;
  border-collapse: collapse;
}
.rows-table th {
  text-align: left;
  font-weight: 500;
  padding: 0 0.5rem 0.25rem 0;
}
.rows-table td {
  padding: 0.15rem 0.5rem 0.15rem 0;
  vertical-align: middle;
}
.rows-table td:last-child,
.rows-table th:last-child { padding-right: 0; }
.rows-table input[type="text"],
.rows-table input[type="number"],
.rows-table select {
  width: 100%;
  box-sizing: border-box;
}

/* Owner direct-edit link (C.3) */
.brief-section-link--owner {
  color: var(--color-oxblood);
}

/* ====================================================== VERSION HISTORY (C.4) === */

.version-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 0.5rem;
}
.version-row {
  background: var(--color-bg);
  border: 1px solid var(--color-rule);
  border-radius: 2px;
  padding: 0.85rem 1rem;
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 1rem;
  align-items: center;
}
.version-row--current { border-left: 3px solid var(--color-oxblood); }
.version-row-identity { display: grid; gap: 0.25rem; }
.version-row-id {
  font-family: var(--font-mono);
  font-size: var(--type-eyebrow);
  letter-spacing: 0.12em;
  color: var(--color-muted);
}
.version-row-link {
  font-weight: 500;
  color: var(--color-text);
  text-decoration: none;
}
.version-row-link:hover { color: var(--color-oxblood); }

.version-rollback-form { margin: 1rem 0 0; }

.version-diff { display: grid; gap: 1.25rem; }
.version-diff-section h3 {
  font-family: var(--font-mono);
  font-size: var(--type-eyebrow);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--color-muted);
  margin: 0 0 0.6rem;
}
.version-diff-row {
  border-left: 2px solid var(--color-rule);
  padding: 0.4rem 0.85rem;
  margin-bottom: 0.6rem;
}
.version-diff-row--list { border-left-color: var(--color-rule-strong); }
.version-diff-row--scalar { border-left-color: var(--color-oxblood); }
.version-diff-row--json { border-left-color: var(--color-muted); }

.version-diff-field {
  font-family: var(--font-mono);
  font-size: var(--type-eyebrow);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--color-muted);
  display: block;
  margin-bottom: 0.4rem;
}
.version-diff-list {
  list-style: none;
  padding: 0;
  margin: 0.2rem 0;
  font-family: var(--font-mono);
  font-size: 0.9rem;
}
.version-diff-list--removed li { color: var(--color-error); }
.version-diff-list--added   li { color: var(--color-status-ok-fg); }
.version-diff-side {
  display: block;
  padding: 0.3rem 0;
  font-size: 0.95rem;
}
.version-diff-side--before { color: var(--color-muted); }
.version-diff-json {
  margin: 0.3rem 0;
  background: var(--color-bg-tint);
  border: 1px solid var(--color-rule);
  border-radius: 2px;
  padding: 0.5rem 0.75rem;
  font-size: 0.85rem;
  white-space: pre-wrap;
  word-break: break-word;
}

/* Brief suggestions (C.5) */
.suggestion-row .suggestion-rationale summary {
  cursor: pointer;
  list-style: none;
}
.suggestion-row .suggestion-rationale summary::-webkit-details-marker { display: none; }
.suggestion-row .suggestion-rationale summary::marker { content: ""; }
.suggestion-row .suggestion-rationale[open] summary { color: var(--color-oxblood); }
.suggestion-row .suggestion-rationale p {
  margin: 0.5rem 0 0.4rem;
  font-size: 0.95rem;
}

/* Status pills for suggestions reuse the role-pill base */
.team-role-pending   { background: var(--color-status-warn-bg); color: var(--color-status-warn-fg); }
.team-role-accepted  { background: var(--color-status-ok-bg); color: var(--color-status-ok-fg); }
.team-role-dismissed { background: var(--color-bg-tint); color: var(--color-muted); }

/* ====================================================== QUEUE MOBILE (D.2) === */

/* Card swipe animation */
.card { transition: transform 0.18s ease, box-shadow 0.18s ease; }
.card.card--swiping { transition: none; }
.card.card--swiping-right {
  box-shadow: -4px 0 0 var(--color-status-ok-fg), 0 1px 4px rgba(0,0,0,0.06);
}
.card.card--swiping-left {
  box-shadow: 4px 0 0 var(--color-error), 0 1px 4px rgba(0,0,0,0.06);
}
.card.card--swiping-right::after,
.card.card--swiping-left::after {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  font-family: var(--font-mono);
  font-size: var(--type-eyebrow);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  font-weight: 600;
}
.card { position: relative; }
.card.card--swiping-right::after {
  content: "Approve →";
  left: 1rem;
  color: var(--color-status-ok-fg);
}
.card.card--swiping-left::after {
  content: "← Reject";
  right: 1rem;
  color: var(--color-error);
}

/* Desktop drag-and-drop reorder (Phase D.4). Touch-only surfaces use
 * the swipe gestures + arrow buttons above; desktop layers drag-drop
 * on top of those for power users.
 *
 * IMPORTANT: only the tiny handle is draggable. Making the whole card
 * draggable steals caret placement / text-selection gestures from the
 * textarea in some browsers.
 */
.queue-drag-handle {
  display: none;
  color: var(--color-muted);
  font-size: 0.9rem;
  line-height: 1;
  letter-spacing: -0.15em;
  user-select: none;
}
@media (min-width: 721px) and (pointer: fine) {
  .queue-drag-handle { display: inline-block; cursor: grab; }
  .queue-drag-handle:active { cursor: grabbing; }
}

.card.card--dragging { opacity: 0.55; }
.card.card--drop-target {
  outline: 2px dashed var(--color-oxblood);
  outline-offset: -2px;
}
.card.card--saving { opacity: 0.7; pointer-events: none; }
@media (prefers-reduced-motion: reduce) {
  .card.card--dragging { opacity: 0.7; }
}
@media (max-width: 720px), (pointer: coarse) {
  /* Mobile keeps the arrow buttons + swipe; HTML5 drag is desktop-only. */
  .card.card--dragging { opacity: 1; }
  .card.card--drop-target { outline: none; }
}

/* Sticky bulk-approve bar */
.queue-stickybar {
  display: none;  /* mobile-only; desktop uses the inline header button */
  position: fixed;
  left: 0;
  right: 0;
  bottom: calc(var(--bottom-tab-height) + var(--bottom-tab-clearance) + env(safe-area-inset-bottom, 0));
  z-index: 11;
  background: var(--color-bg);
  border-top: 1px solid var(--color-rule);
  padding: 0.6rem 1rem 0.75rem;
  align-items: center;
  gap: 0.75rem;
  box-shadow: 0 -4px 12px rgba(0, 0, 0, 0.06);
}
.queue-stickybar[data-visible="1"] { display: flex; }
.queue-stickybar-count {
  font-family: var(--font-mono);
  font-size: 1.2rem;
  font-weight: 600;
  color: var(--color-oxblood);
  min-width: 1.5em;
  text-align: center;
}
.queue-stickybar-label {
  flex: 1;
  font-family: var(--font-mono);
  font-size: var(--type-eyebrow);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--color-muted);
}

@media (min-width: 721px) {
  /* Desktop: never show the sticky bar; the header button covers it. */
  .queue-stickybar { display: none !important; }
}

/* Reject reason bottom sheet (<dialog>) */
.reject-sheet {
  /* The browser default is a centred dialog; we anchor to the bottom on
     mobile and centre on desktop. */
  border: 0;
  padding: 0;
  background: transparent;
  max-width: 480px;
  width: 100%;
  margin: auto;
}
.reject-sheet::backdrop { background: rgba(0, 0, 0, 0.4); }
.reject-sheet[open] { display: flex; flex-direction: column; }
.reject-sheet-inner {
  background: var(--color-bg);
  border: 1px solid var(--color-rule);
  border-radius: 4px;
  padding: 1rem 1.25rem 1.5rem;
  width: 100%;
}
.reject-sheet-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 0.6rem;
}
.reject-sheet-title {
  font-family: var(--font-serif);
  font-weight: 500;
  font-size: 1.1rem;
}
.reject-sheet-close {
  background: transparent;
  border: 0;
  font-size: 1.5rem;
  line-height: 1;
  padding: 0.25rem 0.5rem;
  color: var(--color-muted);
  cursor: pointer;
  min-width: 44px;
  min-height: 44px;
}
.reject-sheet-close:hover { color: var(--color-oxblood); }
.reject-sheet-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 0.4rem;
}
.reject-sheet-reason {
  width: 100%;
  text-align: left;
  padding: 0.85rem 1rem;
  min-height: 44px;
  background: var(--color-bg-tint);
  border: 1px solid var(--color-rule);
  border-radius: 2px;
  font: inherit;
  font-size: 16px;
  color: var(--color-text);
  cursor: pointer;
}
.reject-sheet-reason:hover {
  background: var(--color-bg);
  border-color: var(--color-oxblood);
  color: var(--color-oxblood);
}

/* Mobile: anchor the sheet to the bottom edge instead of centring. */
@media (max-width: 720px) {
  .reject-sheet {
    margin: auto auto 0;
    max-width: 100%;
  }
  .reject-sheet-inner {
    border-radius: 8px 8px 0 0;
    padding-bottom: calc(1.5rem + env(safe-area-inset-bottom, 0));
  }
  /* The card-reject-form's inline select is awkward on mobile; the
     swipe / sheet handles it. Hide the inline reason picker but keep
     the form (the JS submits it programmatically). */
  .card-reject-form select { display: none; }
}

/* ====================================================== QUICK-POST FAB (D.3) === */

.queue-fab {
  position: fixed;
  right: clamp(0.85rem, 3vw, 1.25rem);
  bottom: calc(var(--bottom-tab-height) + var(--bottom-tab-clearance) + 8px + env(safe-area-inset-bottom, 0));
  z-index: 11;
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.85rem 1.1rem;
  min-height: 52px;
  background: var(--color-oxblood);
  color: var(--color-bg);
  border: 0;
  border-radius: 9999px;
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.18);
  font-family: var(--font-mono);
  font-size: var(--type-eyebrow);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  cursor: pointer;
}
.queue-fab:hover { background: var(--color-oxblood-hover); }
.queue-fab:focus-visible {
  outline: 2px solid var(--color-text);
  outline-offset: 3px;
}

/* Mobile: hide the label, show only the + icon — tighter footprint
 * above the bottom tab bar. */
@media (max-width: 720px) {
  .queue-fab { padding: 0; width: 56px; height: 56px; justify-content: center; }
  .queue-fab-label { display: none; }
  /* Sit above the sticky bulk bar AND the tab bar. Sticky bar is
   * ~63px tall (44px button + 0.6rem top + 0.75rem bottom padding);
   * add another 8px FAB-above-stickybar gap. */
  .queue-fab {
    bottom: calc(var(--bottom-tab-height) + var(--bottom-tab-clearance) + 63px + 8px + env(safe-area-inset-bottom, 0));
  }
  /* When sticky bar is hidden (data-visible='0'), come back down to
   * 8px above the tab bar. */
  body:has(.queue-stickybar[data-visible="0"]) .queue-fab {
    bottom: calc(var(--bottom-tab-height) + var(--bottom-tab-clearance) + 8px + env(safe-area-inset-bottom, 0));
  }
}

/* ====================================================== GENERATE FAB (Week tab) === */

/* Sister of .queue-fab: a sticky lozenge on the Generate Week tab so the
 * "Generate selected" submit is always visible regardless of scroll
 * position. Submits the in-page #week-form via the HTML5 `form`
 * attribute (no JS-driven submit). Live count + disabled state are
 * managed by a small inline script in _week.html. */
.generate-fab {
  position: fixed;
  right: clamp(0.85rem, 3vw, 1.25rem);
  bottom: calc(72px + env(safe-area-inset-bottom, 0));
  z-index: 11;
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.85rem 1.1rem;
  min-height: 52px;
  background: var(--color-oxblood);
  color: var(--color-bg);
  border: 0;
  border-radius: 9999px;
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.18);
  font-family: var(--font-mono);
  font-size: var(--type-eyebrow);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  cursor: pointer;
}
.generate-fab:hover { background: var(--color-oxblood-hover); }
.generate-fab:focus-visible {
  outline: 2px solid var(--color-text);
  outline-offset: 3px;
}
.generate-fab[disabled] {
  background: var(--color-rule);
  color: var(--color-muted);
  cursor: not-allowed;
  box-shadow: none;
}
.generate-fab-count { font-weight: 700; }

@media (max-width: 720px) {
  .generate-fab { padding: 0; width: 56px; height: 56px; justify-content: center; }
  .generate-fab-label { display: none; }
}
@media print { .generate-fab { display: none; } }

/* Quickpost sheet inherits .reject-sheet base styles; specialise content. */
.quickpost-form { display: flex; flex-direction: column; gap: 0.85rem; }
.quickpost-field { display: flex; flex-direction: column; gap: 0.25rem; }
.quickpost-field select,
.quickpost-field textarea {
  font-size: 16px;
  padding: 0.7rem 0.8rem;
  background: var(--color-bg);
  border: 1px solid var(--color-rule);
  border-radius: 2px;
  font-family: inherit;
  width: 100%;
}
.quickpost-field textarea {
  font-family: var(--font-mono);
  font-size: 15px;
  line-height: 1.5;
  min-height: 7rem;
  resize: vertical;
}
.quickpost-hint {
  margin: 0;
  font-family: var(--font-mono);
  font-size: var(--type-eyebrow);
  letter-spacing: 0.06em;
  color: var(--color-muted);
}
.quickpost-hint .quickpost-over { color: var(--color-error); font-weight: 600; }
.quickpost-actions { justify-content: flex-end; }
.quickpost-actions .btn[disabled] {
  opacity: 0.5;
  cursor: not-allowed;
}

/* ============================================================ CALENDAR (interlude) === */

/* Header strip (page title + tenant timezone). */
.cal-header {
  display: flex;
  align-items: baseline;
  gap: 1rem;
  flex-wrap: wrap;
  margin-bottom: 1rem;
}
.cal-header h1 {
  font-family: var(--font-serif);
  font-size: clamp(1.75rem, 3.4vw, 2.4rem);
  font-weight: 500;
  letter-spacing: -0.02em;
  line-height: 1.1;
  margin: 0;
}
.cal-header-sub {
  font-family: var(--font-mono);
  font-size: var(--type-eyebrow);
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  margin: 0;
}

/* Prev / Today / Next + Week / Month toggle. */
.cal-nav {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  align-items: center;
  margin-bottom: 0.85rem;
}
.cal-nav-spacer { flex: 1 1 auto; min-width: 0.5rem; }
.cal-nav-btn { min-width: 5rem; }
.cal-toggle--active {
  background: var(--color-oxblood);
  color: #fff;
  border-color: var(--color-oxblood);
}

/* Active-filter strip (echoes ?platform=, ?status=, ?overlay=). */
.cal-filters {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  align-items: center;
  font-size: var(--type-small);
  margin-bottom: 0.85rem;
  padding: 0.5rem 0.7rem;
  background: var(--color-bg-tint);
  border: 1px solid var(--color-rule);
  border-radius: 2px;
}
.cal-filters-label {
  font-family: var(--font-mono);
  font-size: var(--type-eyebrow);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--color-muted);
}
.cal-filters-chip {
  background: #fff;
  border: 1px solid var(--color-rule-strong);
  border-radius: 999px;
  padding: 0.2rem 0.7rem;
  font-family: var(--font-mono);
  font-size: var(--type-eyebrow);
}
.cal-filters-clear {
  margin-left: auto;
  font-size: var(--type-eyebrow);
  text-decoration: underline;
  text-underline-offset: 3px;
  color: var(--color-muted);
}
.cal-filters-clear:hover { color: var(--color-oxblood); }

/* Unscheduled rail above the grid. Horizontal-scrolling row of chips. */
.cal-unscheduled {
  margin-bottom: 1rem;
  padding-bottom: 0.5rem;
  border-bottom: 1px solid var(--color-rule);
}
.cal-unscheduled-head {
  display: flex;
  align-items: baseline;
  gap: 0.6rem;
  margin-bottom: 0.4rem;
}
.cal-unscheduled-head h2 {
  font-family: var(--font-serif);
  font-size: 1.05rem;
  font-weight: 500;
  margin: 0;
}
.cal-unscheduled-count {
  font-family: var(--font-mono);
  font-size: var(--type-eyebrow);
  letter-spacing: 0.12em;
  text-transform: uppercase;
}
.cal-unscheduled-rail {
  display: flex;
  gap: 0.4rem;
  overflow-x: auto;
  scroll-snap-type: x proximity;
  padding-bottom: 0.4rem;
}
.cal-unscheduled-rail .cal-chip { scroll-snap-align: start; flex: 0 0 auto; }

/* -------- Chips (shared by week / month / unscheduled rail) -------- */

.cal-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  padding: 0.25rem 0.55rem;
  border-radius: 2px;
  border: 1px solid var(--color-rule-strong);
  background: #fff;
  text-decoration: none;
  color: var(--color-text);
  font-size: var(--type-small);
  line-height: 1.25;
  max-width: 100%;
  cursor: pointer;
  transition: transform var(--transition-fast), box-shadow var(--transition-fast);
}
.cal-chip:hover {
  transform: translateY(-1px);
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.08);
}
.cal-chip:focus-visible {
  outline: 2px solid var(--color-oxblood);
  outline-offset: 2px;
}
.cal-chip-pill {
  display: inline-block;
  font-family: var(--font-mono);
  font-size: var(--type-eyebrow);
  font-weight: 500;
  letter-spacing: 0.06em;
  padding: 0.05rem 0.35rem;
  border-radius: 2px;
  background: var(--color-bg-tint);
  color: var(--color-muted);
  flex: 0 0 auto;
}
.cal-chip-pill--bluesky   { background: #1185fe22; color: #0a4f99; }
.cal-chip-pill--x         { background: #00000010; color: #000; }
.cal-chip-pill--linkedin  { background: #0a66c222; color: #0a66c2; }
.cal-chip-pill--instagram { background: #e1306c22; color: #c13584; }
.cal-chip-time {
  font-family: var(--font-mono);
  font-size: var(--type-eyebrow);
  color: var(--color-muted);
  flex: 0 0 auto;
}
.cal-chip-body {
  font-size: var(--type-small);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  min-width: 0;
}

/* Status colour classes -- reuse existing tokens, no new palette. */
.cal-chip.chip--warn {
  background: var(--color-status-warn-bg);
  color: var(--color-status-warn-fg);
  border-color: var(--color-status-warn-fg);
}
.cal-chip.chip--oxblood {
  background: var(--color-oxblood);
  color: #fff;
  border-color: var(--color-oxblood);
}
.cal-chip.chip--oxblood .cal-chip-time,
.cal-chip.chip--oxblood .cal-chip-pill {
  color: #fff;
  background: rgba(255, 255, 255, 0.18);
}
.cal-chip.chip--ok {
  background: var(--color-status-ok-bg);
  color: var(--color-status-ok-fg);
  border-color: var(--color-status-ok-fg);
}
.cal-chip.chip--fail {
  background: var(--color-status-fail-bg);
  color: var(--color-error);
  border-color: var(--color-error);
}

/* -------- Week grid (desktop) -------- */

.cal-week {
  display: grid;
  grid-template-columns: 60px repeat(7, minmax(0, 1fr));
  border: 1px solid var(--color-rule);
  border-radius: 2px;
  background: #fff;
  overflow: hidden;
}
.cal-week-head { display: contents; }
.cal-week-corner,
.cal-week-day-head {
  background: var(--color-bg-tint);
  border-bottom: 1px solid var(--color-rule);
  padding: 0.5rem 0.6rem;
  font-family: var(--font-mono);
  font-size: var(--type-eyebrow);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--color-muted);
  position: sticky;
  top: 0;
  z-index: 2;
}
.cal-week-day-head {
  display: flex;
  align-items: baseline;
  gap: 0.4rem;
  border-left: 1px solid var(--color-rule);
}
.cal-week-day-head--today { color: var(--color-oxblood); }
.cal-week-day-name { font-weight: 600; }
.cal-week-day-num { color: var(--color-muted-soft); }
.cal-week-day-count {
  margin-left: auto;
  background: var(--color-oxblood);
  color: #fff;
  border-radius: 999px;
  padding: 0 0.4rem;
  font-size: 0.7rem;
}
.cal-week-body { display: contents; }
.cal-week-hour-row { display: contents; }
.cal-week-hour-label {
  background: var(--color-bg-tint);
  border-top: 1px solid var(--color-rule);
  padding: 0.4rem 0.6rem;
  font-family: var(--font-mono);
  font-size: var(--type-eyebrow);
  color: var(--color-muted);
}
.cal-week-cell {
  border-top: 1px solid var(--color-rule);
  border-left: 1px solid var(--color-rule);
  min-height: 56px;
  padding: 0.3rem;
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
  position: relative;
}
.cal-week-cell--today { background: rgba(92, 31, 31, 0.04); }

/* "Now" indicator: a thin oxblood line drawn inside today's hour cell at
 * render time, positioned vertically by minute-of-hour. The dot on the
 * left anchors the eye; the line itself spans the cell width. Pointer
 * events are disabled so the line never intercepts chip clicks. */
.cal-week-now {
  position: absolute;
  left: 0;
  right: 0;
  height: 2px;
  background: var(--color-oxblood);
  pointer-events: none;
  z-index: 1;
}
.cal-week-now::before {
  content: "";
  position: absolute;
  left: -3px;
  top: -3px;
  width: 8px;
  height: 8px;
  background: var(--color-oxblood);
  border-radius: 50%;
}

.cal-empty {
  text-align: center;
  padding: 1.5rem;
  font-style: italic;
}

/* -------- Month grid (desktop) -------- */

.cal-month {
  display: grid;
  grid-template-rows: auto 1fr;
  border: 1px solid var(--color-rule);
  border-radius: 2px;
  background: #fff;
  overflow: hidden;
}
.cal-month-head {
  display: grid;
  grid-template-columns: repeat(7, minmax(0, 1fr));
}
.cal-month-day-head {
  background: var(--color-bg-tint);
  border-bottom: 1px solid var(--color-rule);
  border-left: 1px solid var(--color-rule);
  padding: 0.5rem 0.7rem;
  font-family: var(--font-mono);
  font-size: var(--type-eyebrow);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--color-muted);
}
.cal-month-day-head:first-child { border-left: 0; }
.cal-month-body {
  display: grid;
  grid-template-columns: repeat(7, minmax(0, 1fr));
  grid-auto-rows: minmax(96px, 1fr);
}
.cal-month-cell {
  border-top: 1px solid var(--color-rule);
  border-left: 1px solid var(--color-rule);
  padding: 0.4rem 0.5rem;
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  min-height: 96px;
}
.cal-month-cell--out {
  background: var(--color-bg-tint);
  color: var(--color-muted-soft);
}
.cal-month-cell--out .cal-month-cell-num { color: var(--color-muted-soft); }
.cal-month-cell--today { box-shadow: inset 0 0 0 2px var(--color-oxblood); }
.cal-month-cell-num {
  font-family: var(--font-mono);
  font-size: var(--type-small);
  font-weight: 500;
  color: var(--color-muted);
}
.cal-month-cell--today .cal-month-cell-num { color: var(--color-oxblood); }
.cal-month-cell-chips {
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
  min-width: 0;
}
.cal-month-cell-chips .cal-chip {
  font-size: var(--type-eyebrow);
  padding: 0.15rem 0.4rem;
}
.cal-month-cell-overflow {
  margin-top: auto;
  font-family: var(--font-mono);
  font-size: var(--type-eyebrow);
  letter-spacing: 0.06em;
  color: var(--color-muted);
  text-decoration: underline;
  text-underline-offset: 3px;
}
.cal-month-cell-overflow:hover { color: var(--color-oxblood); }

/* -------- Mobile (<=720px) -------- */

@media (max-width: 720px) {
  /* Week view: horizontal-scrolling strip; one column per day at a
     comfortable phone width. PR #6 will scrollIntoView the today
     column on load. */
  .cal-week {
    grid-template-columns: 56px repeat(7, 80vw);
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    -webkit-overflow-scrolling: touch;
  }
  .cal-week-day-head { scroll-snap-align: start; }
  .cal-week-corner,
  .cal-week-hour-label { position: sticky; left: 0; z-index: 3; }
  .cal-week-day-head { position: sticky; top: 0; z-index: 2; }

  /* Month view: chips compress to colour dots so 3+ posts in a day
     don't blow out the 7-column grid. PR #6 wires the +N more to a
     bottom sheet day-list. */
  .cal-month-body { grid-auto-rows: minmax(72px, 1fr); }
  .cal-month-cell { padding: 0.3rem 0.35rem; }
  .cal-month-cell-chips .cal-chip {
    width: 8px;
    height: 8px;
    border-radius: 999px;
    padding: 0;
    overflow: hidden;
  }
  .cal-month-cell-chips .cal-chip-pill,
  .cal-month-cell-chips .cal-chip-time,
  .cal-month-cell-chips .cal-chip-body { display: none; }
  .cal-month-cell-chips {
    flex-direction: row;
    flex-wrap: wrap;
    gap: 4px;
  }
  .cal-nav-btn { min-width: 0; padding-left: 0.6rem; padding-right: 0.6rem; }
}

/* Reduced motion: drop the chip hover lift. */
@media (prefers-reduced-motion: reduce) {
  .cal-chip { transition: none; }
  .cal-chip:hover { transform: none; box-shadow: none; }
}

/* -------- Drag-to-reschedule (PR #3, desktop week-view only) -------- */

.cal-chip--draggable { cursor: grab; }
.cal-chip--draggable:active { cursor: grabbing; }
.cal-chip--dragging { opacity: 0.55; }
.cal-chip--saving { opacity: 0.7; pointer-events: none; }

.cal-week-cell--drop-target {
  background: rgba(92, 31, 31, 0.08);
  outline: 2px dashed var(--color-oxblood);
  outline-offset: -2px;
}

/* Reschedule + general calendar toast (success / failure feedback). */
.cal-toast {
  position: fixed;
  left: 50%;
  bottom: 5rem;
  transform: translateX(-50%);
  padding: 0.6rem 1rem;
  border-radius: 2px;
  background: var(--color-text);
  color: #fff;
  font-family: var(--font-mono);
  font-size: var(--type-small);
  letter-spacing: 0.04em;
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.18);
  z-index: 50;
  max-width: min(560px, 92vw);
  text-align: center;
}
.cal-toast[data-kind="ok"]   { background: var(--color-status-ok-fg); }
.cal-toast[data-kind="fail"] { background: var(--color-error); }

/* Mobile: drag is JS-disabled, so the grab cursor / drop styles are
   never visible. The toast still surfaces server-side errors if any
   (e.g. via a manual reschedule from a future bottom-sheet). */
@media (max-width: 720px) {
  .cal-chip--draggable { cursor: pointer; }
  .cal-toast { bottom: 5.5rem; }
}

@media (prefers-reduced-motion: reduce) {
  .cal-chip--dragging { opacity: 1; }
  .cal-chip--saving { opacity: 1; }
}

/* -------- Cross-tenant calendar (PR #5) -------- */

/* Per-tenant chip colours. Chips on /sef/calendar/ are coloured by
   tenant rather than by status: the cross-tenant view's job is to
   surface clashes, so tenant identity dominates.

   Colour source: --tenant-accent is set per .cal-tenant-{slug} by an
   inline <style> block in cross_tenant_calendar.html, populated from
   BrandKit.accent_color in the view (with MMTAction overridden to
   black). Adding a new tenant therefore needs no CSS edit -- as long
   as the tenant has a BrandKit row, its accent flows through here.
   The fallback below catches any tenant with a missing / blank
   accent. */
.cal-chip[class*=" cal-tenant-"],
.cal-chip[class^="cal-tenant-"] {
  background: var(--tenant-accent, var(--color-muted));
  color: #fff;
  border-color: var(--tenant-accent, var(--color-muted));
}
.cal-chip[class*=" cal-tenant-"] .cal-chip-time,
.cal-chip[class*=" cal-tenant-"] .cal-chip-pill,
.cal-chip[class^="cal-tenant-"] .cal-chip-time,
.cal-chip[class^="cal-tenant-"] .cal-chip-pill {
  color: #fff;
  background: rgba(255, 255, 255, 0.18);
}

/* Sent / posted chips on /sef/calendar/ render at reduced opacity so
   the operator's eye lands on what's still upcoming. Tenant accent
   colour stays intact -- the chip just visually quiets. Scoped to
   the cal-tenant-* class so the tenant calendar's status-coloured
   chips are unaffected. */
.cal-chip[class*=" cal-tenant-"][data-cal-status="posted"],
.cal-chip[class^="cal-tenant-"][data-cal-status="posted"],
.cal-chip[class*=" cal-tenant-"][data-cal-status="succeeded"],
.cal-chip[class^="cal-tenant-"][data-cal-status="succeeded"] {
  opacity: 0.45;
}
.cal-chip[class*=" cal-tenant-"][data-cal-status="posted"]:hover,
.cal-chip[class^="cal-tenant-"][data-cal-status="posted"]:hover,
.cal-chip[class*=" cal-tenant-"][data-cal-status="succeeded"]:hover,
.cal-chip[class^="cal-tenant-"][data-cal-status="succeeded"]:hover {
  opacity: 0.85;
}

/* Tenant legend (clickable filter pills above the grid). */
.cal-tenants-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  align-items: center;
  margin-bottom: 0.85rem;
  padding: 0.5rem 0.7rem;
  background: var(--color-bg-tint);
  border: 1px solid var(--color-rule);
  border-radius: 2px;
}
.cal-tenants-pill {
  display: inline-flex;
  align-items: center;
  padding: 0.25rem 0.7rem;
  border-radius: 999px;
  font-family: var(--font-mono);
  font-size: var(--type-eyebrow);
  letter-spacing: 0.04em;
  text-decoration: none;
  border: 1px solid transparent;
  opacity: 0.85;
  transition: opacity var(--transition-fast), transform var(--transition-fast);
}
.cal-tenants-pill:hover { opacity: 1; transform: translateY(-1px); }
.cal-tenants-pill--active {
  outline: 2px solid var(--color-text);
  outline-offset: 2px;
  opacity: 1;
}
/* Legend pills share the same --tenant-accent source as the chips. */
.cal-tenants-pill[class*=" cal-tenant-"],
.cal-tenants-pill[class^="cal-tenant-"] {
  background: var(--tenant-accent, var(--color-muted));
  color: #fff;
}

@media (prefers-reduced-motion: reduce) {
  .cal-tenants-pill { transition: none; }
  .cal-tenants-pill:hover { transform: none; }
}

/* -------- Mobile polish (PR #6) -------- */

/* Desktop month view: cap the visible chip count at 3 per cell. The
   server still renders all chips so the bottom-sheet JS can clone
   them; CSS just hides the overflow inline. The "+N more" link is
   what surfaces the rest. Mobile rules below override this back to
   "show all" because the chips are already compressed to dots there. */
@media (min-width: 721px) {
  .cal-month .cal-month-cell-chips .cal-chip:nth-child(n+4) {
    display: none;
  }
}

/* Day-sheet bottom sheet -- inherits .reject-sheet base from
   components.css; layout adjustments specific to the chip list. */
.cal-day-sheet .cal-day-sheet-inner {
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
}
.cal-day-sheet .cal-day-sheet-title {
  font-family: var(--font-serif);
  font-size: 1.05rem;
  font-weight: 500;
}
.cal-day-sheet-list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  max-height: 60vh;
  overflow-y: auto;
}
.cal-day-sheet-item {
  display: block;
}
.cal-day-sheet-item .cal-chip {
  display: flex;
  width: 100%;
  font-size: var(--type-small);
  padding: 0.45rem 0.7rem;
}
.cal-day-sheet-item .cal-chip-body {
  white-space: normal;
  text-overflow: clip;
}

/* Mobile: cells with chips become tap targets for the bottom sheet.
   The cursor hint matches the tap affordance and keyboard users
   still reach the chips via tab order (chips are <a>s). */
@media (max-width: 720px) {
  .cal-month-cell:has(.cal-chip) {
    cursor: pointer;
  }
  /* Mobile: don't hide the "extra" chips -- they're dots and we
     want every dot visible so the colour distribution reflects the
     day at a glance. */
  .cal-month .cal-month-cell-chips .cal-chip:nth-child(n+4) {
    display: inline-flex;
  }
}

/* =========================================================================
   Contacts list surface — tabbed table with filter chips and pagination.
   Used by Outreach's /<slug>/contacts/ surface; styles are namespaced
   under .contacts-* so they don't bleed into Studio surfaces.
   ========================================================================= */

.contacts-surface { padding: 1rem 0 4rem; }

.contacts-head {
  display: flex; justify-content: space-between; align-items: flex-end;
  gap: 1rem; margin-bottom: 1rem; flex-wrap: wrap;
}
.contacts-title { font-family: var(--font-display); font-size: 1.875rem; margin: 0 0 .25rem; }
.contacts-meta  { color: var(--color-muted); margin: 0; font-size: .9rem; }
.contacts-head-actions { display: flex; gap: .5rem; flex-wrap: wrap; }

.contacts-search {
  display: flex; gap: .5rem; align-items: center; margin-bottom: 1rem;
  flex-wrap: wrap;
}
.contacts-search-input {
  flex: 1 1 18ch; min-width: 18ch; min-height: 44px; font-size: 16px;
  padding: .5rem .75rem;
  /* --color-border is undefined, so the bare var() was invalid and the
     resting border never rendered (only the focus ring showed on click).
     A fallback makes the border permanent. */
  border: 1px solid var(--color-border, rgba(0, 0, 0, 0.25));
  border-radius: 6px; background: var(--color-bg);
}
.contacts-search-clear {
  color: var(--color-muted); font-size: .9rem; padding: .4rem .6rem;
}
/* Derived-value hint (e.g. a person's country inherited from their org).
   Native title tooltip on hover/focus explains it may be wrong. */
.contacts-derived {
  color: var(--color-muted); cursor: help; font-size: .9em;
  margin-left: .2rem;
}

.contacts-tabs {
  display: flex; gap: .25rem; border-bottom: 1px solid var(--color-border);
  margin-bottom: 1rem;
}
.contacts-tab {
  padding: .65rem 1rem; color: var(--color-muted); text-decoration: none;
  border-bottom: 2px solid transparent; font-weight: 500;
  min-height: 44px; display: inline-flex; align-items: center; gap: .4rem;
}
.contacts-tab:hover { color: var(--color-text); }
.contacts-tab--active {
  color: var(--color-oxblood); border-bottom-color: var(--color-oxblood);
}
.contacts-tab-count {
  display: inline-block; padding: .05rem .45rem; font-size: .75rem;
  background: var(--color-bg-tint); color: var(--color-muted); border-radius: 99px;
}
.contacts-tab--active .contacts-tab-count {
  background: var(--color-oxblood); color: var(--color-cream);
}

.contacts-filters { display: flex; flex-direction: column; gap: .35rem; margin-bottom: .75rem; }
.contacts-filter-row {
  display: flex; gap: .35rem; align-items: center; flex-wrap: wrap;
}
.contacts-filter-label {
  font-size: .8rem; color: var(--color-muted); text-transform: uppercase;
  letter-spacing: .04em; min-width: 5rem;
}

/* Reusable contact-chip vocabulary. Mirrors .cal-chip's token colour
   classes (chip--warn / --ok / --fail) but lives on a different base
   class so they don't accidentally inherit calendar-chip sizing. */
.contacts-chip {
  display: inline-flex; align-items: center; gap: .25rem;
  font-size: .8rem; font-weight: 500; padding: .15rem .5rem;
  border-radius: 99px; line-height: 1.4; white-space: nowrap;
}
.contacts-chip--warn   { background: var(--color-status-warn-bg); color: var(--color-status-warn-fg); }
.contacts-chip--ok     { background: var(--color-status-ok-bg);   color: var(--color-status-ok-fg); }
.contacts-chip--fail   { background: var(--color-status-fail-bg); color: var(--color-status-fail-fg); }
.contacts-chip--info   { background: var(--color-status-info-bg); color: var(--color-status-info-fg); }
.contacts-chip--muted  { background: var(--color-bg-tint);        color: var(--color-muted); }
.contacts-chip-empty   { color: var(--color-muted); opacity: .4; }

/* Tier pills use the same colour vocabulary as the chips above, but
   are narrower because they hold two characters. */
.contacts-chip-tier { font-variant-numeric: tabular-nums; padding: .15rem .4rem; min-width: 2.2rem; justify-content: center; }
.contacts-chip--t1 { background: var(--color-status-fail-bg); color: var(--color-status-fail-fg); }
.contacts-chip--t2 { background: var(--color-status-warn-bg); color: var(--color-status-warn-fg); }
.contacts-chip--t3 { background: var(--color-status-ok-bg);   color: var(--color-status-ok-fg); }
.contacts-chip--tx { background: var(--color-status-info-bg); color: var(--color-status-info-fg); }

/* Filter chips are clickable; on chips have a subtle ring. */
.contacts-chip-filter {
  text-decoration: none; border: 1px solid transparent;
  background: var(--color-bg-tint); color: var(--color-text);
  min-height: 32px;
}
.contacts-chip-filter:hover { border-color: var(--color-border); }
.contacts-chip-filter.contacts-chip--on {
  background: var(--color-oxblood); color: var(--color-cream);
}
.contacts-chip-count {
  font-size: .7rem; opacity: .75; font-variant-numeric: tabular-nums;
}

.contacts-listbar {
  display: flex; justify-content: space-between; align-items: center;
  gap: 1rem; flex-wrap: wrap; margin: .75rem 0;
  font-size: .9rem; color: var(--color-muted);
}
.contacts-sort { display: flex; gap: .5rem; align-items: center; }
.contacts-sort-label { font-size: .8rem; }
.contacts-sort-select { min-height: 36px; font-size: 14px; padding: .25rem .5rem; }

.contacts-table-wrap { overflow-x: auto; border: 1px solid var(--color-border); border-radius: 8px; }
.contacts-table { width: 100%; border-collapse: collapse; font-size: .92rem; }
.contacts-table th, .contacts-table td { padding: .7rem .85rem; text-align: left; vertical-align: middle; }
.contacts-table thead th {
  font-weight: 600; color: var(--color-muted); font-size: .78rem;
  text-transform: uppercase; letter-spacing: .04em;
  background: var(--color-bg-tint); border-bottom: 1px solid var(--color-border);
}
.contacts-table tbody tr { border-top: 1px solid var(--color-border); }
.contacts-table tbody tr:first-child { border-top: none; }
.contacts-table tbody tr:hover { background: var(--color-bg-tint); }
.contacts-rowlink {
  color: var(--color-text); font-weight: 500; text-decoration: none;
}
.contacts-rowlink:hover { color: var(--color-oxblood); }
.contacts-row-sub { display: none; font-size: .8rem; color: var(--color-muted); margin-top: .15rem; }
.contacts-touch { font-variant-numeric: tabular-nums; color: var(--color-muted); font-size: .85rem; }

.contacts-empty {
  padding: 2rem; text-align: center; color: var(--color-muted);
  background: var(--color-bg-tint); border-radius: 8px;
}

.contacts-pager {
  display: flex; justify-content: space-between; align-items: center;
  margin-top: 1rem; gap: 1rem; flex-wrap: wrap;
}
.contacts-pager-link {
  padding: .5rem 1rem; text-decoration: none; color: var(--color-text);
  border: 1px solid var(--color-border); border-radius: 6px; min-height: 44px;
  display: inline-flex; align-items: center;
}
.contacts-pager-link:hover { background: var(--color-bg-tint); }
.contacts-pager-link--disabled { color: var(--color-muted); opacity: .4; pointer-events: none; }
.contacts-pager-current { color: var(--color-muted); font-size: .9rem; }

/* Mobile: drop the secondary columns, surface them under the row name. */
.show-narrow { display: none; }
@media (max-width: 720px) {
  .contacts-table .hide-narrow { display: none; }
  .contacts-table th, .contacts-table td { padding: .6rem .55rem; }
  .contacts-row-sub.show-narrow { display: block; }
  .contacts-filter-label { min-width: 4rem; }
  .contacts-head { flex-direction: column; align-items: flex-start; }
}

/* =========================================================================
   Outreach detail-page shell — shared by Contacts org/person detail and
   Initiative detail. Provides a consistent head + stats + card + kv grid
   + timeline + form layout vocabulary so every detail surface reads the
   same way.

   Naming: .outreach-* (service-generic) not .contacts-* (which would lock
   it to one app). Chip pills already live under .contacts-chip-* in this
   file and are reused as-is — the prefix is historical, not semantic.
   ========================================================================= */

.outreach-page { padding: 1rem 0 4rem; }
.outreach-page-back {
  display: inline-block; margin-bottom: .75rem; color: var(--color-muted);
  font-size: .9rem; text-decoration: none;
}
.outreach-page-back:hover { color: var(--color-text); }

.outreach-page-head {
  display: flex; justify-content: space-between; align-items: flex-start;
  gap: 1.5rem; flex-wrap: wrap; margin-bottom: .5rem;
}
.outreach-page-head-main { flex: 1 1 24ch; min-width: 0; }
.outreach-page-title {
  font-family: var(--font-display); font-size: 1.875rem; margin: 0 0 .25rem;
  word-wrap: break-word;
}
.outreach-page-subtitle { color: var(--color-muted); margin: 0; font-size: .95rem; }
.outreach-page-meta {
  display: flex; flex-wrap: wrap; gap: .35rem; margin: .6rem 0 0;
  align-items: center;
}
.outreach-page-actions {
  display: flex; gap: .5rem; flex-wrap: wrap; align-items: center;
  flex-shrink: 0;
}

.outreach-stats {
  display: grid; gap: .75rem; grid-template-columns: repeat(auto-fit, minmax(8rem, 1fr));
  margin: 1rem 0 1.25rem;
}
.outreach-stat {
  background: var(--color-bg-tint); border-radius: 8px;
  padding: .75rem .9rem; border: 1px solid var(--color-border);
}
.outreach-stat-value {
  font-size: 1.4rem; font-weight: 600; font-variant-numeric: tabular-nums;
  line-height: 1.1; display: block;
}
.outreach-stat-label {
  font-size: .75rem; color: var(--color-muted); text-transform: uppercase;
  letter-spacing: .04em; margin-top: .15rem; display: block;
}

.outreach-card {
  background: var(--color-bg); border: 1px solid var(--color-border);
  border-radius: 8px; padding: 1.1rem 1.25rem; margin-bottom: 1rem;
}
.outreach-card-head {
  display: flex; justify-content: space-between; align-items: baseline;
  gap: 1rem; margin-bottom: .75rem;
}
.outreach-card-title {
  font-family: var(--font-display); font-size: 1.05rem; margin: 0;
  letter-spacing: 0;
}
.outreach-card-eyebrow {
  font-size: .75rem; color: var(--color-muted); text-transform: uppercase;
  letter-spacing: .04em;
}
.outreach-card-empty {
  color: var(--color-muted); font-style: italic; padding: .5rem 0;
}

/* Two-column key/value grid for tenant-profile-shaped data. Replaces
   the bare <dl> pattern that didn't render legibly. */
.outreach-kv { display: grid; gap: .65rem 1.25rem; grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr)); margin: 0; }
.outreach-kv-row { display: flex; flex-direction: column; gap: .15rem; min-width: 0; }
.outreach-kv-label {
  font-size: .72rem; color: var(--color-muted); text-transform: uppercase;
  letter-spacing: .04em;
}
.outreach-kv-value { font-size: .95rem; word-wrap: break-word; }
.outreach-kv-value-muted { color: var(--color-muted); }

.outreach-notes {
  margin-top: .75rem; padding: .75rem; background: var(--color-bg-tint);
  border-radius: 6px; border-left: 3px solid var(--color-border);
  font-size: .9rem;
}
.outreach-notes p:first-child { margin-top: 0; }
.outreach-notes p:last-child { margin-bottom: 0; }

/* Activity timeline — used for ContactEvent + similar log-shaped data. */
.outreach-timeline { list-style: none; padding: 0; margin: 0; }
.outreach-timeline-item {
  display: grid; grid-template-columns: 8.5rem 1fr; gap: .8rem;
  padding: .55rem 0; border-top: 1px solid var(--color-border);
  font-size: .9rem;
}
.outreach-timeline-item:first-child { border-top: none; }
.outreach-timeline-when {
  color: var(--color-muted); font-variant-numeric: tabular-nums;
  font-size: .85rem;
}
.outreach-timeline-what { min-width: 0; }
.outreach-timeline-channel { font-weight: 500; }
.outreach-timeline-direction {
  font-size: .75rem; color: var(--color-muted); margin-left: .35rem;
}

/* Form layout that mirrors a sensible CRM form: labelled fields stack;
   short fields share a row at >=720px. Uses the studio button vocab. */
.outreach-form { display: grid; gap: 1rem; }
.outreach-form-row { display: flex; flex-direction: column; gap: .25rem; }
.outreach-form-row > label {
  font-family: var(--font-mono);
  font-size: var(--type-eyebrow);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--color-muted);
  font-weight: 500;
}
/* Initiative form sections (Timeline, Event details) */
.initiative-section {
  border: 1px solid var(--color-rule);
  border-radius: 4px;
  overflow: hidden;
}
.initiative-section-title {
  background: var(--color-bg-tint);
  border-bottom: 1px solid var(--color-rule);
  padding: 0.4rem 0.85rem;
  font-family: var(--font-mono);
  font-size: var(--type-eyebrow);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--color-muted);
  font-weight: 600;
  margin: 0;
}
.initiative-section-body {
  padding: 0.85rem;
  display: grid;
  gap: 0.75rem;
}
.outreach-form-row > label > span.required { color: var(--color-error); margin-left: .15rem; }
.outreach-form-row > input[type="text"],
.outreach-form-row > input[type="email"],
.outreach-form-row > input[type="url"],
.outreach-form-row > input[type="tel"],
.outreach-form-row > input[type="number"],
.outreach-form-row > input[type="date"],
.outreach-form-row > input[type="search"],
.outreach-form-row > select,
.outreach-form-row > textarea {
  min-height: 44px; font-size: 16px; padding: .5rem .75rem;
  border: 1px solid var(--color-border); border-radius: 6px;
  background: var(--color-bg); width: 100%;
}
.outreach-form-row > textarea { min-height: 5.5rem; resize: vertical; line-height: 1.45; }
.outreach-form-help { color: var(--color-muted); font-size: .8rem; }
.outreach-form-error { color: var(--color-error); font-size: .85rem; }
.outreach-form-actions {
  display: flex; gap: .6rem; margin-top: .25rem; flex-wrap: wrap;
}
.outreach-form-banner {
  padding: .65rem .85rem; border-radius: 6px;
  background: var(--color-status-fail-bg); color: var(--color-status-fail-fg);
  font-size: .9rem;
}

/* Mini-table — used for People-at-org, Targets-on-initiative.
   Same chrome as .contacts-table but tighter. */
.outreach-mini-table { width: 100%; border-collapse: collapse; font-size: .9rem; }
.outreach-mini-table th, .outreach-mini-table td {
  padding: .55rem .65rem; text-align: left; vertical-align: middle;
}
.outreach-mini-table thead th {
  font-weight: 600; color: var(--color-muted); font-size: .72rem;
  text-transform: uppercase; letter-spacing: .04em;
  border-bottom: 1px solid var(--color-border);
}
.outreach-mini-table tbody tr { border-top: 1px solid var(--color-border); }
.outreach-mini-table tbody tr:hover { background: var(--color-bg-tint); }
.outreach-mini-table a { color: var(--color-text); font-weight: 500; text-decoration: none; }
.outreach-mini-table a:hover { color: var(--color-oxblood); }

@media (max-width: 720px) {
  .outreach-page-head { flex-direction: column; align-items: flex-start; }
  .outreach-page-actions { width: 100%; }
  .outreach-timeline-item { grid-template-columns: 1fr; gap: .15rem; }
  .outreach-timeline-when { font-size: .8rem; }
  .outreach-card { padding: .85rem .95rem; }
}

/* "Active / live" chip variant — used by Initiative status when the
   initiative is currently sending. Uses the brand oxblood the way the
   calendar chips do. */
.contacts-chip--live {
  background: var(--color-oxblood); color: var(--color-cream);
}

/* ----------------------------------------------------------------------
   Contacts bulk-add sticky action bar.
   Appears when the operator ticks one or more rows in the Contacts table.
   Sits above the mobile bottom-tab bar (which is fixed at bottom: 0)
   via a bottom offset that leaves the tab bar visible.
   ---------------------------------------------------------------------- */
.contacts-bulk-bar {
  position: sticky;
  bottom: 0;
  background: var(--color-bg, #fff);
  border-top: 1px solid var(--color-border, rgba(0, 0, 0, 0.12));
  box-shadow: 0 -4px 16px rgba(0, 0, 0, 0.08);
  padding: .65rem .9rem;
  z-index: 20;
  display: none;
}
.contacts-bulk-bar--visible { display: block; }
.contacts-bulk-bar-inner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .65rem;
  max-width: 60rem;
  margin: 0 auto;
}
.contacts-bulk-bar-summary {
  font-size: .9rem;
  margin-right: .35rem;
}
.contacts-bulk-bar-summary strong {
  font-weight: 700;
  color: var(--color-oxblood, #5c1f1f);
}
.contacts-bulk-bar-picker {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .35rem;
  flex: 1 1 18rem;
  min-width: 0;
}

@media (max-width: 720px) {
  /* Lift the bar above the bottom-tab nav (approx 64px). */
  .contacts-bulk-bar { bottom: 64px; }
  .contacts-bulk-bar-inner { gap: .5rem; }
  .contacts-bulk-bar-picker { flex: 1 1 100%; }
}

/* Stateful next-step card on the Outreach home. The state token comes
   from the view so the card can lean colour cues in future without
   changing template logic — for now they share the same chrome. */
.outreach-card--next-step {
  border-left: 4px solid var(--color-oxblood, #5c1f1f);
}
.outreach-card--state-empty,
.outreach-card--state-contacts_no_initiative {
  border-left-color: var(--color-warn, #c98a1a);
}
.outreach-card--state-targets_no_drafts {
  border-left-color: var(--color-ok, #2a9d8f);
}
.outreach-card--state-no_email_channel {
  border-left-color: var(--color-warn, #c98a1a);
}

/* Getting-started checklist on the Outreach home: a <details> card with
   the four bootstrap steps. Disappears entirely once all steps are done
   (the view passes None), so no dismiss machinery is needed. */
details.outreach-card--setup > summary.outreach-setup-summary {
  list-style: none; cursor: pointer; min-height: 44px;
  display: flex; align-items: baseline; margin-bottom: 0;
}
details.outreach-card--setup[open] > summary.outreach-setup-summary {
  margin-bottom: .75rem;
}
details.outreach-card--setup > summary.outreach-setup-summary::-webkit-details-marker { display: none; }
details.outreach-card--setup > summary.outreach-setup-summary::after {
  content: "\25BE"; color: var(--color-muted); margin-left: auto;
  font-size: .85rem;
}
details.outreach-card--setup[open] > summary.outreach-setup-summary::after {
  content: "\25B4";
}
.outreach-setup-steps {
  list-style: none; margin: 0; padding: 0;
  display: flex; flex-direction: column;
}
.outreach-setup-step {
  display: flex; align-items: center; gap: .6rem;
  min-height: 44px; padding: .35rem 0;
  border-top: 1px solid var(--color-border);
  font-size: .92rem;
}
.outreach-setup-step:first-child { border-top: none; }
.outreach-setup-step--done .outreach-setup-label {
  color: var(--color-muted); text-decoration: line-through;
}
.outreach-setup-link { font-weight: 600; text-decoration: none; }
.outreach-setup-link:hover { color: var(--color-oxblood); text-decoration: underline; }
.outreach-setup-hint { color: var(--color-muted); font-size: .8rem; }

/* Explained status chip: a <details> popover wrapping the standard chip.
   Summary keeps the chip's inline footprint plus a small "?" affordance;
   the panel borrows the .bulk-menu popover chrome. On narrow screens the
   panel expands inline instead, so it is never clipped by a horizontally
   scrolling .contacts-table-wrap. No animation, so prefers-reduced-motion
   needs no special-casing. */
.chip-explain { position: relative; display: inline-block; vertical-align: baseline; }
.chip-explain > summary.chip-explain-summary {
  list-style: none; cursor: pointer; user-select: none;
  display: inline-flex; align-items: center; gap: .2rem;
  /* Generous tap target without inflating the visual chip. */
  padding: .35rem .15rem; margin: -.35rem -.15rem;
}
.chip-explain > summary.chip-explain-summary::-webkit-details-marker { display: none; }
.chip-explain-q {
  display: inline-flex; align-items: center; justify-content: center;
  width: .95rem; height: .95rem; border-radius: 50%;
  border: 1px solid var(--color-border);
  color: var(--color-muted); background: var(--color-bg);
  font-size: .62rem; font-weight: 700; line-height: 1;
}
.chip-explain[open] .chip-explain-q,
.chip-explain > summary.chip-explain-summary:hover .chip-explain-q {
  color: var(--color-oxblood); border-color: var(--color-oxblood);
}
.chip-explain-panel {
  position: absolute; top: calc(100% + .35rem); left: 0; z-index: 30;
  width: min(20rem, 78vw);
  background: var(--color-bg, #fff);
  border: 1px solid var(--color-border, rgba(0, 0, 0, 0.12));
  border-radius: 6px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);
  padding: .65rem .8rem;
  font-size: .85rem; font-weight: 400; line-height: 1.45;
  text-align: left; white-space: normal; text-transform: none;
  letter-spacing: normal; color: var(--color-text);
}
.chip-explain-text { margin: 0; }
.chip-explain-cta {
  display: inline-block; margin-top: .45rem; font-weight: 600;
  color: var(--color-oxblood); text-decoration: none; min-height: 32px;
}
.chip-explain-cta:hover { text-decoration: underline; }
@media (max-width: 720px) {
  .chip-explain[open] { display: block; }
  .chip-explain-panel {
    position: static; width: auto; margin-top: .35rem;
    box-shadow: none; background: var(--color-bg-tint);
  }
}

/* Filters disclosure: all the filter rows + saved views fold behind one
   summary with an active-count badge. Open by default (server-side)
   whenever a filter is applied, so shared URLs stay self-explanatory. */
.filter-disclosure { margin: 0 0 1rem; }
.filter-disclosure > summary.filter-disclosure-summary {
  list-style: none; cursor: pointer; user-select: none;
  display: flex; align-items: center; gap: .5rem;
  min-height: 44px; padding: .35rem .75rem;
  border: 1px solid var(--color-border); border-radius: 8px;
  background: var(--color-bg-tint);
}
.filter-disclosure > summary.filter-disclosure-summary::-webkit-details-marker { display: none; }
.filter-disclosure-title { font-weight: 600; font-size: .92rem; }
.filter-disclosure-caret { margin-left: auto; color: var(--color-muted); font-size: .85rem; }
.filter-disclosure[open] .filter-disclosure-caret { transform: rotate(180deg); }
.filter-disclosure[open] > summary.filter-disclosure-summary {
  border-bottom-left-radius: 0; border-bottom-right-radius: 0;
}
.filter-disclosure[open] > *:not(summary) {
  border: 1px solid var(--color-border); border-top: 0;
  padding: .75rem .75rem .35rem;
}
.filter-disclosure[open] > *:last-child {
  border-bottom-left-radius: 8px; border-bottom-right-radius: 8px;
  padding-bottom: .75rem;
}

/* Compose sticky action bar: the recipient count + submit stay in reach
   however long the form gets. Static flow until it would scroll away;
   sticky keeps it above the mobile tab bar. No animation. */
.compose-sticky-bar {
  position: sticky; bottom: 0; z-index: 20;
  display: flex; align-items: center; gap: .9rem; flex-wrap: wrap;
  background: var(--color-bg, #fff);
  border-top: 1px solid var(--color-border, rgba(0, 0, 0, 0.12));
  box-shadow: 0 -4px 16px rgba(0, 0, 0, 0.06);
  padding: .65rem .9rem; margin-top: 1rem;
}
.compose-sticky-count strong { color: var(--color-oxblood, #5c1f1f); font-size: 1rem; }
@media (max-width: 720px) {
  /* Lift above the bottom-tab nav (approx 64px), like the bulk bar. */
  .compose-sticky-bar { bottom: 64px; }
}

/* Disclosure card: an .outreach-card that opens and closes. Used for the
   secondary cards on the initiative hub (Brief / Context / Sequences) so
   the default page reads identity, numbers, next action, work. The
   one-line digest in the eyebrow keeps closed cards scannable. */
details.disclosure-card > summary.disclosure-card-summary {
  list-style: none; cursor: pointer; user-select: none;
  display: flex; align-items: baseline; gap: .75rem; flex-wrap: wrap;
  min-height: 44px; margin-bottom: 0;
}
details.disclosure-card[open] > summary.disclosure-card-summary { margin-bottom: .75rem; }
details.disclosure-card > summary.disclosure-card-summary::-webkit-details-marker { display: none; }
.disclosure-card-caret { margin-left: auto; color: var(--color-muted); font-size: .85rem; }
details.disclosure-card[open] > summary .disclosure-card-caret { transform: rotate(180deg); }

/* Card-row table pattern: the single mobile answer for wide list tables.
   Add .table-cards to a table and, below the 720px breakpoint, the thead
   disappears and each row becomes a bordered card. Cells flow inline;
   give a cell .tc-primary to make it the full-width headline, .tc-select
   to pin a bulk-select checkbox in the card corner, and data-label="..."
   to caption a value that is ambiguous without its column header. */
@media (max-width: 720px) {
  table.table-cards { display: block; border-collapse: separate; }
  table.table-cards > thead { display: none; }
  table.table-cards > tbody { display: block; }
  table.table-cards > tbody > tr {
    display: block; position: relative;
    border: 1px solid var(--color-border) !important; border-radius: 8px;
    margin: 0 0 .6rem; padding: .6rem .75rem;
    background: var(--color-bg);
  }
  table.table-cards > tbody > tr:hover { background: var(--color-bg); }
  table.table-cards > tbody > tr > td {
    display: inline-block; border: 0; padding: .2rem .6rem .2rem 0;
    vertical-align: top;
  }
  table.table-cards > tbody > tr > td.tc-primary {
    display: block; padding-right: 0;
  }
  table.table-cards > tbody > tr > td.tc-select {
    position: absolute; top: .55rem; right: .6rem; padding: 0; width: auto;
  }
  /* Leave breathing room for the pinned checkbox. */
  table.table-cards > tbody > tr > td.tc-select ~ td.tc-primary { padding-right: 2.2rem; }
  table.table-cards td[data-label]::before {
    content: attr(data-label);
    display: block; font-size: .66rem; color: var(--color-muted);
    text-transform: uppercase; letter-spacing: .04em; margin-bottom: .1rem;
  }
}


/* ================== OUTREACH PIPELINE STEPPER + BANNER ============= */
/* The persistent 8-stage stepper threaded across every initiative-journey
   surface. Reuses the existing status colour tokens (ok / oxblood / muted);
   no new colour tokens. One horizontally-scrollable band on every width,
   so mobile keeps a single "where am I" row rather than stacking. */
.pipeline-stepper { margin: .25rem 0 1.1rem; }
.pipeline-steps {
  list-style: none; margin: 0; padding: 0;
  display: flex; gap: .4rem; overflow-x: auto;
  scroll-snap-type: x proximity; -webkit-overflow-scrolling: touch;
}
.pipeline-step { flex: 1 1 0; min-width: 7.5rem; scroll-snap-align: start; }
.pipeline-step-link {
  display: flex; align-items: center; gap: .5rem;
  min-height: 44px; padding: .45rem .6rem;
  border: 1px solid var(--color-border); border-radius: 8px;
  background: var(--color-bg); text-decoration: none;
  color: var(--color-muted); font-size: .82rem; line-height: 1.15;
  white-space: nowrap; height: 100%;
}
a.pipeline-step-link:hover { border-color: var(--color-oxblood); color: var(--color-text); }
.pipeline-step-link:focus-visible { outline: 2px solid var(--color-oxblood); outline-offset: 2px; }
.pipeline-step-num {
  flex-shrink: 0; width: 1.5rem; height: 1.5rem; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: .8rem; font-weight: 600; font-variant-numeric: tabular-nums;
  border: 1px solid var(--color-border); background: var(--color-bg-tint);
  color: var(--color-muted);
}
.pipeline-step-label { min-width: 0; overflow: hidden; text-overflow: ellipsis; }

.pipeline-step--done .pipeline-step-link { color: var(--color-text); }
.pipeline-step--done .pipeline-step-num {
  background: var(--color-ok, #2a9d8f); border-color: var(--color-ok, #2a9d8f); color: #fff;
}
.pipeline-step--current .pipeline-step-link {
  border-color: var(--color-oxblood); color: var(--color-text); font-weight: 600;
  box-shadow: inset 0 0 0 1px var(--color-oxblood);
}
.pipeline-step--current .pipeline-step-num {
  background: var(--color-oxblood); border-color: var(--color-oxblood);
  color: var(--color-cream, #fff);
}
.pipeline-step--locked .pipeline-step-link { opacity: .5; cursor: default; }

/* The recommended "do this next" jump under the stepper. Visible on every
   pipeline page when you've wandered off the recommended funnel stage. */
.pipeline-next {
  display: flex; align-items: center; flex-wrap: wrap; gap: .6rem;
  margin: -.4rem 0 1.1rem;
}
.pipeline-next-label {
  font-size: .75rem; font-weight: 600; text-transform: uppercase;
  letter-spacing: .04em; color: var(--color-muted);
}
.pipeline-next-stage { font-size: .85rem; }

.outreach-card--stage { border-left: 4px solid var(--color-oxblood, #5c1f1f); }
.pipeline-banner-summary { font-size: 1.05rem; font-weight: 600; margin: 0 0 .25rem; }
.pipeline-banner-est { color: var(--color-muted); font-weight: 400; font-size: .9rem; }
.pipeline-banner-why { color: var(--color-muted); font-size: .9rem; margin: 0; max-width: 70ch; }

@media (max-width: 720px) {
  .pipeline-step { flex: 0 0 auto; min-width: 0; }
}

/* Live send progress (draft detail, stage 6). Honest climbing count
   instead of a static "sent"; polled via HTMX until nothing is pending. */
.send-progress { margin: .25rem 0 1rem; }
.send-progress-bar {
  height: 10px; border-radius: 999px; background: var(--color-bg-tint);
  border: 1px solid var(--color-border); overflow: hidden;
}
.send-progress-fill {
  display: block; height: 100%; background: var(--color-ok, #2a9d8f);
  transition: width .4s ease;
}
.send-progress-text { font-size: .9rem; color: var(--color-muted); margin: .4rem 0 0; }

/* ==================================== REACTIVE SURFACES ============ */

.page-head {
  margin-bottom: clamp(1.5rem, 3vh, 2.25rem);
}
.page-head--split {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
}
.page-head h1 {
  font-family: var(--font-serif);
  font-size: clamp(1.75rem, 3.4vw, 2.4rem);
  font-weight: 500;
  line-height: 1.05;
  letter-spacing: -0.02em;
  margin: 0 0 0.4rem;
}

.reactive-actions {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.55rem;
}

.reactive-cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 0.85rem;
  margin-bottom: 1.4rem;
}
.reactive-cards .card {
  display: flex;
  flex-direction: column;
  gap: 0.45rem;
}
.reactive-cards .card > .btn,
.reactive-cards .card > form {
  margin-top: auto;
}
@media (min-width: 960px) {
  .reactive-cards .card--span-2 { grid-column: span 2; }
}

.metric {
  font-family: var(--font-serif);
  font-size: clamp(1.9rem, 3.2vw, 2.35rem);
  font-weight: 500;
  line-height: 1;
  letter-spacing: -0.02em;
  margin: 0;
}

.library-list,
.reactive-digest-list,
.draft-list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: grid;
  gap: 0.55rem;
}
.library-list > li,
.reactive-digest-list > li {
  border: 1px solid var(--color-rule);
  border-radius: 2px;
  padding: 0.75rem 0.9rem;
  background: var(--color-bg);
}
.library-list > li {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.55rem;
}
.library-list > li > p,
.library-list > li > ol {
  flex-basis: 100%;
  margin: 0.2rem 0 0;
}
.library-list > li > ol {
  padding-left: 1.2rem;
}

.data-table {
  width: 100%;
  border-collapse: collapse;
  margin: 1rem 0 1.4rem;
  font-size: var(--type-small);
}
.data-table thead th {
  text-align: left;
  font-family: var(--font-mono);
  font-size: var(--type-eyebrow);
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--color-muted);
  border-bottom: 1px solid var(--color-rule-strong);
  padding: 0.55rem 0.7rem;
}
.data-table tbody td {
  padding: 0.62rem 0.7rem;
  border-bottom: 1px solid var(--color-rule);
  vertical-align: top;
}
.data-table tbody tr:hover { background: var(--color-bg-tint); }

form.form-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 0.65rem;
  align-items: end;
  margin: 0.85rem 0 0;
}
form.form-row input,
form.form-row select,
form.form-row textarea {
  width: 100%;
  font-family: var(--font-sans);
  font-size: 16px;
  line-height: 1.4;
  padding: 0.5rem 0.65rem;
  background: var(--color-bg);
  color: var(--color-text);
  border: 1px solid var(--color-rule-strong);
  border-radius: 2px;
}
form.form-row input:focus,
form.form-row select:focus,
form.form-row textarea:focus {
  outline: none;
  border-color: var(--color-oxblood);
  box-shadow: 0 0 0 3px rgba(92, 31, 31, 0.12);
}

form.form-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 0.75rem;
  align-items: end;
}
form.form-grid .span2 {
  grid-column: 1 / -1;
}
form.form-grid label {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
  font-family: var(--font-mono);
  font-size: var(--type-eyebrow);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--color-muted);
}
form.form-grid input,
form.form-grid select,
form.form-grid textarea {
  text-transform: none;
  letter-spacing: 0;
  font-family: var(--font-sans);
  font-size: 16px;
  line-height: 1.4;
  padding: 0.5rem 0.65rem;
  background: var(--color-bg);
  color: var(--color-text);
  border: 1px solid var(--color-rule-strong);
  border-radius: 2px;
}
form.form-grid input:focus,
form.form-grid select:focus,
form.form-grid textarea:focus {
  outline: none;
  border-color: var(--color-oxblood);
  box-shadow: 0 0 0 3px rgba(92, 31, 31, 0.12);
}

.draft-card {
  border: 1px solid var(--color-rule);
  border-radius: 2px;
  background: var(--color-bg);
  padding: 0.85rem 1rem;
}
.draft-card--focus {
  border-color: var(--color-oxblood);
  box-shadow: 0 0 0 3px rgba(92, 31, 31, 0.14);
}
.draft-card-head {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.55rem;
  margin-bottom: 0.65rem;
}
.draft-card-body p {
  margin: 0 0 0.6rem;
  word-break: break-word;
}
.draft-card-body p:last-child { margin-bottom: 0; }
.draft-card-foot {
  margin-top: 0.75rem;
  padding-top: 0.7rem;
  border-top: 1px solid var(--color-rule);
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.6rem;
}
.draft-card-foot form.inline {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
}
.draft-card-foot input[type="text"] {
  min-width: min(320px, 68vw);
}

.reactive-queue {
  max-width: 900px;
}

.repost-settings {
  flex-basis: 100%;
}
.repost-settings > summary {
  width: fit-content;
}

@media (max-width: 720px) {
  .page-head--split {
    align-items: flex-start;
  }
  .draft-card-foot {
    align-items: stretch;
  }
  .draft-card-foot form.inline {
    display: flex;
    width: 100%;
  }
  .draft-card-foot input[type="text"] {
    min-width: 0;
    flex: 1;
  }
}

/* ================================================================== */
/* Reactive — config picker, library cards, queue provenance, callouts  */
/* ================================================================== */

/* Cross-page callout used on Sources and Reactive Library to disambiguate
   the two pipelines for new users. */
.reactive-callout {
  border-left: 3px solid var(--color-oxblood);
  background: var(--color-bg-tint);
  padding: 0.8rem 1rem;
  margin: 0.9rem 0 1.2rem;
  font-size: var(--type-small);
  line-height: 1.45;
}
.reactive-callout strong { color: var(--color-text); }
.reactive-callout a { font-weight: 500; }

/* Config form layout */
.reactive-config-form {
  display: grid;
  gap: 1.4rem;
  max-width: 920px;
}
.reactive-config-section {
  border: 1px solid var(--color-rule);
  border-radius: 2px;
  padding: 1rem 1.2rem 1.2rem;
  background: var(--color-bg);
  display: grid;
  gap: 0.85rem;
  max-width: 920px;
}
.reactive-config-section-head { display: grid; gap: 0.25rem; }
.reactive-config-section-head h2 { margin: 0; }
.reactive-config-section-head p { margin: 0; }
.reactive-config-actions {
  display: flex;
  justify-content: flex-end;
  max-width: 920px;
}

/* Trust mode picker (replaces the old radio-with-label list) */
.trust-mode-picker {
  display: grid;
  gap: 0.7rem;
}
.trust-mode-card {
  display: flex;
  align-items: flex-start;
  gap: 0.75rem;
  border: 1px solid var(--color-rule);
  border-radius: 2px;
  padding: 0.85rem 1rem;
  background: var(--color-bg);
  cursor: pointer;
  transition: border-color 0.15s ease, background 0.15s ease;
}
.trust-mode-card:hover { border-color: var(--color-rule-strong); }
.trust-mode-card--active {
  border-color: var(--color-oxblood);
  background: var(--color-bg-tint);
  box-shadow: 0 0 0 2px rgba(92, 31, 31, 0.10);
}
.trust-mode-card-input { margin-top: 0.25rem; flex-shrink: 0; }
.trust-mode-card-body { display: grid; gap: 0.25rem; }
.trust-mode-card-name { font-weight: 600; font-size: 1rem; color: var(--color-text); }
.trust-mode-card-summary { line-height: 1.4; }
.trust-mode-card-detail { line-height: 1.45; font-style: italic; opacity: 0.85; }

/* Generic config form field — consistent labels + inputs */
.reactive-config-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 0.85rem;
  align-items: start;
}
.reactive-config-field { display: grid; gap: 0.35rem; }
.reactive-config-label {
  font-family: var(--font-mono);
  font-size: var(--type-eyebrow);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--color-muted);
}
.reactive-config-field input[type="text"],
.reactive-config-field input[type="email"],
.reactive-config-field input[type="url"],
.reactive-config-field input[type="number"],
.reactive-config-field input[type="time"],
.reactive-config-field select {
  width: 100%;
  box-sizing: border-box;
  min-height: 42px;
  font-family: var(--font-sans);
  font-size: 16px;
  line-height: 1.4;
  padding: 0.5rem 0.65rem;
  background: var(--color-bg);
  color: var(--color-text);
  border: 1px solid var(--color-rule-strong);
  border-radius: 2px;
}
/* Equalise the native select arrow inset so the visible text baseline
   sits at the same position as the time inputs. Custom inset arrow as
   a background SVG; suppresses the Chromium native dropdown caret. */
.reactive-config-field select {
  appearance: none;
  -webkit-appearance: none;
  -moz-appearance: none;
  padding-right: 2rem;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6' fill='none'><path d='M1 1L5 5L9 1' stroke='%23555' stroke-width='1.4' stroke-linecap='round' stroke-linejoin='round'/></svg>");
  background-repeat: no-repeat;
  background-position: right 0.7rem center;
  background-size: 10px 6px;
}
.reactive-config-field input:focus,
.reactive-config-field select:focus {
  outline: none;
  border-color: var(--color-oxblood);
  box-shadow: 0 0 0 3px rgba(92, 31, 31, 0.12);
}
.reactive-config-help { line-height: 1.4; }
.reactive-config-checkbox {
  display: flex;
  align-items: flex-start;
  gap: 0.55rem;
  padding: 0.35rem 0;
  cursor: pointer;
  line-height: 1.4;
}
.reactive-config-checkbox input[type="checkbox"] {
  margin-top: 0.25rem;
  flex-shrink: 0;
}

/* Nominees */
.reactive-nominee-list .reactive-nominee-row { justify-content: space-between; }
.reactive-nominee-identity { display: grid; gap: 0.15rem; }
.reactive-nominee-add {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 0.75rem;
  align-items: end;
  margin-top: 0.85rem;
  padding-top: 0.85rem;
  border-top: 1px solid var(--color-rule);
}
.reactive-nominee-add-actions { display: flex; align-items: end; }
/* Member-picker variant: label on its own row, then a flex row with
   the select + button (forced to identical heights so the picker
   caret baseline sits exactly on the button text baseline), then
   help text below. Avoids the previous `align-items: end` problem
   where the button bottom aligned with the help text bottom instead
   of the select bottom. */
.reactive-nominee-add-member {
  display: grid;
  gap: 0.35rem;
  margin-top: 0.85rem;
}
.reactive-nominee-member-controls {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem;
  align-items: stretch;
}
.reactive-nominee-member-controls select {
  flex: 1 1 260px;
  box-sizing: border-box;
  min-height: 42px;
  font-family: var(--font-sans);
  font-size: 16px;
  line-height: 1.4;
  padding: 0.5rem 2rem 0.5rem 0.65rem;
  background-color: var(--color-bg);
  color: var(--color-text);
  border: 1px solid var(--color-rule-strong);
  border-radius: 2px;
  appearance: none;
  -webkit-appearance: none;
  -moz-appearance: none;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6' fill='none'><path d='M1 1L5 5L9 1' stroke='%23555' stroke-width='1.4' stroke-linecap='round' stroke-linejoin='round'/></svg>");
  background-repeat: no-repeat;
  background-position: right 0.7rem center;
  background-size: 10px 6px;
}
.reactive-nominee-member-controls select:focus {
  outline: none;
  border-color: var(--color-oxblood);
  box-shadow: 0 0 0 3px rgba(92, 31, 31, 0.12);
}
.reactive-nominee-member-controls .btn {
  align-self: stretch;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 42px;
  white-space: nowrap;
}
.reactive-nominee-add-divider {
  margin: 0.9rem 0 0.4rem;
  text-align: center;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

/* Library — wraps each watch in a card */
.reactive-library-section { margin: 1.4rem 0; }
.reactive-library-section-head { margin-bottom: 0.7rem; }
.reactive-library-section-head h2 { margin: 0 0 0.3rem; }
.reactive-watch-list { gap: 0.7rem; }
.reactive-watch-row {
  display: grid !important;
  align-items: stretch !important;
  gap: 0.5rem;
  padding: 0.9rem 1rem !important;
}
.reactive-watch-head {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.45rem;
}
.reactive-watch-url { word-break: break-all; }
.reactive-watch-url a { color: inherit; text-decoration: underline; }
.reactive-watch-settings { margin-top: 0.35rem; }
.reactive-watch-settings > summary { width: fit-content; }
.reactive-watch-form {
  margin-top: 0.7rem;
  display: grid;
  gap: 1rem;
}
.reactive-watch-form-block {
  border: 1px solid var(--color-rule);
  border-radius: 2px;
  padding: 0.85rem 1rem;
  background: var(--color-bg-tint);
  display: grid;
  gap: 0.7rem;
}
.reactive-watch-form-heading {
  margin: 0 0 0.25rem;
  font-size: 0.95rem;
  font-weight: 600;
}
.reactive-watch-form-grid {
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
}
.reactive-watch-form-field--wide { grid-column: 1 / -1; }
.reactive-watch-form-actions { display: flex; justify-content: flex-end; }
.reactive-watch-remove { align-self: flex-end; }

/* Add-private grid */
.reactive-add-private-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 0.85rem;
  margin-top: 0.6rem;
}
.reactive-add-private-form {
  border: 1px solid var(--color-rule);
  border-radius: 2px;
  padding: 0.85rem 1rem;
  background: var(--color-bg);
  display: grid;
  gap: 0.6rem;
}
.reactive-add-private-heading {
  margin: 0 0 0.25rem;
  font-size: 0.95rem;
  font-weight: 600;
}

/* Queue provenance block */
.reactive-draft-card .draft-card-head { margin-bottom: 0.4rem; }
.reactive-provenance {
  display: grid;
  gap: 0.25rem;
  padding: 0.5rem 0.7rem;
  background: var(--color-bg-tint);
  border-left: 2px solid var(--color-rule-strong);
  border-radius: 2px;
  margin-bottom: 0.65rem;
  line-height: 1.5;
}
.reactive-provenance strong { color: var(--color-text); font-weight: 600; }
.reactive-draft-foot { align-items: stretch; }
.reactive-reject-form {
  display: flex;
  align-items: end;
  gap: 0.5rem;
  flex: 1;
}
.reactive-reject-label {
  display: grid;
  gap: 0.25rem;
  flex: 1;
}
.reactive-reject-label input {
  width: 100%;
  font-family: var(--font-sans);
  font-size: 16px;
  padding: 0.45rem 0.6rem;
  background: var(--color-bg);
  border: 1px solid var(--color-rule-strong);
  border-radius: 2px;
}

/* Inline edit form on the reactive queue card (parity with the Review
   queue). 16px inputs avoid the iOS zoom-on-focus; 44px Save button meets
   the touch floor (CLAUDE.md rule 7). */
.reactive-edit-form {
  display: grid;
  gap: 0.5rem;
  margin-bottom: 0.65rem;
}
.reactive-edit-form textarea {
  width: 100%;
  font-family: var(--font-sans);
  font-size: 16px;
  line-height: 1.5;
  min-height: 88px;
  padding: 0.55rem 0.7rem;
  background: var(--color-bg);
  border: 1px solid var(--color-rule-strong);
  border-radius: 2px;
  resize: vertical;
}
.reactive-edit-link {
  display: grid;
  gap: 0.25rem;
}
.reactive-edit-link input {
  width: 100%;
  font-family: var(--font-sans);
  font-size: 16px;
  padding: 0.45rem 0.6rem;
  background: var(--color-bg);
  border: 1px solid var(--color-rule-strong);
  border-radius: 2px;
}
.reactive-edit-actions {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.6rem;
}
.reactive-edit-actions .btn { min-height: 44px; }

/* Heightened-review banner on overview */
.reactive-heightened-banner {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.55rem;
  border-left: 3px solid var(--color-status-warn-fg);
  background: var(--color-status-warn-bg);
  padding: 0.7rem 1rem;
  margin: 0 0 1.2rem;
  font-size: var(--type-small);
}

/* Trust card on overview */
.reactive-trust-card .reactive-trust-card-name {
  font-family: var(--font-serif);
  font-size: 1.4rem;
  font-weight: 500;
  letter-spacing: -0.01em;
  line-height: 1.2;
  margin: 0;
  color: var(--color-text);
}

/* Mobile adjustments */
@media (max-width: 720px) {
  .reactive-watch-form-grid { grid-template-columns: 1fr; }
  .reactive-nominee-add { grid-template-columns: 1fr; }
  .reactive-add-private-grid { grid-template-columns: 1fr; }
  .reactive-reject-form { flex-direction: column; align-items: stretch; }
  .trust-mode-card { padding: 0.7rem 0.85rem; }
}

/* ================================================================== */
/* Post Room — notification preferences                                 */
/* ================================================================== */

.postroom-nominee-flags {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex-wrap: wrap;
}

.postroom-flag-label {
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  gap: 0.2rem;
  min-height: 44px;
  justify-content: center;
  cursor: pointer;
}

.postroom-flag-abbr {
  font-family: var(--font-mono);
  font-size: var(--type-small);
  font-weight: 600;
  letter-spacing: 0.04em;
  color: var(--color-oxblood);
}

.postroom-flag-off {
  opacity: 0.35;
}

.postroom-nominee-flags--readonly {
  display: flex;
  gap: 0.6rem;
  align-items: center;
}

/* On very narrow screens, stack the flags below the identity row */
@media (max-width: 420px) {
  .postroom-nominee-flags {
    order: 3;
    width: 100%;
    justify-content: flex-start;
    padding-top: 0.25rem;
  }
}

/* ---------------------------------------------------------------------------
   Reactive catalogue: grouped pick list + checkbox bulk-subscribe bar
   --------------------------------------------------------------------------- */
.catalogue-subscribe-form {
  margin-top: 0.5rem;
}

.catalogue-group {
  border: 1px solid var(--color-rule);
  border-radius: 2px;
  margin-bottom: 0.7rem;
  background: var(--color-bg);
}

.catalogue-group-summary {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.7rem 0.9rem;
  cursor: pointer;
  font-weight: 600;
  list-style: none;
  min-height: 44px;
}
.catalogue-group-summary::-webkit-details-marker { display: none; }
.catalogue-group-summary::before {
  content: "\25B8"; /* triangle marker */
  color: var(--color-muted);
  transition: transform 0.15s ease;
}
.catalogue-group[open] > .catalogue-group-summary::before {
  transform: rotate(90deg);
}
.catalogue-group-title { flex: 1; }
.catalogue-group-summary:focus-visible {
  outline: 2px solid var(--color-oxblood, currentColor);
  outline-offset: 2px;
}

.catalogue-pick-list {
  list-style: none;
  margin: 0;
  padding: 0 0.5rem 0.4rem;
}
.catalogue-pick-row {
  border-top: 1px solid var(--color-rule);
}
.catalogue-pick {
  display: flex;
  align-items: flex-start;
  gap: 0.7rem;
  padding: 0.65rem 0.5rem;
  cursor: pointer;
  min-height: 44px;
}
.catalogue-pick-check {
  flex: 0 0 auto;
  width: 20px;
  height: 20px;
  margin-top: 0.15rem;
}
.catalogue-pick-body {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
}
.catalogue-pick-head {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.4rem;
}
.catalogue-pick-blurb { line-height: 1.35; }

.catalogue-bulk-bar {
  position: sticky;
  bottom: 0;
  z-index: 4;
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 0.8rem;
  margin-top: 0.6rem;
  padding: 0.6rem 0.9rem;
  background: var(--color-bg);
  border: 1px solid var(--color-rule);
  border-radius: 2px;
  box-shadow: 0 -2px 10px rgba(0, 0, 0, 0.08);
}
.catalogue-bulk-count { margin-right: auto; }

/* Keep the sticky bar clear of the fixed mobile bottom tab bar. */
@media (max-width: 720px) {
  .catalogue-bulk-bar {
    bottom: calc(var(--bottom-tab-height, 56px) + var(--bottom-tab-clearance, 8px));
  }
}

@media (prefers-reduced-motion: reduce) {
  .catalogue-group-summary::before { transition: none; }
}

/* Full-width cell in the reactive config grid (CSV / long text inputs). */
.reactive-config-field--wide { grid-column: 1 / -1; }

/* Batch-edit bar above the RSS source list: pick a setting + value, apply to
   selected rows or all. Sits outside the per-source cards. */
.reactive-batch-bar {
  margin: 0.6rem 0;
  padding: 0.7rem 0.9rem;
  background: var(--color-bg);
  border: 1px solid var(--color-rule);
  border-radius: 2px;
}
.reactive-batch-intro { margin: 0 0 0.6rem; max-width: 70ch; }
.reactive-batch-controls {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  gap: 0.8rem;
}
.reactive-batch-controls .reactive-batch-field { margin: 0; min-width: 13rem; }
/* Only the value control matching the chosen setting shows. The [hidden]
   attribute alone loses to `.reactive-config-field { display: grid }`, so we
   force it here. JS toggles `hidden` on the non-matching controls. */
.reactive-batch-field[hidden] { display: none !important; }
.reactive-batch-actions {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  margin-left: auto;
  align-self: flex-end;
}
.reactive-batch-selectall {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  margin: 0 0 0.4rem;
}
.reactive-batch-check { margin-right: 0.5rem; }
