/* Directory pages (templates/directory/), ported from the prototype's place lists (/pois): text,
   category chips, place rows, and the filter panel on the left that the "Filters" button shows
   and hides. Colours from site.css. */
* { box-sizing: border-box; }
body {
  margin: 0;
  background: var(--bg);
  color: var(--fg);
  font: 1rem/1.6 system-ui, sans-serif;
  -webkit-font-smoothing: antialiased;
}
a { color: var(--fg); }
.page {
  max-width: 1040px;
  margin: 0 auto;
  padding: 1.5rem var(--gutter) 4rem;
}
h1, h2 {
  margin: 0 0 1rem;
  font-weight: 700;
  line-height: 1.25;
  letter-spacing: -0.01em;
}
h1 {
  font-size: clamp(1.75rem, 4vw, 2.25rem);
  letter-spacing: -0.02em;
}
h2 { font-size: 1.125rem; }
.lead {
  margin: 0 0 1.5rem;
  color: var(--fg-secondary);
}
.meta {
  margin: 0 0 0.5rem;
  font-size: 0.875rem;
  line-height: 1.5;
  color: var(--fg-tertiary);
}
.breadcrumb {
  margin: 0 0 0.75rem;
  font-size: 0.875rem;
  color: var(--fg-tertiary);
}
.breadcrumb a {
  color: inherit;
  text-decoration: none;
}
.breadcrumb a:hover {
  color: var(--fg);
  text-decoration: underline;
}
.region-th {
  color: var(--fg-tertiary);
  font-weight: 400;
}

/* Categories over the list, with their number of places */
.tag-filter ul {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  list-style: none;
  padding: 0;
  margin: 0;
}
.tag-filter {
  margin-bottom: 2rem;
}
.tag-filter a {
  display: inline-block;
  padding: 0.25rem 0.875rem;
  font-size: 0.875rem;
  line-height: 1.6;
  color: var(--fg-secondary);
  border: 1px solid var(--border);
  border-radius: 100px;
  text-decoration: none;
}
.tag-filter a:hover {
  border-color: var(--border-hover);
  color: var(--fg);
}
.tag-filter a[aria-current] {
  background: var(--bg-surface);
  border-color: var(--fg);
  color: var(--fg);
}
.chip-count {
  color: var(--fg-tertiary);
  font-variant-numeric: tabular-nums;
}

/* A category's OSM types (hotel, hostel, …) under the category chips */
.subtype-chips {
  margin-top: -1.25rem;
}
.chips-label {
  align-self: center;
  min-width: 4.5rem;
  color: var(--fg-tertiary);
  font-size: 0.8125rem;
}

/* Hub: a big entry's categories as tiles with OM's category icons, instead of a list of everything */
.hub {
  margin-bottom: 2rem;
}
.hub h2 {
  font-size: 1rem;
  margin: 0 0 0.75rem;
}
.hub-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(11rem, 1fr));
  gap: 0.5rem;
  list-style: none;
  margin: 0;
  padding: 0;
}
.hub-grid a {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.625rem 0.75rem;
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-radius: 12px;
  color: var(--fg);
  text-decoration: none;
}
.hub-grid a:hover {
  border-color: var(--border-hover);
}
.hub-grid img {
  display: block;
  width: 36px;
  height: 36px;
  flex: none;
}
/* The name over its count, so the name has the tile's width ("Where to eat" in one line) */
.hub-text {
  display: flex;
  flex-direction: column;
  min-width: 0;
  line-height: 1.3;
}
.hub-name {
  font-weight: 500;
}
.hub-count {
  color: var(--fg-tertiary);
  font-size: 0.8125rem;
  font-variant-numeric: tabular-nums;
}

/* The entries below this one (provinces of a region, districts of a province, …) */
.area-children-block {
  margin-bottom: 2rem;
}
.town-list {
  display: flex;
  flex-wrap: wrap;
  gap: 0.25rem 1rem;
  list-style: none;
  margin: 0;
  padding: 0;
  font-size: 0.9375rem;
}
/* A station's timetable (rail pages) */
.departures { border-collapse: collapse; font-size: 0.9375rem; font-variant-numeric: tabular-nums; }
.departures th { text-align: left; font-weight: 600; font-size: 0.8125rem; color: var(--fg-tertiary); padding: 0 1.25rem 0.25rem 0; }
.departures td { padding: 0.2rem 1.25rem 0.2rem 0; border-top: 1px solid var(--border); }
.timetable-source { margin: 0.75rem 0 0; font-size: 0.8125rem; color: var(--fg-tertiary); }
/* A station's code or a line's neighbouring stations after the name (rail pages) */
.town-list .entry-note { margin-left: 0.4em; color: var(--fg-tertiary); font-size: 0.85em; font-variant-numeric: tabular-nums; }
.town-list .region-th {
  font-size: 0.8125rem;
}

