:root {
  /* Theme tokens — neutral defaults, overridden per-campaign by themes/<slug>.css.
     The shared chrome (form layout, highlight box, action buttons, header,
     footer) reads these. To brand a campaign, set theme=<slug> on the
     campaign and have themes/<slug>.css override the values you care about. */

  --theme-fg: #1a1a1a;
  --theme-fg-muted: #666;
  --theme-bg-page: #fafafa;
  --theme-bg-card: #ffffff;
  --theme-border: #ddd;
  --theme-primary: #c3202e;
  --theme-primary-dark: #a11a26;
  --theme-secondary: #044f9d;
  --theme-secondary-dark: #03306a;
  --theme-accent: var(--theme-primary);
  --theme-on-primary: #ffffff;
  --theme-on-secondary: #ffffff;
  --theme-font-body: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  --theme-font-heading: Georgia, "Times New Roman", serif;

  /* Highlight box — themes can override the border treatment. The
     baseline is a single-color thin border; LA replaces it with the
     blue/red striped look, Signature replaces it with a gold left-edge. */
  --theme-highlight-bg: var(--theme-bg-card);
  --theme-highlight-border: 1px solid var(--theme-border);
  --theme-highlight-border-left: 4px solid var(--theme-primary);
  --theme-highlight-radius: 4px;

  /* Page title (the H1 / section heading shown above campaign content) */
  --theme-page-title-color: var(--theme-fg);
  --theme-page-title-transform: none;
  --theme-page-title-letter-spacing: normal;

  /* Header / footer chrome — themes set bg + colors. Header height is
     auto by default; LA uses the banner SVG so we let it set its own. */
  --theme-header-bg: transparent;
  --theme-header-fg: var(--theme-fg);
  --theme-footer-bg: var(--theme-secondary);
  --theme-footer-fg: var(--theme-on-secondary);

  /* Button look — themes can override font/weight/border without
     overriding the whole .public-button rule. */
  --theme-button-font: var(--theme-font-body);
  --theme-button-weight: 500;
  --theme-button-border-width: 1px;
  --theme-button-radius: 4px;

  /* Spacing scale (used by theme-aware components) */
  --space-xs: 0.25rem;
  --space-sm: 0.5rem;
  --space-md: 1rem;
  --space-lg: 1.5rem;
  --space-xl: 2rem;
  --space-xxl: 3rem;

  /* Backwards-compat aliases — the old `--la-*` and short names still
     resolve to theme tokens so admin templates and a few stragglers keep
     working without a rename pass. */
  --la-red: var(--theme-primary);
  --la-red-dark: var(--theme-primary-dark);
  --la-blue: var(--theme-secondary);
  --la-white: #ffffff;
  --la-black: #000000;
  --la-font-body: var(--theme-font-body);
  --la-font-heading: var(--theme-font-heading);
  --la-spacing-xs: var(--space-xs);
  --la-spacing-sm: var(--space-sm);
  --la-spacing-md: var(--space-md);
  --la-spacing-lg: var(--space-lg);
  --la-spacing-xl: var(--space-xl);
  --la-spacing-xxl: var(--space-xxl);

  --fg: var(--theme-fg);
  --muted: var(--theme-fg-muted);
  --bg: var(--theme-bg-page);
  --accent: var(--theme-accent);
  --border: var(--theme-border);
  --error: #b00020;
  --success: #1e7c35;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  font: 16px/1.5 var(--theme-font-body);
  color: var(--theme-fg);
  background: var(--theme-bg-page);
}

main {
  max-width: 800px;
  margin: 0 auto;
  padding: 1.5rem 1rem 4rem;
}

.site-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0.75rem 1rem;
  background: white;
  border-bottom: 1px solid var(--border);
}

.brand {
  font-weight: 700;
  text-decoration: none;
  color: var(--accent);
  font-size: 1.1rem;
}

nav a, nav .link-button {
  margin-left: 1rem;
  text-decoration: none;
  color: var(--fg);
}

