/* IBM Plex Sans is loaded from the Google Fonts CDN; see the <link> tags in
   index.html. Weights used: 400/500/600/700. */

/* ------------------------------------------------------------------ tokens */

:root {
  color-scheme: light;
  --bg: #f7f6f4;
  --surface: #ffffff;
  --surface-2: #efedf3;
  --border: #e5e2ea;
  --border-strong: #cfcad9;
  --ink: #201d29;
  --muted: #6b6779;
  --faint: #a19db0;
  --accent: #6747c7;
  --accent-hover: #54379f;
  --accent-ink: #ffffff;
  --accent-soft: #efeaf9;
  --star: #d9930d;
  --badge-con-bg: #e9e7f6; /* constructed formats */
  --badge-con-ink: #5a4f93;
  --badge-lim-bg: #f3ecd9; /* limited formats */
  --badge-lim-ink: #8a6c2a;
  --shadow: 0 1px 2px rgba(25, 20, 40, 0.05), 0 2px 8px rgba(25, 20, 40, 0.04);
  --ring: #6747c766;
  --r-ctl: 8px;   /* inputs, buttons, chips-adjacent controls */
  --r-card: 12px; /* cards and panels */
  --mono: "IBM Plex Mono", ui-monospace, "SF Mono", Menlo, monospace;
}

:root[data-theme="dark"] {
  color-scheme: dark;
  --bg: #15131a;
  --surface: #1e1b26;
  --surface-2: #292433;
  --border: #343040;
  --border-strong: #4a4459;
  --ink: #eae7f1;
  --muted: #a5a0b4;
  --faint: #726d82;
  --accent: #a489f5;
  --accent-hover: #b9a5f8;
  --accent-ink: #1d1430;
  --accent-soft: #2c2440;
  --star: #eab308;
  --badge-con-bg: #2e2a44;
  --badge-con-ink: #b3a8e8;
  --badge-lim-bg: #393222;
  --badge-lim-ink: #d8b86a;
  --shadow: 0 1px 2px rgba(0, 0, 0, 0.4);
  --ring: #a489f580;
}

/* ------------------------------------------------------------------- base */

* { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  font-family: "IBM Plex Sans", system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  font-variant-numeric: tabular-nums;
  background: var(--bg);
  color: var(--ink);
  line-height: 1.45;
}

.container {
  max-width: 880px;
  margin: 0 auto;
  padding: 0 20px;
}

a { color: var(--accent); text-decoration-color: color-mix(in srgb, var(--accent) 40%, transparent); }
a:hover { text-decoration-color: var(--accent); }

button { font: inherit; }

:focus-visible {
  outline: 2px solid var(--ring);
  outline-offset: 2px;
  border-radius: 4px;
}

/* ----------------------------------------------------------------- header */

header {
  background: var(--surface);
  border-bottom: 1px solid var(--border);
}

.header-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding-top: 10px;
  padding-bottom: 10px;
}

.brand { display: flex; align-items: center; gap: 10px; }
.brand-mark { width: 26px; height: 26px; color: var(--accent); flex: 0 0 auto; }
.brand h1 {
  margin: 0;
  font-size: 20px;
  font-weight: 700;
  letter-spacing: -0.02em;
}

.icon-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 40px;
  min-height: 40px;
  padding: 0 8px;
  border: 1px solid var(--border);
  border-radius: var(--r-ctl);
  background: var(--surface);
  color: var(--ink);
  cursor: pointer;
}
.icon-btn:hover { background: var(--surface-2); }
.icon-btn svg { width: 18px; height: 18px; }

#theme-toggle .sun { display: none; }
:root[data-theme="dark"] #theme-toggle .sun { display: block; }
:root[data-theme="dark"] #theme-toggle .moon { display: none; }

/* ---------------------------------------------------------- quick filters */

.quick-filters {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  margin: 20px 0 14px;
}

.chip {
  border: 1px solid var(--border-strong);
  background: var(--surface);
  color: var(--ink);
  border-radius: 999px;
  padding: 8px 16px;
  min-height: 38px;
  font-size: 14px;
  font-weight: 500;
  cursor: pointer;
  transition: background 0.12s, border-color 0.12s;
}
.chip:hover { background: var(--surface-2); }
.chip.active {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--accent-ink);
}

/* ------------------------------------------------------------ search form */

.search-panel {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-card);
  padding: 16px;
  box-shadow: var(--shadow);
}

.search-main,
.search-filters {
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  gap: 12px;
}