/* Place rows */
.poi-count {
  margin: 0;
  color: var(--fg-secondary);
  font-size: 0.875rem;
}
.poi-rows {
  list-style: none;
  margin: 0;
  padding: 0;
}
.poi-rows li {
  padding: 0.75rem 0;
  border-bottom: 1px solid var(--border);
}
.poi-name {
  font-weight: 600;
  text-decoration: none;
}
.poi-name:hover {
  text-decoration: underline;
}
.poi-th {
  color: var(--fg-tertiary);
}
.poi-rows .meta {
  margin: 0.125rem 0 0;
}
.poi-rows .poi-links {
  font-size: 0.75rem;
}
.poi-rows .meta a {
  color: inherit;
}
.pagination {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-top: 2rem;
  color: var(--fg-secondary);
  font-size: 0.875rem;
}

/* Filter fields */
.poi-filter {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 0.75rem 1rem;
  margin-bottom: 1.5rem;
}
.poi-filter label {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  font-size: 0.875rem;
  color: var(--fg-secondary);
}
.poi-filter-q {
  flex: 1 1 16rem;
}
.poi-filter input,
.poi-filter select,
.poi-filter button {
  min-height: 2.5rem;
  padding: 0.375rem 0.75rem;
  font: inherit;
  font-size: 1rem;
  color: var(--fg);
  background: var(--bg-elevated);
  border: 1px solid var(--border-hover);
  border-radius: 8px;
}
.poi-filter button {
  cursor: pointer;
}
.poi-filter button:hover {
  background: var(--bg-surface);
}
.js .poi-filter button {
  display: none;
} /* with JavaScript the list filters while typing */
@media print {
  .poi-filter,
  .pois-sidebar,
  .tag-filter,
  .pagination {
    display: none;
  }
}

/* The filter panel on the left, sticking under the header while scrolling. With JavaScript the
   "Filters" button shows and hides it (Alpine component filters in directory.js, data-state on
   .pois-layout); the button stands above the heading and names the chosen filters. On desktop
   the panel slides open on the left (as wide as its content, 12 to 20rem) and pushes button,
   heading and list to the right; open unless closed before. On narrow screens heading, button,
   filters and list stand one below the other, closed by default. Without JavaScript always open. */
/* Flexbox rather than a grid: the list starts exactly at the (sliding) width of the panel */
.pois-layout {
  display: flex;
  gap: 2.5rem;
  align-items: flex-start;
}
.pois-sidebar {
  flex: none;
}
.pois-main {
  flex: 1 1 0;
  min-width: 0;
}
.pois-sidebar {
  position: sticky;
  top: var(--header-h, 5rem);
  max-width: 20rem;
  max-height: calc(100vh - var(--header-h, 5rem) - 1rem);
  overflow-y: auto;
  padding: 1rem;
  background: var(--bg-surface);
  border-radius: 10px;
}
.pois-sidebar-heading {
  margin: 0 0 0.75rem;
  font-size: 1rem;
}
.pois-sidebar .poi-filter {
  flex-direction: column;
  flex-wrap: nowrap;
  align-items: stretch;
  gap: 0.75rem;
  margin: 0;
}
.pois-sidebar .poi-filter-q {
  flex: none;
}
.pois-sidebar .poi-filter input,
.pois-sidebar .poi-filter select {
  width: 100%;
}
.pois-clear {
  font-size: 0.875rem;
}
.pois-filters-toggle {
  display: none;
}
.js .pois-sidebar {
  padding: 0;
}
.js .pois-sidebar .poi-filter {
  padding: 1rem;
}
.js .pois-sidebar-heading {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}
.js .pois-filters-toggle {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  max-width: 100%;
  margin: 0 0 0.75rem;
  padding: 0.5rem 0.875rem;
  font: inherit;
  font-size: 0.875rem;
  font-weight: 600;
  color: var(--fg);
  background: var(--bg-surface);
  border: 0;
  border-radius: 10px;
  cursor: pointer;
}
/* Hover the same in both states, without changing the background (open, the button hangs on the
   panel, it would flicker on click): icon, arrow and chosen filters darken, the label underlines */
