/* ============================================================
   pack12tx.org — single stylesheet
   Tokens, base, layout, components.
   Mobile-first. No frameworks.
   ============================================================ */

/* ---------- Design tokens ---------- */
:root {
  /* Color — paper, ink, scout red. Deliberately small palette. */
  --c-paper:      #FAF7F2;     /* warm cream page background */
  --c-paper-2:    #F2EDE3;     /* slightly deeper, for sections */
  --c-card:       #FFFFFF;
  --c-ink:        #16181C;     /* near-black, warm navy undertone */
  --c-ink-2:      #3B3F46;     /* secondary text */
  --c-ink-3:      #6B6F77;     /* muted */
  --c-rule:       #DCD5C7;     /* hairline rules on cream */
  --c-rule-2:     #E7E1D4;
  --c-red:        #CE1126;     /* BSA scout red */
  --c-red-deep:   #A60D1E;
  --c-khaki:      #8C7A5B;
  --c-canvas:     #2B2F36;     /* deep ink for footer */
  --c-canvas-2:   #1B1E22;

  /* Type scale — modular, conservative */
  --f-display: "Roboto Slab", "Georgia", "Times New Roman", serif;
  --f-body:    "Source Sans 3", "Helvetica Neue", Helvetica, Arial, sans-serif;
  --f-mono:    "JetBrains Mono", "SF Mono", Menlo, Consolas, monospace;

  --fs-xs:   0.75rem;    /* 12 */
  --fs-sm:   0.875rem;   /* 14 */
  --fs-base: 1rem;       /* 16 */
  --fs-md:   1.125rem;   /* 18 */
  --fs-lg:   1.375rem;   /* 22 */
  --fs-xl:   1.75rem;    /* 28 */
  --fs-2xl:  2.25rem;    /* 36 */
  --fs-3xl:  3rem;       /* 48 */
  --fs-4xl:  3.75rem;    /* 60 */

  /* Spacing scale */
  --s-1:  0.25rem;
  --s-2:  0.5rem;
  --s-3:  0.75rem;
  --s-4:  1rem;
  --s-5:  1.5rem;
  --s-6:  2rem;
  --s-7:  3rem;
  --s-8:  4rem;
  --s-9:  6rem;

  /* Misc */
  --radius:     6px;
  --radius-sm:  3px;
  --shadow-sm:  0 1px 2px rgba(22,24,28,.05);
  --shadow-md:  0 4px 14px rgba(22,24,28,.08);
  --container:  1140px;
  --container-narrow: 720px;
}

/* ---------- Reset-ish ---------- */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0;
  font-family: var(--f-body);
  font-size: var(--fs-base);
  line-height: 1.55;
  color: var(--c-ink);
  background: var(--c-paper);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}
/* Global safety net against horizontal-scroll: any long unbreakable
   string (URLs, location text, technical IDs) inside a text-bearing
   element wraps instead of forcing the layout wider than the viewport.
   `anywhere` only breaks when there's no other option. */
a, p, h1, h2, h3, h4, h5, h6, li, td, dd, dt, blockquote, cite, code, pre {
  overflow-wrap: anywhere;
}
img { max-width: 100%; display: block; }
a { color: var(--c-red-deep); text-decoration: underline; text-underline-offset: 2px; text-decoration-thickness: 1px; }
a:hover { color: var(--c-red); }
h1,h2,h3,h4 { font-family: var(--f-display); font-weight: 700; line-height: 1.15; margin: 0 0 var(--s-4); letter-spacing: -0.01em; }
h1 { font-size: var(--fs-3xl); letter-spacing: -0.02em; }
h2 { font-size: var(--fs-2xl); }
h3 { font-size: var(--fs-xl); }
h4 { font-size: var(--fs-lg); }
p  { margin: 0 0 var(--s-4); text-wrap: pretty; }
hr { border: 0; border-top: 1px solid var(--c-rule); margin: var(--s-6) 0; }

/* ---------- Containers ---------- */
.container        { max-width: var(--container);        margin: 0 auto; padding: 0 var(--s-5); }
.container-narrow { max-width: var(--container-narrow); margin: 0 auto; padding: 0 var(--s-5); }

/* ---------- Eyebrow / micro labels ---------- */
.eyebrow {
  font-family: var(--f-mono);
  font-size: var(--fs-xs);
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--c-ink-3);
  margin: 0 0 var(--s-3);
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
}
.eyebrow::before {
  content: "";
  width: 18px;
  height: 1px;
  background: var(--c-red);
}
.eyebrow.no-rule::before { display: none; }

/* ---------- Buttons ---------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--s-2);
  padding: 14px 22px;
  font-family: var(--f-body);
  font-size: var(--fs-base);
  font-weight: 600;
  line-height: 1;
  text-decoration: none;
  border: 1px solid transparent;
  border-radius: var(--radius);
  cursor: pointer;
  transition: background-color .15s ease, color .15s ease, border-color .15s ease, transform .05s ease;
}
.btn:active { transform: translateY(1px); }
.btn { white-space: nowrap; }
.btn-primary,
a.btn-primary,
a.btn-primary:link,
a.btn-primary:visited {
  background: var(--c-red);
  color: #fff;
  border-color: var(--c-red-deep);
  text-decoration: none;
}
a.btn-primary:hover,
.btn-primary:hover { background: var(--c-red-deep); color: #fff; }
.btn-secondary {
  background: transparent;
  color: var(--c-ink);
  border-color: var(--c-ink);
  text-decoration: none;
}
a.btn-secondary:link, a.btn-secondary:visited { color: var(--c-ink); text-decoration: none; }
.btn-secondary:hover, a.btn-secondary:hover { background: var(--c-ink); color: #fff; }
.btn-ghost {
  background: transparent;
  color: var(--c-ink);
  border-color: var(--c-rule);
  text-decoration: none;
}
a.btn-ghost:link, a.btn-ghost:visited { color: var(--c-ink); text-decoration: none; }
.btn-ghost:hover { border-color: var(--c-ink); color: var(--c-ink); }
.btn-block { width: 100%; }
.btn-lg { padding: 18px 28px; font-size: var(--fs-md); }
/* Compact size for secondary, page-level controls — Log out, Actions
   menu trigger, Filter toggle. Sized to match form inputs (.input /
   .select) so a button next to a search field reads as the same
   control type. Distinguishes from primary in-form actions (Save /
   Send blast) which use the default larger .btn size. */
.btn-sm { padding: 11px 16px; font-size: var(--fs-sm); }

/* ---------- Header / nav ---------- */
/* The wrapper owns the page-level stacking slot for header + mobile
   drawer (z-index:10 over page content). Inside it, the header sits
   at z-index:2 with its full opaque background; the drawer sits at
   z-index:1, so the drawer's slide-down animation visually comes
   from BEHIND the header — both the header's content AND its
   background fully obscure the drawer in transit. */
.site-header-wrap {
  position: relative;
  z-index: 10;
}
.site-header {
  background: var(--c-paper-2);
  border-bottom: 1px solid var(--c-rule);
  position: relative;
  z-index: 2;
}
.site-header__bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-5);
  padding: var(--s-4) 0;
}
.brand {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  text-decoration: none;
  color: var(--c-ink);
}
.brand__mark {
  width: 44px;
  height: 44px;
  flex: 0 0 44px;
  display: block;
  object-fit: contain;
  border-radius: var(--radius-sm);
}
.brand__text {
  display: flex;
  flex-direction: column;
  line-height: 1.1;
}
.brand__name {
  font-family: var(--f-display);
  font-weight: 700;
  font-size: var(--fs-md);
  letter-spacing: -0.01em;
}
.brand__sub {
  font-family: var(--f-mono);
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--c-ink-3);
  margin-top: 2px;
}

.nav {
  display: none;
}
.nav__list {
  list-style: none;
  display: flex;
  align-items: center;
  gap: var(--s-2);
  margin: 0;
  padding: 0;
}

/* All top-level nav items (links and dropdown parents) share one box
   so they line up identically. Scoped to direct children so dropdown
   items don't inherit. */
.nav__list > li { display: flex; align-items: center; }
.nav__list > li > a:not(.btn),
.nav__parent {
  display: inline-flex;
  align-items: center;
  gap: var(--s-1);
  height: 36px;
  padding: 0 var(--s-2);
  background: transparent;
  border: 0;
  border-radius: var(--radius-sm);
  color: var(--c-ink);
  font: inherit;
  font-size: var(--fs-sm);
  font-weight: 500;
  text-decoration: none;
  cursor: pointer;
  white-space: nowrap;
  position: relative;
  transition: background-color .15s ease;
}
/* Red underline = "you are here" (current page or section parent). */
.nav__list > li > a:not(.btn).is-active::after,
.nav__parent.is-active::after {
  content: "";
  position: absolute;
  left: var(--s-2);
  right: var(--s-2);
  bottom: -2px;
  height: 2px;
  background: var(--c-red);
  border-radius: 2px;
}
.nav__list > li > a:not(.btn):hover,
.nav__parent:hover {
  background: var(--c-paper);
}
.nav__parent.is-open {
  background: var(--c-card);
  border: 1px solid var(--c-rule);
  border-bottom-color: var(--c-card);
  border-bottom-left-radius: 0;
  border-bottom-right-radius: 0;
  /* Counter the 1px borders so the box doesn't grow and shift siblings. */
  padding: 0 calc(var(--s-2) - 1px);
}
.nav__cta {
  margin-left: var(--s-3);
  align-items: center;
}

.nav__item { position: relative; }
.nav__caret { transition: transform .15s ease; flex-shrink: 0; }
.nav__parent.is-open .nav__caret { transform: rotate(180deg); }

.nav__dropdown {
  position: absolute;
  top: 100%;
  right: 0;
  z-index: 40;
  min-width: 220px;
  background: var(--c-card);
  border: 1px solid var(--c-rule);
  border-radius: var(--radius-sm);
  border-top-right-radius: 0;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.08);
  padding: 0;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
/* The form wrapper around the logout button uses `display: contents`
   so the button participates in the dropdown's flex layout directly —
   that's what lets the button fill the row width. Separators are drawn
   per-item (top border) with the dropdown's first child cleared, which
   handles both the plain-anchor and form-wrapped-button cases. */
.nav__dropdown-form { display: contents; }
.nav__dropdown-item {
  display: flex;
  align-items: center;
  width: 100%;
  min-height: 40px;
  padding: var(--s-2) var(--s-3);
  color: var(--c-ink);
  font-size: var(--fs-sm);
  font-weight: 500;
  font-family: inherit;
  line-height: 1.3;
  text-decoration: none;
  text-align: left;
  background: transparent;
  border: 0;
  border-top: 1px solid var(--c-rule);
  cursor: pointer;
  white-space: nowrap;
  transition: background-color .12s ease;
}
.nav__dropdown > .nav__dropdown-item:first-child,
.nav__dropdown > form:first-child > .nav__dropdown-item {
  border-top: 0;
}
.nav__dropdown-item:hover,
.nav__dropdown-item:focus-visible {
  background: var(--c-paper);
  color: var(--c-red);
  outline: 0;
}
.nav__dropdown-item.is-active {
  background: var(--c-paper);
  color: var(--c-red);
}

/* mobile menu button */
.nav-toggle {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  border: 1px solid var(--c-rule);
  background: transparent;
  padding: 10px 14px;
  border-radius: var(--radius);
  font-family: var(--f-mono);
  font-size: var(--fs-xs);
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--c-ink);
  cursor: pointer;
}
.nav-toggle__bars {
  display: inline-block;
  width: 16px; height: 10px;
  position: relative;
}
.nav-toggle__bars::before, .nav-toggle__bars::after, .nav-toggle__bars span {
  content: ""; position: absolute; left: 0; right: 0; height: 2px; background: var(--c-ink);
  transition: transform 200ms ease, opacity 150ms ease, top 200ms ease, bottom 200ms ease;
}
.nav-toggle__bars::before { top: 0; }
.nav-toggle__bars span { top: 4px; }
.nav-toggle__bars::after { bottom: 0; }

/* When the menu is open, animate the three bars into an X so the
   button reads as "close". Top + bottom converge on center then
   rotate ±45°; middle bar fades out. */
.nav-toggle.is-open .nav-toggle__bars::before {
  top: 4px;
  transform: rotate(45deg);
}
.nav-toggle.is-open .nav-toggle__bars span {
  opacity: 0;
}
.nav-toggle.is-open .nav-toggle__bars::after {
  bottom: 4px;
  transform: rotate(-45deg);
}

