:root {
  --bg: #f5efe1;
  --ink: #111;
  --muted: #666;
  --rule: #ddd;
  --accent: #d4a574;
  --accent-soft: #f5f0e8;
  --chip-bg: #f5efe1;
  --chip-border: #ccc;
  --chip-ink: #222;
  --chip-active-bg: #111;
  --chip-active-ink: #fff;
  --hi: #2a5a2a;
  --mid: #c08030;
  --lo: #a02020;
  --max: 1000px;
  --serif: "Source Serif 4", "Source Serif Pro", "Saol Display", "Didot", "Bodoni Moda", "Playfair Display", Georgia, serif;
  --sans: "Inter", "Helvetica Neue", "Arial", system-ui, sans-serif;
  --text-xs: 0.75rem;
  --text-sm: 0.875rem;
  --text-base: 1rem;
  /* task-5.5: heading-tier scales use clamp() so type fluidly shrinks on
     phones without per-breakpoint pixel overrides. Lower bounds match the
     prior @320px / @480px overrides; upper bounds match the desktop values. */
  --text-md: clamp(1rem, 0.875rem + 0.4vw, 1.1875rem);
  --text-lg: clamp(1.5rem, 1.25rem + 1.25vw, 1.75rem);
  --text-xl: clamp(1.75rem, 0.95rem + 4vw, 3.5rem);
}

* { box-sizing: border-box; }

body {
  background: var(--bg);
  color: var(--ink);
  font-family: var(--serif);
  font-size: var(--text-base);
  line-height: 1.6;
  margin: 0;
  padding: 0;
  /* task-5.6: Source Serif 4 ships an optical-size axis — opt in so the body
     copy uses the Subhead/Small cuts at 14–17px and the Display cut at the
     masthead, matching the rationale in docs/TYPOGRAPHY.md. */
  font-optical-sizing: auto;
  font-feature-settings: "kern" 1, "liga" 1;
}

.masthead {
  padding: 2em 1em 1.5em;
  text-align: center;
  border-bottom: 1px solid var(--rule);
}

.masthead-inner {
  max-width: var(--max);
  margin: 0 auto;
}

.masthead-title {
  font-size: var(--text-xl);
  font-weight: 800;
  letter-spacing: -0.02em;
  margin: 0;
  text-transform: uppercase;
}

.masthead-subtitle {
  color: var(--muted);
  font-family: var(--sans);
  font-size: 13px;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  margin: 8px 0 0;
}

.subscribe-links {
  display: flex;
  justify-content: center;
  flex-wrap: wrap;
  gap: 14px;
  margin: 10px 0 0;
  font-family: var(--sans);
  font-size: 11px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

.subscribe-link {
  color: var(--muted);
  text-decoration: none;
  border-bottom: 1px solid var(--rule);
  padding-bottom: 1px;
}

.subscribe-link:hover,
.subscribe-link:focus {
  color: var(--ink);
  border-bottom-color: var(--ink);
  outline: none;
}

/* task-T2.2: Masthead email signup (Buttondown + stub fallback). */
.signup-form {
  max-width: 520px;
  margin: 16px auto 0;
  text-align: left;
  font-family: var(--sans);
}

.signup-form-label {
  display: block;
  font-size: 11px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 6px;
  text-align: center;
}

.signup-form-row {
  display: flex;
  gap: 8px;
}

.signup-form-input {
  flex: 1;
  padding: 10px 14px;
  font-family: var(--sans);
  font-size: 14px;
  line-height: 1.4;
  color: var(--ink);
  background: var(--bg);
  border: 1px solid var(--chip-border);
  border-radius: 3px;
  -webkit-appearance: none;
  appearance: none;
}

.signup-form-input:focus {
  outline: 2px solid var(--accent);
  outline-offset: -2px;
}

.signup-form-button {
  padding: 10px 18px;
  font-family: var(--sans);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--chip-active-ink);
  background: var(--chip-active-bg);
  border: 1px solid var(--chip-active-bg);
  border-radius: 3px;
  cursor: pointer;
}