.inline { display: inline; margin: 0; }
.link-button {
  background: none; border: none; color: var(--fg);
  cursor: pointer; padding: 0; font: inherit;
  text-decoration: underline;
}

h1, h2, h3 { line-height: 1.2; }

a { color: var(--accent); }

label { display: block; margin-top: 0.75rem; font-weight: 600; }
input[type="text"], input[type="email"], input[type="password"],
input[type="url"], textarea, select {
  width: 100%;
  padding: 0.5rem;
  border: 1px solid var(--border);
  border-radius: 4px;
  font: inherit;
}
textarea { min-height: 8rem; font-family: ui-monospace, "SF Mono", Consolas, monospace; }

.row { display: grid; grid-template-columns: 1fr 1fr; gap: 0.75rem; }
.row-3 { display: grid; grid-template-columns: 2fr 1fr 1fr; gap: 0.75rem; }

.form-grid {
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: 0.5rem 0.75rem;
  align-items: baseline;
  margin-top: 1rem;
}
.form-grid label,
.form-grid input { margin: 0; }
.form-grid .skip-label { grid-column: 2; }
.form-grid .optional-hint {
  font-size: 0.85em;
  font-style: italic;
  color: var(--muted);
  margin-top: 0.15rem;
}

/* <details> styled with the disclosure trigger looking like a regular button.
   Apply to a <details> wrapper whose <summary> should read as a plain button
   (no triangle, no plus, no card outline on the summary itself). */
.disclosure-button summary {
  display: inline-block;
  list-style: none;
  padding: 0.5rem 1rem;
  background: var(--accent);
  color: white;
  border-radius: 4px;
  cursor: pointer;
  font: inherit;
}
.disclosure-button summary::-webkit-details-marker { display: none; }
.disclosure-button summary::marker { content: ""; }
.disclosure-button > .card { margin-top: 0.75rem; }

button, .button {
  display: inline-block;
  padding: 0.5rem 1rem;
  background: var(--accent);
  color: white;
  border: none;
  border-radius: 4px;
  font: inherit;
  text-decoration: none;
  cursor: pointer;
}
button.secondary, .button.secondary {
  background: white;
  color: var(--fg);
  border: 1px solid var(--border);
}
button.danger { background: var(--error); }

.flashes { list-style: none; padding: 0; max-width: 800px; margin: 1rem auto; }
.flash { padding: 0.5rem 0.75rem; border-radius: 4px; margin: 0.25rem 1rem; }
.flash-error { background: #fde7ea; color: var(--error); }

.danger-zone {
  background: #fde7ea;
  border: 1px solid #f3b8be;
  border-radius: 6px;
  padding: 1rem 1.25rem 1.25rem;
  margin-top: 2rem;
}
.danger-zone > h2 { margin-top: 0; }
.danger-zone > form { margin: 0; }
.flash-success { background: #e6f4ea; color: var(--success); }

.card {
  background: white;
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 1rem;
  margin-bottom: 1rem;
}

.muted { color: var(--muted); font-size: 0.9rem; }

.not-found {
  text-align: center;
  padding: 4rem 1rem;
}
.not-found-code {
  font-size: 4rem;
  font-weight: 700;
  color: var(--muted);
  letter-spacing: 0.05em;
  margin: 0 0 0.5rem;
}
.not-found h1 {
  margin: 0 0 0.5rem;
  font-size: 1.5rem;
}

.details-readonly {
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: 0.25rem 0.75rem;
  margin: 0.5rem 0 0;
  font-size: 0.95rem;
}
.details-readonly dt { color: var(--muted); }
.details-readonly dd { margin: 0; }
details[open] > summary > .details-readonly,
details[open] > summary > .edit-hint { display: none; }

/* Inline consent rows (checkbox + wrapping label text). The label is the
   click target and wraps the input + the explanatory copy. */
.consent-row {
  display: flex;
  gap: 0.5rem;
  align-items: flex-start;
  font-weight: 400;
  font-size: 0.95rem;
  line-height: 1.4;
}
.consent-row input[type="checkbox"] {
  margin-top: 0.2rem;
  flex-shrink: 0;
}

.consent-block { margin-top: 1rem; }
.consent-demo { margin-top: 0.5rem; margin-left: 1.5rem; font-size: 0.9rem; }
.consent-demo > summary { color: var(--accent); }
.consent-demo-table {
  width: 100%;
  border-collapse: collapse;
  margin-top: 0.5rem;
  font-size: 0.95rem;
  table-layout: fixed;
}
.consent-demo-table th,
.consent-demo-table td {
  text-align: left;
  padding: 0.2rem 0.5rem;
  vertical-align: top;
  font-weight: 400;
  word-break: break-word;
}
.consent-demo-table th:first-child,
.consent-demo-table td:first-child { width: 14rem; }
.consent-demo-table thead th {
  font-size: 0.85rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--muted);
  border-bottom: 1px solid var(--border);
}
.consent-demo-table tbody th {
  color: var(--muted);
}

.target-list {
  list-style: none;
  padding: 0;
  margin: 0;
}

/* Section header with an action button (e.g. "+ Add target") aligned to
   the right of the H2. The header replaces the H2's natural top margin
   so the section break stays visible. */
.section-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 1rem;
  flex-wrap: wrap;
  margin-top: 1.5rem;
}
.section-header > h1,
.section-header > h2 { margin: 0; }
.section-header > form { margin: 0; }
.section-header > .header-actions {
  display: flex;
  gap: 0.5rem;
  flex-wrap: wrap;
}

