:root {
  --ink: #14213D;
  --paper: #F5F6F2;
  --accent: #FF4B3E;
  --muted: #6B7280;
  --border: #E2E4DD;
  --font-display: 'Oswald', sans-serif;
  --font-body: 'Inter', sans-serif;
  --font-mono: 'JetBrains Mono', monospace;
}
html { overflow-y: scroll; scrollbar-gutter: stable; }
* { box-sizing: border-box; }
body { margin: 0; background: var(--paper); color: var(--ink); font-family: var(--font-body); line-height: 1.5; }
.site-nav { display: flex; align-items: center; gap: 2rem; padding: 1.25rem 2rem; border-bottom: 1px solid var(--border); }
.site-nav .brand { font-family: var(--font-display); font-weight: 700; font-size: 1.5rem; text-transform: uppercase; }
.site-nav a { color: var(--ink); text-decoration: none; font-weight: 500; }
.site-nav a:hover { color: var(--accent); }
.container { max-width: 1100px; margin: 0 auto; padding: 2rem; }
h1, h2, h3 { font-family: var(--font-display); text-transform: uppercase; letter-spacing: 0.01em; }

/* city/month index lists → grid instead of a single tall column */
.place-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 0.75rem; list-style: none; padding: 0; }
.place-grid a { display: block; padding: 0.75rem 1rem; background: white; border: 1px solid var(--border); border-radius: 6px; color: var(--ink); text-decoration: none; font-weight: 500; }
.place-grid a:hover { border-color: var(--accent); color: var(--accent); }


.race-detail-distances__label {
  font-size: 0.7rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted);
  font-weight: 700;
  margin: 0.9rem 0 0.4rem;
}
.race-detail-distances { display: flex; flex-wrap: wrap; gap: 0.4rem; }


/* Breadcrumb: the only links above the fold on a phone, so they must look
   like links (blue, soft underline) and be easy to tap (padding). */
.breadcrumb-race { margin-bottom: 0.5rem; font-size: 0.9rem; }
.breadcrumb-race a {
  display: inline-block;
  padding: 0.3rem 0;
  color: #2563EB;
  text-decoration: underline;
  text-decoration-color: rgba(37, 99, 235, 0.35);
  text-underline-offset: 3px;
}
.breadcrumb-race a:hover { color: var(--accent); text-decoration-color: currentColor; }
.breadcrumb-race__sep { color: var(--muted); margin: 0 0.3rem; }

/* Race detail: card + related races on the left, "explore" links on the right.
   Stacks under 900px, so on mobile the links land below the related races. */
.race-layout { display: grid; grid-template-columns: minmax(0, 720px) 280px; gap: 1.5rem; justify-content: center; align-items: start; text-align: left; }
.race-layout__main { min-width: 0; }
.explore-links { background: white; border: 1px solid var(--border); border-radius: 10px; padding: 1.25rem; }
.explore-links h2 { font-size: 1.1rem; margin-bottom: 0.75rem; }
.explore-links li { padding: 0.5rem 0; border-bottom: 1px solid var(--border); }
.explore-links li:last-child { border-bottom: none; }
.explore-links a { color: var(--ink); font-weight: 500; font-size: 0.95rem; text-decoration: none; }
.explore-links a:hover { color: var(--accent); }
/* Breadcrumb only when the sidebar has dropped to the bottom of the page. */
.race-layout .breadcrumb-race { display: none; }
@media (max-width: 900px) {
  .race-layout { grid-template-columns: minmax(0, 1fr); }
  .race-layout .breadcrumb-race { display: block; }

  /* Stacked: order stays card → related races → "Zobacz więcej". The
     breadcrumb above the H1 already links up to city/region, so real races
     come next. "Zobacz więcej" becomes compact chips instead of a tall list. */
  .explore-links { padding: 0.9rem 1rem; }
  .explore-links h2 { font-size: 0.95rem; margin-bottom: 0.5rem; }
  .explore-links ul { display: flex; flex-wrap: wrap; gap: 0.4rem; }
  .explore-links li { padding: 0; border-bottom: none; }
  .explore-links a {
    display: inline-block;
    padding: 0.3rem 0.75rem;
    border: 1px solid var(--border);
    border-radius: 999px;
    font-size: 0.85rem;
    background: white;
  }
}

.race-card { background: white; border: 1px solid var(--border); border-top: 4px solid var(--accent); border-radius: 10px; padding: 2rem; max-width: 720px; width: 100%; }
/* Must come AFTER the base rule: same specificity, so the later one wins.
   It used to sit above it and never applied. */
@media (max-width: 480px) {
  .race-card { padding: 1.25rem; }
}


