
/* ──────────────────────────────────────────────────────────────
   Tokens
   ────────────────────────────────────────────────────────────── */
:root {
  color-scheme: light;

  --bg: #FFF7F4;
  --surface: #FFFFFF;
  --surface-2: #FDF2EE;
  --surface-3: #F8E9E3;
  --border: #F0E6E0;
  --border-strong: #E2D2CA;
  --border-control: #9A8A82;
  --text: #1A1A1A;
  --text-muted: #6B6B6B;

  --accent: #F2725C;
  --accent-hover: #D4493A;
  --accent-ink: #B23A2C;
  --accent-wash: rgba(242, 114, 92, 0.12);
  --accent-edge: rgba(212, 73, 58, 0.28);

  --btn-bg: #B23A2C;
  --btn-bg-hover: #98301F;
  --btn-fg: #FFFFFF;

  --ok-ink: #1D6B4A;
  --ok-wash: rgba(29, 107, 74, 0.10);
  --warn-ink: #9B2C1C;
  --warn-wash: rgba(155, 44, 28, 0.09);

  --focus: #B23A2C;
  --header-bg: rgba(255, 247, 244, 0.85);

  /* Map palette. The static SVG reads these directly; the interactive canvas
     reads them through getComputedStyle, so both layers follow the theme from
     one definition. */
  --map-water: #D8E7EF;
  --map-land: #FFF9F6;
  --map-line: #CDB9AE;
  --map-label: #7D6D65;

  --shadow-sm: 0 1px 2px rgba(60, 30, 22, 0.05), 0 1px 3px rgba(60, 30, 22, 0.05);
  --shadow-md: 0 4px 14px rgba(60, 30, 22, 0.08), 0 2px 4px rgba(60, 30, 22, 0.04);
  --shadow-lg: 0 14px 36px rgba(60, 30, 22, 0.12);

  --font: "Nunito", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
    "Helvetica Neue", Arial, sans-serif;

  --container: 1100px;
  --gutter: clamp(1rem, 4vw, 2rem);

  --sp-1: 0.25rem;
  --sp-2: 0.5rem;
  --sp-3: 0.75rem;
  --sp-4: 1rem;
  --sp-5: 1.5rem;
  --sp-6: 2rem;
  --sp-7: 3rem;
  --sp-8: 4.5rem;

  /* Vertical rhythm. --flow separates blocks that belong to the same idea;
     --flow-section separates top-level sections and grows with the viewport,
     so a wide screen reads as chapters rather than one continuous column. */
  --flow: var(--sp-6);
  --flow-section: clamp(2.75rem, 2rem + 3vw, 4.5rem);

  --r-sm: 10px;
  --r-md: 14px;
  --r-lg: 20px;
  --r-pill: 999px;

  --fs-xs: 0.8125rem;
  --fs-sm: 0.9375rem;
  --fs-base: 1rem;
  --fs-md: 1.0625rem;
  --fs-lg: clamp(1.125rem, 0.95rem + 0.5vw, 1.3125rem);
  --fs-xl: clamp(1.375rem, 1.1rem + 1vw, 1.75rem);
  --fs-2xl: clamp(1.5rem, 1.15rem + 1.6vw, 2.25rem);
  --fs-3xl: clamp(1.75rem, 1.25rem + 2.4vw, 3rem);
}

[data-theme="dark"] {
  color-scheme: dark;

  --bg: #161622;
  --surface: #1E1E2E;
  --surface-2: #232334;
  --surface-3: #2A2A3E;
  --border: #2A2A3A;
  --border-strong: #3A3A4E;
  --border-control: #6A6A80;
  --text: #F5F0EB;
  --text-muted: #A0A0A8;

  --accent: #FF8A73;
  --accent-hover: #FFAB98;
  --accent-ink: #FFAB98;
  --accent-wash: rgba(242, 114, 92, 0.16);
  --accent-edge: rgba(255, 171, 152, 0.35);

  --btn-bg: #F2725C;
  --btn-bg-hover: #FFAB98;
  --btn-fg: #161622;

  --ok-ink: #7BD8A6;
  --ok-wash: rgba(123, 216, 166, 0.14);
  --warn-ink: #FF9C8A;
  --warn-wash: rgba(255, 156, 138, 0.14);

  --focus: #FFAB98;
  --header-bg: rgba(22, 22, 34, 0.85);

  --map-water: #131A28;
  --map-land: #22222F;
  --map-line: #3E3E52;
  --map-label: #A79A93;

  --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.32);
  --shadow-md: 0 6px 18px rgba(0, 0, 0, 0.38);
  --shadow-lg: 0 16px 40px rgba(0, 0, 0, 0.46);
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
  color-scheme: dark;

  --bg: #161622;
  --surface: #1E1E2E;
  --surface-2: #232334;
  --surface-3: #2A2A3E;
  --border: #2A2A3A;
  --border-strong: #3A3A4E;
  --border-control: #6A6A80;
  --text: #F5F0EB;
  --text-muted: #A0A0A8;

  --accent: #FF8A73;
  --accent-hover: #FFAB98;
  --accent-ink: #FFAB98;
  --accent-wash: rgba(242, 114, 92, 0.16);
  --accent-edge: rgba(255, 171, 152, 0.35);

  --btn-bg: #F2725C;
  --btn-bg-hover: #FFAB98;
  --btn-fg: #161622;

  --ok-ink: #7BD8A6;
  --ok-wash: rgba(123, 216, 166, 0.14);
  --warn-ink: #FF9C8A;
  --warn-wash: rgba(255, 156, 138, 0.14);

  --focus: #FFAB98;
  --header-bg: rgba(22, 22, 34, 0.85);

  --map-water: #131A28;
  --map-land: #22222F;
  --map-line: #3E3E52;
  --map-label: #A79A93;

  --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.32);
  --shadow-md: 0 6px 18px rgba(0, 0, 0, 0.38);
  --shadow-lg: 0 16px 40px rgba(0, 0, 0, 0.46);
}
}

/* ──────────────────────────────────────────────────────────────
   Reset
   ────────────────────────────────────────────────────────────── */
*,
*::before,
*::after { box-sizing: border-box; }

body, h1, h2, h3, h4, p, ul, ol, dl, dd, figure, blockquote, fieldset {
  margin: 0;
}

ul[class], ol[class] { padding: 0; list-style: none; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  scroll-padding-top: 5rem;
  /* Nothing may ever scroll the document sideways on a phone. Uses clip, not
     hidden: hidden would make this a scroll container and break the sticky
     header. */
  overflow-x: clip;
  background: var(--bg);
}