/* Two-column grid: drag handle on the left (aligned with the H2 above),
   target name + meta both pinned to column 2 so wrapped text stays
   past the handle and never slides back under it. */
.target-row {
  display: grid;
  grid-template-columns: auto 1fr;
  grid-template-areas:
    "handle main"
    ".      meta";
  column-gap: 0.5rem;
  row-gap: 0.4rem;
  padding: 0.6rem 0;
  border-bottom: 1px solid var(--border);
}
.target-row:last-child { border-bottom: none; }
.target-row .actions { white-space: nowrap; }
.target-row.dragging { opacity: 0.4; }
.target-row > .drag-handle { grid-area: handle; margin-right: 0; }
.target-row-main { grid-area: main; }
.target-row-meta {
  grid-area: meta;
  display: flex;
  align-items: center;
  gap: 0.75rem;
  flex-wrap: wrap;
}
.target-row-report {
  padding: 0.25rem 0.6rem;
  font-size: 0.9rem;
}
.target-row .drag-handle,
.reorder-row .drag-handle {
  display: inline-block;
  margin-right: 0.5rem;
  color: var(--muted);
  cursor: grab;
  user-select: none;
  font-size: 1.1em;
  letter-spacing: -2px;
}
.target-row .drag-handle:active,
.reorder-row .drag-handle:active { cursor: grabbing; }

/* Inline disclosure row for admin lists where each row expands into an
   edit form. Styled to match the tighter `.target-row` look on the
   Campaigns page rather than the heavier `.card` look. */
.reorder-row {
  border-bottom: 1px solid var(--border);
}
.reorder-row:last-child { border-bottom: none; }
.reorder-row.dragging { opacity: 0.4; }
.reorder-row > summary {
  list-style: none;
  cursor: pointer;
  padding: 0.5rem 0;
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex-wrap: wrap;
}
.reorder-row > summary::-webkit-details-marker { display: none; }
.reorder-row > summary::marker { content: ""; }
.reorder-row[open] > form {
  padding: 0.25rem 0 1rem 1.25rem;
  border-left: 2px solid var(--border);
  margin-left: 0.5rem;
}