.pois-filters-toggle svg,
.js .pois-filters-toggle::after {
  color: var(--fg-secondary);
}
.js .pois-filters-toggle:hover svg,
.js .pois-filters-toggle:hover::after,
.js .pois-filters-toggle:hover .pois-filters-active {
  color: var(--fg);
}
.js .pois-filters-toggle:hover .pois-filters-label {
  text-decoration: underline;
  text-underline-offset: 0.2em;
  text-decoration-thickness: 1px;
}
.pois-filters-toggle svg {
  flex: none;
}
.pois-filters-toggle:focus-visible {
  outline-offset: -2px;
} /* inside: open, the button hangs on the panel */
.pois-filters-label {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.pois-filters-active {
  font-weight: 400;
  color: var(--fg-secondary);
}
.js .pois-filters-toggle::after {
  content: "";
  flex: none;
  width: 0.4375rem;
  height: 0.4375rem;
  margin-left: 0.25rem;
  border: solid currentColor;
  border-width: 0 1.5px 1.5px 0;
  transform: rotate(-45deg); /* closed: arrow to the right (open) */
}
.js .pois-layout[data-state="open"] .pois-filters-toggle::after {
  transform: rotate(135deg);
} /* open: to the left */
@media (min-width: 44.01em) {
  /* On desktop the state is an attribute on <html> (data-poi-filters, set before the
     first paint by directory-init.js, then by directory.js), so nothing jumps on load. It only
     animates after a click on the button (data-animate): the width slides where the browser can
     interpolate between 0 and fit-content (interpolate-size), else it jumps; the form fades in
     after. The gap to the list is padding of the right column: open, the button above it reaches
     left to the panel, same colour, unrounded there, like a tab on it. */
  .js .pois-layout {
    column-gap: 0;
  }
  .js .pois-main {
    padding-left: 2.5rem;
  }
  .js .pois-sidebar {
    interpolate-size: allow-keywords;
    width: fit-content;
    min-width: 12rem;
    overflow-x: hidden;
  }
  /* Open, the bar with the button sticks under the header like the panel (else they separate),
     on the page background, so the list disappears cleanly below it */
  .js:not([data-poi-filters="closed"]) .pois-toolbar {
    position: sticky;
    top: var(--header-h, 5rem);
    z-index: 5;
    margin-left: -2.5rem;
    padding-bottom: 0.75rem;
    background: var(--bg);
  }
  .js:not([data-poi-filters="closed"]) .pois-filters-toggle {
    margin: 0;
    padding-left: calc(0.875rem + 2.5rem);
    border-radius: 0 10px 10px 0;
  }
  .js:not([data-poi-filters="closed"]) .pois-filters-toggle::after {
    transform: rotate(135deg);
  }
  .js:not([data-poi-filters="closed"]) .pois-sidebar {
    border-top-right-radius: 0;
  }
  [data-poi-filters="closed"] .pois-main {
    padding-left: 0;
  }
  [data-poi-filters="closed"] .pois-sidebar {
    width: 0;
    min-width: 0;
  }
  [data-poi-filters="closed"] .poi-filter {
    display: none;
  }
  [data-poi-filters="closed"] .pois-filters-toggle::after {
    transform: rotate(-45deg);
  }
  /* The list's gap doesn't slide (it jumps): so the button hangs on the edge of the panel in
     every frame, whose width slides */
  .pois-layout[data-animate] .pois-sidebar {
    transition:
      width 0.25s ease,
      min-width 0.25s ease;
  }
  .pois-layout[data-animate] .pois-sidebar .poi-filter {
    transition: opacity 0.2s ease 0.2s;
  }
  @starting-style {
    .pois-layout[data-animate] .pois-sidebar .poi-filter {
      opacity: 0;
    }
  }
}
@media (prefers-reduced-motion: reduce) {
  .pois-layout[data-animate] :is(.pois-sidebar, .poi-filter) {
    transition: none;
  }
}
@media (max-width: 44em) {
  /* One below the other: heading, button, filters, list (the right column dissolves for it) */
  .pois-layout {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: 0;
  }
  .pois-main,
  #results {
    display: contents;
  }
  #results > h1,
  #results > .lead {
    order: -1;
  }
  .pois-sidebar {
    order: 1;
    position: static;
    max-width: none;
    max-height: none;
    overflow: visible;
    margin-bottom: 1.5rem;
  }
  #results > :not(h1, .lead) {
    order: 2;
  }
  .pois-sidebar .poi-filter {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
  .pois-sidebar .poi-filter-q,
  .pois-sidebar .pois-clear {
    grid-column: 1 / -1;
  }
  .js .pois-filters-toggle {
    display: flex;
    width: 100%;
    padding: 0.75rem 1rem;
    font-size: 1rem;
  }
  .js .pois-filters-toggle::after {
    margin-left: auto;
    transform: rotate(45deg);
  } /* closed: down */
  .js .pois-layout[data-state="open"] .pois-filters-toggle::after {
    transform: rotate(-135deg);
  }
  .js .pois-layout:not([data-state="open"]) .pois-sidebar {
    margin-bottom: 0.75rem;
  }
  .js .pois-layout:not([data-state="open"]) .poi-filter {
    display: none;
  }
}

/* The swappable selects (templates/directory/_filter_fields.html) lay out as if the wrapper weren't there */
.poi-filter-fields { display: contents; }

/* The entry on the map at the end of the page (static/directory-map.js) */
.entry-map-block {
  margin-top: 3rem;
}
.entry-map-block h2 {
  font-size: 1rem;
  margin: 0 0 0.75rem;
}
#entry-map {
  height: 380px;
  border: 1px solid var(--border);
  border-radius: 12px;
  overflow: hidden;
  background: var(--bg-surface);
}
.entry-map-link {
  margin: 0.5rem 0 0;
  font-size: 0.875rem;
}