body {
  min-height: 100vh;
  max-width: 100%;
  overflow-x: clip;
  display: flex;
  flex-direction: column;
  font-family: var(--font);
  font-size: var(--fs-base);
  line-height: 1.6;
  color: var(--text);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

img, svg, picture, video { display: block; max-width: 100%; }
img { height: auto; }

input, button, select, textarea {
  font: inherit;
  color: inherit;
}

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

h1, h2, h3, h4 {
  line-height: 1.2;
  font-weight: 800;
  letter-spacing: -0.015em;
  text-wrap: balance;
}

p { text-wrap: pretty; }

hr {
  border: 0;
  border-top: 1px solid var(--border);
  margin: var(--sp-6) 0;
}

/* ──────────────────────────────────────────────────────────────
   Focus & assistive utilities
   ────────────────────────────────────────────────────────────── */
:focus-visible {
  outline: 3px solid var(--focus);
  outline-offset: 2px;
  border-radius: 4px;
}

/* Older engines that do not support :focus-visible still get a ring. */
:focus:not(:focus-visible) { outline: none; }

.visually-hidden {
  position: absolute !important;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

.skip-link {
  position: absolute;
  left: var(--sp-4);
  top: var(--sp-4);
  z-index: 200;
  transform: translateY(-200%);
  padding: var(--sp-3) var(--sp-4);
  background: var(--surface);
  color: var(--text);
  border: 2px solid var(--focus);
  border-radius: var(--r-sm);
  font-weight: 700;
  text-decoration: none;
  box-shadow: var(--shadow-md);
}
.skip-link:focus { transform: translateY(0); }

/* Controls that only make sense with scripting. The pre-paint bootstrap adds
   `js` to <html>, so this is correct on first paint rather than after load. */
:root:not(.js) .js-only { display: none !important; }
:root.js .no-js-only { display: none !important; }

/* ──────────────────────────────────────────────────────────────
   Layout primitives
   ────────────────────────────────────────────────────────────── */
.container,
.site-main > * {
  width: 100%;
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.container--narrow { max-width: 760px; }

/* Opt a direct child of <main> out of the automatic container so it can carry
   an edge-to-edge background; put a .container inside it. */
.site-main > .band {
  max-width: none;
  padding-inline: 0;
}

.site-main {
  flex: 1 0 auto;
  display: block;
  padding-block: var(--sp-6) var(--sp-8);
}

.site-main > * + * { margin-top: var(--flow-section); }

/* The hero, its stat summary and the filter row are one introductory unit:
   they sit closer to each other than to the first real section, and the
   filters get clear air above them so they do not crowd the stats. */
/* A breadcrumb labels the heading beneath it, so it hugs that heading rather
   than floating a full section gap away from it. */
.site-main > .breadcrumbs + * { margin-top: var(--sp-4); }

/* Filters belong to the heading above them on a list page — the same
   introductory unit the home page forms with its hero and stats. */
.site-main > .page-header + .stack,
.site-main > .page-header + .chip-row-wrap { margin-top: var(--sp-5); }

.site-main > .page-header + .stat-bar { margin-top: var(--sp-5); }
.site-main > .stat-bar + * { margin-top: clamp(2.25rem, 1.8rem + 1.8vw, 3rem); }

.stack > * + * { margin-top: var(--sp-4); }
.stack-lg > * + * { margin-top: var(--flow); }

.band {
  background: var(--surface-2);
  border-block: 1px solid var(--border);
  padding-block: var(--sp-7);
}

.panel {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  padding: var(--sp-5);
  box-shadow: var(--shadow-sm);
}

/* ──────────────────────────────────────────────────────────────
   Header
   ────────────────────────────────────────────────────────────── */
.site-header {
  position: sticky;
  top: 0;
  z-index: 50;
  background: var(--bg);
  border-bottom: 1px solid var(--border);
}

@supports (backdrop-filter: blur(8px)) or (-webkit-backdrop-filter: blur(8px)) {
  .site-header {
    background: var(--header-bg);
    -webkit-backdrop-filter: saturate(1.6) blur(10px);
    backdrop-filter: saturate(1.6) blur(10px);
  }
}

.header-inner {
  display: flex;
  align-items: center;
  gap: var(--sp-4);
  min-height: 3.75rem;
  padding-block: var(--sp-2);
  flex-wrap: wrap;
}

.wordmark {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  font-size: 1.1875rem;
  font-weight: 800;
  letter-spacing: -0.02em;
  color: var(--text);
  text-decoration: none;
  flex: 0 0 auto;
}
.wordmark__type {
  display: flex;
  flex-direction: column;
  gap: 0.05rem;
  line-height: 1.05;
}
.wordmark__name { display: block; }

/* The balloon drifts a little on hover — a small, one-off moment of life for
   the brand mark, suppressed entirely under prefers-reduced-motion. */
.balloon {
  flex: 0 0 auto;
  color: var(--text-muted);
  transform-origin: 50% 90%;
  transition: transform 320ms cubic-bezier(0.34, 1.3, 0.64, 1);
}
.wordmark:hover .balloon,
.wordmark:focus-visible .balloon { transform: translateY(-2px) rotate(-4deg); }

.footer-brand .balloon { width: 26px; height: 26px; }
.wordmark .balloon { width: 25px; height: 25px; }

@media (min-width: 46em) {
  .wordmark { font-size: 1.375rem; }
  .wordmark .balloon { width: 30px; height: 30px; }
}
.wordmark:hover { color: var(--text); }
.wordmark__dot { color: var(--accent-ink); }
.wordmark__tag {
  font-size: 0.6875rem;
  font-weight: 700;
  color: var(--text-muted);
  letter-spacing: 0.02em;
  text-transform: uppercase;
  display: none;
}

.header-tools {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  margin-left: auto;
}

.primary-nav {
  order: 3;
  width: 100%;
  max-width: 100%;
  min-width: 0;
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scroll-snap-type: x proximity;
  scrollbar-width: none;
}
.primary-nav::-webkit-scrollbar { display: none; }

.nav-list {
  display: flex;
  gap: var(--sp-1);
  padding-bottom: var(--sp-2);
}

.nav-link {
  display: block;
  flex: 0 0 auto;
  scroll-snap-align: start;
  padding: 0.375rem 0.7rem;
  border-radius: var(--r-pill);
  font-size: var(--fs-sm);
  font-weight: 700;
  color: var(--text-muted);
  text-decoration: none;
  white-space: nowrap;
  transition: background-color 0.15s ease, color 0.15s ease;
}
.nav-link:hover { color: var(--text); background: var(--surface-3); }
.nav-link.is-active,
.nav-link[aria-current] {
  color: var(--accent-ink);
  background: var(--accent-wash);
}

.search-form {
  display: flex;
  align-items: center;
  gap: 0;
  background: var(--surface);
  border: 1px solid var(--border-control);
  border-radius: var(--r-pill);
  padding: 0.125rem 0.125rem 0.125rem 0.75rem;
  min-width: 0;
}
.search-form:focus-within {
  outline: 3px solid var(--focus);
  outline-offset: 1px;
}
.search-input {
  border: 0;
  background: transparent;
  padding: 0.4rem 0.25rem;
  font-size: var(--fs-sm);
  width: 7.5rem;
  min-width: 0;
}
.search-input:focus { outline: none; }
.search-input::placeholder { color: var(--text-muted); }
.search-submit {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2rem;
  height: 2rem;
  border: 0;
  border-radius: 50%;
  background: transparent;
  color: var(--accent-ink);
  cursor: pointer;
  flex: 0 0 auto;
}
.search-submit:hover { background: var(--accent-wash); }

.theme-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.375rem;
  height: 2.375rem;
  flex: 0 0 auto;
  border: 1px solid var(--border-control);
  border-radius: 50%;
  background: var(--surface);
  color: var(--text);
  cursor: pointer;
  transition: border-color 0.15s ease, background-color 0.15s ease;
}
.theme-toggle:hover { border-color: var(--accent); background: var(--accent-wash); }
.theme-toggle .icon-sun { display: none; }
.theme-toggle .icon-moon { display: block; }
[data-theme="dark"] .theme-toggle .icon-sun { display: block; }
[data-theme="dark"] .theme-toggle .icon-moon { display: none; }

@media (min-width: 46em) {
  .header-inner { flex-wrap: nowrap; gap: var(--sp-5); }
  .primary-nav {
    order: 0;
    width: auto;
    margin-inline: 0;
    padding-inline: 0;
    /* Keeps the base overflow-x: auto so a tight row scrolls, never wraps. */
    min-width: 0;
  }
  /* Never wrap: a two-line header reads as broken. If the row is ever too
     tight the nav falls back to the same horizontal scroll it uses on
     mobile, with the fade cue marking it as swipeable. */
  .nav-list { padding-bottom: 0; flex-wrap: nowrap; }
  .search-input { width: 9.5rem; }
  .wordmark__tag { display: inline; }
}

@media (min-width: 64em) {
  .search-input { width: 13rem; }
}

/* ──────────────────────────────────────────────────────────────
   Breadcrumbs
   ────────────────────────────────────────────────────────────── */
.breadcrumbs { font-size: var(--fs-sm); }

.breadcrumb-list {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.35rem;
  padding: 0;
  margin: 0;
  list-style: none;
  color: var(--text-muted);
}
.breadcrumb-list a { color: var(--text-muted); text-decoration: none; }
.breadcrumb-list a:hover { color: var(--accent-ink); text-decoration: underline; }
.breadcrumb-item { display: inline-flex; align-items: center; gap: 0.35rem; }
.breadcrumb-item [aria-current] { color: var(--text); font-weight: 700; }
.breadcrumb-sep { color: var(--border-strong); }

/* ──────────────────────────────────────────────────────────────
   Typography helpers
   ────────────────────────────────────────────────────────────── */
.page-title { font-size: var(--fs-2xl); }

/* The header block spans the content column so it lines up with the stats,
   filters and cards beneath it, inheriting the container width from
   .site-main > *; only its prose is measure-limited. Capping the block itself
   let the auto inline margins center it, which left the hero floating
   mid-screen while everything below hugged the left. */
.page-header > * { max-width: 62ch; }
.page-header > * + * { margin-top: var(--sp-3); }

.lede {
  font-size: var(--fs-md);
  color: var(--text-muted);
  line-height: 1.55;
  max-width: 60ch;
}

@media (min-width: 46em) {
  .lede { font-size: var(--fs-lg); }
}

.muted { color: var(--text-muted); }
.small { font-size: var(--fs-sm); }
.eyebrow {
  font-size: var(--fs-xs);
  font-weight: 800;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--accent-ink);
}

.prose { max-width: 68ch; }
.prose > * + * { margin-top: var(--sp-4); }
.prose h2 { font-size: var(--fs-xl); margin-top: var(--sp-6); }
.prose h3 { font-size: var(--fs-lg); margin-top: var(--sp-5); }
.prose ul, .prose ol { padding-left: 1.35rem; }
.prose li + li { margin-top: var(--sp-2); }
.prose a { text-underline-offset: 0.15em; }

/* ──────────────────────────────────────────────────────────────
   Buttons
   ────────────────────────────────────────────────────────────── */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  padding: 0.65rem 1.15rem;
  border: 1px solid transparent;
  border-radius: var(--r-pill);
  font-size: var(--fs-sm);
  font-weight: 800;
  line-height: 1.2;
  text-decoration: none;
  cursor: pointer;
  transition: background-color 0.15s ease, border-color 0.15s ease,
    color 0.15s ease, transform 0.12s ease;
}
.btn:active { transform: translateY(1px); }