/* ---------- Mobile menu ----------
   Slide-down overlay anchored under the header. The menu sits in the
   document but is taken out of normal flow with `position: absolute`
   so opening it doesn't push page content down (no content-shift
   shock). Closed state is `translateY(-110%)` + `opacity: 0` +
   `pointer-events: none`; opening flips all three.
*/
.mobile-menu {
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  background: var(--c-paper);
  border-top: 1px solid var(--c-rule);
  border-bottom: 1px solid var(--c-rule);
  padding: var(--s-4) 0 var(--s-5);
  transform: translateY(-110%);
  opacity: 0;
  pointer-events: none;
  transition:
    transform 260ms cubic-bezier(0.32, 0.72, 0.24, 1.0),
    opacity 200ms ease-out;
  /* z-index 1 within .site-header-wrap (which is z-index:10 over the
     page). The header is z-index:2, so the drawer paints under it
     and is fully obscured during the slide. */
  z-index: 1;
  box-shadow: 0 12px 24px rgba(15, 23, 42, 0.08);
  /* When closed, prevent any tabbing into hidden links. JS-free fallback
     for the pointer-events guard above. */
  visibility: hidden;
}
.mobile-menu.is-open {
  transform: translateY(0);
  opacity: 1;
  pointer-events: auto;
  visibility: visible;
}

/* Panels system. The root list + sub-panels are stacked at the same
   coordinate; CSS transforms move them in/out as a single
   right-to-left motion when `.is-drilled` toggles on the panels
   container. The panels container's height tracks whichever panel is
   active by way of `display: grid` + grid-template-rows trickery — see
   `.mobile-menu__panel` rules. */
.mobile-menu__panels {
  position: relative;
  overflow: hidden;
  margin-bottom: var(--s-4);
}
.mobile-menu__panel {
  grid-area: 1 / 1;  /* stack on top of each other */
  transition:
    transform 240ms cubic-bezier(0.32, 0.72, 0.24, 1.0),
    opacity 180ms ease-out;
}
.mobile-menu__panels {
  display: grid;
  grid-template-columns: 1fr;
}
/* Root list — visible at start, slides out to the LEFT when drilled. */
.mobile-menu__panel--root {
  transform: translateX(0);
  opacity: 1;
}
.mobile-menu__panels.is-drilled .mobile-menu__panel--root {
  transform: translateX(-22%);
  opacity: 0;
  pointer-events: none;
}
/* Sub-panels — sit off-canvas to the RIGHT, slide in when active. */
.mobile-menu__panel--sub {
  transform: translateX(100%);
  opacity: 0;
  pointer-events: none;
}
.mobile-menu__panel--sub.is-active {
  transform: translateX(0);
  opacity: 1;
  pointer-events: auto;
}
.mobile-menu__list {
  list-style: none;
  padding: 0;
  margin: 0;
}
.mobile-menu__row {
  border-bottom: 1px solid var(--c-rule-2);
}
.mobile-menu__row:last-child { border-bottom: 0; }
.mobile-menu__row-link,
.mobile-menu__row-btn {
  display: flex;
  justify-content: space-between;
  align-items: center;
  width: 100%;
  padding: 14px 0;
  background: transparent;
  border: 0;
  color: var(--c-ink);
  text-decoration: none;
  font-size: var(--fs-md);
  font-family: var(--f-display);
  font-weight: inherit;
  text-align: left;
  cursor: pointer;
}
.mobile-menu__row-link.is-active { color: var(--c-red); }
.mobile-menu__row-link:not(.mobile-menu__row-link--btn)::after {
  content: "›";
  color: var(--c-ink-3);
  font-size: 1.4em;
}
.mobile-menu__row-form { margin: 0; width: 100%; }
.mobile-menu__back {
  display: inline-flex;
  align-items: center;
  gap: var(--s-1);
  padding: var(--s-2) 0;
  margin-bottom: var(--s-1);
  background: transparent;
  border: 0;
  color: var(--c-ink-2);
  font: inherit;
  font-size: var(--fs-sm);
  font-weight: 500;
  cursor: pointer;
}
.mobile-menu__back:hover { color: var(--c-ink); }
.mobile-menu__sub-title {
  font-family: var(--f-display);
  font-size: var(--fs-lg);
  margin: 0 0 var(--s-2);
}

@media (min-width: 880px) {
  .nav { display: flex; align-items: center; }
  .nav-toggle { display: none; }
  .mobile-menu { display: none !important; }
}

/* ---------- Hero ---------- */
.hero {
  position: relative;
  padding: var(--s-7) 0 var(--s-8);
  background: var(--c-paper);
  overflow: hidden;
}
.hero__grid {
  display: grid;
  gap: var(--s-6);
  grid-template-columns: minmax(0, 1fr);
}
.hero__title {
  font-size: var(--fs-3xl);
  letter-spacing: -0.02em;
  margin-bottom: var(--s-4);
}
.hero__title em {
  font-style: normal;
  color: var(--c-red);
}
.hero__lede {
  font-size: var(--fs-md);
  color: var(--c-ink-2);
  max-width: 38ch;
  margin-bottom: var(--s-5);
}
.hero__ctas {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-3);
  align-items: center;
}
.hero__ctas .meta {
  font-family: var(--f-mono);
  font-size: var(--fs-xs);
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--c-ink-3);
  padding-left: var(--s-3);
  border-left: 1px solid var(--c-rule);
}
.hero__media-wrap { display: flex; flex-direction: column; gap: var(--s-2); }
.hero__media {
  position: relative;
  display: block;
  border-radius: var(--radius);
  overflow: hidden;
  aspect-ratio: 4 / 3;
  background: var(--c-paper-2);
  text-decoration: none;
}
.hero__media img { width: 100%; height: 100%; object-fit: cover; }
.hero__media-foot {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--s-3);
  padding: 0 2px;
}
.hero__media-credit {
  font-family: var(--f-mono);
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--c-ink-3);
}
.hero__media-more {
  font-size: var(--fs-sm);
  font-weight: 600;
  color: var(--c-red-deep);
  text-decoration: none;
}
.hero__media-more:hover { color: var(--c-red); text-decoration: underline; }
.hero__factbar {
  margin-top: var(--s-6);
  border-top: 1px solid var(--c-rule);
  border-bottom: 1px solid var(--c-rule);
  padding: var(--s-5) 0;
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-4) var(--s-8);
}
.hero__fact {
  display: flex;
  flex-direction: column;
  min-width: 0;
}
.hero__fact-label {
  font-family: var(--f-mono);
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--c-ink-3);
  margin-bottom: 6px;
}
.hero__fact-value {
  font-family: var(--f-display);
  font-size: var(--fs-md);
  color: var(--c-ink);
  font-weight: 700;
  line-height: 1.2;
  white-space: nowrap;
}
a.hero__fact-value { text-decoration: none; }
a.hero__fact-value:hover { color: var(--c-red-deep); text-decoration: underline; }

@media (min-width: 880px) {
  .hero { padding: var(--s-8) 0 var(--s-9); }
  .hero__grid {
    grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr);
    gap: var(--s-7);
    align-items: center;
  }
  .hero__title { font-size: var(--fs-4xl); }
  .hero__factbar {
    padding: var(--s-5) 0;
    gap: var(--s-4) var(--s-9);
  }
}

/* ---------- Section header ---------- */
.section { padding: var(--s-8) 0; }
.section--alt { background: var(--c-paper-2); }
.section__head {
  display: flex;
  flex-direction: column;
  gap: var(--s-2);
  margin-bottom: var(--s-6);
}
.section__head-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--s-4);
  flex-wrap: wrap;
}
.section__head h2 { margin: 0; }
.section__head a { font-size: var(--fs-sm); }

/* ---------- Two-column home grid: events + announcement ---------- */
.home-grid {
  display: grid;
  gap: var(--s-6);
  grid-template-columns: minmax(0, 1fr);
}
@media (min-width: 880px) {
  .home-grid { grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr); gap: var(--s-7); }
}
.home-section__cta {
  margin-top: var(--s-5);
  display: flex;
  justify-content: flex-start;
}

/* Events list */
.event-list { list-style: none; margin: 0; padding: 0; }
.event {
  display: grid;
  grid-template-columns: 64px minmax(0, 1fr) auto;
  gap: var(--s-4);
  padding: var(--s-5) 0;
  border-top: 1px solid var(--c-rule);
  align-items: start;
}
.event:last-child { border-bottom: 1px solid var(--c-rule); }
.event__date {
  text-align: center;
  border: 1px solid var(--c-rule);
  border-radius: var(--radius-sm);
  padding: 8px 4px;
  background: var(--c-card);
}
.event__date-mo {
  font-family: var(--f-mono);
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--c-red);
  font-weight: 600;
}
.event__date-day {
  font-family: var(--f-display);
  font-size: var(--fs-xl);
  font-weight: 700;
  line-height: 1;
  margin-top: 2px;
}
.event__body { min-width: 0; }  /* let the 1fr grid column actually shrink */
.event__body h3 {
  font-size: var(--fs-md);
  margin: 0 0 6px;
  overflow-wrap: anywhere;
}
.event__body h3 a { color: var(--c-ink); text-decoration: none; }
.event__body h3 a:hover { color: var(--c-red); text-decoration: underline; }
.event__meta {
  display: flex;
  flex-wrap: wrap;
  gap: 14px;
  font-size: var(--fs-sm);
  color: var(--c-ink-3);
  min-width: 0;
}
.event__meta span { display: inline-flex; align-items: center; gap: 6px; min-width: 0; }
.event__meta a, .event__meta span { overflow-wrap: anywhere; word-break: break-word; }
.event__cta {
  font-family: var(--f-mono);
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--c-red-deep);
  text-decoration: none;
  white-space: nowrap;
  align-self: center;
  padding-top: 4px;
}
.event__cta:hover { color: var(--c-red); }

/* Announcement card */
.announce {
  background: var(--c-card);
  border: 1px solid var(--c-rule);
  border-radius: var(--radius);
  padding: var(--s-5);
  position: relative;
}
.announce__head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: var(--s-3);
  padding-bottom: var(--s-3);
  border-bottom: 1px solid var(--c-rule-2);
}
.announce__pin {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  background: var(--c-red);
  color: #fff;
  padding: 4px 8px;
  border-radius: var(--radius-sm);
  font-family: var(--f-mono);
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  font-weight: 600;
}
.announce__date {
  font-family: var(--f-mono);
  font-size: var(--fs-xs);
  color: var(--c-ink-3);
}
.announce__title {
  font-size: var(--fs-lg);
  margin: 0 0 var(--s-3);
}
.announce__body {
  font-size: var(--fs-base);
  color: var(--c-ink-2);
}
.announce__body p:last-child { margin-bottom: 0; }
.announce__sig {
  margin-top: var(--s-4);
  padding-top: var(--s-3);
  border-top: 1px solid var(--c-rule-2);
  font-size: var(--fs-sm);
  color: var(--c-ink-3);
  font-style: italic;
}

/* ---------- Quick links ---------- */
.quicklinks {
  display: grid;
  gap: var(--s-3);
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
}
@media (min-width: 700px) { .quicklinks { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (min-width: 880px) { .quicklinks { grid-template-columns: repeat(6, minmax(0, 1fr)); } }
.quicklink {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--s-2);
  padding: var(--s-4);
  background: var(--c-card);
  border: 1px solid var(--c-rule);
  border-radius: var(--radius);
  text-decoration: none;
  color: var(--c-ink);
  transition: border-color .15s ease, transform .1s ease;
  min-height: 110px;
}
.quicklink:hover {
  border-color: var(--c-ink);
  color: var(--c-ink);
  transform: translateY(-1px);
}
.quicklink__num {
  font-family: var(--f-mono);
  font-size: 11px;
  letter-spacing: 0.12em;
  color: var(--c-ink-3);
}
.quicklink__title {
  font-family: var(--f-display);
  font-size: var(--fs-md);
  font-weight: 700;
  line-height: 1.2;
}
.quicklink__sub {
  font-size: var(--fs-sm);
  color: var(--c-ink-3);
  margin-top: auto;
}

/* ---------- Inner page (Den) ---------- */
.page-hero {
  background: var(--c-paper);
  border-bottom: 1px solid var(--c-rule);
  padding: var(--s-7) 0 var(--s-6);
}
.crumb {
  font-family: var(--f-mono);
  font-size: var(--fs-xs);
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--c-ink-3);
  margin-bottom: var(--s-4);
}
.crumb a { color: var(--c-ink-3); text-decoration: none; }
.crumb a:hover { color: var(--c-ink); }
.crumb__sep { margin: 0 8px; opacity: .5; }

/* Top bar above the page-hero title row: holds the breadcrumbs on the
   left and an "Edit page" link on the right (staff only — set by the
   pack_info context processor when the current path maps to a CMS
   editor). When neither is present, the wrapper itself isn't rendered. */
.page-hero__topbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-3);
  margin-bottom: var(--s-4);
}
.page-hero__topbar .crumb { margin-bottom: 0; }
/* Shared style for the editor↔public round-trip links — "Edit page →"
   on the public site, "View on site →" in the CMS. Two selectors
   sharing one rule so the two surfaces can't visually drift. */