.kind-badge {
  display: inline-block;
  font-size: 0.75rem;
  padding: 0.1rem 0.4rem;
  border-radius: 3px;
  background: #eee;
  margin-left: 0.5rem;
}
.kind-email { background: #d6e9ff; }
.kind-letter { background: #fde9c2; }

/* Tight tabular view of response submissions on the admin target page.
   Wraps in a horizontally-scrolling container so wide rows (many
   parameters) don't blow out the page width. Redacted rows get a faint
   tint so they read as "missing PII by design". */
.respondents-scroll {
  overflow-x: auto;
  border: 1px solid var(--border);
  border-radius: 4px;
  margin-top: 1rem;
}
.respondents-table {
  border-collapse: collapse;
  font-size: 0.85rem;
  width: max-content;
  min-width: 100%;
}
.respondents-table th,
.respondents-table td {
  padding: 0.3rem 0.5rem;
  text-align: left;
  vertical-align: top;
  border-bottom: 1px solid var(--border);
  white-space: nowrap;
  max-width: 18rem;
  overflow: hidden;
  text-overflow: ellipsis;
}
.respondents-table thead th {
  background: #f5f5f5;
  font-weight: 600;
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--muted);
  position: sticky;
  top: 0;
  z-index: 1;
}
.respondents-table tbody tr:hover { background: #fafafa; }
.respondents-table tbody tr.redacted { background: #fbf6ec; }
.respondents-table tbody tr.redacted:hover { background: #f7eed8; }
.respondents-table .num { color: var(--muted); text-align: right; }
.respondents-table .bool { text-align: center; }
.respondents-table .nowrap { white-space: nowrap; }

/* Target report — summary stats, weekly bar chart, per-recipient table. */
.report-stats {
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: 0.5rem 1.5rem;
  margin: 0;
}
.report-stats dt { color: var(--muted); align-self: center; }
.report-stats dd { margin: 0; font-size: 1.25rem; font-weight: 600; }
.report-stats dd .muted { font-weight: 400; font-size: 0.9rem; margin-left: 0.5rem; }

.weekly-chart {
  display: grid;
  grid-template-columns: max-content 1fr max-content;
  gap: 0.35rem 0.75rem;
  align-items: center;
  margin-top: 0.5rem;
  max-width: 700px;
}
.weekly-label {
  color: var(--muted);
  font-size: 0.85rem;
  white-space: nowrap;
}
.weekly-bar-track {
  background: #f0f0f0;
  border-radius: 3px;
  height: 1.1rem;
  overflow: hidden;
}
.weekly-bar-fill {
  background: var(--accent);
  height: 100%;
  min-width: 2px;
}
.weekly-count {
  font-variant-numeric: tabular-nums;
  text-align: right;
  min-width: 2.5rem;
  color: var(--muted);
}

table.recipient-counts {
  border-collapse: collapse;
  margin-top: 0.5rem;
  width: 100%;
  max-width: 500px;
}
table.recipient-counts th,
table.recipient-counts td {
  padding: 0.4rem 0.75rem;
  border-bottom: 1px solid var(--border);
  text-align: left;
}
table.recipient-counts th {
  background: #f5f5f5;
  font-weight: 600;
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--muted);
}
table.recipient-counts th.num,
table.recipient-counts td.num {
  text-align: right;
  font-variant-numeric: tabular-nums;
}

/* Substituted-value highlight in rendered letter bodies and previews.
   Browser default is bright yellow; soften it for readability. */
mark {
  background: #fff7d6;
  color: inherit;
  padding: 0 2px;
  border-radius: 2px;
}

@media print {
  .site-header, nav, .no-print { display: none !important; }
  main { max-width: none; padding: 0; }
  body { background: white; }
  .letter { white-space: pre-wrap; }
  /* Don't print the highlight — it muddies the page on real paper. */
  mark { background: transparent; padding: 0; }
}

.letter {
  white-space: pre-wrap;
  font-family: Georgia, "Times New Roman", serif;
  font-size: 1rem;
  line-height: 1.5;
  background: white;
  padding: 1.5rem;
  border: 1px solid var(--border);
  border-radius: 4px;
}

.public-highlight-box.artifact-card > h2 {
  font-size: clamp(1.15rem, 2vw, 1.5rem);
}

.artifact-subject {
  font-size: 1.15rem;
  margin: 0.75rem 0 0.5rem;
}

.artifact-preview-body {
  font-size: 0.9rem;
  padding: 1.25rem;
}

details > summary { cursor: pointer; padding: 0.25rem 0; }

/* Autocomplete popup for the {{ var }} placeholder helper on admin
   artifact body / subject fields. */
.placeholder-popup {
  background: white;
  border: 1px solid var(--border);
  border-radius: 4px;
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.12);
  font-family: ui-monospace, "SF Mono", Consolas, monospace;
  font-size: 0.9rem;
  z-index: 1000;
  max-height: 240px;
  overflow-y: auto;
  display: none;
}
.placeholder-popup-item {
  padding: 0.4rem 0.75rem;
  cursor: pointer;
  white-space: nowrap;
}
.placeholder-popup-item.active,
.placeholder-popup-item:hover {
  background: var(--la-blue);
  color: white;
}

#toast {
  position: fixed;
  bottom: 1.5rem;
  left: 50%;
  transform: translateX(-50%) translateY(20px);
  background: #1a1a1a;
  color: white;
  padding: 0.65rem 1.1rem;
  border-radius: 6px;
  font-size: 0.95rem;
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.18);
  opacity: 0;
  transition: opacity 0.2s ease, transform 0.2s ease;
  pointer-events: none;
  z-index: 1000;
  max-width: 90vw;
}
#toast.toast--visible {
  opacity: 1;
  transform: translateX(-50%) translateY(0);
}