.btn--primary {
  background: var(--btn-bg);
  color: var(--btn-fg);
}
.btn--primary:hover { background: var(--btn-bg-hover); color: var(--btn-fg); }

.btn--ghost {
  background: var(--surface);
  color: var(--text);
  border-color: var(--border-control);
}
.btn--ghost:hover { border-color: var(--accent); background: var(--accent-wash); color: var(--text); }

.btn--quiet {
  background: transparent;
  color: var(--accent-ink);
  padding-inline: 0.5rem;
}
.btn--quiet:hover { color: var(--accent-hover); text-decoration: underline; }

.btn--sm { padding: 0.4rem 0.85rem; font-size: var(--fs-xs); }
.btn--lg { padding: 0.85rem 1.6rem; font-size: var(--fs-base); }
.btn--block { width: 100%; }

.btn-row,
.event-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2);
}

@media (min-width: 30em) {
  .btn-row,
  .event-actions { gap: var(--sp-3); }
}

/* A row of buttons directly after body copy would otherwise sit on top of the
   last line. Affects /support, /newsletter and the unsubscribe page. */
.prose + .btn-row { margin-top: var(--sp-5); }

/* ──────────────────────────────────────────────────────────────
   Chips
   ────────────────────────────────────────────────────────────── */
/* Layout containment here is load-bearing, not decoration.
   A swipeable rail is far wider than the phone it sits on. Setting overflow-x
   to auto stops it scrolling the document, but on a phone the browser still
   sizes the LAYOUT VIEWPORT from the widest content on the page — so the rail
   quietly stretched the viewport to 999px on the home page while the content
   stayed 393px, leaving two thirds of the screen empty to the right. Layout
   containment is the assertion that fixes it: what happens inside this rail
   cannot change anything outside it. The overflow-x: clip on html and body
   does NOT cover this — clip suppresses scrolling, not viewport sizing.
   Verified at a 393px viewport: home 999 -> 393, guides 754 -> 393, with the
   rail still horizontally scrollable. */