.f-location { grid-column: span 8; }
.f-within   { grid-column: span 4; }
.f-type     { grid-column: span 3; }
.f-format   { grid-column: span 3; }
.f-text     { grid-column: span 6; }

.within-wrap { display: flex; gap: 8px; }
.within-wrap select { flex: 1; min-width: 0; }

.label-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
}
.label-row label { margin-bottom: 5px; }

.unit-toggle { display: inline-flex; }
.unit-toggle button {
  font-family: inherit;
  font-size: 11px;
  font-weight: 600;
  line-height: 1;
  padding: 3px 8px;
  border: 1px solid var(--border-strong);
  background: var(--surface);
  color: var(--muted);
  cursor: pointer;
}
.unit-toggle button + button { margin-left: -1px; }
.unit-toggle button:first-child { border-radius: var(--r-ctl) 0 0 var(--r-ctl); }
.unit-toggle button:last-child { border-radius: 0 var(--r-ctl) var(--r-ctl) 0; }
.unit-toggle button:hover { background: var(--surface-2); }
.unit-toggle button[aria-pressed="true"] {
  background: var(--ink);
  border-color: var(--ink);
  color: var(--bg);
  position: relative;
}

.field label {
  display: block;
  font-size: 12px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--muted);
  margin-bottom: 5px;
}

.field input,
.field select {
  width: 100%;
  font-family: inherit; /* form controls don't inherit the body font */
  font-size: 16px; /* prevents iOS zoom-on-focus */
  padding: 9px 11px;
  min-height: 42px;
  border: 1px solid var(--border-strong);
  border-radius: var(--r-ctl);
  background: var(--surface);
  color: var(--ink);
}
.field input::placeholder { color: var(--faint); }

.loc-wrap { position: relative; }
.loc-wrap input { width: 100%; padding-right: 42px; }
/* The wrapper carries the absolute placement so its tooltip popover anchors
   to the button; the button itself sits static inside it. */
.locate-wrap {
  position: absolute;
  right: 4px;
  top: 50%;
  transform: translateY(-50%);
}
.loc-wrap .icon-btn {
  min-width: 34px;
  min-height: 34px;
  border: none;
  background: none;
  color: var(--muted);
}
.loc-wrap .icon-btn:hover { color: var(--ink); background: none; }
/* Instant "Use current location" label on hover, matching the address/fee
   popovers — no waiting on the browser's slow native title tooltip. */
@media (hover: hover) {
  .locate-wrap:hover .popover { display: block; }
}

.filters-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-top: 12px;
  padding: 7px 14px;
  min-height: 36px;
  border: 1px solid var(--border-strong);
  border-radius: var(--r-ctl);
  background: var(--surface);
  color: var(--muted);
  font-size: 13.5px;
  font-weight: 600;
  cursor: pointer;
}
.filters-btn:hover { background: var(--surface-2); color: var(--ink); }
.filters-btn.has-active { color: var(--ink); background: var(--surface-2); }
.filters-btn .chev { width: 13px; height: 13px; transition: transform 0.15s; }
.filters-btn .chev.open { transform: rotate(180deg); }

.search-filters { margin-top: 12px; }
.search-filters[hidden] { display: none; }

/* ---------------------------------------------------------------- results */