.signup-form-button:hover,
.signup-form-button:focus {
  background: var(--ink);
  border-color: var(--ink);
  outline: none;
}

.signup-form-status {
  min-height: 1.2em;
  margin-top: 8px;
  font-size: 12px;
  color: var(--muted);
  text-align: center;
}

.signup-form-status.is-success { color: var(--hi); }
.signup-form-status.is-error { color: var(--lo); }
.signup-form-status.is-pending { color: var(--muted); }

@media (max-width: 480px) {
  .signup-form-row { flex-direction: column; }
  .signup-form-button { width: 100%; }
}

.search-wrap {
  position: relative;
  max-width: 520px;
  margin: 20px auto 0;
  text-align: left;
}

#event-search {
  width: 100%;
  padding: 10px 14px;
  font-family: var(--sans);
  font-size: 14px;
  line-height: 1.4;
  color: var(--ink);
  background: var(--bg);
  border: 1px solid var(--chip-border);
  border-radius: 3px;
  -webkit-appearance: none;
  appearance: none;
}

#event-search:focus {
  outline: 2px solid var(--accent);
  outline-offset: -2px;
}

.search-suggestions {
  position: absolute;
  top: calc(100% + 4px);
  left: 0;
  right: 0;
  margin: 0;
  padding: 4px 0;
  list-style: none;
  background: var(--bg);
  border: 1px solid var(--rule);
  border-radius: 3px;
  box-shadow: 0 6px 24px rgba(0, 0, 0, 0.08);
  max-height: 50vh;
  overflow-y: auto;
  z-index: 50;
  text-align: left;
}

.search-suggestions[hidden] {
  display: none;
}

.suggestion-group {
  font-family: var(--sans);
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--muted);
  padding: 10px 14px 4px;
  margin-top: 4px;
  border-top: 1px solid var(--rule);
}

.suggestion-group:first-child {
  margin-top: 0;
  border-top: none;
}

.suggestion {
  padding: 8px 14px;
  cursor: pointer;
  font-family: var(--sans);
  font-size: 14px;
  color: var(--ink);
}

.suggestion:hover,
.suggestion.is-active {
  background: var(--accent-soft);
}

.suggestion-empty {
  padding: 10px 14px;
  font-family: var(--sans);
  font-size: 13px;
  color: var(--muted);
  text-align: center;
}

/* task-T8.1: Filter bar — category + time chips.
   Sticky on mobile so users always have access. */
.filter-bar {
  max-width: var(--max);
  margin: 1em auto 0;
  padding: 0 1em;
}
.filter-row {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-bottom: 8px;
}
.filter-chip {
  font-family: var(--sans);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.04em;
  padding: 7px 14px;
  background: transparent;
  border: 1px solid var(--chip-border);
  border-radius: 999px;
  color: var(--chip-ink);
  cursor: pointer;
  transition: background-color 0.15s ease, border-color 0.15s ease, color 0.15s ease;
  white-space: nowrap;
  min-height: 36px;
}
.filter-chip:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
@media (hover: hover) {
  .filter-chip:hover { border-color: var(--ink); }
}
.filter-chip.is-active {
  background: var(--chip-active-bg);
  border-color: var(--chip-active-bg);
  color: var(--chip-active-ink);
}
@media (max-width: 480px) {
  .filter-bar { position: sticky; top: 0; z-index: 5; background: var(--bg); margin: 0 auto; padding: 8px 1em; border-bottom: 1px solid var(--rule); }
  .filter-row { gap: 6px; margin-bottom: 6px; }
  .filter-chip { font-size: 11px; padding: 6px 10px; }
}

@media (max-width: 480px) {
  .search-wrap {
    max-width: 100%;
    margin-left: 4px;
    margin-right: 4px;
  }
}

.picks-section, .listings {
  max-width: var(--max);
  margin: 2em auto;
  padding: 0 1em;
}

