/* ---------------------------------------------------------------------------
   Savings Sites Events Network — Master Production Stylesheet (Pass 2)
   Covers 15 territory calendars (~103,000 pages, 63,000+ events).

   Design Thesis:
     A modern civic broadsheet framing an exceptionally fast local event guide.
     Neutral, high-contrast typography and disciplined spatial hierarchy act
     as framing paper so authentic event photography provides the color.

   Hard Architecture:
     - Single stylesheet, zero build steps, zero external requests, system fonts.
     - Sub-15KB page weights, instant cellular discovery, privacy-first (no cookies).
     - 100% complete and legible with JavaScript disabled.
     - Dark mode via semantic design tokens (no global image filters).
--------------------------------------------------------------------------- */

/* ---------------------------------------------------------------------------
   1. TOKENS & BASE THEME
--------------------------------------------------------------------------- */
:root {
  /* Neutral Palette (Light Mode - Primary Art Direction) */
  --ink: #0f172a;
  --ink-soft: #475569;
  --ink-muted: #64748b;
  --line: #e2e8f0;
  --line-soft: #f1f5f9;
  --bg: #ffffff;
  --bg-soft: #f8fafc;
  --card-bg: #ffffff;
  --card-border: #e2e8f0;

  /* Commercial Partner Action (SavingsSites Deals - Consistent Across All) */
  --accent: #b91c1c;
  --accent-hover: #991b1b;
  --accent-tint: #fef2f2;

  /* Territory Baseline (Default Navy) */
  --brand: #1e3a5f;
  --brand-hover: #0f233d;
  --brand-tint: #eff6ff;

  /* Geometry & Typography */
  --radius-sm: 4px;
  --radius: 8px;
  --radius-lg: 10px;
  --radius-pill: 999px;
  --wrap: 1140px;
  --font: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji";
  --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.04);
  --shadow-card: 0 1px 3px rgba(0, 0, 0, 0.05), 0 1px 2px rgba(0, 0, 0, 0.03);
  --shadow-hover: 0 8px 20px -3px rgba(0, 0, 0, 0.08), 0 3px 6px -2px rgba(0, 0, 0, 0.04);
  --shadow-pop: 0 12px 28px -4px rgba(0, 0, 0, 0.12), 0 4px 8px -2px rgba(0, 0, 0, 0.04);
}