.page-hero__edit-link,
.cms-public-link {
  font-family: var(--f-mono);
  font-size: var(--fs-xs);
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--c-red);
  text-decoration: none;
  white-space: nowrap;
}
.page-hero__edit-link:hover,
.cms-public-link:hover { text-decoration: underline; }

.page-hero__row {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--s-5);
  align-items: center;
}
@media (min-width: 720px) {
  .page-hero__row { grid-template-columns: minmax(0, 1fr) auto; gap: var(--s-6); }
}
.page-hero__title { font-size: var(--fs-3xl); margin: 0 0 var(--s-2); }
.page-hero__sub {
  font-size: var(--fs-md);
  color: var(--c-ink-2);
  margin: 0;
}
.rank-badge {
  width: 110px;
  height: 110px;
  background: var(--c-card);
  border: 1px solid var(--c-rule);
  border-radius: var(--radius);
  padding: var(--s-3);
  display: grid;
  place-items: center;
}
.rank-badge img { max-width: 100%; max-height: 100%; object-fit: contain; }

/* Calendar filter. The primary row holds Pack 12 events + the
   "Show den calendars" toggle; the den-row drawer expands below
   when the toggle's open. Disabled den options show "no calendar
   yet" via title-attribute tooltips so the bar stays compact. */
.cal-filter {
  padding: var(--s-3) var(--s-4);
  background: var(--c-card);
  border: 1px solid var(--c-rule);
  border-radius: var(--radius);
  margin-bottom: var(--s-5);
}
.cal-filter__primary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-3);
  flex-wrap: wrap;
}
.cal-filter__dens {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  gap: var(--s-1) var(--s-3);
  margin-top: var(--s-3);
  padding-top: var(--s-3);
  border-top: 1px solid var(--c-rule-2);
}
.cal-filter__opt {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  font-size: var(--fs-sm);
  cursor: pointer;
  user-select: none;
}
.cal-filter__opt input[type=checkbox] {
  width: 16px; height: 16px;
  flex-shrink: 0;
  cursor: pointer;
}
.cal-filter__opt-label { white-space: nowrap; }
.cal-filter__opt.is-disabled {
  color: var(--c-ink-3);
  cursor: not-allowed;
}
.cal-filter__opt.is-disabled input[type=checkbox] { cursor: not-allowed; }
/* Subscribe icon — sits inline immediately after the label so the
   parent reads "Wolf (2nd) [icon]" as one unit. 28px square keeps
   the tap target reasonable without bulking the row. */
.cal-filter__sub {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px; height: 28px;
  border-radius: var(--radius-sm);
  color: var(--c-ink-2);
  text-decoration: none;
  flex-shrink: 0;
}
.cal-filter__sub:hover,
.cal-filter__sub:focus-visible { color: var(--c-red); background: var(--c-paper); }
.cal-filter__sub svg { width: 14px; height: 14px; }
/* Toggle that expands/collapses the den-row drawer. */
.cal-filter__toggle {
  background: transparent;
  border: 0;
  padding: 4px 8px;
  font: inherit;
  font-size: var(--fs-sm);
  color: var(--c-red);
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 4px;
}
.cal-filter__toggle:hover { text-decoration: underline; }
.cal-filter__toggle-caret { font-size: 10px; }
@media (max-width: 600px) {
  .cal-filter__dens { grid-template-columns: 1fr 1fr; }
}

/* Bottom subscribe list — every calendar source one row, with a
   subscribe link or a "no calendar yet" stub. Replaces the old
   single "Subscribe to the pack calendar" card so a parent who
   wants to subscribe to a SPECIFIC den isn't tricked into
   subscribing to the whole pack. */
.cal-subscribe-list {
  list-style: none;
  margin: var(--s-3) 0 0;
  padding: 0;
}
.cal-subscribe-list__item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-3);
  padding: var(--s-2) 0;
  border-bottom: 1px solid var(--c-rule-2);
}
.cal-subscribe-list__item:last-child { border-bottom: 0; }
.cal-subscribe-list__label { font-weight: 600; }

/* Den-page hero: rank badge sits inline before the title instead of
   floating off in the right column. Badge gets a touch smaller here
   so it pairs visually with the title without dominating it. */
.den-hero {
  display: flex;
  align-items: center;
  gap: var(--s-5);
  flex-wrap: wrap;
}
.den-hero__badge {
  width: 88px;
  height: 88px;
  flex-shrink: 0;
}
/* Grade eyebrow above the den-page title — color it the same ink as
   the title so it reads as part of the heading group, not as another
   muted breadcrumb above it. Tighten the margin so eyebrow and h1
   read as one unit. */
.den-hero .eyebrow {
  color: var(--c-ink);
  margin-bottom: 4px;
}

/* Den info block */
.info-block {
  display: grid;
  gap: 0;
  grid-template-columns: minmax(0, 1fr);
  border: 1px solid var(--c-rule);
  border-radius: var(--radius);
  background: var(--c-card);
  /* No top margin — when this block opens an article column it
     should line up with the first sidebar card, not float down. */
  margin: 0 0 var(--s-7);
  overflow: hidden;
}
@media (min-width: 720px) {
  .info-block { grid-template-columns: repeat(3, 1fr); }
}
.info-block__cell {
  padding: var(--s-5);
  border-bottom: 1px solid var(--c-rule-2);
}
@media (min-width: 720px) {
  .info-block__cell { border-bottom: 0; border-right: 1px solid var(--c-rule-2); }
  .info-block__cell:last-child { border-right: 0; }
}
.info-block__cell:last-child { border-bottom: 0; }
.info-block__label {
  font-family: var(--f-mono);
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--c-ink-3);
  margin-bottom: var(--s-2);
}
.info-block__value {
  font-family: var(--f-display);
  font-size: var(--fs-md);
  font-weight: 700;
  line-height: 1.25;
  color: var(--c-ink);
}
.info-block__value a { color: var(--c-ink); text-decoration: none; border-bottom: 1px solid var(--c-rule); }
.info-block__value a:hover { color: var(--c-red); border-bottom-color: var(--c-red); }
.info-block__sub {
  font-size: var(--fs-sm);
  color: var(--c-ink-3);
  margin-top: 4px;
  font-family: var(--f-body);
  font-weight: 400;
}

/* Prose (markdown body) */
.prose {
  max-width: 68ch;
  font-size: var(--fs-md);
  line-height: 1.7;
  color: var(--c-ink);
}
.prose h1 { font-size: var(--fs-3xl); margin-top: var(--s-7); }
.prose h2 { font-size: var(--fs-xl); margin-top: var(--s-6); margin-bottom: var(--s-3); }
.prose h3 { font-size: var(--fs-lg); margin-top: var(--s-5); margin-bottom: var(--s-2); }
.prose p  { margin-bottom: var(--s-4); }
.prose ul, .prose ol { margin: 0 0 var(--s-4) 0; padding-left: 1.4em; }
.prose li { margin-bottom: var(--s-2); }
.prose strong { color: var(--c-ink); }
.prose blockquote {
  margin: var(--s-5) 0;
  padding: var(--s-4) var(--s-5);
  border-left: 3px solid var(--c-red);
  background: var(--c-paper-2);
  font-size: var(--fs-md);
  color: var(--c-ink-2);
  border-radius: 0 var(--radius) var(--radius) 0;
}
.prose blockquote p:last-child { margin-bottom: 0; }
.prose hr { margin: var(--s-6) 0; }

/* page sidebar */
.page-layout {
  display: grid;
  gap: var(--s-7);
  grid-template-columns: minmax(0, 1fr);  /* minmax(0,1fr) lets content shrink past min-content */
  padding: var(--s-7) 0;
}
@media (min-width: 960px) {
  .page-layout { grid-template-columns: minmax(0, 1fr) 280px; gap: var(--s-8); }
}
/* Long unbreakable strings inside article/aside (URLs, location text) must
   wrap rather than force the grid track wider. Belt + suspenders. */
.page-layout > article, .page-layout > aside { min-width: 0; }
.page-layout a, .page-layout .announce, .page-layout .prose { overflow-wrap: anywhere; word-break: break-word; }
.sidebar { display: flex; flex-direction: column; gap: var(--s-5); }
.sidebar-card {
  border: 1px solid var(--c-rule);
  background: var(--c-card);
  border-radius: var(--radius);
  padding: var(--s-5);
}
.sidebar-card h4 {
  font-size: var(--fs-md);
  margin: 0 0 var(--s-3);
  padding-bottom: var(--s-3);
  border-bottom: 1px solid var(--c-rule-2);
}
.sidebar-card ul { list-style: none; margin: 0; padding: 0; }
.sidebar-card li {
  padding: 8px 0;
  font-size: var(--fs-sm);
  border-bottom: 1px dotted var(--c-rule-2);
}
.sidebar-card li:last-child { border-bottom: 0; }
.sidebar-card li a { color: var(--c-ink); text-decoration: none; display: flex; justify-content: space-between; align-items: center; }
.sidebar-card li a:hover { color: var(--c-red); }
.sidebar-card li.is-current a { color: var(--c-red); font-weight: 600; }
.sidebar-card li .grade {
  font-family: var(--f-mono);
  font-size: 11px;
  color: var(--c-ink-3);
}
.sidebar-card--tinted { background: var(--c-paper-2); }

/* Den-leader card on /dens/<rank>/ — square photo on top, name +
   email below, then their bio body rendered with prose styles
   tightened down for the narrower sidebar column. */
.den-leader__photo {
  width: 100%;
  aspect-ratio: 1 / 1;
  object-fit: cover;
  border-radius: var(--radius-sm);
  margin-bottom: var(--s-3);
}
/* When a leader hasn't uploaded a headshot, fall back to the same
   leader-default.svg the CMS list uses — keeps the card's visual
   rhythm and stays consistent across surfaces. */
.den-leader__photo--default {
  background: var(--c-paper-2);
  padding: var(--s-3);
}
.den-leader__name {
  margin: 0;
  font-family: var(--f-display);
  font-size: var(--fs-lg);
  font-weight: 700;
  line-height: 1.2;
}
.den-leader__role {
  margin: 0 0 var(--s-1);
  font-family: var(--f-mono);
  font-size: var(--fs-xs);
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--c-ink-2);
}
.den-leader__alias {
  margin: 4px 0 var(--s-3);
  font-size: var(--fs-sm);
}
.den-leader__alias a { color: var(--c-ink-2); text-decoration: none; }
.den-leader__alias a:hover { color: var(--c-red); text-decoration: underline; }
.den-leader__bio {
  font-size: var(--fs-sm);
  margin-top: var(--s-4);
}
.den-leader__bio p { margin-bottom: var(--s-3); }
.den-leader__bio p:last-child { margin-bottom: 0; }
/* About-page carousel cards: the Prev/Next nav below the card
   needs to sit at the same y-position regardless of which leader
   is showing. Two pieces stabilize it:
     1. Pin the bio to a fixed height (long bios scroll inside).
     2. Pin the whole card to a min-height that absorbs role/name
        wrap differences (e.g. "Advancement Chair" wraps to two
        lines on a narrow sidebar, Cubmaster doesn't).
*/
.den-leader--carousel { min-height: 720px; }
.den-leader--carousel .den-leader__bio {
  height: 380px;
  overflow-y: auto;
  padding-right: var(--s-2);
  scrollbar-gutter: stable;
}
.sidebar-card--tinted h4 { border-bottom-color: var(--c-rule); }

/* Carousel nav below the Pack-leadership card on /about/.
   Each button stacks an arrow icon (big tap target) on top with a
   "Next: <Position>" label below. Previous is hidden when on the
   first leader; Next is hidden on the last. Two-col grid keeps
   each button anchored to its side regardless of the other being
   visible. */
.leader-carousel__nav {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--s-3);
  margin-top: var(--s-4);
  padding-top: var(--s-3);
  border-top: 1px solid var(--c-rule-2);
}
.leader-carousel__btn {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  padding: var(--s-2);
  background: transparent;
  border: 0;
  border-radius: var(--radius-sm);
  font: inherit;
  font-size: var(--fs-xs);
  /* Match the site-wide link color so the carousel buttons sit on
     the same red as "View all leaders" below them and any other
     <a> in body copy. The brighter --c-red is the hover/accent
     shade, not the resting link color. */
  color: var(--c-red-deep);
  cursor: pointer;
  text-align: center;
  line-height: 1.3;
}
.leader-carousel__btn:hover {
  background: var(--c-paper);
  color: var(--c-red);
}
.leader-carousel__btn:hover .leader-carousel__btn-label {
  text-decoration: underline;
}
.leader-carousel__btn--prev { grid-column: 1; }
.leader-carousel__btn--next { grid-column: 2; }
.leader-carousel__btn-label { white-space: normal; }