.picks-heading, .listings-heading {
  font-family: var(--sans);
  font-size: 12px;
  font-weight: 800;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--ink);
  margin: 0 0 1em;
  padding: 12px 0;
  border-top: 3px solid var(--ink);
  border-bottom: 1px solid var(--rule);
}

.picks-list {
  list-style: none;
  margin: 0;
  padding: 0;
  counter-reset: pick;
  border: 1px solid var(--rule);
}

.pick-item {
  counter-increment: pick;
  display: grid;
  grid-template-columns: 40px 72px 1fr;
  gap: 14px;
  align-items: center;
  padding: 14px 16px;
  border-bottom: 1px solid var(--rule);
}
.pick-item:last-child { border-bottom: none; }
.pick-item::before {
  content: counter(pick);
  font-family: var(--sans);
  font-weight: 800;
  font-size: 16px;
  color: var(--muted);
}

.pick-rating, .event-rating-badge {
  text-align: center;
  font-family: var(--sans);
  font-weight: 800;
  font-size: 12px;
  padding: 6px 8px;
  border-radius: 3px;
  color: #fff;
  white-space: nowrap;
  /* task-5.6: Inter's tabular figures keep "10/10" and "7/10" the same width
     so rating columns align across cards — primary reason for choosing Inter
     over the prior Helvetica fallback (see docs/TYPOGRAPHY.md). */
  font-feature-settings: "tnum" 1, "cv01" 1;
}

.pick-rating--high, .rating-high { background: var(--hi); }
.pick-rating--mid, .rating-mid { background: var(--mid); }
.pick-rating--low, .rating-low { background: var(--lo); }

/* Cards for categories we do not score (everything but film).

   No badge, so the header reclaims the 72px rating column. A rule down the
   left edge replaces the badge as the card's visual anchor, otherwise the row
   reads as a film card with a missing score rather than a deliberately
   different kind of listing. */
.event-card-unscored {
  border-left: 3px solid var(--accent);
}

.event-card-unscored .event-header {
  grid-template-columns: 1fr 28px;
}

/* How long is left on a run - the useful, knowable fact that stands in for a
   score on an exhibition. Emphasised only when the show is nearly down. */
.event-run-note {
  font-family: var(--sans);
  font-size: 11px;
  letter-spacing: 0.02em;
  color: var(--muted);
  white-space: nowrap;
}

.event-run-note::before {
  content: " · ";
  color: var(--muted);
}

.event-run-note.is-closing-soon {
  color: var(--lo);
  font-weight: 700;
}

.pick-title { font-size: 16px; font-weight: 600; }
.pick-title a { color: var(--ink); text-decoration: none; border-bottom: 2px solid var(--accent); }

.pick-meta {
  grid-column: 3;
  font-family: var(--sans);
  font-size: 12px;
  color: var(--muted);
  margin-top: 4px;
}

.event-card {
  border: 1px solid var(--rule);
  margin-bottom: 1em;
  background: var(--bg);
}

.event-header {
  display: grid;
  grid-template-columns: 72px 1fr 28px;
  gap: 14px;
  align-items: center;
  padding: 14px 16px;
  cursor: pointer;
}
.event-header:hover { background: var(--accent-soft); }
.event-header:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }

.event-title-text {
  font-family: var(--serif);
  font-size: var(--text-md);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: -0.01em;
  margin-bottom: 4px;
}

.event-title-link { color: var(--ink); text-decoration: none; border-bottom: 2px solid var(--accent); }

.event-subtitle {
  font-family: var(--sans);
  font-size: 12px;
  color: var(--muted);
}

.event-when {
  font-family: var(--sans);
  font-size: 12px;
  color: var(--muted);
  margin-top: 2px;
  letter-spacing: 0.01em;
}

/* task-T3.1: venue street address rendered under the subtitle on the
   card face so logistics-focused users can see where to go without
   expanding the review panel. */