/* ---------------------------------------------------------------------------
   2. RESTRAINED TERRITORY IDENTITY (15 Editions)
   All 15 sites share identical layout and typography. Only the civic brand
   accent and its subtle wash shift to reflect the region.
--------------------------------------------------------------------------- */
:root[data-territory="fl"] { --brand: #0b6e7f; --brand-hover: #074e5b; --brand-tint: #e6f6f8; } /* Florida: Coastal Ocean Teal */
:root[data-territory="va"] { --brand: #1e3a5f; --brand-hover: #12253e; --brand-tint: #eef4fb; } /* Virginia: Historic Tidewater Navy */
:root[data-territory="nc"] { --brand: #1d5c42; --brand-hover: #133e2c; --brand-tint: #eaf5f0; } /* North Carolina: Longleaf Pine Forest */
:root[data-territory="ga"] { --brand: #8c3a27; --brand-hover: #61271a; --brand-tint: #fbeee9; } /* Georgia: Piedmont Red Clay */
:root[data-territory="al"] { --brand: #7a1f2d; --brand-hover: #54141e; --brand-tint: #faeaed; } /* Alabama: Deep Southern Crimson */
:root[data-territory="tn"] { --brand: #244b6e; --brand-hover: #17324b; --brand-tint: #eef4f9; } /* Tennessee: Smoky Mountain Dusk */
:root[data-territory="ky"] { --brand: #1a4358; --brand-hover: #102b39; --brand-tint: #edf4f8; } /* Kentucky: Bluegrass River Basin */
:root[data-territory="wv"] { --brand: #285338; --brand-hover: #1a3825; --brand-tint: #edf5f0; } /* West Virginia: Mountain Spruce */
:root[data-territory="ar"] { --brand: #335c43; --brand-hover: #223f2d; --brand-tint: #eff6f2; } /* Arkansas: Natural State Timber */
:root[data-territory="ms"] { --brand: #194a3b; --brand-hover: #103328; --brand-tint: #ebf5f1; } /* Mississippi: Delta Magnolia Evergreen */
:root[data-territory="mo"] { --brand: #1d3b58; --brand-hover: #12263a; --brand-tint: #eef4f9; } /* Missouri: River Confluence Cobalt */
:root[data-territory="oh"] { --brand: #2c3e50; --brand-hover: #1c2834; --brand-tint: #eff3f6; } /* Ohio: Buckeye Charcoal Slate */
:root[data-territory="pr"] { --brand: #006d77; --brand-hover: #004950; --brand-tint: #e5f4f5; } /* Puerto Rico: Caribbean Sea Azure */
:root[data-territory="la"] { --brand: #3c356e; --brand-hover: #272248; --brand-tint: #f1f0f8; } /* Louisiana: French Quarter Indigo */
:root[data-territory="sc"] { --brand: #1c4456; --brand-hover: #122d3a; --brand-tint: #edf4f7; } /* South Carolina: Lowcountry Palmetto Indigo */

/* ---------------------------------------------------------------------------
   3. DARK MODE (First-Class Interface Adaptation)
   CRITICAL RULING: Event imagery, flyers, logos and banners retain 100% of
   their original pixels. No global filter: brightness/contrast on images!
--------------------------------------------------------------------------- */
@media (prefers-color-scheme: dark) {
  :root {
    --ink: #f8fafc;
    --ink-soft: #94a3b8;
    --ink-muted: #64748b;
    --line: #263342;
    --line-soft: #1a2430;
    --bg: #0b1118;
    --bg-soft: #131c26;
    --card-bg: #131c26;
    --card-border: #263342;

    --accent: #dc2626;
    --accent-hover: #ef4444;
    --accent-tint: #2c1214;

    --brand: #6ba6d6;
    --brand-hover: #8ec2eb;
    --brand-tint: #182838;

    --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.25);
    --shadow-card: 0 1px 3px rgba(0, 0, 0, 0.35);
    --shadow-hover: 0 8px 24px rgba(0, 0, 0, 0.45);
    --shadow-pop: 0 14px 32px rgba(0, 0, 0, 0.55);
  }

  /* Accessible dark-mode brand accents (≥ 4.5:1 against dark slate surfaces) */
  :root[data-territory="fl"] { --brand: #2dd4bf; --brand-hover: #5eead4; --brand-tint: #0e2d2a; }
  :root[data-territory="va"] { --brand: #60a5fa; --brand-hover: #93c5fd; --brand-tint: #14253d; }
  :root[data-territory="nc"] { --brand: #34d399; --brand-hover: #6ee7b7; --brand-tint: #10291e; }
  :root[data-territory="ga"] { --brand: #fb923c; --brand-hover: #fdba74; --brand-tint: #331c12; }
  :root[data-territory="al"] { --brand: #f87171; --brand-hover: #fca5a5; --brand-tint: #321418; }
  :root[data-territory="tn"] { --brand: #38bdf8; --brand-hover: #7dd3fc; --brand-tint: #12283b; }
  :root[data-territory="ky"] { --brand: #38bdf8; --brand-hover: #7dd3fc; --brand-tint: #102533; }
  :root[data-territory="wv"] { --brand: #4ade80; --brand-hover: #86efac; --brand-tint: #122a1b; }
  :root[data-territory="ar"] { --brand: #4ade80; --brand-hover: #86efac; --brand-tint: #152d1d; }
  :root[data-territory="ms"] { --brand: #34d399; --brand-hover: #6ee7b7; --brand-tint: #0f271f; }
  :root[data-territory="mo"] { --brand: #60a5fa; --brand-hover: #93c5fd; --brand-tint: #14273c; }
  :root[data-territory="oh"] { --brand: #94a3b8; --brand-hover: #cbd5e1; --brand-tint: #1a2533; }
  :root[data-territory="pr"] { --brand: #2dd4bf; --brand-hover: #5eead4; --brand-tint: #0e2d2a; }
  :root[data-territory="la"] { --brand: #a78bfa; --brand-hover: #c4b5fd; --brand-tint: #201b3b; }
  :root[data-territory="sc"] { --brand: #38bdf8; --brand-hover: #7dd3fc; --brand-tint: #112633; }
}

/* ---------------------------------------------------------------------------
   4. BASE RESET & ACCESSIBILITY
--------------------------------------------------------------------------- */
* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0;
  font-family: var(--font);
  font-size: 16px;
  line-height: 1.5;
  color: var(--ink);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}
img { max-width: 100%; height: auto; display: block; }
a { color: var(--brand); text-decoration: none; }
a:hover { text-decoration: underline; }

/* Accessible Focus States on Every Interactive Element */
:focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: 2px;
}
input:focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: 0;
}

/* Skip Link */
.skip {
  position: absolute; left: -9999px;
  background: var(--bg); color: var(--ink);
  padding: 8px 14px; font-weight: 600; border: 2px solid var(--brand);
  border-radius: var(--radius); z-index: 1000;
}
.skip:focus { left: 12px; top: 12px; }

/* Structural Wrap */
.wrap { max-width: var(--wrap); margin: 0 auto; padding: 0 16px; }
@media (min-width: 621px) {
  .wrap { padding: 0 20px; }
}

/* Headings */
h1, h2, h3 { line-height: 1.2; margin: 0 0 .35em; color: var(--ink); }
h1 { font-size: 1.85rem; font-weight: 750; letter-spacing: -0.025em; }

/* ---------------------------------------------------------------------------
   5. HEADER SYSTEM (Desktop & Mobile)
--------------------------------------------------------------------------- */
.site-header {
  border-bottom: 1px solid var(--line);
  background: var(--bg);
  position: relative;
  z-index: 20;
}
.header-row {
  display: flex;
  align-items: center;
  gap: 16px;
  padding-top: 10px;
  padding-bottom: 10px;
}

/* Brand Masthead */
.brand {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 1.12rem;
  font-weight: 700;
  color: var(--ink);
  white-space: nowrap;
  text-decoration: none;
}
.brand:hover { text-decoration: none; }
.brand-mark {
  background: var(--brand);
  color: #ffffff;
  font-weight: 750;
  letter-spacing: 0.04em;
  padding: 4px 8px;
  border-radius: var(--radius-sm);
  font-size: 0.8rem;
  line-height: 1.1;
}
.brand-text b { color: var(--brand); }

/* Navigation */
.nav {
  display: flex;
  align-items: center;
  gap: 18px;
  font-size: 0.92rem;
  font-weight: 500;
}
.nav a {
  color: var(--ink-soft);
  text-decoration: none;
  padding: 4px 2px;
  transition: color 0.15s ease;
}
.nav a:hover {
  color: var(--brand);
  text-decoration: underline;
}

/* Commercial Deals Action */
.cta {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: var(--accent);
  color: #ffffff;
  padding: 7px 14px;
  border-radius: var(--radius);
  font-weight: 600;
  font-size: 0.88rem;
  white-space: nowrap;
  text-decoration: none;
  transition: background 0.15s ease, transform 0.1s ease;
  line-height: 1.2;
}
.cta:hover {
  background: var(--accent-hover);
  text-decoration: none;
  color: #ffffff;
}
.cta-sm { padding: 5px 10px; font-size: 0.82rem; }
.ghost {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--line);
  background: var(--bg);
  color: var(--ink);
  padding: 7px 14px;
  border-radius: var(--radius);
  font-weight: 600;
  font-size: 0.88rem;
  text-decoration: none;
}
.ghost:hover {
  border-color: var(--brand);
  color: var(--brand);
  text-decoration: none;
}

/* Desktop Header Distribution */
@media (min-width: 621px) {
  .nav { margin-left: auto; }
  .header-row .cta { margin-left: 0; }
}

/* Mobile Header (≤ 620px) — Solving the Real Content Arithmetic
   Row 1: Brand (left), Location (middle), Deals CTA (right edge).
   Row 2: Primary Navigation spanning 100% width with intentional edge fade
          affordance and smooth horizontal continuation.
   Header is compact (~64px), perfectly balanced, and Deals CTA is fully integrated! */
@media (max-width: 620px) {
  .header-row {
    display: grid;
    grid-template-columns: 1fr auto auto;
    align-items: center;
    gap: 6px 10px;
    padding-top: 8px;
    padding-bottom: 7px;
  }
  .brand {
    grid-column: 1;
    font-size: 0.98rem;
    min-width: 0;
  }
  .brand-text {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
  .brand-mark {
    padding: 3px 6px;
    font-size: 0.74rem;
    flex-shrink: 0;
  }
  .geo-home {
    grid-column: 2;
    font-size: 0.80rem;
    white-space: nowrap;
  }
  .geo-home:empty {
    display: none;
  }
  .header-row .cta {
    grid-column: 3;
    padding: 5px 9px;
    font-size: 0.78rem;
    border-radius: var(--radius-sm);
    white-space: nowrap;
    flex-shrink: 0;
  }
  .nav {
    grid-column: 1 / -1;
    width: 100%;
    margin-left: 0;
    gap: 14px;
    font-size: 0.84rem;
    justify-content: flex-start;
    padding-top: 5px;
    padding-bottom: 2px;
    padding-right: 28px;
    border-top: 1px solid var(--line-soft);
    overflow-x: auto;
    scrollbar-width: none;
    -webkit-overflow-scrolling: touch;
    white-space: nowrap;
    -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 32px), transparent 100%);
    mask-image: linear-gradient(to right, #000 calc(100% - 32px), transparent 100%);
  }
  .nav::-webkit-scrollbar { display: none; }
  .nav a {
    padding: 4px 2px;
    flex-shrink: 0;
  }
}

/* ---------------------------------------------------------------------------
   6. BREADCRUMBS & SECTION HEADERS
--------------------------------------------------------------------------- */
.crumbs {
  padding: 10px 0 2px;
  font-size: 0.82rem;
  color: var(--ink-muted);
}
.crumbs a { color: var(--ink-soft); text-decoration: none; }
.crumbs a:hover { color: var(--brand); text-decoration: underline; }
.crumbs span { margin: 0 5px; color: var(--line); }

/* Section Headings */
.sec-h {
  font-size: 1.25rem;
  font-weight: 750;
  margin: 24px 0 12px;
  padding-bottom: 6px;
  border-bottom: 1px solid var(--line);
  display: flex;
  align-items: baseline;
  gap: 10px;
  color: var(--ink);
}
.sec-h .more {
  margin-left: auto;
  font-size: 0.85rem;
  font-weight: 500;
  color: var(--brand);
}
@media (max-width: 620px) {
  .sec-h { margin: 18px 0 10px; font-size: 1.15rem; }
}

/* Hero / Page Head */
.hero { padding: 24px 0 8px; }
.page-head { padding: 18px 0 4px; }
.lede {
  font-size: 1.02rem;
  color: var(--ink-soft);
  max-width: 66ch;
  margin: 0 0 10px;
  line-height: 1.45;
}
.hero-actions { display: flex; gap: 10px; flex-wrap: wrap; margin: 14px 0 0; }
.empty {
  background: var(--bg-soft);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 18px;
  color: var(--ink-soft);
}

/* Mobile Arrival Stack Ordering
   Inverts the DOM order inside .page-head so that #geo-bar appears right
   after the H1 and Fact Bar, rather than being buried below filters/places! */
@media (max-width: 620px) {
  .hero { padding: 16px 0 6px; }
  .page-head {
    padding: 12px 0 4px;
    display: flex;
    flex-direction: column;
  }
  .page-head > h1 { order: 1; font-size: 1.55rem; margin-bottom: 4px; }
  .page-head > .lede { order: 2; font-size: 0.92rem; margin-bottom: 6px; }
  .page-head > .geo-bar { order: 3; }
  .page-head > .filters { order: 4; }
  .page-head > .places { order: 5; }
}

/* ---------------------------------------------------------------------------
   7. LOCATION LAYER (geo.js Elements — Styling Real States Only)
--------------------------------------------------------------------------- */

/* Header Home Control (#geo-home) */
.geo-home {
  display: flex;
  align-items: center;
  gap: 5px;
  font-size: 0.86rem;
}
.geo-home:empty { display: none; }
.geo-home-pin {
  color: var(--brand);
  font-size: 0.85rem;
  line-height: 1;
}
.geo-home-name {
  font-weight: 600;
  color: var(--ink);
  text-decoration: none;
  max-width: 140px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.geo-home-name:hover { text-decoration: underline; }
.geo-home-change {
  border: 0; background: none; color: var(--ink-muted);
  font: inherit; font-size: 0.78rem; cursor: pointer;
  padding: 2px 2px; text-decoration: underline;
}
.geo-home-change:hover { color: var(--brand); }
.geo-home-set {
  border: 1px solid var(--line);
  background: var(--bg);
  color: var(--ink);
  font: inherit;
  font-size: 0.82rem;
  font-weight: 500;
  padding: 4px 9px;
  border-radius: var(--radius);
  cursor: pointer;
  text-decoration: none;
}
.geo-home-set:hover {
  border-color: var(--brand);
  color: var(--brand);
}

/* Location / Context Bar (.geo-bar) */
.geo-bar {
  display: flex;
  align-items: center;
  gap: 8px 12px;
  flex-wrap: wrap;
  margin: 10px 0 6px;
  padding: 10px 14px;
  background: var(--bg-soft);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  font-size: 0.9rem;
}
.geo-label { color: var(--ink-soft); font-size: 0.88rem; }
.geo-label b { color: var(--ink); font-weight: 600; }
.geo-count { color: var(--ink-soft); font-size: 0.84rem; }
.geo-or { color: var(--ink-muted); font-size: 0.84rem; }

/* Geo Buttons & Actions */
.geo-btn {
  border: 1px solid var(--line);
  background: var(--bg);
  color: var(--ink);
  border-radius: var(--radius);
  padding: 6px 12px;
  font: inherit;
  font-size: 0.86rem;
  font-weight: 500;
  cursor: pointer;
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  line-height: 1.2;
}
.geo-btn:hover {
  border-color: var(--brand);
  color: var(--brand);
  text-decoration: none;
}
.geo-link {
  border: 0; background: none; color: var(--brand);
  font: inherit; font-size: 0.85rem; cursor: pointer;
  padding: 4px 2px; text-decoration: underline;
}
.geo-link:hover { text-decoration-thickness: 2px; }

/* Specific Geo States */
.geo-go-local {
  background: var(--brand);
  border-color: var(--brand);
  color: #ffffff;
  font-weight: 600;
}
.geo-go-local:hover {
  background: var(--brand-hover);
  color: #ffffff;
  text-decoration: none;
}
.geo-back {
  border-color: var(--line);
  color: var(--brand);
  font-weight: 600;
}

/* Unconfirmed IP State (.geo-check) */
.geo-bar.geo-check {
  border-left: 3px solid var(--brand);
  background: var(--brand-tint);
}
.geo-confirm {
  background: var(--brand);
  border-color: var(--brand);
  color: #ffffff;
  font-weight: 600;
}
.geo-confirm:hover {
  background: var(--brand-hover);
  color: #ffffff;
  text-decoration: none;
}

/* Geo Form & Combobox Input */
.geo-form { position: relative; display: inline-flex; gap: 6px; align-items: center; }
.geo-form input {
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 6px 10px;
  font: inherit;
  font-size: 0.86rem;
  background: var(--bg);
  color: var(--ink);
  width: 11em;
}
.geo-form input:focus { border-color: var(--brand); }
.geo-msg { color: var(--ink-soft); font-size: 0.84rem; }

/* Typeahead Dropdown (.geo-suggest) */
.geo-suggest {
  position: absolute; top: 100%; left: 0; z-index: 50; margin: 4px 0 0;
  min-width: 16em; max-height: 16em; overflow-y: auto; padding: 4px;
  list-style: none; background: var(--card-bg);
  border: 1px solid var(--line); border-radius: var(--radius);
  box-shadow: var(--shadow-pop);
}
.geo-suggest li {
  display: flex; justify-content: space-between; align-items: baseline; gap: 12px;
  padding: 6px 10px; border-radius: var(--radius-sm); cursor: pointer;
  color: var(--ink);
}
/* Carefully Scoped .on to Avoid Collision with Category Chips */
.geo-suggest li.on, .geo-suggest li:hover {
  background: var(--brand-tint);
  color: var(--brand);
}
.gs-name { font-weight: 600; font-size: 0.88rem; }
.gs-n { color: var(--ink-soft); font-size: 0.78rem; white-space: nowrap; }



/* ---------------------------------------------------------------------------
   8. CATEGORY FILTERS & PLACE CHIPS
--------------------------------------------------------------------------- */
.filters, .places { margin: 12px 0 4px; }
.filters { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; }
.filters-label {
  font-size: 0.8rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  font-weight: 600;
  color: var(--ink-soft);
  white-space: nowrap;
}

/* Chip Styles */
.chips {
  list-style: none; padding: 0; margin: 0;
  display: flex; flex-wrap: wrap; gap: 6px 8px;
}
.chips a {
  display: inline-flex;
  align-items: center;
  border: 1px solid var(--line);
  border-radius: var(--radius-pill);
  padding: 4px 11px;
  font-size: 0.85rem;
  color: var(--ink);
  background: var(--bg);
  text-decoration: none;
  min-height: 32px;
  transition: border-color 0.15s ease, background 0.15s ease;
}
.chips a:hover {
  border-color: var(--brand);
  text-decoration: none;
}
.chips .n {
  color: var(--ink-muted);
  font-size: 0.78rem;
  margin-left: 5px;
}

/* Active Filter Pill */
.chips-filter a.on {
  background: var(--brand);
  border-color: var(--brand);
  color: #ffffff;
  font-weight: 600;
}
.chips-filter a.on .n {
  color: rgba(255, 255, 255, 0.8);
}

/* Places (ZIPs / Towns) */
.places-h {
  font-size: 0.8rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  font-weight: 600;
  color: var(--ink-soft);
  margin: 0 0 6px;
  display: flex;
  align-items: baseline;
  gap: 10px;
}
.places-h .more {
  margin-left: auto;
  text-transform: none;
  letter-spacing: 0;
  font-size: 0.84rem;
  font-weight: 500;
}
.chip-dist {
  margin-left: 5px;
  color: var(--ink-muted);
  font-size: 0.76rem;
  font-weight: 500;
}

/* Mobile Category Rail (Controlling Height on Mobile)
   Reduces category pill height from 276px to 36px!
   Peek affordance signals horizontal scrollability intuitively. */
@media (max-width: 620px) {
  .filters {
    margin: 8px 0 2px;
    flex-wrap: nowrap;
    align-items: center;
  }
  .filters-label { display: none; } /* Redundant on compact mobile */
  .chips-filter {
    display: flex;
    flex-wrap: nowrap;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
    padding: 2px 24px 6px 0;
    gap: 6px;
    width: 100%;
    -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 28px), transparent 100%);
    mask-image: linear-gradient(to right, #000 calc(100% - 28px), transparent 100%);
  }
  .chips-filter::-webkit-scrollbar { display: none; }
  .chips-filter li { flex-shrink: 0; }
  .chips-filter a {
    padding: 5px 11px;
    font-size: 0.82rem;
    min-height: 32px;
    display: inline-flex;
    align-items: center;
  }
  .places { margin: 6px 0 2px; }
  .places-h { font-size: 0.76rem; margin-bottom: 4px; }
}

/* ---------------------------------------------------------------------------
   9. EVENT CARD — THE CORE SCANNING OBJECT
--------------------------------------------------------------------------- */
.grid {
  display: grid;
  gap: 20px;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
}
@media (min-width: 900px) {
  .grid {
    grid-template-columns: repeat(3, 1fr);
    gap: 24px;
  }
}
@media (max-width: 620px) {
  .grid {
    grid-template-columns: 1fr;
    gap: 16px;
  }
}

/* The Card Container */
.card {
  border: 1px solid var(--card-border);
  border-radius: var(--radius-lg);
  overflow: hidden;
  background: var(--card-bg);
  box-shadow: var(--shadow-card);
  transition: transform 0.18s ease, box-shadow 0.18s ease;
  display: flex;
  flex-direction: column;
}
@media (min-width: 621px) {
  .card:hover {
    transform: translateY(-2px);
    box-shadow: var(--shadow-hover);
  }
}

/* 100% Unobstructed Artwork Banner */
.card-img {
  display: block;
  position: relative;
  background: var(--bg-soft);
  text-decoration: none;
}
.card-img img {
  aspect-ratio: 3 / 1;
  object-fit: cover;
  /* Anchor a crop to the TOP, not the centre. Where an image is close enough
     to 3:1 to be covered, what gets trimmed is the bottom, and a flyer or a
     poster carries its headline at the top. */
  object-position: top;
  width: 100%;
}

/* FULL-SCREEN PICTURE VIEWER (zoom.js)
   A contained flyer is whole but small: a 0.75:1 poster in a 3:1 frame renders
   about a quarter of the width, and the date and price on it are what the
   reader came for. Tapping the hero opens it full screen. Everything here is
   inert until zoom.js builds the overlay, so with JS off the page is unchanged. */
.zoomable { cursor: zoom-in; }
html.zoomer-open, html.zoomer-open body { overflow: hidden; }
.zoomer {
  position: fixed;
  inset: 0;
  z-index: 1000;
  background: rgba(8, 12, 18, 0.94);
  display: flex;
  align-items: center;
  justify-content: center;
  overscroll-behavior: contain;
}
.zoomer[hidden] { display: none; }
.zoomer img {
  max-width: 100%;
  max-height: 100%;
  /* The gesture is handled in JS: a fixed overlay does not reliably get the
     browser's own pinch-zoom on iOS, and letting the browser start one
     mid-gesture fights our transform. */
  touch-action: none;
  transform-origin: center center;
  will-change: transform;
  user-select: none;
  -webkit-user-select: none;
}
.zoomer-close {
  position: absolute;
  top: 10px;
  right: 14px;
  width: 44px;
  height: 44px;              /* a real touch target, not a 16px glyph */
  font-size: 1.9rem;
  line-height: 1;
  color: #ffffff;
  background: rgba(15, 23, 42, 0.7);
  border: 1px solid rgba(255, 255, 255, 0.25);
  border-radius: 50%;
  cursor: pointer;
}
.zoomer-close:focus-visible { outline: 2px solid #ffffff; outline-offset: 2px; }
.zoomer-hint {
  position: absolute;
  bottom: 14px;
  left: 0;
  right: 0;
  text-align: center;
  color: rgba(255, 255, 255, 0.75);
  font-size: 0.8rem;
  pointer-events: none;
}
.zoomer[data-zoomed="yes"] .zoomer-hint { opacity: 0; }
@media (prefers-reduced-motion: no-preference) {
  .zoomer-hint { transition: opacity 0.2s ease; }
}

/* OFF-RATIO PRESENTATION (.is-contain)
   Was .is-portrait and fired only when h > w*1.2, which left squares, 4:3
   phone photos and 16:9 stills to be centre-cropped to a third or a half of
   themselves: 6,791 live events. It now fires whenever the image is more than
   FIT_TOL off the 3:1 tile (see image_fit() in savings_site_build.py), which
   is the rule SavingsSites adopted for the same problem.
   The image is contained so nothing is cut, over a blurred, dimmed copy of
   itself so the frame still reads as full bleed rather than as bars. */
.card-img.is-contain, .event-hero.is-contain {
  overflow: hidden;
  position: relative;
  background: #17232e;
}
.card-img.is-contain::before, .event-hero.is-contain::before {
  content: "";
  position: absolute;
  inset: -10px;
  background-image: var(--flyer);
  background-size: cover;
  background-position: center;
  filter: blur(18px) brightness(0.65);
  transform: scale(1.15);
  opacity: 0.9;
}
.card-img.is-contain img, .event-hero.is-contain img {
  position: relative;
  object-fit: contain;
  width: 100%;
  height: 100%;
  z-index: 1;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.35);
}

/* Administrative Banner (State 3B) */
.admin-banner {
  display: flex;
  align-items: center;
  justify-content: center;
  aspect-ratio: 3 / 1;
  width: 100%;
  background: linear-gradient(135deg, var(--g1) 0%, var(--g2) 100%);
  color: rgba(255, 255, 255, 0.65);
}
.admin-banner svg { width: 44px; height: 44px; }

/* Card Body & Hierarchy */
.card-body {
  padding: 14px 16px 16px;
  display: flex;
  flex-direction: column;
  flex-grow: 1;
}
@media (max-width: 620px) {
  .card-body { padding: 12px 14px 14px; }
}

/* 1. High-Contrast Date Anchor */
.card-when {
  margin: 0 0 5px;
  font-size: 0.9rem;
  font-weight: 750;
  color: var(--brand);
  text-transform: uppercase;
  letter-spacing: 0.03em;
  line-height: 1.2;
}
.card-time {
  color: var(--ink-soft);
  font-weight: 500;
  margin-left: 6px;
  text-transform: none;
  letter-spacing: 0;
  font-size: 0.86rem;
}
.card-time::before {
  content: "· ";
  margin-right: 2px;
  color: var(--line);
}

/* 2. Event Title */
.card-title {
  font-size: 1.08rem;
  font-weight: 700;
  line-height: 1.25;
  margin: 0 0 6px;
  color: var(--ink);
}
.card-title a { color: inherit; text-decoration: none; }
.card-title a:hover { color: var(--brand); text-decoration: underline; }

/* 3. Venue, Town & Distance */
.card-where {
  margin: 0;
  font-size: 0.86rem;
  color: var(--ink-soft);
  line-height: 1.4;
  display: flow-root; /* Cleanly clears float without anonymous flex item issues */
}
.card-where .venue {
  display: block;
  font-weight: 600;
  color: var(--ink);
  margin-bottom: 2px;
}
.card-where a { color: var(--ink-soft); text-decoration: none; }
.card-where a:hover { color: var(--ink); text-decoration: underline; }

/* Plain Typography Distance (Right-Aligned) */
.dist {
  float: right;
  margin-left: 8px;
  font-size: 0.8rem;
  font-weight: 600;
  color: var(--brand);
  white-space: nowrap;
}

/* 4. Bottom Metadata Row (Category · Recurrence)
   Exists ONLY when data exists; collapses completely when absent! */
.card-series {
  margin: 8px 0 0;
  padding-top: 6px;
  border-top: 1px solid var(--line-soft);
  font-size: 0.8rem;
  color: var(--ink-muted);
  line-height: 1.35;
}
.card-cat {
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--ink-soft);
}
.card-sep {
  color: var(--line);
  margin: 0 4px;
}

/* ---------------------------------------------------------------------------
   10. EVENT DETAIL PAGE (/e/.../)
--------------------------------------------------------------------------- */
.event-hero {
  position: relative;
  max-width: 1400px;
  margin: 0 auto;
  border-radius: var(--radius-lg);
  overflow: hidden;
  background: var(--bg-soft);
}
.event-hero img {
  aspect-ratio: 3 / 1;
  object-fit: cover;
  width: 100%;
}
.event-hero .card-cat {
  position: absolute;
  top: 12px;
  right: 12px;
  background: rgba(15, 23, 42, 0.85);
  backdrop-filter: blur(4px);
  color: #ffffff;
  font-size: 0.72rem;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  font-weight: 600;
  padding: 4px 10px;
  border-radius: var(--radius-pill);
}
.event-hero .card-cat a { color: #ffffff; text-decoration: none; }

.event-body {
  max-width: 780px;
  padding-top: 20px;
  padding-bottom: 12px;
}
.event-body h1 { font-size: 2.1rem; margin-bottom: 12px; }
@media (max-width: 620px) {
  .event-body h1 { font-size: 1.65rem; }
}

.past-note {
  background: #fefce8;
  border: 1px solid #fef08a;
  color: #854d0e;
  border-radius: var(--radius);
  padding: 10px 14px;
  font-size: 0.9rem;
  margin-bottom: 14px;
}

/* Event Facts Table / Summary Card */
.event-facts {
  display: grid;
  grid-template-columns: 110px 1fr;
  gap: 8px 18px;
  margin: 18px 0;
  padding: 16px;
  background: var(--bg-soft);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  font-size: 0.92rem;
}
.event-facts dt {
  color: var(--ink-soft);
  font-size: 0.82rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  font-weight: 600;
}
.event-facts dd { margin: 0; color: var(--ink); }
@media (max-width: 620px) {
  .event-facts { grid-template-columns: 1fr; gap: 4px; padding: 12px 14px; }
  .event-facts dt { margin-top: 6px; }
}

.event-desc { font-size: 1.0rem; line-height: 1.6; }
.event-desc p { margin: 0 0 1em; }
.event-translation {
  margin-top: 24px;
  padding: 16px;
  background: var(--bg-soft);
  border-radius: var(--radius);
}
.translation-heading { font-size: 1.05rem; margin-bottom: 8px; }

.event-actions { display: flex; gap: 12px; flex-wrap: wrap; margin: 24px 0 14px; }
.disclaimer { font-size: 0.82rem; color: var(--ink-muted); line-height: 1.4; }
.img-credit {
  margin: 6px 0 0;
  font-size: 0.75rem;
  color: var(--ink-muted);
  text-align: right;
}
.inline-link {
  color: var(--brand);
  text-decoration: underline;
  text-underline-offset: 2px;
}
.inline-link:hover { text-decoration-thickness: 2px; }

/* ---------------------------------------------------------------------------
   11. PLACES, PROSE, INDEXES & PAGINATION
--------------------------------------------------------------------------- */
.facts-grid {
  display: grid;
  grid-template-columns: 150px 1fr;
  gap: 6px 18px;
  margin: 0 0 18px;
  font-size: 0.92rem;
}
.facts-grid dt { color: var(--ink-soft); font-size: 0.85rem; }
.facts-grid dd { margin: 0; }
@media (max-width: 620px) {
  .facts-grid { grid-template-columns: 1fr; gap: 2px; }
  .facts-grid dt { margin-top: 6px; }
}

.note-carved {
  font-size: 0.86rem;
  color: var(--ink-soft);
  background: var(--bg-soft);
  border-left: 3px solid var(--brand);
  padding: 10px 14px;
  border-radius: 0 var(--radius) var(--radius) 0;
}

.index-list {
  list-style: none; padding: 0; margin: 0;
  columns: 4; column-gap: 26px; font-size: 0.95rem;
}
.index-list li { break-inside: avoid; padding: 3px 0; }
.index-list .note { color: var(--ink-muted); font-size: 0.8rem; margin-left: 6px; }
@media (max-width: 900px) { .index-list { columns: 2; } }
@media (max-width: 620px) { .index-list { columns: 1; } }

.pager { display: flex; align-items: center; gap: 12px; margin: 24px 0 8px; flex-wrap: wrap; }
.pager-pos { color: var(--ink-soft); font-size: 0.88rem; }

.prose { max-width: 74ch; padding-bottom: 20px; }
.prose h2 { font-size: 1.15rem; margin-top: 1.6em; }
.prose ul { padding-left: 1.2em; }
.prose li { margin-bottom: 0.5em; }
.contact-email { font-size: 1.15rem; font-weight: 600; color: var(--brand); }

/* ---------------------------------------------------------------------------
   12. FOOTER SYSTEM
--------------------------------------------------------------------------- */
.site-footer {
  margin-top: 48px;
  border-top: 1px solid var(--line);
  background: var(--bg-soft);
  padding: 32px 0 24px;
  font-size: 0.9rem;
}
.foot-grid {
  display: grid;
  gap: 28px;
  grid-template-columns: 2fr 1fr 1fr;
}
@media (max-width: 900px) { .foot-grid { grid-template-columns: 1fr; } }
.foot-h {
  font-size: 0.82rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--ink-soft);
  font-weight: 700;
  margin-bottom: 10px;
}
.foot-list { list-style: none; padding: 0; margin: 0; }
.foot-list li { padding: 3px 0; }
.foot-list a { color: var(--ink-soft); text-decoration: none; }
.foot-list a:hover { color: var(--brand); text-decoration: underline; }

.territories {
  margin-top: 28px;
  padding-top: 18px;
  border-top: 1px solid var(--line);
}
.terr-list { color: var(--ink-muted); line-height: 2; margin: 0; font-size: 0.85rem; }
.terr-list a { color: var(--ink-soft); }
.legal {
  margin-top: 20px;
  padding-top: 14px;
  border-top: 1px solid var(--line);
  color: var(--ink-muted);
  font-size: 0.8rem;
  line-height: 1.4;
}

/* ---------------------------------------------------------------------------
   13. REDUCED MOTION PREFERENCE
--------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
  .card:hover { transform: none !important; }
}

/* ---------------------------------------------------------------------------
   CLASS CONTRACT — the templates emit exactly these. A redesign may restyle
   any of them freely, but renaming one means editing templates/savings_site/.

   layout    wrap  skip  site-header  header-row  brand  brand-mark  brand-text
             nav  cta  cta-sm  ghost  crumbs  hero  hero-actions  page-head
             lede  sec-h  more  empty  site-footer  foot-grid  foot-h
             foot-list  territories  terr-list  legal
   listings  grid  card  card-img  card-cat  card-body  card-when  card-time
             card-title  card-where  venue  dist  card-series  card-admin
             is-contain   admin-banner  card-sep
   viewer    zoomable  zoomer  zoomer-close  zoomer-hint
   indexes   chips  n  index-list  note  chips-filter  filters  filters-label
             places  places-h  pager  pager-pos
   event     event  event-hero  event-body  past-note  event-facts  event-desc
             event-actions  disclaimer  img-credit  inline-link  event-translation
             translation-heading
   places    facts  facts-grid  note-carved
   prose     prose  contact-email
   location  geo-home  geo-home-pin  geo-home-name  geo-home-change  geo-home-set
             geo-bar  geo-label  geo-count  geo-or  geo-btn  geo-go-local
             geo-back  geo-link  geo-form  geo-msg  geo-suggest  gs-name  gs-n
             chip-dist  js-dist  js-places  geo-check  geo-confirm
             (geo-* are injected by /js/geo.js, never by a template; the
              templates emit only the empty #geo-home slot, js-dist spans and
              the data-lat/data-lng attributes those read)
--------------------------------------------------------------------------- */