/* ---------- Event detail map ---------- */
.event-map {
  width: 100%;
  background: var(--c-paper-2);
  border-top: 1px solid var(--c-rule);
  border-bottom: 1px solid var(--c-rule);
}
.event-map iframe {
  display: block;
  width: 100%;
  height: 320px;
  border: 0;
}
@media (min-width: 720px) {
  .event-map iframe { height: 420px; }
}

/* ---------- Form (Join) ---------- */
.join-layout {
  display: grid;
  gap: var(--s-7);
  grid-template-columns: minmax(0, 1fr);
  padding: var(--s-7) 0 var(--s-8);
}
/* On mobile (single-column stack), the form is the primary CTA — pull it
   above the prose. DOM order stays prose-first so desktop keeps the
   editorial reading flow with prose on the left. */
.join-layout > .join-form-col { order: -1; }
.join-layout > .join-intro { order: 0; }
@media (min-width: 960px) {
  .join-layout { grid-template-columns: minmax(0, 1fr) minmax(0, 1.1fr); gap: var(--s-8); align-items: start; }
  .join-layout > .join-form-col,
  .join-layout > .join-intro { order: 0; }
}

/* Right column: form on top, "Already decided?" CTA stacked under it
   so the two alternate paths read as siblings. Without this wrapper
   the second card slotted below the prose column on wide layouts and
   visually drifted away from the form. */
.join-form-col {
  display: flex;
  flex-direction: column;
  gap: var(--s-5);
}

/* Secondary CTA — for parents who already know they want to register
   and don't need the soft-funnel form. Distinct visual treatment so
   it doesn't get confused with the primary form action. */
.join-direct {
  text-align: center;
  padding: var(--s-5) var(--s-4);
  border: 1px dashed var(--c-rule);
  border-radius: var(--radius);
  background: var(--c-paper);
}
.join-direct__lede {
  margin: 0 0 var(--s-3);
  font-family: var(--f-display);
  font-size: var(--fs-lg);
}
.join-direct__note {
  margin: var(--s-3) auto 0;
  max-width: 42ch;
  color: var(--c-ink-2);
  font-size: var(--fs-sm);
}

.join-intro h1 { font-size: var(--fs-2xl); }
.join-intro p { font-size: var(--fs-md); color: var(--c-ink-2); }
.steps { list-style: none; counter-reset: step; padding: 0; margin: var(--s-5) 0; }
.steps li {
  counter-increment: step;
  position: relative;
  padding-left: 44px;
  margin-bottom: var(--s-4);
}
.steps li::before {
  content: counter(step, decimal-leading-zero);
  position: absolute;
  left: 0; top: 1px;
  width: 32px; height: 32px;
  display: grid; place-items: center;
  border: 1px solid var(--c-ink);
  border-radius: var(--radius-sm);
  font-family: var(--f-mono);
  font-size: var(--fs-xs);
  font-weight: 600;
  color: var(--c-ink);
  background: var(--c-paper);
}
.steps strong {
  display: block;
  font-family: var(--f-display);
  font-size: var(--fs-md);
  margin-bottom: 2px;
}
.steps p { margin: 0; color: var(--c-ink-2); font-size: var(--fs-sm); }

.form-card {
  background: var(--c-card);
  border: 1px solid var(--c-rule);
  border-radius: var(--radius);
  padding: var(--s-6);
  position: relative;
}
.form-card h2 { font-size: var(--fs-xl); margin-top: 0; }
.form-card__sub {
  font-size: var(--fs-sm);
  color: var(--c-ink-3);
  margin-bottom: var(--s-5);
}

.field { margin-bottom: var(--s-4); }
.field--row { display: grid; gap: var(--s-4); grid-template-columns: minmax(0, 1fr); }
@media (min-width: 600px) { .field--row { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); } }

.field label, .field__label {
  display: flex;
  justify-content: space-between;
  font-family: var(--f-mono);
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--c-ink-2);
  margin-bottom: 6px;
  font-weight: 600;
}
.field__label .req { color: var(--c-red); }
.field__hint { color: var(--c-ink-3); font-weight: 500; text-transform: none; letter-spacing: 0; font-family: var(--f-body); font-size: var(--fs-xs); }
.field__hint--error { color: var(--c-red); }
.field__hint--error.field__hint--block { margin-bottom: var(--s-4); }

.input, .select, .textarea {
  width: 100%;
  font-family: var(--f-body);
  font-size: var(--fs-base);
  color: var(--c-ink);
  background: var(--c-paper);
  border: 1px solid var(--c-rule);
  border-radius: var(--radius-sm);
  /* Padding tuned so input + .btn render at the same height (~45px),
     keeping fields and buttons visually consistent in toolbars. */
  padding: 10px 14px;
  line-height: 1.4;
  transition: border-color .15s ease, background-color .15s ease;
}
.input:focus, .select:focus, .textarea:focus {
  outline: none;
  border-color: var(--c-ink);
  background-color: #fff;
}
.select {
  appearance: none;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'><path fill='none' stroke='%2316181C' stroke-width='1.5' d='M1 1.5l5 5 5-5'/></svg>");
  background-repeat: no-repeat;
  background-position: right 14px center;
  padding-right: 40px;
}

.privacy {
  margin-top: var(--s-5);
  padding: var(--s-4);
  background: var(--c-paper);
  border: 1px dashed var(--c-rule);
  border-radius: var(--radius-sm);
  font-size: var(--fs-sm);
  color: var(--c-ink-2);
  line-height: 1.5;
}
.privacy strong { color: var(--c-ink); display: block; font-family: var(--f-display); font-size: var(--fs-sm); margin-bottom: 4px; }

.form-actions {
  margin-top: var(--s-5);
  display: flex;
  flex-direction: column;
  gap: var(--s-3);
  align-items: stretch;
}
.form-actions .skip {
  text-align: center;
  font-size: var(--fs-sm);
  color: var(--c-ink-3);
}
.form-actions .skip a { color: var(--c-ink-2); }

/* ---------- Footer ---------- */
.site-footer {
  background-color: var(--c-canvas);
  color: #D9D5CB;
  /* The bottom padding clears the folio band (.site-footer::after).
     Band height = 100vw × 350/2632 (its aspect ratio scales to width).
     Add `var(--s-5)` (~32px) of breathing room so the copyright line
     doesn't sit right against the silhouette. */
  padding: var(--s-8) 0 calc(100vw * 350 / 2632 + var(--s-5));
  margin-top: var(--s-8);
  font-size: var(--fs-sm);
  position: relative;
  overflow: hidden;
}
/* Folio band — full-width scout silhouette anchored to the footer's
   bottom. The PNG is 2632×476 native, but the bottom row is the
   ground line which makes the band visually heavy at wide viewport
   widths; we only need the top portion. The pseudo's aspect ratio is
   set to 2632/350 (the visible crop), and the image is painted at
   100% width with its top anchored. The image's natural height
   (W × 476/2632) overflows the pseudo's height (W × 350/2632) by
   ~8%, which gets clipped by background-clip:padding-box — i.e. the
   ground line falls off the bottom on every viewport width. */
.site-footer::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  aspect-ratio: 2632 / 350;
  background-image: url("../img/Folio_White.c5aede5d9119.png");
  background-position: top center;
  background-size: 100% auto;
  background-repeat: no-repeat;
  pointer-events: none;
  z-index: 0;
}
.site-footer > .container { position: relative; z-index: 1; }
.site-footer a { color: #fff; text-decoration: none; border-bottom: 1px solid rgba(255,255,255,.18); }
.site-footer a:hover { border-bottom-color: var(--c-red); color: #fff; }
/* Brand link is logo + name, not body copy — the underline + red-on-hover
   treatment applies to genuine links in body text only. */
.site-footer a.footer__brand,
.site-footer a.footer__brand:hover { border-bottom: 0; }
.footer-grid {
  display: grid;
  gap: var(--s-6);
  grid-template-columns: minmax(0, 1fr);
}
@media (min-width: 720px) {
  .footer-grid { grid-template-columns: 2fr 1fr 1fr; gap: var(--s-7); }
}
.footer__brand .brand__name, .footer__brand .brand__sub { color: #fff; }
.footer__brand .brand__sub { color: rgba(255,255,255,.55); }
.footer__about {
  margin-top: var(--s-4);
  color: rgba(255,255,255,.7);
  max-width: 38ch;
  line-height: 1.55;
}
.footer__h {
  font-family: var(--f-mono);
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: rgba(255,255,255,.5);
  margin: 0 0 var(--s-3);
}
.footer__list { list-style: none; padding: 0; margin: 0; }
.footer__list li { padding: 6px 0; }
.footer__list a { border-bottom: 0; opacity: .85; }
.footer__list a:hover { opacity: 1; }
.footer__social { display: flex; gap: var(--s-3); margin-top: var(--s-3); }
.footer__social a {
  width: 38px; height: 38px;
  border: 1px solid rgba(255,255,255,.18);
  border-radius: var(--radius-sm);
  display: grid; place-items: center;
  font-family: var(--f-mono);
  font-size: 12px;
  border-bottom: 1px solid rgba(255,255,255,.18);
}
.footer__bottom {
  margin-top: var(--s-7);
  padding-top: var(--s-5);
  border-top: 1px solid rgba(255,255,255,.1);
  display: flex;
  flex-direction: column;
  gap: var(--s-4);
}
.footer__copy {
  font-family: var(--f-mono);
  font-size: var(--fs-xs);
  color: rgba(255,255,255,.5);
  letter-spacing: 0.04em;
  text-align: center;
}
.footer__disclaimer {
  font-size: 12px;
  line-height: 1.6;
  color: rgba(255,255,255,.55);
}
.footer__disclaimer strong { color: rgba(255,255,255,.8); font-weight: 600; }

/* ---------- Utility ---------- */
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; border: 0;
}
.muted { color: var(--c-ink-3); }
.divider-mark {
  display: flex; align-items: center; gap: var(--s-3);
  margin: var(--s-6) 0;
}
.divider-mark::before, .divider-mark::after {
  content: ""; flex: 1; height: 1px; background: var(--c-rule);
}
.divider-mark span {
  font-family: var(--f-mono);
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.16em;
  color: var(--c-ink-3);
}

/* ============================================================
   CMS — custom editor at /cms/. Public-site components above
   are reused (form-card, field, input, btn, page-hero, prose,
   sidebar-card, eyebrow). Below are the small additions the CMS
   needs that don't already exist: the user/breadcrumb strip,
   dashboard cards, list tables, and inline action buttons.
   ============================================================ */

.cms-shell {
  padding: var(--s-5) 0 var(--s-8);
  min-height: 60vh;
}

/* Page heading inside the CMS shell */
.cms-page-head { margin: 0 0 var(--s-6); }
.cms-page-head .eyebrow { margin-bottom: var(--s-2); }
.cms-page-head--row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-4);
  flex-wrap: wrap;
}
.cms-page-head__actions { display: flex; gap: var(--s-3); flex-wrap: wrap; justify-content: flex-end; margin-left: auto; }

/* Action menu (cotton: c-action-menu)
   Trigger button + popover panel. Items are top-level <a> or <button>
   children of the panel; styled uniformly so callers don't have to think. */
.action-menu { position: relative; display: inline-block; }
/* Match the standard .btn sizing — keeps the Actions trigger visually
   consistent with other btn-ghost buttons elsewhere in the CMS (the
   "Filter" button on the contacts list, etc.). */
.action-menu__trigger { gap: var(--s-2); }
.action-menu__trigger[aria-expanded="true"] { border-color: var(--c-ink); color: var(--c-ink); }
.action-menu__panel {
  position: absolute;
  top: calc(100% + 4px);
  z-index: 40;
  min-width: 220px;
  padding: var(--s-2);
  background: var(--c-card);
  border: 1px solid var(--c-rule);
  border-radius: var(--radius);
  box-shadow: 0 10px 24px rgba(16, 18, 28, 0.12);
}
.action-menu--right .action-menu__panel { right: 0; }
.action-menu--left  .action-menu__panel { left: 0; }
.action-menu__panel > a,
.action-menu__panel > button,
.action-menu__panel > form > button {
  display: block;
  width: 100%;
  text-align: left;
  padding: var(--s-2) var(--s-3);
  font-family: var(--f-body);
  font-size: var(--fs-sm);
  font-weight: 500;
  color: var(--c-ink);
  background: none;
  border: 0;
  border-radius: calc(var(--radius) - 2px);
  cursor: pointer;
  text-decoration: none;
  white-space: nowrap;
}
.action-menu__panel > a:hover,
.action-menu__panel > button:hover,
.action-menu__panel > form > button:hover { background: var(--c-paper-2); color: var(--c-ink); }
.action-menu__panel > form { margin: 0; }
.action-menu__item--danger,
.action-menu__panel > .action-menu__item--danger { color: var(--c-red-deep); }
.cms-h1 {
  font-family: var(--f-display);
  font-weight: 700;
  font-size: var(--fs-2xl);
  letter-spacing: -0.01em;
  margin: 0 0 var(--s-2);
  color: var(--c-ink);
}