.chip-row-wrap,
.primary-nav {
  contain: layout;
}

.chip-row-wrap {
  max-width: 100%;
  min-width: 0;
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scroll-snap-type: x proximity;
  scroll-padding-inline: var(--sp-1);
  scrollbar-width: none;
}

/* Fade the trailing edge so a cut-off row reads as swipeable, not clipped.
   The class is set by the client script only when content actually overflows,
   so a short row never gets a pointless fade. */
.chip-row-wrap.is-scrollable,
.primary-nav.is-scrollable {
  -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 3rem), transparent);
  mask-image: linear-gradient(to right, #000 calc(100% - 3rem), transparent);
}
.chip-row-wrap::-webkit-scrollbar { display: none; }

.chip .icon { flex: 0 0 auto; margin-right: 0.1rem; }
/* The active chip fills with its category ink. That ink is dark in the light
   theme and light in the dark theme, so the label color has to flip with it —
   white on the dark-theme ink measures 1.65:1. --cat-on carries the correct
   pairing and is redefined alongside the palette below. */
.chip--category.is-active {
  background: var(--cat-ink);
  border-color: var(--cat-ink);
  color: var(--cat-on, #fff);
}
.chip--category.is-active .chip__count { color: var(--cat-on, #fff); opacity: 0.78; }

.chip-row {
  display: flex;
  gap: var(--sp-2);
  padding: 0 0 var(--sp-1);
  margin: 0;
  list-style: none;
}

.chip {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  flex: 0 0 auto;
  scroll-snap-align: start;
  padding: 0.45rem 0.85rem;
  border: 1px solid var(--border-strong);
  border-radius: var(--r-pill);
  background: var(--surface);
  color: var(--text);
  font-size: var(--fs-sm);
  font-weight: 700;
  text-decoration: none;
  white-space: nowrap;
  transition: border-color 0.15s ease, background-color 0.15s ease;
}
.chip:hover { border-color: var(--accent); background: var(--accent-wash); color: var(--text); }
.chip.is-active {
  background: var(--btn-bg);
  border-color: var(--btn-bg);
  color: var(--btn-fg);
}
.chip.is-active:hover { background: var(--btn-bg-hover); border-color: var(--btn-bg-hover); color: var(--btn-fg); }

.chip__count {
  font-size: var(--fs-xs);
  font-weight: 700;
  color: var(--text-muted);
}
.chip.is-active .chip__count { color: var(--btn-fg); opacity: 0.85; }

@media (min-width: 46em) {
  .chip-row-wrap {
    margin-inline: 0;
    padding-inline: 0;
    overflow: visible;
  }
  .chip-row { flex-wrap: wrap; }
}

/* ──────────────────────────────────────────────────────────────
   Section headers
   ────────────────────────────────────────────────────────────── */
.section-header {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--sp-4);
  flex-wrap: wrap;
  margin-bottom: var(--sp-5);
}
.section-header__text > * + * { margin-top: var(--sp-1); }
.section-title { font-size: var(--fs-xl); }
.section-subtitle { color: var(--text-muted); font-size: var(--fs-sm); }
.section-header__link {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  font-weight: 800;
  font-size: var(--fs-sm);
  text-decoration: none;
  white-space: nowrap;
}
.section-header__link:hover { text-decoration: underline; }

/* ──────────────────────────────────────────────────────────────
   Category color
   ──────────────────────────────────────────────────────────────
   Every card, pill and chip inherits its hue from one of these six
   classes, so a grid of results is color-coded and scannable rather
   than six shades of coral. --cat-ink is the text color and clears
   4.5:1 against --cat-wash in both themes; --cat-a/--cat-b drive the
   generated cover gradient, where contrast is not a text concern. */
.cat-storytimes { --cat-on:#fff; --cat-ink:#8A5300; --cat-wash:#FCF2DF; --cat-edge:#EAD6A8; --cat-a:#F7C25C; --cat-b:#E39122; }
.cat-parks { --cat-on:#fff; --cat-ink:#1B6742; --cat-wash:#E5F3EA; --cat-edge:#B9DCC7; --cat-a:#69C48F; --cat-b:#2E8B5B; }
.cat-museums { --cat-on:#fff; --cat-ink:#66399B; --cat-wash:#F0E9FA; --cat-edge:#D3C2EE; --cat-a:#B18CE8; --cat-b:#7A4FC0; }
.cat-farmers-markets { --cat-on:#fff; --cat-ink:#0F6668; --cat-wash:#E1F2F2; --cat-edge:#AFDBDC; --cat-a:#5FC7C9; --cat-b:#1B8C8E; }
.cat-festivals { --cat-on:#fff; --cat-ink:#B23A2C; --cat-wash:#FCEBE7; --cat-edge:#F2C7BE; --cat-a:#FF9C86; --cat-b:#E05B44; }
.cat-community { --cat-on:#fff; --cat-ink:#20569F; --cat-wash:#E7F0FB; --cat-edge:#BED6F1; --cat-a:#7EAEEA; --cat-b:#3A72C0; }

[data-theme="dark"] .cat-storytimes,
[data-theme="dark"] .cat-parks,
[data-theme="dark"] .cat-museums,
[data-theme="dark"] .cat-farmers-markets,
[data-theme="dark"] .cat-festivals,
[data-theme="dark"] .cat-community { --cat-edge: rgba(255,255,255,0.10); }
[data-theme="dark"] .cat-storytimes { --cat-on:#161622; --cat-ink:#F3C267; --cat-wash:rgba(243,194,103,0.13); }
[data-theme="dark"] .cat-parks { --cat-on:#161622; --cat-ink:#7FD3A3; --cat-wash:rgba(127,211,163,0.13); }
[data-theme="dark"] .cat-museums { --cat-on:#161622; --cat-ink:#C0A3F2; --cat-wash:rgba(192,163,242,0.13); }
[data-theme="dark"] .cat-farmers-markets { --cat-on:#161622; --cat-ink:#6CD1D3; --cat-wash:rgba(108,209,211,0.13); }
[data-theme="dark"] .cat-festivals { --cat-on:#161622; --cat-ink:#FF8A73; --cat-wash:rgba(255,138,115,0.13); }
[data-theme="dark"] .cat-community { --cat-on:#161622; --cat-ink:#8FB6EF; --cat-wash:rgba(143,182,239,0.13); }

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .cat-storytimes,
  :root:not([data-theme="light"]) .cat-parks,
  :root:not([data-theme="light"]) .cat-museums,
  :root:not([data-theme="light"]) .cat-farmers-markets,
  :root:not([data-theme="light"]) .cat-festivals,
  :root:not([data-theme="light"]) .cat-community { --cat-edge: rgba(255,255,255,0.10); }
  :root:not([data-theme="light"]) .cat-storytimes { --cat-on:#161622; --cat-ink:#F3C267; --cat-wash:rgba(243,194,103,0.13); }
  :root:not([data-theme="light"]) .cat-parks { --cat-on:#161622; --cat-ink:#7FD3A3; --cat-wash:rgba(127,211,163,0.13); }
  :root:not([data-theme="light"]) .cat-museums { --cat-on:#161622; --cat-ink:#C0A3F2; --cat-wash:rgba(192,163,242,0.13); }
  :root:not([data-theme="light"]) .cat-farmers-markets { --cat-on:#161622; --cat-ink:#6CD1D3; --cat-wash:rgba(108,209,211,0.13); }
  :root:not([data-theme="light"]) .cat-festivals { --cat-on:#161622; --cat-ink:#FF8A73; --cat-wash:rgba(255,138,115,0.13); }
  :root:not([data-theme="light"]) .cat-community { --cat-on:#161622; --cat-ink:#8FB6EF; --cat-wash:rgba(143,182,239,0.13); }
}

/* ──────────────────────────────────────────────────────────────
   Source cards (/sources)
   ────────────────────────────────────────────────────────────── */
.source-card__name {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-size: var(--fs-md);
}
.source-card__name .icon {
  flex: 0 0 auto;
  color: var(--cat-ink, var(--accent-ink));
}
.source-card__name a { color: var(--text); text-decoration: none; }
.source-card__name a:hover {
  color: var(--cat-ink, var(--accent-ink));
  text-decoration: underline;
}
.source-card { border-left: 3px solid var(--cat-ink, var(--accent)); }

/* ──────────────────────────────────────────────────────────────
   Generated card cover
   ────────────────────────────────────────────────────────────── */
.card-media {
  position: relative;
  height: 5.25rem;
  border-radius: calc(var(--r-md) - 1px) calc(var(--r-md) - 1px) 0 0;
  background: linear-gradient(135deg, var(--cat-a, var(--accent)) 0%, var(--cat-b, var(--accent-hover)) 100%);
  overflow: hidden;
  display: flex;
  align-items: flex-end;
  padding: var(--sp-3);
}
/* The glyph is a watermark, deliberately cropped by the band. */
.card-media > .icon {
  position: absolute;
  right: -0.5rem;
  top: -0.75rem;
  width: 4.75rem;
  height: 4.75rem;
  color: #fff;
  opacity: 0.34;
  stroke-width: 1.4;
}

.date-tile {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  min-width: 3rem;
  padding: 0.3rem 0.55rem;
  border-radius: var(--r-sm);
  background: var(--surface);
  box-shadow: var(--shadow-sm);
  line-height: 1.05;
}
.date-tile__top {
  font-size: 0.625rem;
  font-weight: 800;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--cat-ink, var(--accent-ink));
}
.date-tile__bottom {
  font-size: 1.125rem;
  font-weight: 800;
  color: var(--text);
  font-variant-numeric: tabular-nums;
}
.date-tile--today .date-tile__bottom { color: var(--cat-ink, var(--accent-ink)); }

/* ──────────────────────────────────────────────────────────────
   Event cards
   ────────────────────────────────────────────────────────────── */
.event-grid {
  display: grid;
  gap: var(--sp-4);
  grid-template-columns: 1fr;
  padding: 0;
  margin: 0;
  list-style: none;
}

@media (min-width: 40em) {
  .event-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (min-width: 64em) {
  .event-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

.event-grid__item { display: flex; }

.event-card {
  display: flex;
  flex-direction: column;
  width: 100%;
  overflow: hidden;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  box-shadow: var(--shadow-sm);
  transition: box-shadow 0.18s ease, border-color 0.18s ease, transform 0.18s ease;
}
.event-card:hover {
  box-shadow: var(--shadow-md);
  border-color: var(--cat-edge, var(--border-strong));
  transform: translateY(-2px);
}

.event-card__body {
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
  flex: 1;
  padding: var(--sp-4);
}

.event-card__top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-2);
}

.event-card__title {
  font-size: var(--fs-md);
  font-weight: 800;
  line-height: 1.3;
}
.event-card__link {
  color: var(--text);
  text-decoration: none;
}
.event-card__link:hover { color: var(--cat-ink, var(--accent-ink)); text-decoration: underline; }


.event-card__meta {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  font-size: var(--fs-sm);
  color: var(--text-muted);
  margin-top: auto;
}
.event-card__meta p {
  display: flex;
  align-items: flex-start;
  gap: 0.45rem;
}
.event-card__meta .icon { flex: 0 0 auto; margin-top: 0.15rem; color: var(--text-muted); }
.event-card__when { color: var(--text); font-weight: 700; }
.event-card__dot { color: var(--text-muted); font-weight: 400; }

.event-card__badges {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem;
  padding: 0;
  margin: 0;
  list-style: none;
}

.event-card__source {
  font-size: var(--fs-xs);
  color: var(--text-muted);
  border-top: 1px solid var(--border);
  padding-top: var(--sp-2);
}

/* ──────────────────────────────────────────────────────────────
   Pills & badges
   ────────────────────────────────────────────────────────────── */
.pill {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  padding: 0.25rem 0.6rem;
  border-radius: var(--r-pill);
  font-size: var(--fs-xs);
  font-weight: 800;
  text-decoration: none;
  background: var(--accent-wash);
  color: var(--accent-ink);
  border: 1px solid var(--accent-edge);
  white-space: nowrap;
}
/* A pill inside a category-scoped element takes that category's hue. Declared
   after the base .pill so it wins on equal specificity. */
.pill--category,
.chip--category {
  color: var(--cat-ink, var(--accent-ink));
  background: var(--cat-wash, var(--accent-wash));
  border-color: var(--cat-edge, var(--accent-edge));
}
a.pill:hover { background: var(--surface-3); color: var(--accent-hover); }
a.pill--category:hover { background: var(--cat-wash); color: var(--cat-ink); border-color: var(--cat-ink); }

.badge {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  padding: 0.2rem 0.55rem;
  border-radius: var(--r-pill);
  border: 1px solid var(--border-strong);
  background: var(--surface-2);
  color: var(--text-muted);
  font-size: var(--fs-xs);
  font-weight: 700;
  white-space: nowrap;
}
.badge--free {
  color: var(--ok-ink);
  background: var(--ok-wash);
  border-color: transparent;
}

.save-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.125rem;
  height: 2.125rem;
  flex: 0 0 auto;
  padding: 0;
  border: 1px solid var(--border-strong);
  border-radius: 50%;
  background: var(--surface);
  color: var(--text-muted);
  cursor: pointer;
  transition: color 0.15s ease, border-color 0.15s ease, background-color 0.15s ease;
}
.save-btn:hover { color: var(--accent-ink); border-color: var(--accent); }
.save-btn[aria-pressed="true"] {
  color: var(--btn-fg);
  background: var(--btn-bg);
  border-color: var(--btn-bg);
}
.save-btn[aria-pressed="true"] .icon { fill: currentColor; }

/* ──────────────────────────────────────────────────────────────
   Day groups
   ────────────────────────────────────────────────────────────── */
.day-group + .day-group { margin-top: var(--sp-7); }

.day-heading {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 0.6rem;
  font-size: var(--fs-lg);
  padding-bottom: var(--sp-2);
  margin-bottom: var(--sp-4);
  border-bottom: 2px solid var(--accent-edge);
}
.day-heading__rel { color: var(--text); }
.day-heading__date {
  font-size: var(--fs-sm);
  font-weight: 700;
  color: var(--text-muted);
  letter-spacing: 0;
}

/* ──────────────────────────────────────────────────────────────
   Empty state
   ────────────────────────────────────────────────────────────── */
.empty-state {
  text-align: center;
  padding: var(--sp-7) var(--sp-4);
  background: var(--surface);
  border: 1px dashed var(--border-strong);
  border-radius: var(--r-lg);
}
.empty-state > * + * { margin-top: var(--sp-3); }
.empty-state__icon { margin-inline: auto; color: var(--accent); }
.empty-state__title { font-size: var(--fs-lg); font-weight: 800; }
.empty-state__body { color: var(--text-muted); max-width: 46ch; margin-inline: auto; }
.empty-state__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-3);
  justify-content: center;
}

/* ──────────────────────────────────────────────────────────────
   Pagination
   ────────────────────────────────────────────────────────────── */
.pagination {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  gap: var(--sp-2);
  margin-top: var(--sp-7);
}
.pagination__list {
  display: flex;
  align-items: center;
  gap: 0.25rem;
  padding: 0;
  margin: 0;
  list-style: none;
}
.page-link {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.35rem;
  min-width: 2.5rem;
  height: 2.5rem;
  padding: 0 0.7rem;
  border: 1px solid var(--border-strong);
  border-radius: var(--r-sm);
  background: var(--surface);
  color: var(--text);
  font-size: var(--fs-sm);
  font-weight: 700;
  text-decoration: none;
}
.page-link:hover { border-color: var(--accent); background: var(--accent-wash); color: var(--text); }
.page-link.is-current {
  background: var(--btn-bg);
  border-color: var(--btn-bg);
  color: var(--btn-fg);
  cursor: default;
}
/* One arrow glyph, mirrored for "Previous". */
.page-link--prev .icon { transform: scaleX(-1); }

.page-ellipsis {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 1.75rem;
  color: var(--text-muted);
}

/* ──────────────────────────────────────────────────────────────
   Stat bar
   ────────────────────────────────────────────────────────────── */
/* The surface lives on each stat, never on the grid: .stat-bar is a direct
   child of main and therefore carries the container inline padding, so a
   background here would paint edge-to-edge on a phone. */
.stat-bar {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--sp-2);
}
.stat {
  /* Value reads first visually; the <dt> label must come first in the DOM. */
  display: flex;
  flex-direction: row-reverse;
  align-items: baseline;
  justify-content: flex-end;
  gap: 0.4rem;
  min-width: 0;
  padding: var(--sp-3);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-sm);
}
.stat__value {
  margin: 0;
  font-size: var(--fs-md);
  font-weight: 800;
  color: var(--accent-ink);
  line-height: 1.2;
  font-variant-numeric: tabular-nums;
}
.stat__label {
  font-size: var(--fs-xs);
  font-weight: 600;
  color: var(--text-muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

@media (min-width: 34em) {
  .stat-bar {
    grid-template-columns: repeat(auto-fit, minmax(8rem, 1fr));
    gap: var(--sp-3);
  }
  .stat {
    flex-direction: column-reverse;
    align-items: center;
    justify-content: center;
    text-align: center;
    gap: 0.1rem;
    padding: var(--sp-4);
    border-radius: var(--r-md);
  }
  .stat__value { font-size: var(--fs-xl); }
  .stat__label { white-space: normal; }
}

/* ──────────────────────────────────────────────────────────────
   Callouts
   ────────────────────────────────────────────────────────────── */
.callout {
  display: flex;
  gap: var(--sp-3);
  padding: var(--sp-4);
  border-radius: var(--r-md);
  border: 1px solid var(--border-strong);
  background: var(--surface-2);
  font-size: var(--fs-sm);
}
.callout--success { background: var(--ok-wash); border-color: transparent; color: var(--ok-ink); }
.callout--error { background: var(--warn-wash); border-color: transparent; color: var(--warn-ink); }

/* An empty callout is collapsed rather than removed: a role="status" region
   has to stay in the accessibility tree while empty, or screen readers never
   register it and the text JS drops in later goes unannounced. */
.callout:empty {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  border: 0;
  overflow: hidden;
  clip-path: inset(50%);
}

/* ──────────────────────────────────────────────────────────────
   Map
   ────────────────────────────────────────────────────────────── */
.map-shell > * + * { margin-top: var(--sp-3); }

.map-frame {
  position: relative;
  width: 100%;
  aspect-ratio: 720 / 520;
  max-height: 560px;
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  overflow: hidden;
  background: var(--map-water);
  box-shadow: var(--shadow-sm);
}

.static-map {
  display: block;
  width: 100%;
  height: 100%;
}

.msvg-water { fill: var(--map-water); }
.msvg-land { fill: var(--map-land); stroke: var(--map-line); stroke-width: 1.1; }
.msvg-city {
  font-size: 11.5px;
  font-weight: 700;
  fill: var(--map-label);
  paint-order: stroke;
  stroke: var(--map-land);
  stroke-width: 3.5px;
  stroke-linejoin: round;
}
.msvg-credit { font-size: 10px; fill: var(--map-label); }
.msvg-pin { stroke: #fff; stroke-width: 2.5; }
.msvg-pin-count { font-size: 14px; font-weight: 800; fill: #fff; }
.msvg-badge { fill: #1A1A1A; stroke: #fff; stroke-width: 1.6; }
.msvg-badge-count { font-size: 10px; font-weight: 800; fill: #fff; }

/* The interactive canvas replaces the SVG inside the same frame. */
.map-frame .maplibregl-map {
  position: absolute;
  inset: 0;
  font: inherit;
}

/* DOM markers: anchors, so pins stay keyboard-reachable and are real links. */
.map-pin {
  display: block;
  width: 31px;
  height: 31px;
  cursor: pointer;
}
.map-pin svg { display: block; overflow: visible; }
.map-pin:focus-visible { outline: 3px solid var(--focus); outline-offset: 2px; border-radius: 50%; }

.map-city-label {
  font-size: 11.5px;
  font-weight: 700;
  color: var(--map-label);
  text-shadow: 0 0 3px var(--map-land), 0 0 3px var(--map-land);
  pointer-events: none;
  white-space: nowrap;
}

/* MapLibre popup, restyled to the site's card language. Scoped under
   .map-frame for specificity: the vendored MapLibre stylesheet loads after
   this one on map pages, and these overrides must still win. */
.map-frame .maplibregl-popup-content {
  background: var(--surface);
  color: var(--text);
  border-radius: var(--r-md);
  box-shadow: var(--shadow-md);
  padding: var(--sp-3) var(--sp-4);
  font-family: var(--font);
  max-width: 280px;
}
.map-frame .maplibregl-popup-tip { border-top-color: var(--surface) !important; }
.map-frame .maplibregl-popup-close-button {
  font-size: 1.1rem;
  padding: 2px 8px;
  color: var(--text-muted);
}
.map-popup__title {
  font-weight: 800;
  font-size: var(--fs-sm);
  line-height: 1.3;
  display: block;
  color: var(--accent-ink);
}
.map-popup__meta {
  margin-top: 0.3rem;
  font-size: var(--fs-xs);
  color: var(--text-muted);
}
.map-popup__list { margin: 0; padding: 0; list-style: none; }
.map-popup__list > li + li {
  margin-top: var(--sp-2);
  padding-top: var(--sp-2);
  border-top: 1px solid var(--border);
}

/* Maplibre attribution, kept quiet but legible in both themes. */
.map-frame .maplibregl-ctrl-attrib {
  background: color-mix(in srgb, var(--map-land) 82%, transparent);
  color: var(--map-label);
  font-size: 10px;
}
.map-frame .maplibregl-ctrl-attrib a { color: var(--map-label); }

.map-note:empty { display: none; }

/* The home-page map teaser: the static SVG as one big link to /map. */
.map-teaser {
  display: block;
  position: relative;
  text-decoration: none;
  border-radius: var(--r-lg);
}
.map-teaser .map-frame { max-height: 420px; transition: box-shadow 0.15s ease; }
.map-teaser:hover .map-frame { box-shadow: var(--shadow-md); }
.map-teaser:focus-visible { outline: 3px solid var(--focus); outline-offset: 3px; }

.map-teaser__cta {
  position: absolute;
  left: 50%;
  bottom: var(--sp-4);
  transform: translateX(-50%);
  padding: 0.55rem 1.2rem;
  border-radius: var(--r-pill);
  background: var(--btn-bg);
  color: var(--btn-fg);
  font-size: var(--fs-sm);
  font-weight: 800;
  box-shadow: var(--shadow-md);
  white-space: nowrap;
}
.map-teaser:hover .map-teaser__cta { background: var(--btn-bg-hover); }

/* Expand-to-full-screen.

   CSS expansion rather than the Fullscreen API, because iPhone Safari has no
   element fullscreen — the API path is a bonus for desktop, this is the one
   that always runs. 100dvh, not 100vh: on mobile 100vh is the tallest the
   viewport ever gets, so the map would run under the browser toolbar. */
.map-frame--expanded {
  position: fixed;
  inset: 0;
  z-index: 120;
  width: 100vw;
  height: 100dvh;
  max-height: none;
  aspect-ratio: auto;
  border: 0;
  border-radius: 0;
  box-shadow: none;
  overscroll-behavior: none;
}

/* Hold the page still behind the overlay. overflow-y only: html already
   carries overflow-x: clip, and switching that to hidden would make the root
   a scroll container and break the sticky header once collapsed. */
.map-is-expanded { overflow-y: hidden; }

/* Keep the controls and the filter pill clear of notches and home bars. */
.map-frame--expanded .maplibregl-ctrl-top-right {
  padding-top: env(safe-area-inset-top, 0px);
  padding-right: env(safe-area-inset-right, 0px);
}
.map-frame--expanded .maplibregl-ctrl-bottom-right {
  padding-bottom: env(safe-area-inset-bottom, 0px);
  padding-right: env(safe-area-inset-right, 0px);
}
.map-frame--expanded .maplibregl-ctrl-bottom-left {
  padding-bottom: env(safe-area-inset-bottom, 0px);
  padding-left: env(safe-area-inset-left, 0px);
}
.map-frame--expanded .map-filter-pill {
  top: calc(var(--sp-3) + env(safe-area-inset-top, 0px));
  left: calc(var(--sp-3) + env(safe-area-inset-left, 0px));
}

/* Matches the vendored control buttons, which are sized in px, not tokens.

   Selector qualified with .maplibregl-ctrl-group on purpose. MapLibre's own
   rule is .maplibregl-ctrl-group button { display: block } — two classes and
   a type, which outranks a lone .map-expand-btn no matter what order the
   stylesheets load in. Unqualified, display: flex silently lost and the icon
   sat on a text baseline, high and left of centre. MapLibre's own buttons do
   not hit this: they centre a background-image, not a child element. */
.maplibregl-ctrl-group button.map-expand-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 29px;
  height: 29px;
  padding: 0;
  border: 0;
  background: transparent;
  color: #333;
  cursor: pointer;
}
/* The SVG is the only child; line-height would otherwise add a stray strip
   of baseline space below it inside the flex line. */
.maplibregl-ctrl-group button.map-expand-btn > svg { display: block; }
.maplibregl-ctrl-group button.map-expand-btn:hover { background: rgba(0, 0, 0, 0.05); }

/* Active pin-filter indicator (#cat= / #free= deep links). */
.map-filter-pill {
  position: absolute;
  top: var(--sp-3);
  left: var(--sp-3);
  z-index: 5;
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  padding: 0.35rem 0.5rem 0.35rem 0.85rem;
  border-radius: var(--r-pill);
  background: var(--surface);
  color: var(--text);
  border: 1px solid var(--border-strong);
  font-size: var(--fs-xs);
  font-weight: 700;
  box-shadow: var(--shadow-sm);
}
.map-filter-pill__clear {
  border: 0;
  background: var(--surface-3);
  color: var(--text);
  border-radius: 50%;
  width: 1.35rem;
  height: 1.35rem;
  line-height: 1;
  font-size: 0.95rem;
  cursor: pointer;
}
.map-filter-pill__clear:hover { background: var(--accent-wash); }

/* ──────────────────────────────────────────────────────────────
   Support (tip jar)
   ────────────────────────────────────────────────────────────── */

/* The promo card at the foot of /about. Tinted rather than outlined so it
   reads as an aside, not as another section of the page it sits under. */
.support-card {
  background: var(--accent-wash);
  border: 1px solid var(--accent-edge);
  border-radius: var(--r-lg);
  padding: var(--sp-5);
}
.support-card > * + * { margin-top: var(--sp-3); }

.support-card__title {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  font-size: var(--fs-lg);
  font-weight: 800;
}
.support-card__title .icon { color: var(--accent-ink); flex: 0 0 auto; }

/* The one call to action on /support. Left at the full container width,
   because the layout primitive centers every direct child of the main element
   — capping this panel would float it off the axis every heading on the page
   sits on. The measure is held by the inner copy instead. */
.support-panel { text-align: center; }
.support-panel > * + * { margin-top: var(--sp-4); }
.support-panel .prose { margin-inline: auto; max-width: 44ch; }
.support-panel .btn-row { justify-content: center; }

/* ──────────────────────────────────────────────────────────────
   Newsletter
   ────────────────────────────────────────────────────────────── */
.newsletter > * + * { margin-top: var(--sp-3); }

.newsletter--panel {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  padding: var(--sp-5);
  box-shadow: var(--shadow-sm);
}

.newsletter__title { font-size: var(--fs-lg); font-weight: 800; }
.newsletter__blurb { color: var(--text-muted); font-size: var(--fs-sm); }

.newsletter__field {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2);
}
.newsletter__input {
  flex: 1 1 14rem;
  min-width: 0;
  padding: 0.65rem 0.9rem;
  border: 1px solid var(--border-control);
  border-radius: var(--r-pill);
  background: var(--surface);
  color: var(--text);
  font-size: var(--fs-sm);
}
.newsletter__input::placeholder { color: var(--text-muted); }

.newsletter__note {
  font-size: var(--fs-xs);
  color: var(--text-muted);
}

/* Honeypot: off-screen for people, still submitted by naive bots. */
.hp-field {
  position: absolute !important;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

/* ──────────────────────────────────────────────────────────────
   Icons
   ────────────────────────────────────────────────────────────── */
.icon {
  display: inline-block;
  vertical-align: middle;
  flex: 0 0 auto;
}

/* ──────────────────────────────────────────────────────────────
   Footer
   ────────────────────────────────────────────────────────────── */
.site-footer {
  flex: 0 0 auto;
  margin-top: var(--sp-8);
  background: var(--surface-2);
  border-top: 1px solid var(--border);
  padding-block: var(--sp-7) var(--sp-5);
  font-size: var(--fs-sm);
}

.footer-top {
  display: grid;
  gap: var(--sp-6);
  grid-template-columns: 1fr;
}
@media (min-width: 46em) {
  .footer-top { grid-template-columns: minmax(0, 1.2fr) minmax(0, 2fr); }
}

.footer-blurb { max-width: 40ch; color: var(--text-muted); }
.footer-blurb > * + * { margin-top: var(--sp-2); }
.footer-brand {
  font-size: 1.25rem;
  font-weight: 800;
  color: var(--text);
  text-decoration: none;
  letter-spacing: -0.02em;
}

.footer-cols {
  display: grid;
  gap: var(--sp-5);
  grid-template-columns: repeat(2, minmax(0, 1fr));
}
@media (min-width: 34em) {
  .footer-cols { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}

.footer-col h2 {
  font-size: var(--fs-xs);
  font-weight: 800;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--text-muted);
  margin-bottom: var(--sp-3);
}
.footer-col ul { padding: 0; margin: 0; list-style: none; }
.footer-col li + li { margin-top: 0.4rem; }
.footer-col a {
  color: var(--text);
  text-decoration: none;
}
.footer-col a:hover { color: var(--accent-ink); text-decoration: underline; }

.footer-bottom {
  margin-top: var(--sp-6);
  padding-top: var(--sp-4);
  border-top: 1px solid var(--border);
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2) var(--sp-5);
  align-items: baseline;
  justify-content: space-between;
  color: var(--text-muted);
  font-size: var(--fs-xs);
}
.footer-bottom a { color: var(--text-muted); }
.footer-bottom a:hover { color: var(--accent-ink); }
.footer-note { max-width: 62ch; }

/* ──────────────────────────────────────────────────────────────
   Motion
   ────────────────────────────────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
  .event-card:hover { transform: none; }
  .btn:active { transform: none; }
}

/* ──────────────────────────────────────────────────────────────
   Print — tuned for the event detail page
   ────────────────────────────────────────────────────────────── */
@media print {
  :root {
    --bg: #FFFFFF;
    --surface: #FFFFFF;
    --surface-2: #FFFFFF;
    --text: #000000;
    --text-muted: #333333;
    --border: #CCCCCC;
    --border-strong: #999999;
  }
  body { background: #FFFFFF; color: #000000; font-size: 12pt; }
  .site-header,
  .site-footer,
  .skip-link,
  .save-btn,
  .theme-toggle,
  .search-form,
  .chip-row-wrap,
  .pagination,
  .newsletter,
  .event-actions,
  .breadcrumbs,
  .related-events { display: none !important; }
  .site-main { padding: 0; }
  .site-main > * { max-width: none; padding-inline: 0; }
  .panel,
  .event-card { border: 1px solid #CCCCCC; box-shadow: none; }
  a { color: #000000; text-decoration: underline; }
  /* Make link targets recoverable on paper, but not for in-page anchors. */
  .prose a[href^="http"]::after,
  .event-detail a[href^="http"]::after {
    content: " (" attr(href) ")";
    font-size: 0.85em;
    word-break: break-all;
  }
  h1, h2, h3 { page-break-after: avoid; }
}