/* ============================================================
   Public-page chrome — the shared scaffolding that every themed
   campaign page sits on top of. Theme-specific colors, fonts, and
   header/footer treatments live in themes/<slug>.css and override
   the variables declared at :root above.
   ============================================================ */

body.public {
  background: var(--theme-bg-page);
  color: var(--theme-fg);
  font-family: var(--theme-font-body);
}
body.public h1,
body.public h2,
body.public h3,
body.public h4 {
  font-family: var(--theme-font-heading);
}

.public-section {
  max-width: 1100px;
  margin: 0 auto;
  padding: var(--space-lg) var(--space-md);
}

/* Public header / footer containers. Markup comes from
   base_public.html driven by app/themes.py: a banner-image header
   renders <img>, a text header renders eyebrow + brand. Themes set
   background/color via tokens and only override layout when they
   want something distinctive. */
.public-header {
  background: var(--theme-header-bg);
  color: var(--theme-header-fg);
}
.public-header a { color: inherit; text-decoration: none; }

/* Banner-image header — kept tight (line-height: 0) so the SVG banner
   touches the page edges without an inherited line-box gap. */
.public-header-banner { display: block; line-height: 0; }
.public-header-banner img {
  display: block;
  width: 100%;
  height: auto;
}

/* Text header — themes set padding + font sizes; this baseline just
   stacks the eyebrow above the brand. */
.public-header-text {
  display: block;
  padding: var(--space-md) var(--space-lg);
}
.public-header-eyebrow {
  display: block;
  font-size: 0.7rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  margin-bottom: var(--space-xs);
}
.public-header-brand {
  display: block;
  font-family: var(--theme-font-heading);
  font-size: 1.1rem;
  font-weight: 500;
}

.public-footer {
  background: var(--theme-footer-bg);
  color: var(--theme-footer-fg);
  margin-top: var(--space-xxl);
  padding: var(--space-lg) var(--space-md);
  text-align: center;
}
.public-footer a { color: inherit; }

/* Page title hero on public list / campaign overview pages. */
.public-page-title {
  font-family: var(--theme-font-heading);
  color: var(--theme-page-title-color);
  font-size: clamp(2rem, 5vw, 3.5rem);
  font-weight: 400;
  text-transform: var(--theme-page-title-transform);
  letter-spacing: var(--theme-page-title-letter-spacing);
  text-align: center;
  margin: var(--space-xl) 0 var(--space-md);
}
.public-page-intro {
  text-align: center;
  max-width: 720px;
  margin: 0 auto var(--space-xl);
  font-size: 1.05rem;
}

/* Campaign titles inside highlight boxes — themes can override
   color/transform via the page-title vars. */