/* Admin index — categorized list of CMS sections. The card-grid that
   used to live here was hard to scan: every tile read as a peer when
   really there's a "tools we use day to day" group and a "website
   content" group, and the user wanted them visibly separated. */
.cms-admin-groups {
  display: flex;
  flex-direction: column;
  gap: var(--s-7);
}
.cms-admin-group__title {
  font-family: var(--f-mono);
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--c-ink-2);
  margin: 0 0 var(--s-3);
}
.cms-admin-list {
  list-style: none;
  margin: 0;
  padding: 0;
  background: var(--c-card);
  border: 1px solid var(--c-rule);
  border-radius: var(--radius);
  overflow: hidden;
}
.cms-admin-list > li + li {
  border-top: 1px solid var(--c-rule);
}
.cms-admin-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-4);
  padding: var(--s-4) var(--s-5);
  text-decoration: none;
  color: var(--c-ink);
  transition: background-color .12s ease;
}
.cms-admin-item:hover {
  background: var(--c-paper);
  color: var(--c-ink);
}
.cms-admin-item__main {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}
.cms-admin-item__title {
  font-family: var(--f-display);
  font-weight: 700;
  font-size: var(--fs-lg);
  line-height: 1.2;
}
.cms-admin-item__desc {
  font-size: var(--fs-sm);
  color: var(--c-ink-2);
  line-height: 1.4;
}
.cms-admin-item__meta {
  font-family: var(--f-mono);
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--c-ink-3);
  white-space: nowrap;
  flex-shrink: 0;
}
@media (max-width: 600px) {
  .cms-admin-item { flex-direction: column; align-items: flex-start; }
  .cms-admin-item__meta { align-self: flex-start; }
}

/* Tables (lists) */
/* Scroll wrapper: on narrow viewports the table outgrows the container
   and the user swipes horizontally instead of every cell wrapping. The
   right-edge fade is a scroll affordance — only painted when there's
   actually content to scroll to (background-attachment: local trick). */
.cms-table-scroll {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  border-radius: var(--radius);
  background:
    linear-gradient(to right, var(--c-card), var(--c-card)) left center / 20px 100% no-repeat local,
    linear-gradient(to right, var(--c-card), var(--c-card)) right center / 20px 100% no-repeat local,
    linear-gradient(to right, rgba(0, 0, 0, 0.08), transparent) left center / 12px 100% no-repeat scroll,
    linear-gradient(to left,  rgba(0, 0, 0, 0.08), transparent) right center / 12px 100% no-repeat scroll;
}
.cms-table-scroll:focus { outline: 2px solid var(--c-red); outline-offset: 2px; }
.cms-table-scroll:focus:not(:focus-visible) { outline: none; }
.cms-table {
  width: 100%;
  min-width: 600px;
  border-collapse: collapse;
  background: var(--c-card);
  border: 1px solid var(--c-rule);
  border-radius: var(--radius);
  overflow: hidden;
  font-size: var(--fs-sm);
}
.cms-table thead th {
  background: var(--c-paper-2);
  font-family: var(--f-mono);
  font-size: var(--fs-xs);
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--c-ink-3);
  text-align: left;
  padding: var(--s-3) var(--s-4);
  border-bottom: 1px solid var(--c-rule);
}
.cms-table tbody td {
  padding: var(--s-3) var(--s-4);
  border-bottom: 1px solid var(--c-rule-2);
  vertical-align: middle;
}
.cms-table tbody tr:last-child td { border-bottom: 0; }
.cms-table tbody tr:hover td { background: var(--c-paper); }
.cms-table a { color: var(--c-ink); text-decoration: none; font-weight: 600; }
.cms-table a:hover { color: var(--c-red); }
.cms-table__actions {
  text-align: right;
  white-space: nowrap;
}
.cms-mono {
  font-family: var(--f-mono);
  font-size: var(--fs-xs);
  color: var(--c-ink-2);
  background: var(--c-paper-2);
  padding: 2px 6px;
  border-radius: var(--radius-sm);
}

/* Inline row actions (link-styled buttons) */
.cms-action {
  display: inline-block;
  font-family: var(--f-mono);
  font-size: var(--fs-xs);
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--c-ink-2);
  background: none;
  border: 0;
  padding: 4px 8px;
  cursor: pointer;
  text-decoration: none;
}
.cms-action:hover { color: var(--c-red); }
.cms-action--danger { color: var(--c-red-deep); }
.cms-action--danger:hover { color: #7b0a17; }

/* Definition list, used on /cms/ops/roles/<id>/ for label / value pairs.
   Two columns on wide screens, stacked on narrow ones. */
.cms-defs {
  display: grid;
  grid-template-columns: 180px 1fr;
  gap: var(--s-2) var(--s-4);
  margin: 0;
}
.cms-defs dt {
  font-family: var(--f-mono);
  font-size: var(--fs-xs);
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--c-ink-3);
  margin: 0;
}
.cms-defs dd {
  margin: 0;
  font-size: var(--fs-sm);
  color: var(--c-ink);
}
@media (max-width: 600px) {
  .cms-defs { grid-template-columns: 1fr; gap: var(--s-1) 0; }
  .cms-defs dd { margin-bottom: var(--s-2); }
}

/* Status pills (used on lead list) */
.cms-pill {
  display: inline-block;
  font-family: var(--f-mono);
  font-size: var(--fs-xs);
  text-transform: uppercase;
  letter-spacing: 0.1em;
  padding: 3px 8px;
  border-radius: var(--radius-sm);
}
.cms-pill--ok   { background: #e8f5e9; color: #1f6f33; }
.cms-pill--warn { background: #fff8e1; color: #7a5d10; }
.cms-pill--ink  { background: var(--c-paper-2); color: var(--c-ink-2); }
.cms-pill--current { background: var(--c-ink); color: var(--c-card); }

/* Wizard stepper used on the Gmail send-mail-as guide. */
.cms-stepper {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-2);
  margin: 0 0 var(--s-5);
  padding: 0;
  list-style: none;
}
.cms-stepper a,
.cms-stepper span { text-decoration: none; }

/* Copyable credential row used in the wizard SMTP step. */
.cms-credential {
  display: grid;
  grid-template-columns: 160px 1fr auto;
  gap: var(--s-2) var(--s-3);
  align-items: center;
  padding: var(--s-2) 0;
  border-bottom: 1px solid var(--c-rule);
}
.cms-credential:last-child { border-bottom: 0; }
.cms-credential__label {
  font-family: var(--f-mono);
  font-size: var(--fs-xs);
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--c-ink-3);
}
.cms-credential__value {
  font-family: var(--f-mono);
  font-size: var(--fs-sm);
  color: var(--c-ink);
  word-break: break-all;
}
.cms-credential__value--masked { color: var(--c-ink-3); }
@media (max-width: 600px) {
  .cms-credential {
    grid-template-columns: 1fr;
  }
}

/* Forms inside the CMS — reuses .field/.input/.select/.textarea */
.cms-form { max-width: 100%; }
/* Single-line text inputs and selects look stretched in a wide container.
   Cap them. Textareas and the markdown editor's grid still fill the
   full form width so preview panes get whatever the page allows. */
/* CMS form inputs fill the available column. The instruction text sits
   beside the label (top-right of the field), so the input visually
   "goes the distance" instead of leaving dead space on desktop. */
.cms-form .input,
.cms-form .select,
.cms-form select,
.cms-form .textarea,
.cms-form textarea { width: 100%; }
.cms-form .field { margin-bottom: var(--s-5); }

/* Sibling cards inside a CMS form get vertical breathing room so each
   section reads as its own block. Without this they abut and look
   accidentally joined. */
.cms-form > .announce + .announce { margin-top: var(--s-5); }

/* Email alias row: input + fixed domain suffix on one line, meta line
   (forwarding destination) below, action buttons below that. */
.email-alias__input {
  display: flex;
  align-items: stretch;
  gap: 0;
}
.email-alias__input .input {
  border-top-right-radius: 0;
  border-bottom-right-radius: 0;
}
.email-alias__suffix {
  display: inline-flex;
  align-items: center;
  padding: 0 var(--s-3);
  border: 1px solid var(--c-rule);
  border-left: 0;
  border-top-right-radius: var(--radius);
  border-bottom-right-radius: var(--radius);
  background: var(--c-paper-2);
  color: var(--c-ink-2);
  font-family: var(--f-mono);
  font-size: var(--fs-sm);
  white-space: nowrap;
}
.email-alias__meta {
  margin-top: var(--s-2);
  color: var(--c-ink-2);
  font-size: var(--fs-sm);
}
.email-alias__actions {
  margin-top: var(--s-3);
  display: flex;
  gap: var(--s-2);
  flex-wrap: wrap;
}
.cms-form-errors {
  border: 1px solid var(--c-red);
  background: #fdecea;
  padding: var(--s-3) var(--s-4);
  border-radius: var(--radius);
  margin-bottom: var(--s-5);
}
.cms-form-actions {
  flex-direction: row;
  justify-content: flex-start;
  align-items: stretch;
  gap: var(--s-3);
}
/* If any button in a form-actions group is .btn-lg, every sibling button
   matches its padding + font-size. Stops the "primary lg next to default
   cancel = visibly different heights" mismatch from being possible. */
.cms-form-actions:has(.btn-lg) .btn { padding: 18px 28px; font-size: var(--fs-md); }

/* Breadcrumb row in CMS pages — left side carries the breadcrumb
   trail, right side carries an optional "View on site" link out to
   the matching public-facing page. Mirrors the public-site pattern
   (page-hero__topbar) so the editor ↔ public round trip reads as
   a paired affordance. */
.cms-crumb-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-3);
  margin-bottom: var(--s-4);
}
.cms-crumb-row .crumb { margin-bottom: 0; }
/* .cms-public-link styling is shared with .page-hero__edit-link —
   see the rule near the top of this file. */

/* Inline pill-toggle used in CMS list cells (e.g. show-in-hero on
   the photos list). Click flips state via htmx; the cell re-renders
   with the new label/class. */
.cms-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 48px;
  padding: 4px 10px;
  background: var(--c-paper);
  border: 1px solid var(--c-rule);
  border-radius: 999px;
  font-family: var(--f-mono);
  font-size: var(--fs-xs);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--c-ink-2);
  cursor: pointer;
  transition: background-color .12s ease, color .12s ease, border-color .12s ease;
}
.cms-toggle:hover { border-color: var(--c-ink); }
.cms-toggle.is-on {
  background: var(--c-red);
  border-color: var(--c-red);
  color: #fff;
}

/* Sortable column header in CMS tables — link looks like a regular
   header until clicked. Active column flips to ink color and shows
   the direction caret. */
.cms-sort {
  color: inherit;
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  gap: 4px;
}
.cms-sort:hover { color: var(--c-ink); }
.cms-sort--active { color: var(--c-ink); }
.cms-sort__caret { font-size: 9px; }

/* Sticky save bar — pinned to the bottom of the viewport while editing
   so Save is always reachable on tall forms. The bar is visually full-
   bleed (extends to the viewport edges) so a half-card sliver doesn't
   sit awkwardly inside the page background. The buttons inside, though,
   align to the page's content container so they sit where the rest of
   the form's controls do. */
.cms-form-bar {
  position: sticky;
  bottom: 0;
  z-index: 30;
  /* Break out of the parent container width using the standard
     "100vw centered" trick: 100vw wide, pulled left by half the
     overflow on each side. Stays in document flow so the sticky
     `bottom: 0` against the viewport behaves naturally. */
  width: 100vw;
  margin-left: calc(50% - 50vw);
  margin-top: var(--s-5);
  padding: var(--s-3) 0;
  background: var(--c-card);
  border-top: 1px solid var(--c-rule);
  box-shadow: 0 -4px 12px rgba(0, 0, 0, 0.04);
}
.cms-form-bar__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-3);
  max-width: 100%;
}
/* When a form has a sticky save bar, kill the cms-shell's bottom
   padding AND the footer's top margin so the bar can butt right up
   against the dark footer. Both gaps render as cream/tan bands and
   look like the page is broken. */
.cms-shell:has(.cms-form-bar) { padding-bottom: 0; }
body:has(.cms-form-bar) .site-footer { margin-top: 0; }
.cms-form-bar__primary {
  display: flex;
  align-items: center;
  gap: var(--s-3);
}
.cms-form-bar__hint {
  font-size: var(--fs-sm);
  color: var(--c-ink-2);
}
.cms-form-bar.is-dirty .cms-form-bar__hint { color: var(--c-red); }