.related-races { max-width: 720px; width: 100%; text-align: left; }
.related-races h3 { font-size: 1.1rem; margin-bottom: 0.75rem; text-align: left; }
.related-races li { display: flex; flex-direction: column; gap: 0.35rem; padding: 0.4rem 0; border-bottom: 1px solid var(--border); }
.related-races li:last-child { border-bottom: none; }
.related-races__row { display: flex; justify-content: space-between; gap: 1rem; }
.related-races__date { color: var(--muted); font-size: 0.85rem; }
.related-races__note { color: var(--muted); font-size: 0.85rem; margin: 0 0 0.35rem; }
.related-races a { color: var(--ink); font-weight: 500; text-decoration: none; }
.related-races a:hover { color: var(--accent); }

/* Homepage hero */
.hero { text-align: center; padding: 3rem 1rem 2.5rem; }
.hero h1 { font-size: 2.75rem; margin-bottom: 0.5rem; }
.hero-stat { font-family: var(--font-mono); color: var(--muted); }

/* Upcoming races list */
.home-section { max-width: 640px; margin: 0 auto 2.5rem; text-align: left; }
.home-section h2 { margin-bottom: 1rem; }
.upcoming-list li {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  padding: 0.85rem 0;
  border-bottom: 1px solid var(--border);
}
.upcoming-list a { color: var(--ink); font-weight: 600; text-decoration: none; }
.upcoming-list a:hover { color: var(--accent); }

/* Homepage nav cards */
.home-nav-cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 1rem; max-width: 860px; margin: 0 auto 2rem; }
.nav-card { display: block; background: white; border: 1px solid var(--border); border-radius: 10px; padding: 1.5rem; text-decoration: none; color: var(--ink); text-align: left; }
.nav-card:hover { border-color: var(--accent); }
.nav-card h3 { font-size: 1.1rem; margin: 0 0 0.35rem; }
.nav-card p { margin: 0; color: var(--muted); font-size: 0.9rem; }

@media (max-width: 600px) {
  .home-nav-cards { grid-template-columns: 1fr; }
  .hero h1 { font-size: 2rem; }
}

.hero-sub { max-width: 480px; margin: 0.75rem auto 0; color: var(--muted); font-size: 0.95rem; }

/* Homepage hero: decorative course profile under the text. The SVG stretches
   to any width (preserveAspectRatio="none"); non-scaling-stroke keeps every
   line the same thickness while it does. */
.hero-profile { max-width: 640px; margin: 1.75rem auto 0; }
.hero-profile__labels { position: relative; height: 1.1rem; margin-bottom: 0.35rem; font-family: var(--font-mono); font-size: 0.75rem; text-transform: uppercase; color: var(--ink); }
.hero-profile__labels span { position: absolute; left: calc(var(--km) / 42.195 * 100%); transform: translateX(-50%); white-space: nowrap; }
.hero-profile__labels span:first-child { transform: none; }
.hero-profile__labels span:last-child { transform: translateX(-100%); }
.hero-profile svg { display: block; width: 100%; height: 72px; overflow: visible; }
.hero-profile path { vector-effect: non-scaling-stroke; }
.hero-profile__area { fill: var(--accent); fill-opacity: 0.08; }
.hero-profile__marks { stroke: var(--ink); stroke-opacity: 0.3; stroke-width: 1; stroke-dasharray: 2 3; }
.hero-profile__base { stroke: var(--border); stroke-width: 1; }
.hero-profile__line { fill: none; stroke: var(--accent); stroke-width: 2.5; stroke-linejoin: round; }
.hero-profile__dot-ring { stroke: var(--ink); stroke-width: 10; stroke-linecap: round; }
.hero-profile__dot { stroke: white; stroke-width: 6; stroke-linecap: round; }

.race-table { width: 100%; max-width: 1000px; margin: 0 auto; border-collapse: collapse; table-layout: fixed; background: white; border-radius: 10px; overflow: hidden; border: 1px solid var(--border); }
.race-table th { background: var(--ink); color: white; font-family: var(--font-display); text-transform: uppercase; font-size: 0.85rem; letter-spacing: 0.03em; padding: 0.85rem 1rem; text-align: left; }
.race-table td { padding: 0.75rem 1rem; border-top: 1px solid var(--border); font-size: 0.95rem; white-space: normal; overflow: visible; text-overflow: clip; text-align: left; }

/* DATE is the only column that should stay single-line — dates are a
   fixed, predictable length ("29 sierpnia 2026") and never need to wrap.
   Every other column (name, distance, city) wraps by default now; this is
   the one deliberate exception, not the other way around. */