.event-venue-address {
  font-family: var(--sans);
  font-size: 11px;
  color: var(--muted);
  margin-top: 2px;
  letter-spacing: 0.01em;
  font-style: italic;
}

/* task-T3.4: "Because you liked X" annotation on re-ranked picks.
   Sits under the subtitle so it is visible without expanding. Uses
   accent color to mark it as a personalized signal, lighter weight
   to keep the title dominant. */
.because-you-liked {
  font-family: var(--sans);
  font-size: 11px;
  font-weight: 500;
  color: var(--accent);
  margin-top: 4px;
  letter-spacing: 0.02em;
  font-style: italic;
}
.because-you-liked::before {
  content: "★ ";
  font-style: normal;
  margin-right: 2px;
}

.expand-indicator {
  color: var(--muted);
  transition: transform 0.2s;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
/* task-T3: inline SVG chevron replaces the prior triangle glyph; the
   size below holds the chevron at a similar visual weight to the old
   16px text triangle and inherits color via stroke="currentColor". */
.expand-indicator svg { width: 14px; height: 14px; display: block; }
.event-card.is-expanded .expand-indicator { transform: rotate(90deg); color: var(--accent); }

.event-panel {
  max-height: 0;
  overflow: hidden;
  padding: 0 16px 0 102px;
  transition: max-height 0.3s, padding 0.3s;
}
.event-card.is-expanded .event-panel {
  max-height: 2000px;
  padding: 14px 16px 18px 102px;
  border-top: 1px solid var(--rule);
}

.picks-list.top-picks { counter-reset: pick; }
.picks-list.top-picks .event-card {
  counter-increment: pick;
  margin-bottom: 0;
  border: none;
  border-bottom: 1px solid var(--rule);
}
.picks-list.top-picks .event-card:last-child { border-bottom: none; }
.picks-list.top-picks .event-card .event-header {
  grid-template-columns: 40px 72px 1fr 28px;
}

/* Same card without the rating column. Needs to beat the rule above on
   specificity, otherwise the title is squeezed into the vacated 72px.
   The rank counter goes too: in an urgency-ordered list a big "1" next to the
   first item reads as "best", which is the exact claim we stopped making. */
.picks-list.top-picks .event-card.event-card-unscored .event-header {
  grid-template-columns: 1fr 28px;
}
.picks-list.top-picks .event-card.event-card-unscored .event-header::before {
  content: none;
}
.picks-list.top-picks .event-card .event-header::before {
  content: counter(pick);
  font-family: var(--sans);
  font-weight: 800;
  font-size: 16px;
  color: var(--muted);
  text-align: center;
}
.picks-list.top-picks .event-card.is-open .expand-indicator {
  transform: rotate(90deg);
  color: var(--accent);
}
/* The 126px indent aligns the panel under the title column, past the rank and
   rating cells. Neither exists on an unscored card, so it indents to nothing. */
.picks-list.top-picks .event-card.event-card-unscored.is-open .event-panel {
  padding-left: 16px;
}
.picks-list.top-picks .event-card.is-open .event-panel {
  max-height: 2000px;
  padding: 14px 16px 18px 126px;
  border-top: 1px solid var(--rule);
}

/* task-T3.4: clamp the card-face one-liner to 2 lines so long hooks
   do not push the card into a tall block; expanding the card restores
   the full text. Uses -webkit-line-clamp with display:-webkit-box,
   the widely-supported recipe across Safari/Chrome/Firefox. */
.event-oneliner { -webkit-line-clamp: 2; line-clamp: 2;
  font-style: italic;
  color: #5a4a3a;
  font-weight: 500;
  margin: 0 0 12px;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.event-card.is-expanded .event-oneliner,
.event-card.is-open .event-oneliner {
  -webkit-line-clamp: initial;
  line-clamp: initial;
  display: block;
  overflow: visible;
}

.event-review {
  max-width: 70ch;
}

.event-review-section {
  margin-top: 1.2em;
}

.event-review-section.event-review-first {
  margin-top: 0;
}

.event-review h3,
.event-review h4,
.event-review-heading,
.event-review strong {
  font-family: var(--sans);
  font-weight: 700;
  font-size: 13px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink);
  margin: 0 0 0.4em;
  line-height: 1.3;
}

.event-review-emoji {
  margin-right: 0.25em;
}

.event-review p,
.event-review-body {
  font-size: 15px;
  line-height: 1.7;
  margin: 0 0 0.8em;
  max-width: 70ch;
}

/* task-T8.7: rich-text formatting inside review body paragraphs */
.event-review-body strong {
  font-weight: 700;
  color: var(--ink);
}
.event-review-body em {
  font-style: italic;
  color: #5a4a3a;
}

/* task-T3.2: primary "Get Tickets" CTA inside the expanded panel. Sits above
   .event-actions so logistics-focused users can reach the venue's ticketing
   URL without scanning past the review body. Uses the site accent as a
   filled button so it reads as the panel's primary action. */
.event-ticket-link {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-family: var(--sans);
  font-size: 14px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-decoration: none;
  color: #fff;
  background: var(--ink);
  border: 1px solid var(--ink);
  border-radius: 999px;
  padding: 12px 20px;
  min-height: 44px;
  margin: 4px 0 12px;
  transition: background-color 0.15s ease, border-color 0.15s ease, color 0.15s ease, transform 0.1s ease;
}
.event-ticket-link:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
@media (hover: hover) {
  .event-ticket-link:hover {
    background: var(--accent);
    border-color: var(--accent);
    color: var(--ink);
  }
}
.event-ticket-link:active {
  transform: scale(0.98);
}

/* task-T3.1: thumbs up/down taste controls — persisted to localStorage.cc_taste.
   Lives inside .event-actions beside the read-aloud button. */
.event-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 16px;
  margin-top: 16px;
}
.thumb-controls {
  display: inline-flex;
  gap: 8px;
}
.thumb-button {
  font-family: var(--sans);
  font-size: 18px;
  line-height: 1;
  background: transparent;
  border: 1px solid var(--rule);
  border-radius: 999px;
  padding: 0;
  width: 44px;
  height: 44px;
  min-width: 44px;
  min-height: 44px;
  cursor: pointer;
  color: var(--ink);
  transition: background-color 0.15s ease, border-color 0.15s ease, color 0.15s ease, transform 0.1s ease;
}
.thumb-button:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
@media (hover: hover) {
  .thumb-button:hover {
    border-color: var(--ink);
  }
}
.thumb-button:active {
  transform: scale(0.96);
}
.thumb-button.is-active {
  background: var(--accent-soft);
  border-color: var(--accent);
  color: var(--ink);
}
.thumb-up.is-active { border-color: var(--hi); background: #e9f3e9; }
.thumb-down.is-active { border-color: var(--lo); background: #f6e6e6; }

/* task-T3.2: save (star) button — shares pill geometry with .thumb-button
   so it flows naturally inside .thumb-controls. Saved state uses a warm
   amber fill distinct from the green/red thumb states. */
.save-button {
  font-family: var(--sans);
  font-size: 22px;
  line-height: 1;
  background: transparent;
  border: 1px solid var(--rule);
  border-radius: 999px;
  padding: 0;
  width: 44px;
  height: 44px;
  min-width: 44px;
  min-height: 44px;
  cursor: pointer;
  color: var(--ink);
  transition: background-color 0.15s ease, border-color 0.15s ease, color 0.15s ease, transform 0.1s ease;
}
.save-button:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
@media (hover: hover) {
  .save-button:hover {
    border-color: var(--ink);
  }
}
.save-button:active {
  transform: scale(0.96);
}
.save-button.is-saved {
  background: #fff6d9;
  border-color: #c9a227;
  color: #a6831d;
}

/* task-T3.2: My Picks filter toggle — injected into masthead after
   .search-wrap. Active state uses the site accent-soft to signal that
   the listing has been narrowed. */
.my-picks-toggle-wrap {
  margin-top: 10px;
  display: flex;
  justify-content: flex-end;
}
.my-picks-toggle {
  font-family: var(--sans);
  font-size: 14px;
  line-height: 1;
  padding: 10px 16px;
  min-height: 40px;
  background: transparent;
  border: 1px solid var(--rule);
  border-radius: 999px;
  color: var(--ink);
  cursor: pointer;
  transition: background-color 0.15s ease, border-color 0.15s ease;
}
.my-picks-toggle:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
@media (hover: hover) {
  .my-picks-toggle:hover {
    border-color: var(--ink);
  }
}
.my-picks-toggle.is-active {
  background: var(--accent-soft);
  border-color: var(--accent);
}

/* task-T1.5: Web Speech API read-aloud button inside expanded review panels */
.event-tts-slot {
  margin-top: 0;
}
.tts-button {
  font-family: var(--sans);
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.04em;
  color: var(--accent);
  background: transparent;
  border: 1px solid var(--accent);
  border-radius: 999px;
  padding: 10px 18px;
  min-height: 44px;
  min-width: 44px;
  cursor: pointer;
  transition: background-color 0.15s ease, color 0.15s ease;
}
.tts-button:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
@media (hover: hover) {
  .tts-button:hover {
    background: var(--accent);
    color: #fff;
  }
}
.tts-button:active,
.tts-button.is-playing {
  background: var(--accent);
  color: #fff;
}

/* task-T4.2: Audio brief button. Lives in the picks-section header; reuses
   .tts-button styling so it matches the per-card Read-aloud control. */
.audio-brief-button {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin: 0 0 1em;
}

/* task-T6.3: Share this pick button + inline fallback popover.
   Button lives in .event-actions beside the Read-aloud + taste controls.
   Popover renders only when navigator.share is unavailable. */
.event-share-slot {
  position: relative;
  display: inline-flex;
}
.share-button {
  font-family: var(--sans);
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.04em;
  color: var(--ink);
  background: transparent;
  border: 1px solid var(--rule);
  border-radius: 999px;
  padding: 10px 18px;
  min-height: 44px;
  min-width: 44px;
  cursor: pointer;
  transition: background-color 0.15s ease, border-color 0.15s ease, color 0.15s ease;
}
.share-button:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
@media (hover: hover) {
  .share-button:hover {
    border-color: var(--ink);
    background: var(--accent-soft);
  }
}
.share-button[aria-expanded="true"] {
  background: var(--accent-soft);
  border-color: var(--accent);
}
/* task-T1.1: popover hosts 9 platforms (twitter, threads, bluesky,
   mastodon, linkedin, whatsapp, sms, email, copy). Flex column with a
   max-height + scroll for narrow viewports; 2-col grid on wider screens
   to keep the menu compact without pushing the page layout. */
.share-popover {
  position: absolute;
  top: calc(100% + 6px);
  left: 0;
  z-index: 10;
  display: flex;
  flex-direction: column;
  min-width: 200px;
  max-width: min(92vw, 360px);
  max-height: min(70vh, 440px);
  overflow-y: auto;
  padding: 6px;
  background: var(--bg);
  border: 1px solid var(--rule);
  border-radius: 10px;
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.08);
}
@media (min-width: 520px) {
  .share-popover {
    display: grid;
    grid-template-columns: 1fr 1fr;
    column-gap: 4px;
    row-gap: 2px;
  }
  .share-popover .share-option-copy { grid-column: 1 / -1; }
}
/* task-T1.3: 375px polish. Share button can sit near the right edge of an
   event card, so anchor the popover to its right edge to prevent overflow
   past the viewport on iPhone SE / 375px widths. Bump option touch targets
   to the 44px iOS minimum and widen the menu for thumb-friendly tapping. */
@media (max-width: 420px) {
  .share-popover {
    left: auto;
    right: 0;
    min-width: 240px;
    max-width: calc(100vw - 24px);
    padding: 8px;
  }
  .share-option {
    font-size: 15px;
    min-height: 44px;
    padding: 12px 14px;
  }
}
.share-option {
  font-family: var(--sans);
  font-size: 14px;
  color: var(--ink);
  background: transparent;
  border: 0;
  border-radius: 6px;
  padding: 10px 12px;
  text-align: left;
  text-decoration: none;
  cursor: pointer;
  min-height: 40px;
  display: flex;
  align-items: center;
  gap: 8px;
  white-space: nowrap;
}
.share-option:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
@media (hover: hover) {
  .share-option:hover {
    background: var(--accent-soft);
  }
}

.empty-state {
  padding: 24px;
  text-align: center;
  color: var(--muted);
  font-family: var(--sans);
  font-size: 14px;
}

.status {
  max-width: var(--max);
  margin: 24px auto;
  text-align: center;
  color: var(--muted);
  font-family: var(--sans);
  padding: 0 1em;
}
.status.error { color: var(--lo); }

@media (max-width: 480px) {
  /* task-5.5: masthead-title and event-title-text font-sizes now flow from
     clamp() in :root, so no per-breakpoint pixel override needed here. */
  .event-header { grid-template-columns: 64px 1fr 24px; gap: 10px; padding: 12px; }
  /* Mobile: drop the deep left indent under the rating column so review
     text uses the full viewport width — desktop alignment trades too much
     readable width on a 375px phone. */
  .event-panel, .event-card.is-expanded .event-panel { padding-left: 16px; padding-right: 16px; }
  .picks-list.top-picks .event-card .event-header { grid-template-columns: 28px 64px 1fr 24px; gap: 10px; padding: 12px; }
  .picks-list.top-picks .event-card.is-open .event-panel { padding-left: 16px; padding-right: 16px; }
  /* Mobile: bump body + heading sizes so reviews are comfortable to read. */
  .event-review p, .event-review-body { font-size: 16px; line-height: 1.65; }
  .event-review h3, .event-review h4, .event-review-heading, .event-review strong { font-size: 14px; }
  /* Mobile: never clamp the one-liner — vertical space is cheap on phones
     and truncation looks broken. Wrap long tokens instead of overflowing. */
  .event-oneliner {
    -webkit-line-clamp: initial;
    line-clamp: initial;
    display: block;
    overflow: visible;
    overflow-wrap: anywhere;
    word-break: break-word;
    font-size: 16px;
  }
}

@media (prefers-reduced-motion: reduce) {
  .expand-indicator, .event-panel { transition: none; }
}

/* About section — collapsible methodology at page bottom */
.about-section {
  max-width: var(--max);
  margin: 48px auto 32px;
  padding: 0 1em;
}
.about-details {
  border-top: 1px solid var(--rule);
  border-bottom: 1px solid var(--rule);
  padding: 16px 0;
}
.about-summary {
  font-family: var(--sans);
  font-size: 13px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--muted);
  cursor: pointer;
  list-style: none;
  padding: 8px 0;
}
.about-summary::-webkit-details-marker { display: none; }
.about-summary::after {
  content: " +";
  color: var(--muted);
}
.about-details[open] .about-summary::after {
  content: " –";
}
.about-summary:hover,
.about-summary:focus-visible {
  color: var(--ink);
}
.about-body {
  font-family: var(--serif);
  font-size: 16px;
  line-height: 1.7;
  color: var(--ink);
  max-width: 65ch;
  margin: 24px 0 16px;
}
.about-body p {
  margin: 0 0 24px;
}
.about-heading {
  font-family: var(--sans);
  font-size: 13px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--muted);
  margin: 32px 0 8px;
  font-weight: 600;
}
.about-heading:first-child {
  margin-top: 0;
}
.about-list {
  margin: 0 0 24px;
  padding-left: 32px;
}
.about-list li {
  margin-bottom: 8px;
}