/* Roster import diff preview */
.cms-diff-block { margin-top: var(--s-4); }
.cms-diff-block:first-child { margin-top: 0; }
.cms-diff-block__title { font-size: var(--fs-md); margin: 0 0 var(--s-2); }
.cms-diff-block__count { color: var(--c-ink-3); font-weight: normal; }
.cms-diff-list {
  list-style: none;
  margin: 0;
  padding: 0;
  border: 1px solid var(--c-rule);
  border-radius: var(--radius);
  overflow: hidden;
}
.cms-diff-row {
  padding: var(--s-2) var(--s-3);
  border-top: 1px solid var(--c-rule);
  font-size: var(--fs-sm);
}
.cms-diff-row:first-child { border-top: 0; }
.cms-diff-row--family-add,
.cms-diff-row--scout-add { border-left: 3px solid var(--c-ok, #1c7c3a); }
.cms-diff-row--family-update,
.cms-diff-row--scout-update { border-left: 3px solid var(--c-warn, #b07c1d); }
.cms-diff-row--family-deactivate,
.cms-diff-row--scout-deactivate { border-left: 3px solid var(--c-ink-3); color: var(--c-ink-2); }
.cms-diff-row__detail { color: var(--c-ink-2); }

.cms-warnings {
  margin: var(--s-2) 0 0;
  padding-left: var(--s-4);
  font-size: var(--fs-sm);
  color: var(--c-ink-2);
}
.cms-warnings li { margin-bottom: var(--s-1); }

/* Family list page */
.cms-family-page { display: flex; flex-direction: column; gap: var(--s-4); }

.cms-filterbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s-3);
  padding: var(--s-3) var(--s-4);
  background: var(--c-card);
  border: 1px solid var(--c-rule);
  border-radius: var(--radius);
}
.cms-filterbar__field { display: flex; flex-direction: column; gap: var(--s-1); min-width: 180px; }
.cms-filterbar__field--grow { flex: 1 1 240px; }
.cms-filterbar__label {
  font-family: var(--f-mono);
  font-size: var(--fs-xs);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--c-ink-3);
}
.cms-filterbar__check {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  font-size: var(--fs-sm);
  color: var(--c-ink-2);
  cursor: pointer;
}
.cms-filterbar__clear { font-size: var(--fs-sm); margin-left: auto; }

/* Sticky bulk-action bar — appears when ≥1 row checked. */
/* Bulk-action strip — sits inside the data card, between the filter
   panel and the table. Flush with the card's edges (no rounding, no
   shadow) so it reads as part of the same surface, not a separate
   floating tray. --c-canvas matches the site footer for palette
   consistency. */
.cms-data-card__bulkbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-3);
  padding: var(--s-3) var(--s-4);
  background: var(--c-canvas);
  color: var(--c-card);
  border-bottom: 1px solid var(--c-rule);
}
.cms-data-card__bulkbar-count { font-weight: 600; }
.cms-data-card__bulkbar-actions { display: flex; gap: var(--s-2); flex-wrap: wrap; }
.cms-data-card__bulkbar .btn-ghost {
  background: transparent;
  color: var(--c-card);
  border-color: rgba(255, 255, 255, 0.4);
}
.cms-bulkbar .btn-ghost:hover { background: rgba(255, 255, 255, 0.1); }

/* Inactive / muted row — desaturate without making the row unreadable. */
.cms-row--muted { color: var(--c-ink-3); }
.cms-row--muted a { color: var(--c-ink-2); }

.cms-table__check { width: 36px; }

.cms-scout-line { font-size: var(--fs-sm); }
.cms-scout-line + .cms-scout-line { margin-top: 2px; }

.cms-scout-list { list-style: none; margin: 0; padding: 0; }
.cms-scout-list__item {
  padding: var(--s-2) 0;
  border-top: 1px solid var(--c-rule);
}
.cms-scout-list__item:first-child { border-top: 0; }

.text-warn { color: var(--c-warn, #b07c1d); }

/* Family detail — per-scout row layout. Three columns on wide screens
   (name | imported den | override dropdown), stacked on narrow. */
.cms-scout-row {
  display: grid;
  grid-template-columns: 1.4fr 1fr 1.6fr;
  gap: var(--s-3);
  align-items: center;
}
.cms-scout-row__name { display: flex; flex-direction: column; gap: 2px; }
@media (max-width: 720px) {
  .cms-scout-row { grid-template-columns: 1fr; }
}

/* Per-contact message timeline (family detail Messages card). Outbound and
   inbound entries share the structure; direction is colored by the modifier. */
/* Generic data-card: filter controls + table in one bordered container.
   Used by the contacts list and the "Link as additional parent" picker
   on the contact detail page. The table-inside-card pattern keeps the
   filter bar visually attached to the rows it filters, and the sticky
   thead means the column labels stay visible while scrolling. */
.cms-data-card {
  border: 1px solid var(--c-rule);
  border-radius: var(--radius);
  background: var(--c-card);
  overflow: hidden;  /* clip the table's own scroll-frame to the rounded corners */
}
.cms-data-card__controls {
  display: flex;
  gap: var(--s-3);
  align-items: center;
  padding: var(--s-3) var(--s-4);
  background: var(--c-card);
  flex-wrap: wrap;
}
.cms-data-card__search { flex: 1 1 240px; }
.cms-data-card__den { flex: 0 0 200px; }
.cms-data-card__filter-toggle {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  gap: var(--s-1);
}
.cms-data-card__filter-caret { font-size: 0.85em; color: var(--c-ink-3); }

/* Expandable filter panel below the controls. Visually continuous with
   the controls row above — same white background, no divider — so it
   reads as "more filters" rather than a separate strip. Designed to
   grow as more secondary filters land here. */
.cms-data-card__filters {
  padding: 0 var(--s-4) var(--s-3);
  background: var(--c-card);
  display: flex;
  flex-direction: column;
  gap: var(--s-2);
}
.cms-data-card__check {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  font-size: var(--fs-sm);
  color: var(--c-ink-2);
  cursor: pointer;
}
/* Horizontal scroll wrapper — on narrow viewports the 5-column contacts
   table compresses badly; this lets it scroll sideways instead while the
   filter bar above keeps wrapping naturally. tabindex makes the region
   keyboard-scrollable; role/aria-label keep screen readers oriented. */
.cms-data-card__table-scroll {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}
.cms-data-card__table {
  width: 100%;
  min-width: 760px;  /* enough for all 5 columns at readable widths */
  border-collapse: collapse;
}
.cms-data-card__table thead th {
  font-family: var(--f-mono);
  font-size: var(--fs-xs);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--c-ink-3);
  text-align: left;
  padding: var(--s-3) var(--s-4);
  border-bottom: 1px solid var(--c-rule);
  background: var(--c-paper);
  position: sticky;
  top: 0;
  z-index: 1;
}
.cms-data-card__table thead th.sortable {
  cursor: pointer;
  user-select: none;
}
.cms-data-card__table thead th.sortable:hover { color: var(--c-ink); }
.cms-data-card__table thead th .sort-indicator {
  display: inline-block;
  margin-left: var(--s-1);
  color: var(--c-red);
  font-size: 0.85em;
}
.cms-data-card__table tbody td {
  padding: var(--s-3) var(--s-4);
  border-bottom: 1px solid var(--c-rule);
  vertical-align: middle;
  /* Keep values on one line — long emails / scout names / phones
     shouldn't wrap mid-row. The .cms-data-card__table-scroll wrapper
     handles horizontal overflow at narrow viewports. */
  white-space: nowrap;
}
.cms-data-card__table tbody tr:last-child td { border-bottom: 0; }
.cms-data-card__table tbody tr:hover td { background: var(--c-paper); }
.cms-data-card__table a { color: var(--c-ink); text-decoration: none; font-weight: 600; }
.cms-data-card__table a:hover { color: var(--c-red); }
.cms-data-card__cell-check { width: 36px; }

/* Picker variant: compact rows + fixed-height scroll for in-form usage */
.cms-picker {
  margin-top: var(--s-2);
  border: 1px solid var(--c-rule);
  border-radius: var(--radius);
  background: var(--c-card);
}
.cms-picker__controls {
  display: flex;
  gap: var(--s-3);
  align-items: center;
  padding: var(--s-3) var(--s-4);
  border-bottom: 1px solid var(--c-rule);
  position: sticky;
  top: 0;
  background: var(--c-card);
  z-index: 1;
  flex-wrap: wrap;
}
.cms-picker__search { flex: 1 1 240px; }
.cms-picker__den { flex: 0 0 200px; }
.cms-picker__table {
  width: 100%;
  border-collapse: collapse;
  display: block;
  max-height: 360px;
  overflow-y: auto;
}
.cms-picker__table thead, .cms-picker__table tbody { display: table; width: 100%; table-layout: fixed; }
.cms-picker__table thead th {
  font-family: var(--f-mono);
  font-size: var(--fs-xs);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--c-ink-3);
  text-align: left;
  padding: var(--s-2);
  border-bottom: 1px solid var(--c-rule);
  background: var(--c-paper);
  position: sticky;
  top: 0;
}
.cms-picker__table tbody td {
  padding: var(--s-2);
  border-bottom: 1px solid var(--c-rule);
}
.cms-picker__table tbody tr:last-child td { border-bottom: 0; }
.cms-picker__table tbody tr:hover td { background: var(--c-paper); }
.cms-picker__check { width: 36px; }
.cms-picker__bsa { width: 110px; text-align: right; }

/* Same-household sibling list on the contact detail page. */
.cms-household-list {
  list-style: none;
  padding: 0;
  margin: var(--s-2) 0 0;
  display: flex;
  flex-direction: column;
  gap: var(--s-1);
}
.cms-household-list a { color: var(--c-ink); text-decoration: none; font-weight: 600; }
.cms-household-list a:hover { color: var(--c-red); }

.cms-msg-timeline {
  list-style: none;
  padding: 0;
  margin: var(--s-3) 0 0;
  display: flex;
  flex-direction: column;
  gap: var(--s-3);
}
.cms-msg {
  border: 1px solid var(--c-rule);
  border-left-width: 4px;
  border-radius: var(--radius);
  padding: var(--s-3);
  background: var(--c-paper);
}
.cms-msg--out { border-left-color: var(--c-ink-3); }
.cms-msg--in  { border-left-color: var(--c-red); background: var(--c-card); }
.cms-msg__head {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-3);
  align-items: baseline;
  margin-bottom: var(--s-1);
}
.cms-msg__dir {
  font-family: var(--f-mono);
  font-size: var(--fs-xs);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--c-ink-2);
}
.cms-msg--in .cms-msg__dir { color: var(--c-red); }
.cms-msg__channel {
  font-family: var(--f-mono);
  font-size: var(--fs-xs);
  color: var(--c-ink-3);
}
.cms-msg__subject { margin: var(--s-1) 0; }
.cms-msg__body { white-space: pre-wrap; }
.cms-msg__meta { margin-top: var(--s-1); }