.race-table td.date-cell { white-space: nowrap; }
.race-table tr:hover td { background: #FAFAF7; }
.race-table a { color: var(--ink); font-weight: 500; text-decoration: none; }
.race-table a:hover { color: var(--accent); }
.race-table td.past { color: var(--muted); }

/* --- Mobile: table becomes a stacked card list --------------------------- */
/* Below this width, 4 fixed-percentage columns don't leave room for
   unbreakable Polish words ("MIEJSCOWOŚĆ", "Warszawa") to render without
   overflowing sideways into the next column — browsers don't break a word
   mid-string by default, so a too-narrow column spills instead of wrapping.
   The fix isn't tighter columns, it's not having columns at all here: each
   row becomes its own card, each field stacks with a label pulled from
   data-label (set in _race_row.html) via ::before.

   Accessibility trade-off, noted rather than silently accepted: hiding
   <thead> removes it from the accessibility tree along with the visual
   removal. A fully accessible version would visually hide it instead
   (clip it off-screen rather than display:none) so screen readers still
   get the column context. Skipping that polish for now — flag if you want
   it done properly later. */
@media (max-width: 640px) {
  .race-table { max-width: 100%; }
  .race-table thead { display: none; }
  .race-table, .race-table tbody, .race-table tr, .race-table td {
    display: block;
    width: auto !important;
  }
  .race-table tr {
    border: 1px solid var(--border);
    border-radius: 8px;
    margin-bottom: 0.75rem;
    padding: 0.75rem 1rem;
  }
  .race-table tr:last-child { margin-bottom: 0; }

  .race-table td { border-top: none; padding: 0.3rem 0; }

  /* Race name reads as the card's title — bigger, bold, no label prefix
     (a card header doesn't need "Nazwa biegu:" in front of it). */
  .race-table td.name-cell { font-weight: 600; font-size: 1rem; padding-bottom: 0.5rem; }

  /* City and date: short single values, label + value side by side. */
  .race-table td.city-cell,
  .race-table td.date-cell {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 0.75rem;
  }
  .race-table td.city-cell::before,
  .race-table td.date-cell::before {
    content: attr(data-label);
    font-family: var(--font-display);
    text-transform: uppercase;
    font-size: 0.7rem;
    letter-spacing: 0.05em;
    color: var(--muted);
    font-weight: 700;
    flex-shrink: 0;
  }

  /* Distance chips can be several and wrap — label goes above, not beside. */
  .race-table td.dist-cell::before {
    content: attr(data-label);
    display: block;
    font-family: var(--font-display);
    text-transform: uppercase;
    font-size: 0.7rem;
    letter-spacing: 0.05em;
    color: var(--muted);
    font-weight: 700;
    margin-bottom: 0.3rem;
  }
}

.past-races summary {
  cursor: pointer; font-weight: 700; color: var(--muted);
  text-transform: uppercase; font-size: 0.85rem; letter-spacing: 0.05em;
  margin: 3rem 0 1.5rem; text-align: center; list-style: none;
}
.past-races summary::-webkit-details-marker { display: none; }
.past-races summary::after { content: " ▾"; }

/* Month hub grid — migrated off month_hub.html's old inline <style> block (Issues Backlog 5.3) */
.month-hub { max-width: 1000px; margin: 0 auto; padding: 2rem 1rem 4rem; }
.month-hub__eyebrow {
  font-size: 0.8rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--accent);
  font-weight: 700;
  margin-bottom: 0.4rem;
}
.month-hub__title { font-size: 1.9rem; margin: 0 0 2rem; }

.month-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 0.75rem; }

/* Shared hub tile base — used by both month and city hub grids so they can't drift apart again */
.hub-card {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  padding: 1.25rem 0.75rem;
  border: 1px solid var(--border);
  border-radius: 6px;
  text-align: center;
  text-decoration: none;
  color: var(--ink);
  font-weight: 600;
  background: white;
  transition: border-color 0.15s ease, transform 0.15s ease, opacity 0.15s ease;
}
.hub-card:hover { border-color: var(--accent); transform: translateY(-2px); }
.hub-card__count { font-size: 0.75rem; font-weight: 400; color: var(--muted); }

/* Dead months — requires month.is_past from the view (see races_month.html's is_past_month for the same pattern) */
.month-card--past { opacity: 0.55; }
.month-card--past:hover { opacity: 0.85; transform: none; }

/* City hub grid — migrated off city_hub.html's old inline <style> block, same twin pattern as month hub */
.city-hub { max-width: 1000px; margin: 0 auto; padding: 2rem 1rem 4rem; }
.city-hub__eyebrow {
  font-size: 0.8rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--accent);
  font-weight: 700;
  margin-bottom: 0.4rem;
}
.city-hub__title { font-size: 1.9rem; margin: 0 0 2rem; }

.top-cities { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 0.75rem; margin-bottom: 3rem; }

.az-heading {
  font-size: 0.8rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted);
  font-weight: 700;
  margin: 0 0 1rem;
  border-top: 1px solid var(--border);
  padding-top: 1.5rem;
}

.az-list { columns: 3 160px; column-gap: 1.5rem; }
.az-list a {
  display: block;
  padding: 0.3rem 0;
  color: var(--ink);
  text-decoration: none;
  border-bottom: 1px solid var(--border);
  break-inside: avoid;
}
.az-list a:hover { color: var(--accent); text-decoration: underline; }

@media (max-width: 480px) {
  .az-list { columns: 2 140px; }
}

/* Past-month status badge (races_month.html) */
.month-status-badge {
  display: inline-block;
  font-family: var(--font-mono);
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  background: var(--muted);
  color: white;
  padding: 0.2rem 0.55rem;
  border-radius: 4px;
  vertical-align: middle;
  margin-left: 0.5rem;
}

