/* Mailroom — consistent design system.
   Radius:  pill (999) for every interactive control; --r-md (12) for panels/
            cells; --r-lg (16) for cards/modal/map.
   Borders: every default control gets a 1px border; filled = active/primary;
            tinted-no-border = passive chip.
   Spacing: 8px grid (4px only for icon/text-tight, 12px only for chip padding). */

:root {
  /* Fonts — matches Party Pal: Unbounded display, Switzer body */
  --font-head: "Unbounded", "Switzer", system-ui, sans-serif;
  --font-body: "Switzer", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;

  /* Palette — Party Pal neutrals */
  --bg: #f9fafb;
  --bg-card: #ffffff;
  --bg-sunken: #f3f4f6;
  --border: #e5e7eb;
  --border-strong: #d1d5db;
  --text: #111827;
  --text-soft: #6b7280;
  --text-faint: #9ca3af;

  /* Accent — HOT PINK (Party Pal uses blue; this is its pink sibling) */
  --accent: #e01e7b;
  --accent-hover: #c2186a;
  --accent-soft: #fdebf4;
  --nav-bg: #e01e7b;
  --nav-fg: #ffffff;

  --free: #1f7a48; --free-bg: #e7f4ec;
  --paid: #8a5a00; --paid-bg: #fbf0dc;
  --rel: #7c3aed;  --rel-bg: #f3eefe;
  --shadow: 0 1px 2px rgba(0,0,0,.04), 0 8px 24px rgba(0,0,0,.05);
  --shadow-pop: 0 4px 12px rgba(0,0,0,.08), 0 16px 40px rgba(0,0,0,.10);
  --r-lg: 16px;
  --r-md: 12px;
  --r-pill: 999px;
  --max: 1024px;
  /* one shared horizontal inset so every full-width band lines up at 1024px */
  --pad-x: max(24px, calc((100% - var(--max)) / 2));
}

* { box-sizing: border-box; }
/* hidden must always win — class rules like .view-sub{display:inline-flex} would
   otherwise override the attribute and leak the calendar/map control rows. */
[hidden] { display: none !important; }

body {
  margin: 0;
  font-family: var(--font-body);
  background: var(--bg);
  color: var(--text);
  -webkit-font-smoothing: antialiased;
  font-size: 15px;
  line-height: 1.5;
}