/* task-T2.5: low-confidence "Pending more research" section */
.needs-research-section {
  max-width: var(--max);
  margin: 2em auto;
  padding: 16px 20px;
  border: 1px dashed var(--rule);
  border-radius: 4px;
  background: #fafafa;
  opacity: 0.85;
  font-family: var(--sans);
}
.needs-research-section[open] {
  opacity: 1;
}
.needs-research-summary {
  cursor: pointer;
  font-size: 12px;
  font-weight: 800;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--muted);
  list-style: none;
  padding: 4px 0;
}
.needs-research-summary::-webkit-details-marker {
  display: none;
}
.needs-research-summary::before {
  content: "▸ ";
  display: inline-block;
  margin-right: 4px;
  transition: transform 0.15s ease;
}
.needs-research-section[open] > .needs-research-summary::before {
  content: "▾ ";
}
.needs-research-body {
  margin-top: 16px;
  font-family: var(--serif);
}
.needs-research-empty {
  margin: 0;
  color: var(--muted);
  font-style: italic;
  font-size: 14px;
}
.needs-research-body .event-card {
  opacity: 0.95;
}
@media (max-width: 640px) {
  .needs-research-section {
    margin-left: 12px;
    margin-right: 12px;
  }
}

/* task-T2.3: subscribed / unsubscribed landing pages */
.landing-main {
  max-width: 640px;
  margin: 0 auto;
  padding: 48px 20px 64px;
}
.landing-message {
  text-align: center;
}
.landing-heading {
  font-family: var(--serif);
  font-size: var(--text-lg);
  font-weight: 700;
  letter-spacing: -0.01em;
  margin: 0 0 16px;
}
.landing-lead {
  color: var(--muted);
  font-size: 16px;
  line-height: 1.6;
  margin: 0 0 12px;
}
.landing-actions {
  display: flex;
  justify-content: center;
  flex-wrap: wrap;
  gap: 14px;
  margin-top: 24px;
  font-family: var(--sans);
  font-size: 11px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}