.public-highlight-box h2 {
  font-family: var(--theme-font-heading);
  color: var(--theme-page-title-color);
  font-weight: 400;
  font-size: clamp(1.4rem, 2.8vw, 2rem);
  text-transform: var(--theme-page-title-transform);
  letter-spacing: var(--theme-page-title-letter-spacing);
  margin-top: 0;
  margin-bottom: var(--space-md);
}
.public-highlight-box h2 a {
  color: inherit;
  text-decoration: none;
}
.public-highlight-box h2 a:hover { text-decoration: underline; }

/* Campaign subhead — sentence-case heavier serif between title and blurb. */
.public-subhead {
  font-family: var(--theme-font-heading);
  font-weight: 700;
  font-size: 1.15rem;
  color: var(--theme-fg);
  margin-top: 0;
  margin-bottom: var(--space-md);
}

/* "Take action" section above the target cards on a campaign page. */
.public-take-action {
  margin: var(--space-xl) 0 var(--space-md);
}
.public-take-action-label {
  font-size: 0.8rem;
  font-weight: 700;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--theme-fg-muted);
  margin: 0 0 var(--space-sm);
}
.public-take-action-header {
  font-family: var(--theme-font-heading);
  font-weight: 700;
  font-size: clamp(1.6rem, 3vw, 2.2rem);
  color: var(--theme-fg);
  margin: 0 0 var(--space-md);
}
.public-take-action-blurb {
  font-size: 1.05rem;
  margin: 0;
}

/* Resources section on a campaign page. */
.public-resources {
  margin-top: var(--space-xl);
}
.public-resource-list {
  list-style: none;
  padding: 0;
  margin: 0;
}
.public-resource {
  padding: var(--space-sm) 0;
  border-top: 1px solid var(--theme-border);
}
.public-resource:last-child {
  border-bottom: 1px solid var(--theme-border);
}
.public-resource-category {
  display: block;
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--theme-fg-muted);
  margin-bottom: var(--space-xs);
}
.public-resource-name {
  font-weight: 500;
}

/* Highlight box — visual "card" used for campaign cards, target panels,
   the writer details disclosure, and the artifact previews. The border
   treatment varies by theme (LA uses thick blue + red-left; Signature
   uses a thin gold left-edge), so we expose it via theme variables. */
.public-highlight-box {
  background: var(--theme-highlight-bg);
  border: var(--theme-highlight-border);
  border-left: var(--theme-highlight-border-left);
  border-radius: var(--theme-highlight-radius);
  padding: var(--space-lg);
  margin: var(--space-md) 0;
}
.public-highlight-box h2,
.public-highlight-box h3 { margin-top: 0; }

/* Brand button — primary fills with the theme primary color; secondary
   fills with the theme secondary. Font/weight/border thickness/radius
   come from --theme-button-* tokens so themes can adjust shape without
   re-declaring the whole rule. Hover darkens by default; themes that
   want a cross-color hover (e.g. LA red↔blue flip) override
   .public-button(:hover) directly. */
.public-button {
  display: inline-block;
  padding: var(--space-sm) var(--space-lg);
  background: var(--theme-primary);
  color: var(--theme-on-primary);
  font-family: var(--theme-button-font);
  font-size: 1rem;
  font-weight: var(--theme-button-weight);
  border: var(--theme-button-border-width) solid var(--theme-primary);
  border-radius: var(--theme-button-radius);
  text-align: center;
  text-decoration: none;
  cursor: pointer;
  transition: background 0.2s, color 0.2s, border-color 0.2s;
}
.public-button:hover,
.public-button:focus {
  background: var(--theme-primary-dark);
  border-color: var(--theme-primary-dark);
  color: var(--theme-on-primary);
}
.public-button-secondary {
  background: var(--theme-secondary);
  color: var(--theme-on-secondary);
  border-color: var(--theme-secondary);
}
.public-button-secondary:hover,
.public-button-secondary:focus {
  background: var(--theme-secondary-dark);
  border-color: var(--theme-secondary-dark);
  color: var(--theme-on-secondary);
}