/* Compose recipient chips. */
.chip-list { display: flex; flex-wrap: wrap; gap: var(--s-2); }
.chip {
  display: inline-flex;
  align-items: center;
  gap: var(--s-1);
  padding: 4px 10px;
  background: var(--c-paper-2);
  border: 1px solid var(--c-rule);
  border-radius: 999px;
  font-size: var(--fs-sm);
  color: var(--c-ink);
}
.chip--warn { background: #fff8e1; color: #7a5d10; border-color: #e9d8a8; }
.chip__tag {
  font-size: var(--fs-xs);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  background: rgba(0, 0, 0, 0.08);
  padding: 1px 6px;
  border-radius: 999px;
}

/* Channel + test-mode toggles look better as full-width rows than as
   stacked checkbox + label. */
.cms-checkbox-row {
  display: flex;
  align-items: flex-start;
  gap: var(--s-2);
  padding: var(--s-2) 0;
  cursor: pointer;
}
.cms-checkbox-row input[type=checkbox] { margin-top: 4px; }

.event-picker { border: 1px solid var(--c-rule); border-radius: var(--radius); padding: var(--s-2) var(--s-3); }
.event-picker > summary { cursor: pointer; font-size: var(--fs-sm); color: var(--c-ink-2); }
.event-picker__list { list-style: none; margin: var(--s-2) 0 0; padding: 0; }
.event-picker__list li + li { margin-top: var(--s-1); }
.event-picker__item {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 2px;
  width: 100%;
  text-align: left;
  background: transparent;
  border: 1px solid transparent;
  border-radius: var(--radius);
  padding: var(--s-2) var(--s-3);
  cursor: pointer;
  font: inherit;
}
.event-picker__item:hover { background: var(--c-paper-2); border-color: var(--c-rule); }

.cms-blast-body {
  white-space: pre-wrap;
  font-family: inherit;
  font-size: var(--fs-md);
  margin: 0;
  padding: var(--s-3);
  background: var(--c-paper-2);
  border-radius: var(--radius);
}

/* `danger` is a modifier on top of a base variant — semantic only,
   the visual is whatever that variant already gives us. Both reds
   below are the design-system tokens; no off-palette colors. */

/* Ghost danger: red text + red border on transparent (the standalone
   "Delete" link on edit pages). */
.btn-ghost.btn-danger,
a.btn-ghost.btn-danger { color: var(--c-red-deep); border-color: var(--c-red-deep); }
.btn-ghost.btn-danger:hover,
a.btn-ghost.btn-danger:hover { background: var(--c-red-deep); color: #fff; }

/* Primary danger: visually identical to .btn-primary (same red token,
   white text). The earlier "deeper red bg" override drifted from the
   single-red rule. .btn-primary already supplies bg+color+border, and
   .btn-danger has no business changing them on a filled button. */

/* Pagination row */
.cms-pagination {
  display: flex;
  gap: var(--s-3);
  align-items: center;
  margin-top: var(--s-5);
}

/* Messages */
.cms-messages {
  list-style: none;
  margin: 0 0 var(--s-5);
  padding: 0;
}
.cms-messages li {
  border-radius: var(--radius);
  border: 1px solid var(--c-rule);
  background: var(--c-card);
  padding: var(--s-3) var(--s-4);
  margin-bottom: var(--s-2);
  font-size: var(--fs-sm);
}
.cms-messages li.error { border-color: var(--c-red); background: #fdecea; }
.cms-messages li.success { border-color: #b3d8b8; background: #e8f5e9; }

/* ---------- Utilities ----------
   Conservative spacing/typography helpers mapped to design tokens.
   Use these instead of inline `style="…"`. Add new utilities only when a
   pattern repeats; one-offs should become a component variant instead. */
.icon { display: inline-block; vertical-align: -2px; flex-shrink: 0; }
.text-ok { color: #1f6f33; }
.mt-0 { margin-top: 0; }
.mt-1 { margin-top: var(--s-1); }
.mt-2 { margin-top: var(--s-2); }
.mt-3 { margin-top: var(--s-3); }
.mt-4 { margin-top: var(--s-4); }
.mt-5 { margin-top: var(--s-5); }
.mt-6 { margin-top: var(--s-6); }
.mt-7 { margin-top: var(--s-7); }
.mt-8 { margin-top: var(--s-8); }
.mt-9 { margin-top: var(--s-9); }
.mb-0 { margin-bottom: 0; }
.mb-1 { margin-bottom: var(--s-1); }
.mb-2 { margin-bottom: var(--s-2); }
.mb-3 { margin-bottom: var(--s-3); }
.mb-4 { margin-bottom: var(--s-4); }
.mb-5 { margin-bottom: var(--s-5); }
.mb-6 { margin-bottom: var(--s-6); }
.mb-7 { margin-bottom: var(--s-7); }
.mb-8 { margin-bottom: var(--s-8); }
.mb-9 { margin-bottom: var(--s-9); }
.fs-xs  { font-size: var(--fs-xs); }
.fs-sm  { font-size: var(--fs-sm); }
.fs-md  { font-size: var(--fs-md); }
.fs-lg  { font-size: var(--fs-lg); }
.fs-xl  { font-size: var(--fs-xl); }
.fs-2xl { font-size: var(--fs-2xl); }
.text-muted { color: var(--c-ink-2); }
.text-quiet { color: var(--c-ink-3); }
.bg-paper-2 { background: var(--c-paper-2); }
.d-inline { display: inline; }
.cms-pill--saved { margin-left: var(--s-2); }

/* Row-margin variant of section__head — replaces inline margin-top. */
.section__head--mt7 { margin-top: var(--s-7); }

/* Centered styleguide demo helpers (used on /styleguide/). */
.sg-row { display: flex; gap: var(--s-3); flex-wrap: wrap; align-items: center; }
.sg-card-wide { max-width: 320px; }
.sg-render--canvas-dark {
  background: var(--c-canvas);
  color: rgba(255,255,255,.7);
  padding: var(--s-5);
  border-radius: var(--radius);
}
.sg-render--canvas-pad {
  background: var(--c-canvas);
  padding: var(--s-5);
  border-radius: var(--radius);
}

/* ---------- Hero rotator (home page) ---------- */
.hero__media--rotator { position: relative; }
.hero__media--rotator .hero__rotator-img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0;
  transition: opacity 1.2s ease-in-out;
  pointer-events: none;
}
.hero__media--rotator .hero__rotator-img.is-active { opacity: 1; }
/* First image stays painted under the rotation until JS boots, so the area
   never appears blank on slow networks or when JS is disabled. */
.hero__media--rotator .hero__rotator-img:first-of-type { opacity: 1; }
.hero__media--rotator .hero__rotator-img:first-of-type:not(.is-active) { opacity: 0; }

/* ---------- Page hero photo (above-prose) ---------- */
.page-hero-photo {
  margin: 0 0 var(--s-6);
  border-radius: var(--radius);
  overflow: hidden;
  background: var(--c-paper-2);
  border: 1px solid var(--c-rule);
}
.page-hero-photo img {
  width: 100%;
  height: auto;
  display: block;
  aspect-ratio: 16 / 9;
  object-fit: cover;
}
.page-hero-photo figcaption {
  padding: var(--s-3) var(--s-4);
  font-family: var(--f-mono);
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--c-ink-3);
  background: var(--c-paper);
  border-top: 1px solid var(--c-rule);
}

/* ---------- Photo gallery ---------- */
.photos__section { margin: var(--s-7) 0; }
.photos__section-head { margin-bottom: var(--s-4); }
.photos__section-head h2 {
  font-size: var(--fs-xl);
  margin: var(--s-2) 0 0;
}

.photo-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--s-4);
}
@media (min-width: 700px)  { .photo-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (min-width: 1000px) { .photo-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); } }

.photo-tile {
  display: flex;
  flex-direction: column;
  border: 1px solid var(--c-rule);
  border-radius: var(--radius);
  background: var(--c-card);
  padding: 0;
  cursor: pointer;
  text-align: left;
  font: inherit;
  color: inherit;
  overflow: hidden;
  transition: transform 0.15s ease, box-shadow 0.15s ease, border-color 0.15s ease;
}
.photo-tile:hover {
  transform: translateY(-2px);
  box-shadow: var(--shadow-md);
  border-color: var(--c-khaki);
}
.photo-tile:focus-visible {
  outline: 2px solid var(--c-red);
  outline-offset: 2px;
}
.photo-tile__media {
  display: block;
  aspect-ratio: 4 / 3;
  background: var(--c-paper-2);
  overflow: hidden;
}
.photo-tile__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.photo-tile__caption {
  display: block;
  padding: var(--s-3) var(--s-4);
  font-size: var(--fs-sm);
  color: var(--c-ink-2);
  border-top: 1px solid var(--c-rule);
}

/* ---------- Photo lightbox ---------- */
[x-cloak] { display: none !important; }
.photo-lightbox {
  position: fixed;
  inset: 0;
  z-index: 100;
  background: rgba(15, 17, 20, 0.92);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--s-5);
}
.photo-lightbox__figure {
  max-width: min(1100px, 95vw);
  max-height: 90vh;
  margin: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--s-3);
}
.photo-lightbox__figure img {
  max-width: 100%;
  max-height: 80vh;
  object-fit: contain;
  border-radius: var(--radius-sm);
  box-shadow: 0 4px 24px rgba(0, 0, 0, 0.4);
}
.photo-lightbox__figure figcaption {
  color: #f4efe5;
  font-family: var(--f-mono);
  font-size: var(--fs-xs);
  text-transform: uppercase;
  letter-spacing: 0.12em;
  text-align: center;
}
.photo-lightbox__close,
.photo-lightbox__nav {
  position: absolute;
  background: rgba(255, 255, 255, 0.08);
  border: 1px solid rgba(255, 255, 255, 0.18);
  color: #fff;
  width: 44px;
  height: 44px;
  border-radius: 999px;
  cursor: pointer;
  font-size: 22px;
  line-height: 1;
  display: flex;
  align-items: center;
  justify-content: center;
}
.photo-lightbox__close:hover,
.photo-lightbox__nav:hover { background: rgba(255, 255, 255, 0.18); }
.photo-lightbox__close { top: var(--s-4); right: var(--s-4); }
.photo-lightbox__nav--prev { left: var(--s-4); top: 50%; transform: translateY(-50%); }
.photo-lightbox__nav--next { right: var(--s-4); top: 50%; transform: translateY(-50%); }
@media (max-width: 600px) {
  .photo-lightbox__nav--prev { left: var(--s-2); }
  .photo-lightbox__nav--next { right: var(--s-2); }
}

/* CMS leaders-list row thumbnail. 64px circle, links to the leader's
   edit page so it's a generous click target. */
.cms-leader-thumb-cell { width: 80px; padding-right: 0; padding-top: var(--s-2); padding-bottom: var(--s-2); }
.cms-leader-thumb {
  display: block;
  width: 64px; height: 64px;
  border-radius: 50%;
  overflow: hidden;
  background: var(--c-paper-2);
  border: 1px solid var(--c-rule);
}
.cms-leader-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.cms-leader-thumb__default { object-fit: contain; padding: 6px; opacity: .7; }