.landing-link {
  color: var(--muted);
  text-decoration: none;
  border-bottom: 1px solid var(--rule);
  padding-bottom: 1px;
}
.landing-link:hover,
.landing-link:focus {
  color: var(--ink);
  border-bottom-color: var(--accent);
}

/* task-T8.4: category grouping sections */
.category-section {
  margin-bottom: 2.5em;
}

/* task-T8.5: mobile hardening */
@media (max-width: 480px) {
  .filter-bar { position: sticky; top: 0; z-index: 5; background: var(--bg); margin: 0 auto; padding: 8px 1em; border-bottom: 1px solid var(--rule); }
  .filter-row { gap: 6px; margin-bottom: 6px; }
  .filter-chip { font-size: 11px; padding: 6px 10px; }
  .event-header { grid-template-columns: 64px 1fr 24px; gap: 10px; padding: 12px; }
  .event-panel, .event-card.is-expanded .event-panel { padding-left: 16px; padding-right: 16px; }
  .picks-list.top-picks .event-card .event-header { grid-template-columns: 28px 64px 1fr 24px; gap: 10px; padding: 12px; }
  .picks-list.top-picks .event-card.is-open .event-panel { padding-left: 16px; padding-right: 16px; }
  .event-review p, .event-review-body { font-size: 16px; line-height: 1.65; }
  .event-review h3, .event-review h4, .event-review-heading, .event-review strong { font-size: 14px; }
  .event-oneliner {
    -webkit-line-clamp: initial;
    line-clamp: initial;
    display: block;
    overflow: visible;
    overflow-wrap: anywhere;
    word-break: break-word;
    font-size: 16px;
  }
}

@media (max-width: 320px) {
  .event-header { grid-template-columns: 56px 1fr 32px; gap: 8px; padding: 10px; }
  .event-panel, .event-card.is-expanded .event-panel { padding-left: 72px; padding-right: 10px; }
  .subscribe-links { gap: 10px; font-size: 10px; }
  #event-search { font-size: 13px; padding: 9px 40px 9px 12px; }
}