/* ==========================================================================
   APPEND TO style.css
   Also DELETE the four existing .race-table nth-child width lines — they're
   restated below with the distance column widened. (If you forget, the ones
   below still win on source order, but you'd have dead duplicated rules.)
   ========================================================================== */

/* --- Table column widths, rebalanced for distance chips ------------------- */
/* Distance was 18% when it held "10 km". It now holds up to 4 chips, so it
   takes width from the name column. Name still gets the most room. */
/* Column widths. DATE is sized for its worst case, not its average case:
   "Pon, 30 października 2026" (25 chars) is the longest realistic string
   the |date:"D, j E Y" format can produce - needs ~245px at this font size.
   28% of a 1000px table = 280px, leaving real margin instead of the ~5px
   slack a tighter percentage would leave. Learned this the hard way once
   already: the previous 20% was sized for the pre-weekday format ("j E Y"),
   and nobody re-checked it when the format changed - the string just
   silently overflowed past its cell and got clipped by the table's own
   border-radius/overflow:hidden edge. Whenever DATE's format changes again,
   recompute the worst case, don't eyeball it. */
.race-table th:nth-child(1), .race-table td:nth-child(1) { width: 36%; }  /* name */
.race-table th:nth-child(2), .race-table td:nth-child(2) { width: 22%; }  /* distance */
.race-table th:nth-child(3), .race-table td:nth-child(3) { width: 20%; }  /* city */
.race-table th:nth-child(4), .race-table td:nth-child(4) { width: 22%; }  /* date */

/* The distance cell is the one exception to the table's nowrap/ellipsis rule —
   chips need to wrap, not get cut off mid-chip. Rows holding several distances
   will be taller than single-distance rows; that's the accepted trade-off for
   showing them all. */
.race-table td.dist-cell {
  vertical-align: middle;
}

/* --- Distance chips ------------------------------------------------------- */
.dist-chips { display: flex; flex-wrap: wrap; gap: 0.25rem; }

.dist-chip {
  display: inline-block;
  font-family: var(--font-mono);
  font-size: 0.7rem;
  line-height: 1.4;
  font-weight: 500;
  padding: 0.15rem 0.45rem;
  border-radius: 4px;
  color: white;
  white-space: nowrap;
}