/* ---------- Public leaders page (/about/leaders/) ---------- */
.leaders-section {
  margin-top: var(--s-8);
}
.leaders-section:first-child { margin-top: 0; }
.leaders-section__head {
  font-size: var(--fs-2xl);
  margin: 0 0 var(--s-5);
  padding-bottom: var(--s-3);
  border-bottom: 1px solid var(--c-rule);
}
.leaders-grid {
  display: grid;
  gap: var(--s-5);
  grid-template-columns: minmax(0, 1fr);
}
@media (min-width: 640px) {
  .leaders-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (min-width: 1000px) {
  .leaders-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

/* ---------- Leader photos (public + CMS upload) ---------- */
.leader-photo {
  margin: 0 0 var(--s-3);
  width: 120px;
  aspect-ratio: 1;
  border-radius: 50%;
  overflow: hidden;
  background: var(--c-paper-2);
  border: 1px solid var(--c-rule);
}
.leader-photo img { width: 100%; height: 100%; object-fit: cover; display: block; }
.leader-photo--default { object-fit: contain; padding: 8px; background: var(--c-paper-2); }

/* Image-crop upload widget (cotton: c-image-crop-upload) */
.image-crop input[type="file"] { display: none; }
.image-crop__preview { display: flex; align-items: center; gap: var(--s-4); }
.image-crop__current,
.image-crop__placeholder {
  width: 120px; height: 120px;
  border-radius: 50%;
  background: var(--c-paper-2);
  border: 1px solid var(--c-rule);
  overflow: hidden;
  display: flex; align-items: center; justify-content: center;
  flex-shrink: 0;
}
.image-crop__current { object-fit: cover; }
.image-crop__placeholder img { max-width: 80%; max-height: 80%; opacity: .6; }
.image-crop__pick { padding: 10px 16px; font-size: var(--fs-sm); }

.image-crop__modal {
  position: fixed; inset: 0;
  z-index: 100;
  background: rgba(16, 18, 28, 0.55);
  display: flex; align-items: center; justify-content: center;
  padding: var(--s-4);
}
.image-crop__modal-card {
  background: var(--c-card);
  border-radius: var(--radius);
  padding: var(--s-5);
  width: min(100%, 560px);
  max-height: 90vh;
  overflow: auto;
  box-shadow: 0 20px 60px rgba(16, 18, 28, 0.35);
}
.image-crop__modal-title { margin: 0 0 var(--s-2); font-family: var(--f-display); font-size: var(--fs-xl); }
.image-crop__stage { background: #1a1c22; border-radius: var(--radius-sm); height: 380px; overflow: hidden; margin-bottom: var(--s-4); }
.image-crop__stage img { display: block; max-width: 100%; }
.image-crop__modal-actions { display: flex; gap: var(--s-3); }

/* ---------- CMS photo list/preview ---------- */
/* Photos list has 8 columns including a thumbnail and a long auto-slug;
   the default 600px min-width is way too cramped here, so bump it and
   keep slug values + caption on a single line. The .cms-table-scroll
   wrapper handles horizontal scroll on narrow viewports. */
.cms-photos-table .cms-table { min-width: 960px; }
.cms-photos-table .cms-table .cms-mono { white-space: nowrap; }
.cms-photos-table .cms-table tbody td { white-space: nowrap; }
.cms-photo-thumb-cell { width: 92px; min-width: 92px; }
.cms-photo-thumb {
  width: 80px;
  height: 56px;
  /* Override the global `img { max-width: 100% }` rule, which otherwise
     collapses the thumbnail when the table cell is narrower than 80px
     (happens on mobile inside the scroll wrapper). */
  max-width: none;
  object-fit: cover;
  border-radius: var(--radius-sm);
  border: 1px solid var(--c-rule);
  display: block;
}
.cms-photo-preview {
  margin: 0 0 var(--s-5);
  border: 1px solid var(--c-rule);
  border-radius: var(--radius);
  overflow: hidden;
  background: var(--c-paper-2);
}
.cms-photo-preview img {
  display: block;
  width: 100%;
  max-height: 360px;
  object-fit: cover;
}
.cms-photo-preview figcaption {
  padding: var(--s-2) var(--s-3);
  font-size: var(--fs-xs);
  color: var(--c-ink-3);
  background: var(--c-paper);
  border-top: 1px solid var(--c-rule);
}

/* ---------- Roster importer + Blasts (Phase 2/3) ----------
   Diff/summary cards used on /cms/roster/import/preview/ and the blast
   preview pane. Tokens reused from the rest of the CMS so these blend
   with everything else. */

.cms-h2 {
  font-family: var(--f-display);
  font-weight: 700;
  font-size: var(--fs-xl);
  letter-spacing: -0.005em;
  margin: var(--s-6) 0 var(--s-3);
  color: var(--c-ink);
}
.cms-h3 {
  font-family: var(--f-display);
  font-weight: 700;
  font-size: var(--fs-lg);
  margin: 0 0 var(--s-3);
  color: var(--c-ink);
}
.cms-roster-den { margin-bottom: var(--s-7); }
.cms-roster-den .cms-table { margin-top: var(--s-3); }

.cms-summary {
  display: grid;
  gap: var(--s-3);
  grid-template-columns: repeat(2, minmax(0, 1fr));
  margin: var(--s-5) 0;
}
@media (min-width: 700px) { .cms-summary { grid-template-columns: repeat(3, 1fr); } }
@media (min-width: 960px) { .cms-summary { grid-template-columns: repeat(6, 1fr); } }
.cms-summary__cell {
  padding: var(--s-4);
  background: var(--c-card);
  border: 1px solid var(--c-rule);
  border-radius: var(--radius);
  display: flex;
  flex-direction: column;
  gap: var(--s-1);
}
.cms-summary__num {
  font-family: var(--f-display);
  font-weight: 700;
  font-size: var(--fs-xl);
  color: var(--c-ink);
}
.cms-summary__label {
  font-size: var(--fs-xs);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--c-ink-3);
}

.cms-diff {
  background: var(--c-card);
  border: 1px solid var(--c-rule);
  border-left-width: 4px;
  border-radius: var(--radius);
  padding: var(--s-4) var(--s-5);
  margin-bottom: var(--s-4);
}
.cms-diff--add { border-left-color: #2e7d32; }
.cms-diff--update { border-left-color: #c79100; }
.cms-diff--remove { border-left-color: var(--c-red); }
.cms-diff__list {
  list-style: disc;
  padding-left: var(--s-5);
  margin: 0;
}
.cms-diff__list li { margin-bottom: var(--s-1); }

.cms-callout {
  background: var(--c-card);
  border: 1px solid var(--c-rule);
  border-radius: var(--radius);
  padding: var(--s-4) var(--s-5);
  margin-bottom: var(--s-5);
}
.cms-callout--warn { background: #fff8e1; border-color: #e6c66a; }
.cms-callout--info { background: #e7f1fb; border-color: #b9d4ec; }
.cms-callout--alert { background: #fdecea; border-color: var(--c-red); }
.cms-callout__list {
  margin: var(--s-2) 0 0;
  padding-left: var(--s-5);
}
.cms-callout__list li { margin-bottom: var(--s-1); font-size: var(--fs-sm); }

/* Blast composer specifics */
.cms-radio-row {
  display: flex;
  gap: var(--s-3);
  flex-wrap: wrap;
  margin-bottom: var(--s-4);
}
.cms-radio-row label {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  padding: var(--s-2) var(--s-3);
  border: 1px solid var(--c-rule);
  border-radius: var(--radius-sm);
  background: var(--c-card);
  font-size: var(--fs-sm);
  cursor: pointer;
}
.cms-charcount {
  font-size: var(--fs-xs);
  color: var(--c-ink-3);
  margin-top: var(--s-1);
}
.cms-charcount--over { color: var(--c-red); }
.cms-blast-preview {
  background: var(--c-paper);
  border: 1px solid var(--c-rule);
  border-radius: var(--radius);
  padding: var(--s-4) var(--s-5);
  white-space: pre-wrap;
  font-family: var(--f-body);
  font-size: var(--fs-base);
  color: var(--c-ink);
}

/* ===========================================================
   Chatbot widget — floating bottom-right.
   Always visible on public pages; hidden on /cms/ via base.html.
   =========================================================== */

.chatbot-widget { position: fixed; right: 24px; bottom: 24px; z-index: 40; }
@media (max-width: 600px) { .chatbot-widget { right: 16px; bottom: 16px; } }
[x-cloak] { display: none !important; }

.chatbot-bubble {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  padding: 12px 18px;
  border: 0;
  border-radius: 999px;
  background: var(--c-red-deep);
  color: #fff;
  font-family: var(--f-body);
  font-size: var(--fs-sm);
  font-weight: 600;
  letter-spacing: 0.01em;
  cursor: pointer;
  box-shadow: 0 8px 24px rgba(166, 13, 30, 0.25), 0 2px 4px rgba(0,0,0,0.12);
  transition: transform 0.15s ease, box-shadow 0.15s ease;
}
.chatbot-bubble:hover { transform: translateY(-1px); box-shadow: 0 10px 28px rgba(166, 13, 30, 0.32), 0 2px 6px rgba(0,0,0,0.16); }
.chatbot-bubble:focus-visible { outline: 2px solid #fff; outline-offset: 2px; }
.chatbot-bubble svg { display: block; }
@media (max-width: 480px) {
  .chatbot-bubble__label { display: none; }
  .chatbot-bubble { padding: 14px; }
}

.chatbot-panel {
  position: fixed;
  right: 24px;
  bottom: 24px;
  width: 380px;
  height: min(560px, calc(100vh - 48px));
  background: var(--c-card);
  border: 1px solid var(--c-rule);
  border-radius: 12px;
  box-shadow: 0 12px 40px rgba(0,0,0,0.18), 0 4px 12px rgba(0,0,0,0.08);
  display: flex;
  flex-direction: column;
  overflow: hidden;
  z-index: 41;
}
@media (max-width: 600px) {
  .chatbot-panel {
    right: 0;
    bottom: 0;
    left: 0;
    top: 0;
    width: 100%;
    height: 100dvh;
    border-radius: 0;
    border: 0;
  }
}
.chatbot-panel--enter-start { opacity: 0; transform: translateY(8px); }
.chatbot-panel--enter-end { opacity: 1; transform: translateY(0); }
.chatbot-panel--enter { transition: opacity 0.18s ease, transform 0.18s ease; }

.chatbot-panel__head {
  display: flex;
  align-items: flex-start;
  gap: var(--s-3);
  padding: 14px 16px;
  background: var(--c-red-deep);
  color: #fff;
}
.chatbot-panel__title { flex: 1; min-width: 0; }
.chatbot-panel__title strong { font-family: var(--f-display); font-size: var(--fs-md); display: block; }
.chatbot-panel__sub { display: block; font-size: var(--fs-xs); opacity: 0.85; margin-top: 2px; }
.chatbot-panel__sub a { color: #fff; text-decoration: underline; }
.chatbot-panel__close {
  flex-shrink: 0;
  background: transparent;
  border: 0;
  color: #fff;
  width: 28px;
  height: 28px;
  border-radius: 4px;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.chatbot-panel__close:hover { background: rgba(255,255,255,0.15); }

.chatbot-panel__body {
  flex: 1;
  overflow-y: auto;
  padding: 16px;
  background: var(--c-paper);
  display: flex;
  flex-direction: column;
  gap: var(--s-3);
}

.chatbot-empty {
  background: var(--c-card);
  border: 1px solid var(--c-rule);
  border-radius: 8px;
  padding: 14px 16px;
  font-size: var(--fs-sm);
  color: var(--c-ink);
}
.chatbot-empty p { margin: 0 0 8px 0; }
.chatbot-empty p:last-of-type { margin-bottom: 12px; }

.chatbot-suggestions { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 6px; }
.chatbot-suggestion {
  display: block;
  width: 100%;
  text-align: left;
  background: var(--c-paper-2);
  border: 1px solid var(--c-rule);
  border-radius: 6px;
  padding: 8px 12px;
  font-family: var(--f-body);
  font-size: var(--fs-sm);
  color: var(--c-ink-2);
  cursor: pointer;
}
.chatbot-suggestion:hover { background: var(--c-paper); border-color: var(--c-red-deep); color: var(--c-ink); }

.chatbot-msg { display: flex; }
.chatbot-msg--user { justify-content: flex-end; }
.chatbot-msg--bot { justify-content: flex-start; }
.chatbot-msg__bubble {
  max-width: 85%;
  width: fit-content;
  padding: 10px 14px;
  border-radius: 12px;
  font-size: var(--fs-sm);
  line-height: 1.5;
  word-wrap: break-word;
  overflow-wrap: anywhere;
}
.chatbot-msg--user .chatbot-msg__bubble { background: var(--c-red-deep); color: #fff; border-bottom-right-radius: 4px; }
.chatbot-msg--bot .chatbot-msg__bubble { background: var(--c-card); color: var(--c-ink); border: 1px solid var(--c-rule); border-bottom-left-radius: 4px; }
.chatbot-msg__bubble p { margin: 0 0 8px 0; }
.chatbot-msg__bubble p:last-child { margin-bottom: 0; }
.chatbot-msg__bubble ul, .chatbot-msg__bubble ol { margin: 4px 0 8px 18px; padding-left: 0; }
.chatbot-msg__bubble li { margin-bottom: 2px; }
.chatbot-msg__bubble strong { font-weight: 700; }
.chatbot-msg__bubble em { font-style: italic; }
.chatbot-msg__bubble a { color: inherit; text-decoration: underline; }
.chatbot-msg--user .chatbot-msg__bubble a { color: #fff; }
.chatbot-msg__bubble code {
  background: rgba(0,0,0,0.06);
  padding: 1px 4px;
  border-radius: 3px;
  font-size: 0.92em;
  font-family: var(--f-mono, monospace);
}
.chatbot-msg--user .chatbot-msg__bubble code { background: rgba(255,255,255,0.18); }

.chatbot-citation {
  display: inline-block;
  font-size: var(--fs-xs);
  padding: 2px 8px;
  background: var(--c-paper-2);
  border: 1px solid var(--c-rule);
  border-radius: 999px;
  color: var(--c-ink-2);
  text-decoration: none;
}
.chatbot-citation:hover { background: var(--c-paper); border-color: var(--c-red-deep); color: var(--c-ink); }

.chatbot-msg__citations {
  margin-top: 10px;
  padding-top: 8px;
  border-top: 1px dashed var(--c-rule);
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  align-items: center;
}
.chatbot-citations-label { font-size: var(--fs-xs); color: var(--c-ink-3); margin-right: 4px; }

.chatbot-form {
  display: flex;
  gap: 8px;
  padding: 12px;
  background: var(--c-card);
  border-top: 1px solid var(--c-rule);
  align-items: center;
}
.chatbot-input {
  flex: 1;
  padding: 10px 12px;
  font-family: var(--f-body);
  font-size: var(--fs-sm);
  border: 1px solid var(--c-rule);
  border-radius: 999px;
  background: var(--c-paper);
  color: var(--c-ink);
  outline: none;
}
.chatbot-input:focus { border-color: var(--c-red-deep); }
.chatbot-input:disabled { opacity: 0.6; }
.chatbot-send {
  flex-shrink: 0;
  width: 40px;
  height: 40px;
  border: 0;
  border-radius: 999px;
  background: var(--c-red-deep);
  color: #fff;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.chatbot-send:disabled { opacity: 0.5; cursor: not-allowed; }
.chatbot-send:hover:not(:disabled) { background: var(--c-red); }

.chatbot-spinner {
  width: 16px;
  height: 16px;
  border: 2px solid rgba(255,255,255,0.4);
  border-top-color: #fff;
  border-radius: 50%;
  animation: chatbot-spin 0.8s linear infinite;
}
@keyframes chatbot-spin { to { transform: rotate(360deg); } }

.chatbot-citation--inert { pointer-events: none; opacity: 0.7; }
.chatbot-typing { color: var(--c-ink-3); font-style: italic; }

/* Chatbot sources list — 7 columns, needs more horizontal room than
   the default 600px minimum before the .cms-table-scroll wrapper
   kicks in. Pattern mirrors .cms-photos-table. */
.cms-digest-table .cms-table { min-width: 980px; }
.cms-digest-table .cms-table tbody td { white-space: nowrap; }
.cms-digest-table .cms-table tbody td:nth-child(2) { white-space: normal; min-width: 220px; }