.status {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
  font-size: 14px;
  color: var(--muted);
  margin: 14px 2px 10px;
  min-height: 20px;
}
.status strong { color: var(--ink); font-weight: 600; }
.status-range {
  font-size: 13px;
  color: var(--faint);
  white-space: nowrap;
}
.status.error { color: #c62828; }
:root[data-theme="dark"] .status.error { color: #ef9a9a; }

.results { display: flex; flex-direction: column; }
.empty { color: var(--muted); padding: 14px 2px; }

/* Day headers rule the list like a printed schedule: mono small-caps over a
   hairline, sticky so the date stays in view while scrolling its events. */
.day-header {
  position: sticky;
  top: 0;
  z-index: 2;
  margin: 26px 0 0;
  padding: 8px 14px 6px;
  background: var(--bg);
  border-bottom: 1px solid var(--border-strong);
  font-family: var(--mono);
  font-size: 12px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  color: var(--muted);
}

/* Events are rows in a list: a fixed mono time column, the event itself, and
   a right-aligned fee column. A subtle zebra (alt rows lift to the surface
   tone, toggled per day in app.js) carries the rhythm — no rules between rows,
   and no hover highlight since the row itself isn't clickable. */
.event-row {
  display: flex;
  gap: 14px;
  align-items: flex-start;
  padding: 14px 14px 13px;
}
.event-row.alt { background: var(--surface); }

.event-time {
  flex: 0 0 64px;
  padding-top: 3px;
  text-align: right;
  font-family: var(--mono);
  font-size: 12.5px;
  font-weight: 500;
  color: var(--ink);
  white-space: nowrap;
}

.event-body { flex: 1; min-width: 0; }
/* Title and badges share one inline flow, so the pills trail the title's last
   word — even when a long title wraps to a second line — instead of dropping
   onto their own row. */
.title-row {
  margin-bottom: 5px;
}
.event-title {
  display: inline;
  font-size: 15.5px;
  font-weight: 600;
  margin: 0;
  letter-spacing: -0.005em;
  overflow-wrap: anywhere;
}

.badges {
  display: inline-flex;
  gap: 6px;
  flex-wrap: wrap;
  vertical-align: middle;
  margin-left: 8px;
}
.badge {
  font-size: 11.5px;
  font-weight: 600;
  padding: 2.5px 9px;
  border-radius: 999px;
  background: var(--surface-2);
  color: var(--muted);
}
.badge.rcq { background: var(--accent); color: var(--accent-ink); }
.badge.constructed { background: var(--badge-con-bg); color: var(--badge-con-ink); }
.badge.limited { background: var(--badge-lim-bg); color: var(--badge-lim-ink); }

.event-meta {
  font-size: 13px;
  color: var(--muted);
  line-height: 1.5;
  overflow-wrap: anywhere;
}
.event-meta strong { color: var(--ink); font-weight: 600; }
/* WPN Premium stores get the accent; a hover popover explains why. */
.event-meta strong.premium { color: var(--accent); }
/* Store links read as text with a quiet underline, not accent-coloured —
   the accent is reserved for primary actions. */
.event-meta a { color: inherit; text-decoration-color: var(--border-strong); }
.event-meta a:hover { text-decoration-color: var(--ink); }

.dist-wrap { position: relative; display: inline-block; }
.distance {
  background: none;
  border: none;
  padding: 0;
  font: inherit;
  color: inherit;
  cursor: pointer;
  text-decoration: underline dotted;
  text-underline-offset: 3px;
}
/* The outer .popover carries an invisible padding bridge over the gap, so
   the cursor can travel from the distance text up into the popover without
   leaving the hover area. The inner element is the visible box. */
.popover {
  display: none;
  position: absolute;
  bottom: 100%;
  left: 50%;
  /* --shift is set by clampPopover() in app.js to keep the box on screen
     when centring would push it past a viewport edge. */
  transform: translateX(calc(-50% + var(--shift, 0px)));
  z-index: 5;
  width: max-content;
  /* Wide enough that a full street address stays on one line; wrapping
     only kicks in when the viewport itself can't fit it. */
  max-width: min(520px, calc(100vw - 40px));
  padding-bottom: 8px;
}
.popover-inner {
  display: block;
  padding: 8px 12px;
  background: var(--surface);
  border: 1px solid var(--border-strong);
  border-radius: var(--r-ctl);
  box-shadow: var(--shadow);
  font-size: 13px;
  line-height: 1.4;
}
@media (hover: hover) {
  .dist-wrap:hover .popover { display: block; }
}
.dist-wrap.open .popover { display: block; }
/* The calendar chooser opens on click only — no hover rule, since its
   entries are clickable and a menu shouldn't appear on a stray mouse pass. */
.cal-wrap.open .popover { display: block; }

.event-fee {
  white-space: nowrap;
  font-family: var(--mono);
  font-size: 13px;
  font-weight: 600;
  padding-top: 3px;
}

.star,
.cal {
  flex: 0 0 auto;
  background: none;
  border: none;
  cursor: pointer;
  line-height: 1;
  padding: 6px;
  margin: -3px -6px 0 -4px;
  color: var(--faint);
}
.star svg,
.cal svg { width: 18px; height: 18px; display: block; }
.star:hover { color: var(--star); }
.star.active { color: var(--star); }
.star.active svg { fill: currentColor; }

/* Tuck the star in next to the calendar icon, inset from the row's edge
   (negative margin eats most of the row's flex gap between the pair). The
   wrapper carries the icon's flex placement so its chooser popover has a
   positioning context. */
.cal-wrap {
  position: relative;
  display: inline-flex;
  flex: 0 0 auto;
  margin: -3px -8px 0 -4px;
}
.cal-wrap .cal { margin: 0; }
.star { margin-right: 4px; }
.cal:hover { color: var(--ink); }

/* The add-to-calendar chooser: two stacked entries in a popover. */
.cal-menu .popover-inner {
  display: flex;
  flex-direction: column;
  padding: 5px;
}
.cal-menu a,
.cal-menu button {
  font: inherit;
  font-size: 13px;
  padding: 5px 10px;
  border: none;
  border-radius: 6px;
  background: none;
  color: var(--ink);
  text-align: left;
  text-decoration: none;
  cursor: pointer;
  white-space: nowrap;
}
.cal-menu a:hover,
.cal-menu button:hover { background: var(--surface-2); }

/* ------------------------------------------------------------- pagination */

.pagination {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 14px;
  margin: 0 0 12px;
  font-size: 14px;
  color: var(--muted);
}
.pagination:empty { display: none; }
.pagination button {
  min-height: 38px;
  padding: 7px 14px;
  border: 1px solid var(--border-strong);
  border-radius: var(--r-ctl);
  background: var(--surface);
  color: var(--ink);
  font-weight: 500;
  cursor: pointer;
}
.pagination button:hover:not(:disabled) { background: var(--surface-2); }
.pagination button:disabled { opacity: 0.45; cursor: default; }

/* ----------------------------------------------------------------- footer */

footer {
  padding: 28px 0 36px;
  color: var(--faint);
  font-size: 12.5px;
  text-align: center;
}
.footer-row {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
}
footer .bsky,
footer .kofi {
  display: inline-flex;
  color: var(--faint);
}
footer .bsky:hover,
footer .kofi:hover { color: var(--ink); }
footer .bsky svg { width: 15px; height: 15px; }
footer .kofi svg { width: 16px; height: 16px; }
/* The timestamp triggers the same popover as event distances; reset the
   button so it reads as inline text with a dotted underline. */
footer .timestamp {
  background: none;
  border: none;
  padding: 0;
  font: inherit;
  color: inherit;
  cursor: help;
  text-decoration: underline dotted;
  text-underline-offset: 3px;
}
.footer-links {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 16px;
  margin-top: 12px;
}
.footer-links .about-btn {
  display: inline-flex;
  padding: 0;
  border: 0;
  background: none;
  color: var(--faint);
  cursor: pointer;
}
.footer-links .about-btn:hover { color: var(--ink); }
.footer-links .about-btn svg { width: 16px; height: 16px; }

/* ------------------------------------------------------------------ modal */

.modal {
  width: calc(100% - 32px);
  max-width: 460px;
  padding: 0;
  border: 1px solid var(--border);
  border-radius: var(--r-card);
  background: var(--surface);
  color: var(--ink);
  box-shadow: var(--shadow);
}
.modal::backdrop {
  background: rgba(25, 20, 40, 0.5);
  backdrop-filter: blur(2px);
}
.modal-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 16px 18px;
  border-bottom: 1px solid var(--border);
}
.modal-head h2 {
  margin: 0;
  font-size: 17px;
  font-weight: 700;
  letter-spacing: -0.01em;
}
.modal-close {
  display: inline-flex;
  padding: 4px;
  border: 0;
  border-radius: var(--r-ctl);
  background: none;
  color: var(--faint);
  cursor: pointer;
}
.modal-close:hover { color: var(--ink); background: var(--surface-2); }
.modal-close svg { width: 18px; height: 18px; }
.modal-body {
  padding: 16px 18px 20px;
  font-size: 14px;
  line-height: 1.55;
  color: var(--muted);
}
.modal-body h3 {
  margin: 18px 0 6px;
  font-size: 13px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--ink);
}
.modal-body p { margin: 0; }
.modal-body a {
  color: var(--accent);
  text-decoration: underline;
  text-underline-offset: 2px;
}

/* ----------------------------------------------------------------- mobile */

@media (max-width: 680px) {
  .container { padding: 0 14px; }

  .header-row { padding-top: 8px; padding-bottom: 8px; }
  .brand-mark { width: 22px; height: 22px; }
  .brand h1 { font-size: 18px; }

  .search-panel { padding: 13px; }
  .search-main, .search-filters { gap: 10px; }
  .f-location { grid-column: span 12; }
  .f-within   { grid-column: span 12; }
  .f-type     { grid-column: span 6; }
  .f-format   { grid-column: span 6; }
  .f-text     { grid-column: span 12; }

  .event-row { gap: 10px; padding: 12px 14px 11px; flex-wrap: wrap; }
  .event-time { flex-basis: 56px; }
  .event-body { flex: 1 1 0; }
  /* The fee drops to its own line, aligned with the body text. */
  .event-fee { order: 3; width: 100%; padding: 2px 0 0 66px; }
}