.dist-5km        { background: #0E7C66; }   /* teal   */
.dist-10km       { background: #2563EB; }   /* blue   */
.dist-polmaraton { background: #7C3AED; }   /* violet */
.dist-maraton    { background: var(--accent); }
.dist-ultra      { background: var(--ink); }
/* Outline chips get a white fill, not transparent: on the beige page
   background (homepage list, related races) a transparent chip looked faded,
   as if disabled. */
.dist-inne { background: white; color: var(--muted); border: 1px solid var(--border); }
.dist-typ { background: white; color: var(--muted); border: 1px solid var(--border); }

/* "+3" overflow indicator — hover shows the rest via the title attribute */
.dist-more {
  background: white;
  color: var(--muted);
  border: 1px dashed var(--border);
  cursor: help;
}

/* Race has no distance data at all (~a handful of rows) */
.dist-none {
  background: white;
  color: var(--muted);
  border: 1px solid var(--border);
  font-style: italic;
}

/* Past races: chips desaturate along with the rest of the row */
.race-table td.past .dist-chip { opacity: 0.55; }

/* --- Distance filter bar -------------------------------------------------- */
.dist-filter {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 0.4rem;
  max-width: 900px;
  margin: 0 auto 1.5rem;
}

.dist-filter__label {
  font-size: 0.75rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted);
  font-weight: 700;
  margin-right: 0.25rem;
}

.dist-filter-btn {
  font-family: var(--font-body);
  font-size: 0.8rem;
  font-weight: 500;
  padding: 0.3rem 0.75rem;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: white;
  color: var(--ink);
  cursor: pointer;
  transition: border-color 0.15s ease, background 0.15s ease, color 0.15s ease;
}
.dist-filter-btn:hover { border-color: var(--muted); }

/* Active state uses the same colour as the matching chip, so the filter and
   the thing it filters are visually linked. */
.dist-filter-btn.is-active { color: white; border-color: transparent; }
.dist-filter-btn.dist-btn-5km.is-active        { background: #0E7C66; }
.dist-filter-btn.dist-btn-10km.is-active       { background: #2563EB; }
.dist-filter-btn.dist-btn-polmaraton.is-active { background: #7C3AED; }
.dist-filter-btn.dist-btn-maraton.is-active    { background: var(--accent); }
.dist-filter-btn.dist-btn-ultra.is-active      { background: var(--ink); }
.dist-filter-btn.dist-btn-inne.is-active       { background: var(--muted); }
.dist-filter-btn[data-cat="all"].is-active     { background: var(--ink); }

.dist-hidden { display: none !important; }
.dist-empty { margin: 1.5rem 0; color: var(--muted); }

@media (max-width: 600px) {
  .dist-filter__label { width: 100%; text-align: center; margin: 0 0 0.25rem; }
  .dist-filter-btn { font-size: 0.75rem; padding: 0.25rem 0.6rem; }
}

/* --- Moved out of races_city.html's inline <style> block ------------------ */
/* Renamed from .month-hub__eyebrow — that class already existed in this file
   for month_hub.html with different values (accent colour, 0.8rem). Two
   different looks were sharing one name and only working because the inline
   block overrode the shared one on that one page. */
.city-months__eyebrow {
  font-size: 0.75rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted);
  font-weight: 700;
  margin-bottom: 0.5rem;
  text-align: center;
}

.month-grid-compact {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.5rem;
  max-width: 700px;
  margin: 0 auto 3rem;
}

/* Same size as .dist-filter-btn, the distance pills right above it on the
   city page (was 0.85rem / 0.4rem 0.9rem, visibly bigger). */
.month-pill {
  padding: 0.3rem 0.75rem;
  border: 1px solid var(--border);
  border-radius: 999px;
  text-decoration: none;
  color: var(--ink);
  font-size: 0.8rem;
  font-weight: 500;
  background: white;
  transition: border-color 0.15s ease;
}
.month-pill:hover { border-color: var(--accent); color: var(--accent); }
/* Phone size, matching .dist-filter-btn's ≤600px rule. Must sit below the
   base .month-pill rule above, or the base rule wins (same specificity). */
@media (max-width: 600px) {
  .month-pill { font-size: 0.75rem; padding: 0.25rem 0.6rem; }
  .month-grid-compact { gap: 0.4rem; }
}

/* Collapsible "Zakończone biegi" section. Now used by races_city.html AND
   races_city_month.html, hence the move to shared CSS. */
.past-races summary {
  cursor: pointer;
  font-weight: 700;
  color: var(--muted);
  text-transform: uppercase;
  font-size: 0.85rem;
  letter-spacing: 0.05em;
  margin: 3rem 0 1.5rem;
  text-align: center;
  list-style: none;
}
.past-races summary::-webkit-details-marker { display: none; }
.past-races summary::after { content: " ▾"; }
.city-search-box {
    background: #fff;
    border: 1px solid var(--border, #ddd9c8);
    border-radius: 10px;
    padding: 12px 14px;
    margin: 0 auto 2.5rem;
    max-width: 900px;
    text-align: left;
}

.city-search-box .city-search-label {
    display: block;
    font-size: 11px;
    font-weight: 500;
    color: var(--muted, #5f5e5a);
    letter-spacing: 0.5px;
    margin-bottom: 8px;
}

.city-search-box input[type="text"] {
    width: 100%;
    box-sizing: border-box;
    margin-bottom: 10px;
    padding: 8px 10px;
    border: 1px solid #ccc;
    border-radius: 6px;
    font-size: 14px;
}

.city-search-box .place-grid {
    max-height: 160px;
    overflow-y: auto;
    padding-right: 4px;
}

.city-search-box .no-city-match {
    font-size: 13px;
    color: var(--muted, #5f5e5a);
    margin: 8px 0 0;
}

/* Shared by race-detail header and homepage upcoming list. Plain muted text,
   not chips — chips should carry filterable data (distance category), not
   display data. No emoji: the built-in 📅 glyph renders with a baked-in "17"
   on most platforms, which read as a UI bug next to a real date. */
.meta-line { display: flex; gap: 0.35rem; align-items: center; flex-wrap: wrap; font-size: 0.85rem; }
.meta-line .meta-sep { color: var(--border); }
.meta-line .meta-date { color: var(--ink); font-weight: 500; }
.meta-line .meta-city { color: var(--muted); }
.meta-line .meta-city::before { content: "📍"; margin-right: 0.25rem; }

.race-card .btn-primary {
  background: var(--ink);
  border-color: var(--ink);
  font-weight: 600;
}
.race-card .btn-primary:hover {
  filter: brightness(1.15);
}

.month-filter {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 0.4rem;
  max-width: 900px;
  margin: 0 auto 1.5rem;
}
.month-filter-btn {
  font-family: var(--font-body);
  font-size: 0.8rem;
  font-weight: 500;
  padding: 0.3rem 0.75rem;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: white;
  color: var(--ink);
  cursor: pointer;
  transition: border-color 0.15s ease, background 0.15s ease, color 0.15s ease;
}
.month-filter-btn:hover { border-color: var(--muted); }
.month-filter-btn.is-active { color: white; border-color: transparent; background: var(--ink); }
.month-hidden { display: none !important; }
.month-empty { margin: 1.5rem 0; color: var(--muted); }

@media (max-width: 600px) {
  .month-filter__label { width: 100%; text-align: center; margin: 0 0 0.25rem; }
  .month-filter-btn { font-size: 0.75rem; padding: 0.25rem 0.6rem; }
}

.filter-bar { display: flex; flex-direction: column; gap: 0.75rem; margin-bottom: 1.5rem; }
.filter-group { display: flex; flex-wrap: wrap; gap: 0.4rem; align-items: center; }
.filter-label { font-size: 0.85rem; color: var(--muted); min-width: 5rem; text-align: left; }
.filter-pill {
  padding: 0.25rem 0.7rem; border: 1px solid var(--border); border-radius: 999px;
  font-size: 0.85rem; text-decoration: none; color: var(--ink); background: #fff;
}
.filter-pill:hover { border-color: var(--ink); }
.filter-pill.is-active { background: var(--ink); border-color: var(--ink); color: #fff; }

/* --- Dropdown filter (native <details>, no JS) --- */
.filter-dropdown { position: relative; }
.filter-dropdown > summary {
  list-style: none;
  cursor: pointer;
  padding: 0.25rem 0.7rem;
  border: 1px solid var(--border);
  border-radius: 999px;
  font-size: 0.85rem;
  background: #fff;
  color: var(--ink);
}
.filter-dropdown > summary::-webkit-details-marker { display: none; }
.filter-dropdown > summary:hover,
.filter-dropdown[open] > summary,
.filter-dropdown > summary.is-active { border-color: var(--ink); }

.filter-dropdown__panel {
  position: absolute;
  top: calc(100% + 0.35rem);
  left: 0;
  z-index: 20;
  display: flex;
  flex-direction: column;
  min-width: 9rem;
  max-height: 16rem;
  overflow-y: auto;
  padding: 0.35rem;
  background: #fff;
  border: 1px solid var(--border);
  border-radius: 8px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.14);   /* was 0 4px 16px / 0.08 */
  text-align: left;
}
.filter-dropdown__panel a {
  padding: 0.3rem 0.6rem;
  border-radius: 4px;
  font-size: 0.85rem;        /* was 0.9rem — matches the pills now */
  line-height: 1.4;          /* new — kills the inherited tall line-height */
  color: var(--ink);
  text-decoration: none;
  white-space: nowrap;
}
.filter-dropdown__panel a:hover { background: var(--bg); }
.filter-dropdown__panel a.is-active { font-weight: 600; }

/* --- Active filter chips --- */
.active-filters {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  align-items: center;
  margin-top: 0.25rem;
}
.active-chip {
  display: inline-flex;
  gap: 0.4rem;
  padding: 0.25rem 0.7rem;
  border-radius: 999px;
  background: var(--ink);
  color: #fff;
  font-size: 0.85rem;
  text-decoration: none;
}
.active-chip span { opacity: 0.6; }
.active-chip:hover { color: #fff; }
.active-chip:hover span { opacity: 1; }
.filter-clear { font-size: 0.85rem; color: var(--muted); text-decoration: none; }
.filter-clear:hover { color: var(--ink); }

/* Phase 2 — footer */
.site-footer {
  margin-top: 0;
  padding: 2rem 1rem;
  border-top: 1px solid var(--border);
  text-align: center;
}
.footer-cities__label {
  display: block;
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--muted);
  margin-bottom: 0.5rem;
}
.footer-cities__links {
  display: flex;
  gap: 0.9rem;
  justify-content: center;
  flex-wrap: wrap;
  margin-bottom: 1.25rem;
}
.footer-cities__links a {
  color: var(--ink);
  text-decoration: none;
  font-size: 0.9rem;
}
.footer-cities__links a:hover { text-decoration: underline; }
.footer-links {
  display: flex;
  gap: 1.25rem;
  justify-content: center;
  flex-wrap: wrap;
  margin-bottom: 0.5rem;
}
.footer-links a {
  color: var(--muted);
  text-decoration: none;
  font-size: 0.9rem;
}
.footer-links a:hover { color: var(--ink); text-decoration: underline; }
.footer-copy { color: var(--muted); font-size: 0.8rem; margin: 0; }

.region-index {
  list-style: none;
  margin: 1.5rem auto 0;
  padding: 0;
  max-width: 900px;
  columns: 2;
  column-gap: 2.5rem;
}

.region-index li {
  break-inside: avoid;
}

.region-index a {
  display: grid;
  grid-template-columns: minmax(9rem, auto) 1fr 2.5rem;
  align-items: center;
  gap: 0.75rem;
  padding: 0.5rem 0.25rem;
  text-decoration: none;
  color: inherit;
  border-bottom: 1px solid rgba(20, 28, 51, 0.08);
}

.region-index a:hover,
.region-index a:focus-visible {
  background: rgba(20, 28, 51, 0.04);
}

.region-index__name {
  font-weight: 600;
  text-align: left;
  line-height: 1.25;
}

.region-index__bar {
  height: 5px;
  border-radius: 3px;
  background: rgba(20, 28, 51, 0.08);
  overflow: hidden;
}

.region-index__bar > span {
  display: block;
  height: 100%;
  border-radius: 3px;
  background: rgba(20, 28, 51, 0.55);
}

.region-index a:hover .region-index__bar > span {
  background: rgba(20, 28, 51, 0.85);
}

.region-index__count {
  text-align: right;
  font-variant-numeric: tabular-nums;
  opacity: 0.6;
  font-size: 0.9rem;
}

@media (max-width: 640px) {
  .region-index { columns: 1; }
  .region-index a { grid-template-columns: minmax(8rem, auto) 1fr 2.5rem; }
}

.city-hub__all {
  margin-top: 2rem;
  text-align: center;
  font-size: 0.95rem;
}

.city-index-search {
  max-width: 480px;
  margin: 0 auto 2.5rem;
}

.city-index-search input {
  width: 100%;
  padding: 0.6rem 0.9rem;
  border: 1px solid rgba(20, 28, 51, 0.2);
  border-radius: 6px;
  font-size: 1rem;
}

.city-index__group {
  margin-bottom: 2rem;
}

.city-index__letter {
  font-size: 1.1rem;
  margin: 0 0 0.6rem;
  padding-bottom: 0.3rem;
  border-bottom: 2px solid rgba(20, 28, 51, 0.12);
}

.city-index__list {
  list-style: none;
  margin: 0;
  padding: 0;
  columns: 4;
  column-gap: 2rem;
}

.city-index__list li {
  break-inside: avoid;
  padding: 0.15rem 0;
}

.city-index__list a {
  text-decoration: none;
  color: inherit;
}

.city-index__list a:hover { text-decoration: underline; }

.city-index__list a span {
  opacity: 0.45;
  font-size: 0.85rem;
}

@media (max-width: 900px) { .city-index__list { columns: 2; } }
@media (max-width: 560px) { .city-index__list { columns: 1; } }

/* Nested .container (most list templates put one inside main.container):
   no top spacing at any width. Its 2rem padding + Bootstrap's mt-4 stacked on
   main's py-5 left 104px between navbar and H1; now it's main's own padding
   only (48px desktop, 24px on phones). margin-top needs !important because
   Bootstrap's mt-4 utility uses it. */
.container .container { padding-top: 0; margin-top: 0 !important; }

/* --- Phone layout (≤576px) ------------------------------------------------
   Everything here is phone-only; desktop is untouched.
   1. .container has 2rem padding (overriding Bootstrap's 12px), and most list
      templates nest a second .container inside main.container, so a 375px
      phone lost 128px to padding. Thinner outer padding, none on the inner one.
   2. Less empty space between the navbar and the page (main has py-5).
   3. Race page: date and place on separate lines, so the "·" separator can't
      dangle at the end of a wrapped line.
   4. "Inne biegi" on the race page: date under the name, not squeezed
      beside it (dates wrapped onto 2-3 lines of different widths). */
@media (max-width: 576px) {
  .container { padding-left: 1rem; padding-right: 1rem; }
  .container .container { padding-left: 0; padding-right: 0; }
  main.container { padding-top: 1.5rem !important; }

  .meta-line { flex-direction: column; align-items: flex-start; gap: 0.15rem; }
  .meta-line .meta-sep { display: none; }

  .related-races__row { flex-direction: column; gap: 0.1rem; }
  .related-races__date { white-space: nowrap; }

  /* Homepage: less hero padding and slimmer nav cards, so the "Nadchodzące
     biegi" list starts on the first screen. */
  .hero { padding: 1rem 0 1.25rem; }
  /* Course profile: shorter chart; "Start" would collide with "5 km". */
  .hero-profile { margin-top: 1.25rem; }
  .hero-profile svg { height: 56px; }
  .hero-profile__start { display: none; }
  .home-nav-cards { gap: 0.5rem; margin-bottom: 1.5rem; }
  .nav-card { padding: 0.75rem 1rem; }
  .nav-card h3 { font-size: 1rem; margin-bottom: 0.15rem; }
  .nav-card p { font-size: 0.85rem; }

  /* City hub: the 12 top-city tiles were one tall column (two 150px columns
     need 312px, a 375px phone has 311), pushing the regions ~1,100px down.
     Two fixed columns + shorter tiles. */
  .top-cities { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0.5rem; margin-bottom: 2rem; }
  .top-cities .hub-card { padding: 0.6rem 0.5rem; }
  .city-hub { padding-top: 0; }
  .city-hub__title { margin-bottom: 1.25rem; }
}

/* Mobile card rows (≤640px, see the race-table card layout above): the city
   cell is a flex row. Town + region used to be two separate flex items next
   to the label, so three things were spread across the row: the town floated
   mid-row and the region got clipped by the table's overflow:hidden. Wrapped
   in one .cell-value (_race_row.html), the value is a single right-aligned
   block: town on top, region under it. min-width:0 lets it shrink and wrap
   instead of overflowing. */
@media (max-width: 640px) {
  .race-table td.city-cell .cell-value { display: block; min-width: 0; text-align: right; }
}

/* --- Filters on phones: one swipeable line per row (STOPGAP until B1) ------
   Wrapped pill rows took ~300px above the first race. Each row now stays on
   one line and scrolls sideways; a pill cut off at the edge hints there's
   more. Rows holding a dropdown are left alone: overflow would clip its
   pop-up panel. At the end of the file on purpose, so it wins over the
   earlier ≤600px label rules. Delete this block when B1 replaces the filters. */
@media (max-width: 576px) {
  .dist-filter,
  .month-grid-compact,
  .month-filter,
  .filter-group:not(:has(.filter-dropdown)) {
    flex-wrap: nowrap;
    justify-content: flex-start;
    overflow-x: auto;
    scrollbar-width: none;
    padding-bottom: 2px;
    /* "There's more to the right" hints: the row runs to the screen edge
       (pills visibly slide off it) and fades out over its last 2.5rem. The
       extra right padding lets the last pill scroll clear of the fade. */
    margin-right: -1rem;
    padding-right: 2.5rem;
    -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 2.5rem), transparent);
    mask-image: linear-gradient(to right, #000 calc(100% - 2.5rem), transparent);
  }
  .dist-filter::-webkit-scrollbar,
  .month-grid-compact::-webkit-scrollbar,
  .month-filter::-webkit-scrollbar,
  .filter-group::-webkit-scrollbar { display: none; }

  .dist-filter__label, .month-filter__label, .filter-label { flex-shrink: 0; width: auto; margin: 0 0.25rem 0 0; }
  .dist-filter-btn, .month-pill, .month-filter-btn, .filter-pill { flex-shrink: 0; white-space: nowrap; }

  /* City page: less air around the month row (mt-5 is Bootstrap, !important). */
  .city-months__eyebrow { margin-top: 1rem !important; text-align: left; }
  .month-grid-compact { margin-bottom: 1.5rem; }
}

/* --- Whole race card tappable on phones (≤640px, the card layout) ----------
   "Stretched link": the race-name link stays the only real link, but its
   ::after covers the whole card, so tapping the date or town opens the race
   too. Scoped to the card layout: on desktop a table row can't reliably be
   a positioning box, and the ::after would cover something else.
   The hover colour moves from the cells to the card: on cells it left an
   inner grey rectangle inside the card's padding after a tap. */
@media (max-width: 640px) {
  .race-table tr { position: relative; }
  .race-table td.name-cell a::after { content: ""; position: absolute; inset: 0; }
  .race-table tr:hover td { background: transparent; }
  .race-table tr:hover, .race-table tr:active { background: #FAFAF7; }

  /* Same for the homepage "Nadchodzące biegi" list. */
  .upcoming-list li { position: relative; }
  .upcoming-list li > a::after { content: ""; position: absolute; inset: 0; }
}

/* --- Compact race cards on phones (≤640px) -----------------------------------
   Was ~220px per card (labels "DYSTANS / MIEJSCOWOŚĆ / DATA" + a row each).
   Now: name (+ type), date, 📍 place, then the chips.
   - The row becomes a wrapping flex box; `order` puts date/place before the
     chips without touching the HTML (desktop table unchanged).
   - Date and place each get a full line, always. "Beside if it fits" made
     the place jump between cards (next to a short date, under a long one).
     A long "Janowiec Wielkopolski, kujawsko-pomorskie" just wraps in its line.
   - The 📍 marks the place instead of a "·" separator.
   - Labels come from td::before (data-label); they're switched off here.
   Must stay below the earlier card-layout rules so it wins. */
@media (max-width: 640px) {
  .race-table tr {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    column-gap: 0.75rem;
    row-gap: 0.2rem;
    padding: 0.75rem 0.9rem;
    margin-bottom: 0.6rem;
  }
  /* border: none — Bootstrap's .table (on /biegi/) draws a line under every
     cell, which inside a card showed up as a line under each row. */
  .race-table td { padding: 0; border: none; }
  .race-table td.name-cell { order: 1; flex-basis: 100%; padding-bottom: 0.15rem; }

  .race-table td.date-cell,
  .race-table td.city-cell { display: block; font-size: 0.9rem; }
  .race-table td.date-cell::before,
  .race-table td.dist-cell::before { content: none; }

  .race-table td.date-cell { order: 2; flex-basis: 100%; white-space: nowrap; font-weight: 500; }
  .race-table td.city-cell { order: 3; flex-basis: 100%; min-width: 0; color: var(--muted); }
  .race-table td.city-cell::before {
    content: "📍";
    font-family: inherit; font-size: 0.8rem; text-transform: none; letter-spacing: 0;
    margin-right: 0.2rem;
  }
  .race-table td.city-cell .cell-value { display: inline; text-align: left; }
  /* Region inline after the town: "Warszawa, mazowieckie" (Bootstrap's
     d-block is !important, hence the !important here). */
  .race-table td.city-cell .cell-value .d-block { display: inline !important; font-size: inherit; }
  .race-table td.city-cell .cell-value .d-block::before { content: ", "; }

  .race-table td.dist-cell { order: 4; flex-basis: 100%; margin-top: 0.3rem; }
}