/* ── Shared interactive-control base ─────────────────── */
.btn, .ctl, .dd-btn, .iconbtn {
  font: inherit;
  font-size: 14px;
  color: var(--text);
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--r-pill);
  cursor: pointer;
  transition: background .15s, border-color .15s, color .15s;
}
.btn:hover, .dd-btn:hover, .iconbtn:hover { background: #fff; border-color: var(--border-strong); }

:root { --ctl-h: 44px; }   /* ONE height for every button, pill and toggle option */
.btn { font-weight: 600; height: var(--ctl-h); padding: 0 16px;
  display: inline-flex; align-items: center; justify-content: center; gap: 8px; white-space: nowrap; }
.dd-btn { height: var(--ctl-h); }
/* A link styled as a button is a pill OR an underline, never both. */
a.btn, a.btn:hover { text-decoration: none; }
.btn-primary { background: var(--accent); color: #fff; border-color: var(--accent); }
.btn-primary:hover { background: var(--accent-hover); border-color: var(--accent-hover); }
.btn-primary:disabled { opacity: .6; cursor: default; }
.btn-ghost { color: var(--text-soft); }

.iconbtn {
  display: inline-flex; align-items: center; justify-content: center;
  width: var(--ctl-h); height: var(--ctl-h); font-size: 16px; line-height: 1; color: var(--text-soft);
}
/* Today + arrows share one height so the nav reads as a set */
.cal-nav .btn, .cal-nav .iconbtn { height: var(--ctl-h); }

/* Consistent CSS-drawn chevrons for every prev/next arrow (the ‹ › glyphs
   render unevenly across fonts). Text is hidden; a square's two borders form it. */
.iconbtn[id$="Prev"], .iconbtn[id$="Next"] { font-size: 0; }
.iconbtn[id$="Prev"]::before, .iconbtn[id$="Next"]::before {
  content: ""; display: block; width: 7px; height: 7px;
  border-right: 2px solid currentColor; border-bottom: 2px solid currentColor;
}
.iconbtn[id$="Prev"]::before { transform: rotate(135deg); margin-left: 3px; }
.iconbtn[id$="Next"]::before { transform: rotate(-45deg); margin-right: 3px; }

/* ── Segmented control (view tabs + calendar modes) ──── */
.seg {
  display: inline-flex;
  gap: 4px;
  padding: 4px;
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--r-pill);
}
.seg-btn {
  font: inherit; font-size: 14px; font-weight: 600;
  color: var(--text-soft);
  background: transparent; border: none;
  border-radius: var(--r-pill);
  height: var(--ctl-h); padding: 0 16px;
  display: inline-flex; align-items: center; justify-content: center;
  cursor: pointer;
  transition: background .15s, color .15s;
}
.seg-btn:hover:not(.active) { color: var(--text); }
.seg-btn.active { background: var(--accent); color: #fff; }
/* icon view tabs — icon inherits currentColor (white when active, grey otherwise) */
#viewTabs .seg-btn { padding: 0 16px; }
#viewTabs .seg-btn svg { display: block; }

/* ── Sticky header stack (nav + filters move together, no overlap) ── */
.sticky-top { position: sticky; top: 0; z-index: 30; }

/* ── Top bar (hot-pink nav, like Party Pal's blue nav) ─── */
.topbar {
  background: var(--nav-bg); color: var(--nav-fg);
  padding: 16px var(--pad-x);   /* equal top/bottom (8px grid); each pair centered within */
}
.topbar-main {
  display: flex; align-items: center; justify-content: space-between;
  gap: 16px; flex-wrap: wrap;
}
.brand h1 { margin: 0; font-family: var(--font-head); font-size: 28px; font-weight: 700; letter-spacing: -0.01em; color: var(--nav-fg); }
.tagline { margin: 4px 0 0; color: rgba(255,255,255,.85); font-size: 14px; }
.topbar-actions { display: flex; flex-direction: column; align-items: flex-end; gap: 6px; }
.action-row { display: flex; align-items: center; gap: 24px; }   /* toggle ↔ refresh: exactly 24px */
/* shorter header refresh button */
.topbar .topbar-sources { text-decoration: none; background: rgba(255,255,255,.18); color: #fff; border-color: transparent; }
.topbar .topbar-sources:hover { background: rgba(255,255,255,.28); border-color: transparent; }
/* a real on/off switch, vertically centered with the refresh button */
.src-toggle { display: inline-flex; align-items: center; gap: 8px; height: 34px; }
.switch { width: 40px; height: 22px; border-radius: 999px; border: none; padding: 0; position: relative; cursor: pointer; background: rgba(255,255,255,.3); transition: background .15s; }
.switch[aria-checked="true"] { background: #fff; }
.switch .knob { position: absolute; top: 3px; left: 3px; width: 16px; height: 16px; border-radius: 50%; background: #fff; transition: left .15s, background .15s; }
.switch[aria-checked="true"] .knob { left: 21px; background: var(--accent); }
.src-label { color: #fff; font-size: 13px; font-weight: 600; white-space: nowrap; }
.meta { color: var(--text-faint); font-size: 13px; }
.topbar .meta { color: rgba(255,255,255,.8); }
.topbar-link { color: #fff; text-decoration: underline; text-underline-offset: 3px; }
.topbar-link:hover { opacity: .85; }
.health-banner { margin: 8px 0 0; padding: 12px 16px; border-radius: 10px; font-size: 13px;
  font-weight: 500; background: var(--accent-soft); color: var(--accent-hover);
  border: 1px solid var(--accent); }
.topbar .btn-primary { background: #fff; color: var(--accent); border-color: #fff; }
.topbar .btn-primary:hover { background: rgba(255,255,255,.88); border-color: rgba(255,255,255,.88); }

/* Time-zone menu — the header's own pill in the local app, a settings row in
   the hosted one. Same pill, border, type and accent as every other control. */
.tz-menu { position: relative; }
.tz-btn { display: inline-flex; align-items: center; gap: 8px; height: 34px; padding: 8px 16px; font-size: 13px; white-space: nowrap; }
.tz-btn svg { display: block; opacity: .7; }
.topbar .tz-btn { background: rgba(255,255,255,.18); color: #fff; border-color: transparent; }
.topbar .tz-btn:hover { background: rgba(255,255,255,.28); border-color: transparent; }
.tz-label { opacity: .75; }
.tz-value { font-weight: 600; }
.tz-list { position: absolute; z-index: 60; top: calc(100% + 8px); right: 0; min-width: 100%; max-height: 320px; overflow-y: auto;
  margin: 0; padding: 8px; list-style: none; background: var(--bg-card); color: var(--text);
  border: 1px solid var(--border); border-radius: var(--r-md); box-shadow: 0 8px 24px rgba(17,24,39,.18); }
.tz-list[hidden] { display: none; }
.tz-list button { display: block; width: 100%; text-align: left; white-space: nowrap; font: inherit; font-size: 14px;
  color: var(--text); background: none; border: none; border-radius: var(--r-md); padding: 8px 16px; cursor: pointer; }
.tz-list button:hover { background: var(--bg-sunken); }
.tz-list button[aria-selected="true"] { background: var(--accent-soft); color: var(--accent); font-weight: 600; }

.refresh-status {
  margin: 16px 0 0; padding: 8px 16px;
  background: rgba(255,255,255,.18); border-radius: var(--r-md);
  font-size: 13px; color: var(--nav-fg); font-variant-numeric: tabular-nums;
}

/* ── Controls row ────────────────────────────────────── */
.controls {
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px;
  padding: 16px var(--pad-x);
  background: var(--bg); border-bottom: 1px solid var(--border);
}
.ctl { display: inline-flex; align-items: center; gap: 8px; padding: 8px 16px; }
.search-wrap { flex: 1 1 360px; height: 44px; box-sizing: border-box; display: flex; align-items: center; gap: 8px; padding: 4px 4px 4px 16px; }
.search-wrap:focus-within { border-color: var(--accent); }
.search-wrap input { flex: 1; min-width: 0; border: none; background: transparent; outline: none; font: inherit; font-size: 14px; color: var(--text); }
.search-go {
  flex: 0 0 auto; width: 34px; height: 34px; border-radius: var(--r-pill);
  background: var(--accent); border: none; color: #fff; cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center; transition: background .15s;
}
.search-go:hover { background: var(--accent-hover); }
.search-go svg { width: 18px; height: 18px; }
/* type="search" makes the browser draw its OWN clear ✕ beside ours once the field
   has text — the "double x". Kill the native one; #searchClear is the only clear. */
#search::-webkit-search-cancel-button,
#search::-webkit-search-decoration,
#search::-webkit-search-results-button { -webkit-appearance: none; appearance: none; display: none; }
.search-clear {
  flex: 0 0 auto; width: 24px; height: 24px; border: none; background: transparent;
  color: var(--text-faint); font-size: 13px; cursor: pointer; border-radius: var(--r-pill);
  display: inline-flex; align-items: center; justify-content: center;
}
.search-clear:hover { background: var(--bg-sunken); color: var(--text); }
/* scope toggle stays hidden until the search is focused or has text.
   Fixed height (matches the search bar) + only width/opacity animate, so the
   row height never changes — nothing below it shifts. */
#scopeSeg {
  height: 44px; box-sizing: border-box; align-items: center;
  max-width: 0; opacity: 0; padding: 0 0; border: 0; overflow: hidden;
  white-space: nowrap; pointer-events: none;
  margin-left: -8px;   /* cancel the controls' 8px gap while hidden, so the search bar stays symmetric */
  transition: max-width .25s ease, opacity .18s ease;
}
.controls.searching #scopeSeg { max-width: 24em; opacity: 1; padding: 0 4px; border: 1px solid var(--border); margin-left: 0; pointer-events: auto; }
/* clickable map counts */
.link-count { background: none; border: none; padding: 0; font: inherit; color: inherit; cursor: pointer; }
.link-count:hover { color: var(--accent); text-decoration: underline; }
#resetBtn { flex: 0 0 auto; }
.ctl-label { color: var(--text-soft); font-size: 13px; white-space: nowrap; }
.ctl-slider input[type="range"] { width: 96px; accent-color: var(--accent); cursor: pointer; }
.ctl-slider b { color: var(--text); }

/* ── Filters & sort ──────────────────────────────────── */
.filter-btn { display: inline-flex; align-items: center; gap: 8px; height: 44px; box-sizing: border-box; padding: 4px 16px; white-space: nowrap; }
.filter-btn svg { display: block; }
.filter-btn.has-value { border-color: var(--accent); color: var(--accent); padding-right: 4px; }   /* tuck the 34px badge in 4px from the edge, like the search button */
.filter-badge {
  display: inline-flex; align-items: center; justify-content: center;
  width: 34px; height: 34px; box-sizing: border-box;   /* match the search button circle */
  border-radius: var(--r-pill); background: var(--accent); color: #fff;
  font-size: 13px; font-weight: 600; line-height: 1;
}
/* Active-filter chips — only the ones you've set, with an ✕ to clear each */
.active-chips { display: flex; flex-wrap: wrap; gap: 8px; padding: 0 var(--pad-x) 16px; background: var(--bg); border-bottom: 1px solid var(--border); }
.active-chips[hidden] { display: none; }
/* when chips are showing, they own the bottom border — drop the controls' so the two rows read as one block */
.sticky-top:has(#activeChips:not([hidden])) .controls { border-bottom-color: transparent; }
.fchip {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 4px 8px 4px 12px; border-radius: var(--r-pill);
  background: var(--accent-soft); color: var(--accent);
  border: none; font: inherit; font-size: 12px; font-weight: 500; cursor: pointer;
}
.fchip:hover { background: #fbd9ea; }
.fchip-x { font-size: 11px; opacity: .7; }
.fchip:hover .fchip-x { opacity: 1; }

/* Filters & sort modal (reuses .modal / .modal-card / .modal-head / .modal-body) */
.filter-card { width: min(560px, 100%); }
.modal-foot { flex: 0 0 auto; display: flex; justify-content: space-between; gap: 8px; padding: 16px 24px; border-top: 1px solid var(--border); }
/* Each category is a collapsed accordion card (reuses .acc / .acc-body). */
.fsec-head {
  width: 100%; text-align: left; background: var(--bg-card); border: none; cursor: pointer;
  padding: 16px; display: flex; align-items: center; gap: 8px; font: inherit;
  transition: background .12s;
}
.fsec-head:hover, .fsec.open .fsec-head { background: var(--bg-sunken); }
.fsec-label { font-size: 14px; font-weight: 600; color: var(--text); }
.fsec-summary { margin-left: auto; font-size: 13px; color: var(--text-soft); text-align: right; }
.fsec-head::after {   /* chevron: down when collapsed, up when open */
  content: ""; flex: 0 0 auto; width: 8px; height: 8px;
  border-right: 1.5px solid var(--text-faint); border-bottom: 1.5px solid var(--text-faint);
  transform: translateY(-2px) rotate(45deg); transition: transform .15s;
}
.fsec.open .fsec-head::after { transform: translateY(1px) rotate(225deg); }
.fhint { font-size: 12px; color: var(--text-faint); }
.fsearch {
  width: 100%; padding: 8px 16px; box-sizing: border-box;
  border: 1px solid var(--border); border-radius: var(--r-pill);
  font: inherit; font-size: 14px; outline: none;
}
.fsearch:focus { border-color: var(--accent); }
.fpills { display: flex; flex-wrap: wrap; gap: 8px; }
.fpills-scroll { max-height: 196px; overflow-y: auto; padding: 4px; margin: -4px; }
.fpill {
  padding: 8px 12px; border-radius: var(--r-pill);
  border: 1px solid var(--border); background: var(--bg-card);
  color: var(--text); font: inherit; font-size: 13px; cursor: pointer;
  transition: background .15s, border-color .15s, color .15s;
}
.fpill:hover { border-color: var(--border-strong); }
.fpill.selected { background: var(--accent); border-color: var(--accent); color: #fff; }

/* ── View bar ────────────────────────────────────────── */
.viewbar {
  display: flex; align-items: center; gap: 16px; flex-wrap: wrap;
  padding: 16px var(--pad-x) 0;
}
/* Beside the tabs only when there's reliably room for THAT row, else its own
   line. Breakpoint-driven (not content-driven) so date/count length never flips
   it — and each row gets its own threshold (Gallery/Calendar are narrow; the Map
   row with its two checkboxes needs more width). */
.view-sub { display: inline-flex; flex: 1 1 100%; align-items: center; gap: 16px; flex-wrap: wrap; }
@media (min-width: 720px)  { #gallerySub, #calSub { flex: 1 1 auto; } }
@media (min-width: 1100px) { #mapSub { flex: 1 1 auto; } }
.cal-nav { display: inline-flex; align-items: center; gap: 16px; }
/* Hour-height zoom. Sits next to the day/week/month segment; hidden in Month,
   which has no hour grid to scale. */
.cal-zoom { display: inline-flex; align-items: center; gap: 4px; }
.cal-zoom-label { min-width: 44px; text-align: center; font-size: 13px; font-variant-numeric: tabular-nums; color: var(--text-soft); cursor: default; }
.cal-zoom .iconbtn:disabled { opacity: .4; cursor: default; }
#calSub .cal-nav { margin-left: auto; }       /* push month title + ‹Today› to the right */
.navgroup { display: inline-flex; align-items: center; gap: 4px; }
.cal-title { font-weight: 600; }
#mapCount, #galCount { margin-left: auto; }    /* push the count to the right edge, away from the title (same as the map) */
.check { display: inline-flex; align-items: center; gap: 8px; font-size: 14px; color: var(--text-soft); cursor: pointer; }
.check input { accent-color: var(--accent); }

/* ── Gallery (grouped cards) ─────────────────────────── */
.gallery { padding: 24px var(--pad-x); }
.week { margin-bottom: 32px; }
.week-head {
  display: flex; align-items: center; gap: 16px;
  margin: 0 0 16px; padding-bottom: 8px; border-bottom: 1px solid var(--border);
}
.week-head .navgroup { margin-right: 8px; }
.week-head h2 { margin: 0; font-family: var(--font-head); font-size: 16px; font-weight: 600; letter-spacing: -0.01em; }
.week-head .count { color: var(--text-faint); font-size: 13px; }
.week-head .this-week {
  color: var(--accent); font-size: 12px; font-weight: 600;
  background: var(--accent-soft); padding: 4px 12px; border-radius: var(--r-pill);
}
.cards { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 16px; }

/* Gallery sections — same subtitle style for "Earlier" + "Upcoming this week" */
.gal-section { margin-bottom: 24px; }
.gal-subtitle {
  font-family: var(--font-head); font-size: 14px; font-weight: 600; color: var(--text-soft);
  margin: 0 0 16px; display: flex; align-items: center; gap: 8px;
}
.gal-toggle { background: none; border: none; cursor: pointer; padding: 0; }
.gal-toggle:hover { color: var(--text); }
.gal-toggle .count { color: var(--text-faint); font-weight: 500; }
/* count set off from the bold week date in search-result section headers */
.gal-subtitle .count { font-family: var(--font-body); font-weight: 500; font-size: 13px; color: var(--text-faint); margin-left: 4px; }
/* up/down chevron only — never sideways (collapsed = down, expanded = up) */
.gal-toggle .caret {
  display: inline-block; width: 8px; height: 8px;
  border-right: 2px solid currentColor; border-bottom: 2px solid currentColor;
  transform: translateY(-2px) rotate(45deg); opacity: .6; transition: transform .15s;
}
.gal-toggle.open .caret { transform: translateY(1px) rotate(225deg); }

/* ── Card ────────────────────────────────────────────── */
.card {
  background: var(--bg-card); border: 1px solid var(--border);
  border-radius: var(--r-lg); padding: 16px; box-shadow: var(--shadow);
  display: flex; flex-direction: column; gap: 8px;
  transition: transform .12s, box-shadow .12s;
}
.card { cursor: pointer; }
.card:hover { transform: translateY(-2px); box-shadow: var(--shadow-pop); }
.card.cancelled { opacity: .55; }
.card-when { font-size: 13px; font-weight: 600; color: var(--accent); font-variant-numeric: tabular-nums; display: flex; align-items: center; gap: 8px; }
/* thumbs up/down — rate the match, never hide the event */
.card-fb { margin-left: auto; display: inline-flex; gap: 2px; }
.fb { display: inline-flex; align-items: center; justify-content: center; width: 28px; height: 28px; padding: 0; border: none; background: transparent; color: var(--text-faint); border-radius: 8px; cursor: pointer; transition: background .12s, color .12s; }
.fb:hover { background: #f1f0ec; color: var(--text-soft); }
.fb.up.on { color: var(--accent); background: var(--accent-soft); }
.fb.down.on { color: #4b5563; background: #eef0f2; }
.fb.on svg { fill: currentColor; fill-opacity: .14; }
/* Copy-link button, top-right of a card. Hidden until the card is hovered or
   something inside it takes keyboard focus, so a grid of cards stays quiet.
   Always visible once focused, so it is reachable without a mouse. */
.card-copy {
  display: inline-flex; align-items: center; justify-content: center;
  width: 28px; height: 28px; padding: 0; margin-left: 4px;
  border: none; background: transparent; color: var(--text-faint);
  border-radius: 8px; cursor: pointer;
  opacity: 0; transition: opacity .12s, background .12s, color .12s;
}
.card:hover .card-copy, .card:focus-within .card-copy, .card-copy:focus-visible { opacity: 1; }
/* Anchor it within the title row and reserve its lane. Inline placement let a
   two-line title wrap the button out of view; this stays visible without
   crowding the thumbs/Going controls in the row above. */
.card-title { position: relative; padding-right: 32px; }
.card-title .card-copy {
  position: absolute; right: 0; top: 50%; transform: translateY(-50%);
  display: inline-flex; width: 24px; height: 24px; margin: 0;
}
.card-copy:hover { background: #f1f0ec; color: var(--text-soft); }
.card-copy .card-copy-ok { display: none; }
.card-copy.copied { color: var(--free, #2e7d32); opacity: 1; }
.card-copy.copied svg:first-of-type { display: none; }
.card-copy.copied .card-copy-ok { display: block; }
.card-copy.failed { color: #b3261e; opacity: 1; }
@media (hover: none) { .card-copy { opacity: 1; } }   /* touch has no hover to reveal it */
.hover-copy-float {
  position: fixed; z-index: 1100;
  display: inline-flex; align-items: center; justify-content: center;
  width: 28px; height: 28px; padding: 0;
  border: 1px solid var(--border); border-radius: 8px;
  background: var(--bg-card); color: var(--text-faint);
  box-shadow: var(--shadow); cursor: pointer;
}
.hover-copy-float[hidden] { display: none; }
.hover-copy-float:hover { background: #f1f0ec; color: var(--text-soft); }
.hover-copy-float.copied { color: var(--free, #2e7d32); }
.hover-copy-float.failed { color: #b3261e; }
.card-title { margin: 0; font-size: 16px; font-weight: 600; line-height: 1.35; letter-spacing: -0.01em; }
.card-title a { color: var(--text); text-decoration: none; }
.card-title a:hover { text-decoration: underline; }
.card-loc { font-size: 13px; color: var(--text-soft); }

.chips { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 4px; }
.chip {
  font-size: 12px; font-weight: 500; padding: 4px 12px;
  border-radius: var(--r-pill); background: var(--bg-sunken); color: var(--text-soft); white-space: nowrap;
}
.chip.free { background: var(--free-bg); color: var(--free); }
.chip.paid { background: var(--paid-bg); color: var(--paid); }
.chip.host { background: var(--accent-soft); color: var(--accent); }
.chip.investors { background: #ede9fe; color: #5b21b6; }
.chip.rel { background: var(--rel-bg); color: var(--rel); }
.chip.translated { background: #eef2ff; color: #4f46e5; }   /* hover the chip to see the original title */
.chip.loc-nyc { background: #e9f1ee; color: #2a6b54; }
.chip.loc-virtual { background: #ede9f6; color: #6248a8; }
.chip.loc-other { background: #f3efe7; color: #7a6a4a; }

.card-reasons { font-size: 12px; color: var(--text-faint); }
.card-source {
  margin-top: auto;            /* pin source row + divider to the card bottom so a row aligns */
  padding-top: 16px; border-top: 1px solid var(--border);
  font-size: 12px; color: var(--text-faint);
}
.email-link { color: var(--accent); text-decoration: none; font-weight: 500; }
.email-link:hover { text-decoration: underline; }

/* Collapsible description (2-line preview) */
.card-desc-wrap { margin-top: 4px; }
.card-desc {
  margin: 0; font-size: 13px; line-height: 1.5; color: var(--text-soft);
  white-space: pre-line; display: -webkit-box; -webkit-line-clamp: 2;
  -webkit-box-orient: vertical; overflow: hidden;
}
.card-desc-wrap.short .card-desc, .card-desc-wrap.open .card-desc {
  display: block; -webkit-line-clamp: unset; overflow: visible;
}
.desc-toggle {
  margin-top: 4px; padding: 0; background: none; border: none;
  color: var(--accent); font: inherit; font-size: 12px; font-weight: 600; cursor: pointer;
}
.desc-toggle:hover { text-decoration: underline; }

/* ── Calendar (full-width) ───────────────────────────── */
.calendar { padding: 16px var(--pad-x) 24px; }
.cal-grid {
  display: grid; grid-template-columns: repeat(7, 1fr); gap: 1px;
  background: var(--border); border: 1px solid var(--border);
  border-radius: var(--r-md); overflow: hidden;
}
.cal-dow { background: var(--bg); padding: 8px; font-size: 12px; font-weight: 600; color: var(--text-faint); text-align: center; }
.cal-cell {
  background: var(--bg-card); min-height: 104px; padding: 8px;
  display: flex; flex-direction: column; gap: 4px; cursor: pointer;
  transition: background .12s;
}
.cal-cell:hover { background: var(--bg-sunken); }
.cal-cell.out { background: var(--bg-sunken); }
.cal-cell.out .cal-num { color: var(--text-faint); }
.cal-cell.today .cal-num {
  background: var(--accent); color: #fff; border-radius: var(--r-pill);
  width: 24px; height: 24px; display: inline-flex; align-items: center; justify-content: center;
}
.cal-num { font-size: 12px; font-weight: 600; color: var(--text-soft); }
.day-chip {
  display: block; width: 100%; text-align: left;
  font: inherit; font-size: 11px; line-height: 1.3; padding: 4px 8px;
  border: none; border-radius: 8px; background: var(--bg-sunken); color: var(--text);
  white-space: normal; cursor: pointer;
}
.day-chip:hover { background: var(--border); }
.day-chip.free { background: var(--free-bg); color: var(--free); }
.day-chip.paid { background: var(--paid-bg); color: var(--paid); }
.day-chip b { font-weight: 600; }
.day-more { font-size: 11px; color: var(--text-faint); padding-left: 4px; }

/* Calendar: day / 2-day / week TIME GRID */
.tg { border: 1px solid var(--border); border-radius: var(--r-md); overflow: hidden; background: var(--bg-card); }
.tg-head, .tg-allday { display: grid; grid-template-columns: 56px repeat(var(--n), 1fr); }
.tg-head { border-bottom: 1px solid var(--border); }
.tg-allday { border-bottom: 1px solid var(--border); background: var(--bg-sunken); }
.tg-corner { border-right: 1px solid var(--border); }
.tg-allday-label { display: flex; align-items: center; justify-content: flex-end; padding-right: 8px; font-size: 11px; color: var(--text-faint); }
.tg-colhead { padding: 8px; text-align: center; font-size: 13px; color: var(--text-soft); border-left: 1px solid var(--border); cursor: pointer; }
.tg-colhead.today { color: var(--accent); }
.tg-colhead.today b { color: var(--accent); }
.tg-colhead b { color: var(--text); }
.tg-allday-cell { min-height: 8px; padding: 4px; border-left: 1px solid var(--border); display: flex; flex-direction: column; gap: 4px; }
.tg-body { display: grid; grid-template-columns: 56px 1fr; max-height: calc(100vh - 320px); min-height: 360px; overflow-y: auto; }
.tg-gutter { position: relative; }
.tg-hour { position: absolute; right: 8px; transform: translateY(-50%); font-size: 11px; color: var(--text-faint); white-space: nowrap; }
.tg-cols { display: grid; grid-template-columns: repeat(var(--n), 1fr); }
.tg-col {
  position: relative; border-left: 1px solid var(--border);
  background: repeating-linear-gradient(to bottom, var(--border) 0 1px, transparent 1px var(--tg-pxh, 56px));
}
.tg-col.today { background-color: var(--accent-soft); }
/* current-time line on today, in the accent color */
.tg-now { position: absolute; left: 0; right: 0; height: 2px; background: var(--accent); z-index: 6; pointer-events: none; }
.tg-now::before { content: ""; position: absolute; left: -4px; top: -3px; width: 8px; height: 8px; border-radius: 50%; background: var(--accent); }
.tg-block {
  position: absolute; overflow: hidden; cursor: pointer; font: inherit; text-align: left;
  border: 1px solid rgba(255,255,255,.55); border-radius: 8px; padding: 4px 8px;
  background: var(--accent-soft); color: var(--accent);
  display: flex; flex-direction: column; box-shadow: var(--shadow);
}
.tg-block:hover { filter: brightness(0.97); }
.tg-block.free { background: var(--free-bg); color: var(--free); }
.tg-block.paid { background: var(--paid-bg); color: var(--paid); }
.tg-time { font-size: 10px; font-weight: 600; opacity: .85; line-height: 1.2; }
.tg-name { font-size: 11px; font-weight: 600; line-height: 1.25; }

/* ── Map ─────────────────────────────────────────────── */
#mapWrap { margin: 16px 0 24px; padding: 0 var(--pad-x); }
#map { height: calc(100vh - 280px); min-height: 480px; border: 1px solid var(--border); border-radius: var(--r-lg); overflow: hidden; }
.leaflet-popup-content { font-family: var(--font-body); font-size: 13px; line-height: 1.5; }
.leaflet-popup-content a { color: var(--accent); font-weight: 600; }
/* "You are here" dot — neutral black/white, matching the map's other controls rather
   than competing with them. Accent pink is reserved for EVENT pins: when the locate dot
   was also pink it read as one more event instead of as "you". (owner note, 2026-07-28) */
.maplibregl-user-location-dot,
.maplibregl-user-location-dot::before { background-color: var(--text); }
.maplibregl-user-location-dot::before { box-shadow: 0 0 0 2px var(--text); }
.maplibregl-user-location-accuracy-circle { background-color: rgba(17, 24, 39, 0.12); }
/* Recolour ONLY. Don't add a border/box-shadow to .maplibregl-user-location-dot — its
   ::after already draws the white ring (19px, box-sizing:border-box, offset -2px to
   centre on the 15px dot). An extra border grows the dot's box under content-box, which
   moves that -2px reference and visibly knocks the ring off-centre. */

/* The locate BUTTON. Selectors MUST carry the ".maplibregl-ctrl button" prefix:
   MapLibre's own rules do (0,4,1 specificity), and a prefix-less override silently
   loses — the blue survived a week of "fixes" that never applied (2026-07-28). MapLibre bakes its own light blue (#33b5e5) into the icon as a
   data-URI SVG, so it can't be recolored with `color` or `fill` — the whole background
   -image has to be replaced. These are MapLibre 4.7.1's exact paths with only the fill
   swapped to near-black, so the control reads as monochrome like the zoom buttons next
   to it. If MapLibre is upgraded, re-copy the paths from its stylesheet. */
.maplibregl-ctrl button.maplibregl-ctrl-geolocate.maplibregl-ctrl-geolocate-active .maplibregl-ctrl-icon {
  background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='29' height='29' fill='%23111827' viewBox='0 0 20 20'%3E%3Cpath d='M10 4C9 4 9 5 9 5v.1A5 5 0 0 0 5.1 9H5s-1 0-1 1 1 1 1 1h.1A5 5 0 0 0 9 14.9v.1s0 1 1 1 1-1 1-1v-.1a5 5 0 0 0 3.9-3.9h.1s1 0 1-1-1-1-1-1h-.1A5 5 0 0 0 11 5.1V5s0-1-1-1m0 2.5a3.5 3.5 0 1 1 0 7 3.5 3.5 0 1 1 0-7'/%3E%3Ccircle cx='10' cy='10' r='2'/%3E%3C/svg%3E");
}
.maplibregl-ctrl button.maplibregl-ctrl-geolocate.maplibregl-ctrl-geolocate-background .maplibregl-ctrl-icon {
  background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='29' height='29' fill='%23111827' viewBox='0 0 20 20'%3E%3Cpath d='M10 4C9 4 9 5 9 5v.1A5 5 0 0 0 5.1 9H5s-1 0-1 1 1 1 1 1h.1A5 5 0 0 0 9 14.9v.1s0 1 1 1 1-1 1-1v-.1a5 5 0 0 0 3.9-3.9h.1s1 0 1-1-1-1-1-1h-.1A5 5 0 0 0 11 5.1V5s0-1-1-1m0 2.5a3.5 3.5 0 1 1 0 7 3.5 3.5 0 1 1 0-7'/%3E%3C/svg%3E");
}

/* ── Map controls: styled as the FORMAT PICKER (.seg / .seg-btn) ─────────────
   owner note, 2026-09-01: the zoom/locate stack should read as the same component as
   the gallery/calendar/map picker — same 18px icons, same 1.7 stroke, same
   --text-soft grey darkening on hover, same pill container with a 1px border and
   4px padding/gap. Pink is reserved for the ACTIVE state there, so these stay
   grey; making them accent-colored is the "extra color" problem in reverse.
   MapLibre bakes its icons into data-URI backgrounds that `color` cannot reach,
   so each icon is redrawn here on the same 24px grid the picker's icons use.
   The `.maplibregl-ctrl button` prefix is REQUIRED — MapLibre's own rules are
   (0,4,1) and a prefix-less override silently loses. */
.maplibregl-ctrl-group,
.maplibregl-ctrl-group:not(:empty) {
  display: flex; flex-direction: column; gap: 4px; padding: 4px;
  background: var(--bg-card); border: 1px solid var(--border);
  border-radius: var(--r-pill); box-shadow: none;
}
.maplibregl-ctrl-group button,
.maplibregl-ctrl-group button + button {
  width: 34px; height: 34px; border: none; border-radius: var(--r-pill);
  background: transparent; transition: background .15s;
}
.maplibregl-ctrl-group button:hover { background: var(--bg-sunken); }
.maplibregl-ctrl button .maplibregl-ctrl-icon {
  background-size: 18px 18px; background-position: center; background-repeat: no-repeat;
}
.maplibregl-ctrl button.maplibregl-ctrl-zoom-in .maplibregl-ctrl-icon {
  background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%236b7280' stroke-width='1.7' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 5v14M5 12h14'/%3E%3C/svg%3E");
}
.maplibregl-ctrl button.maplibregl-ctrl-zoom-out .maplibregl-ctrl-icon {
  background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%236b7280' stroke-width='1.7' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 12h14'/%3E%3C/svg%3E");
}
.maplibregl-ctrl button.maplibregl-ctrl-geolocate .maplibregl-ctrl-icon,
.maplibregl-ctrl button.maplibregl-ctrl-geolocate.maplibregl-ctrl-geolocate-active .maplibregl-ctrl-icon,
.maplibregl-ctrl button.maplibregl-ctrl-geolocate.maplibregl-ctrl-geolocate-background .maplibregl-ctrl-icon {
  background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%236b7280' stroke-width='1.7' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='7'/%3E%3Cpath d='M12 2v3M12 19v3M2 12h3M19 12h3'/%3E%3Ccircle cx='12' cy='12' r='2.5'/%3E%3C/svg%3E");
}
/* Hover darkens the icon to --text, exactly as .seg-btn:hover:not(.active) does. */
.maplibregl-ctrl button.maplibregl-ctrl-zoom-in:hover .maplibregl-ctrl-icon {
  background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23111827' stroke-width='1.7' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 5v14M5 12h14'/%3E%3C/svg%3E");
}
.maplibregl-ctrl button.maplibregl-ctrl-zoom-out:hover .maplibregl-ctrl-icon {
  background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23111827' stroke-width='1.7' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 12h14'/%3E%3C/svg%3E");
}
.maplibregl-ctrl button.maplibregl-ctrl-geolocate:hover .maplibregl-ctrl-icon {
  background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23111827' stroke-width='1.7' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='7'/%3E%3Cpath d='M12 2v3M12 19v3M2 12h3M19 12h3'/%3E%3Ccircle cx='12' cy='12' r='2.5'/%3E%3C/svg%3E");
}
/* The JS swaps MapLibre's soft background-image glyphs for the same inline SVG
   family as #viewTabs. This final layer keeps every MapLibre state from painting
   its bundled image underneath the crisp icon. */
.maplibregl-ctrl button .maplibregl-ctrl-icon.mailroom-control-icon {
  display: grid; place-items: center;
  background-image: none !important;
  color: var(--text-soft);
}
.maplibregl-ctrl button .maplibregl-ctrl-icon svg { display: block; width: 18px; height: 18px; }
.maplibregl-ctrl button:hover .maplibregl-ctrl-icon.mailroom-control-icon { color: var(--text); }

/* ── Modal (day popup) ───────────────────────────────── */
.modal { position: fixed; inset: 0; z-index: 100; display: flex; align-items: center; justify-content: center; padding: 24px; }
.modal[hidden] { display: none; }
.modal-backdrop { position: absolute; inset: 0; background: rgba(17,24,39,.35); backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px); }
.modal-card {
  position: relative; width: 100%; max-width: 560px; max-height: calc(100dvh - 48px);
  display: flex; flex-direction: column;
  background: var(--bg-card); border-radius: var(--r-lg); box-shadow: var(--shadow-pop); overflow: hidden;
}
.modal-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; padding: 24px; border-bottom: 1px solid var(--border); }
.modal-head-text { display: flex; flex-direction: column; gap: 8px; min-width: 0; }
.modal-head h3 { margin: 0; font-family: var(--font-head); font-size: 18px; font-weight: 600; line-height: 1.25; letter-spacing: -0.01em; }
#modalTitle { position: relative; padding-right: 32px; }
#modalTitle .card-copy { position: absolute; right: 0; top: 50%; transform: translateY(-50%); margin: 0; }
.modal-card:hover #modalTitle .card-copy, .modal-card:focus-within #modalTitle .card-copy { opacity: 1; }
.modal-close { flex: 0 0 auto; background: none; border: none; color: var(--text-faint); cursor: pointer; font-size: 18px; line-height: 1; padding: 4px; border-radius: 8px; }
.modal-close:hover { color: var(--text); background: var(--bg-sunken); }
/* flex:1 + min-height:0 makes this the scroll region inside the height-capped
   card, so the header stays pinned and long day-lists scroll instead of clipping */
.modal-body { flex: 1 1 auto; min-height: 0; padding: 24px; overflow-y: auto; display: flex; flex-direction: column; gap: 16px; }
.modal-body > * { flex: 0 0 auto; }   /* don't let children shrink — they'd clip; scroll instead */
.modal-head { flex: 0 0 auto; }
/* Day-modal accordion */
.acc { border: 1px solid var(--border); border-radius: var(--r-md); overflow: hidden; }
.acc.open { border-color: var(--border-strong); }
.acc-head {
  width: 100%; text-align: left; background: var(--bg-card); border: none; cursor: pointer;
  padding: 16px; display: flex; flex-direction: column; gap: 4px; font: inherit;
  transition: background .12s;
}
.acc-head:hover, .acc.open .acc-head { background: var(--bg-sunken); }
.acc-body { padding: 16px; display: flex; flex-direction: column; gap: 16px; border-top: 1px solid var(--border); }
.di-when { font-size: 12px; font-weight: 600; color: var(--accent); }
.di-name { font-size: 15px; font-weight: 600; color: var(--text); line-height: 1.3; }
.di-meta { font-size: 12px; color: var(--text-soft); }

/* Event detail modal body */
.detail-when { font-size: 13px; font-weight: 600; color: var(--accent); font-variant-numeric: tabular-nums; }
.detail-desc { margin: 0; font-size: 14px; line-height: 1.6; color: var(--text-soft); white-space: pre-line; }
/* clickable links inside descriptions (open in a new tab) */
.detail-desc a, .card-desc a { color: var(--accent); text-decoration: underline; overflow-wrap: anywhere; }
.detail-desc a:hover, .card-desc a:hover { color: var(--accent-hover); }
.empty-note { color: var(--text-faint); text-align: center; font-size: 13px; padding: 16px 0; margin: 0; }
.cards .empty-note { grid-column: 1 / -1; }
.detail-actions { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 8px; }
.detail-actions .btn { text-decoration: none; display: inline-flex; align-items: center; }

/* ── Empty / footer ──────────────────────────────────── */
.empty { margin: 0; padding: 64px var(--pad-x); text-align: center; color: var(--text-soft); }
.footer { margin: 0; padding: 24px var(--pad-x); color: var(--text-faint); font-size: 12px; border-top: 1px solid var(--border); }
.foot-sep { margin: 0 6px; opacity: .55; }
/* map dot → multiple events at one location: pick-list */
.evlist { display: flex; flex-direction: column; gap: 8px; }
.evlist-item { display: flex; flex-direction: column; gap: 4px; width: 100%; text-align: left;
  background: var(--bg-card); border: 1px solid var(--border); border-radius: 12px; padding: 12px;
  cursor: pointer; transition: background .15s, border-color .15s; }
.evlist-item:hover { background: var(--accent-soft); border-color: var(--accent); }
.evlist-when { font-size: 12px; color: var(--text-faint); }
.evlist-title { font-size: 15px; font-weight: 600; color: var(--text); }

/* ── Mobile ──────────────────────────────────────────── */
/* Phones, 320px (iPhone SE) up to 430px (Pro Max). Two rules drive most of it:
   1. Every grid track is minmax(0, 1fr). A bare `1fr` keeps an automatic
      min-content floor, so one unbreakable title/chip widened the whole grid —
      the gallery scrolled sideways and the month grid clipped Thu–Sat
      (overflow: hidden) at every phone width (measured 2026-09-02).
   2. Nothing is squeezed to fit: month cells show the date + a count and open
      the day; the time grid keeps legible columns and scrolls sideways. */
@media (max-width: 640px) {
  :root { --pad-x: 16px; }
  .topbar-main { gap: 12px; }
  .topbar-actions { width: 100%; align-items: stretch; }
  .action-row { justify-content: space-between; gap: 16px; }
  .topbar .meta { text-align: right; }
  .controls { position: static; }
  .search-wrap { flex-basis: 100%; }
  .controls.searching #scopeSeg { max-width: 100%; }
  .brand h1 { font-size: 24px; }
  .viewbar { padding-top: 16px; gap: 12px; }
  .gallery { padding: 16px var(--pad-x); }

  /* Gallery: one column; the header row (date · thumbs · Going?) may wrap */
  .cards { grid-template-columns: minmax(0, 1fr); }
  .card { min-width: 0; }
  .card-when { flex-wrap: wrap; row-gap: 8px; }
  .card-title, .card-loc, .card-reasons, .card-source { overflow-wrap: anywhere; }
  .chip { max-width: 100%; white-space: normal; overflow-wrap: anywhere; }

  /* Month: 7 columns are ~40px wide here — no room for a title. Date + count
     only (day-chip text is hidden); tapping the cell opens the day list. */
  .calendar { padding: 16px var(--pad-x) 24px; }
  .cal-grid { grid-template-columns: repeat(7, minmax(0, 1fr)); }
  .cal-dow { padding: 8px 0; font-size: 11px; }
  .cal-cell { min-height: 56px; padding: 8px 4px; align-items: center; gap: 6px; }
  .cal-cell .day-chip, .cal-cell .day-more { display: none; }
  .cal-cell[data-count]:not([data-count="0"])::after {
    content: attr(data-count);
    font-size: 11px; font-weight: 600; line-height: 1;
    padding: 4px 6px; min-width: 20px; text-align: center;
    border-radius: var(--r-pill); background: var(--accent-soft); color: var(--accent);
  }
  .cal-cell.out[data-count]::after { background: var(--border); color: var(--text-soft); }

  /* Day / 2-day / week time grid: columns never drop below 96px; the grid
     scrolls sideways inside its frame (week = 7 × 96 + gutter) while the
     hour axis scrolls vertically as before. */
  .tg { overflow-x: auto; -webkit-overflow-scrolling: touch; }
  .tg-head, .tg-allday { grid-template-columns: 48px repeat(var(--n), minmax(96px, 1fr)); }
  .tg-body { grid-template-columns: 48px minmax(0, 1fr); max-height: calc(100dvh - 260px); }
  .tg-cols { grid-template-columns: repeat(var(--n), minmax(96px, 1fr)); }
  .tg-head, .tg-allday, .tg-body { min-width: calc(48px + var(--n) * 96px); }
  .tg-colhead { padding: 8px 4px; font-size: 12px; }
  .tg-block { padding: 4px 6px; }
  /* All-day row: three one-line chips, the rest folded into "+N more"
     (the column header opens the whole day) — otherwise a busy day's all-day
     list pushed the hour grid off the screen */
  .tg-allday .day-chip { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .tg-allday-cell .day-chip:nth-child(n + 4) { display: none; }
  .tg-allday-cell:not([data-more="0"])::after { content: "+" attr(data-more) " more"; font-size: 11px; color: var(--text-faint); padding: 4px; }
  /* Segmented controls never break a label ("2 Days") across lines */
  .seg-btn { white-space: nowrap; }

  /* Map */
  #mapWrap { padding: 0 var(--pad-x); }
  #map { height: 60dvh; min-height: 360px; }

  /* Modals: edge-to-edge sheet with 16px insets */
  .modal { padding: 16px; }
  .modal-card { max-height: calc(100dvh - 32px); }
  .modal-head, .modal-body, .modal-foot { padding: 16px; }
  .modal-foot { flex-wrap: wrap; }
  .modal-foot .btn { flex: 1 1 auto; text-align: center; }
  .detail-actions .btn, .detail-actions .attend, .detail-actions .rsvp { flex: 1 1 auto; justify-content: center; text-align: center; }
}

/* 320px phones: the four calendar modes only fit with 12px side padding */
@media (max-width: 360px) {
  #calModes .seg-btn { padding-left: 12px; padding-right: 12px; }
  .cal-zoom-label { min-width: 36px; }
}

/* ── Touch targets ───────────────────────────────────── */
/* Fingers, not pointers: every control reaches 36–44px. Gated on a coarse
   pointer so desktop layouts (Air trackpad = fine pointer) are untouched. */
@media (hover: none) and (pointer: coarse) {
  .search-go, .filter-badge { width: 36px; height: 36px; }
  .search-clear { width: 36px; height: 36px; }
  .fb, .card-copy { width: 36px; height: 36px; }
  .card-title .card-copy { width: 32px; height: 32px; vertical-align: -10px; }
  .attend, .rsvp { min-height: 36px; padding: 8px 12px; }
  .desc-toggle { padding: 8px 0; margin-top: 0; }
  .gal-toggle { padding: 8px 0; }
  .email-link { display: inline-block; padding: 8px 0; }
  .link-count { padding: 8px 0; }
  .check { min-height: 44px; }
  .check input { width: 20px; height: 20px; }
  .day-chip { padding: 8px; }
  .day-more { padding: 8px 4px; display: inline-block; }
  .modal-close { padding: 10px; }
  .fchip { padding: 8px 12px 8px 16px; }
  .fpill { padding: 12px 16px; }
  .maplibregl-ctrl-group button, .maplibregl-ctrl-group button + button { width: 40px; height: 40px; }
  /* the switch keeps its 40×22 look; an invisible halo takes the tap */
  .switch::before { content: ""; position: absolute; inset: -11px -8px; }
}

/* Floating "Copy address" button — appears when you select an address (any view) */
#copyFloat {
  position: fixed;
  transform: translateX(-50%);
  z-index: 1000;
  background: var(--accent);
  color: #fff;
  border: none;
  cursor: pointer;
  font: 600 13px/1 "Switzer", system-ui, sans-serif;
  padding: 8px 12px;
  border-radius: 999px;
  box-shadow: 0 4px 14px rgba(0, 0, 0, .18);
  white-space: nowrap;
}
#copyFloat[hidden] { display: none; }
#copyFloat:hover { background: var(--accent-hover); }

/* shared address under "N events here" */
.list-loc { margin: 0 0 12px; }

/* Attendance toggle — Going? / Going / Attending / Attended */
.attend {
  margin-left: 8px; padding: 4px 12px; border-radius: 999px;
  border: 1px solid var(--border); background: var(--bg-card);
  font: 600 12px/1 "Switzer", system-ui, sans-serif; color: var(--text-soft, #6b7280);
  cursor: pointer; transition: background .15s, border-color .15s, color .15s; white-space: nowrap;
}
.attend:hover { border-color: var(--accent); color: var(--accent); }
.attend.on { background: var(--accent-soft); border-color: var(--accent); color: var(--accent); }
.detail-actions .attend { padding: 12px 16px; margin-left: 0; font-size: 14px; }

/* RSVP badge — real status from your logged-in account (read-only, not clickable) */
.rsvp {
  margin-left: 8px; padding: 4px 12px; border-radius: 999px;
  border: 1px solid transparent;
  font: 600 12px/1 "Switzer", system-ui, sans-serif;
  white-space: nowrap; display: inline-flex; align-items: center;
}
.rsvp-src { opacity: .6; font-weight: 500; }
.rsvp-going             { background: var(--free-bg);     color: var(--free); }
.rsvp-hosting           { background: var(--accent-soft); color: var(--accent); }
.rsvp-maybe,
.rsvp-waitlist,
.rsvp-pending           { background: var(--paid-bg);     color: var(--paid); }
.rsvp-invited           { background: var(--bg-card); border-color: var(--border); color: var(--text-soft, #6b7280); }
.rsvp-declined          { background: transparent; border-color: var(--border); color: var(--text-faint, #9ca3af); }
.detail-actions .rsvp   { padding: 12px 16px; margin-left: 0; font-size: 14px; }

/* Going control surfaced at the TOP of the detail modal (prominent, first action you see
   when you click into an event from gallery / calendar / map). */
.detail-going { margin: 0 0 16px; }
.detail-going .attend,
.detail-going .rsvp { margin-left: 0; padding: 12px 16px; font-size: 14px; }

/* "Near my calendar" ranking (2026-07-28) — violet ties the note to the
   calendar anchor it measures from; 8px grid, sentence case. */
.di-near { color: #7c3aed; font-weight: 600; }
.maplibregl-popup-content .near-btn { display: block; margin-top: 8px; font-size: 13px; padding: 8px 16px; }
.maplibregl-popup-content { font-family: var(--font-body); font-size: 13px; line-height: 1.5; border-radius: var(--r-md); }

/* Format filter: Tagged only / Include likely */
.fsec-body .fmode { margin-bottom: 16px; }
